VisualBasicCompiler.vb 9.5 KB
Newer Older
1
' Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
P
Pilchie 已提交
2 3 4 5 6

Imports System.Collections.Immutable
Imports System.IO
Imports System.Reflection
Imports System.Threading.Tasks
7
Imports Microsoft.CodeAnalysis.Diagnostics
8
Imports Roslyn.Utilities
P
Pilchie 已提交
9 10 11 12 13 14

Namespace Microsoft.CodeAnalysis.VisualBasic

    Friend MustInherit Class VisualBasicCompiler
        Inherits CommonCompiler

15
        Friend Const ResponseFileName As String = "vbc.rsp"
16
        Friend Const VbcCommandLinePrefix = "vbc : " 'Common prefix String For VB diagnostic output with no location.
17 18 19
        Private Shared s_responseFileName As String
        Private ReadOnly _responseFile As String
        Private ReadOnly _diagnosticFormatter As CommandLineDiagnosticFormatter
P
Pilchie 已提交
20

J
Jared Parsons 已提交
21 22
        Protected Sub New(parser As VisualBasicCommandLineParser, responseFile As String, args As String(), clientDirectory As String, baseDirectory As String, sdkDirectory As String, additionalReferenceDirectories As String)
            MyBase.New(parser, responseFile, args, clientDirectory, baseDirectory, sdkDirectory, additionalReferenceDirectories)
23
            _diagnosticFormatter = New CommandLineDiagnosticFormatter(baseDirectory)
P
Pilchie 已提交
24 25
        End Sub

A
angocke 已提交
26
        Friend Overloads ReadOnly Property Arguments As VisualBasicCommandLineArguments
P
Pilchie 已提交
27
            Get
A
angocke 已提交
28
                Return DirectCast(MyBase.Arguments, VisualBasicCommandLineArguments)
P
Pilchie 已提交
29 30 31 32 33
            End Get
        End Property

        Public Overrides ReadOnly Property DiagnosticFormatter As DiagnosticFormatter
            Get
34
                Return _diagnosticFormatter
P
Pilchie 已提交
35 36 37 38
            End Get
        End Property

        Private Function ParseFile(consoleOutput As TextWriter,
A
angocke 已提交
39 40
                                   parseOptions As VisualBasicParseOptions,
                                   scriptParseOptions As VisualBasicParseOptions,
P
Pilchie 已提交
41
                                   ByRef hadErrors As Boolean,
42 43
                                   file As CommandLineSourceFile,
                                   errorLogger As ErrorLogger) As SyntaxTree
P
Pilchie 已提交
44 45

            Dim fileReadDiagnostics As New List(Of DiagnosticInfo)()
46
            Dim content = ReadFileContent(file, fileReadDiagnostics, Arguments.Encoding, Arguments.ChecksumAlgorithm)
P
Pilchie 已提交
47 48

            If content Is Nothing Then
49
                ReportErrors(fileReadDiagnostics, consoleOutput, errorLogger)
P
Pilchie 已提交
50 51 52 53 54
                fileReadDiagnostics.Clear()
                hadErrors = True
                Return Nothing
            End If

A
angocke 已提交
55
            Dim tree = VisualBasicSyntaxTree.ParseText(content, If(file.IsScript, scriptParseOptions, parseOptions), file.Path)
56 57 58 59 60 61 62 63

            ' prepopulate line tables.
            ' we will need line tables anyways and it is better to Not wait until we are in emit
            ' where things run sequentially.
            Dim isHiddenDummy As Boolean
            tree.GetMappedLineSpanAndVisibility(Nothing, isHiddenDummy)

            Return tree
P
Pilchie 已提交
64 65
        End Function

J
Jared Parsons 已提交
66
        Public Overrides Function CreateCompilation(consoleOutput As TextWriter, touchedFilesLogger As TouchedFileLogger, errorLogger As ErrorLogger) As Compilation
P
Pilchie 已提交
67 68 69 70 71 72 73 74 75
            Dim parseOptions = Arguments.ParseOptions
            Dim scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script)

            Dim hadErrors As Boolean = False

            Dim sourceFiles As ImmutableArray(Of CommandLineSourceFile) = Arguments.SourceFiles
            Dim trees(sourceFiles.Length - 1) As SyntaxTree

            If Arguments.CompilationOptions.ConcurrentBuild Then
76
                Parallel.For(0, sourceFiles.Length,
77 78 79
                   UICultureUtilities.WithCurrentUICulture(Of Integer)(
                        Sub(i As Integer)
                            ' NOTE: order of trees is important!!
80
                            trees(i) = ParseFile(consoleOutput, parseOptions, scriptParseOptions, hadErrors, sourceFiles(i), errorLogger)
81
                        End Sub))
P
Pilchie 已提交
82 83 84
            Else
                For i = 0 To sourceFiles.Length - 1
                    ' NOTE: order of trees is important!!
85
                    trees(i) = ParseFile(consoleOutput, parseOptions, scriptParseOptions, hadErrors, sourceFiles(i), errorLogger)
P
Pilchie 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
                Next
            End If

            ' If there were any errors while trying to read files, then exit.
            If hadErrors Then
                Return Nothing
            End If

            If Arguments.TouchedFilesPath IsNot Nothing Then
                For Each file In sourceFiles
                    touchedFilesLogger.AddRead(file.Path)
                Next
            End If

            Dim diagnostics = New List(Of DiagnosticInfo)()

102
            Dim assemblyIdentityComparer = DesktopAssemblyIdentityComparer.Default
