diff --git a/docs/compilers/API Notes/6-11-20.md b/docs/compilers/API Notes/6-11-20.md new file mode 100644 index 0000000000000..c3dd3d10823e6 --- /dev/null +++ b/docs/compilers/API Notes/6-11-20.md @@ -0,0 +1,61 @@ +### `BaseTypeSyntax` Design + +In master, we currently have added an optional argument list to `SimpleBaseTypeSyntax` for record primary constructors. However, there is an argument to be made that we should add a new subtype of `BaseTypeSyntax`, something like `PrimaryConstructorTypeSyntax`, to represent these new base type clauses. This was an explicit extension point added in the original design for this very purpose. For either of these designs, GetSymbolInfo will behave consistently: if the `BaseTypeSyntax` has an argument list (either because it's a separate type or because it's a `PrimaryConstructorTypeSyntax`), it will return the constructor symbol or candidates as appropriate. If there are no arguments, then it will return nothing. + +Pros for keeping the optional argument list on `SimpleBaseTypeSyntax`: +* The primary constructor arguments feel like an extension to existing nodes, not a totally new node type +* Existing analyzers/fixers might pick things up right without much modification + +Pros for extending `BaseTypeSyntax`: +* This extension point was put in explicitly for this +* Existing code might be less likely to erroneously use it +* There was some feeling that it would serve as a more clear delineation for future additions to this syntax (if such C# features ever come to pass) + +#### Conclusion + +We lean towards extending `BaseTypeSyntax` in the next preview. + +### `CompilationOutputFilePaths` + +The plural when this struct only has one path in it currently felt wrong. Some options for renaming: + +* `CompilationOutputFileInfo` +* `CompilationOutputInfo` +* `CompilationOutputFiles` + +We leave it up to whoever does the rename to choose among these. + +### `SolutionInfo.Create` + +Add `EditorBrowsable(Never)` to the backcompat overload. + +### `SymbolKind.FunctionPointer` + +Suffix with `Type` for consistency with the other kinds that are also `TypeKind`s. + +### `SyntaxFactory.ParseType` + +The new overload should use `ParseOptions` instead of the specific C#/VB type in both factories. +Most of the Parse overloads that take a `ParseOptions` here use the non-specific one, and it can be very convenient for IDE APIs here. +While it is marginally less type-safe, the ergonomic and consistency benefits are a deciding factor. + +### `WithExpressionSyntax.Receiver` + +This should be renamed to `Expression` for consistency with other `SyntaxNode`s. + +### `SymbolFinder.Find(Derived(Classes|Interfaces)|Interfaces)Async` + +We should reconsider adding multiple overloads, and instead remove the default parameters from the existing overload and introduce a new overload with `transitive` set to `true` to match current behavior. +This is our standard modus operandi for these scenarios. + +### `INegatedPatternOperation.NegatedPattern` + +Rename to just `Pattern`. + +### `IWithOperation.Value` + +Rename to `Operand`. + +### `Renamer.RenameDocumentAsync` + +Make this and the related structs internal unless we have a partner team ready to consume the API in 16.7. We can make the API public again when someone is ready to consume and validate the API shape. diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs index d041478f85fc2..4d8b7aaca042c 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs @@ -666,7 +666,7 @@ private ImmutableArray GetRewrittenAttributeConstructorArguments( } else if (reorderedArgument.Kind == TypedConstantKind.Array && parameter.Type.TypeKind == TypeKind.Array && - !((TypeSymbol)reorderedArgument.TypeInternal).Equals(parameter.Type, TypeCompareKind.AllIgnoreOptions)) + !((TypeSymbol)reorderedArgument.TypeInternal!).Equals(parameter.Type, TypeCompareKind.AllIgnoreOptions)) { // NOTE: As in dev11, we don't allow array covariance conversions (presumably, we don't have a way to // represent the conversion in metadata). @@ -922,6 +922,7 @@ private static bool TryGetNormalParamValue(ParameterSymbol parameter, ImmutableA } HashSet? useSiteDiagnostics = null; // ignoring, since already bound argument and parameter + Debug.Assert(argument.TypeInternal is object); Conversion conversion = conversions.ClassifyBuiltInConversion((TypeSymbol)argument.TypeInternal, parameter.Type, ref useSiteDiagnostics); // NOTE: Won't always succeed, even though we've performed overload resolution. diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index d2cc52a1bef5d..b26e85c09bb00 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -3777,9 +3777,8 @@ private static bool IsNegativeConstantForArraySize(BoundExpression expression) /// /// /// Null for implicit, - /// BaseConstructorInitializerSyntax.ArgumentList, or - /// ThisConstructorInitializerSyntax.ArgumentList, or - /// SimpleBaseTypeSyntax.ArgumentList for explicit. + /// , or + /// for explicit. /// Constructor containing the initializer. /// Accumulates errors (e.g. unable to find constructor to invoke). /// A bound expression for the constructor initializer call. @@ -3921,9 +3920,8 @@ private BoundExpression BindConstructorInitializerCore( errorLocation = initializerSyntax.ThisOrBaseKeyword.GetLocation(); break; - case SimpleBaseTypeSyntax baseWithArguments: - Debug.Assert(baseWithArguments.Parent?.Parent is RecordDeclarationSyntax recordDecl && recordDecl.BaseList.Types.FirstOrDefault() == baseWithArguments); - nonNullSyntax = initializerArgumentListOpt; + case PrimaryConstructorBaseTypeSyntax baseWithArguments: + nonNullSyntax = baseWithArguments; errorLocation = initializerArgumentListOpt.GetLocation(); break; @@ -6241,9 +6239,9 @@ private BoundExpression BindInstanceMemberAccess( lookupResult, flags); - if (!boundMethodGroup.HasErrors && boundMethodGroup.ResultKind == LookupResultKind.Empty && typeArgumentsSyntax.Any(SyntaxKind.OmittedTypeArgument)) + if (!boundMethodGroup.HasErrors && typeArgumentsSyntax.Any(SyntaxKind.OmittedTypeArgument)) { - Error(diagnostics, ErrorCode.ERR_BadArity, node, rightName, MessageID.IDS_MethodGroup.Localize(), typeArgumentsSyntax.Count); + Error(diagnostics, ErrorCode.ERR_OmittedTypeArgument, node); } return boundMethodGroup; diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs index f425958c6f4bf..0d14e5253e038 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Patterns.cs @@ -180,7 +180,7 @@ internal BoundPattern BindConstantPatternWithFallbackToTypePattern( bool hasErrors, DiagnosticBag diagnostics) { - ExpressionSyntax innerExpression = expression.SkipParens(); + ExpressionSyntax innerExpression = SkipParensAndNullSuppressions(expression); if (innerExpression.Kind() == SyntaxKind.DefaultLiteralExpression) { diagnostics.Add(ErrorCode.ERR_DefaultPattern, innerExpression.Location); @@ -204,6 +204,24 @@ internal BoundPattern BindConstantPatternWithFallbackToTypePattern( } } + private ExpressionSyntax SkipParensAndNullSuppressions(ExpressionSyntax e) + { + while (true) + { + switch (e) + { + case ParenthesizedExpressionSyntax p: + e = p.Expression; + break; + case PostfixUnaryExpressionSyntax { RawKind: (int)SyntaxKind.SuppressNullableWarningExpression } p: + e = p.Operand; + break; + default: + return e; + } + } + } + /// /// Binds the expression for a pattern. Sets if it was a type rather than an expression, /// and in that case it returns a . @@ -1239,6 +1257,12 @@ private BoundPattern BindRelationalPattern( DiagnosticBag diagnostics) { BoundExpression value = BindExpressionForPattern(inputType, node.Expression, ref hasErrors, diagnostics, out var constantValueOpt, out _); + ExpressionSyntax innerExpression = SkipParensAndNullSuppressions(node.Expression); + if (innerExpression.Kind() == SyntaxKind.DefaultLiteralExpression) + { + diagnostics.Add(ErrorCode.ERR_DefaultPattern, innerExpression.Location); + hasErrors = true; + } RoslynDebug.Assert(value.Type is { }); BinaryOperatorKind operation = tokenKindToBinaryOperatorKind(node.OperatorToken.Kind()); if (operation == BinaryOperatorKind.Equal) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index be2802ac4751e..ea2cf793cc199 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -3322,7 +3322,7 @@ private BoundNode BindRecordConstructorBody(RecordDeclarationSyntax recordDecl, Debug.Assert(bodyBinder != null); BoundExpressionStatement initializer = null; - if (recordDecl.BaseWithArguments is SimpleBaseTypeSyntax baseWithArguments) + if (recordDecl.PrimaryConstructorBaseType is PrimaryConstructorBaseTypeSyntax baseWithArguments) { initializer = bodyBinder.BindConstructorInitializer(baseWithArguments, diagnostics); } @@ -3334,10 +3334,8 @@ private BoundNode BindRecordConstructorBody(RecordDeclarationSyntax recordDecl, expressionBody: null); } - internal BoundExpressionStatement BindConstructorInitializer(SimpleBaseTypeSyntax initializer, DiagnosticBag diagnostics) + internal virtual BoundExpressionStatement BindConstructorInitializer(PrimaryConstructorBaseTypeSyntax initializer, DiagnosticBag diagnostics) { - Debug.Assert(initializer.Parent?.Parent is RecordDeclarationSyntax recordDecl && recordDecl.ParameterList is object && recordDecl.BaseWithArguments == initializer); - BoundExpression initializerInvocation = GetBinder(initializer).BindConstructorInitializer(initializer.ArgumentList, (MethodSymbol)this.ContainingMember(), diagnostics); var constructorInitializer = new BoundExpressionStatement(initializer, initializerInvocation); Debug.Assert(initializerInvocation.HasAnyErrors || constructorInitializer.IsConstructorInitializer(), "Please keep this bound node in sync with BoundNodeExtensions.IsConstructorInitializer."); diff --git a/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs b/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs index 48bd938480ade..a2a2eb2767d3b 100644 --- a/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs @@ -49,7 +49,7 @@ protected void FindExpressionVariables( case SyntaxKind.GotoCaseStatement: break; case SyntaxKind.ArgumentList: - Debug.Assert(node.Parent is ConstructorInitializerSyntax); + Debug.Assert(node.Parent is ConstructorInitializerSyntax || node.Parent is PrimaryConstructorBaseTypeSyntax); break; case SyntaxKind.RecordDeclaration: Debug.Assert(((RecordDeclarationSyntax)node).ParameterList is object); @@ -397,7 +397,7 @@ public override void VisitRecordDeclaration(RecordDeclarationSyntax node) { Debug.Assert(node.ParameterList is object); - if (node.BaseWithArguments is SimpleBaseTypeSyntax baseWithArguments) + if (node.PrimaryConstructorBaseType is PrimaryConstructorBaseTypeSyntax baseWithArguments) { VisitNodeToBind(baseWithArguments); } diff --git a/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs b/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs index ef27e8dcdd1cf..7a025be2810c6 100644 --- a/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs +++ b/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs @@ -162,13 +162,14 @@ public override void VisitRecordDeclaration(RecordDeclarationSyntax node) Binder enclosing = new ExpressionVariableBinder(node, _enclosing); AddToMap(node, enclosing); + Visit(node.PrimaryConstructorBaseType, enclosing); + } - if (node.BaseWithArguments is SimpleBaseTypeSyntax baseWithArguments) - { - enclosing = enclosing.WithAdditionalFlags(BinderFlags.ConstructorInitializer); - AddToMap(baseWithArguments, enclosing); - Visit(baseWithArguments.ArgumentList, enclosing); - } + public override void VisitPrimaryConstructorBaseType(PrimaryConstructorBaseTypeSyntax node) + { + Binder enclosing = _enclosing.WithAdditionalFlags(BinderFlags.ConstructorInitializer); + AddToMap(node, enclosing); + VisitConstructorInitializerArgumentList(node, node.ArgumentList, enclosing); } public override void VisitDestructorDeclaration(DestructorDeclarationSyntax node) @@ -317,16 +318,20 @@ public override void VisitConstructorInitializer(ConstructorInitializerSyntax no { var binder = _enclosing.WithAdditionalFlags(BinderFlags.ConstructorInitializer); AddToMap(node, binder); + VisitConstructorInitializerArgumentList(node, node.ArgumentList, binder); + } - if (node.ArgumentList != null) + private void VisitConstructorInitializerArgumentList(CSharpSyntaxNode node, ArgumentListSyntax argumentList, Binder binder) + { + if (argumentList != null) { if (_root == node) { - binder = new ExpressionVariableBinder(node.ArgumentList, binder); - AddToMap(node.ArgumentList, binder); + binder = new ExpressionVariableBinder(argumentList, binder); + AddToMap(argumentList, binder); } - Visit(node.ArgumentList, binder); + Visit(argumentList, binder); } } diff --git a/src/Compilers/CSharp/Portable/Binder/SwitchBinder_Patterns.cs b/src/Compilers/CSharp/Portable/Binder/SwitchBinder_Patterns.cs index 8a5090ddf7d69..14095889a81a9 100644 --- a/src/Compilers/CSharp/Portable/Binder/SwitchBinder_Patterns.cs +++ b/src/Compilers/CSharp/Portable/Binder/SwitchBinder_Patterns.cs @@ -237,7 +237,6 @@ private BoundSwitchLabel BindSwitchSectionLabel( case SyntaxKind.CaseSwitchLabel: { var caseLabelSyntax = (CaseSwitchLabelSyntax)node; - SyntaxNode innerExpression = caseLabelSyntax.Value.SkipParens(); bool hasErrors = node.HasErrors; BoundPattern pattern = sectionBinder.BindConstantPatternWithFallbackToTypePattern( caseLabelSyntax.Value, caseLabelSyntax.Value, SwitchGoverningType, hasErrors, diagnostics); diff --git a/src/Compilers/CSharp/Portable/CSharpExtensions.cs b/src/Compilers/CSharp/Portable/CSharpExtensions.cs index 1875ac2f36bf3..8e7998236412d 100644 --- a/src/Compilers/CSharp/Portable/CSharpExtensions.cs +++ b/src/Compilers/CSharp/Portable/CSharpExtensions.cs @@ -537,6 +537,22 @@ public static Conversion ClassifyConversion(this Compilation? compilation, IType } } + /// + /// Returns what symbol(s), if any, the given constructor initializer syntax bound to in the program. + /// + public static SymbolInfo GetSymbolInfo(this SemanticModel? semanticModel, PrimaryConstructorBaseTypeSyntax constructorInitializer, CancellationToken cancellationToken = default(CancellationToken)) + { + var csmodel = semanticModel as CSharpSemanticModel; + if (csmodel != null) + { + return csmodel.GetSymbolInfo(constructorInitializer, cancellationToken); + } + else + { + return SymbolInfo.None; + } + } + /// /// Returns what symbol(s), if any, the given attribute syntax bound to in the program. /// @@ -643,6 +659,27 @@ public static SymbolInfo GetSpeculativeSymbolInfo(this SemanticModel? semanticMo } } + /// + /// Bind the constructor initializer in the context of the specified location and get semantic information + /// about symbols. This method is used to get semantic information about a constructor + /// initializer that did not actually appear in the source code. + /// + /// NOTE: This will only work in locations where there is already a constructor initializer. + /// . + /// + public static SymbolInfo GetSpeculativeSymbolInfo(this SemanticModel? semanticModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer) + { + var csmodel = semanticModel as CSharpSemanticModel; + if (csmodel != null) + { + return csmodel.GetSpeculativeSymbolInfo(position, constructorInitializer); + } + else + { + return SymbolInfo.None; + } + } + /// /// Gets type information about a constructor initializer. /// @@ -1178,6 +1215,27 @@ public static bool TryGetSpeculativeSemanticModel([NotNullWhen(true)] this Seman } } + /// + /// Get a SemanticModel object that is associated with a constructor initializer that did not appear in + /// this source code. This can be used to get detailed semantic information about sub-parts + /// of a constructor initializer that did not appear in source code. + /// + /// NOTE: This will only work in locations where there is already a constructor initializer. + /// + public static bool TryGetSpeculativeSemanticModel([NotNullWhen(true)] this SemanticModel? semanticModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, [NotNullWhen(true)] out SemanticModel? speculativeModel) + { + var csmodel = semanticModel as CSharpSemanticModel; + if (csmodel != null) + { + return csmodel.TryGetSpeculativeSemanticModel(position, constructorInitializer, out speculativeModel); + } + else + { + speculativeModel = null; + return false; + } + } + /// /// Get a SemanticModel object that is associated with an attribute that did not appear in /// this source code. This can be used to get detailed semantic information about sub-parts diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 6bf06fd5cde2f..00b6d833826b8 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -471,6 +471,9 @@ Keyword 'this' is not available in the current context + + Omitting the type argument is not allowed in the current context + '{0}' has the wrong signature to be an entry point diff --git a/src/Compilers/CSharp/Portable/Compilation/AttributeSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/AttributeSemanticModel.cs index cd1a135d60701..c5a400824172a 100644 --- a/src/Compilers/CSharp/Portable/Compilation/AttributeSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/AttributeSemanticModel.cs @@ -118,6 +118,12 @@ internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticMode return false; } + internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out SemanticModel speculativeModel) + { + speculativeModel = null; + return false; + } + internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, EqualsValueClauseSyntax initializer, out SemanticModel speculativeModel) { speculativeModel = null; diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs index 41f8b3b4f4eb5..07fb552aeeb41 100644 --- a/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs @@ -120,6 +120,7 @@ internal static bool CanGetSemanticInfo(CSharpSyntaxNode node, bool allowNamedAr return (node is ExpressionSyntax && (isSpeculative || allowNamedArgumentName || !SyntaxFacts.IsNamedArgumentName(node))) || (node is ConstructorInitializerSyntax) || + (node is PrimaryConstructorBaseTypeSyntax) || (node is AttributeSyntax) || (node is CrefSyntax); } @@ -636,7 +637,6 @@ private static SymbolInfo GetSymbolInfoFromSymbolOrNone(ITypeSymbol type) return SymbolInfo.None; } - /// /// Returns what symbol(s), if any, the given constructor initializer syntax bound to in the program. /// @@ -651,6 +651,20 @@ private static SymbolInfo GetSymbolInfoFromSymbolOrNone(ITypeSymbol type) : SymbolInfo.None; } + /// + /// Returns what symbol(s), if any, the given constructor initializer syntax bound to in the program. + /// + /// The syntax node to get semantic information for. + /// The cancellation token. + public SymbolInfo GetSymbolInfo(PrimaryConstructorBaseTypeSyntax constructorInitializer, CancellationToken cancellationToken = default(CancellationToken)) + { + CheckSyntaxNode(constructorInitializer); + + return CanGetSemanticInfo(constructorInitializer) + ? GetSymbolInfoWorker(constructorInitializer, SymbolInfoOptions.DefaultOptions, cancellationToken) + : SymbolInfo.None; + } + /// /// Returns what symbol(s), if any, the given attribute syntax bound to in the program. /// @@ -798,7 +812,82 @@ public SymbolInfo GetSpeculativeSymbolInfo(int position, ConstructorInitializerS binder = new ExecutableCodeBinder(constructorInitializer, binder.ContainingMemberOrLambda, binder); BoundExpressionStatement bnode = binder.BindConstructorInitializer(constructorInitializer, diagnostics); - var binfo = memberModel.GetSymbolInfoForNode(SymbolInfoOptions.DefaultOptions, bnode.Expression, bnode.Expression, boundNodeForSyntacticParent: null, binderOpt: binder); + var binfo = GetSymbolInfoFromBoundConstructorInitializer(memberModel, binder, bnode); + diagnostics.Free(); + return binfo; + } + else + { + return SymbolInfo.None; + } + } + + private static SymbolInfo GetSymbolInfoFromBoundConstructorInitializer(MemberSemanticModel memberModel, Binder binder, BoundExpressionStatement bnode) + { + BoundExpression expression = bnode.Expression; + + while (expression is BoundSequence sequence) + { + expression = sequence.Value; + } + + return memberModel.GetSymbolInfoForNode(SymbolInfoOptions.DefaultOptions, expression, expression, boundNodeForSyntacticParent: null, binderOpt: binder); + } + + /// + /// Bind the constructor initializer in the context of the specified location and get semantic information + /// about symbols. This method is used to get semantic information about a constructor + /// initializer that did not actually appear in the source code. + /// + /// NOTE: This will only work in locations where there is already a constructor initializer. + /// + /// A character position used to identify a declaration scope and accessibility. This + /// character position must be within the span of an existing constructor initializer. + /// + /// A syntax node that represents a parsed constructor initializer. This syntax node + /// need not and typically does not appear in the source code referred to SemanticModel instance. + /// The semantic information for the topmost node of the constructor initializer. + public SymbolInfo GetSpeculativeSymbolInfo(int position, PrimaryConstructorBaseTypeSyntax constructorInitializer) + { + Debug.Assert(CanGetSemanticInfo(constructorInitializer, isSpeculative: true)); + + position = CheckAndAdjustPosition(position); + + if (constructorInitializer == null) + { + throw new ArgumentNullException(nameof(constructorInitializer)); + } + + // NOTE: since we're going to be depending on a MemberModel to do the binding for us, + // we need to find a constructor initializer in the tree of this semantic model. + // NOTE: This approach will not allow speculative binding of a constructor initializer + // on a constructor that didn't formerly have one. + // TODO: Should we support positions that are not in existing constructor initializers? + // If so, we will need to build up the context that would otherwise be built up by + // InitializerMemberModel. + var existingConstructorInitializer = this.Root.FindToken(position).Parent.AncestorsAndSelf().OfType().FirstOrDefault(); + + if (existingConstructorInitializer == null) + { + return SymbolInfo.None; + } + + MemberSemanticModel memberModel = GetMemberModel(existingConstructorInitializer); + + if (memberModel == null) + { + return SymbolInfo.None; + } + + var argumentList = existingConstructorInitializer.ArgumentList; + var binder = memberModel.GetEnclosingBinder(LookupPosition.IsBetweenTokens(position, argumentList.OpenParenToken, argumentList.CloseParenToken) ? position : argumentList.OpenParenToken.SpanStart); + if (binder != null) + { + var diagnostics = DiagnosticBag.GetInstance(); + binder = new ExecutableCodeBinder(constructorInitializer, binder.ContainingMemberOrLambda, binder); + + BoundExpressionStatement bnode = binder.BindConstructorInitializer(constructorInitializer, diagnostics); + SymbolInfo binfo = GetSymbolInfoFromBoundConstructorInitializer(memberModel, binder, bnode); diagnostics.Free(); return binfo; } @@ -1014,7 +1103,7 @@ public Conversion GetSpeculativeConversion(int position, ExpressionSyntax expres } /// - /// Gets a list of method or indexed property symbols for a syntax node. + /// Gets a list of method symbols for a syntax node. /// /// The syntax node to get semantic information for. /// The cancellation token. @@ -2514,6 +2603,33 @@ public bool TryGetSpeculativeSemanticModel(int position, ConstructorInitializerS internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ConstructorInitializerSyntax constructorInitializer, out SemanticModel speculativeModel); + /// + /// Get a SemanticModel object that is associated with a constructor initializer that did not appear in + /// this source code. This can be used to get detailed semantic information about sub-parts + /// of a constructor initializer that did not appear in source code. + /// + /// NOTE: This will only work in locations where there is already a constructor initializer. + /// + /// A character position used to identify a declaration scope and accessibility. This + /// character position must be within the span of an existing constructor initializer. + /// + /// A syntax node that represents a parsed constructor initializer. + /// This node should not be present in the syntax tree associated with this object. + /// A SemanticModel object that can be used to inquire about the semantic + /// information associated with syntax nodes within . + /// Flag indicating whether a speculative semantic model was created. + /// Throws this exception if the node is contained any SyntaxTree in the current Compilation. + /// Throws this exception if is null. + /// Throws this exception if this model is a speculative semantic model, i.e. is true. + /// Chaining of speculative semantic model is not supported. + public bool TryGetSpeculativeSemanticModel(int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out SemanticModel speculativeModel) + { + CheckModelAndSyntaxNodeToSpeculate(constructorInitializer); + return TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, constructorInitializer, out speculativeModel); + } + + internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out SemanticModel speculativeModel); + /// /// Get a SemanticModel object that is associated with a cref that did not appear in /// this source code. This can be used to get detailed semantic information about sub-parts @@ -4753,6 +4869,8 @@ private SymbolInfo GetSymbolInfoFromNode(SyntaxNode node, CancellationToken canc return this.GetSymbolInfo(expression, cancellationToken); case ConstructorInitializerSyntax initializer: return this.GetSymbolInfo(initializer, cancellationToken); + case PrimaryConstructorBaseTypeSyntax initializer: + return this.GetSymbolInfo(initializer, cancellationToken); case AttributeSyntax attribute: return this.GetSymbolInfo(attribute, cancellationToken); case CrefSyntax cref: @@ -4820,6 +4938,8 @@ protected sealed override SymbolInfo GetSpeculativeSymbolInfoCore(int position, return GetSpeculativeSymbolInfo(position, expression, bindingOption); case ConstructorInitializerSyntax initializer: return GetSpeculativeSymbolInfo(position, initializer); + case PrimaryConstructorBaseTypeSyntax initializer: + return GetSpeculativeSymbolInfo(position, initializer); case AttributeSyntax attribute: return GetSpeculativeSymbolInfo(position, attribute); case CrefSyntax cref: diff --git a/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs index bcaca17ced874..7ae4615fa0954 100644 --- a/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs @@ -30,7 +30,7 @@ private InitializerSemanticModel(CSharpSyntaxNode syntax, int speculatedPosition = 0) : base(syntax, symbol, rootBinder, containingSemanticModelOpt, parentSemanticModelOpt, snapshotManagerOpt: null, parentRemappedSymbolsOpt, speculatedPosition) { - Debug.Assert(!(syntax is ConstructorInitializerSyntax)); + Debug.Assert(!(syntax is ConstructorInitializerSyntax || syntax is PrimaryConstructorBaseTypeSyntax)); } /// @@ -104,11 +104,6 @@ internal override BoundNode GetBoundRoot() rootSyntax = ((EnumMemberDeclarationSyntax)rootSyntax).EqualsValue.Value; break; - case SyntaxKind.BaseConstructorInitializer: - case SyntaxKind.ThisConstructorInitializer: - case SyntaxKind.ArgumentList: - break; - case SyntaxKind.PropertyDeclaration: rootSyntax = ((PropertyDeclarationSyntax)rootSyntax).Initializer.Value; break; @@ -207,11 +202,6 @@ private bool IsBindableInitializer(CSharpSyntaxNode node) return this.Root == node || /*enum or parameter initializer*/ this.Root == node.Parent /*field initializer*/; - case SyntaxKind.BaseConstructorInitializer: - case SyntaxKind.ThisConstructorInitializer: - case SyntaxKind.ArgumentList: - return this.Root == node; - default: return false; } @@ -237,6 +227,12 @@ internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticMode return false; } + internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out SemanticModel speculativeModel) + { + speculativeModel = null; + return false; + } + internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ArrowExpressionClauseSyntax expressionBody, out SemanticModel speculativeModel) { speculativeModel = null; diff --git a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.SpeculativeMemberSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.SpeculativeMemberSemanticModel.cs index 197ac790a5366..9b41ade76912c 100644 --- a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.SpeculativeMemberSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.SpeculativeMemberSemanticModel.cs @@ -49,6 +49,11 @@ internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticMode throw ExceptionUtilities.Unreachable; } + internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out SemanticModel speculativeModel) + { + throw ExceptionUtilities.Unreachable; + } + internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, EqualsValueClauseSyntax initializer, out SemanticModel speculativeModel) { throw ExceptionUtilities.Unreachable; diff --git a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs index 6a2d25d132d91..233dc45f1f834 100644 --- a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs @@ -317,7 +317,7 @@ private static Binder GetEnclosingBinderInternalWithinRoot(SyntaxNode node, int { binder = rootBinder.GetBinder(current); } - else if (kind == SyntaxKind.ThisConstructorInitializer || kind == SyntaxKind.BaseConstructorInitializer || kind == SyntaxKind.SimpleBaseType) + else if (kind == SyntaxKind.ThisConstructorInitializer || kind == SyntaxKind.BaseConstructorInitializer || kind == SyntaxKind.PrimaryConstructorBaseType) { binder = rootBinder.GetBinder(current); } @@ -1549,6 +1549,7 @@ private CSharpSyntaxNode GetBindingRoot(CSharpSyntaxNode node) { case SyntaxKind.ThisConstructorInitializer: case SyntaxKind.BaseConstructorInitializer: + case SyntaxKind.PrimaryConstructorBaseType: return current; case SyntaxKind.ArrowExpressionClause: // If this is an arrow expression on a local function statement, then our bindable root is actually our parent syntax as it's @@ -2207,6 +2208,7 @@ internal protected virtual CSharpSyntaxNode GetBindableSyntaxNode(CSharpSyntaxNo !(node is JoinIntoClauseSyntax) && !(node is QueryContinuationSyntax) && !(node is ConstructorInitializerSyntax) && + !(node is PrimaryConstructorBaseTypeSyntax) && !(node is ArrowExpressionClauseSyntax) && !(node is PatternSyntax)) { @@ -2433,6 +2435,11 @@ internal override BoundExpressionStatement BindConstructorInitializer(Constructo return (BoundExpressionStatement)TryGetBoundNodeFromMap(node) ?? base.BindConstructorInitializer(node, diagnostics); } + internal override BoundExpressionStatement BindConstructorInitializer(PrimaryConstructorBaseTypeSyntax node, DiagnosticBag diagnostics) + { + return (BoundExpressionStatement)TryGetBoundNodeFromMap(node) ?? base.BindConstructorInitializer(node, diagnostics); + } + internal override BoundBlock BindExpressionBodyAsBlock(ArrowExpressionClauseSyntax node, DiagnosticBag diagnostics) { BoundBlock block = (BoundBlock)TryGetBoundNodeFromMap(node); diff --git a/src/Compilers/CSharp/Portable/Compilation/MethodBodySemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MethodBodySemanticModel.cs index 7a2090bd1e8d8..9a43b48c9a43d 100644 --- a/src/Compilers/CSharp/Portable/Compilation/MethodBodySemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/MethodBodySemanticModel.cs @@ -4,6 +4,7 @@ using System.Collections.Immutable; using System.Diagnostics; +using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -85,6 +86,9 @@ internal override BoundNode Bind(Binder binder, CSharpSyntaxNode node, Diagnosti case SyntaxKind.ThisConstructorInitializer: return binder.BindConstructorInitializer((ConstructorInitializerSyntax)node, diagnostics); + case SyntaxKind.PrimaryConstructorBaseType: + return binder.BindConstructorInitializer((PrimaryConstructorBaseTypeSyntax)node, diagnostics); + case SyntaxKind.MethodDeclaration: case SyntaxKind.ConversionOperatorDeclaration: case SyntaxKind.OperatorDeclaration: @@ -149,6 +153,19 @@ internal static MethodBodySemanticModel CreateSpeculative(SyntaxTreeSemanticMode return new MethodBodySemanticModel(owner, rootBinder, syntax, parentSemanticModelOpt: parentSemanticModel, speculatedPosition: position); } + /// + /// Creates a speculative SemanticModel for a constructor initializer that did not appear in the original source code. + /// + internal static MethodBodySemanticModel CreateSpeculative(SyntaxTreeSemanticModel parentSemanticModel, MethodSymbol owner, PrimaryConstructorBaseTypeSyntax syntax, Binder rootBinder, int position) + { + Debug.Assert(parentSemanticModel != null); + Debug.Assert(syntax != null); + Debug.Assert(rootBinder != null); + Debug.Assert(rootBinder.IsSemanticModelBinder); + + return new MethodBodySemanticModel(owner, rootBinder, syntax, parentSemanticModelOpt: parentSemanticModel, speculatedPosition: position); + } + internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, BaseMethodDeclarationSyntax method, out SemanticModel speculativeModel) { // CONSIDER: Do we want to ensure that speculated method and the original method have identical signatures? @@ -231,12 +248,12 @@ internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticMode internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, ConstructorInitializerSyntax constructorInitializer, out SemanticModel speculativeModel) { - if ((MemberSymbol as MethodSymbol)?.MethodKind == MethodKind.Constructor) + if (MemberSymbol is MethodSymbol methodSymbol && methodSymbol.MethodKind == MethodKind.Constructor && + Root.FindToken(position).Parent?.AncestorsAndSelf().OfType().FirstOrDefault()?.Parent == Root) { var binder = this.GetEnclosingBinder(position); if (binder != null) { - var methodSymbol = (MethodSymbol)this.MemberSymbol; binder = new WithNullableContextBinder(SyntaxTree, position, binder); binder = new ExecutableCodeBinder(constructorInitializer, methodSymbol, binder); speculativeModel = CreateSpeculative(parentModel, methodSymbol, constructorInitializer, binder, position); @@ -248,6 +265,25 @@ internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticMode return false; } + internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out SemanticModel speculativeModel) + { + if (MemberSymbol is SynthesizedRecordConstructor primaryCtor && + Root.FindToken(position).Parent?.AncestorsAndSelf().OfType().FirstOrDefault() == primaryCtor.GetSyntax().PrimaryConstructorBaseType) + { + var binder = this.GetEnclosingBinder(position); + if (binder != null) + { + binder = new WithNullableContextBinder(SyntaxTree, position, binder); + binder = new ExecutableCodeBinder(constructorInitializer, primaryCtor, binder); + speculativeModel = CreateSpeculative(parentModel, primaryCtor, constructorInitializer, binder, position); + return true; + } + } + + speculativeModel = null; + return false; + } + internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, EqualsValueClauseSyntax initializer, out SemanticModel speculativeModel) { speculativeModel = null; diff --git a/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs index e31435850de7a..1c5c44a5064d7 100644 --- a/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs @@ -711,10 +711,34 @@ internal sealed override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSeman { position = CheckAndAdjustPosition(position); - var model = this.GetMemberModel(position); - if (model != null) + var existingConstructorInitializer = this.Root.FindToken(position).Parent.AncestorsAndSelf().OfType().FirstOrDefault(); + + if (existingConstructorInitializer != null) + { + var model = this.GetMemberModel(position); + if (model != null) + { + return model.TryGetSpeculativeSemanticModelCore(parentModel, position, constructorInitializer, out speculativeModel); + } + } + + speculativeModel = null; + return false; + } + + internal sealed override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, PrimaryConstructorBaseTypeSyntax constructorInitializer, out SemanticModel speculativeModel) + { + position = CheckAndAdjustPosition(position); + + var existingConstructorInitializer = this.Root.FindToken(position).Parent.AncestorsAndSelf().OfType().FirstOrDefault(); + + if (existingConstructorInitializer != null) { - return model.TryGetSpeculativeSemanticModelCore(parentModel, position, constructorInitializer, out speculativeModel); + var model = this.GetMemberModel(existingConstructorInitializer); + if (model != null) + { + return model.TryGetSpeculativeSemanticModelCore(parentModel, position, constructorInitializer, out speculativeModel); + } } speculativeModel = null; @@ -784,7 +808,7 @@ private MemberSemanticModel GetMemberModel(int position) } else { - var argumentList = recordDecl.BaseWithArguments?.ArgumentList; + var argumentList = recordDecl.PrimaryConstructorBaseType?.ArgumentList; outsideMemberDecl = argumentList is null || !LookupPosition.IsBetweenTokens(position, argumentList.OpenParenToken, argumentList.CloseParenToken); } } @@ -846,7 +870,9 @@ internal override MemberSemanticModel GetMemberModel(SyntaxNode node) case SyntaxKind.RecordDeclaration: { var recordDecl = (RecordDeclarationSyntax)memberDecl; - return recordDecl.ParameterList is object && recordDecl.BaseWithArguments?.ArgumentList.FullSpan.Contains(span) == true ? GetOrAddModel(memberDecl) : null; + return recordDecl.ParameterList is object && + recordDecl.PrimaryConstructorBaseType is PrimaryConstructorBaseTypeSyntax baseWithArguments && + (node == baseWithArguments || baseWithArguments.ArgumentList.FullSpan.Contains(span)) ? GetOrAddModel(memberDecl) : null; } case SyntaxKind.DestructorDeclaration: diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 43ce114a6e3fa..eaf44f30d12dc 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1581,6 +1581,7 @@ internal enum ErrorCode WRN_TypeParameterSameAsOuterMethodTypeParameter = 8387, ERR_OutVariableCannotBeByRef = 8388, + ERR_OmittedTypeArgument = 8389, #region diagnostics introduced for C# 8.0 ERR_FeatureNotAvailableInVersion8 = 8400, diff --git a/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 b/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 index 9791532660a28..b522789a8b835 100644 --- a/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 +++ b/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 @@ -272,11 +272,16 @@ base_list ; base_type - : simple_base_type + : primary_constructor_base_type + | simple_base_type + ; + +primary_constructor_base_type + : type argument_list ; simple_base_type - : type argument_list? + : type ; enum_member_declaration diff --git a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs index 7c7c3d2403d0e..05ef43a82fc30 100644 --- a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs @@ -22279,50 +22279,124 @@ protected BaseTypeSyntax(ObjectReader reader) internal sealed partial class SimpleBaseTypeSyntax : BaseTypeSyntax { internal readonly TypeSyntax type; - internal readonly ArgumentListSyntax? argumentList; - internal SimpleBaseTypeSyntax(SyntaxKind kind, TypeSyntax type, ArgumentListSyntax? argumentList, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations) + internal SimpleBaseTypeSyntax(SyntaxKind kind, TypeSyntax type, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations) : base(kind, diagnostics, annotations) { - this.SlotCount = 2; + this.SlotCount = 1; this.AdjustFlagsAndWidth(type); this.type = type; - if (argumentList != null) + } + + internal SimpleBaseTypeSyntax(SyntaxKind kind, TypeSyntax type, SyntaxFactoryContext context) + : base(kind) + { + this.SetFactoryContext(context); + this.SlotCount = 1; + this.AdjustFlagsAndWidth(type); + this.type = type; + } + + internal SimpleBaseTypeSyntax(SyntaxKind kind, TypeSyntax type) + : base(kind) + { + this.SlotCount = 1; + this.AdjustFlagsAndWidth(type); + this.type = type; + } + + public override TypeSyntax Type => this.type; + + internal override GreenNode? GetSlot(int index) + => index == 0 ? this.type : null; + + internal override SyntaxNode CreateRed(SyntaxNode? parent, int position) => new CSharp.Syntax.SimpleBaseTypeSyntax(this, parent, position); + + public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSimpleBaseType(this); + public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSimpleBaseType(this); + + public SimpleBaseTypeSyntax Update(TypeSyntax type) + { + if (type != this.Type) { - this.AdjustFlagsAndWidth(argumentList); - this.argumentList = argumentList; + var newNode = SyntaxFactory.SimpleBaseType(type); + var diags = GetDiagnostics(); + if (diags?.Length > 0) + newNode = newNode.WithDiagnosticsGreen(diags); + var annotations = GetAnnotations(); + if (annotations?.Length > 0) + newNode = newNode.WithAnnotationsGreen(annotations); + return newNode; } + + return this; + } + + internal override GreenNode SetDiagnostics(DiagnosticInfo[]? diagnostics) + => new SimpleBaseTypeSyntax(this.Kind, this.type, diagnostics, GetAnnotations()); + + internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations) + => new SimpleBaseTypeSyntax(this.Kind, this.type, GetDiagnostics(), annotations); + + internal SimpleBaseTypeSyntax(ObjectReader reader) + : base(reader) + { + this.SlotCount = 1; + var type = (TypeSyntax)reader.ReadValue(); + AdjustFlagsAndWidth(type); + this.type = type; + } + + internal override void WriteTo(ObjectWriter writer) + { + base.WriteTo(writer); + writer.WriteValue(this.type); + } + + static SimpleBaseTypeSyntax() + { + ObjectBinder.RegisterTypeReader(typeof(SimpleBaseTypeSyntax), r => new SimpleBaseTypeSyntax(r)); + } + } + + internal sealed partial class PrimaryConstructorBaseTypeSyntax : BaseTypeSyntax + { + internal readonly TypeSyntax type; + internal readonly ArgumentListSyntax argumentList; + + internal PrimaryConstructorBaseTypeSyntax(SyntaxKind kind, TypeSyntax type, ArgumentListSyntax argumentList, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations) + : base(kind, diagnostics, annotations) + { + this.SlotCount = 2; + this.AdjustFlagsAndWidth(type); + this.type = type; + this.AdjustFlagsAndWidth(argumentList); + this.argumentList = argumentList; } - internal SimpleBaseTypeSyntax(SyntaxKind kind, TypeSyntax type, ArgumentListSyntax? argumentList, SyntaxFactoryContext context) + internal PrimaryConstructorBaseTypeSyntax(SyntaxKind kind, TypeSyntax type, ArgumentListSyntax argumentList, SyntaxFactoryContext context) : base(kind) { this.SetFactoryContext(context); this.SlotCount = 2; this.AdjustFlagsAndWidth(type); this.type = type; - if (argumentList != null) - { - this.AdjustFlagsAndWidth(argumentList); - this.argumentList = argumentList; - } + this.AdjustFlagsAndWidth(argumentList); + this.argumentList = argumentList; } - internal SimpleBaseTypeSyntax(SyntaxKind kind, TypeSyntax type, ArgumentListSyntax? argumentList) + internal PrimaryConstructorBaseTypeSyntax(SyntaxKind kind, TypeSyntax type, ArgumentListSyntax argumentList) : base(kind) { this.SlotCount = 2; this.AdjustFlagsAndWidth(type); this.type = type; - if (argumentList != null) - { - this.AdjustFlagsAndWidth(argumentList); - this.argumentList = argumentList; - } + this.AdjustFlagsAndWidth(argumentList); + this.argumentList = argumentList; } public override TypeSyntax Type => this.type; - public ArgumentListSyntax? ArgumentList => this.argumentList; + public ArgumentListSyntax ArgumentList => this.argumentList; internal override GreenNode? GetSlot(int index) => index switch @@ -22332,16 +22406,16 @@ internal SimpleBaseTypeSyntax(SyntaxKind kind, TypeSyntax type, ArgumentListSynt _ => null, }; - internal override SyntaxNode CreateRed(SyntaxNode? parent, int position) => new CSharp.Syntax.SimpleBaseTypeSyntax(this, parent, position); + internal override SyntaxNode CreateRed(SyntaxNode? parent, int position) => new CSharp.Syntax.PrimaryConstructorBaseTypeSyntax(this, parent, position); - public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSimpleBaseType(this); - public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSimpleBaseType(this); + public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitPrimaryConstructorBaseType(this); + public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitPrimaryConstructorBaseType(this); - public SimpleBaseTypeSyntax Update(TypeSyntax type, ArgumentListSyntax argumentList) + public PrimaryConstructorBaseTypeSyntax Update(TypeSyntax type, ArgumentListSyntax argumentList) { if (type != this.Type || argumentList != this.ArgumentList) { - var newNode = SyntaxFactory.SimpleBaseType(type, argumentList); + var newNode = SyntaxFactory.PrimaryConstructorBaseType(type, argumentList); var diags = GetDiagnostics(); if (diags?.Length > 0) newNode = newNode.WithDiagnosticsGreen(diags); @@ -22355,24 +22429,21 @@ public SimpleBaseTypeSyntax Update(TypeSyntax type, ArgumentListSyntax argumentL } internal override GreenNode SetDiagnostics(DiagnosticInfo[]? diagnostics) - => new SimpleBaseTypeSyntax(this.Kind, this.type, this.argumentList, diagnostics, GetAnnotations()); + => new PrimaryConstructorBaseTypeSyntax(this.Kind, this.type, this.argumentList, diagnostics, GetAnnotations()); internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations) - => new SimpleBaseTypeSyntax(this.Kind, this.type, this.argumentList, GetDiagnostics(), annotations); + => new PrimaryConstructorBaseTypeSyntax(this.Kind, this.type, this.argumentList, GetDiagnostics(), annotations); - internal SimpleBaseTypeSyntax(ObjectReader reader) + internal PrimaryConstructorBaseTypeSyntax(ObjectReader reader) : base(reader) { this.SlotCount = 2; var type = (TypeSyntax)reader.ReadValue(); AdjustFlagsAndWidth(type); this.type = type; - var argumentList = (ArgumentListSyntax?)reader.ReadValue(); - if (argumentList != null) - { - AdjustFlagsAndWidth(argumentList); - this.argumentList = argumentList; - } + var argumentList = (ArgumentListSyntax)reader.ReadValue(); + AdjustFlagsAndWidth(argumentList); + this.argumentList = argumentList; } internal override void WriteTo(ObjectWriter writer) @@ -22382,9 +22453,9 @@ internal override void WriteTo(ObjectWriter writer) writer.WriteValue(this.argumentList); } - static SimpleBaseTypeSyntax() + static PrimaryConstructorBaseTypeSyntax() { - ObjectBinder.RegisterTypeReader(typeof(SimpleBaseTypeSyntax), r => new SimpleBaseTypeSyntax(r)); + ObjectBinder.RegisterTypeReader(typeof(PrimaryConstructorBaseTypeSyntax), r => new PrimaryConstructorBaseTypeSyntax(r)); } } @@ -32376,6 +32447,7 @@ internal partial class CSharpSyntaxVisitor public virtual TResult VisitEnumMemberDeclaration(EnumMemberDeclarationSyntax node) => this.DefaultVisit(node); public virtual TResult VisitBaseList(BaseListSyntax node) => this.DefaultVisit(node); public virtual TResult VisitSimpleBaseType(SimpleBaseTypeSyntax node) => this.DefaultVisit(node); + public virtual TResult VisitPrimaryConstructorBaseType(PrimaryConstructorBaseTypeSyntax node) => this.DefaultVisit(node); public virtual TResult VisitTypeParameterConstraintClause(TypeParameterConstraintClauseSyntax node) => this.DefaultVisit(node); public virtual TResult VisitConstructorConstraint(ConstructorConstraintSyntax node) => this.DefaultVisit(node); public virtual TResult VisitClassOrStructConstraint(ClassOrStructConstraintSyntax node) => this.DefaultVisit(node); @@ -32604,6 +32676,7 @@ internal partial class CSharpSyntaxVisitor public virtual void VisitEnumMemberDeclaration(EnumMemberDeclarationSyntax node) => this.DefaultVisit(node); public virtual void VisitBaseList(BaseListSyntax node) => this.DefaultVisit(node); public virtual void VisitSimpleBaseType(SimpleBaseTypeSyntax node) => this.DefaultVisit(node); + public virtual void VisitPrimaryConstructorBaseType(PrimaryConstructorBaseTypeSyntax node) => this.DefaultVisit(node); public virtual void VisitTypeParameterConstraintClause(TypeParameterConstraintClauseSyntax node) => this.DefaultVisit(node); public virtual void VisitConstructorConstraint(ConstructorConstraintSyntax node) => this.DefaultVisit(node); public virtual void VisitClassOrStructConstraint(ClassOrStructConstraintSyntax node) => this.DefaultVisit(node); @@ -33148,6 +33221,9 @@ public override CSharpSyntaxNode VisitBaseList(BaseListSyntax node) => node.Update((SyntaxToken)Visit(node.ColonToken), VisitList(node.Types)); public override CSharpSyntaxNode VisitSimpleBaseType(SimpleBaseTypeSyntax node) + => node.Update((TypeSyntax)Visit(node.Type)); + + public override CSharpSyntaxNode VisitPrimaryConstructorBaseType(PrimaryConstructorBaseTypeSyntax node) => node.Update((TypeSyntax)Visit(node.Type), (ArgumentListSyntax)Visit(node.ArgumentList)); public override CSharpSyntaxNode VisitTypeParameterConstraintClause(TypeParameterConstraintClauseSyntax node) @@ -36736,17 +36812,37 @@ public BaseListSyntax BaseList(SyntaxToken colonToken, Microsoft.CodeAnalysis.Sy return result; } - public SimpleBaseTypeSyntax SimpleBaseType(TypeSyntax type, ArgumentListSyntax? argumentList) + public SimpleBaseTypeSyntax SimpleBaseType(TypeSyntax type) { #if DEBUG if (type == null) throw new ArgumentNullException(nameof(type)); #endif int hash; - var cached = CSharpSyntaxNodeCache.TryGetNode((int)SyntaxKind.SimpleBaseType, type, argumentList, this.context, out hash); + var cached = CSharpSyntaxNodeCache.TryGetNode((int)SyntaxKind.SimpleBaseType, type, this.context, out hash); if (cached != null) return (SimpleBaseTypeSyntax)cached; - var result = new SimpleBaseTypeSyntax(SyntaxKind.SimpleBaseType, type, argumentList, this.context); + var result = new SimpleBaseTypeSyntax(SyntaxKind.SimpleBaseType, type, this.context); + if (hash >= 0) + { + SyntaxNodeCache.AddNode(result, hash); + } + + return result; + } + + public PrimaryConstructorBaseTypeSyntax PrimaryConstructorBaseType(TypeSyntax type, ArgumentListSyntax argumentList) + { +#if DEBUG + if (type == null) throw new ArgumentNullException(nameof(type)); + if (argumentList == null) throw new ArgumentNullException(nameof(argumentList)); +#endif + + int hash; + var cached = CSharpSyntaxNodeCache.TryGetNode((int)SyntaxKind.PrimaryConstructorBaseType, type, argumentList, this.context, out hash); + if (cached != null) return (PrimaryConstructorBaseTypeSyntax)cached; + + var result = new PrimaryConstructorBaseTypeSyntax(SyntaxKind.PrimaryConstructorBaseType, type, argumentList, this.context); if (hash >= 0) { SyntaxNodeCache.AddNode(result, hash); @@ -41486,17 +41582,37 @@ public static BaseListSyntax BaseList(SyntaxToken colonToken, Microsoft.CodeAnal return result; } - public static SimpleBaseTypeSyntax SimpleBaseType(TypeSyntax type, ArgumentListSyntax? argumentList) + public static SimpleBaseTypeSyntax SimpleBaseType(TypeSyntax type) { #if DEBUG if (type == null) throw new ArgumentNullException(nameof(type)); #endif int hash; - var cached = SyntaxNodeCache.TryGetNode((int)SyntaxKind.SimpleBaseType, type, argumentList, out hash); + var cached = SyntaxNodeCache.TryGetNode((int)SyntaxKind.SimpleBaseType, type, out hash); if (cached != null) return (SimpleBaseTypeSyntax)cached; - var result = new SimpleBaseTypeSyntax(SyntaxKind.SimpleBaseType, type, argumentList); + var result = new SimpleBaseTypeSyntax(SyntaxKind.SimpleBaseType, type); + if (hash >= 0) + { + SyntaxNodeCache.AddNode(result, hash); + } + + return result; + } + + public static PrimaryConstructorBaseTypeSyntax PrimaryConstructorBaseType(TypeSyntax type, ArgumentListSyntax argumentList) + { +#if DEBUG + if (type == null) throw new ArgumentNullException(nameof(type)); + if (argumentList == null) throw new ArgumentNullException(nameof(argumentList)); +#endif + + int hash; + var cached = SyntaxNodeCache.TryGetNode((int)SyntaxKind.PrimaryConstructorBaseType, type, argumentList, out hash); + if (cached != null) return (PrimaryConstructorBaseTypeSyntax)cached; + + var result = new PrimaryConstructorBaseTypeSyntax(SyntaxKind.PrimaryConstructorBaseType, type, argumentList); if (hash >= 0) { SyntaxNodeCache.AddNode(result, hash); @@ -43012,6 +43128,7 @@ internal static IEnumerable GetNodeTypes() typeof(EnumMemberDeclarationSyntax), typeof(BaseListSyntax), typeof(SimpleBaseTypeSyntax), + typeof(PrimaryConstructorBaseTypeSyntax), typeof(TypeParameterConstraintClauseSyntax), typeof(ConstructorConstraintSyntax), typeof(ClassOrStructConstraintSyntax), diff --git a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs index 9ab4b6174aa34..2940354e56d5f 100644 --- a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Main.Generated.cs @@ -651,6 +651,10 @@ public partial class CSharpSyntaxVisitor [return: MaybeNull] public virtual TResult VisitSimpleBaseType(SimpleBaseTypeSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a PrimaryConstructorBaseTypeSyntax node. + [return: MaybeNull] + public virtual TResult VisitPrimaryConstructorBaseType(PrimaryConstructorBaseTypeSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a TypeParameterConstraintClauseSyntax node. [return: MaybeNull] public virtual TResult VisitTypeParameterConstraintClause(TypeParameterConstraintClauseSyntax node) => this.DefaultVisit(node); @@ -1391,6 +1395,9 @@ public partial class CSharpSyntaxVisitor /// Called when the visitor visits a SimpleBaseTypeSyntax node. public virtual void VisitSimpleBaseType(SimpleBaseTypeSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a PrimaryConstructorBaseTypeSyntax node. + public virtual void VisitPrimaryConstructorBaseType(PrimaryConstructorBaseTypeSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a TypeParameterConstraintClauseSyntax node. public virtual void VisitTypeParameterConstraintClause(TypeParameterConstraintClauseSyntax node) => this.DefaultVisit(node); @@ -2064,7 +2071,10 @@ public partial class CSharpSyntaxRewriter : CSharpSyntaxVisitor => node.Update(VisitToken(node.ColonToken), VisitList(node.Types)); public override SyntaxNode? VisitSimpleBaseType(SimpleBaseTypeSyntax node) - => node.Update((TypeSyntax?)Visit(node.Type) ?? throw new ArgumentNullException("type"), (ArgumentListSyntax?)Visit(node.ArgumentList)); + => node.Update((TypeSyntax?)Visit(node.Type) ?? throw new ArgumentNullException("type")); + + public override SyntaxNode? VisitPrimaryConstructorBaseType(PrimaryConstructorBaseTypeSyntax node) + => node.Update((TypeSyntax?)Visit(node.Type) ?? throw new ArgumentNullException("type"), (ArgumentListSyntax?)Visit(node.ArgumentList) ?? throw new ArgumentNullException("argumentList")); public override SyntaxNode? VisitTypeParameterConstraintClause(TypeParameterConstraintClauseSyntax node) => node.Update(VisitToken(node.WhereKeyword), (IdentifierNameSyntax?)Visit(node.Name) ?? throw new ArgumentNullException("name"), VisitToken(node.ColonToken), VisitList(node.Constraints)); @@ -5044,15 +5054,23 @@ public static BaseListSyntax BaseList(SeparatedSyntaxList types => SyntaxFactory.BaseList(SyntaxFactory.Token(SyntaxKind.ColonToken), types); /// Creates a new SimpleBaseTypeSyntax instance. - public static SimpleBaseTypeSyntax SimpleBaseType(TypeSyntax type, ArgumentListSyntax? argumentList) + public static SimpleBaseTypeSyntax SimpleBaseType(TypeSyntax type) { if (type == null) throw new ArgumentNullException(nameof(type)); - return (SimpleBaseTypeSyntax)Syntax.InternalSyntax.SyntaxFactory.SimpleBaseType((Syntax.InternalSyntax.TypeSyntax)type.Green, argumentList == null ? null : (Syntax.InternalSyntax.ArgumentListSyntax)argumentList.Green).CreateRed(); + return (SimpleBaseTypeSyntax)Syntax.InternalSyntax.SyntaxFactory.SimpleBaseType((Syntax.InternalSyntax.TypeSyntax)type.Green).CreateRed(); } - /// Creates a new SimpleBaseTypeSyntax instance. - public static SimpleBaseTypeSyntax SimpleBaseType(TypeSyntax type) - => SyntaxFactory.SimpleBaseType(type, default); + /// Creates a new PrimaryConstructorBaseTypeSyntax instance. + public static PrimaryConstructorBaseTypeSyntax PrimaryConstructorBaseType(TypeSyntax type, ArgumentListSyntax argumentList) + { + if (type == null) throw new ArgumentNullException(nameof(type)); + if (argumentList == null) throw new ArgumentNullException(nameof(argumentList)); + return (PrimaryConstructorBaseTypeSyntax)Syntax.InternalSyntax.SyntaxFactory.PrimaryConstructorBaseType((Syntax.InternalSyntax.TypeSyntax)type.Green, (Syntax.InternalSyntax.ArgumentListSyntax)argumentList.Green).CreateRed(); + } + + /// Creates a new PrimaryConstructorBaseTypeSyntax instance. + public static PrimaryConstructorBaseTypeSyntax PrimaryConstructorBaseType(TypeSyntax type) + => SyntaxFactory.PrimaryConstructorBaseType(type, SyntaxFactory.ArgumentList()); /// Creates a new TypeParameterConstraintClauseSyntax instance. public static TypeParameterConstraintClauseSyntax TypeParameterConstraintClause(SyntaxToken whereKeyword, IdentifierNameSyntax name, SyntaxToken colonToken, SeparatedSyntaxList constraints) diff --git a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs index 88d43df3f1f7f..0535a9109294c 100644 --- a/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/Syntax.xml.Syntax.Generated.cs @@ -9578,7 +9578,6 @@ internal BaseTypeSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? paren public sealed partial class SimpleBaseTypeSyntax : BaseTypeSyntax { private TypeSyntax? type; - private ArgumentListSyntax? argumentList; internal SimpleBaseTypeSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position) : base(green, parent, position) @@ -9587,13 +9586,49 @@ internal SimpleBaseTypeSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? public override TypeSyntax Type => GetRedAtZero(ref this.type)!; - public ArgumentListSyntax? ArgumentList => GetRed(ref this.argumentList, 1); + internal override SyntaxNode? GetNodeSlot(int index) => index == 0 ? GetRedAtZero(ref this.type)! : null; + + internal override SyntaxNode? GetCachedSlot(int index) => index == 0 ? this.type : null; + + public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSimpleBaseType(this); + [return: MaybeNull] + public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSimpleBaseType(this); + + public SimpleBaseTypeSyntax Update(TypeSyntax type) + { + if (type != this.Type) + { + var newNode = SyntaxFactory.SimpleBaseType(type); + var annotations = GetAnnotations(); + return annotations?.Length > 0 ? newNode.WithAnnotations(annotations) : newNode; + } + + return this; + } + + internal override BaseTypeSyntax WithTypeCore(TypeSyntax type) => WithType(type); + public new SimpleBaseTypeSyntax WithType(TypeSyntax type) => Update(type); + } + + public sealed partial class PrimaryConstructorBaseTypeSyntax : BaseTypeSyntax + { + private TypeSyntax? type; + private ArgumentListSyntax? argumentList; + + internal PrimaryConstructorBaseTypeSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position) + : base(green, parent, position) + { + } + + public override TypeSyntax Type => GetRedAtZero(ref this.type)!; + + public ArgumentListSyntax ArgumentList => GetRed(ref this.argumentList, 1)!; internal override SyntaxNode? GetNodeSlot(int index) => index switch { 0 => GetRedAtZero(ref this.type)!, - 1 => GetRed(ref this.argumentList, 1), + 1 => GetRed(ref this.argumentList, 1)!, _ => null, }; @@ -9605,15 +9640,15 @@ internal SimpleBaseTypeSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? _ => null, }; - public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSimpleBaseType(this); + public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitPrimaryConstructorBaseType(this); [return: MaybeNull] - public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitSimpleBaseType(this); + public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitPrimaryConstructorBaseType(this); - public SimpleBaseTypeSyntax Update(TypeSyntax type, ArgumentListSyntax? argumentList) + public PrimaryConstructorBaseTypeSyntax Update(TypeSyntax type, ArgumentListSyntax argumentList) { if (type != this.Type || argumentList != this.ArgumentList) { - var newNode = SyntaxFactory.SimpleBaseType(type, argumentList); + var newNode = SyntaxFactory.PrimaryConstructorBaseType(type, argumentList); var annotations = GetAnnotations(); return annotations?.Length > 0 ? newNode.WithAnnotations(annotations) : newNode; } @@ -9622,14 +9657,10 @@ public SimpleBaseTypeSyntax Update(TypeSyntax type, ArgumentListSyntax? argument } internal override BaseTypeSyntax WithTypeCore(TypeSyntax type) => WithType(type); - public new SimpleBaseTypeSyntax WithType(TypeSyntax type) => Update(type, this.ArgumentList); - public SimpleBaseTypeSyntax WithArgumentList(ArgumentListSyntax? argumentList) => Update(this.Type, argumentList); + public new PrimaryConstructorBaseTypeSyntax WithType(TypeSyntax type) => Update(type, this.ArgumentList); + public PrimaryConstructorBaseTypeSyntax WithArgumentList(ArgumentListSyntax argumentList) => Update(this.Type, argumentList); - public SimpleBaseTypeSyntax AddArgumentListArguments(params ArgumentSyntax[] items) - { - var argumentList = this.ArgumentList ?? SyntaxFactory.ArgumentList(); - return WithArgumentList(argumentList.WithArguments(argumentList.Arguments.AddRange(items))); - } + public PrimaryConstructorBaseTypeSyntax AddArgumentListArguments(params ArgumentSyntax[] items) => WithArgumentList(this.ArgumentList.WithArguments(this.ArgumentList.Arguments.AddRange(items))); } /// Type parameter constraint clause. diff --git a/src/Compilers/CSharp/Portable/GlobalSuppressions.cs b/src/Compilers/CSharp/Portable/GlobalSuppressions.cs index 90b587b285b06..2f30945ffdf54 100644 --- a/src/Compilers/CSharp/Portable/GlobalSuppressions.cs +++ b/src/Compilers/CSharp/Portable/GlobalSuppressions.cs @@ -36,3 +36,5 @@ [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeconstructionPatternClause(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.SubpatternSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionPatternClauseSyntax")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.FunctionPointerType(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetDeclaredSymbol(Microsoft.CodeAnalysis.SemanticModel,Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax,System.Threading.CancellationToken)~Microsoft.CodeAnalysis.IMethodSymbol")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetSymbolInfo(Microsoft.CodeAnalysis.SemanticModel,Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax,System.Threading.CancellationToken)~Microsoft.CodeAnalysis.SymbolInfo")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetMemberGroup(Microsoft.CodeAnalysis.SemanticModel,Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax,System.Threading.CancellationToken)~System.Collections.Immutable.ImmutableArray{Microsoft.CodeAnalysis.ISymbol}")] diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index 78ad6ac933582..6b8ce9bac91d9 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -1197,6 +1197,8 @@ private static void AppendMissingOptionalArguments( case SyntaxKind.BaseConstructorInitializer: case SyntaxKind.ThisConstructorInitializer: return new SourceLocation(((ConstructorInitializerSyntax)syntax).ArgumentList.OpenParenToken); + case SyntaxKind.PrimaryConstructorBaseType: + return new SourceLocation(((PrimaryConstructorBaseTypeSyntax)syntax).ArgumentList.OpenParenToken); case SyntaxKind.ElementAccessExpression: return new SourceLocation(((ElementAccessExpressionSyntax)syntax).ArgumentList.OpenBracketToken); case SyntaxKind.FromClause: diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 3f882b1b18ed0..53d6fe582c8be 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -1752,7 +1752,7 @@ private BaseListSyntax ParseBaseList(SyntaxToken typeKeyword, bool haveParameter } } - list.Add(_syntaxFactory.SimpleBaseType(firstType, argumentList)); + list.Add(argumentList is object ? _syntaxFactory.PrimaryConstructorBaseType(firstType, argumentList) : (BaseTypeSyntax)_syntaxFactory.SimpleBaseType(firstType)); // any additional types while (true) @@ -1766,7 +1766,7 @@ private BaseListSyntax ParseBaseList(SyntaxToken typeKeyword, bool haveParameter else if (this.CurrentToken.Kind == SyntaxKind.CommaToken || this.IsPossibleType()) { list.AddSeparator(this.EatToken(SyntaxKind.CommaToken)); - list.Add(_syntaxFactory.SimpleBaseType(this.ParseType(), argumentList: null)); + list.Add(_syntaxFactory.SimpleBaseType(this.ParseType())); continue; } else if (this.SkipBadBaseListTokens(ref colon, list, SyntaxKind.CommaToken) == PostSkipAction.Abort) @@ -5013,7 +5013,7 @@ private EnumDeclarationSyntax ParseEnumDeclaration(SyntaxList(); - tmpList.Add(_syntaxFactory.SimpleBaseType(type, argumentList: null)); + tmpList.Add(_syntaxFactory.SimpleBaseType(type)); baseList = _syntaxFactory.BaseList(colon, tmpList); _pool.Free(tmpList); } diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt index a940e60957f16..5a357a9120c6e 100644 --- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt @@ -1,6 +1,12 @@ *REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.ObjectCreationExpressionSyntax.ArgumentList.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax *REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.ObjectCreationExpressionSyntax.Initializer.get -> Microsoft.CodeAnalysis.CSharp.Syntax.InitializerExpressionSyntax *REMOVED*Microsoft.CodeAnalysis.CSharp.Syntax.ObjectCreationExpressionSyntax.NewKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken +Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax.AddArgumentListArguments(params Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax.ArgumentList.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax.Update(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax argumentList) -> Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax.WithArgumentList(Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax argumentList) -> Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax.WithType(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type) -> Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.AddAttributeLists(params Microsoft.CodeAnalysis.CSharp.Syntax.AttributeListSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.AddBaseListTypes(params Microsoft.CodeAnalysis.CSharp.Syntax.BaseTypeSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax @@ -23,10 +29,7 @@ Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.WithOpenBraceToken( Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.WithParameterList(Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList) -> Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.WithSemicolonToken(Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.WithTypeParameterList(Microsoft.CodeAnalysis.CSharp.Syntax.TypeParameterListSyntax typeParameterList) -> Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.SimpleBaseTypeSyntax.AddArgumentListArguments(params Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.SimpleBaseTypeSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.SimpleBaseTypeSyntax.ArgumentList.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.SimpleBaseTypeSyntax.Update(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax argumentList) -> Microsoft.CodeAnalysis.CSharp.Syntax.SimpleBaseTypeSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.SimpleBaseTypeSyntax.WithArgumentList(Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax argumentList) -> Microsoft.CodeAnalysis.CSharp.Syntax.SimpleBaseTypeSyntax +Microsoft.CodeAnalysis.CSharp.SyntaxKind.PrimaryConstructorBaseType = 9065 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.RecordDeclaration = 9063 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.RecordKeyword = 8444 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind abstract Microsoft.CodeAnalysis.CSharp.Syntax.BaseObjectCreationExpressionSyntax.ArgumentList.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax @@ -51,9 +54,13 @@ Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax.WithLessThanToken Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax.WithParameters(Microsoft.CodeAnalysis.SeparatedSyntaxList parameters) -> Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax Microsoft.CodeAnalysis.CSharp.SyntaxKind.FunctionPointerType = 9056 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitFunctionPointerType(Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode +override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitPrimaryConstructorBaseType(Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitRecordDeclaration(Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void override Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult +override Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void +override Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult +override Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax.Type.get -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax override Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void override Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult override Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.AttributeLists.get -> Microsoft.CodeAnalysis.SyntaxList @@ -67,6 +74,9 @@ override Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.Modifiers. override Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.OpenBraceToken.get -> Microsoft.CodeAnalysis.SyntaxToken override Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.SemicolonToken.get -> Microsoft.CodeAnalysis.SyntaxToken override Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax.TypeParameterList.get -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeParameterListSyntax +static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetSpeculativeSymbolInfo(this Microsoft.CodeAnalysis.SemanticModel semanticModel, int position, Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax constructorInitializer) -> Microsoft.CodeAnalysis.SymbolInfo +static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetSymbolInfo(this Microsoft.CodeAnalysis.SemanticModel semanticModel, Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax constructorInitializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.SymbolInfo +static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.TryGetSpeculativeSemanticModel(this Microsoft.CodeAnalysis.SemanticModel semanticModel, int position, Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax constructorInitializer, out Microsoft.CodeAnalysis.SemanticModel speculativeModel) -> bool static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.FunctionPointerType(Microsoft.CodeAnalysis.SeparatedSyntaxList parameters = default(Microsoft.CodeAnalysis.SeparatedSyntaxList)) -> Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.FunctionPointerType(Microsoft.CodeAnalysis.SyntaxToken callingConvention, Microsoft.CodeAnalysis.SeparatedSyntaxList parameters) -> Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.FunctionPointerType(Microsoft.CodeAnalysis.SyntaxToken delegateKeyword, Microsoft.CodeAnalysis.SyntaxToken asteriskToken, Microsoft.CodeAnalysis.SyntaxToken callingConvention, Microsoft.CodeAnalysis.SyntaxToken lessThanToken, Microsoft.CodeAnalysis.SeparatedSyntaxList parameters, Microsoft.CodeAnalysis.SyntaxToken greaterThanToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax @@ -176,6 +186,8 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ImplicitObjectCreationExpress static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ImplicitObjectCreationExpression(Microsoft.CodeAnalysis.SyntaxToken newKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax argumentList, Microsoft.CodeAnalysis.CSharp.Syntax.InitializerExpressionSyntax initializer) -> Microsoft.CodeAnalysis.CSharp.Syntax.ImplicitObjectCreationExpressionSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseTypeName(string text, int offset = 0, Microsoft.CodeAnalysis.ParseOptions options = null, bool consumeFullText = true) -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseTypeName(string text, int offset, bool consumeFullText) -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.PrimaryConstructorBaseType(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type) -> Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.PrimaryConstructorBaseType(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax argumentList) -> Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.RecordDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken keyword, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.TypeParameterListSyntax typeParameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BaseListSyntax baseList, Microsoft.CodeAnalysis.SyntaxList constraintClauses, Microsoft.CodeAnalysis.SyntaxList members) -> Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.RecordDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken keyword, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.TypeParameterListSyntax typeParameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BaseListSyntax baseList, Microsoft.CodeAnalysis.SyntaxList constraintClauses, Microsoft.CodeAnalysis.SyntaxToken openBraceToken, Microsoft.CodeAnalysis.SyntaxList members, Microsoft.CodeAnalysis.SyntaxToken closeBraceToken, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.RecordDeclaration(Microsoft.CodeAnalysis.SyntaxToken keyword, Microsoft.CodeAnalysis.SyntaxToken identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax @@ -183,12 +195,12 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.RecordDeclaration(Microsoft.C static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.WithExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.CSharp.Syntax.InitializerExpressionSyntax initializer) -> Microsoft.CodeAnalysis.CSharp.Syntax.WithExpressionSyntax virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitFunctionPointerType(Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitParenthesizedPattern(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedPatternSyntax node) -> void +virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitPrimaryConstructorBaseType(Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitRecordDeclaration(Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitFunctionPointerType(Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerTypeSyntax node) -> TResult static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParenthesizedPattern(Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax pattern) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedPatternSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParenthesizedPattern(Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax pattern, Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedPatternSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.RelationalPattern(Microsoft.CodeAnalysis.SyntaxToken operatorToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression) -> Microsoft.CodeAnalysis.CSharp.Syntax.RelationalPatternSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.SimpleBaseType(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax argumentList) -> Microsoft.CodeAnalysis.CSharp.Syntax.SimpleBaseTypeSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.TypePattern(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type) -> Microsoft.CodeAnalysis.CSharp.Syntax.TypePatternSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.UnaryPattern(Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax pattern) -> Microsoft.CodeAnalysis.CSharp.Syntax.UnaryPatternSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.UnaryPattern(Microsoft.CodeAnalysis.SyntaxToken operatorToken, Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax pattern) -> Microsoft.CodeAnalysis.CSharp.Syntax.UnaryPatternSyntax @@ -208,6 +220,7 @@ virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitWithExpression(Mi virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitBinaryPattern(Microsoft.CodeAnalysis.CSharp.Syntax.BinaryPatternSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitImplicitObjectCreationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ImplicitObjectCreationExpressionSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitParenthesizedPattern(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedPatternSyntax node) -> TResult +virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitPrimaryConstructorBaseType(Microsoft.CodeAnalysis.CSharp.Syntax.PrimaryConstructorBaseTypeSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitRecordDeclaration(Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitRelationalPattern(Microsoft.CodeAnalysis.CSharp.Syntax.RelationalPatternSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitTypePattern(Microsoft.CodeAnalysis.CSharp.Syntax.TypePatternSyntax node) -> TResult diff --git a/src/Compilers/CSharp/Portable/Symbols/Attributes/AttributeData.cs b/src/Compilers/CSharp/Portable/Symbols/Attributes/AttributeData.cs index 3b7206d7ed084..7c6061f946cee 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Attributes/AttributeData.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Attributes/AttributeData.cs @@ -370,8 +370,8 @@ private DeclarativeSecurityAction DecodeSecurityAttributeAction(Symbol targetSym else { TypedConstant firstArg = ctorArgs.First(); - TypeSymbol firstArgType = (TypeSymbol)firstArg.TypeInternal; - if ((object)firstArgType != null && firstArgType.Equals(compilation.GetWellKnownType(WellKnownType.System_Security_Permissions_SecurityAction))) + var firstArgType = (TypeSymbol?)firstArg.TypeInternal; + if (firstArgType is object && firstArgType.Equals(compilation.GetWellKnownType(WellKnownType.System_Security_Permissions_SecurityAction))) { return DecodeSecurityAction(firstArg, targetSymbol, nodeOpt, diagnostics, out hasErrors); } @@ -387,6 +387,7 @@ private DeclarativeSecurityAction DecodeSecurityAction(TypedConstant typedValue, { Debug.Assert((object)targetSymbol != null); Debug.Assert(targetSymbol.Kind == SymbolKind.Assembly || targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method); + Debug.Assert(typedValue.ValueInternal is object); int securityAction = (int)typedValue.ValueInternal; bool isPermissionRequestAction; @@ -527,15 +528,15 @@ private static Location GetSecurityAttributeActionSyntaxLocation(AttributeSyntax PermissionSetAttributeTypeHasRequiredProperty(attrType, filePropName)) { // resolve file prop path - var fileName = (string)namedArg.Value.ValueInternal; + var fileName = (string?)namedArg.Value.ValueInternal; var resolver = compilation.Options.XmlReferenceResolver; - resolvedFilePath = (resolver != null) ? resolver.ResolveReference(fileName, baseFilePath: null) : null; + resolvedFilePath = (resolver != null && fileName != null) ? resolver.ResolveReference(fileName, baseFilePath: null) : null; if (resolvedFilePath == null) { // CS7053: Unable to resolve file path '{0}' specified for the named argument '{1}' for PermissionSet attribute - Location argSyntaxLocation = nodeOpt != null ? nodeOpt.GetNamedArgumentSyntax(filePropName).Location : NoLocation.Singleton; + Location argSyntaxLocation = nodeOpt?.GetNamedArgumentSyntax(filePropName)?.Location ?? NoLocation.Singleton; diagnostics.Add(ErrorCode.ERR_PermissionSetAttributeInvalidFile, argSyntaxLocation, fileName ?? "", filePropName); } else if (!PermissionSetAttributeTypeHasRequiredProperty(attrType, hexPropName)) @@ -629,7 +630,7 @@ internal string DecodeGuidAttribute(AttributeSyntax? nodeOpt, DiagnosticBag diag { Debug.Assert(!this.HasErrors); - var guidString = (string)this.CommonConstructorArguments[0].ValueInternal; + var guidString = (string?)this.CommonConstructorArguments[0].ValueInternal; // Native compiler allows only a specific GUID format: "D" format (32 digits separated by hyphens) Guid guid; @@ -641,7 +642,7 @@ internal string DecodeGuidAttribute(AttributeSyntax? nodeOpt, DiagnosticBag diag guidString = String.Empty; } - return guidString; + return guidString!; } private protected sealed override bool IsStringProperty(string memberName) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs index 1a024747e2ef8..33c990215fd7b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs @@ -169,9 +169,9 @@ internal static LocalSymbol MakeLocalSymbolWithEnclosingContext( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ThisConstructorInitializer || nodeToBind.Kind() == SyntaxKind.BaseConstructorInitializer || - nodeToBind.Kind() == SyntaxKind.SimpleBaseType || // initializer for a record constructor + nodeToBind.Kind() == SyntaxKind.PrimaryConstructorBaseType || // initializer for a record constructor nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm || - nodeToBind.Kind() == SyntaxKind.ArgumentList && nodeToBind.Parent is ConstructorInitializerSyntax || + nodeToBind.Kind() == SyntaxKind.ArgumentList && (nodeToBind.Parent is ConstructorInitializerSyntax || nodeToBind.Parent is PrimaryConstructorBaseTypeSyntax) || nodeToBind.Kind() == SyntaxKind.GotoCaseStatement || // for error recovery nodeToBind.Kind() == SyntaxKind.VariableDeclarator && new[] { SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement, SyntaxKind.UsingStatement, SyntaxKind.FixedStatement }. @@ -741,8 +741,8 @@ public LocalSymbolWithEnclosingContext( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ThisConstructorInitializer || nodeToBind.Kind() == SyntaxKind.BaseConstructorInitializer || - nodeToBind.Kind() == SyntaxKind.SimpleBaseType || // initializer for a record constructor - nodeToBind.Kind() == SyntaxKind.ArgumentList && nodeToBind.Parent is ConstructorInitializerSyntax || + nodeToBind.Kind() == SyntaxKind.PrimaryConstructorBaseType || // initializer for a record constructor + nodeToBind.Kind() == SyntaxKind.ArgumentList && (nodeToBind.Parent is ConstructorInitializerSyntax || nodeToBind.Parent is PrimaryConstructorBaseTypeSyntax) || nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm || nodeToBind.Kind() == SyntaxKind.GotoCaseStatement || @@ -769,12 +769,21 @@ protected override TypeWithAnnotations InferTypeOfVarVariable(DiagnosticBag diag var initializer = (ConstructorInitializerSyntax)_nodeToBind; _nodeBinder.BindConstructorInitializer(initializer, diagnostics); break; - case SyntaxKind.SimpleBaseType: - _nodeBinder.BindConstructorInitializer((SimpleBaseTypeSyntax)_nodeToBind, diagnostics); + case SyntaxKind.PrimaryConstructorBaseType: + _nodeBinder.BindConstructorInitializer((PrimaryConstructorBaseTypeSyntax)_nodeToBind, diagnostics); break; case SyntaxKind.ArgumentList: - var invocation = (ConstructorInitializerSyntax)_nodeToBind.Parent; - _nodeBinder.BindConstructorInitializer(invocation, diagnostics); + switch (_nodeToBind.Parent) + { + case ConstructorInitializerSyntax ctorInitializer: + _nodeBinder.BindConstructorInitializer(ctorInitializer, diagnostics); + break; + case PrimaryConstructorBaseTypeSyntax ctorInitializer: + _nodeBinder.BindConstructorInitializer(ctorInitializer, diagnostics); + break; + default: + throw ExceptionUtilities.UnexpectedValue(_nodeToBind.Parent); + } break; case SyntaxKind.CasePatternSwitchLabel: _nodeBinder.BindPatternSwitchLabelForInference((CasePatternSwitchLabelSyntax)_nodeToBind, diagnostics); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordConstructor.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordConstructor.cs index 733a516bba650..3d083b323c07c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordConstructor.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordConstructor.cs @@ -33,14 +33,7 @@ internal RecordDeclarationSyntax GetSyntax() protected override CSharpSyntaxNode? GetInitializer() { - var baseTypeSyntax = GetSyntax().BaseList?.Types.FirstOrDefault() as SimpleBaseTypeSyntax; - - if (baseTypeSyntax?.ArgumentList is object) - { - return baseTypeSyntax; - } - - return null; + return GetSyntax().PrimaryConstructorBaseType; } internal override bool IsExpressionBodied diff --git a/src/Compilers/CSharp/Portable/Symbols/TypedConstantExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/TypedConstantExtensions.cs index ec4acfc67ce15..9d6493b07ed7e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypedConstantExtensions.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypedConstantExtensions.cs @@ -2,18 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Collections.Immutable; +#nullable enable + using System.Diagnostics; using System.Linq; using System.Text; -using Microsoft.CodeAnalysis.Collections; -using Microsoft.CodeAnalysis.CSharp.Symbols; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp { @@ -35,8 +29,9 @@ public static string ToCSharpString(this TypedConstant constant) return "{" + string.Join(", ", constant.Values.Select(v => v.ToCSharpString())) + "}"; } - if (constant.Kind == TypedConstantKind.Type || constant.TypeInternal.SpecialType == SpecialType.System_Object) + if (constant.Kind == TypedConstantKind.Type || constant.TypeInternal!.SpecialType == SpecialType.System_Object) { + Debug.Assert(constant.Value is object); return "typeof(" + constant.Value.ToString() + ")"; } @@ -46,6 +41,7 @@ public static string ToCSharpString(this TypedConstant constant) return DisplayEnumConstant(constant); } + Debug.Assert(constant.ValueInternal is object); return SymbolDisplay.FormatPrimitive(constant.ValueInternal, quoteStrings: true, useHexadecimalNumbers: false); } @@ -55,7 +51,8 @@ private static string DisplayEnumConstant(TypedConstant constant) Debug.Assert(constant.Kind == TypedConstantKind.Enum); // Create a ConstantValue of enum underlying type - SpecialType splType = ((INamedTypeSymbol)constant.Type).EnumUnderlyingType.SpecialType; + SpecialType splType = ((INamedTypeSymbol)constant.Type!).EnumUnderlyingType!.SpecialType; + Debug.Assert(constant.ValueInternal is object); ConstantValue valueConstant = ConstantValue.Create(constant.ValueInternal, splType); string typeName = constant.Type.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat); @@ -71,6 +68,8 @@ private static string DisplayEnumConstant(TypedConstant constant) private static string DisplayUnsignedEnumConstant(TypedConstant constant, SpecialType specialType, ulong constantToDecode, string typeName) { + Debug.Assert(constant.Kind == TypedConstantKind.Enum); + // Specified valueConstant might have an exact matching enum field // or it might be a bitwise Or of multiple enum fields. // For the later case, we keep track of the current value of @@ -78,18 +77,18 @@ private static string DisplayUnsignedEnumConstant(TypedConstant constant, Specia ulong curValue = 0; // Initialize the value string to empty - PooledStringBuilder pooledBuilder = null; - StringBuilder valueStringBuilder = null; + PooledStringBuilder? pooledBuilder = null; + StringBuilder? valueStringBuilder = null; // Iterate through all the constant members in the enum type - var members = constant.Type.GetMembers(); + var members = constant.Type!.GetMembers(); foreach (var member in members) { var field = member as IFieldSymbol; - if ((object)field != null && field.HasConstantValue) + if (field is object && field.HasConstantValue) { - ConstantValue memberConstant = ConstantValue.Create(field.ConstantValue, specialType); + ConstantValue memberConstant = ConstantValue.Create(field.ConstantValue!, specialType); // use MemberNotNull when available https://github.com/dotnet/roslyn/issues/41964 ulong memberValue = memberConstant.UInt64Value; // Do we have an exact matching enum field @@ -140,11 +139,16 @@ private static string DisplayUnsignedEnumConstant(TypedConstant constant, Specia } // Unable to decode the enum constant, just display the integral value - return constant.ValueInternal.ToString(); + Debug.Assert(constant.ValueInternal is object); + var result = constant.ValueInternal.ToString(); + Debug.Assert(result is object); + return result; } private static string DisplaySignedEnumConstant(TypedConstant constant, SpecialType specialType, long constantToDecode, string typeName) { + Debug.Assert(constant.Kind == TypedConstantKind.Enum); + // Specified valueConstant might have an exact matching enum field // or it might be a bitwise Or of multiple enum fields. // For the later case, we keep track of the current value of @@ -152,17 +156,17 @@ private static string DisplaySignedEnumConstant(TypedConstant constant, SpecialT long curValue = 0; // Initialize the value string to empty - PooledStringBuilder pooledBuilder = null; - StringBuilder valueStringBuilder = null; + PooledStringBuilder? pooledBuilder = null; + StringBuilder? valueStringBuilder = null; // Iterate through all the constant members in the enum type - var members = constant.Type.GetMembers(); + var members = constant.Type!.GetMembers(); foreach (var member in members) { var field = member as IFieldSymbol; - if ((object)field != null && field.HasConstantValue) + if (field is object && field.HasConstantValue) { - ConstantValue memberConstant = ConstantValue.Create(field.ConstantValue, specialType); + ConstantValue memberConstant = ConstantValue.Create(field.ConstantValue!, specialType); // use MemberNotNull when available https://github.com/dotnet/roslyn/issues/41964 long memberValue = memberConstant.Int64Value; // Do we have an exact matching enum field @@ -213,7 +217,10 @@ private static string DisplaySignedEnumConstant(TypedConstant constant, SpecialT } // Unable to decode the enum constant, just display the integral value - return constant.ValueInternal.ToString(); + Debug.Assert(constant.ValueInternal is object); + var result = constant.ValueInternal.ToString(); + Debug.Assert(result is object); + return result; } } } diff --git a/src/Compilers/CSharp/Portable/Syntax/AliasedQualifiedNameSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/AliasedQualifiedNameSyntax.cs index bd2cb57afb836..3f67d1046129e 100644 --- a/src/Compilers/CSharp/Portable/Syntax/AliasedQualifiedNameSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/AliasedQualifiedNameSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public sealed partial class AliasQualifiedNameSyntax : NameSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/AnonymousFunctionExpressionSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/AnonymousFunctionExpressionSyntax.cs index 564bd1b752ce7..3c813fd2e1aec 100644 --- a/src/Compilers/CSharp/Portable/Syntax/AnonymousFunctionExpressionSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/AnonymousFunctionExpressionSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public partial class AnonymousFunctionExpressionSyntax @@ -10,7 +12,7 @@ public partial class AnonymousFunctionExpressionSyntax /// Either the if it is not null or the /// otherwise. /// - public CSharpSyntaxNode Body => Block ?? (CSharpSyntaxNode)ExpressionBody; + public CSharpSyntaxNode Body => Block ?? (CSharpSyntaxNode)ExpressionBody!; public AnonymousFunctionExpressionSyntax WithBody(CSharpSyntaxNode body) => body is BlockSyntax block diff --git a/src/Compilers/CSharp/Portable/Syntax/ArgumentSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ArgumentSyntax.cs index f9292b41857a8..4973d3a3d6c65 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ArgumentSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ArgumentSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.ComponentModel; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/ArrayRankSpecifierSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ArrayRankSpecifierSyntax.cs index ca28ad5da1982..18663c32841a4 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ArrayRankSpecifierSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ArrayRankSpecifierSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public partial class ArrayRankSpecifierSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/AttributeSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/AttributeSyntax.cs index d1f9ca0182652..688116858c168 100644 --- a/src/Compilers/CSharp/Portable/Syntax/AttributeSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/AttributeSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Diagnostics; @@ -20,7 +22,7 @@ internal string GetErrorDisplayName() return Name.ErrorDisplayName(); } - internal AttributeArgumentSyntax GetNamedArgumentSyntax(string namedArgName) + internal AttributeArgumentSyntax? GetNamedArgumentSyntax(string namedArgName) { Debug.Assert(!String.IsNullOrEmpty(namedArgName)); diff --git a/src/Compilers/CSharp/Portable/Syntax/AttributeTargetSpecifierSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/AttributeTargetSpecifierSyntax.cs index a450587688d4b..0352e3d1c806d 100644 --- a/src/Compilers/CSharp/Portable/Syntax/AttributeTargetSpecifierSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/AttributeTargetSpecifierSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; diff --git a/src/Compilers/CSharp/Portable/Syntax/BlockSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/BlockSyntax.cs index 95319677e94a3..eb3492ed5eab3 100644 --- a/src/Compilers/CSharp/Portable/Syntax/BlockSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/BlockSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/BreakStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/BreakStatementSyntax.cs index c4a4ceb4c1e83..4b4bae8e50eec 100644 --- a/src/Compilers/CSharp/Portable/Syntax/BreakStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/BreakStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/CSharpLineDirectiveMap.cs b/src/Compilers/CSharp/Portable/Syntax/CSharpLineDirectiveMap.cs index bcb1d43284100..fc2ecf9a54f6d 100644 --- a/src/Compilers/CSharp/Portable/Syntax/CSharpLineDirectiveMap.cs +++ b/src/Compilers/CSharp/Portable/Syntax/CSharpLineDirectiveMap.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Diagnostics; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; @@ -60,7 +62,7 @@ protected override LineMappingEntry GetEntry(DirectiveTriviaSyntax directiveNode // skip both the mapped line and the filename if the line number is not valid if (!lineToken.ContainsDiagnostics) { - object value = lineToken.Value; + object? value = lineToken.Value; if (value is int) { // convert one-based line number into zero-based line number @@ -69,7 +71,7 @@ protected override LineMappingEntry GetEntry(DirectiveTriviaSyntax directiveNode if (directive.File.Kind() == SyntaxKind.StringLiteralToken) { - mappedPathOpt = (string)directive.File.Value; + mappedPathOpt = (string?)directive.File.Value; } state = PositionState.Remapped; diff --git a/src/Compilers/CSharp/Portable/Syntax/CSharpPragmaWarningStateMap.cs b/src/Compilers/CSharp/Portable/Syntax/CSharpPragmaWarningStateMap.cs index 75c2eebd0d40c..aa9d0a9c2bfab 100644 --- a/src/Compilers/CSharp/Portable/Syntax/CSharpPragmaWarningStateMap.cs +++ b/src/Compilers/CSharp/Portable/Syntax/CSharpPragmaWarningStateMap.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; @@ -125,7 +127,7 @@ private static WarningStateMapEntry[] CreatePragmaWarningStateEntries(ArrayBuild if (currentErrorCode.Kind() == SyntaxKind.NumericLiteralExpression) { var token = ((LiteralExpressionSyntax)currentErrorCode).Token; - errorId = MessageProvider.Instance.GetIdForErrorCode((int)token.Value); + errorId = MessageProvider.Instance.GetIdForErrorCode((int)token.Value!); } else if (currentErrorCode.Kind() == SyntaxKind.IdentifierName) { diff --git a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxNode.cs b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxNode.cs index b14985aee8897..68d0be4fd2059 100644 --- a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxNode.cs +++ b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxNode.cs @@ -520,7 +520,7 @@ protected internal override SyntaxNode InsertTriviaInListCore(SyntaxTrivia origi return SyntaxReplacer.InsertTriviaInList(this, originalTrivia, newTrivia, insertBefore).AsRootOfNewTreeWithOptionsFrom(this.SyntaxTree); } - protected internal override SyntaxNode RemoveNodesCore(IEnumerable nodes, SyntaxRemoveOptions options) + protected internal override SyntaxNode? RemoveNodesCore(IEnumerable nodes, SyntaxRemoveOptions options) { return SyntaxNodeRemover.RemoveNodes(this, nodes.Cast(), options).AsRootOfNewTreeWithOptionsFrom(this.SyntaxTree); } diff --git a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxRewriter.cs b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxRewriter.cs index f44481578108d..2eca35b725827 100644 --- a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxRewriter.cs +++ b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxRewriter.cs @@ -6,6 +6,7 @@ using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Syntax; @@ -31,6 +32,7 @@ public virtual bool VisitIntoStructuredTrivia private int _recursionDepth; + [return: NotNullIfNotNull("node")] public override SyntaxNode? Visit(SyntaxNode? node) { if (node != null) diff --git a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.Dummy.cs b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.Dummy.cs index ccc199d778c98..b50540d22e896 100644 --- a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.Dummy.cs +++ b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.Dummy.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Immutable; using System.Text; diff --git a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.ParsedSyntaxTree.cs b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.ParsedSyntaxTree.cs index 83ce912b4ca23..b4502d0b85bed 100644 --- a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.ParsedSyntaxTree.cs +++ b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.ParsedSyntaxTree.cs @@ -2,10 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading; @@ -22,20 +25,20 @@ private class ParsedSyntaxTree : CSharpSyntaxTree private readonly string _path; private readonly CSharpSyntaxNode _root; private readonly bool _hasCompilationUnitRoot; - private readonly Encoding _encodingOpt; + private readonly Encoding? _encodingOpt; private readonly SourceHashAlgorithm _checksumAlgorithm; private readonly ImmutableDictionary _diagnosticOptions; - private SourceText _lazyText; + private SourceText? _lazyText; internal ParsedSyntaxTree( - SourceText textOpt, - Encoding encodingOpt, + SourceText? textOpt, + Encoding? encodingOpt, SourceHashAlgorithm checksumAlgorithm, string path, CSharpParseOptions options, CSharpSyntaxNode root, Syntax.InternalSyntax.DirectiveStack directives, - ImmutableDictionary diagnosticOptions, + ImmutableDictionary? diagnosticOptions, bool? isGeneratedCode, bool cloneRoot) { @@ -75,13 +78,13 @@ public override SourceText GetText(CancellationToken cancellationToken) return _lazyText; } - public override bool TryGetText(out SourceText text) + public override bool TryGetText([NotNullWhen(true)] out SourceText? text) { text = _lazyText; return text != null; } - public override Encoding Encoding + public override Encoding? Encoding { get { return _encodingOpt; } } @@ -133,7 +136,7 @@ public override SyntaxTree WithRootAndOptions(SyntaxNode root, ParseOptions opti } return new ParsedSyntaxTree( - null, + textOpt: null, _encodingOpt, _checksumAlgorithm, _path, diff --git a/src/Compilers/CSharp/Portable/Syntax/CheckedStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/CheckedStatementSyntax.cs index 9789f47a1b634..54fe62e236c64 100644 --- a/src/Compilers/CSharp/Portable/Syntax/CheckedStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/CheckedStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/ClassOrStructConstraintSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ClassOrStructConstraintSyntax.cs index e6a6fbe9a1595..bcb1263a97562 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ClassOrStructConstraintSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ClassOrStructConstraintSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public partial class ClassOrStructConstraintSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/CompilationUnitSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/CompilationUnitSyntax.cs index 41f18136ca60f..469886c9863c4 100644 --- a/src/Compilers/CSharp/Portable/Syntax/CompilationUnitSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/CompilationUnitSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; @@ -17,7 +19,7 @@ public IList GetReferenceDirectives() return GetReferenceDirectives(null); } - internal IList GetReferenceDirectives(Func filter) + internal IList GetReferenceDirectives(Func? filter) { // #r directives are always on the first token of the compilation unit. var firstToken = (SyntaxNodeOrToken)this.GetFirstToken(includeZeroWidth: true); diff --git a/src/Compilers/CSharp/Portable/Syntax/ConstructorDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ConstructorDeclarationSyntax.cs index bc5f77fa7fd0d..2608ed0c8df3d 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ConstructorDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ConstructorDeclarationSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; diff --git a/src/Compilers/CSharp/Portable/Syntax/ContinueStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ContinueStatementSyntax.cs index 1cdda97bff701..145f80e275067 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ContinueStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ContinueStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/CrefParameterSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/CrefParameterSyntax.cs index d45df4f20ea1f..22f33fd4403fa 100644 --- a/src/Compilers/CSharp/Portable/Syntax/CrefParameterSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/CrefParameterSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.ComponentModel; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/DeclarationStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/DeclarationStatementSyntax.cs index 71bcee364af47..296fcf0a399c3 100644 --- a/src/Compilers/CSharp/Portable/Syntax/DeclarationStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/DeclarationStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public partial class LocalDeclarationStatementSyntax : StatementSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/DelegateDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/DelegateDeclarationSyntax.cs index 5113e2fb062a3..3afd660c52465 100644 --- a/src/Compilers/CSharp/Portable/Syntax/DelegateDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/DelegateDeclarationSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; diff --git a/src/Compilers/CSharp/Portable/Syntax/DestructorDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/DestructorDeclarationSyntax.cs index b6a1ffc1ec00e..65ddd215eac9d 100644 --- a/src/Compilers/CSharp/Portable/Syntax/DestructorDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/DestructorDeclarationSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; diff --git a/src/Compilers/CSharp/Portable/Syntax/DirectiveTriviaSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/DirectiveTriviaSyntax.cs index a7a2e04776db9..e2fbe2067dc90 100644 --- a/src/Compilers/CSharp/Portable/Syntax/DirectiveTriviaSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/DirectiveTriviaSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; using System.Linq; @@ -62,7 +64,7 @@ public SyntaxToken DirectiveNameToken } } - public DirectiveTriviaSyntax GetNextDirective(Func predicate = null) + public DirectiveTriviaSyntax? GetNextDirective(Func? predicate = null) { var token = (SyntaxToken)this.ParentTrivia.Token; bool next = false; @@ -74,7 +76,7 @@ public DirectiveTriviaSyntax GetNextDirective(Func { if (tr.IsDirective) { - var d = (DirectiveTriviaSyntax)tr.GetStructure(); + var d = (DirectiveTriviaSyntax)tr.GetStructure()!; if (predicate == null || predicate(d)) { return d; @@ -93,7 +95,7 @@ public DirectiveTriviaSyntax GetNextDirective(Func return null; } - public DirectiveTriviaSyntax GetPreviousDirective(Func predicate = null) + public DirectiveTriviaSyntax? GetPreviousDirective(Func? predicate = null) { var token = (SyntaxToken)this.ParentTrivia.Token; bool next = false; @@ -105,7 +107,7 @@ public DirectiveTriviaSyntax GetPreviousDirective(Func list) } } - private DirectiveTriviaSyntax GetNextRelatedDirective() + private DirectiveTriviaSyntax? GetNextRelatedDirective() { - DirectiveTriviaSyntax d = this; + DirectiveTriviaSyntax? d = this; switch (d.Kind()) { case SyntaxKind.IfDirectiveTrivia: @@ -217,9 +219,9 @@ private DirectiveTriviaSyntax GetNextRelatedDirective() return null; } - private DirectiveTriviaSyntax GetNextPossiblyRelatedDirective() + private DirectiveTriviaSyntax? GetNextPossiblyRelatedDirective() { - DirectiveTriviaSyntax d = this; + DirectiveTriviaSyntax? d = this; while (d != null) { d = d.GetNextDirective(); @@ -251,9 +253,9 @@ private DirectiveTriviaSyntax GetNextPossiblyRelatedDirective() return null; } - private DirectiveTriviaSyntax GetPreviousRelatedDirective() + private DirectiveTriviaSyntax? GetPreviousRelatedDirective() { - DirectiveTriviaSyntax d = this; + DirectiveTriviaSyntax? d = this; switch (d.Kind()) { case SyntaxKind.EndIfDirectiveTrivia: @@ -318,9 +320,9 @@ private DirectiveTriviaSyntax GetPreviousRelatedDirective() return null; } - private DirectiveTriviaSyntax GetPreviousPossiblyRelatedDirective() + private DirectiveTriviaSyntax? GetPreviousPossiblyRelatedDirective() { - DirectiveTriviaSyntax d = this; + DirectiveTriviaSyntax? d = this; while (d != null) { d = d.GetPreviousDirective(); diff --git a/src/Compilers/CSharp/Portable/Syntax/DoStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/DoStatementSyntax.cs index 634e1fafb6db5..0c4d6f689e174 100644 --- a/src/Compilers/CSharp/Portable/Syntax/DoStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/DoStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/EmptyStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/EmptyStatementSyntax.cs index 48f59f5bbbf4c..fea389fa85f35 100644 --- a/src/Compilers/CSharp/Portable/Syntax/EmptyStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/EmptyStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/EnumMemberDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/EnumMemberDeclarationSyntax.cs index 00254bd610961..11471dc4f8265 100644 --- a/src/Compilers/CSharp/Portable/Syntax/EnumMemberDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/EnumMemberDeclarationSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public partial class EnumMemberDeclarationSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/EventDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/EventDeclarationSyntax.cs index 22136c749bc25..f223314c6873b 100644 --- a/src/Compilers/CSharp/Portable/Syntax/EventDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/EventDeclarationSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; using System; using System.ComponentModel; diff --git a/src/Compilers/CSharp/Portable/Syntax/ExpressionStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ExpressionStatementSyntax.cs index bf12dcf019bab..54a9261ac1163 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ExpressionStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ExpressionStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/FixedStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/FixedStatementSyntax.cs index f0038681378e9..2892b9c1faa74 100644 --- a/src/Compilers/CSharp/Portable/Syntax/FixedStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/FixedStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/ForEachStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ForEachStatementSyntax.cs index 308a75fedb796..a4f5db2523590 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ForEachStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ForEachStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/ForEachVariableStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ForEachVariableStatementSyntax.cs index 5d84db42596f8..0af79155f6d09 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ForEachVariableStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ForEachVariableStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/ForStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ForStatementSyntax.cs index 059c6078c0bbd..549da08f3ea25 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ForStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ForStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/GenericNameSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/GenericNameSyntax.cs index 67ed2f3a3f589..1adbd7090d7de 100644 --- a/src/Compilers/CSharp/Portable/Syntax/GenericNameSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/GenericNameSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; diff --git a/src/Compilers/CSharp/Portable/Syntax/GlobalStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/GlobalStatementSyntax.cs index 4f444586d234c..fc9cf4fd553de 100644 --- a/src/Compilers/CSharp/Portable/Syntax/GlobalStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/GlobalStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public partial class GlobalStatementSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/GotoStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/GotoStatementSyntax.cs index 4090c54296041..290b0ae8486aa 100644 --- a/src/Compilers/CSharp/Portable/Syntax/GotoStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/GotoStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/IdentifierNameSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/IdentifierNameSyntax.cs index 4134ff6973865..fe9a3ccb43de3 100644 --- a/src/Compilers/CSharp/Portable/Syntax/IdentifierNameSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/IdentifierNameSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public partial class IdentifierNameSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/IfStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/IfStatementSyntax.cs index 6cf4645cfc140..d334a4db11f85 100644 --- a/src/Compilers/CSharp/Portable/Syntax/IfStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/IfStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/IndexerDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/IndexerDeclarationSyntax.cs index c87269a9fe8bc..75ec4c53dfa5b 100644 --- a/src/Compilers/CSharp/Portable/Syntax/IndexerDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/IndexerDeclarationSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; using System; using System.ComponentModel; diff --git a/src/Compilers/CSharp/Portable/Syntax/LabeledStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/LabeledStatementSyntax.cs index b93ed2bf29e50..d39ab9260c3f8 100644 --- a/src/Compilers/CSharp/Portable/Syntax/LabeledStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/LabeledStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/LambdaUtilities.cs b/src/Compilers/CSharp/Portable/Syntax/LambdaUtilities.cs index 697435103fca4..b25062eb443b6 100644 --- a/src/Compilers/CSharp/Portable/Syntax/LambdaUtilities.cs +++ b/src/Compilers/CSharp/Portable/Syntax/LambdaUtilities.cs @@ -2,7 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Roslyn.Utilities; @@ -49,14 +52,15 @@ public static bool IsLambda(SyntaxNode node) /// public static SyntaxNode GetLambda(SyntaxNode lambdaBody) { + Debug.Assert(lambdaBody.Parent is object); var lambda = lambdaBody.Parent; - if (lambda.Kind() == SyntaxKind.ArrowExpressionClause) + if (lambda.IsKind(SyntaxKind.ArrowExpressionClause)) { // In case of expression bodied local functions there is a three level hierarchy: // LocalFunctionStatement -> ArrowExpressionClause -> Expression. // And the lambda is the LocalFunctionStatement. lambda = lambda.Parent; - Debug.Assert(lambda.Kind() == SyntaxKind.LocalFunctionStatement); + Debug.Assert(lambda.IsKind(SyntaxKind.LocalFunctionStatement)); } Debug.Assert(IsLambda(lambda)); @@ -66,8 +70,10 @@ public static SyntaxNode GetLambda(SyntaxNode lambdaBody) /// /// See SyntaxNode.GetCorrespondingLambdaBody. /// - internal static SyntaxNode TryGetCorrespondingLambdaBody(SyntaxNode oldBody, SyntaxNode newLambda) + internal static SyntaxNode? TryGetCorrespondingLambdaBody(SyntaxNode oldBody, SyntaxNode newLambda) { + Debug.Assert(oldBody.Parent is object); + switch (newLambda.Kind()) { case SyntaxKind.ParenthesizedLambdaExpression: @@ -120,7 +126,7 @@ public static SyntaxNode GetNestedFunctionBody(SyntaxNode nestedFunction) => nestedFunction switch { AnonymousFunctionExpressionSyntax anonymousFunctionExpressionSyntax => anonymousFunctionExpressionSyntax.Body, - LocalFunctionStatementSyntax localFunctionStatementSyntax => (CSharpSyntaxNode)localFunctionStatementSyntax.Body ?? localFunctionStatementSyntax.ExpressionBody.Expression, + LocalFunctionStatementSyntax localFunctionStatementSyntax => (CSharpSyntaxNode?)localFunctionStatementSyntax.Body ?? localFunctionStatementSyntax.ExpressionBody!.Expression, _ => throw ExceptionUtilities.UnexpectedValue(nestedFunction), }; @@ -221,6 +227,7 @@ private static bool IsReducedSelectOrGroupByClause(SelectOrGroupClauseSyntax sel SyntaxToken sourceIdentifier; QueryBodySyntax containingBody; + Debug.Assert(selectOrGroupClause.Parent!.Parent is object); var containingQueryOrContinuation = selectOrGroupClause.Parent.Parent; if (containingQueryOrContinuation.IsKind(SyntaxKind.QueryExpression)) { @@ -275,7 +282,7 @@ public static bool IsLambdaBodyStatementOrExpression(SyntaxNode node, out Syntax /// /// If the specified node represents a lambda returns a node (or nodes) that represent its body (bodies). /// - public static bool TryGetLambdaBodies(SyntaxNode node, out SyntaxNode lambdaBody1, out SyntaxNode lambdaBody2) + public static bool TryGetLambdaBodies(SyntaxNode node, [NotNullWhen(true)] out SyntaxNode? lambdaBody1, out SyntaxNode? lambdaBody2) { lambdaBody1 = null; lambdaBody2 = null; @@ -404,8 +411,6 @@ internal static bool IsClosureScope(SyntaxNode node) case SyntaxKind.IfStatement: case SyntaxKind.LockStatement: case SyntaxKind.ReturnStatement: - case SyntaxKind.ThisConstructorInitializer: - case SyntaxKind.BaseConstructorInitializer: case SyntaxKind.ThrowStatement: case SyntaxKind.WhileStatement: case SyntaxKind.YieldReturnStatement: @@ -476,7 +481,7 @@ internal static int GetDeclaratorPosition(SyntaxNode node) private static SyntaxNode GetLocalFunctionBody(LocalFunctionStatementSyntax localFunctionStatementSyntax) { - return (SyntaxNode)localFunctionStatementSyntax.Body ?? localFunctionStatementSyntax.ExpressionBody?.Expression; + return (SyntaxNode?)localFunctionStatementSyntax.Body ?? localFunctionStatementSyntax.ExpressionBody!.Expression; } } } diff --git a/src/Compilers/CSharp/Portable/Syntax/LocalDeclarationStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/LocalDeclarationStatementSyntax.cs index 53c210809e458..1fe84d117a82a 100644 --- a/src/Compilers/CSharp/Portable/Syntax/LocalDeclarationStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/LocalDeclarationStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/LocalFunctionStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/LocalFunctionStatementSyntax.cs index 5930b520c8572..8acac93cbfe34 100644 --- a/src/Compilers/CSharp/Portable/Syntax/LocalFunctionStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/LocalFunctionStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp diff --git a/src/Compilers/CSharp/Portable/Syntax/LockStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/LockStatementSyntax.cs index 7ff788e494f25..499f6f93fe49e 100644 --- a/src/Compilers/CSharp/Portable/Syntax/LockStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/LockStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs b/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs index fc2b987217e8e..efb5ea2cfb747 100644 --- a/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs +++ b/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Diagnostics; using Roslyn.Utilities; @@ -20,21 +22,21 @@ internal static class LookupPosition /// A position is considered to be inside a block if it is on or after /// the open brace and strictly before the close brace. /// - internal static bool IsInBlock(int position, BlockSyntax blockOpt) + internal static bool IsInBlock(int position, BlockSyntax? blockOpt) { return blockOpt != null && IsBeforeToken(position, blockOpt, blockOpt.CloseBraceToken); } internal static bool IsInExpressionBody( int position, - ArrowExpressionClauseSyntax expressionBodyOpt, + ArrowExpressionClauseSyntax? expressionBodyOpt, SyntaxToken semicolonToken) { return expressionBodyOpt != null && IsBeforeToken(position, expressionBodyOpt, semicolonToken); } - private static bool IsInBody(int position, BlockSyntax blockOpt, ArrowExpressionClauseSyntax exprOpt, SyntaxToken semiOpt) + private static bool IsInBody(int position, BlockSyntax? blockOpt, ArrowExpressionClauseSyntax? exprOpt, SyntaxToken semiOpt) { return IsInExpressionBody(position, exprOpt, semiOpt) || IsInBlock(position, blockOpt); @@ -185,7 +187,7 @@ internal static bool IsInConstructorParameterScope(int position, ConstructorDecl return initializerOpt == null ? IsInBody(position, constructorDecl) : IsBetweenTokens(position, initializerOpt.ColonToken, - constructorDecl.SemicolonToken.Kind() == SyntaxKind.None ? constructorDecl.Body.CloseBraceToken : constructorDecl.SemicolonToken); + constructorDecl.SemicolonToken.Kind() == SyntaxKind.None ? constructorDecl.Body!.CloseBraceToken : constructorDecl.SemicolonToken); } internal static bool IsInMethodTypeParameterScope(int position, MethodDeclarationSyntax methodDecl) @@ -370,7 +372,7 @@ internal static SyntaxToken GetFirstExcludedToken(StatementSyntax statement) return ((GotoStatementSyntax)statement).SemicolonToken; case SyntaxKind.IfStatement: IfStatementSyntax ifStmt = (IfStatementSyntax)statement; - ElseClauseSyntax elseOpt = ifStmt.Else; + ElseClauseSyntax? elseOpt = ifStmt.Else; return GetFirstExcludedToken(elseOpt == null ? ifStmt.Statement : elseOpt.Statement); case SyntaxKind.LabeledStatement: return GetFirstExcludedToken(((LabeledStatementSyntax)statement).Statement); @@ -385,13 +387,13 @@ internal static SyntaxToken GetFirstExcludedToken(StatementSyntax statement) case SyntaxKind.TryStatement: TryStatementSyntax tryStmt = (TryStatementSyntax)statement; - FinallyClauseSyntax finallyClause = tryStmt.Finally; + FinallyClauseSyntax? finallyClause = tryStmt.Finally; if (finallyClause != null) { return finallyClause.Block.CloseBraceToken; } - CatchClauseSyntax lastCatch = tryStmt.Catches.LastOrDefault(); + CatchClauseSyntax? lastCatch = tryStmt.Catches.LastOrDefault(); if (lastCatch != null) { return lastCatch.Block.CloseBraceToken; diff --git a/src/Compilers/CSharp/Portable/Syntax/MethodDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/MethodDeclarationSyntax.cs index 79e1e850d10d9..6af2463864611 100644 --- a/src/Compilers/CSharp/Portable/Syntax/MethodDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/MethodDeclarationSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; diff --git a/src/Compilers/CSharp/Portable/Syntax/NameSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/NameSyntax.cs index 7b74f08718361..ba083ce97f482 100644 --- a/src/Compilers/CSharp/Portable/Syntax/NameSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/NameSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; @@ -38,7 +40,7 @@ public int Arity /// containing the explicitly implemented interface symbol - there may be more than one. We just want to know /// how the name was qualified in source so that we can make a similar qualification (for uniqueness purposes). /// - internal string GetAliasQualifierOpt() + internal string? GetAliasQualifierOpt() { NameSyntax name = this; while (true) diff --git a/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntax.cs index b853c6e098b87..af976477df698 100644 --- a/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; diff --git a/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs b/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs index 10aae6d6b8710..4e3beea132236 100644 --- a/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs +++ b/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Diagnostics; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; diff --git a/src/Compilers/CSharp/Portable/Syntax/NullableContextStateMap.cs b/src/Compilers/CSharp/Portable/Syntax/NullableContextStateMap.cs index 717d724cbef9e..67d1c91b46e6a 100644 --- a/src/Compilers/CSharp/Portable/Syntax/NullableContextStateMap.cs +++ b/src/Compilers/CSharp/Portable/Syntax/NullableContextStateMap.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; using System.Collections.Immutable; diff --git a/src/Compilers/CSharp/Portable/Syntax/ParameterListSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ParameterListSyntax.cs index 0a554029ab0ee..351a6171d41ba 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ParameterListSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ParameterListSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; diff --git a/src/Compilers/CSharp/Portable/Syntax/ParameterSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ParameterSyntax.cs index 420409f8577e4..79d848c174f3e 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ParameterSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ParameterSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; diff --git a/src/Compilers/CSharp/Portable/Syntax/ParenthesizedLambdaExpressionSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ParenthesizedLambdaExpressionSyntax.cs index a2a6703e37999..21fa5c18fd427 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ParenthesizedLambdaExpressionSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ParenthesizedLambdaExpressionSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public partial class ParenthesizedLambdaExpressionSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/PropertyDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/PropertyDeclarationSyntax.cs index aff5609cb9091..8404cb1ee9c98 100644 --- a/src/Compilers/CSharp/Portable/Syntax/PropertyDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/PropertyDeclarationSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; using System; using System.ComponentModel; diff --git a/src/Compilers/CSharp/Portable/Syntax/QualifiedNameSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/QualifiedNameSyntax.cs index 6e7fe58edfbc8..ff3ffea89ea0f 100644 --- a/src/Compilers/CSharp/Portable/Syntax/QualifiedNameSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/QualifiedNameSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.ComponentModel; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; diff --git a/src/Compilers/CSharp/Portable/Syntax/RecordDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/RecordDeclarationSyntax.cs index 19ac288a66fd9..0e2ab8a4a75d9 100644 --- a/src/Compilers/CSharp/Portable/Syntax/RecordDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/RecordDeclarationSyntax.cs @@ -8,16 +8,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Syntax { public partial class RecordDeclarationSyntax { - internal SimpleBaseTypeSyntax? BaseWithArguments + internal PrimaryConstructorBaseTypeSyntax? PrimaryConstructorBaseType { get { - if (BaseList?.Types.FirstOrDefault() is SimpleBaseTypeSyntax { ArgumentList: { } } firstBase) - { - return firstBase; - } - - return null; + return BaseList?.Types.FirstOrDefault() as PrimaryConstructorBaseTypeSyntax; } } } diff --git a/src/Compilers/CSharp/Portable/Syntax/RefTypeSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/RefTypeSyntax.cs index 599708eb6ae24..d0bd800ac5ab5 100644 --- a/src/Compilers/CSharp/Portable/Syntax/RefTypeSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/RefTypeSyntax.cs @@ -2,10 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.CodeAnalysis.Collections; -using Microsoft.CodeAnalysis.CSharp.Symbols; +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.CSharp.Syntax { @@ -13,7 +12,7 @@ public partial class RefTypeSyntax { public RefTypeSyntax Update(SyntaxToken refKeyword, TypeSyntax type) { - return Update(refKeyword, default(SyntaxToken), type); + return Update(refKeyword, readOnlyKeyword: default, type); } } } @@ -25,7 +24,7 @@ public partial class SyntaxFactory /// Creates a new RefTypeSyntax instance. public static RefTypeSyntax RefType(SyntaxToken refKeyword, TypeSyntax type) { - return RefType(refKeyword, default(SyntaxToken), type); + return RefType(refKeyword, readOnlyKeyword: default, type); } } } diff --git a/src/Compilers/CSharp/Portable/Syntax/ReturnStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ReturnStatementSyntax.cs index e873eae09f6e2..6b8aeda025d8e 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ReturnStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ReturnStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/SimpleBaseTypeSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/SimpleBaseTypeSyntax.cs deleted file mode 100644 index f6c8032094ff5..0000000000000 --- a/src/Compilers/CSharp/Portable/Syntax/SimpleBaseTypeSyntax.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#nullable enable - -namespace Microsoft.CodeAnalysis.CSharp.Syntax -{ - public partial class SimpleBaseTypeSyntax - { - public SimpleBaseTypeSyntax Update(TypeSyntax type) - => Update(type, argumentList: null); - } -} diff --git a/src/Compilers/CSharp/Portable/Syntax/SimpleNameSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/SimpleNameSyntax.cs index b4ff4ab165602..ab747b1d39bb8 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SimpleNameSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SimpleNameSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.ComponentModel; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; diff --git a/src/Compilers/CSharp/Portable/Syntax/SimpleSyntaxReference.cs b/src/Compilers/CSharp/Portable/Syntax/SimpleSyntaxReference.cs index ef0717fea9991..3b410f3a1d599 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SimpleSyntaxReference.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SimpleSyntaxReference.cs @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.CSharp diff --git a/src/Compilers/CSharp/Portable/Syntax/SkippedTokensTriviaSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/SkippedTokensTriviaSyntax.cs index abc4eb8c6f901..0bb7a60f0f750 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SkippedTokensTriviaSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SkippedTokensTriviaSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public sealed partial class SkippedTokensTriviaSyntax : StructuredTriviaSyntax, ISkippedTokensTriviaSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/StackAllocArrayCreationExpressionSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/StackAllocArrayCreationExpressionSyntax.cs index 059555cc67c7f..fe6a2a9cfee72 100644 --- a/src/Compilers/CSharp/Portable/Syntax/StackAllocArrayCreationExpressionSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/StackAllocArrayCreationExpressionSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/SwitchStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/SwitchStatementSyntax.cs index bedc1f169890f..f2c1bbc5da47e 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SwitchStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SwitchStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml index f7e0fecb2c6d6..1549c7356df01 100644 --- a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml +++ b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml @@ -3451,9 +3451,14 @@ - + + + + + + Type parameter constraint clause. diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs index e2132deefc706..77d1b868cc6db 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs @@ -250,6 +250,7 @@ private static bool IsInContextWhichNeedsDynamicAttribute(CSharpSyntaxNode node) case SyntaxKind.EventFieldDeclaration: case SyntaxKind.BaseList: case SyntaxKind.SimpleBaseType: + case SyntaxKind.PrimaryConstructorBaseType: return true; case SyntaxKind.Block: diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs index c7ecb7a3edfdd..d6794e6184813 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs @@ -186,6 +186,9 @@ public static bool IsInTypeOnlyContext(ExpressionSyntax node) case SimpleBaseType: return true; + case PrimaryConstructorBaseType: + return ((PrimaryConstructorBaseTypeSyntax)parent).Type == node; + case CrefParameter: return true; @@ -313,6 +316,7 @@ public static bool IsNamedArgumentName(SyntaxNode node) case Attribute: case BaseConstructorInitializer: case ThisConstructorInitializer: + case PrimaryConstructorBaseType: return true; default: return false; diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs index b25aa6cbd8093..fde6f519abf04 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs @@ -621,6 +621,8 @@ public enum SyntaxKind : ushort WithExpression = 9061, WithInitializerExpression = 9062, - RecordDeclaration = 9063 + RecordDeclaration = 9063, + + PrimaryConstructorBaseType = 9065, } } diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKindExtensions.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKindExtensions.cs index 303178fa057e7..5e77790f81ca5 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKindExtensions.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKindExtensions.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs index 9651b6d3d119b..54dea9ddf7b75 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -78,14 +80,11 @@ internal static bool CanHaveAssociatedLocalBinder(this SyntaxNode syntax) case SyntaxKind.BaseConstructorInitializer: case SyntaxKind.ThisConstructorInitializer: case SyntaxKind.ConstructorDeclaration: + case SyntaxKind.PrimaryConstructorBaseType: return true; case SyntaxKind.RecordDeclaration: return ((RecordDeclarationSyntax)syntax).ParameterList is object; - case SyntaxKind.SimpleBaseType: - return ((SimpleBaseTypeSyntax)syntax).ArgumentList is object && - syntax.Parent?.Parent is RecordDeclarationSyntax recordDecl && - recordDecl.ParameterList is object && recordDecl.BaseWithArguments == syntax; default: return syntax is StatementSyntax || IsValidScopeDesignator(syntax as ExpressionSyntax); @@ -93,10 +92,10 @@ internal static bool CanHaveAssociatedLocalBinder(this SyntaxNode syntax) } } - internal static bool IsValidScopeDesignator(this ExpressionSyntax expression) + internal static bool IsValidScopeDesignator(this ExpressionSyntax? expression) { // All these nodes are valid scope designators due to the pattern matching and out vars features. - CSharpSyntaxNode parent = expression?.Parent; + CSharpSyntaxNode? parent = expression?.Parent; switch (parent?.Kind()) { case SyntaxKind.SimpleLambdaExpression: @@ -140,7 +139,7 @@ internal static bool IsLegalCSharp73SpanStackAllocPosition(this SyntaxNode node) node = node.Parent; } - SyntaxNode parentNode = node.Parent; + SyntaxNode? parentNode = node.Parent; if (parentNode is null) { @@ -152,7 +151,7 @@ internal static bool IsLegalCSharp73SpanStackAllocPosition(this SyntaxNode node) // In case of a declaration of a Span variable case SyntaxKind.EqualsValueClause: { - SyntaxNode variableDeclarator = parentNode.Parent; + SyntaxNode? variableDeclarator = parentNode.Parent; return variableDeclarator.IsKind(SyntaxKind.VariableDeclarator) && variableDeclarator.Parent.IsKind(SyntaxKind.VariableDeclaration); @@ -234,8 +233,8 @@ internal static TypeSyntax SkipRef(this TypeSyntax syntax, out RefKind refKind) return syntax; } - internal static ExpressionSyntax CheckAndUnwrapRefExpression( - this ExpressionSyntax syntax, + internal static ExpressionSyntax? CheckAndUnwrapRefExpression( + this ExpressionSyntax? syntax, DiagnosticBag diagnostics, out RefKind refKind) { diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeRemover.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeRemover.cs index 2d82c19ea8b63..c0718c3bd4c5a 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeRemover.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeRemover.cs @@ -2,10 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; -using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.Syntax; using Microsoft.CodeAnalysis.Text; @@ -13,7 +16,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Syntax { internal static class SyntaxNodeRemover { - internal static TRoot RemoveNodes(TRoot root, + internal static TRoot? RemoveNodes(TRoot root, IEnumerable nodes, SyntaxRemoveOptions options) where TRoot : SyntaxNode @@ -41,7 +44,7 @@ internal static TRoot RemoveNodes(TRoot root, result = result.WithTrailingTrivia(result.GetTrailingTrivia().Concat(residualTrivia)); } - return (TRoot)result; + return (TRoot?)result; } private class SyntaxRemover : CSharpSyntaxRewriter @@ -50,7 +53,7 @@ private class SyntaxRemover : CSharpSyntaxRewriter private readonly SyntaxRemoveOptions _options; private readonly TextSpan _searchSpan; private readonly SyntaxTriviaListBuilder _residualTrivia; - private HashSet _directivesToKeep; + private HashSet? _directivesToKeep; public SyntaxRemover( SyntaxNode[] nodesToRemove, @@ -160,9 +163,10 @@ private bool ShouldVisit(SyntaxNode node) return node.FullSpan.IntersectsWith(_searchSpan) || (_residualTrivia != null && _residualTrivia.Count > 0); } - public override SyntaxNode Visit(SyntaxNode node) + [return: NotNullIfNotNull("node")] + public override SyntaxNode? Visit(SyntaxNode? node) { - SyntaxNode result = node; + SyntaxNode? result = node; if (node != null) { @@ -207,7 +211,7 @@ public override SeparatedSyntaxList VisitList(SeparatedSyntaxList< var withSeps = list.GetWithSeparators(); bool removeNextSeparator = false; - SyntaxNodeOrTokenListBuilder alternate = null; + SyntaxNodeOrTokenListBuilder? alternate = null; for (int i = 0, n = withSeps.Count; i < n; i++) { var item = withSeps[i]; @@ -227,7 +231,7 @@ public override SeparatedSyntaxList VisitList(SeparatedSyntaxList< } else { - var node = (TNode)item.AsNode(); + var node = (TNode)item.AsNode()!; if (this.IsForRemoval(node)) { @@ -264,7 +268,7 @@ public override SeparatedSyntaxList VisitList(SeparatedSyntaxList< } else { - visited = this.VisitListElement((TNode)item.AsNode()); + visited = this.VisitListElement(node); } } @@ -321,6 +325,7 @@ private void AddTrivia(SyntaxNode node) private void AddTrivia(SyntaxToken token, SyntaxNode node) { + Debug.Assert(node.Parent is object); if ((_options & SyntaxRemoveOptions.KeepLeadingTrivia) != 0) { this.AddResidualTrivia(token.LeadingTrivia); @@ -360,6 +365,7 @@ private void AddTrivia(SyntaxToken token, SyntaxNode node) private void AddTrivia(SyntaxNode node, SyntaxToken token) { + Debug.Assert(node.Parent is object); if ((_options & SyntaxRemoveOptions.KeepLeadingTrivia) != 0) { this.AddResidualTrivia(node.GetLeadingTrivia()); @@ -429,7 +435,7 @@ private void AddDirectives(SyntaxNode node, TextSpan span) var directivesInSpan = node.DescendantTrivia(span, n => n.ContainsDirectives, descendIntoTrivia: true) .Where(tr => tr.IsDirective) - .Select(tr => (DirectiveTriviaSyntax)tr.GetStructure()); + .Select(tr => (DirectiveTriviaSyntax)tr.GetStructure()!); foreach (var directive in directivesInSpan) { diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxNormalizer.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxNormalizer.cs index 857ab9646f26f..477131f0d4cc1 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxNormalizer.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxNormalizer.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Symbols; @@ -29,7 +31,7 @@ internal class SyntaxNormalizer : CSharpSyntaxRewriter // CONSIDER: if we become concerned about space, we shouldn't actually need any // of the values between indentations[0] and indentations[initialDepth] (exclusive). - private ArrayBuilder _indentations; + private ArrayBuilder? _indentations; private SyntaxNormalizer(TextSpan consideredSpan, int initialDepth, string indentWhitespace, string eolWhitespace, bool useElasticTrivia) : base(visitIntoStructuredTrivia: true) @@ -239,10 +241,10 @@ private int LineBreaksAfter(SyntaxToken currentToken, SyntaxToken nextToken) (nextToken.IsKind(SyntaxKind.LetKeyword) && nextToken.Parent.IsKind(SyntaxKind.LetClause)) || (nextToken.IsKind(SyntaxKind.WhereKeyword) && nextToken.Parent.IsKind(SyntaxKind.WhereClause)) || (nextToken.IsKind(SyntaxKind.JoinKeyword) && nextToken.Parent.IsKind(SyntaxKind.JoinClause)) || - (nextToken.IsKind(SyntaxKind.JoinKeyword) && nextToken.Parent.Kind() == SyntaxKind.JoinIntoClause) || - (nextToken.Kind() == SyntaxKind.OrderByKeyword && nextToken.Parent.Kind() == SyntaxKind.OrderByClause) || - (nextToken.Kind() == SyntaxKind.SelectKeyword && nextToken.Parent.Kind() == SyntaxKind.SelectClause) || - (nextToken.Kind() == SyntaxKind.GroupKeyword && nextToken.Parent.Kind() == SyntaxKind.GroupClause)) + (nextToken.IsKind(SyntaxKind.JoinKeyword) && nextToken.Parent.IsKind(SyntaxKind.JoinIntoClause)) || + (nextToken.IsKind(SyntaxKind.OrderByKeyword) && nextToken.Parent.IsKind(SyntaxKind.OrderByClause)) || + (nextToken.IsKind(SyntaxKind.SelectKeyword) && nextToken.Parent.IsKind(SyntaxKind.SelectClause)) || + (nextToken.IsKind(SyntaxKind.GroupKeyword) && nextToken.Parent.IsKind(SyntaxKind.GroupClause))) { return 1; } @@ -309,7 +311,7 @@ private static int LineBreaksAfterCloseBrace(SyntaxToken currentToken, SyntaxTok private static int LineBreaksAfterSemicolon(SyntaxToken currentToken, SyntaxToken nextToken) { - if (currentToken.Parent.Kind() == SyntaxKind.ForStatement) + if (currentToken.Parent.IsKind(SyntaxKind.ForStatement)) { return 0; } @@ -317,13 +319,13 @@ private static int LineBreaksAfterSemicolon(SyntaxToken currentToken, SyntaxToke { return 1; } - else if (currentToken.Parent.Kind() == SyntaxKind.UsingDirective) + else if (currentToken.Parent.IsKind(SyntaxKind.UsingDirective)) { - return nextToken.Parent.Kind() == SyntaxKind.UsingDirective ? 1 : 2; + return nextToken.Parent.IsKind(SyntaxKind.UsingDirective) ? 1 : 2; } - else if (currentToken.Parent.Kind() == SyntaxKind.ExternAliasDirective) + else if (currentToken.Parent.IsKind(SyntaxKind.ExternAliasDirective)) { - return nextToken.Parent.Kind() == SyntaxKind.ExternAliasDirective ? 1 : 2; + return nextToken.Parent.IsKind(SyntaxKind.ExternAliasDirective) ? 1 : 2; } else { @@ -743,7 +745,7 @@ private static bool EndsInLineBreak(SyntaxTrivia trivia) if (trivia.HasStructure) { - var node = trivia.GetStructure(); + var node = trivia.GetStructure()!; var trailing = node.GetTrailingTrivia(); if (trailing.Count > 0) { @@ -800,7 +802,7 @@ private static int GetDeclarationDepth(SyntaxTrivia trivia) return GetDeclarationDepth((SyntaxToken)trivia.Token); } - private static int GetDeclarationDepth(SyntaxNode node) + private static int GetDeclarationDepth(SyntaxNode? node) { if (node != null) { diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxReplacer.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxReplacer.cs index 8eda2ae638bdb..045f565e8b49c 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxReplacer.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxReplacer.cs @@ -2,8 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.Text; @@ -15,12 +18,12 @@ internal static class SyntaxReplacer { internal static SyntaxNode Replace( SyntaxNode root, - IEnumerable nodes = null, - Func computeReplacementNode = null, - IEnumerable tokens = null, - Func computeReplacementToken = null, - IEnumerable trivia = null, - Func computeReplacementTrivia = null) + IEnumerable? nodes = null, + Func? computeReplacementNode = null, + IEnumerable? tokens = null, + Func? computeReplacementToken = null, + IEnumerable? trivia = null, + Func? computeReplacementTrivia = null) where TNode : SyntaxNode { var replacer = new Replacer( @@ -40,12 +43,12 @@ internal static SyntaxNode Replace( internal static SyntaxToken Replace( SyntaxToken root, - IEnumerable nodes = null, - Func computeReplacementNode = null, - IEnumerable tokens = null, - Func computeReplacementToken = null, - IEnumerable trivia = null, - Func computeReplacementTrivia = null) + IEnumerable? nodes = null, + Func? computeReplacementNode = null, + IEnumerable? tokens = null, + Func? computeReplacementToken = null, + IEnumerable? trivia = null, + Func? computeReplacementTrivia = null) { var replacer = new Replacer( nodes, computeReplacementNode, @@ -64,9 +67,9 @@ internal static SyntaxToken Replace( private class Replacer : CSharpSyntaxRewriter where TNode : SyntaxNode { - private readonly Func _computeReplacementNode; - private readonly Func _computeReplacementToken; - private readonly Func _computeReplacementTrivia; + private readonly Func? _computeReplacementNode; + private readonly Func? _computeReplacementToken; + private readonly Func? _computeReplacementTrivia; private readonly HashSet _nodeSet; private readonly HashSet _tokenSet; @@ -78,12 +81,12 @@ private class Replacer : CSharpSyntaxRewriter where TNode : SyntaxNode private readonly bool _shouldVisitTrivia; public Replacer( - IEnumerable nodes, - Func computeReplacementNode, - IEnumerable tokens, - Func computeReplacementToken, - IEnumerable trivia, - Func computeReplacementTrivia) + IEnumerable? nodes, + Func? computeReplacementNode, + IEnumerable? tokens, + Func? computeReplacementToken, + IEnumerable? trivia, + Func? computeReplacementTrivia) { _computeReplacementNode = computeReplacementNode; _computeReplacementToken = computeReplacementToken; @@ -175,9 +178,10 @@ private bool ShouldVisit(TextSpan span) return false; } - public override SyntaxNode Visit(SyntaxNode node) + [return: NotNullIfNotNull("node")] + public override SyntaxNode? Visit(SyntaxNode? node) { - SyntaxNode rewritten = node; + SyntaxNode? rewritten = node; if (node != null) { @@ -188,7 +192,7 @@ public override SyntaxNode Visit(SyntaxNode node) if (_nodeSet.Contains(node) && _computeReplacementNode != null) { - rewritten = _computeReplacementNode((TNode)node, (TNode)rewritten); + rewritten = _computeReplacementNode((TNode)node, (TNode)rewritten!); } } @@ -322,9 +326,10 @@ private bool ShouldVisit(TextSpan span) return false; } - public override SyntaxNode Visit(SyntaxNode node) + [return: NotNullIfNotNull("node")] + public override SyntaxNode? Visit(SyntaxNode? node) { - SyntaxNode rewritten = node; + SyntaxNode? rewritten = node; if (node != null) { @@ -377,7 +382,8 @@ public NodeListEditor( _newNodes = replacementNodes; } - public override SyntaxNode Visit(SyntaxNode node) + [return: NotNullIfNotNull("node")] + public override SyntaxNode? Visit(SyntaxNode? node) { if (node == _originalNode) { diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxTreeDiagnosticEnumerator.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxTreeDiagnosticEnumerator.cs index 7f09d5366a321..0c4c22046875b 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxTreeDiagnosticEnumerator.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxTreeDiagnosticEnumerator.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Diagnostics; using Microsoft.CodeAnalysis.Text; @@ -13,13 +15,13 @@ namespace Microsoft.CodeAnalysis.CSharp /// internal struct SyntaxTreeDiagnosticEnumerator { - private readonly SyntaxTree _syntaxTree; + private readonly SyntaxTree? _syntaxTree; private NodeIterationStack _stack; - private Diagnostic _current; + private Diagnostic? _current; private int _position; private const int DefaultStackCapacity = 8; - internal SyntaxTreeDiagnosticEnumerator(SyntaxTree syntaxTree, GreenNode node, int position) + internal SyntaxTreeDiagnosticEnumerator(SyntaxTree syntaxTree, GreenNode? node, int position) { _syntaxTree = null; _current = null; @@ -58,6 +60,7 @@ public bool MoveNext() int leadingWidthAlreadyCounted = node.IsToken ? node.GetLeadingTriviaWidth() : 0; // don't produce locations outside of tree span + Debug.Assert(_syntaxTree is object); var length = _syntaxTree.GetRoot().FullSpan.Length; var spanStart = Math.Min(_position - leadingWidthAlreadyCounted + sdi.Offset, length); var spanWidth = Math.Min(spanStart + sdi.Width, length) - spanStart; @@ -107,7 +110,7 @@ public bool MoveNext() /// public Diagnostic Current { - get { return _current; } + get { Debug.Assert(_current is object); return _current; } } private struct NodeIteration diff --git a/src/Compilers/CSharp/Portable/Syntax/ThrowStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ThrowStatementSyntax.cs index e6798c0de46c4..f0b1445d11b01 100644 --- a/src/Compilers/CSharp/Portable/Syntax/ThrowStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/ThrowStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/TryStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/TryStatementSyntax.cs index 48ff0334a6a86..4ffc88b713682 100644 --- a/src/Compilers/CSharp/Portable/Syntax/TryStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/TryStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/TypeDeclarationSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/TypeDeclarationSyntax.cs index a4209bb26f1c9..6b9fbbebea061 100644 --- a/src/Compilers/CSharp/Portable/Syntax/TypeDeclarationSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/TypeDeclarationSyntax.cs @@ -5,10 +5,7 @@ #nullable enable using System; -using System.Diagnostics; -using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/TypeSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/TypeSyntax.cs index 115be06a438a5..5a1ac32a8549a 100644 --- a/src/Compilers/CSharp/Portable/Syntax/TypeSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/TypeSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + namespace Microsoft.CodeAnalysis.CSharp.Syntax { public abstract partial class TypeSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/UnsafeStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/UnsafeStatementSyntax.cs index 9fff878b2b648..4ad31257f5031 100644 --- a/src/Compilers/CSharp/Portable/Syntax/UnsafeStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/UnsafeStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/UsingStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/UsingStatementSyntax.cs index 9feda6b733cda..a048169aaa6e3 100644 --- a/src/Compilers/CSharp/Portable/Syntax/UsingStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/UsingStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/WhileStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/WhileStatementSyntax.cs index a29071e434bf8..f2430647dae3b 100644 --- a/src/Compilers/CSharp/Portable/Syntax/WhileStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/WhileStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/Syntax/XmlNameAttributeElementKind.cs b/src/Compilers/CSharp/Portable/Syntax/XmlNameAttributeElementKind.cs index 6135a8ebc023e..90e28b80830eb 100644 --- a/src/Compilers/CSharp/Portable/Syntax/XmlNameAttributeElementKind.cs +++ b/src/Compilers/CSharp/Portable/Syntax/XmlNameAttributeElementKind.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; diff --git a/src/Compilers/CSharp/Portable/Syntax/YieldStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/YieldStatementSyntax.cs index 90f70a7fce803..d19b616bf186b 100644 --- a/src/Compilers/CSharp/Portable/Syntax/YieldStatementSyntax.cs +++ b/src/Compilers/CSharp/Portable/Syntax/YieldStatementSyntax.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Syntax diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 11321d0f1f607..aec3bace55ded 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -537,6 +537,11 @@ Parametr typu s možnou hodnotou null musí být známou hodnotou nebo musí jít o typ odkazu, který nemůže mít hodnotu null. Zvažte přidání 'class', 'struct' nebo omezení typu. + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local Výstupní proměnná nemůže být deklarovaná jako lokální proměnná podle odkazu. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 06512493acfa0..562cd01b51be1 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -537,6 +537,11 @@ Ein Nullable-Typparameter muss als Werttyp oder als Non-Nullable-Verweistyp bekannt sein. Sie sollten eine class-, struct- oder eine Typeinschränkung hinzufügen. + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local Eine out-Variable kann nicht als lokales ref-Element deklariert werden. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index d951fffe51264..0575ff86b014a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -537,6 +537,11 @@ Debe saberse si un parámetro de tipo que acepta valores NULL es un tipo de valor o un tipo de referencia que no admite valores NULL. Considere agregar "class", "struct" o una restricción de tipo. + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local Una variable out no se puede declarar como ref local diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index be5d17fe01552..de461331c35ed 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -537,6 +537,11 @@ Un paramètre de type nullable doit être connu pour pouvoir être un type valeur ou un type référence non-nullable. Ajoutez une contrainte 'class', 'struct' ou une contrainte de type. + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local Impossible de déclarer une variable out en tant que variable locale ref diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 0c39aea3033d4..67a09daff5b16 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -537,6 +537,11 @@ Un parametro di tipo che ammette i valori Null deve essere noto per essere un tipo valore o un tipo riferimento che non ammette i valori Null. Provare ad aggiungere un vincolo di tipo, 'class' o 'struct'. + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local Non è possibile dichiarare una variabile out come variabile locale ref diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 83ca6b556423b..fae66adc636f4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -537,6 +537,11 @@ Null 許容型パラメーターは、値の型または Null 非許容参照型として既知である必要があります。'class'、'struct'、型制約を追加することをご検討ください。 + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local out 変数を ref ローカルと宣言することはできません diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 7c64d29d60080..4d7001e452953 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -537,6 +537,11 @@ 값 형식 또는 null을 허용하지 않는 참조 형식이 되려면 nullable 형식 매개 변수를 알려야 합니다. 'class', 'struct' 또는 형식 제약 조건 추가를 고려하세요. + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local 출력 변수는 참조 로컬로 선언할 수 없습니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 025b4b94771d1..5deb92cbbada3 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -537,6 +537,11 @@ Nullowalny parametr typumusi być typem wartości lub nienullowalnym typem referencyjnym. Rozważ dodanie elementu „class”, „struct” lub ograniczenia typu. + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local Zmiennej out nie można zadeklarować jako lokalnej zmiennej ref diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index a66efba099ab8..ecd5b7330c54d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -537,6 +537,11 @@ Um parâmetro de tipo que permite valor nulo precisa ser um tipo de valor ou um tipo de referência não anulável. Considere a possibilidade de adicionar 'class', 'struct' ou restrição de tipo. + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local Uma variável out não pode ser declarada como uma referência local diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index f77f0fa45eb4e..16a6eb0a263b2 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -537,6 +537,11 @@ Параметр типа, допускающего значение NULL, должен быть известен как тип значения или ссылочный тип, не допускающий значение NULL. Рекомендуется добавить "class", "struct" или ограничение типа. + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local Выходная переменная не может быть объявлена как локальная переменная ref diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 98644e909656f..21832f0499aaa 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -537,6 +537,11 @@ Boş değer atanabilir bir tür parametresi bilinen bir değer türü veya boş değer atanamayan bir başvuru türü olmalıdır. Bir 'class', 'struct' veya tür kısıtlaması eklemeyi düşünün. + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local Bir out değişkeni ref yerel değeri olarak bildirilemez diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 033f7b228d986..1a25e509ecccc 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -537,6 +537,11 @@ 可为 null 的类型参数必须已知为值类型或不可为 null 引用类型。请考虑添加一个 “class”、“struct” 或类型约束。 + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local out 变量无法声明为 ref 局部变量 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 04fc47746bd1a..b4c911a3ad2e8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -537,6 +537,11 @@ 可為 Null 的型別參數必須已知為實值型別或不可為 Null 的參考型別。建議新增 'class'、'struct' 或型別條件約束。 + + Omitting the type argument is not allowed in the current context + Omitting the type argument is not allowed in the current context + + An out variable cannot be declared as a ref local out 變數不可宣告為 ref local diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs index ecafaa59f5743..60587d23a1711 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs @@ -533,6 +533,27 @@ static class Program ); } + [Fact] + public void TestNullAsParamsArgument() + { + var comp = CreateCompilationWithMscorlib46(@" +using System; + +class MarkAttribute : Attribute +{ + public MarkAttribute(params object[] b) + { + } +} + +[Mark(null)] +static class Program +{ +}"); + comp.VerifyDiagnostics( + ); + } + [Fact] [WorkItem(20741, "https://github.com/dotnet/roslyn/issues/20741")] public void TestNamedArgumentOnOrderedObjectParamsArgument() diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Security.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Security.cs index a66488dd5fe52..bb0db3e58dc04 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Security.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Security.cs @@ -1520,6 +1520,42 @@ public class MyClass Diagnostic(ErrorCode.ERR_PermissionSetAttributeInvalidFile, "File = null").WithArguments("", "File").WithLocation(5, 46)); } + [Fact] + public void CS7056ERR_PermissionSetAttributeInvalidFile_WithXmlReferenceResolver() + { + var tempDir = Temp.CreateDirectory(); + var tempFile = tempDir.CreateFile("pset.xml"); + + string text = @" + +"; + + tempFile.WriteAllText(text); + + string source = @" +using System.Security.Permissions; + +[PermissionSetAttribute(SecurityAction.Deny, File = @""NonExistentFile.xml"")] +[PermissionSetAttribute(SecurityAction.Deny, File = null)] +public class MyClass +{ +}"; + var resolver = new XmlFileResolver(tempDir.Path); + CreateCompilationWithMscorlib40(source, options: TestOptions.DebugDll.WithXmlReferenceResolver(resolver)).VerifyDiagnostics( + // (4,25): warning CS0618: 'System.Security.Permissions.SecurityAction.Deny' is obsolete: 'Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.' + // [PermissionSetAttribute(SecurityAction.Deny, File = @"NonExistentFile.xml")] + Diagnostic(ErrorCode.WRN_DeprecatedSymbolStr, "SecurityAction.Deny").WithArguments("System.Security.Permissions.SecurityAction.Deny", "Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information."), + // (5,25): warning CS0618: 'System.Security.Permissions.SecurityAction.Deny' is obsolete: 'Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.' + // [PermissionSetAttribute(SecurityAction.Deny, File = null)] + Diagnostic(ErrorCode.WRN_DeprecatedSymbolStr, "SecurityAction.Deny").WithArguments("System.Security.Permissions.SecurityAction.Deny", "Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information."), + // (4,46): error CS7056: Unable to resolve file path 'NonExistentFile.xml' specified for the named argument 'File' for PermissionSet attribute + // [PermissionSetAttribute(SecurityAction.Deny, File = @"NonExistentFile.xml")] + Diagnostic(ErrorCode.ERR_PermissionSetAttributeInvalidFile, @"File = @""NonExistentFile.xml""").WithArguments("NonExistentFile.xml", "File").WithLocation(4, 46), + // (5,46): error CS7056: Unable to resolve file path '' specified for the named argument 'File' for PermissionSet attribute + // [PermissionSetAttribute(SecurityAction.Deny, File = null)] + Diagnostic(ErrorCode.ERR_PermissionSetAttributeInvalidFile, "File = null").WithArguments("", "File").WithLocation(5, 46)); + } + [WorkItem(545084, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545084"), WorkItem(529492, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529492")] [Fact] public void CS7057ERR_PermissionSetAttributeFileReadError() diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs index 367e5b24d1d6b..2f33afac51fba 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs @@ -3516,81 +3516,81 @@ public void Test() var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); compilation.VerifyDiagnostics( - // (13,27): error CS0305: Using the generic method group 'ExtensionMethod0' requires 1 type arguments - // var omittedArg0 = "string literal".ExtensionMethod0<>(); - Diagnostic(ErrorCode.ERR_BadArity, @"""string literal"".ExtensionMethod0<>").WithArguments("ExtensionMethod0", "method group", "1").WithLocation(13, 27), - // (13,44): error CS1061: 'string' does not contain a definition for 'ExtensionMethod0' and no extension method 'ExtensionMethod0' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var omittedArg0 = "string literal".ExtensionMethod0<>(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod0<>").WithArguments("string", "ExtensionMethod0").WithLocation(13, 44), - // (14,27): error CS0305: Using the generic method group 'ExtensionMethod1' requires 1 type arguments - // var omittedArg1 = "string literal".ExtensionMethod1<>(); - Diagnostic(ErrorCode.ERR_BadArity, @"""string literal"".ExtensionMethod1<>").WithArguments("ExtensionMethod1", "method group", "1").WithLocation(14, 27), - // (15,27): error CS0305: Using the generic method group 'ExtensionMethod2' requires 1 type arguments - // var omittedArg2 = "string literal".ExtensionMethod2<>(); - Diagnostic(ErrorCode.ERR_BadArity, @"""string literal"".ExtensionMethod2<>").WithArguments("ExtensionMethod2", "method group", "1").WithLocation(15, 27), - // (15,44): error CS1061: 'string' does not contain a definition for 'ExtensionMethod2' and no extension method 'ExtensionMethod2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var omittedArg2 = "string literal".ExtensionMethod2<>(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2<>").WithArguments("string", "ExtensionMethod2").WithLocation(15, 44), - // (17,31): error CS0305: Using the generic method group 'ExtensionMethod0' requires 1 type arguments - // var omittedArgFunc0 = "string literal".ExtensionMethod0<>; - Diagnostic(ErrorCode.ERR_BadArity, @"""string literal"".ExtensionMethod0<>").WithArguments("ExtensionMethod0", "method group", "1").WithLocation(17, 31), - // (17,48): error CS1061: 'string' does not contain a definition for 'ExtensionMethod0' and no extension method 'ExtensionMethod0' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var omittedArgFunc0 = "string literal".ExtensionMethod0<>; - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod0<>").WithArguments("string", "ExtensionMethod0").WithLocation(17, 48), - // (18,31): error CS0305: Using the generic method group 'ExtensionMethod1' requires 1 type arguments - // var omittedArgFunc1 = "string literal".ExtensionMethod1<>; - Diagnostic(ErrorCode.ERR_BadArity, @"""string literal"".ExtensionMethod1<>").WithArguments("ExtensionMethod1", "method group", "1").WithLocation(18, 31), - // (18,13): error CS0815: Cannot assign method group to an implicitly-typed variable - // var omittedArgFunc1 = "string literal".ExtensionMethod1<>; - Diagnostic(ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, @"omittedArgFunc1 = ""string literal"".ExtensionMethod1<>").WithArguments("method group").WithLocation(18, 13), - // (19,31): error CS0305: Using the generic method group 'ExtensionMethod2' requires 1 type arguments - // var omittedArgFunc2 = "string literal".ExtensionMethod2<>; - Diagnostic(ErrorCode.ERR_BadArity, @"""string literal"".ExtensionMethod2<>").WithArguments("ExtensionMethod2", "method group", "1").WithLocation(19, 31), - // (19,48): error CS1061: 'string' does not contain a definition for 'ExtensionMethod2' and no extension method 'ExtensionMethod2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var omittedArgFunc2 = "string literal".ExtensionMethod2<>; - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2<>").WithArguments("string", "ExtensionMethod2").WithLocation(19, 48), - // (21,42): error CS1061: 'string' does not contain a definition for 'ExtensionMethod0' and no extension method 'ExtensionMethod0' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var moreArgs0 = "string literal".ExtensionMethod0(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod0").WithArguments("string", "ExtensionMethod0").WithLocation(21, 42), - // (22,42): error CS1061: 'string' does not contain a definition for 'ExtensionMethod1' and no extension method 'ExtensionMethod1' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var moreArgs1 = "string literal".ExtensionMethod1(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod1").WithArguments("string", "ExtensionMethod1").WithLocation(22, 42), - // (23,42): error CS1061: 'string' does not contain a definition for 'ExtensionMethod2' and no extension method 'ExtensionMethod2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var moreArgs2 = "string literal".ExtensionMethod2(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2").WithArguments("string", "ExtensionMethod2").WithLocation(23, 42), - // (25,42): error CS0411: The type arguments for method 'FooExtensions.ExtensionMethod1(object)' cannot be inferred from the usage. Try specifying the type arguments explicitly. - // var lessArgs1 = "string literal".ExtensionMethod1(); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "ExtensionMethod1").WithArguments("FooExtensions.ExtensionMethod1(object)").WithLocation(25, 42), - // (26,42): error CS1061: 'string' does not contain a definition for 'ExtensionMethod2' and no extension method 'ExtensionMethod2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var lessArgs2 = "string literal".ExtensionMethod2(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2").WithArguments("string", "ExtensionMethod2").WithLocation(26, 42), - // (28,51): error CS1061: 'string' does not contain a definition for 'ExtensionMethodNotFound0' and no extension method 'ExtensionMethodNotFound0' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var nonExistingMethod0 = "string literal".ExtensionMethodNotFound0(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethodNotFound0").WithArguments("string", "ExtensionMethodNotFound0").WithLocation(28, 51), - // (29,51): error CS1061: 'string' does not contain a definition for 'ExtensionMethodNotFound1' and no extension method 'ExtensionMethodNotFound1' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var nonExistingMethod1 = "string literal".ExtensionMethodNotFound1(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethodNotFound1").WithArguments("string", "ExtensionMethodNotFound1").WithLocation(29, 51), - // (30,51): error CS1061: 'string' does not contain a definition for 'ExtensionMethodNotFound2' and no extension method 'ExtensionMethodNotFound2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // var nonExistingMethod2 = "string literal".ExtensionMethodNotFound2(); - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethodNotFound2").WithArguments("string", "ExtensionMethodNotFound2").WithLocation(30, 51), - // (32,51): error CS0305: Using the generic method group 'ExtensionMethod0' requires 1 type arguments - // System.Func delegateConversion0 = "string literal".ExtensionMethod0<>; - Diagnostic(ErrorCode.ERR_BadArity, @"""string literal"".ExtensionMethod0<>").WithArguments("ExtensionMethod0", "method group", "1").WithLocation(32, 51), - // (32,68): error CS1061: 'string' does not contain a definition for 'ExtensionMethod0' and no extension method 'ExtensionMethod0' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // System.Func delegateConversion0 = "string literal".ExtensionMethod0<>; - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod0<>").WithArguments("string", "ExtensionMethod0").WithLocation(32, 68), - // (33,51): error CS0305: Using the generic method group 'ExtensionMethod1' requires 1 type arguments - // System.Func delegateConversion1 = "string literal".ExtensionMethod1<>; - Diagnostic(ErrorCode.ERR_BadArity, @"""string literal"".ExtensionMethod1<>").WithArguments("ExtensionMethod1", "method group", "1").WithLocation(33, 51), - // (33,51): error CS0407: '? FooExtensions.ExtensionMethod1(object)' has the wrong return type - // System.Func delegateConversion1 = "string literal".ExtensionMethod1<>; - Diagnostic(ErrorCode.ERR_BadRetType, @"""string literal"".ExtensionMethod1<>").WithArguments("FooExtensions.ExtensionMethod1(object)", "?").WithLocation(33, 51), - // (34,51): error CS0305: Using the generic method group 'ExtensionMethod2' requires 1 type arguments - // System.Func delegateConversion2 = "string literal".ExtensionMethod2<>; - Diagnostic(ErrorCode.ERR_BadArity, @"""string literal"".ExtensionMethod2<>").WithArguments("ExtensionMethod2", "method group", "1").WithLocation(34, 51), - // (34,68): error CS1061: 'string' does not contain a definition for 'ExtensionMethod2' and no extension method 'ExtensionMethod2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) - // System.Func delegateConversion2 = "string literal".ExtensionMethod2<>; - Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2<>").WithArguments("string", "ExtensionMethod2").WithLocation(34, 68)); + // (13,27): error CS8389: Omitting the type argument is not allowed in the current context + // var omittedArg0 = "string literal".ExtensionMethod0<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod0<>").WithLocation(13, 27), + // (13,44): error CS1061: 'string' does not contain a definition for 'ExtensionMethod0' and no accessible extension method 'ExtensionMethod0' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var omittedArg0 = "string literal".ExtensionMethod0<>(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod0<>").WithArguments("string", "ExtensionMethod0").WithLocation(13, 44), + // (14,27): error CS8389: Omitting the type argument is not allowed in the current context + // var omittedArg1 = "string literal".ExtensionMethod1<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod1<>").WithLocation(14, 27), + // (15,27): error CS8389: Omitting the type argument is not allowed in the current context + // var omittedArg2 = "string literal".ExtensionMethod2<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod2<>").WithLocation(15, 27), + // (15,44): error CS1061: 'string' does not contain a definition for 'ExtensionMethod2' and no accessible extension method 'ExtensionMethod2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var omittedArg2 = "string literal".ExtensionMethod2<>(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2<>").WithArguments("string", "ExtensionMethod2").WithLocation(15, 44), + // (17,31): error CS8389: Omitting the type argument is not allowed in the current context + // var omittedArgFunc0 = "string literal".ExtensionMethod0<>; + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod0<>").WithLocation(17, 31), + // (17,48): error CS1061: 'string' does not contain a definition for 'ExtensionMethod0' and no accessible extension method 'ExtensionMethod0' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var omittedArgFunc0 = "string literal".ExtensionMethod0<>; + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod0<>").WithArguments("string", "ExtensionMethod0").WithLocation(17, 48), + // (18,31): error CS8389: Omitting the type argument is not allowed in the current context + // var omittedArgFunc1 = "string literal".ExtensionMethod1<>; + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod1<>").WithLocation(18, 31), + // (18,13): error CS0815: Cannot assign method group to an implicitly-typed variable + // var omittedArgFunc1 = "string literal".ExtensionMethod1<>; + Diagnostic(ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, @"omittedArgFunc1 = ""string literal"".ExtensionMethod1<>").WithArguments("method group").WithLocation(18, 13), + // (19,31): error CS8389: Omitting the type argument is not allowed in the current context + // var omittedArgFunc2 = "string literal".ExtensionMethod2<>; + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod2<>").WithLocation(19, 31), + // (19,48): error CS1061: 'string' does not contain a definition for 'ExtensionMethod2' and no accessible extension method 'ExtensionMethod2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var omittedArgFunc2 = "string literal".ExtensionMethod2<>; + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2<>").WithArguments("string", "ExtensionMethod2").WithLocation(19, 48), + // (21,42): error CS1061: 'string' does not contain a definition for 'ExtensionMethod0' and no accessible extension method 'ExtensionMethod0' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var moreArgs0 = "string literal".ExtensionMethod0(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod0").WithArguments("string", "ExtensionMethod0").WithLocation(21, 42), + // (22,42): error CS1061: 'string' does not contain a definition for 'ExtensionMethod1' and no accessible extension method 'ExtensionMethod1' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var moreArgs1 = "string literal".ExtensionMethod1(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod1").WithArguments("string", "ExtensionMethod1").WithLocation(22, 42), + // (23,42): error CS1061: 'string' does not contain a definition for 'ExtensionMethod2' and no accessible extension method 'ExtensionMethod2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var moreArgs2 = "string literal".ExtensionMethod2(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2").WithArguments("string", "ExtensionMethod2").WithLocation(23, 42), + // (25,42): error CS0411: The type arguments for method 'FooExtensions.ExtensionMethod1(object)' cannot be inferred from the usage. Try specifying the type arguments explicitly. + // var lessArgs1 = "string literal".ExtensionMethod1(); + Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "ExtensionMethod1").WithArguments("FooExtensions.ExtensionMethod1(object)").WithLocation(25, 42), + // (26,42): error CS1061: 'string' does not contain a definition for 'ExtensionMethod2' and no accessible extension method 'ExtensionMethod2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var lessArgs2 = "string literal".ExtensionMethod2(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2").WithArguments("string", "ExtensionMethod2").WithLocation(26, 42), + // (28,51): error CS1061: 'string' does not contain a definition for 'ExtensionMethodNotFound0' and no accessible extension method 'ExtensionMethodNotFound0' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var nonExistingMethod0 = "string literal".ExtensionMethodNotFound0(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethodNotFound0").WithArguments("string", "ExtensionMethodNotFound0").WithLocation(28, 51), + // (29,51): error CS1061: 'string' does not contain a definition for 'ExtensionMethodNotFound1' and no accessible extension method 'ExtensionMethodNotFound1' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var nonExistingMethod1 = "string literal".ExtensionMethodNotFound1(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethodNotFound1").WithArguments("string", "ExtensionMethodNotFound1").WithLocation(29, 51), + // (30,51): error CS1061: 'string' does not contain a definition for 'ExtensionMethodNotFound2' and no accessible extension method 'ExtensionMethodNotFound2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // var nonExistingMethod2 = "string literal".ExtensionMethodNotFound2(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethodNotFound2").WithArguments("string", "ExtensionMethodNotFound2").WithLocation(30, 51), + // (32,51): error CS8389: Omitting the type argument is not allowed in the current context + // System.Func delegateConversion0 = "string literal".ExtensionMethod0<>; + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod0<>").WithLocation(32, 51), + // (32,68): error CS1061: 'string' does not contain a definition for 'ExtensionMethod0' and no accessible extension method 'ExtensionMethod0' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // System.Func delegateConversion0 = "string literal".ExtensionMethod0<>; + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod0<>").WithArguments("string", "ExtensionMethod0").WithLocation(32, 68), + // (33,51): error CS8389: Omitting the type argument is not allowed in the current context + // System.Func delegateConversion1 = "string literal".ExtensionMethod1<>; + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod1<>").WithLocation(33, 51), + // (33,51): error CS0407: '? FooExtensions.ExtensionMethod1(object)' has the wrong return type + // System.Func delegateConversion1 = "string literal".ExtensionMethod1<>; + Diagnostic(ErrorCode.ERR_BadRetType, @"""string literal"".ExtensionMethod1<>").WithArguments("FooExtensions.ExtensionMethod1(object)", "?").WithLocation(33, 51), + // (34,51): error CS8389: Omitting the type argument is not allowed in the current context + // System.Func delegateConversion2 = "string literal".ExtensionMethod2<>; + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, @"""string literal"".ExtensionMethod2<>").WithLocation(34, 51), + // (34,68): error CS1061: 'string' does not contain a definition for 'ExtensionMethod2' and no accessible extension method 'ExtensionMethod2' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) + // System.Func delegateConversion2 = "string literal".ExtensionMethod2<>; + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "ExtensionMethod2<>").WithArguments("string", "ExtensionMethod2").WithLocation(34, 68)); } [WorkItem(22757, "https://github.com/dotnet/roslyn/issues/22757")] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs index cd828e08d82c6..b81f7d7e7f04f 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs @@ -295,7 +295,7 @@ class Test // (28,20): error CS0103: The name 'List2' does not exist in the current context // s = nameof(List2<>.Add); Diagnostic(ErrorCode.ERR_NameNotInContext, "List2<>").WithArguments("List2").WithLocation(28, 20), - // (31,20): error CS8149: An alias-qualified name is not an expression. + // (31,20): error CS8083: An alias-qualified name is not an expression. // s = nameof(global::Program); // not an expression Diagnostic(ErrorCode.ERR_AliasQualifiedNameNotAnExpression, "global::Program").WithLocation(31, 20), // (32,20): error CS0305: Using the generic type 'Test' requires 1 type arguments @@ -307,7 +307,7 @@ class Test // (33,20): error CS0841: Cannot use local variable 'b' before it is declared // s = nameof(b); // cannot use before declaration Diagnostic(ErrorCode.ERR_VariableUsedBeforeDeclaration, "b").WithArguments("b").WithLocation(33, 20), - // (35,20): error CS8150: Type parameters are not allowed on a method group as an argument to 'nameof'. + // (35,20): error CS8084: Type parameters are not allowed on a method group as an argument to 'nameof'. // s = nameof(System.Linq.Enumerable.Select); // type parameters not allowed on method group in nameof Diagnostic(ErrorCode.ERR_NameofMethodGroupWithTypeParameters, "System.Linq.Enumerable.Select").WithLocation(35, 20), // (43,13): error CS0103: The name 'nameof' does not exist in the current context diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests2.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests2.cs index 187d4b65adea0..f5baad8ca0e21 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests2.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests2.cs @@ -347,6 +347,22 @@ public static void Main() switch (i) { case default: break; } // error 3 switch (i) { case default when true: break; } // error 4 switch ((1, 2)) { case (1, default): break; } // error 5 + + if (i is < default) {} // error 6 + switch (i) { case < default: break; } // error 7 + if (i is < ((default))) {} // error 8 + switch (i) { case < ((default)): break; } // error 9 + + if (i is default!) {} // error 10 + if (i is (default!)) {} // error 11 + if (i is < ((default)!)) {} // error 12 + if (i is default!!) {} // error 13 + if (i is (default!!)) {} // error 14 + if (i is < ((default)!!)) {} // error 15 + + // These are not accepted by the parser. See https://github.com/dotnet/roslyn/issues/45387 + if (i is (default)!) {} // error 16 + if (i is ((default)!)) {} // error 17 } }"; var compilation = CreatePatternCompilation(source); @@ -365,7 +381,67 @@ public static void Main() Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(9, 27), // (10,36): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. // switch ((1, 2)) { case (1, default): break; } // error 5 - Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(10, 36) + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(10, 36), + // (12,20): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // if (i is < default) {} // error 6 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(12, 20), + // (13,29): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // switch (i) { case < default: break; } // error 7 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(13, 29), + // (14,22): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // if (i is < ((default))) {} // error 8 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(14, 22), + // (15,31): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // switch (i) { case < ((default)): break; } // error 9 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(15, 31), + // (17,18): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // if (i is default!) {} // error 10 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(17, 18), + // (18,19): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // if (i is (default!)) {} // error 11 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(18, 19), + // (19,22): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // if (i is < ((default)!)) {} // error 12 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(19, 22), + // (20,18): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // if (i is default!!) {} // error 13 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(20, 18), + // (21,19): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // if (i is (default!!)) {} // error 14 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(21, 19), + // (22,22): error CS8715: Duplicate null suppression operator ('!') + // if (i is < ((default)!!)) {} // error 15 + Diagnostic(ErrorCode.ERR_DuplicateNullSuppression, "default").WithLocation(22, 22), + // (22,22): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // if (i is < ((default)!!)) {} // error 15 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(22, 22), + // (25,19): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // if (i is (default)!) {} // error 16 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(25, 19), + // (25,27): error CS1026: ) expected + // if (i is (default)!) {} // error 16 + Diagnostic(ErrorCode.ERR_CloseParenExpected, "!").WithLocation(25, 27), + // (25,28): error CS1525: Invalid expression term ')' + // if (i is (default)!) {} // error 16 + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(25, 28), + // (25,28): error CS1002: ; expected + // if (i is (default)!) {} // error 16 + Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(25, 28), + // (25,28): error CS1513: } expected + // if (i is (default)!) {} // error 16 + Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(25, 28), + // (26,18): error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'int', with 2 out parameters and a void return type. + // if (i is ((default)!)) {} // error 17 + Diagnostic(ErrorCode.ERR_MissingDeconstruct, "((default)!)").WithArguments("int", "2").WithLocation(26, 18), + // (26,20): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. + // if (i is ((default)!)) {} // error 17 + Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(26, 20), + // (26,28): error CS1003: Syntax error, ',' expected + // if (i is ((default)!)) {} // error 17 + Diagnostic(ErrorCode.ERR_SyntaxError, "!").WithArguments(",", "!").WithLocation(26, 28), + // (26,29): error CS1525: Invalid expression term ')' + // if (i is ((default)!)) {} // error 17 + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(26, 29) ); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs index ca68d91577e0d..2627940b0f6d1 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs @@ -4,6 +4,7 @@ #nullable enable +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -7033,6 +7034,8 @@ public static void Main() var c = new C(1, 2); Console.WriteLine(c.Z); } + + C(int X, int Y, int Z) : this(X, Y) {} }"; var verifier = CompileAndVerify(src, expectedOutput: @" 1 @@ -7077,10 +7080,42 @@ .maxstack 3 Assert.Contains(symbol, model.LookupSymbols(x.SpanStart, name: "X")); Assert.Contains("X", model.LookupNames(x.SpanStart)); - var baseWithargs = tree.GetRoot().DescendantNodes().OfType().Single(); - Assert.Equal("Base(X, Y)", baseWithargs.ToString()); - Assert.Null(model.GetTypeInfo(baseWithargs).Type); - Assert.Null(model.GetSymbolInfo(baseWithargs).Symbol); + { + var baseWithargs = tree.GetRoot().DescendantNodes().OfType().Single(); + Assert.Equal("Base(X, Y)", baseWithargs.ToString()); + Assert.Equal("Base", model.GetTypeInfo(baseWithargs.Type).Type.ToTestDisplayString()); + Assert.Equal(TypeInfo.None, model.GetTypeInfo(baseWithargs)); + Assert.Equal("Base..ctor(System.Int32 X, System.Int32 Y)", model.GetSymbolInfo((SyntaxNode)baseWithargs).Symbol.ToTestDisplayString()); + Assert.Equal("Base..ctor(System.Int32 X, System.Int32 Y)", model.GetSymbolInfo(baseWithargs).Symbol.ToTestDisplayString()); + Assert.Equal("Base..ctor(System.Int32 X, System.Int32 Y)", CSharpExtensions.GetSymbolInfo(model, baseWithargs).Symbol.ToTestDisplayString()); + + Assert.Empty(model.GetMemberGroup((SyntaxNode)baseWithargs)); + Assert.Empty(model.GetMemberGroup(baseWithargs)); + + model = comp.GetSemanticModel(tree); + Assert.Equal("Base..ctor(System.Int32 X, System.Int32 Y)", model.GetSymbolInfo((SyntaxNode)baseWithargs).Symbol.ToTestDisplayString()); + model = comp.GetSemanticModel(tree); + Assert.Equal("Base..ctor(System.Int32 X, System.Int32 Y)", model.GetSymbolInfo(baseWithargs).Symbol.ToTestDisplayString()); + model = comp.GetSemanticModel(tree); + Assert.Equal("Base..ctor(System.Int32 X, System.Int32 Y)", CSharpExtensions.GetSymbolInfo(model, baseWithargs).Symbol.ToTestDisplayString()); + + model = comp.GetSemanticModel(tree); + Assert.Empty(model.GetMemberGroup((SyntaxNode)baseWithargs)); + model = comp.GetSemanticModel(tree); + Assert.Empty(model.GetMemberGroup(baseWithargs)); + model = comp.GetSemanticModel(tree); + } + { + var baseWithargs = tree.GetRoot().DescendantNodes().OfType().Single(); + Assert.Equal(": this(X, Y)", baseWithargs.ToString()); + Assert.Equal("C..ctor(System.Int32 X, System.Int32 Y)", model.GetSymbolInfo((SyntaxNode)baseWithargs).Symbol.ToTestDisplayString()); + Assert.Equal("C..ctor(System.Int32 X, System.Int32 Y)", model.GetSymbolInfo(baseWithargs).Symbol.ToTestDisplayString()); + Assert.Equal("C..ctor(System.Int32 X, System.Int32 Y)", CSharpExtensions.GetSymbolInfo(model, baseWithargs).Symbol.ToTestDisplayString()); + + Assert.Empty(model.GetMemberGroup((SyntaxNode)baseWithargs).Select(m => m.ToTestDisplayString())); + Assert.Empty(model.GetMemberGroup(baseWithargs).Select(m => m.ToTestDisplayString())); + Assert.Empty(CSharpExtensions.GetMemberGroup(model, baseWithargs).Select(m => m.ToTestDisplayString())); + } } [Fact] @@ -7825,6 +7860,327 @@ private static int Test(int x, out int y) ); } + [Fact] + public void BaseArguments_19() + { + var src = @" +record Base +{ + public Base(int X) + { + } + + public Base() {} +} + +record C(int X, int Y) : Base(GetInt(X, out var xx) + xx, Y), I +{ + C(int X, int Y, int Z) : this(X, Y, Z, 1) { return; } + + static int GetInt(int x1, out int x2) + { + throw null; + } +} + +interface I {} +"; + + var comp = CreateCompilation(src); + + comp.VerifyDiagnostics( + // (11,30): error CS1729: 'Base' does not contain a constructor that takes 2 arguments + // record C(int X, int Y) : Base(GetInt(X, out var xx) + xx, Y) + Diagnostic(ErrorCode.ERR_BadCtorArgCount, "(GetInt(X, out var xx) + xx, Y)").WithArguments("Base", "2").WithLocation(11, 30), + // (13,30): error CS1729: 'C' does not contain a constructor that takes 4 arguments + // C(int X, int Y, int Z) : this(X, Y, Z, 1) {} + Diagnostic(ErrorCode.ERR_BadCtorArgCount, "this").WithArguments("C", "4").WithLocation(13, 30) + ); + + var tree = comp.SyntaxTrees.First(); + var model = comp.GetSemanticModel(tree); + SymbolInfo symbolInfo; + PrimaryConstructorBaseTypeSyntax speculativePrimaryInitializer; + ConstructorInitializerSyntax speculativeBaseInitializer; + + { + var baseWithargs = tree.GetRoot().DescendantNodes().OfType().Single(); + Assert.Equal("Base(GetInt(X, out var xx) + xx, Y)", baseWithargs.ToString()); + Assert.Equal("Base", model.GetTypeInfo(baseWithargs.Type).Type.ToTestDisplayString()); + Assert.Equal(TypeInfo.None, model.GetTypeInfo(baseWithargs)); + symbolInfo = model.GetSymbolInfo((SyntaxNode)baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + string[] candidates = new[] { "Base..ctor(System.Int32 X)", "Base..ctor()", "Base..ctor(Base )" }; + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + symbolInfo = model.GetSymbolInfo(baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + symbolInfo = CSharpExtensions.GetSymbolInfo(model, baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + + Assert.Empty(model.GetMemberGroup((SyntaxNode)baseWithargs)); + Assert.Empty(model.GetMemberGroup(baseWithargs)); + + model = comp.GetSemanticModel(tree); + symbolInfo = model.GetSymbolInfo((SyntaxNode)baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + model = comp.GetSemanticModel(tree); + symbolInfo = model.GetSymbolInfo(baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + model = comp.GetSemanticModel(tree); + symbolInfo = CSharpExtensions.GetSymbolInfo(model, baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + + model = comp.GetSemanticModel(tree); + Assert.Empty(model.GetMemberGroup((SyntaxNode)baseWithargs)); + model = comp.GetSemanticModel(tree); + Assert.Empty(model.GetMemberGroup(baseWithargs)); + model = comp.GetSemanticModel(tree); + + SemanticModel speculativeModel; + speculativePrimaryInitializer = baseWithargs.WithArgumentList(baseWithargs.ArgumentList.WithArguments(baseWithargs.ArgumentList.Arguments.RemoveAt(1))); + + speculativeBaseInitializer = SyntaxFactory.ConstructorInitializer(SyntaxKind.BaseConstructorInitializer, speculativePrimaryInitializer.ArgumentList); + Assert.False(model.TryGetSpeculativeSemanticModel(baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativeBaseInitializer, out _)); + + symbolInfo = model.GetSpeculativeSymbolInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (SyntaxNode)speculativeBaseInitializer, SpeculativeBindingOption.BindAsExpression); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = CSharpExtensions.GetSpeculativeSymbolInfo(model, baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativeBaseInitializer); + Assert.Equal(SymbolInfo.None, symbolInfo); + + Assert.False(model.TryGetSpeculativeSemanticModel(tree.GetRoot().DescendantNodes().OfType().Single().SpanStart, + speculativeBaseInitializer, out _)); + + var otherBasePosition = ((BaseListSyntax)baseWithargs.Parent!).Types[1].SpanStart; + Assert.False(model.TryGetSpeculativeSemanticModel(otherBasePosition, speculativePrimaryInitializer, out _)); + + Assert.True(model.TryGetSpeculativeSemanticModel(baseWithargs.SpanStart, speculativePrimaryInitializer, out speculativeModel!)); + Assert.Equal("Base..ctor(System.Int32 X)", speculativeModel!.GetSymbolInfo((SyntaxNode)speculativePrimaryInitializer).Symbol.ToTestDisplayString()); + Assert.Equal("Base..ctor(System.Int32 X)", speculativeModel.GetSymbolInfo(speculativePrimaryInitializer).Symbol.ToTestDisplayString()); + Assert.Equal("Base..ctor(System.Int32 X)", CSharpExtensions.GetSymbolInfo(speculativeModel, speculativePrimaryInitializer).Symbol.ToTestDisplayString()); + + Assert.True(model.TryGetSpeculativeSemanticModel(baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativePrimaryInitializer, out speculativeModel!)); + + var xxDecl = OutVarTests.GetOutVarDeclaration(speculativePrimaryInitializer.SyntaxTree, "xx"); + var xxRef = OutVarTests.GetReferences(speculativePrimaryInitializer.SyntaxTree, "xx").ToArray(); + Assert.Equal(1, xxRef.Length); + OutVarTests.VerifyModelForOutVar(speculativeModel, xxDecl, xxRef); + + Assert.Equal("Base..ctor(System.Int32 X)", speculativeModel!.GetSymbolInfo((SyntaxNode)speculativePrimaryInitializer).Symbol.ToTestDisplayString()); + Assert.Equal("Base..ctor(System.Int32 X)", speculativeModel.GetSymbolInfo(speculativePrimaryInitializer).Symbol.ToTestDisplayString()); + Assert.Equal("Base..ctor(System.Int32 X)", CSharpExtensions.GetSymbolInfo(speculativeModel, speculativePrimaryInitializer).Symbol.ToTestDisplayString()); + + Assert.Throws(() => model.TryGetSpeculativeSemanticModel(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (PrimaryConstructorBaseTypeSyntax)null!, out _)); + Assert.Throws(() => model.TryGetSpeculativeSemanticModel(baseWithargs.ArgumentList.OpenParenToken.SpanStart, baseWithargs, out _)); + + symbolInfo = model.GetSpeculativeSymbolInfo(otherBasePosition, (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = CSharpExtensions.GetSpeculativeSymbolInfo(model, otherBasePosition, speculativePrimaryInitializer); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = model.GetSpeculativeSymbolInfo(baseWithargs.SpanStart, (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression); + Assert.Equal("Base..ctor(System.Int32 X)", symbolInfo.Symbol.ToTestDisplayString()); + + symbolInfo = CSharpExtensions.GetSpeculativeSymbolInfo(model, baseWithargs.SpanStart, speculativePrimaryInitializer); + Assert.Equal("Base..ctor(System.Int32 X)", symbolInfo.Symbol.ToTestDisplayString()); + + symbolInfo = model.GetSpeculativeSymbolInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression); + Assert.Equal("Base..ctor(System.Int32 X)", symbolInfo.Symbol.ToTestDisplayString()); + + symbolInfo = CSharpExtensions.GetSpeculativeSymbolInfo(model, baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativePrimaryInitializer); + Assert.Equal("Base..ctor(System.Int32 X)", symbolInfo.Symbol.ToTestDisplayString()); + + Assert.Equal(TypeInfo.None, model.GetSpeculativeTypeInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression)); + Assert.Equal(TypeInfo.None, model.GetSpeculativeTypeInfo(tree.GetRoot().DescendantNodes().OfType().Single().ArgumentList.OpenParenToken.SpanStart, + (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression)); + } + { + var baseWithargs = tree.GetRoot().DescendantNodes().OfType().Single(); + Assert.Equal(": this(X, Y, Z, 1)", baseWithargs.ToString()); + symbolInfo = model.GetSymbolInfo((SyntaxNode)baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + string[] candidates = new[] { "C..ctor(System.Int32 X, System.Int32 Y, System.Int32 Z)", "C..ctor(System.Int32 X, System.Int32 Y)", "C..ctor(C )" }; + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + symbolInfo = model.GetSymbolInfo(baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + symbolInfo = CSharpExtensions.GetSymbolInfo(model, baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + + Assert.Empty(model.GetMemberGroup((SyntaxNode)baseWithargs).Select(m => m.ToTestDisplayString())); + Assert.Empty(model.GetMemberGroup(baseWithargs).Select(m => m.ToTestDisplayString())); + Assert.Empty(CSharpExtensions.GetMemberGroup(model, baseWithargs).Select(m => m.ToTestDisplayString())); + + Assert.False(model.TryGetSpeculativeSemanticModel(baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativePrimaryInitializer, out _)); + + symbolInfo = model.GetSpeculativeSymbolInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativePrimaryInitializer); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = model.GetSpeculativeSymbolInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (SyntaxNode)speculativeBaseInitializer, SpeculativeBindingOption.BindAsExpression); + Assert.Equal("Base..ctor(System.Int32 X)", symbolInfo.Symbol.ToTestDisplayString()); + + symbolInfo = CSharpExtensions.GetSpeculativeSymbolInfo(model, baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativeBaseInitializer); + Assert.Equal("Base..ctor(System.Int32 X)", symbolInfo.Symbol.ToTestDisplayString()); + + Assert.Equal(TypeInfo.None, model.GetSpeculativeTypeInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression)); + } + } + + [Fact] + public void BaseArguments_20() + { + var src = @" +class Base +{ + public Base(int X) + { + } + + public Base() {} +} + +class C : Base(GetInt(X, out var xx) + xx, Y), I +{ + C(int X, int Y, int Z) : base(X, Y, Z, 1) { return; } + + static int GetInt(int x1, out int x2) + { + throw null; + } +} + +interface I {} +"; + + var comp = CreateCompilation(src); + + comp.VerifyDiagnostics( + // (11,15): error CS8861: Unexpected argument list. + // class C : Base(GetInt(X, out var xx) + xx, Y), I + Diagnostic(ErrorCode.ERR_UnexpectedArgumentList, "(").WithLocation(11, 15), + // (13,30): error CS1729: 'Base' does not contain a constructor that takes 4 arguments + // C(int X, int Y, int Z) : base(X, Y, Z, 1) { return; } + Diagnostic(ErrorCode.ERR_BadCtorArgCount, "base").WithArguments("Base", "4").WithLocation(13, 30) + ); + + var tree = comp.SyntaxTrees.First(); + var model = comp.GetSemanticModel(tree); + SymbolInfo symbolInfo; + PrimaryConstructorBaseTypeSyntax speculativePrimaryInitializer; + ConstructorInitializerSyntax speculativeBaseInitializer; + + { + var baseWithargs = tree.GetRoot().DescendantNodes().OfType().Single(); + Assert.Equal("Base(GetInt(X, out var xx) + xx, Y)", baseWithargs.ToString()); + Assert.Equal("Base", model.GetTypeInfo(baseWithargs.Type).Type.ToTestDisplayString()); + Assert.Equal(TypeInfo.None, model.GetTypeInfo(baseWithargs)); + symbolInfo = model.GetSymbolInfo((SyntaxNode)baseWithargs); + Assert.Equal(SymbolInfo.None, symbolInfo); + symbolInfo = model.GetSymbolInfo(baseWithargs); + Assert.Equal(SymbolInfo.None, symbolInfo); + symbolInfo = CSharpExtensions.GetSymbolInfo(model, baseWithargs); + Assert.Equal(SymbolInfo.None, symbolInfo); + + Assert.Empty(model.GetMemberGroup((SyntaxNode)baseWithargs)); + Assert.Empty(model.GetMemberGroup(baseWithargs)); + + speculativePrimaryInitializer = baseWithargs.WithArgumentList(baseWithargs.ArgumentList.WithArguments(baseWithargs.ArgumentList.Arguments.RemoveAt(1))); + + speculativeBaseInitializer = SyntaxFactory.ConstructorInitializer(SyntaxKind.BaseConstructorInitializer, speculativePrimaryInitializer.ArgumentList); + Assert.False(model.TryGetSpeculativeSemanticModel(baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativeBaseInitializer, out _)); + + symbolInfo = model.GetSpeculativeSymbolInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (SyntaxNode)speculativeBaseInitializer, SpeculativeBindingOption.BindAsExpression); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = CSharpExtensions.GetSpeculativeSymbolInfo(model, baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativeBaseInitializer); + Assert.Equal(SymbolInfo.None, symbolInfo); + + Assert.False(model.TryGetSpeculativeSemanticModel(tree.GetRoot().DescendantNodes().OfType().Single().SpanStart, + speculativeBaseInitializer, out _)); + + var otherBasePosition = ((BaseListSyntax)baseWithargs.Parent!).Types[1].SpanStart; + Assert.False(model.TryGetSpeculativeSemanticModel(otherBasePosition, speculativePrimaryInitializer, out _)); + + Assert.False(model.TryGetSpeculativeSemanticModel(baseWithargs.SpanStart, speculativePrimaryInitializer, out _)); + Assert.False(model.TryGetSpeculativeSemanticModel(baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativePrimaryInitializer, out _)); + + Assert.Throws(() => model.TryGetSpeculativeSemanticModel(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (PrimaryConstructorBaseTypeSyntax)null!, out _)); + Assert.Throws(() => model.TryGetSpeculativeSemanticModel(baseWithargs.ArgumentList.OpenParenToken.SpanStart, baseWithargs, out _)); + + symbolInfo = model.GetSpeculativeSymbolInfo(otherBasePosition, (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = CSharpExtensions.GetSpeculativeSymbolInfo(model, otherBasePosition, speculativePrimaryInitializer); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = model.GetSpeculativeSymbolInfo(baseWithargs.SpanStart, (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = CSharpExtensions.GetSpeculativeSymbolInfo(model, baseWithargs.SpanStart, speculativePrimaryInitializer); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = model.GetSpeculativeSymbolInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = CSharpExtensions.GetSpeculativeSymbolInfo(model, baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativePrimaryInitializer); + Assert.Equal(SymbolInfo.None, symbolInfo); + + Assert.Equal(TypeInfo.None, model.GetSpeculativeTypeInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression)); + Assert.Equal(TypeInfo.None, model.GetSpeculativeTypeInfo(tree.GetRoot().DescendantNodes().OfType().Single().ArgumentList.OpenParenToken.SpanStart, + (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression)); + } + { + var baseWithargs = tree.GetRoot().DescendantNodes().OfType().Single(); + Assert.Equal(": base(X, Y, Z, 1)", baseWithargs.ToString()); + symbolInfo = model.GetSymbolInfo((SyntaxNode)baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + string[] candidates = new[] { "Base..ctor(System.Int32 X)", "Base..ctor()" }; + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + symbolInfo = model.GetSymbolInfo(baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + symbolInfo = CSharpExtensions.GetSymbolInfo(model, baseWithargs); + Assert.Null(symbolInfo.Symbol); + Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); + Assert.Equal(candidates, symbolInfo.CandidateSymbols.Select(m => m.ToTestDisplayString())); + + Assert.Empty(model.GetMemberGroup((SyntaxNode)baseWithargs).Select(m => m.ToTestDisplayString())); + Assert.Empty(model.GetMemberGroup(baseWithargs).Select(m => m.ToTestDisplayString())); + Assert.Empty(CSharpExtensions.GetMemberGroup(model, baseWithargs).Select(m => m.ToTestDisplayString())); + + Assert.False(model.TryGetSpeculativeSemanticModel(baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativePrimaryInitializer, out _)); + + symbolInfo = model.GetSpeculativeSymbolInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativePrimaryInitializer); + Assert.Equal(SymbolInfo.None, symbolInfo); + + symbolInfo = model.GetSpeculativeSymbolInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (SyntaxNode)speculativeBaseInitializer, SpeculativeBindingOption.BindAsExpression); + Assert.Equal("Base..ctor(System.Int32 X)", symbolInfo.Symbol.ToTestDisplayString()); + + symbolInfo = CSharpExtensions.GetSpeculativeSymbolInfo(model, baseWithargs.ArgumentList.OpenParenToken.SpanStart, speculativeBaseInitializer); + Assert.Equal("Base..ctor(System.Int32 X)", symbolInfo.Symbol.ToTestDisplayString()); + + Assert.Equal(TypeInfo.None, model.GetSpeculativeTypeInfo(baseWithargs.ArgumentList.OpenParenToken.SpanStart, (SyntaxNode)speculativePrimaryInitializer, SpeculativeBindingOption.BindAsExpression)); + } + } + [Fact(Skip = "record struct")] public void Equality_01() { diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs index a2778d5abe676..ae559e9ecf2e8 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs @@ -22799,76 +22799,123 @@ void Test(object p) "; CreateCompilation(text).VerifyDiagnostics( // (16,14): error CS0307: The variable 'l' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "l<>").WithArguments("l", "variable"), + // Test(l<>); + Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "l<>").WithArguments("l", "variable").WithLocation(16, 14), // (17,14): error CS0307: The variable 'object' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "p<>").WithArguments("object", "variable"), + // Test(p<>); + Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "p<>").WithArguments("object", "variable").WithLocation(17, 14), // (19,14): error CS0307: The field 'Program.f' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "f<>").WithArguments("Program.f", "field"), + // Test(f<>); + Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "f<>").WithArguments("Program.f", "field").WithLocation(19, 14), // (20,14): error CS0307: The property 'Program.P' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "P<>").WithArguments("Program.P", "property"), + // Test(P<>); + Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "P<>").WithArguments("Program.P", "property").WithLocation(20, 14), // (21,14): error CS0308: The non-generic method 'Program.M()' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "M<>").WithArguments("Program.M()", "method"), + // Test(M<>()); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "M<>").WithArguments("Program.M()", "method").WithLocation(21, 14), + // (23,14): error CS8389: Omitting the type argument is not allowed in the current context + // Test(this.f<>); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "this.f<>").WithLocation(23, 14), // (23,19): error CS0307: The field 'Program.f' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "f<>").WithArguments("Program.f", "field"), + // Test(this.f<>); + Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "f<>").WithArguments("Program.f", "field").WithLocation(23, 19), + // (24,14): error CS8389: Omitting the type argument is not allowed in the current context + // Test(this.P<>); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "this.P<>").WithLocation(24, 14), // (24,19): error CS0307: The property 'Program.P' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "P<>").WithArguments("Program.P", "property"), + // Test(this.P<>); + Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "P<>").WithArguments("Program.P", "property").WithLocation(24, 19), + // (25,14): error CS8389: Omitting the type argument is not allowed in the current context + // Test(this.M<>()); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "this.M<>").WithLocation(25, 14), // (25,19): error CS0308: The non-generic method 'Program.M()' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "M<>").WithArguments("Program.M()", "method"), + // Test(this.M<>()); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "M<>").WithArguments("Program.M()", "method").WithLocation(25, 19), // (29,13): error CS0308: The non-generic method 'Program.M()' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "M<>").WithArguments("Program.M()", "method"), + // m = M<>; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "M<>").WithArguments("Program.M()", "method").WithLocation(29, 13), + // (30,13): error CS8389: Omitting the type argument is not allowed in the current context + // m = this.M<>; + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "this.M<>").WithLocation(30, 13), // (30,18): error CS0308: The non-generic method 'Program.M()' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "M<>").WithArguments("Program.M()", "method"), + // m = this.M<>; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "M<>").WithArguments("Program.M()", "method").WithLocation(30, 18), // (32,9): error CS0308: The non-generic type 'Program.I' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type"), + // I<> i1 = null; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type").WithLocation(32, 9), // (33,9): error CS0308: The non-generic type 'Program.C' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type"), + // C<> c1 = new C(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type").WithLocation(33, 9), // (34,20): error CS0308: The non-generic type 'Program.C' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type"), + // C c2 = new C<>(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type").WithLocation(34, 20), // (35,9): error CS0308: The non-generic type 'Program.S' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type"), + // S<> s1 = new S(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type").WithLocation(35, 9), // (36,20): error CS0308: The non-generic type 'Program.S' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type"), + // S s2 = new S<>(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type").WithLocation(36, 20), // (37,9): error CS0308: The non-generic type 'Program.D' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "D<>").WithArguments("Program.D", "type"), + // D<> d1 = null; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "D<>").WithArguments("Program.D", "type").WithLocation(37, 9), // (39,17): error CS0308: The non-generic type 'Program.I' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type"), + // Program.I<> i2 = null; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type").WithLocation(39, 17), // (40,17): error CS0308: The non-generic type 'Program.C' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type"), + // Program.C<> c3 = new Program.C(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type").WithLocation(40, 17), // (41,36): error CS0308: The non-generic type 'Program.C' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type"), + // Program.C c4 = new Program.C<>(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type").WithLocation(41, 36), // (42,17): error CS0308: The non-generic type 'Program.S' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type"), + // Program.S<> s3 = new Program.S(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type").WithLocation(42, 17), // (43,36): error CS0308: The non-generic type 'Program.S' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type"), + // Program.S s4 = new Program.S<>(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type").WithLocation(43, 36), // (44,17): error CS0308: The non-generic type 'Program.D' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "D<>").WithArguments("Program.D", "type"), + // Program.D<> d2 = null; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "D<>").WithArguments("Program.D", "type").WithLocation(44, 17), // (46,22): error CS0308: The non-generic type 'Program.I' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type"), + // Test(default(I<>)); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type").WithLocation(46, 22), // (47,22): error CS0308: The non-generic type 'Program.C' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type"), + // Test(default(C<>)); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type").WithLocation(47, 22), // (48,22): error CS0308: The non-generic type 'Program.S' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type"), + // Test(default(S<>)); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type").WithLocation(48, 22), // (50,30): error CS0308: The non-generic type 'Program.I' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type"), + // Test(default(Program.I<>)); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type").WithLocation(50, 30), // (51,30): error CS0308: The non-generic type 'Program.C' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type"), + // Test(default(Program.C<>)); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type").WithLocation(51, 30), // (52,30): error CS0308: The non-generic type 'Program.S' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type"), + // Test(default(Program.S<>)); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type").WithLocation(52, 30), // (56,20): error CS0308: The non-generic type 'Program.I' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type"), + // s = typeof(I<>).Name; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type").WithLocation(56, 20), // (57,20): error CS0308: The non-generic type 'Program.C' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type"), + // s = typeof(C<>).Name; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type").WithLocation(57, 20), // (58,20): error CS0308: The non-generic type 'Program.S' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type"), + // s = typeof(S<>).Name; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type").WithLocation(58, 20), // (60,28): error CS0308: The non-generic type 'Program.I' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type"), + // s = typeof(Program.I<>).Name; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "I<>").WithArguments("Program.I", "type").WithLocation(60, 28), // (61,28): error CS0308: The non-generic type 'Program.C' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type"), + // s = typeof(Program.C<>).Name; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "C<>").WithArguments("Program.C", "type").WithLocation(61, 28), // (62,28): error CS0308: The non-generic type 'Program.S' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type"), + // s = typeof(Program.S<>).Name; + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "S<>").WithArguments("Program.S", "type").WithLocation(62, 28), // (4,9): warning CS0649: Field 'Program.f' is never assigned to, and will always have its default value 0 - Diagnostic(ErrorCode.WRN_UnassignedInternalField, "f").WithArguments("Program.f", "0") - ); + // int f; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "f").WithArguments("Program.f", "0").WithLocation(4, 9) + ); } [WorkItem(542419, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542419")] @@ -22898,32 +22945,47 @@ void Test(T p) // Parser // (12,11): error CS1525: Invalid expression term '>' - Diagnostic(ErrorCode.ERR_InvalidExprTerm, ">").WithArguments(">"), + // E<> += null; //parse error + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ">").WithArguments(">").WithLocation(12, 11), // (12,13): error CS1525: Invalid expression term '+=' - Diagnostic(ErrorCode.ERR_InvalidExprTerm, "+=").WithArguments("+="), + // E<> += null; //parse error + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "+=").WithArguments("+=").WithLocation(12, 13), // (13,11): error CS1525: Invalid expression term '>' - Diagnostic(ErrorCode.ERR_InvalidExprTerm, ">").WithArguments(">"), + // F<> += null; //parse error + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ">").WithArguments(">").WithLocation(13, 11), // (13,13): error CS1525: Invalid expression term '+=' - Diagnostic(ErrorCode.ERR_InvalidExprTerm, "+=").WithArguments("+="), + // F<> += null; //parse error + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "+=").WithArguments("+=").WithLocation(13, 13), // (15,16): error CS1525: Invalid expression term '>' - Diagnostic(ErrorCode.ERR_InvalidExprTerm, ">").WithArguments(">"), + // this.E<> += null; //parse error + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ">").WithArguments(">").WithLocation(15, 16), // (15,18): error CS1525: Invalid expression term '+=' - Diagnostic(ErrorCode.ERR_InvalidExprTerm, "+=").WithArguments("+="), + // this.E<> += null; //parse error + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "+=").WithArguments("+=").WithLocation(15, 18), // (16,16): error CS1525: Invalid expression term '>' - Diagnostic(ErrorCode.ERR_InvalidExprTerm, ">").WithArguments(">"), + // this.F<> += null; //parse error + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ">").WithArguments(">").WithLocation(16, 16), + // (16,18): error CS1525: Invalid expression term '+=' + // this.F<> += null; //parse error + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "+=").WithArguments("+=").WithLocation(16, 18), // Binder - // (16,18): error CS1525: Invalid expression term '+=' - Diagnostic(ErrorCode.ERR_InvalidExprTerm, "+=").WithArguments("+="), // (9,14): error CS0307: The event 'Program.E' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "E<>").WithArguments("Program.E", "event"), + // Test(E<>); + Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "E<>").WithArguments("Program.E", "event").WithLocation(9, 14), + // (10,14): error CS8389: Omitting the type argument is not allowed in the current context + // Test(this.E<>); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "this.E<>").WithLocation(10, 14), // (10,19): error CS0307: The event 'Program.E' cannot be used with type arguments - Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "E<>").WithArguments("Program.E", "event"), + // Test(this.E<>); + Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "E<>").WithArguments("Program.E", "event").WithLocation(10, 19), // (13,9): error CS0079: The event 'Program.F' can only appear on the left hand side of += or -= - Diagnostic(ErrorCode.ERR_BadEventUsageNoField, "F").WithArguments("Program.F"), + // F<> += null; //parse error + Diagnostic(ErrorCode.ERR_BadEventUsageNoField, "F").WithArguments("Program.F").WithLocation(13, 9), // (16,14): error CS0079: The event 'Program.F' can only appear on the left hand side of += or -= - Diagnostic(ErrorCode.ERR_BadEventUsageNoField, "F").WithArguments("Program.F")); + // this.F<> += null; //parse error + Diagnostic(ErrorCode.ERR_BadEventUsageNoField, "F").WithArguments("Program.F").WithLocation(16, 14)); } [WorkItem(542419, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542419")] diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs index e7080f3e3a947..f66303e94ff84 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs @@ -2145,7 +2145,7 @@ void M(int x) SemanticModel speculativeModel; Assert.Throws(() => model.TryGetSpeculativeSemanticModel(statement.SpanStart, statement: null, speculativeModel: out speculativeModel)); - Assert.Throws(() => model.TryGetSpeculativeSemanticModel(statement.SpanStart, constructorInitializer: null, speculativeModel: out speculativeModel)); + Assert.Throws(() => model.TryGetSpeculativeSemanticModel(statement.SpanStart, constructorInitializer: (ConstructorInitializerSyntax)null, speculativeModel: out speculativeModel)); Assert.Throws(() => model.TryGetSpeculativeSemanticModel(statement.SpanStart, attribute: null, speculativeModel: out speculativeModel)); // Speculate on a node from the same syntax tree. diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/GenericConstraintTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/GenericConstraintTests.cs index 5bb735d504ec4..4cc6dd6043220 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/GenericConstraintTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/GenericConstraintTests.cs @@ -6870,5 +6870,259 @@ static void Main(string[] args) Diagnostic(ErrorCode.ERR_BadTypeArgument, "R2").WithArguments("int*").WithLocation(6, 7) ); } + + [Fact] + [WorkItem(41779, "https://github.com/dotnet/roslyn/issues/41779")] + public void Bug41779_Original() + { + var source = +@"interface I +{ + object GetService(); +} + +static class Program +{ + static T GetService(this I obj) => default; + + static void M(I provider) + { + provider.GetService<>(); + provider.GetService<>().ToString(); + provider.GetService<>(); + } +}"; + CreateCompilation(source).VerifyDiagnostics( + // (12,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetService<>").WithLocation(12, 9), + // (13,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetService<>().ToString(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetService<>").WithLocation(13, 9), + // (14,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetService<>").WithLocation(14, 9) + ); + } + + [Fact] + [WorkItem(41779, "https://github.com/dotnet/roslyn/issues/41779")] + public void Bug41779_DoubleTypeArg() + { + var source = +@"interface I +{ + object GetService(); +} + +static class Program +{ + static T1 GetService(this I obj) => default; + + static void M(I provider) + { + provider.GetService<>(); + provider.GetService<>().ToString(); + provider.GetService<>(); + } +}"; + CreateCompilation(source).VerifyDiagnostics( + // (12,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetService<>").WithLocation(12, 9), + // (12,18): error CS0308: The non-generic method 'I.GetService()' cannot be used with type arguments + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "GetService<>").WithArguments("I.GetService()", "method").WithLocation(12, 18), + // (13,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetService<>().ToString(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetService<>").WithLocation(13, 9), + // (13,18): error CS0308: The non-generic method 'I.GetService()' cannot be used with type arguments + // provider.GetService<>().ToString(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "GetService<>").WithArguments("I.GetService()", "method").WithLocation(13, 18), + // (14,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetService<>").WithLocation(14, 9), + // (14,18): error CS0308: The non-generic method 'I.GetService()' cannot be used with type arguments + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "GetService<>").WithArguments("I.GetService()", "method").WithLocation(14, 18) + ); + } + + [Fact] + [WorkItem(41779, "https://github.com/dotnet/roslyn/issues/41779")] + public void Bug41779_Instance() + { + var source = +@"interface I +{ + object GetService(); +} + +interface J +{ + object GetService(); +} + +interface K +{ + object GetService(); +} + +static class Program +{ + static void M(I provider) + { + provider.GetService<>(); + provider.GetService<>().ToString(); + } + + static void M(J provider) + { + provider.GetService<>(); + provider.GetService<>().ToString(); + } + + static void M(K provider) + { + provider.GetService<>(); + provider.GetService<>().ToString(); + } +}"; + CreateCompilation(source).VerifyDiagnostics( + // (20,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetService<>").WithLocation(20, 9), + // (20,18): error CS0308: The non-generic method 'I.GetService()' cannot be used with type arguments + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "GetService<>").WithArguments("I.GetService()", "method").WithLocation(20, 18), + // (21,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetService<>().ToString(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetService<>").WithLocation(21, 9), + // (21,18): error CS0308: The non-generic method 'I.GetService()' cannot be used with type arguments + // provider.GetService<>().ToString(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "GetService<>").WithArguments("I.GetService()", "method").WithLocation(21, 18), + // (26,9): error CS0305: Using the generic method group 'GetService' requires 1 type arguments + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_BadArity, "provider.GetService<>").WithArguments("GetService", "method group", "1").WithLocation(26, 9), + // (27,9): error CS0305: Using the generic method group 'GetService' requires 1 type arguments + // provider.GetService<>().ToString(); + Diagnostic(ErrorCode.ERR_BadArity, "provider.GetService<>").WithArguments("GetService", "method group", "1").WithLocation(27, 9), + // (32,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetService<>").WithLocation(32, 9), + // (32,18): error CS0305: Using the generic method 'K.GetService()' requires 2 type arguments + // provider.GetService<>(); + Diagnostic(ErrorCode.ERR_BadArity, "GetService<>").WithArguments("K.GetService()", "method", "2").WithLocation(32, 18), + // (33,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetService<>().ToString(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetService<>").WithLocation(33, 9), + // (33,18): error CS0305: Using the generic method 'K.GetService()' requires 2 type arguments + // provider.GetService<>().ToString(); + Diagnostic(ErrorCode.ERR_BadArity, "GetService<>").WithArguments("K.GetService()", "method", "2").WithLocation(33, 18) + ); + } + + + [Fact] + [WorkItem(41779, "https://github.com/dotnet/roslyn/issues/41779")] + public void Bug41779_Extension() + { + var source = +@"interface I{} + +static class Program +{ + static void GetServiceA(this I obj){} + static T GetServiceB(this I obj) => default; + static T1 GetServiceC(this I obj) => default; + + static void M(I provider) + { + provider.GetServiceA<>(); + provider.GetServiceA<>().ToString(); + + provider.GetServiceB<>(); + provider.GetServiceB<>().ToString(); + + provider.GetServiceC<>(); + provider.GetServiceC<>().ToString(); + } +}"; + CreateCompilation(source).VerifyDiagnostics( + // (11,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetServiceA<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetServiceA<>").WithLocation(11, 9), + // (11,18): error CS1061: 'I' does not contain a definition for 'GetServiceA' and no accessible extension method 'GetServiceA' accepting a first argument of type 'I' could be found (are you missing a using directive or an assembly reference?) + // provider.GetServiceA<>(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "GetServiceA<>").WithArguments("I", "GetServiceA").WithLocation(11, 18), + // (12,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetServiceA<>().ToString(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetServiceA<>").WithLocation(12, 9), + // (12,18): error CS1061: 'I' does not contain a definition for 'GetServiceA' and no accessible extension method 'GetServiceA' accepting a first argument of type 'I' could be found (are you missing a using directive or an assembly reference?) + // provider.GetServiceA<>().ToString(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "GetServiceA<>").WithArguments("I", "GetServiceA").WithLocation(12, 18), + // (14,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetServiceB<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetServiceB<>").WithLocation(14, 9), + // (15,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetServiceB<>().ToString(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetServiceB<>").WithLocation(15, 9), + // (17,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetServiceC<>(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetServiceC<>").WithLocation(17, 9), + // (17,18): error CS1061: 'I' does not contain a definition for 'GetServiceC' and no accessible extension method 'GetServiceC' accepting a first argument of type 'I' could be found (are you missing a using directive or an assembly reference?) + // provider.GetServiceC<>(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "GetServiceC<>").WithArguments("I", "GetServiceC").WithLocation(17, 18), + // (18,9): error CS8389: Omitting the type argument is not allowed in the current context + // provider.GetServiceC<>().ToString(); + Diagnostic(ErrorCode.ERR_OmittedTypeArgument, "provider.GetServiceC<>").WithLocation(18, 9), + // (18,18): error CS1061: 'I' does not contain a definition for 'GetServiceC' and no accessible extension method 'GetServiceC' accepting a first argument of type 'I' could be found (are you missing a using directive or an assembly reference?) + // provider.GetServiceC<>().ToString(); + Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "GetServiceC<>").WithArguments("I", "GetServiceC").WithLocation(18, 18) + ); + } + + [Fact] + [WorkItem(41779, "https://github.com/dotnet/roslyn/issues/41779")] + public void Bug41779_Static() + { + var source = +@"static class Program +{ + static object GetServiceA(){ return null; } + static T GetServiceB() => default; + static T1 GetServiceC() => default; + + static void M() + { + GetServiceA<>(); + GetServiceA<>().ToString(); + GetServiceB<>(); + GetServiceB<>().ToString(); + GetServiceC<>(); + GetServiceC<>().ToString(); + } +}"; + CreateCompilation(source).VerifyDiagnostics( + // (9,9): error CS0308: The non-generic method 'Program.GetServiceA()' cannot be used with type arguments + // GetServiceA<>(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "GetServiceA<>").WithArguments("Program.GetServiceA()", "method").WithLocation(9, 9), + // (10,9): error CS0308: The non-generic method 'Program.GetServiceA()' cannot be used with type arguments + // GetServiceA<>().ToString(); + Diagnostic(ErrorCode.ERR_HasNoTypeVars, "GetServiceA<>").WithArguments("Program.GetServiceA()", "method").WithLocation(10, 9), + // (11,9): error CS0305: Using the generic method group 'GetServiceB' requires 1 type arguments + // GetServiceB<>(); + Diagnostic(ErrorCode.ERR_BadArity, "GetServiceB<>").WithArguments("GetServiceB", "method group", "1").WithLocation(11, 9), + // (12,9): error CS0305: Using the generic method group 'GetServiceB' requires 1 type arguments + // GetServiceB<>().ToString(); + Diagnostic(ErrorCode.ERR_BadArity, "GetServiceB<>").WithArguments("GetServiceB", "method group", "1").WithLocation(12, 9), + // (13,9): error CS0305: Using the generic method 'Program.GetServiceC()' requires 2 type arguments + // GetServiceC<>(); + Diagnostic(ErrorCode.ERR_BadArity, "GetServiceC<>").WithArguments("Program.GetServiceC()", "method", "2").WithLocation(13, 9), + // (14,9): error CS0305: Using the generic method 'Program.GetServiceC()' requires 2 type arguments + // GetServiceC<>().ToString(); + Diagnostic(ErrorCode.ERR_BadArity, "GetServiceC<>").WithArguments("Program.GetServiceC()", "method", "2").WithLocation(14, 9) + ); + } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs index 68752b7c4a6ab..1fe6a5b00fce9 100644 --- a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs +++ b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs @@ -485,7 +485,10 @@ private static Syntax.InternalSyntax.BaseListSyntax GenerateBaseList() => InternalSyntaxFactory.BaseList(InternalSyntaxFactory.Token(SyntaxKind.ColonToken), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList()); private static Syntax.InternalSyntax.SimpleBaseTypeSyntax GenerateSimpleBaseType() - => InternalSyntaxFactory.SimpleBaseType(GenerateIdentifierName(), null); + => InternalSyntaxFactory.SimpleBaseType(GenerateIdentifierName()); + + private static Syntax.InternalSyntax.PrimaryConstructorBaseTypeSyntax GeneratePrimaryConstructorBaseType() + => InternalSyntaxFactory.PrimaryConstructorBaseType(GenerateIdentifierName(), GenerateArgumentList()); private static Syntax.InternalSyntax.TypeParameterConstraintClauseSyntax GenerateTypeParameterConstraintClause() => InternalSyntaxFactory.TypeParameterConstraintClause(InternalSyntaxFactory.Token(SyntaxKind.WhereKeyword), GenerateIdentifierName(), InternalSyntaxFactory.Token(SyntaxKind.ColonToken), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList()); @@ -2690,7 +2693,17 @@ public void TestSimpleBaseTypeFactoryAndProperties() var node = GenerateSimpleBaseType(); Assert.NotNull(node.Type); - Assert.Null(node.ArgumentList); + + AttachAndCheckDiagnostics(node); + } + + [Fact] + public void TestPrimaryConstructorBaseTypeFactoryAndProperties() + { + var node = GeneratePrimaryConstructorBaseType(); + + Assert.NotNull(node.Type); + Assert.NotNull(node.ArgumentList); AttachAndCheckDiagnostics(node); } @@ -7700,6 +7713,32 @@ public void TestSimpleBaseTypeIdentityRewriter() Assert.Same(oldNode, newNode); } + [Fact] + public void TestPrimaryConstructorBaseTypeTokenDeleteRewriter() + { + var oldNode = GeneratePrimaryConstructorBaseType(); + var rewriter = new TokenDeleteRewriter(); + var newNode = rewriter.Visit(oldNode); + + if(!oldNode.IsMissing) + { + Assert.NotEqual(oldNode, newNode); + } + + Assert.NotNull(newNode); + Assert.True(newNode.IsMissing, "No tokens => missing"); + } + + [Fact] + public void TestPrimaryConstructorBaseTypeIdentityRewriter() + { + var oldNode = GeneratePrimaryConstructorBaseType(); + var rewriter = new IdentityRewriter(); + var newNode = rewriter.Visit(oldNode); + + Assert.Same(oldNode, newNode); + } + [Fact] public void TestTypeParameterConstraintClauseTokenDeleteRewriter() { @@ -9870,7 +9909,10 @@ private static BaseListSyntax GenerateBaseList() => SyntaxFactory.BaseList(SyntaxFactory.Token(SyntaxKind.ColonToken), new SeparatedSyntaxList()); private static SimpleBaseTypeSyntax GenerateSimpleBaseType() - => SyntaxFactory.SimpleBaseType(GenerateIdentifierName(), default(ArgumentListSyntax)); + => SyntaxFactory.SimpleBaseType(GenerateIdentifierName()); + + private static PrimaryConstructorBaseTypeSyntax GeneratePrimaryConstructorBaseType() + => SyntaxFactory.PrimaryConstructorBaseType(GenerateIdentifierName(), GenerateArgumentList()); private static TypeParameterConstraintClauseSyntax GenerateTypeParameterConstraintClause() => SyntaxFactory.TypeParameterConstraintClause(SyntaxFactory.Token(SyntaxKind.WhereKeyword), GenerateIdentifierName(), SyntaxFactory.Token(SyntaxKind.ColonToken), new SeparatedSyntaxList()); @@ -12075,7 +12117,17 @@ public void TestSimpleBaseTypeFactoryAndProperties() var node = GenerateSimpleBaseType(); Assert.NotNull(node.Type); - Assert.Null(node.ArgumentList); + var newNode = node.WithType(node.Type); + Assert.Equal(node, newNode); + } + + [Fact] + public void TestPrimaryConstructorBaseTypeFactoryAndProperties() + { + var node = GeneratePrimaryConstructorBaseType(); + + Assert.NotNull(node.Type); + Assert.NotNull(node.ArgumentList); var newNode = node.WithType(node.Type).WithArgumentList(node.ArgumentList); Assert.Equal(node, newNode); } @@ -17085,6 +17137,32 @@ public void TestSimpleBaseTypeIdentityRewriter() Assert.Same(oldNode, newNode); } + [Fact] + public void TestPrimaryConstructorBaseTypeTokenDeleteRewriter() + { + var oldNode = GeneratePrimaryConstructorBaseType(); + var rewriter = new TokenDeleteRewriter(); + var newNode = rewriter.Visit(oldNode); + + if(!oldNode.IsMissing) + { + Assert.NotEqual(oldNode, newNode); + } + + Assert.NotNull(newNode); + Assert.True(newNode.IsMissing, "No tokens => missing"); + } + + [Fact] + public void TestPrimaryConstructorBaseTypeIdentityRewriter() + { + var oldNode = GeneratePrimaryConstructorBaseType(); + var rewriter = new IdentityRewriter(); + var newNode = rewriter.Visit(oldNode); + + Assert.Same(oldNode, newNode); + } + [Fact] public void TestTypeParameterConstraintClauseTokenDeleteRewriter() { diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/RecordParsing.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/RecordParsing.cs index e18ae00885564..60c4e35205323 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/RecordParsing.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/RecordParsing.cs @@ -1499,7 +1499,7 @@ public void Base_01( N(SyntaxKind.BaseList); { N(SyntaxKind.ColonToken); - N(SyntaxKind.SimpleBaseType); + N(withBaseArguments ? SyntaxKind.PrimaryConstructorBaseType : SyntaxKind.SimpleBaseType); { N(SyntaxKind.IdentifierName); { @@ -1797,7 +1797,7 @@ public void Base_05() N(SyntaxKind.BaseList); { N(SyntaxKind.ColonToken); - N(SyntaxKind.SimpleBaseType); + N(SyntaxKind.PrimaryConstructorBaseType); { N(SyntaxKind.IdentifierName); { diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs b/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs index 0162b5c8e6453..904a59041f540 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs @@ -285,11 +285,12 @@ private ObsoleteAttributeData DecodeObsoleteAttribute() // ObsoleteAttribute(string, bool) Debug.Assert(args.Length <= 2); - message = (string)args[0].ValueInternal; + message = (string?)args[0].ValueInternal; if (args.Length == 2) { - isError = (bool)args[1].ValueInternal; + Debug.Assert(args[1].ValueInternal is object); + isError = (bool)args[1].ValueInternal!; } } @@ -341,8 +342,9 @@ private ObsoleteAttributeData DecodeDeprecatedAttribute() // DeprecatedAttribute(String, DeprecationType, UInt32, Platform) // DeprecatedAttribute(String, DeprecationType, UInt32, String) - message = (string)args[0].ValueInternal; - isError = ((int)args[1].ValueInternal == 1); + Debug.Assert(args[1].ValueInternal is object); + message = (string?)args[0].ValueInternal; + isError = ((int)args[1].ValueInternal! == 1); } return new ObsoleteAttributeData(ObsoleteAttributeKind.Deprecated, message, isError, diagnosticId: null, urlFormat: null); @@ -537,6 +539,7 @@ internal static AttributeUsageInfo DecodeAttributeUsageAttribute(TypedConstant p // // See Roslyn Bug 8603: ETA crashes with InvalidOperationException on duplicate attributes for details. + Debug.Assert(positionalArg.ValueInternal is object); var validOn = (AttributeTargets)positionalArg.ValueInternal; bool allowMultiple = DecodeNamedArgument(namedArgs, "AllowMultiple", SpecialType.System_Boolean, false); bool inherited = DecodeNamedArgument(namedArgs, "Inherited", SpecialType.System_Boolean, true); diff --git a/src/Compilers/Core/Portable/Symbols/TypedConstant.cs b/src/Compilers/Core/Portable/Symbols/TypedConstant.cs index 8ae68df2c2132..0321183883401 100644 --- a/src/Compilers/Core/Portable/Symbols/TypedConstant.cs +++ b/src/Compilers/Core/Portable/Symbols/TypedConstant.cs @@ -19,13 +19,15 @@ namespace Microsoft.CodeAnalysis public struct TypedConstant : IEquatable { private readonly TypedConstantKind _kind; - private readonly ITypeSymbolInternal _type; + private readonly ITypeSymbolInternal? _type; private readonly object? _value; - internal TypedConstant(ITypeSymbolInternal type, TypedConstantKind kind, object? value) + internal TypedConstant(ITypeSymbolInternal? type, TypedConstantKind kind, object? value) { Debug.Assert(kind == TypedConstantKind.Array || !(value is ImmutableArray)); Debug.Assert(!(value is ISymbol) || value is ISymbolInternal); + Debug.Assert(type is object || kind == TypedConstantKind.Error); + _kind = kind; _type = type; _value = value; @@ -48,12 +50,12 @@ public TypedConstantKind Kind /// Returns the of the constant, /// or null if the type can't be determined (error). /// - public ITypeSymbol Type + public ITypeSymbol? Type { - get { return _type.GetITypeSymbol(); } + get { return _type?.GetITypeSymbol(); } } - internal ITypeSymbolInternal TypeInternal + internal ITypeSymbolInternal? TypeInternal { get { return _type; } } @@ -90,7 +92,7 @@ public object? Value /// /// Unlike returns when the value is a symbol. /// - internal object ValueInternal + internal object? ValueInternal { get { @@ -99,7 +101,7 @@ internal object ValueInternal throw new InvalidOperationException("TypedConstant is an array. Use Values property."); } - return _value!; + return _value; } } @@ -131,7 +133,7 @@ internal T DecodeValue(SpecialType specialType) return value; } - internal bool TryDecodeValue(SpecialType specialType, [MaybeNull][NotNullWhen(returnValue: true)] out T value) + internal bool TryDecodeValue(SpecialType specialType, [MaybeNull] out T value) { if (_kind == TypedConstantKind.Error) { @@ -139,9 +141,9 @@ internal bool TryDecodeValue(SpecialType specialType, [MaybeNull][NotNullWhen return false; } - if (_type.SpecialType == specialType || (_type.TypeKind == TypeKind.Enum && specialType == SpecialType.System_Enum)) + if (_type!.SpecialType == specialType || (_type.TypeKind == TypeKind.Enum && specialType == SpecialType.System_Enum)) { - value = (T)_value!; + value = (T)_value; return true; } diff --git a/src/Compilers/Core/Portable/Syntax/LineDirectiveMap.LineMappingEntry.cs b/src/Compilers/Core/Portable/Syntax/LineDirectiveMap.LineMappingEntry.cs index 8749e03951cad..8319c13504b80 100644 --- a/src/Compilers/Core/Portable/Syntax/LineDirectiveMap.LineMappingEntry.cs +++ b/src/Compilers/Core/Portable/Syntax/LineDirectiveMap.LineMappingEntry.cs @@ -76,7 +76,7 @@ public LineMappingEntry(int unmappedLine) public LineMappingEntry( int unmappedLine, int mappedLine, - string mappedPathOpt, + string? mappedPathOpt, PositionState state) { this.UnmappedLine = unmappedLine; diff --git a/src/Compilers/Core/Portable/Syntax/SyntaxNavigator.cs b/src/Compilers/Core/Portable/Syntax/SyntaxNavigator.cs index ecaf05bd916cc..bb7a289007864 100644 --- a/src/Compilers/Core/Portable/Syntax/SyntaxNavigator.cs +++ b/src/Compilers/Core/Portable/Syntax/SyntaxNavigator.cs @@ -128,7 +128,7 @@ internal SyntaxToken GetFirstToken(SyntaxNode current, Func? } } - return default(SyntaxToken); + return default; } finally { @@ -175,7 +175,7 @@ internal SyntaxToken GetLastToken(SyntaxNode current, Func pr } } - return default(SyntaxToken); + return default; } finally { @@ -202,7 +202,7 @@ private SyntaxToken GetFirstToken( } } - return default(SyntaxToken); + return default; } private SyntaxToken GetLastToken( @@ -221,7 +221,7 @@ private SyntaxToken GetLastToken( } } - return default(SyntaxToken); + return default; } private bool TryGetLastTokenForStructuredTrivia( @@ -230,7 +230,7 @@ private bool TryGetLastTokenForStructuredTrivia( Func? stepInto, out SyntaxToken token) { - token = default(SyntaxToken); + token = default; if (!trivia.TryGetStructure(out var structure) || stepInto == null || !stepInto(trivia)) { @@ -273,7 +273,7 @@ private SyntaxToken GetFirstToken( } } - return default(SyntaxToken); + return default; } private SyntaxToken GetLastToken( @@ -307,12 +307,12 @@ private SyntaxToken GetLastToken( } } - return default(SyntaxToken); + return default; } internal SyntaxToken GetNextToken( SyntaxTrivia current, - Func predicate, + Func? predicate, Func? stepInto) { bool returnNext = false; @@ -377,7 +377,7 @@ internal SyntaxToken GetPreviousToken( private SyntaxToken GetNextToken( SyntaxTrivia current, SyntaxTriviaList list, - Func predicate, + Func? predicate, Func? stepInto, ref bool returnNext) { @@ -400,7 +400,7 @@ private SyntaxToken GetNextToken( } } - return default(SyntaxToken); + return default; } private SyntaxToken GetPreviousToken( @@ -426,12 +426,12 @@ private SyntaxToken GetPreviousToken( } } - return default(SyntaxToken); + return default; } internal SyntaxToken GetNextToken( SyntaxNode node, - Func predicate, + Func? predicate, Func? stepInto) { while (node.Parent != null) @@ -476,7 +476,7 @@ internal SyntaxToken GetNextToken( return GetNextToken(((IStructuredTriviaSyntax)node).ParentTrivia, predicate, stepInto); } - return default(SyntaxToken); + return default; } internal SyntaxToken GetPreviousToken( @@ -526,10 +526,10 @@ internal SyntaxToken GetPreviousToken( return GetPreviousToken(((IStructuredTriviaSyntax)node).ParentTrivia, predicate, stepInto); } - return default(SyntaxToken); + return default; } - internal SyntaxToken GetNextToken(in SyntaxToken current, Func predicate, bool searchInsideCurrentTokenTrailingTrivia, Func? stepInto) + internal SyntaxToken GetNextToken(in SyntaxToken current, Func? predicate, bool searchInsideCurrentTokenTrailingTrivia, Func? stepInto) { Debug.Assert(searchInsideCurrentTokenTrailingTrivia == false || stepInto != null); if (current.Parent != null) @@ -579,7 +579,7 @@ internal SyntaxToken GetNextToken(in SyntaxToken current, Func predicate, bool searchInsideCurrentTokenLeadingTrivia, @@ -633,7 +633,7 @@ internal SyntaxToken GetPreviousToken(in SyntaxToken current, Func( /// /// Creates a new tree of nodes with the specified node removed. /// - protected internal abstract SyntaxNode RemoveNodesCore( + protected internal abstract SyntaxNode? RemoveNodesCore( IEnumerable nodes, SyntaxRemoveOptions options); diff --git a/src/Compilers/Core/Portable/Syntax/SyntaxNodeExtensions.cs b/src/Compilers/Core/Portable/Syntax/SyntaxNodeExtensions.cs index b2d21d0c03cca..79ad33a0c1fbd 100644 --- a/src/Compilers/Core/Portable/Syntax/SyntaxNodeExtensions.cs +++ b/src/Compilers/Core/Portable/Syntax/SyntaxNodeExtensions.cs @@ -261,12 +261,12 @@ public static TRoot ReplaceTrivia(this TRoot root, SyntaxTrivia trivia, S /// The root node from which to remove a descendant node from. /// The node to remove. /// Options that determine how the node's trivia is treated. - public static TRoot RemoveNode(this TRoot root, + public static TRoot? RemoveNode(this TRoot root, SyntaxNode node, SyntaxRemoveOptions options) where TRoot : SyntaxNode { - return (TRoot)root.RemoveNodesCore(new[] { node }, options); + return (TRoot?)root.RemoveNodesCore(new[] { node }, options); } /// @@ -276,13 +276,13 @@ public static TRoot RemoveNode(this TRoot root, /// The root node from which to remove a descendant node from. /// The nodes to remove. /// Options that determine how the nodes' trivia is treated. - public static TRoot RemoveNodes( + public static TRoot? RemoveNodes( this TRoot root, IEnumerable nodes, SyntaxRemoveOptions options) where TRoot : SyntaxNode { - return (TRoot)root.RemoveNodesCore(nodes, options); + return (TRoot?)root.RemoveNodesCore(nodes, options); } internal const string DefaultIndentation = " "; diff --git a/src/Compilers/Core/Portable/Syntax/SyntaxTree.cs b/src/Compilers/Core/Portable/Syntax/SyntaxTree.cs index 2ff1b5674864e..587df78df25dd 100644 --- a/src/Compilers/Core/Portable/Syntax/SyntaxTree.cs +++ b/src/Compilers/Core/Portable/Syntax/SyntaxTree.cs @@ -102,7 +102,7 @@ public virtual ImmutableDictionary DiagnosticOptions /// /// The text encoding of the source document. /// - public abstract Encoding Encoding { get; } + public abstract Encoding? Encoding { get; } /// /// Gets the text of the source document asynchronously. diff --git a/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingErrorTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingErrorTests.vb index 8626ed1c10094..204f234758be6 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingErrorTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingErrorTests.vb @@ -1166,6 +1166,12 @@ Imports System ). VerifyDiagnostics(Diagnostic(ERRID.ERR_BadAttributeConstructor1, "myattr1").WithArguments("M1.c1()"), Diagnostic(ERRID.ERR_BadAttributeConstructor1, "myattr2").WithArguments("M1.delegate1()")) + + Dim scen18 = compilation.GlobalNamespace.GetTypeMember("M1").GetTypeMember("Scen18") + Dim attribute = scen18.GetAttributes().Single() + Assert.Equal("M1.myattr1(Nothing)", attribute.ToString()) + Dim argument = attribute.CommonConstructorArguments(0) + Assert.Null(argument.Type) End Sub diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/UnboundGenericType.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/UnboundGenericType.vb index 7e1667093c2db..871a53255c9d3 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/UnboundGenericType.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/UnboundGenericType.vb @@ -289,6 +289,331 @@ End Class Assert.True(DirectCast(c3c6s, INamedTypeSymbol).IsSerializable) End Sub + + + Public Sub UnboundGenericType_Bug41779_Original() + + Dim compilation = CompilationUtils.CreateCompilation( + + + Private Function GetService(Of T)(ByVal obj As I) As T + Return "default" + End Function + + Private Sub M(ByVal provider As I) + provider.GetService(Of)() + provider.GetService(Of)().ToString() + provider.GetService(Of)() + End Sub +End Module + ]]> +) + + compilation.AssertTheseDiagnostics( +BC30311: Value of type 'String' cannot be converted to 'T'. + Return "default" + ~~~~~~~~~ +BC30182: Type expected. + provider.GetService(Of)() + ~ +BC30182: Type expected. + provider.GetService(Of)().ToString() + ~ +BC30182: Type expected. + provider.GetService(Of)() + ~ + ) + + End Sub + + + + Public Sub UnboundGenericType_Bug41779_DoubleArgs() + + Dim compilation = CompilationUtils.CreateCompilation( + + + Private Function GetService(Of T1, T2)(ByVal obj As I) As T1 + Return "default" + End Function + + Private Sub M(ByVal provider As I) + provider.GetService(Of)() + provider.GetService(Of)().ToString() + provider.GetService(Of)() + End Sub +End Module + ]]> +) + + compilation.AssertTheseDiagnostics( +BC30311: Value of type 'String' cannot be converted to 'T1'. + Return "default" + ~~~~~~~~~ +BC32087: Overload resolution failed because no accessible 'GetService' accepts this number of type arguments. + provider.GetService(Of)() + ~~~~~~~~~~~~~~ +BC30182: Type expected. + provider.GetService(Of)() + ~ +BC32087: Overload resolution failed because no accessible 'GetService' accepts this number of type arguments. + provider.GetService(Of)().ToString() + ~~~~~~~~~~~~~~ +BC30182: Type expected. + provider.GetService(Of)().ToString() + ~ +BC32087: Overload resolution failed because no accessible 'GetService' accepts this number of type arguments. + provider.GetService(Of)() + ~~~~~~~~~~~~~~ +BC30182: Type expected. + provider.GetService(Of)() + ~ + ) + + End Sub + + + + Public Sub UnboundGenericType_Bug41779_Instance() + + Dim compilation = CompilationUtils.CreateCompilation( + + +) + + compilation.AssertTheseDiagnostics( +BC32045: 'Function GetService() As Object' has no type parameters and so cannot have type arguments. + provider.GetService(Of)() + ~~~~ +BC30182: Type expected. + provider.GetService(Of)() + ~ +BC32045: 'Function GetService() As Object' has no type parameters and so cannot have type arguments. + provider.GetService(Of)().ToString() + ~~~~ +BC30182: Type expected. + provider.GetService(Of)().ToString() + ~ +BC30182: Type expected. + provider.GetService(Of)() + ~ +BC30182: Type expected. + provider.GetService(Of)().ToString() + ~ +BC32042: Too few type arguments to 'Function GetService(Of T1, T2)() As Object'. + provider.GetService(Of)() + ~~~~ +BC30182: Type expected. + provider.GetService(Of)() + ~ +BC32042: Too few type arguments to 'Function GetService(Of T1, T2)() As Object'. + provider.GetService(Of)().ToString() + ~~~~ +BC30182: Type expected. + provider.GetService(Of)().ToString() + ~ + ) + + End Sub + + + + Public Sub UnboundGenericType_Bug41779_Extension() + + Dim compilation = CompilationUtils.CreateCompilation( + + + Private Sub GetServiceA(ByVal obj As I) + End Sub + + + Private Function GetServiceB(Of T)(ByVal obj As I) As T + Return "default" + End Function + + + Private Function GetServiceC(Of T1, T2)(ByVal obj As I) As T1 + Return "default" + End Function + + Private Sub M(ByVal provider As I) + provider.GetServiceA(Of)() + provider.GetServiceA(Of)().ToString() + provider.GetServiceB(Of)() + provider.GetServiceB(Of)().ToString() + provider.GetServiceC(Of)() + provider.GetServiceC(Of)().ToString() + End Sub +End Module + ]]> +) + + compilation.AssertTheseDiagnostics( +BC30311: Value of type 'String' cannot be converted to 'T'. + Return "default" + ~~~~~~~~~ +BC30311: Value of type 'String' cannot be converted to 'T1'. + Return "default" + ~~~~~~~~~ +BC36907: Extension method 'Private Sub GetServiceA()' defined in 'Program' is not generic (or has no free type parameters) and so cannot have type arguments. + provider.GetServiceA(Of)() + ~~~~ +BC30182: Type expected. + provider.GetServiceA(Of)() + ~ +BC36907: Extension method 'Private Sub GetServiceA()' defined in 'Program' is not generic (or has no free type parameters) and so cannot have type arguments. + provider.GetServiceA(Of)().ToString() + ~~~~ +BC30182: Type expected. + provider.GetServiceA(Of)().ToString() + ~ +BC30182: Type expected. + provider.GetServiceB(Of)() + ~ +BC30182: Type expected. + provider.GetServiceB(Of)().ToString() + ~ +BC36590: Too few type arguments to extension method 'Private Function GetServiceC(Of T1, T2)() As T1' defined in 'Program'. + provider.GetServiceC(Of)() + ~~~~ +BC30182: Type expected. + provider.GetServiceC(Of)() + ~ +BC36590: Too few type arguments to extension method 'Private Function GetServiceC(Of T1, T2)() As T1' defined in 'Program'. + provider.GetServiceC(Of)().ToString() + ~~~~ +BC30182: Type expected. + provider.GetServiceC(Of)().ToString() + ~ + ) + + End Sub + + + + Public Sub UnboundGenericType_Bug41779_Function() + + Dim compilation = CompilationUtils.CreateCompilation( + + +) + + compilation.AssertTheseDiagnostics( +BC30311: Value of type 'String' cannot be converted to 'T'. + Return "default" + ~~~~~~~~~ +BC30311: Value of type 'String' cannot be converted to 'T1'. + Return "default" + ~~~~~~~~~ +BC32045: 'Private Function GetServiceA() As Object' has no type parameters and so cannot have type arguments. + GetServiceA(Of)() + ~~~~ +BC30182: Type expected. + GetServiceA(Of)() + ~ +BC32045: 'Private Function GetServiceA() As Object' has no type parameters and so cannot have type arguments. + GetServiceA(Of)().ToString() + ~~~~ +BC30182: Type expected. + GetServiceA(Of)().ToString() + ~ +BC30182: Type expected. + GetServiceB(Of)() + ~ +BC30182: Type expected. + GetServiceB(Of)().ToString() + ~ +BC32042: Too few type arguments to 'Private Function GetServiceC(Of T1, T2)() As T1'. + GetServiceC(Of)() + ~~~~ +BC30182: Type expected. + GetServiceC(Of)() + ~ +BC32042: Too few type arguments to 'Private Function GetServiceC(Of T1, T2)() As T1'. + GetServiceC(Of)().ToString() + ~~~~ +BC30182: Type expected. + GetServiceC(Of)().ToString() + ~ + ) + + End Sub + End Class End Namespace diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/Nullable/CSharpDeclareAsNullableCodeFixTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/Nullable/CSharpDeclareAsNullableCodeFixTests.cs index 9a49294320dd5..66b792e6f20f3 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/Nullable/CSharpDeclareAsNullableCodeFixTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/Nullable/CSharpDeclareAsNullableCodeFixTests.cs @@ -832,6 +832,22 @@ void M2(string? x) { } }", parameters: s_nullableFeature); } + [Fact] + [WorkItem(44338, "https://github.com/dotnet/roslyn/issues/44338")] + public async Task NoFixInvocationOfExternalMethod_NamedArgument() + { + await TestMissingInRegularAndScriptAsync( +@"#nullable enable +class Program +{ + void M() + { + var list = new System.Collections.Generic.List(); + list.Add(item: [|null|]); + } +}", parameters: s_nullableFeature); + } + [Fact] public async Task FixInvocation_NamedArgument_OutOfOrder() { @@ -856,6 +872,22 @@ void M2(int i, string? x) { } }", parameters: s_nullableFeature); } + [Fact] + [WorkItem(44338, "https://github.com/dotnet/roslyn/issues/44338")] + public async Task NoFixInvocationOfExternalMethod_NamedArgument_OutOfOrder() + { + await TestMissingInRegularAndScriptAsync( +@"#nullable enable +class Program +{ + void M() + { + var dict = new System.Collections.Generic.Dictionary(); + dict.Add(value: 0, key: [|null|]); + } +}", parameters: s_nullableFeature); + } + [Fact] public async Task FixInvocation_NamedArgument_Partial() { @@ -896,6 +928,22 @@ void M2(string? x) { } }", parameters: s_nullableFeature); } + [Fact] + [WorkItem(44338, "https://github.com/dotnet/roslyn/issues/44338")] + public async Task NoFixInvocationOfExternalMethod_PositionArgument() + { + await TestMissingInRegularAndScriptAsync( +@"#nullable enable +class Program +{ + void M() + { + var list = new System.Collections.Generic.List(); + list.Add([|null|]); + } +}", parameters: s_nullableFeature); + } + [Fact] public async Task FixInvocation_PositionArgument_SecondPosition() { diff --git a/src/Features/CSharp/Portable/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs index 9bde063178b72..5272750ef3986 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Nullable/CSharpDeclareAsNullableCodeFixProvider.cs @@ -340,7 +340,7 @@ declarator.Parent is VariableDeclarationSyntax declaration && static TypeSyntax? TryGetParameterTypeSyntax(IParameterSymbol? parameterSymbol) { if (parameterSymbol is object && - parameterSymbol.DeclaringSyntaxReferences[0].GetSyntax() is ParameterSyntax parameterSyntax && + parameterSymbol.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() is ParameterSyntax parameterSyntax && parameterSymbol.ContainingSymbol is IMethodSymbol method && method.GetAllMethodSymbolsOfPartialParts().Length == 1) { diff --git a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs index ccc1eecf89b38..2ea840063fa1a 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs @@ -545,7 +545,7 @@ internal override bool IsClosureScope(SyntaxNode node) protected override IEnumerable GetLambdaBodyExpressionsAndStatements(SyntaxNode lambdaBody) => SpecializedCollections.SingletonEnumerable(lambdaBody); - protected override SyntaxNode TryGetPartnerLambdaBody(SyntaxNode oldBody, SyntaxNode newLambda) + protected override SyntaxNode? TryGetPartnerLambdaBody(SyntaxNode oldBody, SyntaxNode newLambda) => LambdaUtilities.TryGetCorrespondingLambdaBody(oldBody, newLambda); protected override Match ComputeTopLevelMatch(SyntaxNode oldCompilationUnit, SyntaxNode newCompilationUnit) @@ -1083,7 +1083,7 @@ internal override bool IsLocalFunction(SyntaxNode node) internal override bool IsNestedFunction(SyntaxNode node) => node is LambdaExpressionSyntax || node is LocalFunctionStatementSyntax; - internal override bool TryGetLambdaBodies(SyntaxNode node, out SyntaxNode body1, out SyntaxNode body2) + internal override bool TryGetLambdaBodies(SyntaxNode node, [NotNullWhen(true)] out SyntaxNode? body1, out SyntaxNode? body2) => LambdaUtilities.TryGetLambdaBodies(node, out body1, out body2); internal override SyntaxNode GetLambda(SyntaxNode lambdaBody) diff --git a/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs b/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs index e47024c0dc9e0..44e2178780b81 100644 --- a/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs +++ b/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -52,6 +53,7 @@ private async Task UpdateDocumentAsync( var nodesToRemove = sections.Skip(1).Select(s => s.SyntaxToRemove).Where(s => s.Parent == ifStatement.Parent); root = root.RemoveNodes(nodesToRemove, SyntaxRemoveOptions.KeepNoTrivia); + Debug.Assert(root is object); // we didn't remove the root root = root.ReplaceNode(root.FindNode(ifSpan, getInnermostNodeForTie: true), @switch); return document.WithSyntaxRoot(root); } diff --git a/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs b/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs index 24d544e61ee00..cc2db6cb3d6a2 100644 --- a/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs +++ b/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs @@ -168,7 +168,7 @@ private SyntaxNode FindStatement(SyntaxNode declarationBody, TextSpan span, out /// protected abstract IEnumerable GetLambdaBodyExpressionsAndStatements(SyntaxNode lambdaBody); - protected abstract SyntaxNode TryGetPartnerLambdaBody(SyntaxNode oldBody, SyntaxNode newLambda); + protected abstract SyntaxNode? TryGetPartnerLambdaBody(SyntaxNode oldBody, SyntaxNode newLambda); protected abstract Match ComputeTopLevelMatch(SyntaxNode oldCompilationUnit, SyntaxNode newCompilationUnit); protected abstract Match ComputeBodyMatch(SyntaxNode oldBody, SyntaxNode newBody, IEnumerable>? knownMatches); @@ -344,7 +344,7 @@ protected virtual string GetSuspensionPointDisplayName(SyntaxNode node, EditKind /// /// Some lambda queries (group by, join by) have two bodies. /// - internal abstract bool TryGetLambdaBodies(SyntaxNode node, out SyntaxNode body1, out SyntaxNode body2); + internal abstract bool TryGetLambdaBodies(SyntaxNode node, [NotNullWhen(true)] out SyntaxNode? body1, out SyntaxNode? body2); internal abstract bool IsStateMachineMethod(SyntaxNode declaration); internal abstract SyntaxNode? TryGetContainingTypeDeclaration(SyntaxNode node); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs index 4dedb96972c51..230840efc068c 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs @@ -339,7 +339,7 @@ static void ProcessStructuredTrivia(List list, SyntaxNode str } } - private static bool IsFormatDirective(DirectiveTriviaSyntax trivia, SyntaxKind disableOrRestoreKeyword) + private static bool IsFormatDirective(DirectiveTriviaSyntax? trivia, SyntaxKind disableOrRestoreKeyword) { if (!(trivia is PragmaWarningDirectiveTriviaSyntax pragmaWarningDirectiveTrivia)) {