public override Evaluation VisitDeclarationPattern(DeclarationPatternSyntax node) { node.Designation?.Accept <Evaluation>(this); node.Type?.Accept <Evaluation>(this); return(base.VisitDeclarationPattern(node)); }
protected static void VerifyModelForDeclarationFieldDuplicate( SemanticModel model, DeclarationPatternSyntax decl, params IdentifierNameSyntax[] references) { VerifyModelForDeclarationField(model, decl, true, references); }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { node.Designation?.Accept(this); node.Type?.Accept(this); base.VisitDeclarationPattern(node); }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { if (node.Designation?.Kind() == SyntaxKind.SingleVariableDesignation) { TFieldOrLocalSymbol variable = MakePatternVariable( node.Type, (SingleVariableDesignationSyntax)node.Designation, _nodeToBind ); if ((object)variable != null) { _variablesBuilder.Add(variable); } } else { // The declaration pattern does not permit a ParenthesizedVariableDesignation Debug.Assert( node.Designation == null || node.Designation.Kind() == SyntaxKind.DiscardDesignation ); } base.VisitDeclarationPattern(node); }
protected override Symbol MakePatternVariable(DeclarationPatternSyntax node, SyntaxNode nodeToBind) { return(GlobalExpressionVariable.Create( _containingType, _modifiers, node.Type, node.Identifier.ValueText, node, node.Identifier.GetLocation(), _containingFieldOpt, nodeToBind)); }
private Doc PrintDeclarationPatternSyntax(DeclarationPatternSyntax node) { return(Concat( this.Print(node.Type), " ", this.Print(node.Designation) )); }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { var variable = MakePatternVariable(node, _nodeToBind); if ((object)variable != null) { _variablesBuilder.Add(variable); } base.VisitDeclarationPattern(node); }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { _localsBuilder.Add(SourceLocalSymbol.MakeLocalSymbolWithEnclosingContext( _scopeBinder.ContainingMemberOrLambda, scopeBinder: _scopeBinder, nodeBinder: _enclosingBinder, typeSyntax: node.Type, identifierToken: node.Identifier, kind: LocalDeclarationKind.PatternVariable, nodeToBind: _nodeToBind, forbiddenZone: null)); base.VisitDeclarationPattern(node); }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { if (!PreVisit(node)) { return; } node.Designation?.Accept(this); node.Type?.Accept(this); base.VisitDeclarationPattern(node); PostVisit(node); }
protected override Symbol MakePatternVariable(DeclarationPatternSyntax node, SyntaxNode nodeToBind) { var designation = node.Designation as SingleVariableDesignationSyntax; if (designation == null) { return(null); } return(GlobalExpressionVariable.Create( _containingType, _modifiers, node.Type, designation.Identifier.ValueText, designation, designation.GetLocation(), _containingFieldOpt, nodeToBind)); }
/// <summary> /// Try getting the <see cref="ILocalSymbol"/> for the node. /// Gets the semantic model for the tree if the node is not in the tree corresponding to <paramref name="semanticModel"/>. /// </summary> /// <param name="semanticModel">The <see cref="SemanticModel"/>.</param> /// <param name="node">The <see cref="DeclarationPatternSyntax"/>.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <param name="symbol">The symbol if found. Can be <see cref="IDiscardSymbol"/>.</param> /// <returns>True if a symbol was found.</returns> public static bool TryGetSymbol(this SemanticModel semanticModel, DeclarationPatternSyntax node, CancellationToken cancellationToken, [NotNullWhen(true)] out ISymbol?symbol) { if (semanticModel is null) { throw new ArgumentNullException(nameof(semanticModel)); } if (node is null) { throw new ArgumentNullException(nameof(node)); } symbol = GetDeclaredSymbolSafe(semanticModel, node, cancellationToken); return(symbol != null); }
protected static void VerifyModelNotSupported( SemanticModel model, DeclarationPatternSyntax decl, params IdentifierNameSyntax[] references) { Assert.Null(model.GetDeclaredSymbol(decl)); var identifierText = decl.Identifier.ValueText; Assert.False(model.LookupSymbols(decl.SpanStart, name: identifierText).Any()); Assert.False(model.LookupNames(decl.SpanStart).Contains(identifierText)); Assert.Null(model.GetSymbolInfo(decl.Type).Symbol); Assert.Null(model.GetSymbolInfo(decl).Symbol); Assert.Null(model.GetTypeInfo(decl).Type); Assert.Null(model.GetDeclaredSymbol(decl)); VerifyModelNotSupported(model, references); }
protected static void VerifyModelForDeclarationPattern( SemanticModel model, DeclarationPatternSyntax decl, bool isShadowed, params IdentifierNameSyntax[] references) { var symbol = model.GetDeclaredSymbol(decl); Assert.Equal(decl.Identifier.ValueText, symbol.Name); Assert.Equal(decl, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl)); if (isShadowed) { Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single()); } else { Assert.Same(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single()); } Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText)); Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(decl.Type)); Assert.True(SyntaxFacts.IsInTypeOnlyContext(decl.Type)); var local = ((SourceLocalSymbol)symbol); var type = local.Type; if (type.IsErrorType()) { Assert.Null(model.GetSymbolInfo(decl.Type).Symbol); } else { Assert.Equal(type, model.GetSymbolInfo(decl.Type).Symbol); } foreach (var reference in references) { Assert.Same(symbol, model.GetSymbolInfo(reference).Symbol); Assert.Same(symbol, model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Single()); Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText)); } }
protected static void VerifyModelForDeclarationField( SemanticModel model, SingleVariableDesignationSyntax designation, bool duplicate, params IdentifierNameSyntax[] references) { var symbol = model.GetDeclaredSymbol(designation); Assert.Equal(designation.Identifier.ValueText, symbol.Name); Assert.Equal(SymbolKind.Field, symbol.Kind); Assert.Equal(designation, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)designation)); var symbols = model.LookupSymbols(designation.SpanStart, name: designation.Identifier.ValueText); var names = model.LookupNames(designation.SpanStart); if (duplicate) { Assert.True(symbols.Count() > 1); Assert.Contains(symbol, symbols); } else { Assert.Same(symbol, symbols.Single()); } Assert.Contains(designation.Identifier.ValueText, names); DeclarationPatternSyntax decl = (DeclarationPatternSyntax)designation.Parent; var local = (FieldSymbol)symbol; var typeSyntax = decl.Type; Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(typeSyntax)); Assert.True(SyntaxFacts.IsInTypeOnlyContext(typeSyntax)); if (typeSyntax.IsVar && local.Type.IsErrorType()) { Assert.Null(model.GetSymbolInfo(typeSyntax).Symbol); } else { Assert.Equal(local.Type, model.GetSymbolInfo(typeSyntax).Symbol); } var declarator = designation.Ancestors().OfType <VariableDeclaratorSyntax>().FirstOrDefault(); var inFieldDeclaratorArgumentlist = declarator != null && declarator.Parent.Parent.Kind() != SyntaxKind.LocalDeclarationStatement && (declarator.ArgumentList?.Contains(designation)).GetValueOrDefault(); // this is a declaration site, not a use site. Assert.Null(model.GetSymbolInfo(designation).Symbol); Assert.Null(model.GetSymbolInfo(designation).Symbol); foreach (var reference in references) { var referenceInfo = model.GetSymbolInfo(reference); symbols = model.LookupSymbols(reference.SpanStart, name: designation.Identifier.ValueText); if (duplicate) { Assert.Null(referenceInfo.Symbol); Assert.Contains(symbol, referenceInfo.CandidateSymbols); Assert.True(symbols.Count() > 1); Assert.Contains(symbol, symbols); } else { Assert.Same(symbol, referenceInfo.Symbol); Assert.Same(symbol, symbols.Single()); Assert.Equal(local.Type, model.GetTypeInfo(reference).Type); } Assert.True(model.LookupNames(reference.SpanStart).Contains(designation.Identifier.ValueText)); } if (!inFieldDeclaratorArgumentlist) { var dataFlowParent = designation.FirstAncestorOrSelf <ExpressionSyntax>(); if (model.IsSpeculativeSemanticModel) { Assert.Throws <NotSupportedException>(() => model.AnalyzeDataFlow(dataFlowParent)); } else { var dataFlow = model.AnalyzeDataFlow(dataFlowParent); if (dataFlow.Succeeded) { Assert.False(dataFlow.VariablesDeclared.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.AlwaysAssigned.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.WrittenInside.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.DataFlowsIn.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.ReadInside.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.DataFlowsOut.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.ReadOutside.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.WrittenOutside.Contains(symbol, ReferenceEqualityComparer.Instance)); } } } }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { VisitType(node.Type); //base.VisitDeclarationPattern(node); }
private static void VerifyModelForDeclarationPattern(SemanticModel model, DeclarationPatternSyntax decl, params IdentifierNameSyntax[] references) { var symbol = model.GetDeclaredSymbol(decl); Assert.Equal(decl.Identifier.ValueText, symbol.Name); Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl)); Assert.Same(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single()); Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText)); foreach (var reference in references) { Assert.Same(symbol, model.GetSymbolInfo(reference).Symbol); Assert.Same(symbol, model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Single()); Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText)); } }
private BoundPattern BindDeclarationPattern( DeclarationPatternSyntax node, BoundExpression operand, TypeSymbol operandType, bool hasErrors, DiagnosticBag diagnostics) { Debug.Assert(operand != null && operandType != (object)null); var typeSyntax = node.Type; bool isVar; AliasSymbol aliasOpt; TypeSymbol declType = BindType(typeSyntax, diagnostics, out isVar, out aliasOpt); if (isVar) { declType = operandType; } if (declType == (object)null) { Debug.Assert(hasErrors); declType = this.CreateErrorType("var"); } var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType); if (IsOperatorErrors(node, operandType, boundDeclType, diagnostics)) { hasErrors = true; } else { hasErrors |= CheckValidPatternType(typeSyntax, operand, operandType, declType, isVar: isVar, patternTypeWasInSource: true, diagnostics: diagnostics); } switch (node.Designation.Kind()) { case SyntaxKind.SingleVariableDesignation: break; case SyntaxKind.DiscardedDesignation: return new BoundDeclarationPattern(node, null, boundDeclType, isVar, hasErrors); default: throw ExceptionUtilities.UnexpectedValue(node.Designation.Kind()); } var designation = (SingleVariableDesignationSyntax)node.Designation; var identifier = designation.Identifier; SourceLocalSymbol localSymbol = this.LookupLocal(identifier); if (localSymbol != (object)null) { if (InConstructorInitializer || InFieldInitializer) { Error(diagnostics, ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, node); } localSymbol.SetType(declType); // Check for variable declaration errors. hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); if (!hasErrors) { hasErrors = CheckRestrictedTypeInAsync(this.ContainingMemberOrLambda, declType, diagnostics, typeSyntax); } return new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors); } else { // We should have the right binder in the chain for a script or interactive, so we use the field for the pattern. Debug.Assert(node.SyntaxTree.Options.Kind != SourceCodeKind.Regular); GlobalExpressionVariable expressionVariableField = LookupDeclaredField(designation); DiagnosticBag tempDiagnostics = DiagnosticBag.GetInstance(); expressionVariableField.SetType(declType, tempDiagnostics); tempDiagnostics.Free(); BoundExpression receiver = SynthesizeReceiver(node, expressionVariableField, diagnostics); var variableAccess = new BoundFieldAccess(node, receiver, expressionVariableField, null, hasErrors); return new BoundDeclarationPattern(node, expressionVariableField, variableAccess, boundDeclType, isVar, hasErrors); } }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { Log(node, "Unsupported Syntax !"); }
private BoundPattern BindDeclarationPattern( DeclarationPatternSyntax node, TypeSymbol operandType, bool hasErrors, DiagnosticBag diagnostics) { Debug.Assert(operandType != (object)null); var typeSyntax = node.Type; bool isVar; AliasSymbol aliasOpt; TypeSymbol declType = BindTypeOrVarKeyword(typeSyntax, diagnostics, out isVar, out aliasOpt); if (isVar) { declType = operandType; } if (declType == (object)null) { Debug.Assert(hasErrors); declType = this.CreateErrorType("var"); } var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType); if (IsOperatorErrors(node, operandType, boundDeclType, diagnostics)) { hasErrors = true; } else { hasErrors |= CheckValidPatternType(typeSyntax, operandType, declType, isVar: isVar, patternTypeWasInSource: true, diagnostics: diagnostics); } switch (node.Designation.Kind()) { case SyntaxKind.SingleVariableDesignation: break; case SyntaxKind.DiscardDesignation: return(new BoundDeclarationPattern(node, null, boundDeclType, isVar, hasErrors)); default: throw ExceptionUtilities.UnexpectedValue(node.Designation.Kind()); } var designation = (SingleVariableDesignationSyntax)node.Designation; var identifier = designation.Identifier; SourceLocalSymbol localSymbol = this.LookupLocal(identifier); if (localSymbol != (object)null) { if ((InConstructorInitializer || InFieldInitializer) && ContainingMemberOrLambda.ContainingSymbol.Kind == SymbolKind.NamedType) { CheckFeatureAvailability(node, MessageID.IDS_FeatureExpressionVariablesInQueriesAndInitializers, diagnostics); } localSymbol.SetType(declType); // Check for variable declaration errors. hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); if (!hasErrors) { hasErrors = CheckRestrictedTypeInAsync(this.ContainingMemberOrLambda, declType, diagnostics, typeSyntax); } return(new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors)); } else { // We should have the right binder in the chain for a script or interactive, so we use the field for the pattern. Debug.Assert(node.SyntaxTree.Options.Kind != SourceCodeKind.Regular); GlobalExpressionVariable expressionVariableField = LookupDeclaredField(designation); DiagnosticBag tempDiagnostics = DiagnosticBag.GetInstance(); expressionVariableField.SetType(declType, tempDiagnostics); tempDiagnostics.Free(); BoundExpression receiver = SynthesizeReceiver(node, expressionVariableField, diagnostics); var variableAccess = new BoundFieldAccess(node, receiver, expressionVariableField, null, hasErrors); return(new BoundDeclarationPattern(node, expressionVariableField, variableAccess, boundDeclType, isVar, hasErrors)); } }
internal static async Task ComputeRefactoringAsync(RefactoringContext context, DeclarationPatternSyntax declarationPattern) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.RenameIdentifierAccordingToTypeName)) { VariableDesignationSyntax designation = declarationPattern.Designation; if (designation?.IsKind(SyntaxKind.SingleVariableDesignation) == true) { var singleVariableDesignation = (SingleVariableDesignationSyntax)designation; SyntaxToken identifier = singleVariableDesignation.Identifier; if (identifier.Span.Contains(context.Span)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ISymbol symbol = semanticModel.GetDeclaredSymbol(singleVariableDesignation, context.CancellationToken); if (symbol?.IsLocal() == true) { var localSymbol = (ILocalSymbol)symbol; string oldName = identifier.ValueText; string newName = NameGenerator.Default.CreateUniqueLocalName( localSymbol.Type, oldName, semanticModel, singleVariableDesignation.SpanStart, cancellationToken: context.CancellationToken); if (newName != null) { context.RegisterRefactoring( $"Rename '{oldName}' to '{newName}'", cancellationToken => Renamer.RenameSymbolAsync(context.Solution, symbol, newName, default(OptionSet), cancellationToken)); } } } } } }
private static void VerifyModelForDeclarationPattern(SemanticModel model, DeclarationPatternSyntax decl, bool isShadowed, params IdentifierNameSyntax[] references) { var symbol = model.GetDeclaredSymbol(decl); Assert.Equal(decl.Identifier.ValueText, symbol.Name); Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl)); if (isShadowed) { Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single()); } else { Assert.Same(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single()); } Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText)); var type = ((LocalSymbol)symbol).Type; if (!decl.Type.IsVar || !type.IsErrorType()) { Assert.Equal(type, model.GetSymbolInfo(decl.Type).Symbol); } foreach (var reference in references) { Assert.Same(symbol, model.GetSymbolInfo(reference).Symbol); Assert.Same(symbol, model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Single()); Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText)); } }
public static Doc Print(DeclarationPatternSyntax node) { return(Doc.Concat(Node.Print(node.Type), " ", Node.Print(node.Designation))); }
/// <inheritdoc /> public override Expression VisitDeclarationPattern(DeclarationPatternSyntax node) { throw Unexpected(node, nameof(VisitIsPatternExpression)); }
private BoundPattern BindDeclarationPattern( DeclarationPatternSyntax node, BoundExpression operand, TypeSymbol operandType, bool hasErrors, DiagnosticBag diagnostics) { Debug.Assert(operand != null && operandType != (object)null); var typeSyntax = node.Type; var identifier = node.Identifier; bool isVar; AliasSymbol aliasOpt; TypeSymbol declType = BindType(typeSyntax, diagnostics, out isVar, out aliasOpt); if (isVar) { declType = operandType; } if (declType == (object)null) { Debug.Assert(hasErrors); declType = this.CreateErrorType("var"); } var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType); if (IsOperatorErrors(node, operandType, boundDeclType, diagnostics)) { hasErrors = true; } else { hasErrors |= CheckValidPatternType(typeSyntax, operand, operandType, declType, isVar: isVar, patternTypeWasInSource: true, diagnostics: diagnostics); } SourceLocalSymbol localSymbol = this.LookupLocal(identifier); if (localSymbol != (object)null) { if (InConstructorInitializer || InFieldInitializer) { Error(diagnostics, ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, node); } localSymbol.SetType(declType); // Check for variable declaration errors. hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); if (!hasErrors) { hasErrors = CheckRestrictedTypeInAsync(this.ContainingMemberOrLambda, declType, diagnostics, typeSyntax); } return(new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors)); } else { // We should have the right binder in the chain for a script or interactive, so we use the field for the pattern. Debug.Assert(node.SyntaxTree.Options.Kind != SourceCodeKind.Regular); GlobalExpressionVariable expressionVariableField = LookupDeclaredField(node); DiagnosticBag tempDiagnostics = DiagnosticBag.GetInstance(); expressionVariableField.SetType(declType, tempDiagnostics); tempDiagnostics.Free(); BoundExpression receiver = SynthesizeReceiver(node, expressionVariableField, diagnostics); var variableAccess = new BoundFieldAccess(node, receiver, expressionVariableField, null, hasErrors); return(new BoundDeclarationPattern(node, expressionVariableField, variableAccess, boundDeclType, isVar, hasErrors)); } }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { }
protected abstract TFieldOrLocalSymbol MakePatternVariable(DeclarationPatternSyntax node, SyntaxNode nodeToBind);
private BoundPattern BindDeclarationPattern( DeclarationPatternSyntax node, BoundExpression operand, TypeSymbol operandType, bool hasErrors, DiagnosticBag diagnostics) { Debug.Assert(operand != null || operandType != (object)null); if (InConstructorInitializer || InFieldInitializer) { Error(diagnostics, ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, node); } var typeSyntax = node.Type; var identifier = node.Identifier; bool isVar; AliasSymbol aliasOpt; TypeSymbol declType = BindType(typeSyntax, diagnostics, out isVar, out aliasOpt); if (isVar && operandType != (object)null) { declType = operandType; } if (declType == (object)null) { Debug.Assert(hasErrors); declType = this.CreateErrorType("var"); } var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType); if (IsOperatorErrors(node, operandType, boundDeclType, diagnostics)) { hasErrors = true; } else { hasErrors |= CheckValidPatternType(typeSyntax, operand, operandType, declType, isVar: isVar, patternTypeWasInSource: true, diagnostics: diagnostics); } SourceLocalSymbol localSymbol = this.LookupLocal(identifier); // In error scenarios with misplaced code, it is possible we can't bind the local declaration. // This occurs through the semantic model. In that case concoct a plausible result. if (localSymbol == (object)null) { localSymbol = SourceLocalSymbol.MakeLocal( ContainingMemberOrLambda, this, false, // do not allow ref typeSyntax, identifier, LocalDeclarationKind.PatternVariable); } localSymbol.SetType(declType); // Check for variable declaration errors. hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); if (this.ContainingMemberOrLambda.Kind == SymbolKind.Method && ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync && declType.IsRestrictedType() && !hasErrors) { Error(diagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declType); hasErrors = true; } return(new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors)); }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { throw new NotImplementedException(); }
/// <summary> /// Given a declaration pattern syntax, get the corresponding symbol. /// </summary> /// <param name="declarationSyntax">The syntax node that declares a variable.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The symbol that was declared.</returns> public override ILocalSymbol GetDeclaredSymbol(DeclarationPatternSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { var memberModel = this.GetMemberModel(declarationSyntax); return memberModel == null ? null : memberModel.GetDeclaredSymbol(declarationSyntax, cancellationToken); }
/// <summary> /// Given a declaration pattern syntax, get the corresponding symbol. /// </summary> /// <param name="declarationSyntax">The syntax node that declares a variable.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The symbol that was declared.</returns> public abstract ISymbol GetDeclaredSymbol(DeclarationPatternSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken));
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { _declarationPatterns.Add(SourceLocalSymbol.MakeLocal(_binder.ContainingMemberOrLambda, _binder, RefKind.None, node.Type, node.Identifier, LocalDeclarationKind.PatternVariable)); base.VisitDeclarationPattern(node); }
public override ISymbol GetDeclaredSymbol(DeclarationPatternSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { CheckSyntaxNode(declarationSyntax); return GetDeclaredLocal(declarationSyntax, declarationSyntax.Identifier); }
protected static void AssertContainedInDeclaratorArguments(DeclarationPatternSyntax decl) { Assert.True(decl.Ancestors().OfType<VariableDeclaratorSyntax>().First().ArgumentList.Contains(decl)); }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { _localsBuilder.Add(SourceLocalSymbol.MakeLocal(_binder.ContainingMemberOrLambda, _binder, RefKind.None, node.Type, node.Identifier, LocalDeclarationKind.PatternVariable)); base.VisitDeclarationPattern(node); }
protected static void VerifyModelForDeclarationPattern(SemanticModel model, DeclarationPatternSyntax decl, params IdentifierNameSyntax[] references) { VerifyModelForDeclarationPattern(model, decl, false, references); }
private static void VerifyModelForDeclarationPatternDuplicateInSameScope(SemanticModel model, DeclarationPatternSyntax decl) { var symbol = model.GetDeclaredSymbol(decl); Assert.Equal(decl.Identifier.ValueText, symbol.Name); Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl)); Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single()); Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText)); }
protected static void VerifyModelForDeclarationPatternDuplicateInSameScope(SemanticModel model, DeclarationPatternSyntax decl) { var symbol = model.GetDeclaredSymbol(decl); Assert.Equal(decl.Identifier.ValueText, symbol.Name); Assert.Equal(decl, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl)); Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single()); Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText)); var type = ((LocalSymbol)symbol).Type; if (!decl.Type.IsVar || !type.IsErrorType()) { Assert.Equal(type, model.GetSymbolInfo(decl.Type).Symbol); } }
private BoundPattern BindDeclarationPattern( DeclarationPatternSyntax node, BoundExpression operand, TypeSymbol operandType, bool hasErrors, DiagnosticBag diagnostics) { Debug.Assert(operand != null || operandType != (object)null); var typeSyntax = node.Type; var identifier = node.Identifier; bool isVar; AliasSymbol aliasOpt; TypeSymbol declType = BindType(typeSyntax, diagnostics, out isVar, out aliasOpt); if (isVar && operandType != (object)null) { declType = operandType; } if (declType == (object)null) { Debug.Assert(hasErrors); declType = this.CreateErrorType(); } var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType); if (IsOperatorErrors(node, operandType, boundDeclType, diagnostics)) { hasErrors = true; } else { hasErrors |= CheckValidPatternType(typeSyntax, operand, operandType, declType, isVar: isVar, patternTypeWasInSource: true, diagnostics: diagnostics); } SourceLocalSymbol localSymbol = this.LookupLocal(identifier); // In error scenarios with misplaced code, it is possible we can't bind the local declaration. // This occurs through the semantic model. In that case concoct a plausible result. if (localSymbol == (object)null) { localSymbol = SourceLocalSymbol.MakeLocal( ContainingMemberOrLambda, this, RefKind.None, typeSyntax, identifier, LocalDeclarationKind.PatternVariable); } if (isVar) { localSymbol.SetTypeSymbol(operandType); } // Check for variable declaration errors. hasErrors |= this.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); if (this.ContainingMemberOrLambda.Kind == SymbolKind.Method && ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync && declType.IsRestrictedType() && !hasErrors) { Error(diagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declType); hasErrors = true; } DeclareLocalVariable(localSymbol, identifier, declType); return new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors); }
/// <summary> /// Given a declaration pattern syntax, get the corresponding symbol. /// </summary> /// <param name="declarationSyntax">The syntax node that declares a variable.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The symbol that was declared.</returns> public override ISymbol GetDeclaredSymbol(DeclarationPatternSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { var memberModel = this.GetMemberModel(declarationSyntax); return memberModel?.GetDeclaredSymbol(declarationSyntax, cancellationToken) ?? GetEnclosingBinder(declarationSyntax.Position)?.LookupDeclaredField(declarationSyntax); }
private static void VerifyModelNotSupported(SemanticModel model, DeclarationPatternSyntax decl, params IdentifierNameSyntax[] references) { Assert.Null(model.GetDeclaredSymbol(decl)); Assert.Null(model.GetDeclaredSymbol((SyntaxNode)decl)); Assert.False(model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Any()); Assert.False(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText)); Assert.Null(model.GetSymbolInfo(decl.Type).Symbol); foreach (var reference in references) { Assert.Null(model.GetSymbolInfo(reference).Symbol); Assert.False(model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Any()); Assert.False(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText)); } }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) { _localsBuilder.Add(SourceLocalSymbol.MakeLocal(_scopeBinder.ContainingMemberOrLambda, _scopeBinder, false, node.Type, node.Identifier, LocalDeclarationKind.PatternVariable)); base.VisitDeclarationPattern(node); }
protected static void VerifyModelForDeclarationField( SemanticModel model, DeclarationPatternSyntax decl, bool duplicate, params IdentifierNameSyntax[] references) { var symbol = model.GetDeclaredSymbol(decl); Assert.Equal(decl.Identifier.ValueText, symbol.Name); Assert.Equal(SymbolKind.Field, symbol.Kind); Assert.Equal(decl, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl)); var symbols = model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText); var names = model.LookupNames(decl.SpanStart); if (duplicate) { Assert.True(symbols.Count() > 1); Assert.Contains(symbol, symbols); } else { Assert.Same(symbol, symbols.Single()); } Assert.Contains(decl.Identifier.ValueText, names); var local = (FieldSymbol)symbol; var typeSyntax = decl.Type; Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(typeSyntax)); Assert.True(SyntaxFacts.IsInTypeOnlyContext(typeSyntax)); if (typeSyntax.IsVar && local.Type.IsErrorType()) { Assert.Null(model.GetSymbolInfo(typeSyntax).Symbol); } else { Assert.Equal(local.Type, model.GetSymbolInfo(typeSyntax).Symbol); } var declarator = decl.Ancestors().OfType<VariableDeclaratorSyntax>().FirstOrDefault(); var inFieldDeclaratorArgumentlist = declarator != null && declarator.Parent.Parent.Kind() != SyntaxKind.LocalDeclarationStatement && (declarator.ArgumentList?.Contains(decl)).GetValueOrDefault(); // this is a declaration site, not a use site. Assert.Null(model.GetSymbolInfo(decl).Symbol); Assert.Null(model.GetSymbolInfo(decl).Symbol); foreach (var reference in references) { var referenceInfo = model.GetSymbolInfo(reference); symbols = model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText); if (duplicate) { Assert.Null(referenceInfo.Symbol); Assert.Contains(symbol, referenceInfo.CandidateSymbols); Assert.True(symbols.Count() > 1); Assert.Contains(symbol, symbols); } else { Assert.Same(symbol, referenceInfo.Symbol); Assert.Same(symbol, symbols.Single()); Assert.Equal(local.Type, model.GetTypeInfo(reference).Type); } Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText)); } if (!inFieldDeclaratorArgumentlist) { var dataFlowParent = decl.FirstAncestorOrSelf<ExpressionSyntax>(); if (model.IsSpeculativeSemanticModel) { Assert.Throws<NotSupportedException>(() => model.AnalyzeDataFlow(dataFlowParent)); } else { var dataFlow = model.AnalyzeDataFlow(dataFlowParent); if (dataFlow.Succeeded) { Assert.False(dataFlow.VariablesDeclared.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.AlwaysAssigned.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.WrittenInside.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.DataFlowsIn.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.ReadInside.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.DataFlowsOut.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.ReadOutside.Contains(symbol, ReferenceEqualityComparer.Instance)); Assert.False(dataFlow.WrittenOutside.Contains(symbol, ReferenceEqualityComparer.Instance)); } } } }
public override void VisitDeclarationPattern(DeclarationPatternSyntax node) => base.VisitDeclarationPattern(node);