diff --git a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs index 86c13da0cf90b10abe43c49f0aa3f0e8f64420fb..6bab02a2d4c8b8b806239fc79b5627f6ca976517 100644 --- a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs +++ b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs @@ -964,6 +964,111 @@ public void Target_SimpleTests() parsedArgs.Errors.Verify(Diagnostic(ErrorCode.ERR_BadSwitch).WithArguments("/TARGET-:")); } + [Fact] + public void Target_SimpleTestsNoSource() + { + var parsedArgs = DefaultParse(new[] { "/target:exe"}, _baseDirectory); + parsedArgs.Errors.Verify( + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1) ); + Assert.Equal(OutputKind.ConsoleApplication, parsedArgs.CompilationOptions.OutputKind); + + parsedArgs = DefaultParse(new[] { "/t:module"}, _baseDirectory); + parsedArgs.Errors.Verify( + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1) ); + Assert.Equal(OutputKind.NetModule, parsedArgs.CompilationOptions.OutputKind); + + parsedArgs = DefaultParse(new[] { "/target:library"}, _baseDirectory); + parsedArgs.Errors.Verify( + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1) ); + Assert.Equal(OutputKind.DynamicallyLinkedLibrary, parsedArgs.CompilationOptions.OutputKind); + + parsedArgs = DefaultParse(new[] { "/TARGET:winexe"}, _baseDirectory); + parsedArgs.Errors.Verify( + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1) ); + Assert.Equal(OutputKind.WindowsApplication, parsedArgs.CompilationOptions.OutputKind); + + parsedArgs = DefaultParse(new[] { "/target:appcontainerexe"}, _baseDirectory); + parsedArgs.Errors.Verify( + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1) ); + Assert.Equal(OutputKind.WindowsRuntimeApplication, parsedArgs.CompilationOptions.OutputKind); + + parsedArgs = DefaultParse(new[] { "/target:winmdobj"}, _baseDirectory); + parsedArgs.Errors.Verify( + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1) ); + Assert.Equal(OutputKind.WindowsRuntimeMetadata, parsedArgs.CompilationOptions.OutputKind); + + parsedArgs = DefaultParse(new[] { "/target:winexe", "/T:exe", "/target:module"}, _baseDirectory); + parsedArgs.Errors.Verify( + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1) ); + Assert.Equal(OutputKind.NetModule, parsedArgs.CompilationOptions.OutputKind); + + parsedArgs = DefaultParse(new[] { "/t"}, _baseDirectory); + parsedArgs.Errors.Verify( + // error CS2007: Unrecognized option: '/t' + Diagnostic(ErrorCode.ERR_BadSwitch).WithArguments("/t").WithLocation(1, 1), + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1) ); + + parsedArgs = DefaultParse(new[] { "/target:"}, _baseDirectory); + parsedArgs.Errors.Verify( + // error CS2019: Invalid target type for /target: must specify 'exe', 'winexe', 'library', or 'module' + Diagnostic(ErrorCode.FTL_InvalidTarget).WithLocation(1, 1), + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1)); + + parsedArgs = DefaultParse(new[] { "/target:xyz"}, _baseDirectory); + parsedArgs.Errors.Verify( + // error CS2019: Invalid target type for /target: must specify 'exe', 'winexe', 'library', or 'module' + Diagnostic(ErrorCode.FTL_InvalidTarget).WithLocation(1, 1), + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1)); + + parsedArgs = DefaultParse(new[] { "/T+"}, _baseDirectory); + parsedArgs.Errors.Verify( + // error CS2007: Unrecognized option: '/T+' + Diagnostic(ErrorCode.ERR_BadSwitch).WithArguments("/T+").WithLocation(1, 1), + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1)); + + parsedArgs = DefaultParse(new[] { "/TARGET-:"}, _baseDirectory); + parsedArgs.Errors.Verify( + // error CS2007: Unrecognized option: '/TARGET-:' + Diagnostic(ErrorCode.ERR_BadSwitch).WithArguments("/TARGET-:").WithLocation(1, 1), + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1)); + } + [Fact] public void ModuleManifest() { diff --git a/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCommandLineParser.vb b/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCommandLineParser.vb index 87aef2db8765bd432c7ac1a5c17ac607083bf61d..6d3b4bd6d5df8f8ea666cf456d118acf229d1e5d 100644 --- a/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCommandLineParser.vb +++ b/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCommandLineParser.vb @@ -1138,7 +1138,7 @@ lVbRuntimePlus: specificDiagnosticOptions(item.Key) = item.Value Next - If Not IsScriptRunner AndAlso Not hasSourceFiles AndAlso managedResources.IsEmpty() AndAlso outputKind.IsApplication Then + If Not IsScriptRunner AndAlso Not hasSourceFiles AndAlso managedResources.IsEmpty() Then ' VB displays help when there is nothing specified on the command line If flattenedArgs.Any Then AddDiagnostic(diagnostics, ERRID.ERR_NoSources) diff --git a/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb b/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb index 4baac0481e0c3d8df02ce60de7756105c2e11b0c..da73a9dd11c0684d064ee981e2874658c2dd5a64 100644 --- a/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb +++ b/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb @@ -1736,12 +1736,12 @@ a.vb outWriter = New StringWriter() exitCode = New MockVisualBasicCompiler(Nothing, folder.Path, {"/nologo", "/preferreduilang:en", "/t:library", "/recurse: . ", "/out:abc.dll"}).Run(outWriter, Nothing) Assert.Equal(1, exitCode) - Assert.Equal("vbc : error BC2014: the value ' .' is invalid for option 'recurse'", outWriter.ToString().Trim().Replace(vbCrLf, "|")) + Assert.Equal("vbc : error BC2014: the value ' .' is invalid for option 'recurse'|vbc : error BC2008: no input sources specified", outWriter.ToString().Trim().Replace(vbCrLf, "|")) outWriter = New StringWriter() exitCode = New MockVisualBasicCompiler(Nothing, folder.Path, {"/nologo", "/preferreduilang:en", "/t:library", "/recurse:./.", "/out:abc.dll"}).Run(outWriter, Nothing) Assert.Equal(1, exitCode) - Assert.Equal("vbc : error BC2014: the value './.' is invalid for option 'recurse'", outWriter.ToString().Trim().Replace(vbCrLf, "|")) + Assert.Equal("vbc : error BC2014: the value './.' is invalid for option 'recurse'|vbc : error BC2008: no input sources specified", outWriter.ToString().Trim().Replace(vbCrLf, "|")) Dim args As VisualBasicCommandLineArguments Dim resolvedSourceFiles As String() @@ -2189,6 +2189,62 @@ a.vb parsedArgs.Errors.Verify(Diagnostic(ERRID.WRN_BadSwitch).WithArguments("/TARGET-:")) ' TODO: Dev11 reports ERR_ArgumentRequired End Sub + + Public Sub Target_SimpleTestsNoSourceFile() + Dim parsedArgs = DefaultParse({"/target:exe"}, _baseDirectory) + parsedArgs.Errors.Verify(Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) + Assert.Equal(OutputKind.ConsoleApplication, parsedArgs.CompilationOptions.OutputKind) + + parsedArgs = DefaultParse({"/t:module"}, _baseDirectory) + parsedArgs.Errors.Verify(Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) + Assert.Equal(OutputKind.NetModule, parsedArgs.CompilationOptions.OutputKind) + + parsedArgs = DefaultParse({"/target:library"}, _baseDirectory) + parsedArgs.Errors.Verify(Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) + Assert.Equal(OutputKind.DynamicallyLinkedLibrary, parsedArgs.CompilationOptions.OutputKind) + + parsedArgs = DefaultParse({"/TARGET:winexe"}, _baseDirectory) + parsedArgs.Errors.Verify(Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) + Assert.Equal(OutputKind.WindowsApplication, parsedArgs.CompilationOptions.OutputKind) + + parsedArgs = DefaultParse({"/target:winmdobj"}, _baseDirectory) + parsedArgs.Errors.Verify(Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) + Assert.Equal(OutputKind.WindowsRuntimeMetadata, parsedArgs.CompilationOptions.OutputKind) + + parsedArgs = DefaultParse({"/target:appcontainerexe"}, _baseDirectory) + parsedArgs.Errors.Verify(Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) + Assert.Equal(OutputKind.WindowsRuntimeApplication, parsedArgs.CompilationOptions.OutputKind) + + parsedArgs = DefaultParse({"/target:winexe", "/T:exe", "/target:module"}, _baseDirectory) + parsedArgs.Errors.Verify(Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) + Assert.Equal(OutputKind.NetModule, parsedArgs.CompilationOptions.OutputKind) + + parsedArgs = DefaultParse({"/t"}, _baseDirectory) + parsedArgs.Errors.Verify( + Diagnostic(ERRID.ERR_ArgumentRequired).WithArguments("t", ":exe|winexe|library|module|appcontainerexe|winmdobj"), + Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) + + parsedArgs = DefaultParse({"/target:"}, _baseDirectory) + parsedArgs.Errors.Verify( + Diagnostic(ERRID.ERR_ArgumentRequired).WithArguments("target", ":exe|winexe|library|module|appcontainerexe|winmdobj"), + Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) + + parsedArgs = DefaultParse({"/target:xyz"}, _baseDirectory) + parsedArgs.Errors.Verify( + Diagnostic(ERRID.ERR_InvalidSwitchValue).WithArguments("target", "xyz"), + Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) + + parsedArgs = DefaultParse({"/T+"}, _baseDirectory) + parsedArgs.Errors.Verify( + Diagnostic(ERRID.WRN_BadSwitch).WithArguments("/T+"), + Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) ' TODO: Dev11 reports ERR_ArgumentRequired + + parsedArgs = DefaultParse({"/TARGET-:"}, _baseDirectory) + parsedArgs.Errors.Verify( + Diagnostic(ERRID.WRN_BadSwitch).WithArguments("/TARGET-:"), + Diagnostic(ERRID.ERR_NoSources).WithLocation(1, 1)) ' TODO: Dev11 reports ERR_ArgumentRequired + End Sub + Public Sub Utf8Output() Dim parsedArgs = DefaultParse({"/utf8output", "a.vb"}, _baseDirectory)