public LocalWithInitializer( Symbol containingSymbol, Binder scopeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, EqualsValueClauseSyntax initializer, Binder initializerBinder, LocalDeclarationKind declarationKind ) : base( containingSymbol, scopeBinder, true, typeSyntax, identifierToken, declarationKind ) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); Debug.Assert(initializer != null); _initializer = initializer; _initializerBinder = initializerBinder; // default to the current scope in case we need to handle self-referential error cases. _refEscapeScope = _scopeBinder.LocalScopeDepth; _valEscapeScope = _scopeBinder.LocalScopeDepth; }
public LocalSymbolWithEnclosingContext( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone) : base(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, declarationKind, hasScopedModifier: false) // https://github.com/dotnet/roslyn/issues/62039: Allow 'scoped' modifier. { Debug.Assert( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ThisConstructorInitializer || nodeToBind.Kind() == SyntaxKind.BaseConstructorInitializer || 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 || nodeToBind is ExpressionSyntax); Debug.Assert(!(nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm) || nodeBinder is SwitchExpressionArmBinder); this._nodeBinder = nodeBinder; this._nodeToBind = nodeToBind; this._forbiddenZone = forbiddenZone; }
public static SourceLocalSymbol MakeLocal( Symbol containingSymbol, Binder scopeBinder, bool allowRefKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, EqualsValueClauseSyntax initializer = null, Binder initializerBinderOpt = null ) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); return((initializer != null) ? new LocalWithInitializer( containingSymbol, scopeBinder, typeSyntax, identifierToken, initializer, initializerBinderOpt ?? scopeBinder, declarationKind ) : new SourceLocalSymbol( containingSymbol, scopeBinder, allowRefKind, typeSyntax, identifierToken, declarationKind )); }
internal void CollectLocalsFromDeconstruction( ExpressionSyntax declaration, LocalDeclarationKind kind, ArrayBuilder<LocalSymbol> locals, SyntaxNode deconstructionStatement, Binder enclosingBinderOpt = null) { switch (declaration.Kind()) { case SyntaxKind.TupleExpression: { var tuple = (TupleExpressionSyntax)declaration; foreach (var arg in tuple.Arguments) { CollectLocalsFromDeconstruction(arg.Expression, kind, locals, deconstructionStatement, enclosingBinderOpt); } break; } case SyntaxKind.DeclarationExpression: { var declarationExpression = (DeclarationExpressionSyntax)declaration; CollectLocalsFromDeconstruction( declarationExpression.Designation, declarationExpression.Type, kind, locals, deconstructionStatement, enclosingBinderOpt); break; } case SyntaxKind.IdentifierName: break; default: throw ExceptionUtilities.UnexpectedValue(declaration.Kind()); } }
internal SynthesizedLocal( MethodSymbol containingMethod, TypeSymbol type, string name = null, CSharpSyntaxNode syntax = null, bool isPinned = false, RefKind refKind = RefKind.None, LocalDeclarationKind declarationKind = LocalDeclarationKind.CompilerGenerated, TempKind tempKind = TempKind.None) { this.containingMethod = containingMethod; Debug.Assert(type.SpecialType != SpecialType.System_Void); Debug.Assert((tempKind == TempKind.None) == (syntax == null)); #if NAME_TEMPS if (string.IsNullOrEmpty(name)) { name = "temp_" + Interlocked.Increment(ref nextDebugTempNumber); } #endif this.name = name; this.type = type; this.syntax = syntax; this.isPinned = isPinned; this.declarationKind = declarationKind; this.refKind = refKind; this.tempKind = tempKind; }
public static SourceLocalSymbol MakeDeconstructionLocal( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax closestTypeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode deconstruction ) { Debug.Assert(closestTypeSyntax != null); Debug.Assert(nodeBinder != null); Debug.Assert(closestTypeSyntax.Kind() != SyntaxKind.RefType); return(closestTypeSyntax.IsVar ? new DeconstructionLocalSymbol( containingSymbol, scopeBinder, nodeBinder, closestTypeSyntax, identifierToken, kind, deconstruction ) : new SourceLocalSymbol( containingSymbol, scopeBinder, false, closestTypeSyntax, identifierToken, kind )); }
internal void CollectLocalsFromDeconstruction( VariableComponentSyntax declaration, LocalDeclarationKind kind, ArrayBuilder <LocalSymbol> locals, SyntaxNode deconstructionStatement, Binder enclosingBinderOpt = null) { switch (declaration.Kind()) { case SyntaxKind.ParenthesizedVariableComponent: { var component = (ParenthesizedVariableComponentSyntax)declaration; foreach (var decl in component.Variables) { CollectLocalsFromDeconstruction(decl, kind, locals, deconstructionStatement, enclosingBinderOpt); } break; } case SyntaxKind.TypedVariableComponent: { var component = (TypedVariableComponentSyntax)declaration; CollectLocalsFromDeconstruction(component.Designation, component.Type, kind, locals, deconstructionStatement, enclosingBinderOpt); break; } default: throw ExceptionUtilities.UnexpectedValue(declaration.Kind()); } }
public EELocalSymbol( MethodSymbol method, ImmutableArray <Location> locations, string nameOpt, int ordinal, LocalDeclarationKind declarationKind, TypeSymbol type, RefKind refKind, bool isPinned, bool isCompilerGenerated, bool canScheduleToStack) { Debug.Assert(method != null); Debug.Assert(ordinal >= -1); Debug.Assert(!locations.IsDefault); Debug.Assert(type != null); _method = method; _locations = locations; _nameOpt = nameOpt; _ordinal = ordinal; _declarationKind = declarationKind; _type = type; _refKind = refKind; _isPinned = isPinned; _isCompilerGenerated = isCompilerGenerated; _canScheduleToStack = canScheduleToStack; }
internal static LocalSymbol MakeLocalSymbolWithEnclosingContext( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone) { Debug.Assert( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ThisConstructorInitializer || nodeToBind.Kind() == SyntaxKind.BaseConstructorInitializer || nodeToBind.Kind() == SyntaxKind.PrimaryConstructorBaseType || // initializer for a record constructor nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm || 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 }. Contains(nodeToBind.Ancestors().OfType <StatementSyntax>().First().Kind()) || nodeToBind is ExpressionSyntax); Debug.Assert(!(nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm) || nodeBinder is SwitchExpressionArmBinder); return(typeSyntax?.IsVar != false && kind != LocalDeclarationKind.DeclarationExpressionVariable ? new LocalSymbolWithEnclosingContext(containingSymbol, scopeBinder, nodeBinder, typeSyntax, identifierToken, kind, nodeToBind, forbiddenZone) : new SourceLocalSymbol(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, kind)); }
public LocalSymbolWithEnclosingContext( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone) : base(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, declarationKind) { Debug.Assert( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ThisConstructorInitializer || nodeToBind.Kind() == SyntaxKind.BaseConstructorInitializer || nodeToBind.Kind() == SyntaxKind.SimpleBaseType || // iniializer for a record constructor nodeToBind.Kind() == SyntaxKind.ArgumentList && nodeToBind.Parent is ConstructorInitializerSyntax || nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm || nodeToBind.Kind() == SyntaxKind.GotoCaseStatement || nodeToBind is ExpressionSyntax); Debug.Assert(!(nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm) || nodeBinder is SwitchExpressionArmBinder); this._nodeBinder = nodeBinder; this._nodeToBind = nodeToBind; this._forbiddenZone = forbiddenZone; }
internal void CollectLocalsFromDeconstruction( ExpressionSyntax declaration, LocalDeclarationKind kind, ArrayBuilder<LocalSymbol> locals, SyntaxNode deconstructionStatement, Binder enclosingBinderOpt = null) { switch (declaration.Kind()) { case SyntaxKind.TupleExpression: { var tuple = (TupleExpressionSyntax)declaration; foreach (var arg in tuple.Arguments) { CollectLocalsFromDeconstruction(arg.Expression, kind, locals, deconstructionStatement, enclosingBinderOpt); } break; } case SyntaxKind.DeclarationExpression: { var declarationExpression = (DeclarationExpressionSyntax)declaration; CollectLocalsFromDeconstruction( declarationExpression.Designation, declarationExpression.Type, kind, locals, deconstructionStatement, enclosingBinderOpt); break; } case SyntaxKind.IdentifierName: break; default: // In broken code, we can have an arbitrary expression here. Collect its expression variables. ExpressionVariableFinder.FindExpressionVariables(this, locals, declaration); break; } }
/// <summary> /// Make a local variable symbol whose type can be inferred (if necessary) by binding and enclosing construct. /// </summary> internal static LocalSymbol MakeLocalSymbolWithEnclosingContext( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone) { Debug.Assert( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ThisConstructorInitializer || nodeToBind.Kind() == SyntaxKind.BaseConstructorInitializer || nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm || nodeToBind.Kind() == SyntaxKind.ArgumentList && nodeToBind.Parent is ConstructorInitializerSyntax || nodeToBind.Kind() == SyntaxKind.VariableDeclaration && new[] { SyntaxKind.LocalDeclarationStatement, SyntaxKind.UsingStatement, SyntaxKind.FixedStatement }. Contains(nodeToBind.Ancestors().OfType <StatementSyntax>().First().Kind()) || nodeToBind is ExpressionSyntax); Debug.Assert(!(nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm) || nodeBinder is SwitchExpressionArmBinder); return(typeSyntax.IsNullWithNoType() != false && kind != LocalDeclarationKind.DeclarationExpressionVariable ? new LocalSymbolWithEnclosingContext(containingSymbol, scopeBinder, nodeBinder, typeSyntax, identifierToken, kind, nodeToBind, forbiddenZone) : new SourceLocalSymbol(containingSymbol, scopeBinder, Compiler.RefKind.None, typeSyntax, identifierToken, kind)); }
public static SourceLocalSymbol MakeLocal( Symbol containingSymbol, Binder binder, RefKind refKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, EqualsValueClauseSyntax initializer = null) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); if (initializer == null) { ArgumentSyntax argument; if (ArgumentSyntax.IsIdentifierOfOutVariableDeclaration(identifierToken, out argument)) { if (argument.Type.IsVar) { return(new PossibleOutVarLocalSymbol(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind)); } } return(new SourceLocalSymbol(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind)); } return(new LocalWithInitializer(containingSymbol, binder, refKind, typeSyntax, identifierToken, initializer, declarationKind)); }
public EELocalSymbol( MethodSymbol method, ImmutableArray<Location> locations, string nameOpt, int ordinal, LocalDeclarationKind declarationKind, TypeSymbol type, RefKind refKind, bool isPinned, bool isCompilerGenerated, bool canScheduleToStack) { Debug.Assert(method != null); Debug.Assert(ordinal >= -1); Debug.Assert(!locations.IsDefault); Debug.Assert(type != null); _method = method; _locations = locations; _nameOpt = nameOpt; _ordinal = ordinal; _declarationKind = declarationKind; _type = type; _refKind = refKind; _isPinned = isPinned; _isCompilerGenerated = isCompilerGenerated; _canScheduleToStack = canScheduleToStack; }
private SourceLocalSymbol( Symbol containingSymbol, Binder scopeBinder, bool allowRefKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind) { Debug.Assert(identifierToken.Kind() != SyntaxKind.None); Debug.Assert(declarationKind != LocalDeclarationKind.None); Debug.Assert(scopeBinder != null); this._scopeBinder = scopeBinder; this._containingSymbol = containingSymbol; this._identifierToken = identifierToken; this._typeSyntax = allowRefKind ? typeSyntax?.SkipRef(out this._refKind) : typeSyntax; this._declarationKind = declarationKind; // create this eagerly as it will always be needed for the EnsureSingleDefinition _locations = ImmutableArray.Create <Location>(identifierToken.GetLocation()); _refEscapeScope = this._refKind == RefKind.None ? scopeBinder.LocalScopeDepth : Binder.ExternalScope; // default to returnable, unless there is initializer // we do not know the type yet. // assume this is returnable in case we never get to know our type. _valEscapeScope = Binder.ExternalScope; }
public static SourceLocalSymbol MakeLocal( Symbol containingSymbol, Binder binder, RefKind refKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, EqualsValueClauseSyntax initializer = null) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); if (initializer == null) { DeclarationExpressionSyntax declarationExpression; if (identifierToken.IsIdentifierOfOutVariableDeclaration(out declarationExpression)) { if (declarationExpression.Type().IsVar) { return(new PossiblyImplicitlyTypedOutVarLocalSymbol(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind)); } } return(new SourceLocalSymbol(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind)); } return(new LocalWithInitializer(containingSymbol, binder, refKind, typeSyntax, identifierToken, initializer, declarationKind)); }
public static SourceLocalSymbol MakeLocal( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); return(new SourceLocalSymbol(containingSymbol, binder, typeSyntax, identifierToken, declarationKind)); }
public static SourceLocalSymbol MakeLocalWithInitializer( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, EqualsValueClauseSyntax initializer, LocalDeclarationKind declarationKind) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); return(new LocalWithInitializer(containingSymbol, binder, typeSyntax, identifierToken, initializer, declarationKind)); }
public static SourceLocalSymbol MakeLocal( MethodSymbol containingMethod, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, EqualsValueClauseSyntax initializer, LocalDeclarationKind declarationKind) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEach); return new SourceLocalSymbol(containingMethod, binder, typeSyntax, identifierToken, initializer, null, declarationKind); }
public static SourceLocalSymbol MakeLocalWithInitializer( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, EqualsValueClauseSyntax initializer, LocalDeclarationKind declarationKind) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); return new LocalWithInitializer(containingSymbol, binder, typeSyntax, identifierToken, initializer, declarationKind); }
public DeconstructionLocalSymbol( Symbol containingSymbol, Binder scopeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, SyntaxNode deconstruction) : base(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, declarationKind) { _deconstruction = deconstruction; }
public static SourceLocalSymbol MakeLocal( MethodSymbol containingMethod, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, EqualsValueClauseSyntax initializer, LocalDeclarationKind declarationKind) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEach); return(new SourceLocalSymbol(containingMethod, binder, typeSyntax, identifierToken, initializer, null, declarationKind)); }
public static SourceLocalSymbol MakePossibleOutVarLocalWithoutInitializer( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, CSharpSyntaxNode scopeSegmentRoot, LocalDeclarationKind declarationKind) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); return(new PossibleOutVarLocalWithoutInitializer(containingSymbol, binder, typeSyntax, identifierToken, scopeSegmentRoot, declarationKind)); }
public static SourceLocalSymbol MakePossibleOutVarLocalWithoutInitializer( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, CSharpSyntaxNode scopeSegmentRoot, LocalDeclarationKind declarationKind) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); return new PossibleOutVarLocalWithoutInitializer(containingSymbol, binder, typeSyntax, identifierToken, scopeSegmentRoot, declarationKind); }
public ForEachLocal( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, ExpressionSyntax collection, LocalDeclarationKind declarationKind) : base(containingSymbol, binder, typeSyntax, identifierToken, declarationKind) { Debug.Assert(declarationKind == LocalDeclarationKind.ForEachIterationVariable); this.collection = collection; }
protected SourceLocalSymbol MakeLocal(VariableDeclarationSyntax declaration, LocalDeclarationKind kind, Binder initializerBinderOpt = null) { return(SourceLocalSymbol.MakeLocal( this.ContainingMemberOrLambda, this, declaration.Type.GetRefKind(), declaration.Type, declaration.Identifier, kind, declaration.Initializer, initializerBinderOpt)); }
public ForEachLocalSymbol( Symbol containingSymbol, ForEachLoopBinder scopeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, ExpressionSyntax collection, LocalDeclarationKind declarationKind) : base(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, declarationKind) { Debug.Assert(declarationKind == LocalDeclarationKind.ForEachIterationVariable); _collection = collection; }
public ForEachLocalSymbol( Symbol containingSymbol, ForEachLoopBinder scopeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, ExpressionSyntax collection, LocalDeclarationKind declarationKind) : base(containingSymbol, scopeBinder, allowRefKind: true, typeSyntax, identifierToken, declarationKind, hasScopedModifier: false) // https://github.com/dotnet/roslyn/issues/62039: Allow 'scoped' modifier. { Debug.Assert(declarationKind == LocalDeclarationKind.ForEachIterationVariable); _collection = collection; }
public DeconstructionLocalSymbol( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, SyntaxNode deconstruction) : base(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, declarationKind, hasScopedModifier: false) // https://github.com/dotnet/roslyn/issues/62039: Allow 'scoped' modifier. { _deconstruction = deconstruction; _nodeBinder = nodeBinder; }
protected ImmutableArray <LocalSymbol> BuildLocals(SyntaxList <StatementSyntax> statements) { ArrayBuilder <LocalSymbol> locals = null; foreach (var statement in statements) { var innerStatement = statement; // drill into any LabeledStatements -- atomic LabelStatements have been bound into // wrapped LabeledStatements by this point while (innerStatement.Kind() == SyntaxKind.LabeledStatement) { innerStatement = ((LabeledStatementSyntax)innerStatement).Statement; } switch (innerStatement.Kind()) { case SyntaxKind.LocalDeclarationStatement: { var decl = (LocalDeclarationStatementSyntax)innerStatement; if (locals == null) { locals = ArrayBuilder <LocalSymbol> .GetInstance(); } if (!decl.Declaration.IsDeconstructionDeclaration) { RefKind refKind = decl.RefKeyword.Kind().GetRefKind(); LocalDeclarationKind kind = decl.IsConst ? LocalDeclarationKind.Constant : LocalDeclarationKind.RegularVariable; foreach (var vdecl in decl.Declaration.Variables) { var localSymbol = MakeLocal(refKind, decl.Declaration, vdecl, kind); locals.Add(localSymbol); } } else { CollectLocalsFromDeconstruction(decl.Declaration, decl.Declaration.Type, LocalDeclarationKind.RegularVariable, locals); } } break; default: // no other statement introduces local variables into the enclosing scope break; } } return(locals?.ToImmutableAndFree() ?? ImmutableArray <LocalSymbol> .Empty); }
public EELocalSymbol( MethodSymbol method, ImmutableArray <Location> locations, string nameOpt, int ordinal, LocalDeclarationKind declarationKind, TypeSymbol type, RefKind refKind, bool isPinned, bool isCompilerGenerated, bool canScheduleToStack) : this(method, locations, nameOpt, ordinal, declarationKind, TypeWithAnnotations.Create(type), refKind, isPinned, isCompilerGenerated, canScheduleToStack) { }
public LocalWithInitializer( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, EqualsValueClauseSyntax initializer, LocalDeclarationKind declarationKind) : base(containingSymbol, binder, typeSyntax, identifierToken, declarationKind) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); Debug.Assert(initializer != null); this.initializer = initializer; }
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)); }
public DeconstructionLocalSymbol( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, SyntaxNode deconstruction) : base(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, declarationKind) { Debug.Assert(deconstruction.Kind() == SyntaxKind.SimpleAssignmentExpression || deconstruction.Kind() == SyntaxKind.ForEachVariableStatement); _deconstruction = deconstruction; _nodeBinder = nodeBinder; }
private SourceLocalSymbol( Symbol containingSymbol, Binder scopeBinder, bool allowRefKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, bool hasScopedModifier) { Debug.Assert(identifierToken.Kind() != SyntaxKind.None); Debug.Assert(declarationKind != LocalDeclarationKind.None); Debug.Assert(scopeBinder != null); Debug.Assert(containingSymbol.DeclaringCompilation == scopeBinder.Compilation); this._scopeBinder = scopeBinder; this._containingSymbol = containingSymbol; this._identifierToken = identifierToken; if (allowRefKind && typeSyntax is RefTypeSyntax refTypeSyntax) { this._typeSyntax = refTypeSyntax.Type; this._refKind = refTypeSyntax.ReadOnlyKeyword.Kind() == SyntaxKind.ReadOnlyKeyword ? RefKind.RefReadOnly : RefKind.Ref; this._scope = refTypeSyntax.ScopedKeyword.Kind() == SyntaxKind.ScopedKeyword ? DeclarationScope.ValueScoped : (hasScopedModifier ? DeclarationScope.RefScoped : DeclarationScope.Unscoped); } else { this._typeSyntax = typeSyntax; this._refKind = RefKind.None; this._scope = hasScopedModifier ? DeclarationScope.ValueScoped : DeclarationScope.Unscoped; } this._declarationKind = declarationKind; // create this eagerly as it will always be needed for the EnsureSingleDefinition _locations = ImmutableArray.Create <Location>(identifierToken.GetLocation()); _refEscapeScope = this._refKind == RefKind.None ? scopeBinder.LocalScopeDepth : Binder.ExternalScope; // default to returnable, unless there is initializer // we do not know the type yet. // assume this is returnable in case we never get to know our type. _valEscapeScope = Binder.ExternalScope; }
public LocalWithInitializer( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, EqualsValueClauseSyntax initializer, LocalDeclarationKind declarationKind) : base(containingSymbol, binder, typeSyntax, identifierToken, declarationKind) { if (initializer == null) { throw ExceptionUtilities.Unreachable; } this.initializer = initializer; }
private SourceLocalSymbol( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind) { Debug.Assert(identifierToken.Kind() != SyntaxKind.None); Debug.Assert(declarationKind != LocalDeclarationKind.None); this.binder = binder; _containingSymbol = containingSymbol; _identifierToken = identifierToken; _typeSyntax = typeSyntax; _declarationKind = declarationKind; // create this eagerly as it will always be needed for the EnsureSingleDefinition _locations = ImmutableArray.Create<Location>(identifierToken.GetLocation()); }
private SourceLocalSymbol( Symbol containingSymbol, Binder scopeBinder, bool allowRefKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind) { Debug.Assert(identifierToken.Kind() != SyntaxKind.None); Debug.Assert(declarationKind != LocalDeclarationKind.None); Debug.Assert(scopeBinder != null); this._scopeBinder = scopeBinder; this._containingSymbol = containingSymbol; this._identifierToken = identifierToken; this._typeSyntax = allowRefKind ? typeSyntax.SkipRef(out this._refKind) : typeSyntax; this._declarationKind = declarationKind; // create this eagerly as it will always be needed for the EnsureSingleDefinition _locations = ImmutableArray.Create<Location>(identifierToken.GetLocation()); }
private SourceLocalSymbol( MethodSymbol containingMethod, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, EqualsValueClauseSyntax initializer, ExpressionSyntax collection, LocalDeclarationKind declarationKind) { Debug.Assert(identifierToken.CSharpKind() != SyntaxKind.None); Debug.Assert(declarationKind != LocalDeclarationKind.CompilerGenerated); this.binder = binder; this.containingMethod = containingMethod; this.identifierToken = identifierToken; this.typeSyntax = typeSyntax; this.initializer = initializer; this.collection = collection; this.declarationKind = declarationKind; // create this eagerly as it will always be needed for the EnsureSingleDefinition this.locations = ImmutableArray.Create<Location>(identifierToken.GetLocation()); }
internal SynthesizedLocal( MethodSymbol containingMethod, TypeSymbol type, string name = null, CSharpSyntaxNode syntax = null, bool isPinned = false, RefKind refKind = RefKind.None, LocalDeclarationKind declarationKind = LocalDeclarationKind.CompilerGenerated, TempKind tempKind = TempKind.None) { this.containingMethod = containingMethod; Debug.Assert(type.SpecialType != SpecialType.System_Void); Debug.Assert((tempKind == TempKind.None) == (syntax == null)); #if NAME_TEMPS if (string.IsNullOrEmpty(name)) name = "temp_" + Interlocked.Increment(ref nextDebugTempNumber); #endif this.name = name; this.type = type; this.syntax = syntax; this.isPinned = isPinned; this.declarationKind = declarationKind; this.refKind = refKind; this.tempKind = tempKind; }
public ForEachLocal( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, ExpressionSyntax collection, LocalDeclarationKind declarationKind) : base(containingSymbol, binder, RefKind.None, typeSyntax, identifierToken, declarationKind) { Debug.Assert(declarationKind == LocalDeclarationKind.ForEachIterationVariable); _collection = collection; }
public LocalWithInitializer( Symbol containingSymbol, Binder binder, RefKind refKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, EqualsValueClauseSyntax initializer, LocalDeclarationKind declarationKind) : base(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); Debug.Assert(initializer != null); _initializer = initializer; // byval locals are always returnable // byref locals with initializers are assumed not returnable unless proven otherwise // NOTE: if we assumed returnable, then self-referring initializer could result in // a randomly changing returnability when initializer is bound concurrently. _returnable = refKind == RefKind.None; }
public LocalSymbolWithEnclosingContext( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone) : base(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, declarationKind) { Debug.Assert( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ArgumentList && nodeToBind.Parent is ConstructorInitializerSyntax || nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind is ExpressionSyntax); this._nodeBinder = nodeBinder; this._nodeToBind = nodeToBind; this._forbiddenZone = forbiddenZone; }
protected BoundLocalDeclaration BindVariableDeclaration( LocalDeclarationKind kind, bool isVar, VariableDeclaratorSyntax declarator, TypeSyntax typeSyntax, TypeSymbol declTypeOpt, AliasSymbol aliasOpt, DiagnosticBag diagnostics, CSharpSyntaxNode associatedSyntaxNode = null) { Debug.Assert(declarator != null); return BindVariableDeclaration(LocateDeclaredVariableSymbol(declarator, typeSyntax), kind, isVar, declarator, typeSyntax, declTypeOpt, aliasOpt, diagnostics, associatedSyntaxNode); }
/// <summary> /// Make a local variable symbol for an element of a deconstruction, /// which can be inferred (if necessary) by binding the enclosing statement. /// </summary> /// <param name="containingSymbol"></param> /// <param name="scopeBinder"> /// Binder that owns the scope for the local, the one that returns it in its <see cref="Binder.Locals"/> array. /// </param> /// <param name="nodeBinder"> /// Enclosing binder for the location where the local is declared. /// It should be used to bind something at that location. /// </param> /// <param name="closestTypeSyntax"></param> /// <param name="identifierToken"></param> /// <param name="kind"></param> /// <param name="deconstruction"></param> /// <returns></returns> public static SourceLocalSymbol MakeDeconstructionLocal( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax closestTypeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode deconstruction) { Debug.Assert(closestTypeSyntax != null); Debug.Assert(nodeBinder != null); Debug.Assert(closestTypeSyntax.Kind() != SyntaxKind.RefType); return closestTypeSyntax.IsVar ? new DeconstructionLocalSymbol(containingSymbol, scopeBinder, nodeBinder, closestTypeSyntax, identifierToken, kind, deconstruction) : new SourceLocalSymbol(containingSymbol, scopeBinder, false, closestTypeSyntax, identifierToken, kind); }
public static SourceLocalSymbol MakeLocal( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); return new SourceLocalSymbol(containingSymbol, binder, typeSyntax, identifierToken, declarationKind); }
public PossiblyImplicitlyTypedDeconstructionLocalSymbol( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind) : base(containingSymbol, binder, RefKind.None, typeSyntax, identifierToken, declarationKind) { SyntaxNode parent; Debug.Assert(SyntaxFacts.IsDeconstructionIdentifier(identifierToken, out parent) && parent != null && parent.Kind() == SyntaxKind.DeconstructionDeclarationStatement || parent.Kind() == SyntaxKind.ForStatement || parent.Kind() == SyntaxKind.ForEachComponentStatement); }
public static SourceLocalSymbol MakeDeconstructionLocal( Symbol containingSymbol, Binder binder, TypeSyntax closestTypeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind) { Debug.Assert(closestTypeSyntax != null); if (closestTypeSyntax.IsVar) { return new PossiblyImplicitlyTypedDeconstructionLocalSymbol(containingSymbol, binder, closestTypeSyntax, identifierToken, kind); } else { return new SourceLocalSymbol(containingSymbol, binder, RefKind.None, closestTypeSyntax, identifierToken, kind); } }
private static void VerifyModelForLocal(SemanticModel model, SingleVariableDesignationSyntax decl, LocalDeclarationKind kind, params IdentifierNameSyntax[] references) { VerifyModelForDeconstruction(model, decl, kind, 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); } }
protected BoundLocalDeclaration BindVariableDeclaration( SourceLocalSymbol localSymbol, LocalDeclarationKind kind, bool isVar, VariableDeclaratorSyntax declarator, TypeSyntax typeSyntax, TypeSymbol declTypeOpt, AliasSymbol aliasOpt, DiagnosticBag diagnostics, CSharpSyntaxNode associatedSyntaxNode = null) { Debug.Assert(declarator != null); Debug.Assert((object)declTypeOpt != null || isVar); Debug.Assert(typeSyntax != null); var localDiagnostics = DiagnosticBag.GetInstance(); // if we are not given desired syntax, we use declarator associatedSyntaxNode = associatedSyntaxNode ?? declarator; bool hasErrors = false; BoundExpression initializerOpt; // Check for variable declaration errors. hasErrors |= this.ValidateDeclarationNameConflictsInScope(localSymbol, localDiagnostics); EqualsValueClauseSyntax equalsValueClauseSyntax = declarator.Initializer; if (isVar) { aliasOpt = null; var binder = new ImplicitlyTypedLocalBinder(this, localSymbol); initializerOpt = binder.BindInferredVariableInitializer(localDiagnostics, equalsValueClauseSyntax, declarator); // If we got a good result then swap the inferred type for the "var" if ((object)initializerOpt?.Type != null) { declTypeOpt = initializerOpt.Type; if (declTypeOpt.SpecialType == SpecialType.System_Void) { Error(localDiagnostics, ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, declarator, declTypeOpt); declTypeOpt = CreateErrorType("var"); hasErrors = true; } if (!declTypeOpt.IsErrorType()) { if (declTypeOpt.IsStatic) { Error(localDiagnostics, ErrorCode.ERR_VarDeclIsStaticClass, typeSyntax, initializerOpt.Type); hasErrors = true; } } } else { declTypeOpt = CreateErrorType("var"); hasErrors = true; } } else { if (ReferenceEquals(equalsValueClauseSyntax, null)) { initializerOpt = null; } else { // Basically inlined BindVariableInitializer, but with conversion optional. initializerOpt = BindPossibleArrayInitializer(equalsValueClauseSyntax.Value, declTypeOpt, localDiagnostics); if (kind != LocalDeclarationKind.FixedVariable) { // If this is for a fixed statement, we'll do our own conversion since there are some special cases. initializerOpt = GenerateConversionForAssignment(declTypeOpt, initializerOpt, localDiagnostics); } } } Debug.Assert((object)declTypeOpt != null); if (kind == LocalDeclarationKind.FixedVariable) { // NOTE: this is an error, but it won't prevent further binding. if (isVar) { if (!hasErrors) { Error(localDiagnostics, ErrorCode.ERR_ImplicitlyTypedLocalCannotBeFixed, declarator); hasErrors = true; } } if (!declTypeOpt.IsPointerType()) { if (!hasErrors) { Error(localDiagnostics, ErrorCode.ERR_BadFixedInitType, declarator); hasErrors = true; } } else if (!IsValidFixedVariableInitializer(declTypeOpt, localSymbol, ref initializerOpt, localDiagnostics)) { hasErrors = true; } } if (this.ContainingMemberOrLambda.Kind == SymbolKind.Method && ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync && declTypeOpt.IsRestrictedType()) { Error(localDiagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declTypeOpt); hasErrors = true; } DeclareLocalVariable( localSymbol, declarator.Identifier, declTypeOpt); Debug.Assert((object)localSymbol != null); ImmutableArray<BoundExpression> arguments = BindDeclaratorArguments(declarator, localDiagnostics); if (kind == LocalDeclarationKind.FixedVariable || kind == LocalDeclarationKind.UsingVariable) { // CONSIDER: The error message is "you must provide an initializer in a fixed // CONSIDER: or using declaration". The error message could be targetted to // CONSIDER: the actual situation. "you must provide an initializer in a // CONSIDER: 'fixed' declaration." if (initializerOpt == null) { Error(localDiagnostics, ErrorCode.ERR_FixedMustInit, declarator); hasErrors = true; } } else if (kind == LocalDeclarationKind.Constant && initializerOpt != null && !localDiagnostics.HasAnyResolvedErrors()) { var constantValueDiagnostics = localSymbol.GetConstantValueDiagnostics(initializerOpt); foreach (var diagnostic in constantValueDiagnostics) { diagnostics.Add(diagnostic); hasErrors = true; } } diagnostics.AddRangeAndFree(localDiagnostics); var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declTypeOpt); return new BoundLocalDeclaration(associatedSyntaxNode, localSymbol, boundDeclType, initializerOpt, arguments, hasErrors); }
public PossibleOutVarLocalSymbol( Symbol containingSymbol, Binder binder, RefKind refKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind) : base(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind) { #if DEBUG ArgumentSyntax argument; Debug.Assert(ArgumentSyntax.IsIdentifierOfOutVariableDeclaration(identifierToken, out argument)); Debug.Assert(argument.Parent.Parent is ConstructorInitializerSyntax ? binder.ScopeDesignator == argument.Parent : binder.ScopeDesignator.Contains(argument.Parent.Parent)); #endif }
/// <summary> /// Make a local variable symbol whose type can be inferred (if necessary) by binding and enclosing construct. /// </summary> internal static LocalSymbol MakeLocalSymbolWithEnclosingContext( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone) { Debug.Assert( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ArgumentList && nodeToBind.Parent is ConstructorInitializerSyntax || nodeToBind.Kind() == SyntaxKind.VariableDeclarator && new[] { SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement, SyntaxKind.UsingStatement, SyntaxKind.FixedStatement }. Contains(nodeToBind.Ancestors().OfType<StatementSyntax>().First().Kind()) || nodeToBind is ExpressionSyntax); return typeSyntax.IsVar ? new LocalSymbolWithEnclosingContext(containingSymbol, scopeBinder, nodeBinder, typeSyntax, identifierToken, kind, nodeToBind, forbiddenZone) : new SourceLocalSymbol(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, kind); }
public static SourceLocalSymbol MakeLocal( Symbol containingSymbol, Binder binder, RefKind refKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, EqualsValueClauseSyntax initializer = null) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); if (initializer == null) { ArgumentSyntax argument; if (ArgumentSyntax.IsIdentifierOfOutVariableDeclaration(identifierToken, out argument)) { if (argument.Type.IsVar) { return new PossibleOutVarLocalSymbol(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind); } } return new SourceLocalSymbol(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind); } return new LocalWithInitializer(containingSymbol, binder, refKind, typeSyntax, identifierToken, initializer, declarationKind); }
/// <summary> /// Make a local variable symbol which can be inferred (if necessary) by binding its initializing expression. /// </summary> /// <param name="containingSymbol"></param> /// <param name="scopeBinder"> /// Binder that owns the scope for the local, the one that returns it in its <see cref="Binder.Locals"/> array. /// </param> /// <param name="allowRefKind"></param> /// <param name="typeSyntax"></param> /// <param name="identifierToken"></param> /// <param name="declarationKind"></param> /// <param name="initializer"></param> /// <param name="initializerBinderOpt"> /// Binder that should be used to bind initializer, if different from the <paramref name="scopeBinder"/>. /// </param> /// <returns></returns> public static SourceLocalSymbol MakeLocal( Symbol containingSymbol, Binder scopeBinder, bool allowRefKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, EqualsValueClauseSyntax initializer = null, Binder initializerBinderOpt = null) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); return (initializer != null) ? new LocalWithInitializer(containingSymbol, scopeBinder, typeSyntax, identifierToken, initializer, initializerBinderOpt ?? scopeBinder, declarationKind) : new SourceLocalSymbol(containingSymbol, scopeBinder, allowRefKind, typeSyntax, identifierToken, declarationKind); }
public static SourceLocalSymbol MakeLocal( Symbol containingSymbol, Binder binder, RefKind refKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind, EqualsValueClauseSyntax initializer = null) { Debug.Assert(declarationKind != LocalDeclarationKind.ForEachIterationVariable); if (initializer == null) { DeclarationExpressionSyntax declarationExpression; if (identifierToken.IsIdentifierOfOutVariableDeclaration(out declarationExpression)) { if (declarationExpression.Type().IsVar) { return new PossiblyImplicitlyTypedOutVarLocalSymbol(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind); } } return new SourceLocalSymbol(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind); } return new LocalWithInitializer(containingSymbol, binder, refKind, typeSyntax, identifierToken, initializer, declarationKind); }
internal BoundStatement BindForOrUsingOrFixedDeclarations(VariableDeclarationSyntax nodeOpt, LocalDeclarationKind localKind, DiagnosticBag diagnostics, out ImmutableArray<BoundLocalDeclaration> declarations) { if (nodeOpt == null) { declarations = ImmutableArray<BoundLocalDeclaration>.Empty; return null; } var typeSyntax = nodeOpt.Type; AliasSymbol alias; bool isVar; TypeSymbol declType = BindType(typeSyntax, diagnostics, out isVar, out alias); Debug.Assert((object)declType != null || isVar); var variables = nodeOpt.Variables; int count = variables.Count; Debug.Assert(count > 0); if (isVar && count > 1) { // There are a number of ways in which a var decl can be illegal, but in these // cases we should report an error and then keep right on going with the inference. Error(diagnostics, ErrorCode.ERR_ImplicitlyTypedVariableMultipleDeclarator, nodeOpt); } var declarationArray = new BoundLocalDeclaration[count]; for (int i = 0; i < count; i++) { var variableDeclarator = variables[i]; var declaration = BindVariableDeclaration(localKind, isVar, variableDeclarator, typeSyntax, declType, alias, diagnostics); declarationArray[i] = declaration; } declarations = declarationArray.AsImmutableOrNull(); return (count == 1) ? (BoundStatement)declarations[0] : new BoundMultipleLocalDeclarations(nodeOpt, declarations); }
public PossiblyImplicitlyTypedOutVarLocalSymbol( Symbol containingSymbol, Binder binder, RefKind refKind, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind declarationKind) : base(containingSymbol, binder, refKind, typeSyntax, identifierToken, declarationKind) { #if DEBUG DeclarationExpressionSyntax declarationExpression; Debug.Assert(identifierToken.IsIdentifierOfOutVariableDeclaration(out declarationExpression)); Debug.Assert(declarationExpression.Parent.Parent.Parent is ConstructorInitializerSyntax ? binder.ScopeDesignator == declarationExpression.Parent.Parent : binder.ScopeDesignator.Contains(declarationExpression.Parent.Parent.Parent)); #endif }
public PossibleOutVarLocalWithoutInitializer( Symbol containingSymbol, Binder binder, TypeSyntax typeSyntax, SyntaxToken identifierToken, CSharpSyntaxNode scopeSegmentRoot, LocalDeclarationKind declarationKind) : base(containingSymbol, binder, typeSyntax, identifierToken, declarationKind) { Debug.Assert(identifierToken.Parent.CSharpKind() == SyntaxKind.VariableDeclarator && ((VariableDeclaratorSyntax)identifierToken.Parent).Identifier == identifierToken); Debug.Assert(identifierToken.Parent.Parent.CSharpKind() == SyntaxKind.DeclarationExpression); if (scopeSegmentRoot == null) { throw ExceptionUtilities.Unreachable; } this.scopeSegmentRoot = scopeSegmentRoot; }