提交 7d4f3a0d 编写于 作者: O Omar Tawfik

Public API Changes

上级 5b146f27
......@@ -50,32 +50,10 @@ public override IEnumerable<string> PreprocessorSymbolNames
IEnumerable<string> preprocessorSymbols = null)
: this(languageVersion,
documentationMode,
kind,
preprocessorSymbols.ToImmutableArrayOrEmpty(),
kind,
preprocessorSymbols.ToImmutableArrayOrEmpty(),
ImmutableDictionary<string, string>.Empty)
{
// We test the mapped value, LanguageVersion, rather than the parameter, languageVersion,
// which has not had "Latest" mapped to the latest version yet.
if (!LanguageVersion.IsValid())
{
throw new ArgumentOutOfRangeException(nameof(languageVersion));
}
if (!kind.IsValid())
{
throw new ArgumentOutOfRangeException(nameof(kind));
}
if (preprocessorSymbols != null)
{
foreach (var preprocessorSymbol in preprocessorSymbols)
{
if (!SyntaxFacts.IsValidIdentifier(preprocessorSymbol))
{
throw new ArgumentException($"{nameof(preprocessorSymbols)} contains a symbol that is not a valid identifier", nameof(preprocessorSymbols));
}
}
}
}
internal CSharpParseOptions(
......@@ -84,14 +62,12 @@ public override IEnumerable<string> PreprocessorSymbolNames
SourceCodeKind kind,
IEnumerable<string> preprocessorSymbols,
ImmutableDictionary<string, string> features)
: this(languageVersion, documentationMode, kind, preprocessorSymbols)
: base(kind, documentationMode)
{
if (features == null)
{
throw new ArgumentNullException(nameof(features));
}
_features = features;
this.SpecifiedLanguageVersion = languageVersion;
this.LanguageVersion = languageVersion.MapSpecifiedToEffectiveVersion();
this.PreprocessorSymbols = preprocessorSymbols.ToImmutableArrayOrEmpty();
_features = features ?? ImmutableDictionary<string, string>.Empty;
}
private CSharpParseOptions(CSharpParseOptions other) : this(
......@@ -102,38 +78,18 @@ public override IEnumerable<string> PreprocessorSymbolNames
features: other.Features.ToImmutableDictionary())
{
}
// No validation
private CSharpParseOptions(
LanguageVersion languageVersion,
DocumentationMode documentationMode,
SourceCodeKind kind,
ImmutableArray<string> preprocessorSymbols,
ImmutableDictionary<string, string> features)
: base(kind, documentationMode)
{
Debug.Assert(!preprocessorSymbols.IsDefault);
this.SpecifiedLanguageVersion = languageVersion;
this.LanguageVersion = languageVersion.MapSpecifiedToEffectiveVersion();
this.PreprocessorSymbols = preprocessorSymbols;
_features = features;
}
public override string Language => LanguageNames.CSharp;
public new CSharpParseOptions WithKind(SourceCodeKind kind)
{
if (kind == this.Kind)
if (kind == this.SpecifiedKind)
{
return this;
}
if (!kind.IsValid())
{
throw new ArgumentOutOfRangeException(nameof(kind));
}
return new CSharpParseOptions(this) { Kind = kind };
var effectiveKind = kind.MapSpecifiedToEffectiveKind();
return new CSharpParseOptions(this) { SpecifiedKind = kind, Kind = effectiveKind };
}
public CSharpParseOptions WithLanguageVersion(LanguageVersion version)
......@@ -144,11 +100,6 @@ public CSharpParseOptions WithLanguageVersion(LanguageVersion version)
}
var effectiveLanguageVersion = version.MapSpecifiedToEffectiveVersion();
if (!effectiveLanguageVersion.IsValid())
{
throw new ArgumentOutOfRangeException(nameof(version));
}
return new CSharpParseOptions(this) { SpecifiedLanguageVersion = version, LanguageVersion = effectiveLanguageVersion };
}
......@@ -184,11 +135,6 @@ public new CSharpParseOptions WithDocumentationMode(DocumentationMode documentat
return this;
}
if (!documentationMode.IsValid())
{
throw new ArgumentOutOfRangeException(nameof(documentationMode));
}
return new CSharpParseOptions(this) { DocumentationMode = documentationMode };
}
......@@ -212,12 +158,11 @@ protected override ParseOptions CommonWithFeatures(IEnumerable<KeyValuePair<stri
/// </summary>
public new CSharpParseOptions WithFeatures(IEnumerable<KeyValuePair<string, string>> features)
{
if (features == null)
{
throw new ArgumentNullException(nameof(features));
}
ImmutableDictionary<string, string> dictionary =
features?.ToImmutableDictionary(StringComparer.OrdinalIgnoreCase)
?? ImmutableDictionary<string, string>.Empty;
return new CSharpParseOptions(this) { _features = features.ToImmutableDictionary(StringComparer.OrdinalIgnoreCase) };
return new CSharpParseOptions(this) { _features = dictionary };
}
public override IReadOnlyDictionary<string, string> Features
......@@ -228,6 +173,28 @@ public new CSharpParseOptions WithFeatures(IEnumerable<KeyValuePair<string, stri
}
}
internal override void ValidateOptions(ArrayBuilder<Diagnostic> builder)
{
ValidateOptions(builder, MessageProvider.Instance);
// Validate LanguageVersion not SpecifiedLanguageVersion, after Latest/Default has been converted:
if (!LanguageVersion.IsValid())
{
builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadLanguageVersion, LanguageVersion));
}
if (!PreprocessorSymbols.IsDefaultOrEmpty)
{
foreach (var symbol in PreprocessorSymbols)
{
if (!SyntaxFacts.IsValidIdentifier(symbol))
{
builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.WRN_DefineIdentifierRequired, symbol));
}
}
}
}
internal bool IsFeatureEnabled(MessageID feature)
{
string featureFlag = feature.RequiredFeature();
......
......@@ -1330,6 +1330,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Provided Documentation Mode is unsupported or invalid: &apos;{0}&apos;..
/// </summary>
internal static string ERR_BadDocumentationMode {
get {
return ResourceManager.GetString("ERR_BadDocumentationMode", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos;{0}&apos;: user-defined conversions to or from the dynamic type are not allowed.
/// </summary>
......@@ -1618,6 +1627,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Provided Language Version is unsupported or invalid: &apos;{0}&apos;..
/// </summary>
internal static string ERR_BadLanguageVersion {
get {
return ResourceManager.GetString("ERR_BadLanguageVersion", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The modifier &apos;{0}&apos; is not valid for this item.
/// </summary>
......@@ -1861,6 +1879,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 ERR_BadSourceCodeKind {
get {
return ResourceManager.GetString("ERR_BadSourceCodeKind", resourceCulture);
}
}
/// <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..
/// </summary>
......
......@@ -5020,4 +5020,13 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="ERR_PatternDynamicType" xml:space="preserve">
<value>It is not legal to use the type 'dynamic' in a pattern.</value>
</data>
<data name="ERR_BadDocumentationMode" xml:space="preserve">
<value>Provided Documentation Mode is unsupported or invalid: '{0}'.</value>
</data>
<data name="ERR_BadSourceCodeKind" xml:space="preserve">
<value>Provided Source Code Kind is unsupported or invalid: '{0}'.</value>
</data>
<data name="ERR_BadLanguageVersion" xml:space="preserve">
<value>Provided Language Version is unsupported or invalid: '{0}'.</value>
</data>
</root>
\ No newline at end of file
......@@ -1221,7 +1221,10 @@ public new CSharpCommandLineArguments Parse(IEnumerable<string> args, string bas
features: parsedFeatures
);
var scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script);
if (IsScriptRunner)
{
parseOptions = parseOptions.WithKind(SourceCodeKind.Script);
}
// We want to report diagnostics with source suppression in the error log file.
// However, these diagnostics won't be reported on the command line.
......@@ -1271,6 +1274,7 @@ public new CSharpCommandLineArguments Parse(IEnumerable<string> args, string bas
// add option incompatibility errors if any
diagnostics.AddRange(options.Errors);
diagnostics.AddRange(parseOptions.Errors);
return new CSharpCommandLineArguments
{
......@@ -1307,7 +1311,7 @@ public new CSharpCommandLineArguments Parse(IEnumerable<string> args, string bas
DisplayVersion = displayVersion,
ManifestResources = managedResources.AsImmutable(),
CompilationOptions = options,
ParseOptions = IsScriptRunner ? scriptParseOptions : parseOptions,
ParseOptions = parseOptions,
EmitOptions = emitOptions,
ScriptArguments = scriptArgs.AsImmutableOrEmpty(),
TouchedFilesPath = touchedFilesPath,
......
......@@ -1927,6 +1927,7 @@ internal ImmutableArray<Diagnostic> GetDiagnostics(CompilationStage stage, bool
var syntaxTree = syntaxTrees[i];
AppendLoadDirectiveDiagnostics(builder, _syntaxAndDeclarations, syntaxTree);
builder.AddRange(syntaxTree.GetDiagnostics(cancellationToken));
builder.AddRange(syntaxTree.Options.Errors);
}));
}
else
......
......@@ -1439,7 +1439,13 @@ internal enum ErrorCode
ERR_DelegateRefMismatch = 8189,
#endregion stragglers for C# 7
// Available = 8190-8195
#region diagnostics for parse options
ERR_BadSourceCodeKind = 8190,
ERR_BadDocumentationMode = 8191,
ERR_BadLanguageVersion = 8192,
#endregion
// Available = 8193-8195
#region diagnostics for out var
ERR_ImplicitlyTypedOutVariableUsedInTheSameArgumentList = 8196,
......
......@@ -146,6 +146,10 @@ public override ReportDiagnostic GetDiagnosticReport(DiagnosticInfo diagnosticIn
public override int ERR_CantReadRulesetFile => (int)ErrorCode.ERR_CantReadRulesetFile;
public override int ERR_CompileCancelled => (int)ErrorCode.ERR_CompileCancelled;
// parse options:
public override int ERR_BadSourceCodeKind => (int)ErrorCode.ERR_BadSourceCodeKind;
public override int ERR_BadDocumentationMode => (int)ErrorCode.ERR_BadDocumentationMode;
// compilation options:
public override int ERR_BadCompilationOptionValue => (int)ErrorCode.ERR_BadCompilationOptionValue;
public override int ERR_MutuallyExclusiveOptions => (int)ErrorCode.ERR_MutuallyExclusiveOptions;
......
......@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Linq;
using Roslyn.Utilities;
......@@ -13,11 +14,19 @@ namespace Microsoft.CodeAnalysis
/// </summary>
public abstract class ParseOptions
{
private readonly Lazy<ImmutableArray<Diagnostic>> _lazyErrors;
/// <summary>
/// Specifies whether to parse as regular code files, script files or interactive code.
/// </summary>
public SourceCodeKind Kind { get; protected set; }
/// <summary>
/// Gets the specified source code kind, which is the value that was specified in
/// the call to the constructor, or modified using the <see cref="WithKind(SourceCodeKind)"/> method.
/// </summary>
public SourceCodeKind SpecifiedKind { get; protected set; }
/// <summary>
/// Gets a value indicating whether the documentation comments are parsed.
/// </summary>
......@@ -26,8 +35,16 @@ public abstract class ParseOptions
internal ParseOptions(SourceCodeKind kind, DocumentationMode documentationMode)
{
this.Kind = kind;
this.SpecifiedKind = kind;
this.Kind = kind.MapSpecifiedToEffectiveKind();
this.DocumentationMode = documentationMode;
_lazyErrors = new Lazy<ImmutableArray<Diagnostic>>(() =>
{
var builder = ArrayBuilder<Diagnostic>.GetInstance();
ValidateOptions(builder);
return builder.ToImmutableAndFree();
});
}
/// <summary>
......@@ -35,6 +52,14 @@ internal ParseOptions(SourceCodeKind kind, DocumentationMode documentationMode)
/// </summary>
public abstract string Language { get; }
/// <summary>
/// Errors collection related to an incompatible set of parse options
/// </summary>
public ImmutableArray<Diagnostic> Errors
{
get { return _lazyErrors.Value; }
}
/// <summary>
/// Creates a new options instance with the specified source code kind.
/// </summary>
......@@ -43,6 +68,25 @@ public ParseOptions WithKind(SourceCodeKind kind)
return CommonWithKind(kind);
}
/// <summary>
/// Performs validation of options compatibilities and generates diagnostics if needed
/// </summary>
internal abstract void ValidateOptions(ArrayBuilder<Diagnostic> builder);
internal void ValidateOptions(ArrayBuilder<Diagnostic> builder, CommonMessageProvider messageProvider)
{
// Validate SpecifiedKind not Kind, to catch deprecated specified kinds:
if (!SpecifiedKind.IsValid())
{
builder.Add(messageProvider.CreateDiagnostic(messageProvider.ERR_BadSourceCodeKind, Location.None, SpecifiedKind));
}
if (!DocumentationMode.IsValid())
{
builder.Add(messageProvider.CreateDiagnostic(messageProvider.ERR_BadDocumentationMode, Location.None, DocumentationMode));
}
}
// It was supposed to be a protected implementation detail.
// The "pattern" we have for these is the public With* method is the only public callable one,
// and that forwards to the protected Common* like all the other methods in the class.
......
......@@ -159,6 +159,10 @@ public DiagnosticInfo FilterDiagnosticInfo(DiagnosticInfo diagnosticInfo, Compil
public abstract int ERR_CantReadRulesetFile { get; }
public abstract int ERR_CompileCancelled { get; }
// parse options:
public abstract int ERR_BadSourceCodeKind { get; }
public abstract int ERR_BadDocumentationMode { get; }
// compilation options:
public abstract int ERR_BadCompilationOptionValue { get; }
public abstract int ERR_MutuallyExclusiveOptions { get; }
......
......@@ -188,6 +188,8 @@ Microsoft.CodeAnalysis.OperationKind.VariableDeclarationStatement = 3 -> Microso
Microsoft.CodeAnalysis.OperationKind.WithStatement = 82 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.YieldBreakStatement = 12 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.YieldReturnStatement = 16 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.ParseOptions.Errors.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Diagnostic>
Microsoft.CodeAnalysis.ParseOptions.SpecifiedKind.get -> Microsoft.CodeAnalysis.SourceCodeKind
Microsoft.CodeAnalysis.PortableExecutableReference.GetMetadataId() -> Microsoft.CodeAnalysis.MetadataId
Microsoft.CodeAnalysis.SemanticModel.GetOperation(Microsoft.CodeAnalysis.SyntaxNode node, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ArgumentKind
......
......@@ -32,6 +32,24 @@ public enum SourceCodeKind
internal static partial class SourceCodeKindExtensions
{
internal static SourceCodeKind MapSpecifiedToEffectiveKind(this SourceCodeKind kind)
{
switch (kind)
{
case SourceCodeKind.Regular:
return SourceCodeKind.Regular;
#pragma warning disable CS0618 // SourceCodeKind.Interactive is obsolete
case SourceCodeKind.Script:
case SourceCodeKind.Interactive:
return SourceCodeKind.Script;
#pragma warning restore CS0618 // SourceCodeKind.Interactive is obsolete
default:
throw new NotSupportedException($"SourceCodeKind {kind} not supported");
}
}
internal static bool IsValid(this SourceCodeKind value)
{
return value >= SourceCodeKind.Regular && value <= SourceCodeKind.Script;
......
......@@ -1311,7 +1311,9 @@ lVbRuntimePlus:
preprocessorSymbols:=AddPredefinedPreprocessorSymbols(outputKind, defines.AsImmutableOrEmpty()),
features:=parsedFeatures)
Dim scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script)
If IsScriptRunner Then
parseOptions = parseOptions.WithKind(SourceCodeKind.Script)
End If
' We want to report diagnostics with source suppression in the error log file.
' However, these diagnostics won't be reported on the command line.
......@@ -1357,6 +1359,7 @@ lVbRuntimePlus:
' add option incompatibility errors if any
diagnostics.AddRange(options.Errors)
diagnostics.AddRange(parseOptions.Errors)
If documentationPath Is GenerateFileNameForDocComment Then
documentationPath = PathUtilities.CombineAbsoluteAndRelativePaths(outputDirectory, PathUtilities.RemoveExtension(outputFileName))
......@@ -1398,7 +1401,7 @@ lVbRuntimePlus:
.DisplayVersion = displayVersion,
.ManifestResources = managedResources.AsImmutable(),
.CompilationOptions = options,
.ParseOptions = If(IsScriptRunner, scriptParseOptions, parseOptions),
.ParseOptions = parseOptions,
.EmitOptions = emitOptions,
.ScriptArguments = scriptArgs.AsImmutableOrEmpty(),
.TouchedFilesPath = touchedFilesPath,
......
......@@ -1927,6 +1927,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
For Each tree In SyntaxTrees
cancellationToken.ThrowIfCancellationRequested()
builder.AddRange(tree.GetDiagnostics(cancellationToken))
builder.AddRange(tree.Options.Errors)
Next
End If
End If
......
......@@ -1726,6 +1726,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
ERR_Merge_conflict_marker_encountered = 37284
ERR_BadSourceCodeKind = 37285
ERR_BadDocumentationMode = 37286
ERR_BadLanguageVersion = 37287
'// WARNINGS BEGIN HERE
WRN_UseOfObsoleteSymbol2 = 40000
WRN_InvalidOverrideDueToTupleNames2 = 40001
......
......@@ -232,6 +232,20 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
' parse options:
Public Overrides ReadOnly Property ERR_BadSourceCodeKind As Integer
Get
Return ERRID.ERR_BadSourceCodeKind
End Get
End Property
Public Overrides ReadOnly Property ERR_BadDocumentationMode As Integer
Get
Return ERRID.ERR_BadDocumentationMode
End Get
End Property
' compilation options:
Public Overrides ReadOnly Property ERR_BadCompilationOptionValue As Integer
......
......@@ -1035,6 +1035,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Provided Documentation Mode is unsupported or invalid: &apos;{0}&apos;..
'''</summary>
Friend ReadOnly Property ERR_BadDocumentationMode() As String
Get
Return ResourceManager.GetString("ERR_BadDocumentationMode", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Enum &apos;{0}&apos; must contain at least one member..
'''</summary>
......@@ -1278,6 +1287,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Provided Language Version is unsupported or invalid: &apos;{0}&apos;..
'''</summary>
Friend ReadOnly Property ERR_BadLanguageVersion() As String
Get
Return ResourceManager.GetString("ERR_BadLanguageVersion", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to &apos;{0}&apos; is not valid on a local constant declaration..
'''</summary>
......@@ -1485,6 +1503,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
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>
''' Looks up a localized string similar to &apos;{0}&apos; and &apos;{1}&apos; cannot be combined..
'''</summary>
......
......@@ -5467,4 +5467,13 @@
<data name="ERR_Merge_conflict_marker_encountered" xml:space="preserve">
<value>Merge conflict marker encountered</value>
</data>
<data name="ERR_BadDocumentationMode" xml:space="preserve">
<value>Provided Documentation Mode is unsupported or invalid: '{0}'.</value>
</data>
<data name="ERR_BadLanguageVersion" xml:space="preserve">
<value>Provided Language Version is unsupported or invalid: '{0}'.</value>
</data>
<data name="ERR_BadSourceCodeKind" xml:space="preserve">
<value>Provided Source Code Kind is unsupported or invalid: '{0}'.</value>
</data>
</root>
\ No newline at end of file
......@@ -40,18 +40,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
kind,
If(preprocessorSymbols Is Nothing, DefaultPreprocessorSymbols, ImmutableArray.CreateRange(preprocessorSymbols)),
ImmutableDictionary(Of String, String).Empty)
' We test the mapped value, _languageVersion, rather than the parameter, languageVersion,
' which has not had "Latest" mapped to the latest version yet.
If Not _languageVersion.IsValid Then
Throw New ArgumentOutOfRangeException(NameOf(languageVersion))
End If
If Not kind.IsValid Then
Throw New ArgumentOutOfRangeException(NameOf(kind))
End If
ValidatePreprocessorSymbols(preprocessorSymbols, NameOf(preprocessorSymbols))
End Sub
Friend Sub New(
......@@ -61,65 +49,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
preprocessorSymbols As IEnumerable(Of KeyValuePair(Of String, Object)),
features As ImmutableDictionary(Of String, String))
MyClass.New(languageVersion,
documentationMode,
kind,
If(preprocessorSymbols Is Nothing, DefaultPreprocessorSymbols, ImmutableArray.CreateRange(preprocessorSymbols)),
features)
' We test the mapped value, _languageVersion, rather than the parameter, languageVersion,
' which has not had "Latest" mapped to the latest version yet.
If Not _languageVersion.IsValid Then
Throw New ArgumentOutOfRangeException(NameOf(languageVersion))
End If
If Not kind.IsValid Then
Throw New ArgumentOutOfRangeException(NameOf(kind))
End If
ValidatePreprocessorSymbols(preprocessorSymbols, NameOf(preprocessorSymbols))
If features Is Nothing Then
Throw New ArgumentException(NameOf(features))
End If
End Sub
Private Shared Sub ValidatePreprocessorSymbols(preprocessorSymbols As IEnumerable(Of KeyValuePair(Of String, Object)),
parameterName As String)
If preprocessorSymbols Is Nothing Then
Return
End If
For Each symbol In preprocessorSymbols
If Not IsValidIdentifier(symbol.Key) OrElse
SyntaxFacts.GetKeywordKind(symbol.Key) <> SyntaxKind.None Then
Throw New ArgumentException(parameterName)
End If
Debug.Assert(SyntaxFactory.ParseTokens(symbol.Key).Select(Function(t) t.Kind).SequenceEqual({SyntaxKind.IdentifierToken, SyntaxKind.EndOfFileToken}))
Dim constant = InternalSyntax.CConst.TryCreate(symbol.Value)
If constant Is Nothing Then
Throw New ArgumentException(String.Format(VBResources.IDS_InvalidPreprocessorConstantType, symbol.Key, symbol.Value.GetType()), parameterName)
End If
Next
End Sub
' Does not perform validation.
Private Sub New(
languageVersion As LanguageVersion,
documentationMode As DocumentationMode,
kind As SourceCodeKind,
preprocessorSymbols As ImmutableArray(Of KeyValuePair(Of String, Object)),
features As ImmutableDictionary(Of String, String))
MyBase.New(kind, documentationMode)
Debug.Assert(Not preprocessorSymbols.IsDefault)
_specifiedLanguageVersion = languageVersion
_languageVersion = languageVersion.MapSpecifiedToEffectiveVersion
_preprocessorSymbols = preprocessorSymbols
_preprocessorSymbols = preprocessorSymbols.ToImmutableArrayOrEmpty
_features = features
End Sub
......@@ -200,10 +134,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
Dim effectiveVersion = version.MapSpecifiedToEffectiveVersion()
If Not effectiveVersion.IsValid Then
Throw New ArgumentOutOfRangeException(NameOf(version))
End If
Return New VisualBasicParseOptions(Me) With {._specifiedLanguageVersion = version, ._languageVersion = effectiveVersion}
End Function
......@@ -213,15 +143,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' <param name="kind">The parser source code kind.</param>
''' <returns>A new instance of VisualBasicParseOptions if source code kind is different; otherwise current instance.</returns>
Public Shadows Function WithKind(kind As SourceCodeKind) As VisualBasicParseOptions
If kind = Me.Kind Then
If kind = Me.SpecifiedKind Then
Return Me
End If
If Not kind.IsValid Then
Throw New ArgumentOutOfRangeException(NameOf(kind))
End If
Return New VisualBasicParseOptions(Me) With {.Kind = kind}
Dim effectiveKind = kind.MapSpecifiedToEffectiveKind
Return New VisualBasicParseOptions(Me) With {.SpecifiedKind = kind, .Kind = effectiveKind}
End Function
''' <summary>
......@@ -234,10 +161,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return Me
End If
If Not documentationMode.IsValid() Then
Throw New ArgumentOutOfRangeException(NameOf(documentationMode))
End If
Return New VisualBasicParseOptions(Me) With {.DocumentationMode = documentationMode}
End Function
......@@ -273,8 +196,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return Me
End If
ValidatePreprocessorSymbols(symbols, NameOf(symbols))
Return New VisualBasicParseOptions(Me) With {._preprocessorSymbols = symbols}
End Function
......@@ -306,10 +227,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Shadows Function WithFeatures(features As IEnumerable(Of KeyValuePair(Of String, String))) As VisualBasicParseOptions
' there are currently no parse options for experimental features
If features Is Nothing Then
Throw New ArgumentException(NameOf(features))
Return New VisualBasicParseOptions(Me) With {._features = ImmutableDictionary(Of String, String).Empty}
Else
Return New VisualBasicParseOptions(Me) With {._features = features.ToImmutableDictionary(StringComparer.OrdinalIgnoreCase)}
End If
Return New VisualBasicParseOptions(Me) With {._features = features.ToImmutableDictionary(StringComparer.OrdinalIgnoreCase)}
End Function
Public Overrides ReadOnly Property Features As IReadOnlyDictionary(Of String, String)
......@@ -318,6 +239,31 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
Friend Overrides Sub ValidateOptions(builder As ArrayBuilder(Of Diagnostic))
ValidateOptions(builder, MessageProvider.Instance)
' Validate LanguageVersion Not SpecifiedLanguageVersion, after Latest/Default has been converted
If Not LanguageVersion.IsValid Then
builder.Add(Diagnostic.Create(MessageProvider.Instance, ERRID.ERR_BadLanguageVersion, LanguageVersion))
End If
If Not PreprocessorSymbols.IsDefaultOrEmpty Then
For Each symbol In PreprocessorSymbols
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))
End If
Debug.Assert(SyntaxFactory.ParseTokens(symbol.Key).Select(Function(t) t.Kind).SequenceEqual({SyntaxKind.IdentifierToken, SyntaxKind.EndOfFileToken}))
Dim constant = InternalSyntax.CConst.TryCreate(symbol.Value)
If constant Is Nothing Then
builder.Add(Diagnostic.Create(MessageProvider.Instance, ERRID.IDS_InvalidPreprocessorConstantType, symbol.Key, symbol.Value.GetType))
End If
Next
End If
End Sub
''' <summary>
''' Determines whether the current object is equal to another object of the same type.
''' </summary>
......
......@@ -425,5 +425,21 @@ public override int ERR_BadAssemblyName
throw new NotImplementedException();
}
}
public override int ERR_BadSourceCodeKind
{
get
{
throw new NotImplementedException();
}
}
public override int ERR_BadDocumentationMode
{
get
{
throw new NotImplementedException();
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册