protected override Symbol MakePatternVariable(TypeSyntax type, SingleVariableDesignationSyntax designation, SyntaxNode nodeToBind) { return(designation == null ? null : GlobalExpressionVariable.Create( _containingType, _modifiers, type, designation.Identifier.ValueText, designation, designation.GetLocation(), _containingFieldOpt, nodeToBind)); }
protected static void VerifyModelForDeclarationFieldDuplicate( SemanticModel model, SingleVariableDesignationSyntax decl, params IdentifierNameSyntax[] references) { VerifyModelForDeclarationField(model, decl, true, references); }
internal SourceMemberFieldSymbolFromDesignation( SourceMemberContainerTypeSymbol containingType, SingleVariableDesignationSyntax designation, DeclarationModifiers modifiers) : base(containingType, modifiers, designation.Identifier.ValueText, designation.GetReference(), designation.Identifier.GetLocation()) { Debug.Assert(DeclaredAccessibility == Accessibility.Private); }
protected static void VerifyModelForDeclarationOrVarSimplePatternWithoutDataFlow( SemanticModel model, SingleVariableDesignationSyntax decl, params IdentifierNameSyntax[] references ) { VerifyModelForDeclarationOrVarSimplePattern(model, decl, false, references); }
protected static void VerifyModelForDeclarationOrVarSimplePattern( SemanticModel model, SingleVariableDesignationSyntax designation, bool isShadowed, params IdentifierNameSyntax[] references) { var symbol = model.GetDeclaredSymbol(designation); Assert.Equal(designation.Identifier.ValueText, symbol.Name); Assert.Equal(designation, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal(LocalDeclarationKind.PatternVariable, symbol.GetSymbol <LocalSymbol>().DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)designation)); var other = model.LookupSymbols(designation.SpanStart, name: designation.Identifier.ValueText).Single(); if (isShadowed) { Assert.NotEqual(symbol, other); } else { Assert.Same(symbol, other); } Assert.True(model.LookupNames(designation.SpanStart).Contains(designation.Identifier.ValueText)); switch (designation.Parent) { case DeclarationPatternSyntax decl: { var typeSyntax = decl.Type; Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(typeSyntax)); Assert.True(SyntaxFacts.IsInTypeOnlyContext(typeSyntax)); var local = ((ILocalSymbol)symbol); var type = local.Type; if (type.IsErrorType()) { Assert.Null(model.GetSymbolInfo(typeSyntax).Symbol); } else { Assert.Equal(type, model.GetSymbolInfo(typeSyntax).Symbol); } AssertTypeInfo(model, typeSyntax, type); break; } } foreach (var reference in references) { Assert.Same(symbol, model.GetSymbolInfo(reference).Symbol); Assert.Same(symbol, model.LookupSymbols(reference.SpanStart, name: designation.Identifier.ValueText).Single()); Assert.True(model.LookupNames(reference.SpanStart).Contains(designation.Identifier.ValueText)); } }
public override void VisitSingleVariableDesignation(SingleVariableDesignationSyntax node) { if (!PreVisit(node)) { return; } base.VisitSingleVariableDesignation(node); PostVisit(node); }
protected static void AssertContainedInDeclaratorArguments( SingleVariableDesignationSyntax decl ) { Assert.True( decl.Ancestors() .OfType <VariableDeclaratorSyntax>() .First() .ArgumentList.Contains(decl) ); }
internal SourceMemberFieldSymbolFromDesignationWithEnclosingContext( SourceMemberContainerTypeSymbol containingType, SingleVariableDesignationSyntax designation, DeclarationModifiers modifiers, FieldSymbol containingFieldOpt, SyntaxNode nodeToBind) : base(containingType, designation, modifiers) { Debug.Assert(nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind is ExpressionSyntax); _containingFieldOpt = containingFieldOpt; _nodeToBind = nodeToBind.GetReference(); }
public override SyntaxNode VisitSingleVariableDesignation(SingleVariableDesignationSyntax node) { var newNode = (SingleVariableDesignationSyntax)base.VisitSingleVariableDesignation(node); if (_replacementMap.TryGetValue(node, out object newValue)) { return(newNode.WithIdentifier(SyntaxFactory.Identifier(newValue.ToString()))); } else { return(newNode); } }
/// <summary> /// In embedded statements, returns a BoundLocal when the type was explicit. /// In global statements, returns a BoundFieldAccess when the type was explicit. /// Otherwise returns a DeconstructionVariablePendingInference when the type is implicit. /// </summary> private BoundExpression BindDeconstructionVariable( TypeSymbol declType, TypeSyntax typeSyntax, SingleVariableDesignationSyntax designation, DiagnosticBag diagnostics) { SourceLocalSymbol localSymbol = LookupLocal(designation.Identifier); // is this a local? if ((object)localSymbol != null) { // Check for variable declaration errors. // Use the binder that owns the scope for the local because this (the current) binder // might own nested scope. var hasErrors = localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); if ((object)declType != null) { CheckRestrictedTypeInAsync(this.ContainingMemberOrLambda, declType, diagnostics, typeSyntax); return(new BoundLocal(designation, localSymbol, constantValueOpt: null, type: declType, hasErrors: hasErrors)); } return(new DeconstructionVariablePendingInference(designation, localSymbol, receiverOpt: null)); } // Is this a field? GlobalExpressionVariable field = LookupDeclaredField(designation); if ((object)field == null) { // We should have the right binder in the chain, cannot continue otherwise. throw ExceptionUtilities.Unreachable; } BoundThisReference receiver = ThisReference(designation, this.ContainingType, hasErrors: false, wasCompilerGenerated: true); if ((object)declType != null) { TypeSymbol fieldType = field.GetFieldType(this.FieldsBeingBound); Debug.Assert(declType == fieldType); return(new BoundFieldAccess(designation, receiver, field, constantValueOpt: null, resultKind: LookupResultKind.Viable, type: fieldType)); } return(new DeconstructionVariablePendingInference(designation, field, receiver)); }
internal static SourceMemberFieldSymbolFromDesignation Create( SourceMemberContainerTypeSymbol containingType, SingleVariableDesignationSyntax designation, DeclarationModifiers modifiers, FieldSymbol containingFieldOpt, SyntaxNode nodeToBind) { Debug.Assert(nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind is ExpressionSyntax); var typeSyntax = ((TypedVariableComponentSyntax)designation.Parent).Type; return(typeSyntax.IsVar ? new SourceMemberFieldSymbolFromDesignationWithEnclosingContext(containingType, designation, modifiers, containingFieldOpt, nodeToBind) : new SourceMemberFieldSymbolFromDesignation(containingType, designation, modifiers)); }
internal static void VerifyModelForDuplicateVariableDeclarationInSameScope( SemanticModel model, SingleVariableDesignationSyntax designation, LocalDeclarationKind kind) { var symbol = model.GetDeclaredSymbol(designation); Assert.Equal(designation.Identifier.ValueText, symbol.Name); Assert.Equal(designation, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal(kind, symbol.GetSymbol <LocalSymbol>().DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)designation)); Assert.NotEqual(symbol, model.LookupSymbols(designation.SpanStart, name: designation.Identifier.ValueText).Single()); Assert.True(model.LookupNames(designation.SpanStart).Contains(designation.Identifier.ValueText)); }
private static IEnumerable <string> FindLocalIdentifiersIn(SyntaxNode node) { return(node .DescendantNodes() .Where(node => node.IsKind(SyntaxKind.VariableDeclarator) || node.IsKind(SyntaxKind.LocalFunctionStatement) || node.IsKind(SyntaxKind.SingleVariableDesignation)) // local declaration in pattern matching .Select(node => node switch { VariableDeclaratorSyntax variableDeclarator => variableDeclarator.Identifier.Text, LocalFunctionStatementSyntax localFunction => localFunction.Identifier.Text, SingleVariableDesignationSyntax singleVariableDesignation => singleVariableDesignation.Identifier.Text, _ => default }));
/// <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="SingleVariableDesignationSyntax"/>.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <param name="symbol">The symbol if found.</param> /// <returns>True if a symbol was found.</returns> public static bool TryGetSymbol(this SemanticModel semanticModel, SingleVariableDesignationSyntax node, CancellationToken cancellationToken, [NotNullWhen(true)] out ILocalSymbol?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 override Symbol MakeDeconstructionVariable( TypeSyntax closestTypeSyntax, SingleVariableDesignationSyntax designation, AssignmentExpressionSyntax deconstruction) { return(GlobalExpressionVariable.Create( containingType: _containingType, modifiers: DeclarationModifiers.Private, typeSyntax: closestTypeSyntax, name: designation.Identifier.ValueText, syntax: designation, location: designation.Location, containingFieldOpt: null, nodeToBind: deconstruction)); }
protected static void VerifyModelNotSupported( SemanticModel model, SingleVariableDesignationSyntax designation, params IdentifierNameSyntax[] references ) { Assert.Null(model.GetDeclaredSymbol(designation)); var identifierText = designation.Identifier.ValueText; Assert.False(model.LookupSymbols(designation.SpanStart, name: identifierText).Any()); Assert.False(model.LookupNames(designation.SpanStart).Contains(identifierText)); Assert.Null(model.GetSymbolInfo(designation).Symbol); Assert.Null(model.GetTypeInfo(designation).Type); Assert.Null(model.GetDeclaredSymbol(designation)); var symbol = (ISymbol)model.GetDeclaredSymbol(designation); if (designation.Parent is DeclarationPatternSyntax decl) { Assert.Null(model.GetSymbolInfo(decl.Type).Symbol); TypeInfo typeInfo = model.GetTypeInfo(decl.Type); if ((object)symbol != null) { var type = symbol.GetTypeOrReturnType(); Assert.Equal(type, typeInfo.Type); Assert.Equal(type, typeInfo.ConvertedType); } else { Assert.Equal(SymbolKind.ErrorType, typeInfo.Type.Kind); Assert.Equal(SymbolKind.ErrorType, typeInfo.ConvertedType.Kind); } Assert.Equal(typeInfo, ((CSharpSemanticModel)model).GetTypeInfo(decl.Type)); Assert.True(model.GetConversion(decl.Type).IsIdentity); } else if (designation.Parent is VarPatternSyntax varp) { // Do we want to add any tests for the var pattern? } VerifyModelNotSupported(model, references); }
protected static void VerifyModelForDeclarationPattern( SemanticModel model, SingleVariableDesignationSyntax designation, bool isShadowed, params IdentifierNameSyntax[] references) { var symbol = model.GetDeclaredSymbol(designation); Assert.Equal(designation.Identifier.ValueText, symbol.Name); Assert.Equal(designation, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)designation)); var other = model.LookupSymbols(designation.SpanStart, name: designation.Identifier.ValueText).Single(); if (isShadowed) { Assert.NotEqual(symbol, other); } else { Assert.Same(symbol, other); } Assert.True(model.LookupNames(designation.SpanStart).Contains(designation.Identifier.ValueText)); var decl = (DeclarationPatternSyntax)designation.Parent; 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: designation.Identifier.ValueText).Single()); Assert.True(model.LookupNames(reference.SpanStart).Contains(designation.Identifier.ValueText)); } }
private double ComputeWeightedDistance(SingleVariableDesignationSyntax leftNode, SingleVariableDesignationSyntax rightNode) { var distance = ComputeDistance(leftNode, rightNode); double parentDistance; if (leftNode.Parent != null && rightNode.Parent != null && GetLabel(leftNode.Parent) == GetLabel(rightNode.Parent)) { parentDistance = ComputeDistance(leftNode.Parent, rightNode.Parent); } else { parentDistance = 1; } return(0.5 * parentDistance + 0.5 * distance); }
protected override Symbol MakeDeclarationExpressionVariable( DeclarationExpressionSyntax node, SingleVariableDesignationSyntax designation, BaseArgumentListSyntax argumentListSyntaxOpt, SyntaxNode nodeToBind ) { return(GlobalExpressionVariable.Create( _containingType, _modifiers, node.Type, designation.Identifier.ValueText, designation, designation.Identifier.GetLocation(), _containingFieldOpt, nodeToBind )); }
protected static void VerifyModelNotSupported( SemanticModel model, SingleVariableDesignationSyntax designation, params IdentifierNameSyntax[] references) { Assert.Null(model.GetDeclaredSymbol(designation)); var identifierText = designation.Identifier.ValueText; Assert.False(model.LookupSymbols(designation.SpanStart, name: identifierText).Any()); Assert.False(model.LookupNames(designation.SpanStart).Contains(identifierText)); var decl = (DeclarationPatternSyntax)designation.Parent; Assert.Null(model.GetSymbolInfo(decl.Type).Symbol); Assert.Null(model.GetSymbolInfo(designation).Symbol); Assert.Null(model.GetTypeInfo(designation).Type); Assert.Null(model.GetDeclaredSymbol(designation)); VerifyModelNotSupported(model, references); }
protected static void VerifyModelForDeclarationOrVarPatternDuplicateInSameScope( SemanticModel model, SingleVariableDesignationSyntax designation ) { var symbol = model.GetDeclaredSymbol(designation); Assert.Equal(designation.Identifier.ValueText, symbol.Name); Assert.Equal(designation, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal( LocalDeclarationKind.PatternVariable, symbol.GetSymbol <LocalSymbol>().DeclarationKind ); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)designation)); Assert.NotEqual( symbol, model .LookupSymbols(designation.SpanStart, name: designation.Identifier.ValueText) .Single() ); Assert.True( model.LookupNames(designation.SpanStart).Contains(designation.Identifier.ValueText) ); var type = ((ILocalSymbol)symbol).Type; switch (designation.Parent) { case DeclarationPatternSyntax decl: if (!decl.Type.IsVar || !type.IsErrorType()) { Assert.Equal(type, model.GetSymbolInfo(decl.Type).Symbol); } AssertTypeInfo(model, decl.Type, type); break; case var parent: Assert.True(parent is VarPatternSyntax); break; } }
/// <summary> /// Returns a BoundLocal when the type was explicit, otherwise returns a DeconstructionLocalPendingInference. /// </summary> private BoundExpression BindDeconstructionDeclarationLocal(TypeSyntax typeSyntax, SingleVariableDesignationSyntax designation, DiagnosticBag diagnostics) { var localSymbol = LocateDeclaredVariableSymbol(designation, typeSyntax); // Check for variable declaration errors. // Use the binder that owns the scope for the local because this (the current) binder // might own nested scope. bool hasErrors = localSymbol.Binder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); bool isVar; bool isConst = false; AliasSymbol alias; TypeSymbol declType = BindVariableType(designation, diagnostics, typeSyntax, ref isConst, out isVar, out alias); if (!isVar) { if (designation.Parent.Kind() == SyntaxKind.ParenthesizedVariableDesignation) { // An explicit type can only be provided next to the variable Error(diagnostics, ErrorCode.ERR_DeconstructionVarFormDisallowsSpecificType, designation); hasErrors = true; } return new BoundLocal(designation, localSymbol, constantValueOpt: null, type: declType, hasErrors: hasErrors); } return new DeconstructionLocalPendingInference(designation, localSymbol); }
public override ISymbol GetDeclaredSymbol(SingleVariableDesignationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { CheckSyntaxNode(declarationSyntax); return GetDeclaredLocal(declarationSyntax, declarationSyntax.Identifier); }
protected static void VerifyModelNotSupported( SemanticModel model, SingleVariableDesignationSyntax designation, params IdentifierNameSyntax[] references) { Assert.Null(model.GetDeclaredSymbol(designation)); var identifierText = designation.Identifier.ValueText; Assert.False(model.LookupSymbols(designation.SpanStart, name: identifierText).Any()); Assert.False(model.LookupNames(designation.SpanStart).Contains(identifierText)); var decl = (DeclarationPatternSyntax)designation.Parent; Assert.Null(model.GetSymbolInfo(decl.Type).Symbol); Assert.Null(model.GetSymbolInfo(designation).Symbol); Assert.Null(model.GetTypeInfo(designation).Type); Assert.Null(model.GetDeclaredSymbol(designation)); VerifyModelNotSupported(model, references); }
private SourceLocalSymbol LocateDeclaredVariableSymbol(SingleVariableDesignationSyntax designation, TypeSyntax typeSyntax) { return LocateDeclaredVariableSymbol(designation.Identifier, typeSyntax, null); }
private static TypeSyntax GetTypeSyntax(SingleVariableDesignationSyntax decl) { return (decl.Parent as TypedVariableComponentSyntax)?.Type; }
protected static void VerifyModelForDeclarationPattern(SemanticModel model, SingleVariableDesignationSyntax decl, params IdentifierNameSyntax[] references) { VerifyModelForDeclarationPattern(model, decl, false, references); }
private static void VerifyModelForDeconstructionField(SemanticModel model, SingleVariableDesignationSyntax decl, params IdentifierNameSyntax[] references) { var field = (FieldSymbol)model.GetDeclaredSymbol(decl); Assert.Equal(decl.Identifier.ValueText, field.Name); Assert.Equal(SymbolKind.Field, ((FieldSymbol)field).Kind); Assert.Same(field, model.GetDeclaredSymbol((SyntaxNode)decl)); Assert.Same(field, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single()); Assert.Equal(Accessibility.Private, field.DeclaredAccessibility); Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText)); foreach (var reference in references) { Assert.Same(field, model.GetSymbolInfo(reference).Symbol); Assert.Same(field, model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Single()); Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText)); Assert.Equal(field.Type, model.GetTypeInfo(reference).Type); } }
public override void VisitSingleVariableDesignation(SingleVariableDesignationSyntax node) { RecordVariableDeclaration(node, node.Identifier.ValueText, null); }
protected static void VerifyModelForDeclarationFieldDuplicate( SemanticModel model, SingleVariableDesignationSyntax decl, params IdentifierNameSyntax[] references) { VerifyModelForDeclarationField(model, decl, true, references); }
protected static void AssertContainedInDeclaratorArguments(SingleVariableDesignationSyntax decl) { Assert.True(decl.Ancestors().OfType<VariableDeclaratorSyntax>().First().ArgumentList.Contains(decl)); }
/// <summary> /// In embedded statements, returns a BoundLocal when the type was explicit. /// In global statements, returns a BoundFieldAccess when the type was explicit. /// Otherwise returns a DeconstructionVariablePendingInference when the type is implicit. /// </summary> private BoundExpression BindDeconstructionDeclarationVariable( TypeSyntax typeSyntax, SingleVariableDesignationSyntax designation, DiagnosticBag diagnostics) { SourceLocalSymbol localSymbol = LookupLocal(designation.Identifier); bool hasErrors = false; bool isVar; bool isConst = false; AliasSymbol alias; TypeSymbol declType = BindVariableType(designation, diagnostics, typeSyntax, ref isConst, out isVar, out alias); if (!isVar) { if (designation.Parent.Kind() == SyntaxKind.ParenthesizedVariableDesignation) { // An explicit type can only be provided next to the variable Error(diagnostics, ErrorCode.ERR_DeconstructionVarFormDisallowsSpecificType, designation); hasErrors = true; } } // is this a local? if (localSymbol != null) { // Check for variable declaration errors. // Use the binder that owns the scope for the local because this (the current) binder // might own nested scope. hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); if (!isVar) { return new BoundLocal(designation, localSymbol, constantValueOpt: null, type: declType, hasErrors: hasErrors); } return new DeconstructionVariablePendingInference(designation, localSymbol, receiverOpt: null); } // Is this a field? GlobalExpressionVariable field = LookupDeclaredField(designation); if ((object)field == null) { // We should have the right binder in the chain, cannot continue otherwise. throw ExceptionUtilities.Unreachable; } BoundThisReference receiver = ThisReference(designation, this.ContainingType, hasErrors: false, wasCompilerGenerated: true); if (!isVar) { TypeSymbol fieldType = field.GetFieldType(this.FieldsBeingBound); return new BoundFieldAccess(designation, receiver, field, constantValueOpt: null, resultKind: LookupResultKind.Viable, type: fieldType, hasErrors: hasErrors); } return new DeconstructionVariablePendingInference(designation, field, receiver); }
public override void VisitSingleVariableDesignation(SingleVariableDesignationSyntax node) { _builder.Add(node); base.VisitSingleVariableDesignation(node); }
/// <summary> /// Make a variable for a declaration expression other than a deconstruction left-hand-side. The only /// other legal place for a declaration expression today is an out variable declaration; this method /// handles that and the error cases as well. /// </summary> protected abstract TFieldOrLocalSymbol MakeDeclarationExpressionVariable(DeclarationExpressionSyntax node, SingleVariableDesignationSyntax designation, BaseArgumentListSyntax argumentListSyntax, SyntaxNode nodeToBind);
private static void VerifyModelForDeconstructionForeach(SemanticModel model, SingleVariableDesignationSyntax decl, params IdentifierNameSyntax[] references) { VerifyModelForDeconstruction(model, decl, LocalDeclarationKind.ForEachIterationVariable, references); }
private static void VerifyModelForDeconstruction(SemanticModel model, SingleVariableDesignationSyntax decl, LocalDeclarationKind kind, params IdentifierNameSyntax[] references) { var symbol = model.GetDeclaredSymbol(decl); Assert.Equal(decl.Identifier.ValueText, symbol.Name); Assert.Equal(kind, ((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)); var local = (SourceLocalSymbol)symbol; var typeSyntax = GetTypeSyntax(decl); if (local.IsVar && local.Type.IsErrorType()) { Assert.Null(model.GetSymbolInfo(typeSyntax).Symbol); } else { if (typeSyntax != null) { Assert.Equal(local.Type, model.GetSymbolInfo(typeSyntax).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)); Assert.Equal(local.Type, model.GetTypeInfo(reference).Type); } }
/// <summary> /// Returns a BoundLocal when the type was explicit, otherwise returns a DeconstructionLocalPendingInference. /// </summary> private BoundExpression BindDeconstructionDeclarationLocal(TypeSyntax typeSyntax, SingleVariableDesignationSyntax designation, DiagnosticBag diagnostics) { var localSymbol = LocateDeclaredVariableSymbol(designation, typeSyntax); // Check for variable declaration errors. // Use the binder that owns the scope for the local because this (the current) binder // might own nested scope. bool hasErrors = localSymbol.Binder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); bool isVar; bool isConst = false; AliasSymbol alias; TypeSymbol declType = BindVariableType(designation, diagnostics, typeSyntax, ref isConst, out isVar, out alias); if (!isVar) { if (designation.Parent.Kind() == SyntaxKind.ParenthesizedVariableDesignation) { // An explicit type can only be provided next to the variable Error(diagnostics, ErrorCode.ERR_DeconstructionVarFormDisallowsSpecificType, designation); hasErrors = true; } return(new BoundLocal(designation, localSymbol, constantValueOpt: null, type: declType, hasErrors: hasErrors)); } return(new DeconstructionLocalPendingInference(designation, localSymbol)); }
private static TypeSyntax GetTypeSyntax(SingleVariableDesignationSyntax decl) { return (decl.Parent as DeclarationExpressionSyntax)?.Type; }
public override ISymbol GetDeclaredSymbol(SingleVariableDesignationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { // Might be a local variable. var memberModel = this.GetMemberModel(declarationSyntax); return memberModel?.GetDeclaredSymbol(declarationSyntax, cancellationToken); }
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 VisitSingleVariableDesignation(SingleVariableDesignationSyntax node) { _builder.Add(node); base.VisitSingleVariableDesignation(node); }
public override void VisitSingleVariableDesignation(SingleVariableDesignationSyntax node) { Debug.Fail(node.ToString()); base.VisitSingleVariableDesignation(node); }
public override Evaluation VisitSingleVariableDesignation(SingleVariableDesignationSyntax node) { return(base.VisitSingleVariableDesignation(node)); }
protected abstract TFieldOrLocalSymbol MakePatternVariable(TypeSyntax type, SingleVariableDesignationSyntax designation, SyntaxNode nodeToBind);
/// <summary> /// Given a variable designation (typically in the left-hand-side of a deconstruction declaration statement), /// figure out its type by looking at the declared symbol of the corresponding local. /// </summary> private SymbolInfo TypeFromLocal(SingleVariableDesignationSyntax variableDesignation, CancellationToken cancellationToken) { TypeSymbol variableType = (GetDeclaredSymbol(variableDesignation, cancellationToken) as LocalSymbol)?.Type; if (variableType?.IsErrorType() == false) { return new SymbolInfo(variableType); } return SymbolInfo.None; }
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)); } } } }
/// <summary> /// Given a variable designation 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(SingleVariableDesignationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken));
/// <summary> /// In embedded statements, returns a BoundLocal when the type was explicit. /// In global statements, returns a BoundFieldAccess when the type was explicit. /// Otherwise returns a DeconstructionVariablePendingInference when the type is implicit. /// </summary> private BoundExpression BindDeconstructionVariable( TypeSymbol declType, SingleVariableDesignationSyntax designation, DiagnosticBag diagnostics) { SourceLocalSymbol localSymbol = LookupLocal(designation.Identifier); // is this a local? if ((object)localSymbol != null) { // Check for variable declaration errors. // Use the binder that owns the scope for the local because this (the current) binder // might own nested scope. var hasErrors = localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); if ((object)declType != null) { CheckRestrictedTypeInAsync(this.ContainingMemberOrLambda, declType, diagnostics, designation); return new BoundLocal(designation, localSymbol, isDeclaration: true, constantValueOpt: null, type: declType, hasErrors: hasErrors); } return new DeconstructionVariablePendingInference(designation, localSymbol, receiverOpt: null); } // Is this a field? GlobalExpressionVariable field = LookupDeclaredField(designation); if ((object)field == null) { // We should have the right binder in the chain, cannot continue otherwise. throw ExceptionUtilities.Unreachable; } BoundThisReference receiver = ThisReference(designation, this.ContainingType, hasErrors: false, wasCompilerGenerated: true); if ((object)declType != null) { TypeSymbol fieldType = field.GetFieldType(this.FieldsBeingBound); Debug.Assert(declType == fieldType); return new BoundFieldAccess(designation, receiver, field, constantValueOpt: null, resultKind: LookupResultKind.Viable, type: fieldType); } return new DeconstructionVariablePendingInference(designation, field, receiver); }
/// <summary> /// Given a variable designation (typically in the left-hand-side of a deconstruction declaration statement), /// figure out its type by looking at the declared symbol of the corresponding variable. /// </summary> private SymbolInfo TypeFromVariable(SingleVariableDesignationSyntax variableDesignation, CancellationToken cancellationToken) { var variable = GetDeclaredSymbol(variableDesignation, cancellationToken); if (variable != null) { ITypeSymbol variableType; switch (variable.Kind) { case SymbolKind.Local: variableType = ((ILocalSymbol)variable).Type; break; case SymbolKind.Field: variableType = ((IFieldSymbol)variable).Type; break; default: variableType = null; break; } if (variableType?.Kind != SymbolKind.ErrorType) { return new SymbolInfo(variableType); } } return SymbolInfo.None; }
/// <summary> /// Make a variable for a declaration expression appearing as one of the declared variables of the left-hand-side /// of a deconstruction assignment. /// </summary> protected abstract TFieldOrLocalSymbol MakeDeconstructionVariable( TypeSyntax closestTypeSyntax, SingleVariableDesignationSyntax designation, AssignmentExpressionSyntax deconstruction);
public override ISymbol GetDeclaredSymbol(SingleVariableDesignationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { // Might be a local variable. var memberModel = this.GetMemberModel(declarationSyntax); ISymbol local = memberModel?.GetDeclaredSymbol(declarationSyntax, cancellationToken); if (local != null) { return local; } // Might be a field Binder binder = GetEnclosingBinder(declarationSyntax.Position); return binder?.LookupDeclaredField(declarationSyntax); }
static VariableDeclaration CreateSingle(Context cx, DeclarationExpressionSyntax node, SingleVariableDesignationSyntax designation, IExpressionParentEntity parent, int child) { bool isVar = node.Type.IsVar; var variableSymbol = cx.GetModel(designation).GetDeclaredSymbol(designation) as ILocalSymbol; if (variableSymbol == null) { cx.ModelError(node, "Failed to determine local variable"); return(Create(cx, node, NullType.Create(cx), isVar, parent, child)); } var type = Entities.Type.Create(cx, variableSymbol.GetAnnotatedType()); var location = cx.Create(designation.GetLocation()); var ret = Create(cx, designation, type, isVar, parent, child); cx.Try(null, null, () => LocalVariable.Create(cx, variableSymbol, ret, isVar, location)); return(ret); }
protected static void VerifyModelForDeclarationPatternDuplicateInSameScope(SemanticModel model, SingleVariableDesignationSyntax designation) { var symbol = model.GetDeclaredSymbol(designation); Assert.Equal(designation.Identifier.ValueText, symbol.Name); Assert.Equal(designation, symbol.DeclaringSyntaxReferences.Single().GetSyntax()); Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind); Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)designation)); Assert.NotEqual(symbol, model.LookupSymbols(designation.SpanStart, name: designation.Identifier.ValueText).Single()); Assert.True(model.LookupNames(designation.SpanStart).Contains(designation.Identifier.ValueText)); var type = ((LocalSymbol)symbol).Type; var decl = (DeclarationPatternSyntax)designation.Parent; if (!decl.Type.IsVar || !type.IsErrorType()) { Assert.Equal(type, model.GetSymbolInfo(decl.Type).Symbol); } }