103
            Dim referenceDirectiveResolver As MetadataFileReferenceResolver = Nothing
104
            Dim metadataProvider As MetadataFileReferenceProvider = GetMetadataProvider()
P
Pilchie 已提交
105

106 107
            Dim externalReferenceResolver = GetExternalMetadataResolver(touchedFilesLogger)
            Dim resolvedReferences = ResolveMetadataReferences(externalReferenceResolver, metadataProvider, diagnostics, assemblyIdentityComparer, touchedFilesLogger, referenceDirectiveResolver)
108

109
            If ReportErrors(diagnostics, consoleOutput, errorLogger) Then
P
Pilchie 已提交
110 111 112 113 114 115 116
                Return Nothing
            End If

            If Arguments.OutputLevel = OutputLevel.Verbose Then
                PrintReferences(resolvedReferences, consoleOutput)
            End If

117 118
            Dim strongNameProvider = New LoggingStrongNameProvider(Arguments.KeyFileSearchPaths, touchedFilesLogger)
            Dim xmlFileResolver = New LoggingXmlFileResolver(Arguments.BaseDirectory, touchedFilesLogger)
119 120

            ' TODO: support for #load search paths
121
            Dim sourceFileResolver = New LoggingSourceFileResolver(ImmutableArray(Of String).Empty, Arguments.BaseDirectory, touchedFilesLogger)
P
Pilchie 已提交
122

A
angocke 已提交
123
            Dim result = VisualBasicCompilation.Create(
P
Pilchie 已提交
124 125 126 127
                 Arguments.CompilationName,
                 trees,
                 resolvedReferences,
                 Arguments.CompilationOptions.
128
                     WithMetadataReferenceResolver(New AssemblyReferenceResolver(referenceDirectiveResolver, metadataProvider)).
129
                     WithAssemblyIdentityComparer(assemblyIdentityComparer).
130 131 132
                     WithStrongNameProvider(strongNameProvider).
                     WithXmlReferenceResolver(xmlFileResolver).
                     WithSourceReferenceResolver(sourceFileResolver))
P
Pilchie 已提交
133 134 135 136 137 138 139

            Return result
        End Function

        Private Sub PrintReferences(resolvedReferences As List(Of MetadataReference), consoleOutput As TextWriter)
            For Each reference In resolvedReferences
                If reference.Properties.Kind = MetadataImageKind.Module Then
140
                    consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_MSG_ADDMODULE, Culture), reference.Display)
P
Pilchie 已提交
141
                ElseIf reference.Properties.EmbedInteropTypes Then
142
                    consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_MSG_ADDLINKREFERENCE, Culture), reference.Display)
P
Pilchie 已提交
143
                Else
144
                    consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_MSG_ADDREFERENCE, Culture), reference.Display)
P
Pilchie 已提交
145 146 147 148 149 150
                End If
            Next

            consoleOutput.WriteLine()
        End Sub

151
        Protected Overrides Sub PrintError(Diagnostic As DiagnosticInfo, consoleOutput As TextWriter)
152 153 154 155
            consoleOutput.Write(VisualBasicCompiler.VbcCommandLinePrefix)
            consoleOutput.WriteLine(Diagnostic.ToString(Culture))
        End Sub

P
Pilchie 已提交
156 157 158 159 160 161 162 163 164 165 166 167 168 169
        Friend Overrides Function SuppressDefaultResponseFile(args As IEnumerable(Of String)) As Boolean
            For Each arg In args
                Select Case arg.ToLowerInvariant
                    Case "/noconfig", "-noconfig", "/nostdlib", "-nostdlib"
                        Return True
                End Select
            Next
            Return False
        End Function

        ''' <summary>
        ''' Print compiler logo
        ''' </summary>
        ''' <param name="consoleOutput"></param>
J
Jared Parsons 已提交
170
        Public Overrides Sub PrintLogo(consoleOutput As TextWriter)
171
            consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_LogoLine1, Culture), GetToolName(), GetAssemblyFileVersion())
172
            consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_LogoLine2, Culture))
P
Pilchie 已提交
173 174 175
            consoleOutput.WriteLine()
        End Sub

176 177 178 179
        Friend Overrides Function GetToolName() As String
            Return ErrorFactory.IdToString(ERRID.IDS_ToolName, Culture)
        End Function

P
Pilchie 已提交
180 181 182 183
        ''' <summary>
        ''' Print Commandline help message (up to 80 English characters per line)
        ''' </summary>
        ''' <param name="consoleOutput"></param>
J
Jared Parsons 已提交
184
        Public Overrides Sub PrintHelp(consoleOutput As TextWriter)
185
            consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_VBCHelp, Culture))
P
Pilchie 已提交
186
        End Sub
187 188 189 190

        Protected Overrides Function TryGetCompilerDiagnosticCode(diagnosticId As String, ByRef code As UInteger) As Boolean
            Return CommonCompiler.TryGetCompilerDiagnosticCode(diagnosticId, "BC", code)
        End Function
191

192
        Protected Overrides Function ResolveAnalyzersFromArguments(diagnostics As List(Of DiagnosticInfo), messageProvider As CommonMessageProvider, touchedFiles As TouchedFileLogger) As ImmutableArray(Of DiagnosticAnalyzer)
J
Jared Parsons 已提交
193
            Return Arguments.ResolveAnalyzersFromArguments(LanguageNames.VisualBasic, diagnostics, messageProvider, touchedFiles, AddressOf LoadAssembly)
194
        End Function
P
Pilchie 已提交
195 196 197
    End Class
End Namespace