提交 e24b1fac 编写于 作者: O Omar Tawfik

Tests for parse options

上级 12f88a56
...@@ -61,13 +61,13 @@ public override IEnumerable<string> PreprocessorSymbolNames ...@@ -61,13 +61,13 @@ public override IEnumerable<string> PreprocessorSymbolNames
DocumentationMode documentationMode, DocumentationMode documentationMode,
SourceCodeKind kind, SourceCodeKind kind,
IEnumerable<string> preprocessorSymbols, IEnumerable<string> preprocessorSymbols,
ImmutableDictionary<string, string> features) IReadOnlyDictionary<string, string> features)
: base(kind, documentationMode) : base(kind, documentationMode)
{ {
this.SpecifiedLanguageVersion = languageVersion; this.SpecifiedLanguageVersion = languageVersion;
this.LanguageVersion = languageVersion.MapSpecifiedToEffectiveVersion(); this.LanguageVersion = languageVersion.MapSpecifiedToEffectiveVersion();
this.PreprocessorSymbols = preprocessorSymbols.ToImmutableArrayOrEmpty(); this.PreprocessorSymbols = preprocessorSymbols.ToImmutableArrayOrEmpty();
_features = features ?? ImmutableDictionary<string, string>.Empty; _features = features?.ToImmutableDictionary() ?? ImmutableDictionary<string, string>.Empty;
} }
private CSharpParseOptions(CSharpParseOptions other) : this( private CSharpParseOptions(CSharpParseOptions other) : this(
...@@ -75,7 +75,7 @@ public override IEnumerable<string> PreprocessorSymbolNames ...@@ -75,7 +75,7 @@ public override IEnumerable<string> PreprocessorSymbolNames
documentationMode: other.DocumentationMode, documentationMode: other.DocumentationMode,
kind: other.Kind, kind: other.Kind,
preprocessorSymbols: other.PreprocessorSymbols, preprocessorSymbols: other.PreprocessorSymbols,
features: other.Features.ToImmutableDictionary()) features: other.Features)
{ {
} }
...@@ -180,14 +180,18 @@ internal override void ValidateOptions(ArrayBuilder<Diagnostic> builder) ...@@ -180,14 +180,18 @@ internal override void ValidateOptions(ArrayBuilder<Diagnostic> builder)
// Validate LanguageVersion not SpecifiedLanguageVersion, after Latest/Default has been converted: // Validate LanguageVersion not SpecifiedLanguageVersion, after Latest/Default has been converted:
if (!LanguageVersion.IsValid()) if (!LanguageVersion.IsValid())
{ {
builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadLanguageVersion, LanguageVersion)); builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadLanguageVersion, LanguageVersion.ToString()));
} }
if (!PreprocessorSymbols.IsDefaultOrEmpty) if (!PreprocessorSymbols.IsDefaultOrEmpty)
{ {
foreach (var symbol in PreprocessorSymbols) foreach (var symbol in PreprocessorSymbols)
{ {
if (!SyntaxFacts.IsValidIdentifier(symbol)) if (symbol == null)
{
builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.WRN_DefineIdentifierRequired, "null"));
}
else if (!SyntaxFacts.IsValidIdentifier(symbol))
{ {
builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.WRN_DefineIdentifierRequired, symbol)); builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.WRN_DefineIdentifierRequired, symbol));
} }
......
...@@ -1879,15 +1879,6 @@ internal class CSharpResources { ...@@ -1879,15 +1879,6 @@ internal class CSharpResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Provided Source Code Kind is unsupported or invalid: &apos;{0}&apos;..
/// </summary>
internal static string ERR_BadSourceCodeKind {
get {
return ResourceManager.GetString("ERR_BadSourceCodeKind", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Parameters or locals of type &apos;{0}&apos; cannot be declared in async methods or lambda expressions.. /// Looks up a localized string similar to Parameters or locals of type &apos;{0}&apos; cannot be declared in async methods or lambda expressions..
/// </summary> /// </summary>
...@@ -11114,6 +11105,15 @@ internal class CSharpResources { ...@@ -11114,6 +11105,15 @@ internal class CSharpResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Provided Source Code Kind is unsupported or invalid: &apos;{0}&apos;..
/// </summary>
internal static string WRN_BadSourceCodeKind {
get {
return ResourceManager.GetString("WRN_BadSourceCodeKind", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to The language name &apos;{0}&apos; is invalid.. /// Looks up a localized string similar to The language name &apos;{0}&apos; is invalid..
/// </summary> /// </summary>
...@@ -12132,7 +12132,7 @@ internal class CSharpResources { ...@@ -12132,7 +12132,7 @@ internal class CSharpResources {
} }
/// <summary> /// <summary>
/// Looks up a localized string similar to Invalid value for &apos;/define&apos;; &apos;{0}&apos; is not a valid identifier. /// Looks up a localized string similar to Invalid value for a preprocessing symbol; &apos;{0}&apos; is not a valid identifier.
/// </summary> /// </summary>
internal static string WRN_DefineIdentifierRequired { internal static string WRN_DefineIdentifierRequired {
get { get {
...@@ -12140,15 +12140,6 @@ internal class CSharpResources { ...@@ -12140,15 +12140,6 @@ internal class CSharpResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Invalid value for &apos;/define&apos;; not a valid identifier.
/// </summary>
internal static string WRN_DefineIdentifierRequired_Title {
get {
return ResourceManager.GetString("WRN_DefineIdentifierRequired_Title", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Delay signing was specified and requires a public key, but no public key was specified. /// Looks up a localized string similar to Delay signing was specified and requires a public key, but no public key was specified.
/// </summary> /// </summary>
......
...@@ -3321,10 +3321,7 @@ Give the compiler some way to differentiate the methods. For example, you can gi ...@@ -3321,10 +3321,7 @@ Give the compiler some way to differentiate the methods. For example, you can gi
<value>'id#' syntax is no longer supported. Use '$id' instead.</value> <value>'id#' syntax is no longer supported. Use '$id' instead.</value>
</data> </data>
<data name="WRN_DefineIdentifierRequired" xml:space="preserve"> <data name="WRN_DefineIdentifierRequired" xml:space="preserve">
<value>Invalid value for '/define'; '{0}' is not a valid identifier</value> <value>Invalid value for a preprocessing symbol; '{0}' is not a valid identifier</value>
</data>
<data name="WRN_DefineIdentifierRequired_Title" xml:space="preserve">
<value>Invalid value for '/define'; not a valid identifier</value>
</data> </data>
<data name="FTL_OutputFileExists" xml:space="preserve"> <data name="FTL_OutputFileExists" xml:space="preserve">
<value>Cannot create short filename '{0}' when a long filename with the same short filename already exists</value> <value>Cannot create short filename '{0}' when a long filename with the same short filename already exists</value>
...@@ -5023,7 +5020,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ ...@@ -5023,7 +5020,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="ERR_BadDocumentationMode" xml:space="preserve"> <data name="ERR_BadDocumentationMode" xml:space="preserve">
<value>Provided Documentation Mode is unsupported or invalid: '{0}'.</value> <value>Provided Documentation Mode is unsupported or invalid: '{0}'.</value>
</data> </data>
<data name="ERR_BadSourceCodeKind" xml:space="preserve"> <data name="WRN_BadSourceCodeKind" xml:space="preserve">
<value>Provided Source Code Kind is unsupported or invalid: '{0}'.</value> <value>Provided Source Code Kind is unsupported or invalid: '{0}'.</value>
</data> </data>
<data name="ERR_BadLanguageVersion" xml:space="preserve"> <data name="ERR_BadLanguageVersion" xml:space="preserve">
......
...@@ -1440,7 +1440,7 @@ internal enum ErrorCode ...@@ -1440,7 +1440,7 @@ internal enum ErrorCode
#endregion stragglers for C# 7 #endregion stragglers for C# 7
#region diagnostics for parse options #region diagnostics for parse options
ERR_BadSourceCodeKind = 8190, WRN_BadSourceCodeKind = 8190,
ERR_BadDocumentationMode = 8191, ERR_BadDocumentationMode = 8191,
ERR_BadLanguageVersion = 8192, ERR_BadLanguageVersion = 8192,
#endregion #endregion
......
...@@ -317,6 +317,7 @@ internal static int GetWarningLevel(ErrorCode code) ...@@ -317,6 +317,7 @@ internal static int GetWarningLevel(ErrorCode code)
case ErrorCode.WRN_AlignmentMagnitude: case ErrorCode.WRN_AlignmentMagnitude:
case ErrorCode.WRN_AttributeIgnoredWhenPublicSigning: case ErrorCode.WRN_AttributeIgnoredWhenPublicSigning:
case ErrorCode.WRN_TupleLiteralNameMismatch: case ErrorCode.WRN_TupleLiteralNameMismatch:
case ErrorCode.WRN_BadSourceCodeKind:
return 1; return 1;
default: default:
return 0; return 0;
......
...@@ -147,7 +147,7 @@ public override ReportDiagnostic GetDiagnosticReport(DiagnosticInfo diagnosticIn ...@@ -147,7 +147,7 @@ public override ReportDiagnostic GetDiagnosticReport(DiagnosticInfo diagnosticIn
public override int ERR_CompileCancelled => (int)ErrorCode.ERR_CompileCancelled; public override int ERR_CompileCancelled => (int)ErrorCode.ERR_CompileCancelled;
// parse options: // parse options:
public override int ERR_BadSourceCodeKind => (int)ErrorCode.ERR_BadSourceCodeKind; public override int WRN_BadSourceCodeKind => (int)ErrorCode.WRN_BadSourceCodeKind;
public override int ERR_BadDocumentationMode => (int)ErrorCode.ERR_BadDocumentationMode; public override int ERR_BadDocumentationMode => (int)ErrorCode.ERR_BadDocumentationMode;
// compilation options: // compilation options:
......
...@@ -1382,7 +1382,7 @@ public void Define() ...@@ -1382,7 +1382,7 @@ public void Define()
var nonCompliant = "def1;;def2;"; var nonCompliant = "def1;;def2;";
parsed = CSharpCommandLineParser.ParseConditionalCompilationSymbols(nonCompliant, out diagnostics); parsed = CSharpCommandLineParser.ParseConditionalCompilationSymbols(nonCompliant, out diagnostics);
diagnostics.Verify( diagnostics.Verify(
// warning CS2029: Invalid value for '/define'; '' is not a valid identifier // warning CS2029: Invalid value for a preprocessing symbol; '' is not a valid identifier
Diagnostic(ErrorCode.WRN_DefineIdentifierRequired).WithArguments("")); Diagnostic(ErrorCode.WRN_DefineIdentifierRequired).WithArguments(""));
Assert.Equal(new[] { "def1", "def2" }, parsed); Assert.Equal(new[] { "def1", "def2" }, parsed);
...@@ -6325,7 +6325,7 @@ public void InvalidDefineSwitch() ...@@ -6325,7 +6325,7 @@ public void InvalidDefineSwitch()
outWriter = new StringWriter(CultureInfo.InvariantCulture); outWriter = new StringWriter(CultureInfo.InvariantCulture);
exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), @"/define:""""" }).Run(outWriter); exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), @"/define:""""" }).Run(outWriter);
Assert.Equal(0, exitCode); Assert.Equal(0, exitCode);
Assert.Equal("warning CS2029: Invalid value for '/define'; '' is not a valid identifier", outWriter.ToString().Trim()); Assert.Equal("warning CS2029: Invalid value for a preprocessing symbol; '' is not a valid identifier", outWriter.ToString().Trim());
outWriter = new StringWriter(CultureInfo.InvariantCulture); outWriter = new StringWriter(CultureInfo.InvariantCulture);
exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), "/define: " }).Run(outWriter); exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), "/define: " }).Run(outWriter);
...@@ -6340,29 +6340,29 @@ public void InvalidDefineSwitch() ...@@ -6340,29 +6340,29 @@ public void InvalidDefineSwitch()
outWriter = new StringWriter(CultureInfo.InvariantCulture); outWriter = new StringWriter(CultureInfo.InvariantCulture);
exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), "/define:,,," }).Run(outWriter); exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), "/define:,,," }).Run(outWriter);
Assert.Equal(0, exitCode); Assert.Equal(0, exitCode);
Assert.Equal("warning CS2029: Invalid value for '/define'; '' is not a valid identifier", outWriter.ToString().Trim()); Assert.Equal("warning CS2029: Invalid value for a preprocessing symbol; '' is not a valid identifier", outWriter.ToString().Trim());
outWriter = new StringWriter(CultureInfo.InvariantCulture); outWriter = new StringWriter(CultureInfo.InvariantCulture);
exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), "/define:,blah,Blah" }).Run(outWriter); exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), "/define:,blah,Blah" }).Run(outWriter);
Assert.Equal(0, exitCode); Assert.Equal(0, exitCode);
Assert.Equal("warning CS2029: Invalid value for '/define'; '' is not a valid identifier", outWriter.ToString().Trim()); Assert.Equal("warning CS2029: Invalid value for a preprocessing symbol; '' is not a valid identifier", outWriter.ToString().Trim());
outWriter = new StringWriter(CultureInfo.InvariantCulture); outWriter = new StringWriter(CultureInfo.InvariantCulture);
exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), "/define:a;;b@" }).Run(outWriter); exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), "/define:a;;b@" }).Run(outWriter);
Assert.Equal(0, exitCode); Assert.Equal(0, exitCode);
Assert.Equal("warning CS2029: Invalid value for '/define'; '' is not a valid identifier", outWriter.ToString().Trim()); Assert.Equal("warning CS2029: Invalid value for a preprocessing symbol; '' is not a valid identifier", outWriter.ToString().Trim());
outWriter = new StringWriter(CultureInfo.InvariantCulture); outWriter = new StringWriter(CultureInfo.InvariantCulture);
exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), "/define:a,b@;" }).Run(outWriter); exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), "/define:a,b@;" }).Run(outWriter);
Assert.Equal(0, exitCode); Assert.Equal(0, exitCode);
Assert.Equal("warning CS2029: Invalid value for '/define'; 'b@' is not a valid identifier", outWriter.ToString().Trim()); Assert.Equal("warning CS2029: Invalid value for a preprocessing symbol; 'b@' is not a valid identifier", outWriter.ToString().Trim());
//Bug 531612 - Native would normally not give the 2nd warning //Bug 531612 - Native would normally not give the 2nd warning
outWriter = new StringWriter(CultureInfo.InvariantCulture); outWriter = new StringWriter(CultureInfo.InvariantCulture);
exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), @"/define:OE_WIN32=-1:LANG_HOST_EN=-1:LANG_OE_EN=-1:LANG_PRJ_EN=-1:HOST_COM20SDKEVERETT=-1:EXEMODE=-1:OE_NT5=-1:Win32=-1", @"/d:TRACE=TRUE,DEBUG=TRUE" }).Run(outWriter); exitCode = new MockCSharpCompiler(null, _baseDirectory, new[] { "/nologo", "/preferreduilang:en", "/t:library", src.ToString(), @"/define:OE_WIN32=-1:LANG_HOST_EN=-1:LANG_OE_EN=-1:LANG_PRJ_EN=-1:HOST_COM20SDKEVERETT=-1:EXEMODE=-1:OE_NT5=-1:Win32=-1", @"/d:TRACE=TRUE,DEBUG=TRUE" }).Run(outWriter);
Assert.Equal(0, exitCode); Assert.Equal(0, exitCode);
Assert.Equal(@"warning CS2029: Invalid value for '/define'; 'OE_WIN32=-1:LANG_HOST_EN=-1:LANG_OE_EN=-1:LANG_PRJ_EN=-1:HOST_COM20SDKEVERETT=-1:EXEMODE=-1:OE_NT5=-1:Win32=-1' is not a valid identifier Assert.Equal(@"warning CS2029: Invalid value for a preprocessing symbol; 'OE_WIN32=-1:LANG_HOST_EN=-1:LANG_OE_EN=-1:LANG_PRJ_EN=-1:HOST_COM20SDKEVERETT=-1:EXEMODE=-1:OE_NT5=-1:Win32=-1' is not a valid identifier
warning CS2029: Invalid value for '/define'; 'TRACE=TRUE' is not a valid identifier", outWriter.ToString().Trim()); warning CS2029: Invalid value for a preprocessing symbol; 'TRACE=TRUE' is not a valid identifier", outWriter.ToString().Trim());
CleanupAllGeneratedFiles(src.Path); CleanupAllGeneratedFiles(src.Path);
} }
......
...@@ -52,5 +52,189 @@ public void TestFieldsForEqualsAndGetHashCode() ...@@ -52,5 +52,189 @@ public void TestFieldsForEqualsAndGetHashCode()
"PreprocessorSymbols", "PreprocessorSymbols",
"SpecifiedLanguageVersion"); "SpecifiedLanguageVersion");
} }
[Fact]
public void SpecifiedKindIsMappedCorrectly()
{
var options = new CSharpParseOptions(kind: SourceCodeKind.Regular);
Assert.Equal(SourceCodeKind.Regular, options.Kind);
Assert.Equal(SourceCodeKind.Regular, options.SpecifiedKind);
options.Errors.Verify();
options = new CSharpParseOptions(kind: SourceCodeKind.Script);
Assert.Equal(SourceCodeKind.Script, options.Kind);
Assert.Equal(SourceCodeKind.Script, options.SpecifiedKind);
options.Errors.Verify();
#pragma warning disable CS0618 // SourceCodeKind.Interactive is obsolete
options = new CSharpParseOptions(kind: SourceCodeKind.Interactive);
Assert.Equal(SourceCodeKind.Script, options.Kind);
Assert.Equal(SourceCodeKind.Interactive, options.SpecifiedKind);
#pragma warning restore CS0618 // SourceCodeKind.Interactive is obsolete
options.Errors.Verify(
// error CS8190: Provided Source Code Kind is unsupported or invalid: 'Interactive'.
Diagnostic(ErrorCode.WRN_BadSourceCodeKind).WithArguments("Interactive").WithLocation(1, 1));
}
[Fact]
public void TwoOptionsWithDifferentSpecifiedKindShouldNotHaveTheSameHashCodes()
{
var options1 = new CSharpParseOptions(kind: SourceCodeKind.Script);
var options2 = new CSharpParseOptions(kind: SourceCodeKind.Script);
Assert.Equal(options1.GetHashCode(), options2.GetHashCode());
// They both map internally to SourceCodeKind.Script
#pragma warning disable CS0618 // SourceCodeKind.Interactive is obsolete
options1 = new CSharpParseOptions(kind: SourceCodeKind.Script);
options2 = new CSharpParseOptions(kind: SourceCodeKind.Interactive);
#pragma warning restore CS0618 // SourceCodeKind.Interactive is obsolete
Assert.NotEqual(options1.GetHashCode(), options2.GetHashCode());
}
[Fact]
public void TwoOptionsWithDifferentSpecifiedKindShouldNotBeEqual()
{
var options1 = new CSharpParseOptions(kind: SourceCodeKind.Script);
var options2 = new CSharpParseOptions(kind: SourceCodeKind.Script);
Assert.True(options1.Equals(options2));
// They both map internally to SourceCodeKind.Script
#pragma warning disable CS0618 // SourceCodeKind.Interactive is obsolete
options1 = new CSharpParseOptions(kind: SourceCodeKind.Script);
options2 = new CSharpParseOptions(kind: SourceCodeKind.Interactive);
#pragma warning restore CS0618 // SourceCodeKind.Interactive is obsolete
Assert.False(options1.Equals(options2));
}
[Fact]
public void BadSourceCodeKindShouldProduceDiagnostics()
{
#pragma warning disable CS0618 // Type or member is obsolete
var options = new CSharpParseOptions(kind: SourceCodeKind.Interactive);
#pragma warning restore CS0618 // Type or member is obsolete
options.Errors.Verify(
// error CS8190: Provided Source Code Kind is unsupported or invalid: 'Interactive'.
Diagnostic(ErrorCode.WRN_BadSourceCodeKind).WithArguments("Interactive").WithLocation(1, 1));
}
[Fact]
public void BadDocumentationModeShouldProduceDiagnostics()
{
var options = new CSharpParseOptions(documentationMode: unchecked((DocumentationMode)100));
options.Errors.Verify(
// error CS8191: Provided Documentation Mode is unsupported or invalid: '100'.
Diagnostic(ErrorCode.ERR_BadDocumentationMode).WithArguments("100").WithLocation(1, 1));
}
[Fact]
public void BadLanguageVersionShouldProduceDiagnostics()
{
var options = new CSharpParseOptions(languageVersion: unchecked((LanguageVersion)10000));
options.Errors.Verify(
// error CS8191: Provided Language Version is unsupported or invalid: '10000'.
Diagnostic(ErrorCode.ERR_BadLanguageVersion).WithArguments("10000").WithLocation(1, 1));
}
[Fact]
public void BadPreProcessorSymbolsShouldProduceDiagnostics()
{
var options = new CSharpParseOptions(preprocessorSymbols: new[] { "test", "1" });
options.Errors.Verify(
// warning CS2029: Invalid value for a preprocessing symbol; '1' is not a valid identifier
Diagnostic(ErrorCode.WRN_DefineIdentifierRequired).WithArguments("1").WithLocation(1, 1));
}
[Fact]
public void BadSourceCodeKindShouldProduceDiagnostics_WithVariation()
{
#pragma warning disable CS0618 // Type or member is obsolete
var options = new CSharpParseOptions().WithKind(SourceCodeKind.Interactive);
#pragma warning restore CS0618 // Type or member is obsolete
options.Errors.Verify(
// error CS8190: Provided Source Code Kind is unsupported or invalid: 'Interactive'.
Diagnostic(ErrorCode.WRN_BadSourceCodeKind).WithArguments("Interactive").WithLocation(1, 1));
}
[Fact]
public void BadDocumentationModeShouldProduceDiagnostics_WithVariation()
{
var options = new CSharpParseOptions().WithDocumentationMode(unchecked((DocumentationMode)100));
options.Errors.Verify(
// error CS8191: Provided Documentation Mode is unsupported or invalid: '100'.
Diagnostic(ErrorCode.ERR_BadDocumentationMode).WithArguments("100").WithLocation(1, 1));
}
[Fact]
public void BadLanguageVersionShouldProduceDiagnostics_WithVariation()
{
var options = new CSharpParseOptions().WithLanguageVersion(unchecked((LanguageVersion)10000));
options.Errors.Verify(
// error CS8191: Provided Language Version is unsupported or invalid: '10000'.
Diagnostic(ErrorCode.ERR_BadLanguageVersion).WithArguments("10000").WithLocation(1, 1));
}
[Fact]
public void BadPreProcessorSymbolsShouldProduceDiagnostics_EmptyString()
{
var options = new CSharpParseOptions().WithPreprocessorSymbols(new[] { "" });
options.Errors.Verify(
// warning CS2029: Invalid value for a preprocessing symbol; '' is not a valid identifier
Diagnostic(ErrorCode.WRN_DefineIdentifierRequired).WithArguments("").WithLocation(1, 1));
}
[Fact]
public void BadPreProcessorSymbolsShouldProduceDiagnostics_WhiteSpacetring()
{
var options = new CSharpParseOptions().WithPreprocessorSymbols(new[] { " " });
options.Errors.Verify(
// warning CS2029: Invalid value for a preprocessing symbol; ' ' is not a valid identifier
Diagnostic(ErrorCode.WRN_DefineIdentifierRequired).WithArguments(" ").WithLocation(1, 1));
}
[Fact]
public void BadPreProcessorSymbolsShouldProduceDiagnostics_SymbolWithDots()
{
var options = new CSharpParseOptions().WithPreprocessorSymbols(new[] { "Good", "Bad.Symbol" });
options.Errors.Verify(
// warning CS2029: Invalid value for a preprocessing symbol; 'Bad.Symbol' is not a valid identifier
Diagnostic(ErrorCode.WRN_DefineIdentifierRequired).WithArguments("Bad.Symbol").WithLocation(1, 1));
}
[Fact]
public void BadPreProcessorSymbolsShouldProduceDiagnostics_SymbolWithSlashes()
{
var options = new CSharpParseOptions().WithPreprocessorSymbols(new[] { "Good", "Bad\\Symbol" });
options.Errors.Verify(
// warning CS2029: Invalid value for a preprocessing symbol; 'Bad\Symbol' is not a valid identifier
Diagnostic(ErrorCode.WRN_DefineIdentifierRequired).WithArguments("Bad\\Symbol").WithLocation(1, 1));
}
[Fact]
public void BadPreProcessorSymbolsShouldProduceDiagnostics_NullSymbol()
{
var options = new CSharpParseOptions().WithPreprocessorSymbols(new[] { "Good", null });
options.Errors.Verify(
// warning CS2029: Invalid value for a preprocessing symbol; 'null' is not a valid identifier
Diagnostic(ErrorCode.WRN_DefineIdentifierRequired).WithArguments("null").WithLocation(1, 1));
}
} }
} }
...@@ -78,12 +78,12 @@ internal void ValidateOptions(ArrayBuilder<Diagnostic> builder, CommonMessagePro ...@@ -78,12 +78,12 @@ internal void ValidateOptions(ArrayBuilder<Diagnostic> builder, CommonMessagePro
// Validate SpecifiedKind not Kind, to catch deprecated specified kinds: // Validate SpecifiedKind not Kind, to catch deprecated specified kinds:
if (!SpecifiedKind.IsValid()) if (!SpecifiedKind.IsValid())
{ {
builder.Add(messageProvider.CreateDiagnostic(messageProvider.ERR_BadSourceCodeKind, Location.None, SpecifiedKind)); builder.Add(messageProvider.CreateDiagnostic(messageProvider.WRN_BadSourceCodeKind, Location.None, SpecifiedKind.ToString()));
} }
if (!DocumentationMode.IsValid()) if (!DocumentationMode.IsValid())
{ {
builder.Add(messageProvider.CreateDiagnostic(messageProvider.ERR_BadDocumentationMode, Location.None, DocumentationMode)); builder.Add(messageProvider.CreateDiagnostic(messageProvider.ERR_BadDocumentationMode, Location.None, DocumentationMode.ToString()));
} }
} }
......
...@@ -160,7 +160,7 @@ public DiagnosticInfo FilterDiagnosticInfo(DiagnosticInfo diagnosticInfo, Compil ...@@ -160,7 +160,7 @@ public DiagnosticInfo FilterDiagnosticInfo(DiagnosticInfo diagnosticInfo, Compil
public abstract int ERR_CompileCancelled { get; } public abstract int ERR_CompileCancelled { get; }
// parse options: // parse options:
public abstract int ERR_BadSourceCodeKind { get; } public abstract int WRN_BadSourceCodeKind { get; }
public abstract int ERR_BadDocumentationMode { get; } public abstract int ERR_BadDocumentationMode { get; }
// compilation options: // compilation options:
......
...@@ -1726,7 +1726,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1726,7 +1726,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
ERR_Merge_conflict_marker_encountered = 37284 ERR_Merge_conflict_marker_encountered = 37284
ERR_BadSourceCodeKind = 37285 WRN_BadSourceCodeKind = 37285
ERR_BadDocumentationMode = 37286 ERR_BadDocumentationMode = 37286
ERR_BadLanguageVersion = 37287 ERR_BadLanguageVersion = 37287
......
...@@ -234,9 +234,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -234,9 +234,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' parse options: ' parse options:
Public Overrides ReadOnly Property ERR_BadSourceCodeKind As Integer Public Overrides ReadOnly Property WRN_BadSourceCodeKind As Integer
Get Get
Return ERRID.ERR_BadSourceCodeKind Return ERRID.WRN_BadSourceCodeKind
End Get End Get
End Property End Property
......
...@@ -1503,15 +1503,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1503,15 +1503,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get End Get
End Property End Property
'''<summary>
''' Looks up a localized string similar to Provided Source Code Kind is unsupported or invalid: &apos;{0}&apos;..
'''</summary>
Friend ReadOnly Property ERR_BadSourceCodeKind() As String
Get
Return ResourceManager.GetString("ERR_BadSourceCodeKind", resourceCulture)
End Get
End Property
'''<summary> '''<summary>
''' Looks up a localized string similar to &apos;{0}&apos; and &apos;{1}&apos; cannot be combined.. ''' Looks up a localized string similar to &apos;{0}&apos; and &apos;{1}&apos; cannot be combined..
'''</summary> '''</summary>
...@@ -12792,6 +12783,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -12792,6 +12783,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get End Get
End Property End Property
'''<summary>
''' Looks up a localized string similar to Provided Source Code Kind is unsupported or invalid: &apos;{0}&apos;..
'''</summary>
Friend ReadOnly Property WRN_BadSourceCodeKind() As String
Get
Return ResourceManager.GetString("WRN_BadSourceCodeKind", resourceCulture)
End Get
End Property
'''<summary> '''<summary>
''' Looks up a localized string similar to unrecognized option &apos;{0}&apos;; ignored. ''' Looks up a localized string similar to unrecognized option &apos;{0}&apos;; ignored.
'''</summary> '''</summary>
......
...@@ -5473,7 +5473,7 @@ ...@@ -5473,7 +5473,7 @@
<data name="ERR_BadLanguageVersion" xml:space="preserve"> <data name="ERR_BadLanguageVersion" xml:space="preserve">
<value>Provided Language Version is unsupported or invalid: '{0}'.</value> <value>Provided Language Version is unsupported or invalid: '{0}'.</value>
</data> </data>
<data name="ERR_BadSourceCodeKind" xml:space="preserve"> <data name="WRN_BadSourceCodeKind" xml:space="preserve">
<value>Provided Source Code Kind is unsupported or invalid: '{0}'.</value> <value>Provided Source Code Kind is unsupported or invalid: '{0}'.</value>
</data> </data>
</root> </root>
\ No newline at end of file
...@@ -54,7 +54,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -54,7 +54,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
_specifiedLanguageVersion = languageVersion _specifiedLanguageVersion = languageVersion
_languageVersion = languageVersion.MapSpecifiedToEffectiveVersion _languageVersion = languageVersion.MapSpecifiedToEffectiveVersion
_preprocessorSymbols = preprocessorSymbols.ToImmutableArrayOrEmpty _preprocessorSymbols = preprocessorSymbols.ToImmutableArrayOrEmpty
_features = features _features = If(features, ImmutableDictionary(Of String, String).Empty)
End Sub End Sub
Private Sub New(other As VisualBasicParseOptions) Private Sub New(other As VisualBasicParseOptions)
...@@ -245,20 +245,21 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -245,20 +245,21 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' Validate LanguageVersion Not SpecifiedLanguageVersion, after Latest/Default has been converted ' Validate LanguageVersion Not SpecifiedLanguageVersion, after Latest/Default has been converted
If Not LanguageVersion.IsValid Then If Not LanguageVersion.IsValid Then
builder.Add(Diagnostic.Create(MessageProvider.Instance, ERRID.ERR_BadLanguageVersion, LanguageVersion)) builder.Add(Diagnostic.Create(MessageProvider.Instance, ERRID.ERR_BadLanguageVersion, LanguageVersion.ToString))
End If End If
If Not PreprocessorSymbols.IsDefaultOrEmpty Then If Not PreprocessorSymbols.IsDefaultOrEmpty Then
For Each symbol In PreprocessorSymbols For Each symbol In PreprocessorSymbols
If Not IsValidIdentifier(symbol.Key) OrElse SyntaxFacts.GetKeywordKind(symbol.Key) <> SyntaxKind.None Then If Not IsValidIdentifier(symbol.Key) OrElse SyntaxFacts.GetKeywordKind(symbol.Key) <> SyntaxKind.None Then
builder.Add(Diagnostic.Create(MessageProvider.Instance, ERRID.ERR_ProjectCCError1, VBResources.ERR_ExpectedIdentifier, symbol.Key)) builder.Add(Diagnostic.Create(MessageProvider.Instance, ERRID.ERR_ProjectCCError1, VBResources.ERR_ExpectedIdentifier, symbol.Key))
End If Else
Debug.Assert(SyntaxFactory.ParseTokens(symbol.Key).Select(Function(t) t.Kind).SequenceEqual({SyntaxKind.IdentifierToken, SyntaxKind.EndOfFileToken})) Debug.Assert(SyntaxFactory.ParseTokens(symbol.Key).Select(Function(t) t.Kind).SequenceEqual({SyntaxKind.IdentifierToken, SyntaxKind.EndOfFileToken}))
Dim constant = InternalSyntax.CConst.TryCreate(symbol.Value) Dim constant = InternalSyntax.CConst.TryCreate(symbol.Value)
If constant Is Nothing Then If constant Is Nothing Then
builder.Add(Diagnostic.Create(MessageProvider.Instance, ERRID.IDS_InvalidPreprocessorConstantType, symbol.Key, symbol.Value.GetType)) builder.Add(Diagnostic.Create(MessageProvider.Instance, ERRID.IDS_InvalidPreprocessorConstantType, symbol.Key, symbol.Value.GetType))
End If
End If End If
Next Next
End If End If
......
...@@ -223,4 +223,154 @@ Public Class VisualBasicParseOptionsTests ...@@ -223,4 +223,154 @@ Public Class VisualBasicParseOptionsTests
"PreprocessorSymbols", "PreprocessorSymbols",
"SpecifiedLanguageVersion") "SpecifiedLanguageVersion")
End Sub End Sub
<Fact>
Public Sub SpecifiedKindIsMappedCorrectly()
Dim options = New VisualBasicParseOptions(kind:=SourceCodeKind.Regular)
Assert.Equal(SourceCodeKind.Regular, options.Kind)
Assert.Equal(SourceCodeKind.Regular, options.SpecifiedKind)
options.Errors.Verify()
options = New VisualBasicParseOptions(kind:=SourceCodeKind.Script)
Assert.Equal(SourceCodeKind.Script, options.Kind)
Assert.Equal(SourceCodeKind.Script, options.SpecifiedKind)
options.Errors.Verify()
#Disable Warning BC40000 ' SourceCodeKind.Interactive is obsolete
options = New VisualBasicParseOptions(kind:=SourceCodeKind.Interactive)
Assert.Equal(SourceCodeKind.Script, options.Kind)
Assert.Equal(SourceCodeKind.Interactive, options.SpecifiedKind)
#Enable Warning BC40000 ' SourceCodeKind.Interactive is obsolete
options.Errors.Verify(Diagnostic(ERRID.WRN_BadSourceCodeKind).WithArguments("Interactive").WithLocation(1, 1))
End Sub
<Fact>
Public Sub TwoOptionsWithDifferentSpecifiedKindShouldNotHaveTheSameHashCodes()
Dim options1 = New VisualBasicParseOptions(kind:=SourceCodeKind.Script)
Dim options2 = New VisualBasicParseOptions(kind:=SourceCodeKind.Script)
Assert.Equal(options1.GetHashCode(), options2.GetHashCode())
' They both map internally to SourceCodeKind.Script
#Disable Warning BC40000 ' SourceCodeKind.Interactive is obsolete
options1 = New VisualBasicParseOptions(kind:=SourceCodeKind.Script)
options2 = New VisualBasicParseOptions(kind:=SourceCodeKind.Interactive)
#Enable Warning BC40000 ' SourceCodeKind.Interactive Is obsolete
Assert.NotEqual(options1.GetHashCode(), options2.GetHashCode())
End Sub
<Fact>
Public Sub TwoOptionsWithDifferentSpecifiedKindShouldNotBeEqual()
Dim options1 = New VisualBasicParseOptions(kind:=SourceCodeKind.Script)
Dim options2 = New VisualBasicParseOptions(kind:=SourceCodeKind.Script)
Assert.True(options1.Equals(options2))
' They both map internally to SourceCodeKind.Script
#Disable Warning BC40000 ' SourceCodeKind.Interactive is obsolete
options1 = New VisualBasicParseOptions(kind:=SourceCodeKind.Script)
options2 = New VisualBasicParseOptions(kind:=SourceCodeKind.Interactive)
#Enable Warning BC40000 ' SourceCodeKind.Interactive Is obsolete
Assert.False(options1.Equals(options2))
End Sub
<Fact>
Public Sub BadSourceCodeKindShouldProduceDiagnostics()
#Disable Warning BC40000 ' Type Or member Is obsolete
Dim options = New VisualBasicParseOptions(kind:=SourceCodeKind.Interactive)
#Enable Warning BC40000 ' Type Or member Is obsolete
options.Errors.Verify(Diagnostic(ERRID.WRN_BadSourceCodeKind).WithArguments("Interactive").WithLocation(1, 1))
End Sub
<Fact>
Public Sub BadDocumentationModeShouldProduceDiagnostics()
Dim options = New VisualBasicParseOptions(documentationMode:=DirectCast(CType(100, Byte), DocumentationMode))
options.Errors.Verify(Diagnostic(ERRID.ERR_BadDocumentationMode).WithArguments("100").WithLocation(1, 1))
End Sub
<Fact>
Public Sub BadLanguageVersionShouldProduceDiagnostics()
Dim options = New VisualBasicParseOptions(languageVersion:=DirectCast(10000, LanguageVersion))
options.Errors.Verify(Diagnostic(ERRID.ERR_BadLanguageVersion).WithArguments("10000").WithLocation(1, 1))
End Sub
<Fact>
Public Sub BadPreProcessorSymbolsShouldProduceDiagnostics()
Dim symbols = New Dictionary(Of String, Object)
symbols.Add("test", Nothing)
symbols.Add("1", Nothing)
Dim options = New VisualBasicParseOptions(preprocessorSymbols:=symbols)
options.Errors.Verify(Diagnostic(ERRID.ERR_ProjectCCError1).WithArguments("Identifier expected.", "1").WithLocation(1, 1))
End Sub
<Fact>
Public Sub BadSourceCodeKindShouldProduceDiagnostics_WithDimiation()
#Disable Warning BC40000 ' Type Or member Is obsolete
Dim options = New VisualBasicParseOptions().WithKind(SourceCodeKind.Interactive)
#Enable Warning BC40000 ' Type Or member Is obsolete
options.Errors.Verify(Diagnostic(ERRID.WRN_BadSourceCodeKind).WithArguments("Interactive").WithLocation(1, 1))
End Sub
<Fact>
Public Sub BadDocumentationModeShouldProduceDiagnostics_WithDimiation()
Dim options = New VisualBasicParseOptions().WithDocumentationMode(DirectCast(CType(100, Byte), DocumentationMode))
options.Errors.Verify(Diagnostic(ERRID.ERR_BadDocumentationMode).WithArguments("100").WithLocation(1, 1))
End Sub
<Fact>
Public Sub BadLanguageVersionShouldProduceDiagnostics_WithDimiation()
Dim options = New VisualBasicParseOptions().WithLanguageVersion(DirectCast(10000, LanguageVersion))
options.Errors.Verify(Diagnostic(ERRID.ERR_BadLanguageVersion).WithArguments("10000").WithLocation(1, 1))
End Sub
<Fact>
Public Sub BadPreProcessorSymbolsShouldProduceDiagnostics_EmptyString()
Dim symbols = New Dictionary(Of String, Object)
symbols.Add("", Nothing)
Dim options = New VisualBasicParseOptions().WithPreprocessorSymbols(symbols)
options.Errors.Verify(Diagnostic(ERRID.ERR_ProjectCCError1).WithArguments("Identifier expected.", "").WithLocation(1, 1))
End Sub
<Fact>
Public Sub BadPreProcessorSymbolsShouldProduceDiagnostics_WhiteSpacetring()
Dim symbols = New Dictionary(Of String, Object)
symbols.Add(" ", Nothing)
Dim options = New VisualBasicParseOptions().WithPreprocessorSymbols(symbols)
options.Errors.Verify(Diagnostic(ERRID.ERR_ProjectCCError1).WithArguments("Identifier expected.", " ").WithLocation(1, 1))
End Sub
<Fact>
Public Sub BadPreProcessorSymbolsShouldProduceDiagnostics_SymbolWithDots()
Dim symbols = New Dictionary(Of String, Object)
symbols.Add("Good", Nothing)
symbols.Add("Bad.Symbol", Nothing)
Dim options = New VisualBasicParseOptions().WithPreprocessorSymbols(symbols)
options.Errors.Verify(Diagnostic(ERRID.ERR_ProjectCCError1).WithArguments("Identifier expected.", "Bad.Symbol").WithLocation(1, 1))
End Sub
<Fact>
Public Sub BadPreProcessorSymbolsShouldProduceDiagnostics_SymbolWithSlashes()
Dim symbols = New Dictionary(Of String, Object)
symbols.Add("Good", Nothing)
symbols.Add("Bad\\Symbol", Nothing)
Dim options = New VisualBasicParseOptions().WithPreprocessorSymbols(symbols)
options.Errors.Verify(Diagnostic(ERRID.ERR_ProjectCCError1).WithArguments("Identifier expected.", "Bad\\Symbol").WithLocation(1, 1))
End Sub
End Class End Class
...@@ -426,7 +426,7 @@ public override int ERR_BadAssemblyName ...@@ -426,7 +426,7 @@ public override int ERR_BadAssemblyName
} }
} }
public override int ERR_BadSourceCodeKind public override int WRN_BadSourceCodeKind
{ {
get get
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册