示例#1
0
            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;
            }
示例#2
0
 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;
 }
示例#3
0
 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
                ));
 }
示例#4
0
        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());
            }
        }
示例#5
0
        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;
        }
示例#6
0
        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
                       ));
        }
示例#7
0
        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());
            }
        }
示例#8
0
        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;
        }
示例#9
0
 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));
 }
示例#10
0
 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;
 }
示例#11
0
        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;
            }
        }
示例#12
0
 /// <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));
 }
示例#13
0
        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));
        }
示例#14
0
        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;
        }
示例#15
0
        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;
        }
示例#16
0
        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));
        }
示例#17
0
 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));
 }
示例#18
0
 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));
 }
示例#19
0
 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);
 }
示例#20
0
 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);
 }
示例#21
0
 public DeconstructionLocalSymbol(
     Symbol containingSymbol,
     Binder scopeBinder,
     TypeSyntax typeSyntax,
     SyntaxToken identifierToken,
     LocalDeclarationKind declarationKind,
     SyntaxNode deconstruction)
     : base(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, declarationKind)
 {
     _deconstruction = deconstruction;
 }
示例#22
0
 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));
 }
示例#23
0
 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));
 }
示例#24
0
 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);
 }
示例#25
0
 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;
 }
示例#26
0
 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));
 }
示例#27
0
 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;
 }
示例#28
0
 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;
 }
示例#29
0
 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;
 }
示例#30
0
        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);
        }
示例#31
0
 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)
 {
 }
示例#32
0
            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));
        }
示例#34
0
            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;
            }
示例#35
0
        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;
        }
示例#36
0
            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());
        }
示例#38
0
        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());
        }
示例#39
0
        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());
        }
示例#40
0
        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;
        }
示例#41
0
 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;
 }
示例#42
0
            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;
            }
示例#43
0
 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;
 }
示例#44
0
            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;
            }
示例#45
0
        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);
        }
示例#46
0
        /// <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);
        }
示例#47
0
 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);
 }
示例#48
0
 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);
 }
示例#49
0
        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);
            }
        }
示例#52
0
        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);
        }
示例#53
0
            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
            }
示例#54
0
 /// <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);
 }
示例#55
0
        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);
        }
示例#56
0
 /// <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);
 }
示例#57
0
        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);
        }
示例#58
0
        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);
        }
示例#59
0
            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
            }
示例#60
0
            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;
        }