internal override SymbolInfo GetSymbolInfoWorker(LanguageSyntaxNode node, SymbolInfoOptions options, CancellationToken cancellationToken = default(CancellationToken))
        {
            ValidateSymbolInfoOptions(options);

            // in case this is right side of a qualified name or member access (or part of a cref)
            node = SyntaxFactory.GetStandaloneNode(node);

            var        model = this.GetMemberModel(node);
            SymbolInfo result;

            if (model != null)
            {
                // Expression occurs in an executable code (method body or initializer) context. Use that
                // model to get the information.
                result = model.GetSymbolInfoWorker(node, options, cancellationToken);

                // If we didn't get anything and were in Type/Namespace only context, let's bind normally and see
                // if any symbol comes out.
                if ((object)result.Symbol == null && result.CandidateReason == CandidateReason.None && this.Language.SyntaxFacts.IsInNamespaceOrTypeContext(node))
                {
                    var binder = this.GetEnclosingBinder(GetAdjustedNodePosition(node));

                    if (binder != null)
                    {
                        // Wrap the binder in a LocalScopeBinder because Binder.BindExpression assumes there
                        // will be one in the binder chain and one isn't necessarily required for the batch case.
                        binder = new LocalScopeBinder(binder);

                        BoundExpression bound = binder.BindExpression(node, _boundTree);

                        SymbolInfo info = GetSymbolInfoForNode(options, bound, bound, boundNodeForSyntacticParent: null, binderOpt: null);
                        if ((object)info.Symbol != null)
                        {
                            result = new SymbolInfo(null, ImmutableArray.Create <ISymbol>(info.Symbol), CandidateReason.NotATypeOrNamespace);
                        }
                        else if (!info.CandidateSymbols.IsEmpty)
                        {
                            result = new SymbolInfo(null, info.CandidateSymbols, CandidateReason.NotATypeOrNamespace);
                        }
                    }
                }
            }
            else
            {
                // if expression is not part of a member context then caller may really just have a
                // reference to a type or namespace name
                var symbol = GetSemanticInfoSymbolInNonMemberContext(node, bindVarAsAliasFirst: (options & SymbolInfoOptions.PreserveAliases) != 0);
                result = (object)symbol != null?GetSymbolInfoForSymbol(symbol, options) : SymbolInfo.None;
            }

            return(result);
        }
 private static BoundExpression BindFieldOrEnumInitializer(
     Binder binder,
     FieldSymbol fieldSymbol,
     EqualsValueClauseSyntax initializer,
     DiagnosticBag diagnostics)
 {
     var enumConstant = fieldSymbol as SourceEnumConstantSymbol;
     var collisionDetector = new LocalScopeBinder(binder);
     if ((object)enumConstant != null)
     {
         return collisionDetector.BindEnumConstantInitializer(enumConstant, initializer.Value, diagnostics);
     }
     else
     {
         return collisionDetector.BindVariableOrAutoPropInitializer(initializer, fieldSymbol.Type, diagnostics);
     }
 }
Exemplo n.º 3
0
        private static BoundExpression BindFieldOrEnumInitializer(
            Binder binder,
            FieldSymbol fieldSymbol,
            EqualsValueClauseSyntax initializer,
            DiagnosticBag diagnostics)
        {
            var enumConstant      = fieldSymbol as SourceEnumConstantSymbol;
            var collisionDetector = new LocalScopeBinder(binder);

            if ((object)enumConstant != null)
            {
                return(collisionDetector.BindEnumConstantInitializer(enumConstant, initializer.Value, diagnostics));
            }
            else
            {
                return(collisionDetector.BindVariableOrAutoPropInitializer(initializer, fieldSymbol.Type, diagnostics));
            }
        }
Exemplo n.º 4
0
        private static BoundFieldEqualsValue BindFieldOrEnumInitializer(
            Binder binder,
            FieldSymbol fieldSymbol,
            EqualsValueClauseSyntax initializer,
            BindingDiagnosticBag diagnostics)
        {
            var    enumConstant      = fieldSymbol as SourceEnumConstantSymbol;
            Binder collisionDetector = new LocalScopeBinder(binder);

            collisionDetector = new ExecutableCodeBinder(initializer, fieldSymbol, collisionDetector);
            BoundFieldEqualsValue result;

            if ((object)enumConstant != null)
            {
                result = collisionDetector.BindEnumConstantInitializer(enumConstant, initializer, diagnostics);
            }
            else
            {
                result = collisionDetector.BindFieldInitializer(fieldSymbol, initializer, diagnostics);
            }

            return(result);
        }
Exemplo n.º 5
0
        private static BoundExpression BindFieldOrEnumInitializer(
            Binder binder,
            FieldSymbol fieldSymbol,
            EqualsValueClauseSyntax initializer,
            DiagnosticBag diagnostics)
        {
            var    enumConstant      = fieldSymbol as SourceEnumConstantSymbol;
            Binder collisionDetector = new LocalScopeBinder(binder);

            collisionDetector = new ExecutableCodeBinder(initializer, fieldSymbol, collisionDetector);
            BoundExpression result;

            if ((object)enumConstant != null)
            {
                result = collisionDetector.BindEnumConstantInitializer(enumConstant, initializer, diagnostics);
            }
            else
            {
                result = collisionDetector.BindVariableOrAutoPropInitializer(initializer, RefKind.None, fieldSymbol.Type, diagnostics);
            }

            return(result);
        }
            internal RangeVariableSymbol AddRangeVariable(Binder binder, SyntaxToken identifier, DiagnosticBag diagnostics)
            {
                string name = identifier.ValueText;
                var result = new RangeVariableSymbol(name, binder.ContainingMemberOrLambda, identifier.GetLocation());
                bool error = false;

                foreach (var existingRangeVariable in allRangeVariables.Keys)
                {
                    if (existingRangeVariable.Name == name)
                    {
                        diagnostics.Add(ErrorCode.ERR_QueryDuplicateRangeVariable, identifier.GetLocation(), name);
                        error = true;
                    }
                }

                if (!error)
                {
                    var collisionDetector = new LocalScopeBinder(binder);
                    collisionDetector.ValidateDeclarationNameConflictsInScope(result, diagnostics);
                }

                allRangeVariables.Add(result, ArrayBuilder<string>.GetInstance());
                return result;
            }
        internal override SymbolInfo GetSymbolInfoWorker(CSharpSyntaxNode node, SymbolInfoOptions options, CancellationToken cancellationToken = default(CancellationToken))
        {
            ValidateSymbolInfoOptions(options);

            // in case this is right side of a qualified name or member access (or part of a cref)
            node = SyntaxFactory.GetStandaloneNode(node);

            var model = this.GetMemberModel(node);
            SymbolInfo result;

            XmlNameAttributeSyntax attrSyntax;
            CrefSyntax crefSyntax;

            if (model != null)
            {
                // Expression occurs in an executable code (method body or initializer) context. Use that
                // model to get the information.
                result = model.GetSymbolInfoWorker(node, options, cancellationToken);

                // If we didn't get anything and were in Type/Namespace only context, let's bind normally and see
                // if any symbol comes out.
                if ((object)result.Symbol == null && result.CandidateReason == CandidateReason.None && node is ExpressionSyntax && SyntaxFacts.IsInNamespaceOrTypeContext((ExpressionSyntax)node))
                {
                    var binder = this.GetEnclosingBinder(GetAdjustedNodePosition(node));

                    if (binder != null)
                    {
                        // Wrap the binder in a LocalScopeBinder because Binder.BindExpression assumes there
                        // will be one in the binder chain and one isn't necessarily required for the batch case.
                        binder = new LocalScopeBinder(binder);

                        var diagnostics = DiagnosticBag.GetInstance();
                        BoundExpression bound = binder.BindExpression((ExpressionSyntax)node, diagnostics);
                        diagnostics.Free();

                        SymbolInfo info = GetSymbolInfoForNode(options, bound, bound, boundNodeForSyntacticParent: null, binderOpt: null);
                        if ((object)info.Symbol != null)
                        {
                            result = new SymbolInfo(null, ImmutableArray.Create<ISymbol>(info.Symbol), CandidateReason.NotATypeOrNamespace);
                        }
                        else if (!info.CandidateSymbols.IsEmpty)
                        {
                            result = new SymbolInfo(null, info.CandidateSymbols, CandidateReason.NotATypeOrNamespace);
                        }
                    }
                }
            }
            else if (node.Parent.Kind() == SyntaxKind.XmlNameAttribute && (attrSyntax = (XmlNameAttributeSyntax)node.Parent).Identifier == node)
            {
                result = SymbolInfo.None;

                var binder = this.GetEnclosingBinder(GetAdjustedNodePosition(node));
                if (binder != null)
                {
                    HashSet<DiagnosticInfo> useSiteDiagnostics = null;
                    var symbols = binder.BindXmlNameAttribute(attrSyntax, ref useSiteDiagnostics);

                    // NOTE: We don't need to call GetSymbolInfoForSymbol because the symbols
                    // can only be parameters or type parameters.
                    Debug.Assert(symbols.All(s => s.Kind == SymbolKind.TypeParameter || s.Kind == SymbolKind.Parameter));

                    switch (symbols.Length)
                    {
                        case 0:
                            result = SymbolInfo.None;
                            break;
                        case 1:
                            result = SymbolInfoFactory.Create(symbols, LookupResultKind.Viable, isDynamic: false);
                            break;
                        default:
                            result = SymbolInfoFactory.Create(symbols, LookupResultKind.Ambiguous, isDynamic: false);
                            break;
                    }
                }
            }
            else if ((crefSyntax = node as CrefSyntax) != null)
            {
                int adjustedPosition = GetAdjustedNodePosition(crefSyntax);
                result = GetCrefSymbolInfo(adjustedPosition, crefSyntax, options, HasParameterList(crefSyntax));
            }
            else
            {
                // if expression is not part of a member context then caller may really just have a
                // reference to a type or namespace name
                var symbol = GetSemanticInfoSymbolInNonMemberContext(node, bindVarAsAliasFirst: (options & SymbolInfoOptions.PreserveAliases) != 0);
                result = (object)symbol != null ? GetSymbolInfoForSymbol(symbol, options) : SymbolInfo.None;
            }

            return result;
        }
Exemplo n.º 8
0
        private static BoundFieldInitializer BindFieldInitializer(Binder binder, FieldSymbol fieldSymbol, EqualsValueClauseSyntax equalsValueClauseNode,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(!fieldSymbol.IsMetadataConstant);

            var fieldsBeingBound = binder.FieldsBeingBound;

            var sourceField = fieldSymbol as SourceMemberFieldSymbol;
            bool isImplicitlyTypedField = (object)sourceField != null && sourceField.FieldTypeInferred(fieldsBeingBound);

            // If the type is implicitly typed, the initializer diagnostics have already been reported, so ignore them here:
            // CONSIDER (tomat): reusing the bound field initializers for implicitly typed fields.
            DiagnosticBag initializerDiagnostics;
            if (isImplicitlyTypedField)
            {
                initializerDiagnostics = DiagnosticBag.GetInstance();
            }
            else
            {
                initializerDiagnostics = diagnostics;
            }

            var collisionDetector = new LocalScopeBinder(binder);
            var boundInitValue = collisionDetector.BindVariableOrAutoPropInitializer(equalsValueClauseNode, fieldSymbol.GetFieldType(fieldsBeingBound), initializerDiagnostics);

            if (isImplicitlyTypedField)
            {
                initializerDiagnostics.Free();
            }

            return new BoundFieldInitializer(
                equalsValueClauseNode.Value, //we want the attached sequence point to indicate the value node
                fieldSymbol,
                boundInitValue);
        }
Exemplo n.º 9
0
        /// <summary>
        /// In script C#, some field initializers are assignments to fields and others are global
        /// statements.  There are no restrictions on accessing instance members.
        /// </summary>
        private static void BindScriptFieldInitializers(CSharpCompilation compilation, MethodSymbol scriptCtor,
            ImmutableArray<ImmutableArray<FieldInitializer>> initializers, ArrayBuilder<BoundInitializer> boundInitializers, DiagnosticBag diagnostics,
            bool generateDebugInfo, out ConsList<Imports> firstDebugImports)
        {
            Debug.Assert((object)scriptCtor != null);

            firstDebugImports = null;

            for (int i = 0; i < initializers.Length; i++)
            {
                ImmutableArray<FieldInitializer> siblingInitializers = initializers[i];

                // All sibling initializers share the same parent node and tree so we can reuse the binder 
                // factory across siblings.  Unfortunately, we cannot reuse the binder itself, because
                // individual fields might have their own binders (e.g. because of being declared unsafe).
                BinderFactory binderFactory = null;

                for (int j = 0; j < siblingInitializers.Length; j++)
                {
                    var initializer = siblingInitializers[j];
                    var fieldSymbol = initializer.Field;

                    if ((object)fieldSymbol != null && fieldSymbol.IsConst)
                    {
                        // Constants do not need field initializers.
                        continue;
                    }

                    var syntaxRef = initializer.Syntax;
                    Debug.Assert(syntaxRef.SyntaxTree.Options.Kind != SourceCodeKind.Regular);

                    var initializerNode = (CSharpSyntaxNode)syntaxRef.GetSyntax();

                    if (binderFactory == null)
                    {
                        binderFactory = compilation.GetBinderFactory(syntaxRef.SyntaxTree);
                    }

                    Binder scriptClassBinder = binderFactory.GetBinder(initializerNode);
                    Debug.Assert(((ImplicitNamedTypeSymbol)scriptClassBinder.ContainingMemberOrLambda).IsScriptClass);

                    if (generateDebugInfo && firstDebugImports == null)
                    {
                        firstDebugImports = scriptClassBinder.ImportsList;
                    }

                    Binder parentBinder = new ExecutableCodeBinder((CSharpSyntaxNode)syntaxRef.SyntaxTree.GetRoot(), scriptCtor, scriptClassBinder);

                    BoundInitializer boundInitializer;
                    if ((object)fieldSymbol != null)
                    {
                        boundInitializer = BindFieldInitializer(
                            new LocalScopeBinder(parentBinder).WithAdditionalFlagsAndContainingMemberOrLambda(parentBinder.Flags | BinderFlags.FieldInitializer, fieldSymbol),
                            fieldSymbol,
                            (EqualsValueClauseSyntax)initializerNode,
                            diagnostics);
                    }
                    else if (initializerNode.Kind == SyntaxKind.LabeledStatement)
                    {
                        // TODO: labels in interactive
                        var boundStatement = new BoundBadStatement(initializerNode, ImmutableArray<BoundNode>.Empty, true);
                        boundInitializer = new BoundGlobalStatementInitializer(initializerNode, boundStatement);
                    }
                    else
                    {
                        var collisionDetector = new LocalScopeBinder(parentBinder);
                        boundInitializer = BindGlobalStatement(collisionDetector, (StatementSyntax)initializerNode, diagnostics,
                            isLast: i == initializers.Length - 1 && j == siblingInitializers.Length - 1);
                    }

                    boundInitializers.Add(boundInitializer);
                }
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// In regular C#, all field initializers are assignments to fields and the assigned expressions
        /// may not reference instance members.
        /// </summary>
        internal static void BindRegularCSharpFieldInitializers(
            CSharpCompilation compilation,
            ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> initializers,
            ArrayBuilder<BoundInitializer> boundInitializers,
            DiagnosticBag diagnostics,
            out ImportChain firstDebugImports)
        {
            firstDebugImports = null;

            foreach (ImmutableArray<FieldOrPropertyInitializer> siblingInitializers in initializers)
            {
                // All sibling initializers share the same parent node and tree so we can reuse the binder 
                // factory across siblings.  Unfortunately, we cannot reuse the binder itself, because
                // individual fields might have their own binders (e.g. because of being declared unsafe).
                BinderFactory binderFactory = null;

                foreach (FieldOrPropertyInitializer initializer in siblingInitializers)
                {
                    FieldSymbol fieldSymbol = initializer.FieldOpt;
                    Debug.Assert((object)fieldSymbol != null);

                    // A constant field of type decimal needs a field initializer, so
                    // check if it is a metadata constant, not just a constant to exclude
                    // decimals. Other constants do not need field initializers.
                    if (!fieldSymbol.IsMetadataConstant)
                    {
                        //Can't assert that this is a regular C# compilation, because we could be in a nested type of a script class.
                        SyntaxReference syntaxRef = initializer.Syntax;
                        var initializerNode = (EqualsValueClauseSyntax)syntaxRef.GetSyntax();

                        if (binderFactory == null)
                        {
                            binderFactory = compilation.GetBinderFactory(syntaxRef.SyntaxTree);
                        }

                        Binder parentBinder = binderFactory.GetBinder(initializerNode);
                        Debug.Assert(parentBinder.ContainingMemberOrLambda == fieldSymbol.ContainingType || //should be the binder for the type
                                fieldSymbol.ContainingType.IsImplicitClass); //however, we also allow fields in namespaces to help support script scenarios

                        if (firstDebugImports == null)
                        {
                            firstDebugImports = parentBinder.ImportChain;
                        }

                        parentBinder = new LocalScopeBinder(parentBinder).WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.FieldInitializer, fieldSymbol);

                        BoundFieldInitializer boundInitializer = BindFieldInitializer(parentBinder, fieldSymbol, initializerNode, diagnostics);
                        boundInitializers.Add(boundInitializer);
                    }
                }
            }
        }
Exemplo n.º 11
0
        private UnboundLambda BindAnonymousFunction(CSharpSyntaxNode syntax, DiagnosticBag diagnostics)
        {
            Debug.Assert(syntax != null);
            Debug.Assert(syntax.IsAnonymousFunction());

            var results = AnalyzeAnonymousFunction(syntax, diagnostics);

            var refKinds = results.Item1;
            var types = results.Item2;
            var names = results.Item3;
            var isAsync = results.Item4;

            if (!types.IsDefault)
            {
                foreach (var type in types)
                {
                    // UNDONE: Where do we report improper use of pointer types?
                    if ((object)type != null && type.IsStatic)
                    {
                        Error(diagnostics, ErrorCode.ERR_ParameterIsStaticClass, syntax, type);
                    }
                }
            }

            var lambda = new UnboundLambda(syntax, this, refKinds, types, names, isAsync);

            if (!names.IsDefault)
            {
                var binder = new LocalScopeBinder(this.ContainingMemberOrLambda as MethodSymbol, this);
                for (int n = 0; n < names.Length; ++n)
                {
                    string name = lambda.ParameterName(n);
                    binder.ValidateLambdaParameterNameConflictsInScope(lambda.ParameterLocation(n), name, diagnostics);
                }
            }

            return lambda;
        }
Exemplo n.º 12
0
        private Binder GetFieldOrPropertyInitializerBinder(FieldSymbol symbol, Binder outer, EqualsValueClauseSyntax initializer)
        {
            BinderFlags flags = BinderFlags.None;

            // NOTE: checking for a containing script class is sufficient, but the regular C# test is quick and easy.
            if (this.IsRegularCSharp || !symbol.ContainingType.IsScriptClass)
            {
                flags |= BinderFlags.FieldInitializer;
            }

            outer = new LocalScopeBinder(outer).WithAdditionalFlagsAndContainingMemberOrLambda(flags, symbol);

            if (initializer != null)
            {
                outer = new ExecutableCodeBinder(initializer, symbol, outer);
            }

            return outer;
        }
Exemplo n.º 13
0
        public static ImmutableArray<ParameterSymbol> MakeParameters(
            Binder binder,
            Symbol owner,
            BaseParameterListSyntax syntax,
            bool allowRefOrOut,
            out SyntaxToken arglistToken,
            DiagnosticBag diagnostics)
        {
            arglistToken = default(SyntaxToken);

            int parameterIndex = 0;
            int firstDefault = -1;

            var builder = ArrayBuilder<ParameterSymbol>.GetInstance();
            ImmutableArray<ParameterSymbol> result;

            var parameterBinder = new LocalScopeBinder(binder);
            foreach (var parameterSyntax in syntax.Parameters)
            {

                SyntaxToken outKeyword;
                SyntaxToken refKeyword;
                SyntaxToken paramsKeyword;
                SyntaxToken thisKeyword;
                var refKind = GetModifiers(parameterSyntax.Modifiers, out outKeyword, out refKeyword, out paramsKeyword, out thisKeyword);

                if (parameterSyntax.IsArgList)
                {
                    arglistToken = parameterSyntax.Identifier;
                    // The native compiler produces "Expected type" here, in the parser. Roslyn produces
                    // the somewhat more informative "arglist not valid" error.
                    if (paramsKeyword.CSharpKind() != SyntaxKind.None || outKeyword.CSharpKind() != SyntaxKind.None ||
                        refKeyword.CSharpKind() != SyntaxKind.None || thisKeyword.CSharpKind() != SyntaxKind.None)
                    {
                        // CS1669: __arglist is not valid in this context
                        diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, arglistToken.GetLocation());
                    }
                    continue;
                }

                if (parameterSyntax.Default != null && firstDefault == -1)
                {
                    firstDefault = parameterIndex;
                }

                Debug.Assert(parameterSyntax.Type != null);
                var parameterType = binder.BindType(parameterSyntax.Type, diagnostics);

                if (!allowRefOrOut && (refKind != RefKind.None))
                {
                    var outOrRefKeyword = (outKeyword.CSharpKind() != SyntaxKind.None) ? outKeyword : refKeyword;
                    Debug.Assert(outOrRefKeyword.CSharpKind() != SyntaxKind.None);

                    // error CS0631: ref and out are not valid in this context
                    diagnostics.Add(ErrorCode.ERR_IllegalRefParam, outOrRefKeyword.GetLocation());
                }

                var parameter = SourceParameterSymbol.Create(
                    binder,
                    owner,
                    parameterType,
                    parameterSyntax,
                    refKind,
                    parameterSyntax.Identifier,
                    parameterIndex,
                    (paramsKeyword.CSharpKind() != SyntaxKind.None),
                    parameterIndex == 0 && thisKeyword.CSharpKind() != SyntaxKind.None,
                    diagnostics);

                ReportParameterErrors(owner, parameterSyntax, parameter, firstDefault, diagnostics);

                builder.Add(parameter);
                ++parameterIndex;
            }

            result = builder.ToImmutableAndFree();
            parameterBinder.EnterParameters(owner as MethodSymbol, result, diagnostics);
            return result;
        }
Exemplo n.º 14
0
        internal static ImmutableArray<LocalSymbol> GetFieldInitializerInfos(
            CSharpCompilation compilation,
            FieldInitializers siblingInitializers,
            ArrayBuilder<FieldInitializerInfo> infos,
            bool generateDebugInfo,
            ref ConsList<Imports> firstDebugImports)
        {
            // All sibling initializers share the same parent node and tree so we can reuse the binder 
            // factory across siblings.  Unfortunately, we cannot reuse the binder itself, because
            // individual fields might have their own binders (e.g. because of being declared unsafe).
            BinderFactory binderFactory = null;

            foreach (FieldInitializer initializer in siblingInitializers.Initializers)
            {
                FieldSymbol fieldSymbol = initializer.Field;
                Debug.Assert((object)fieldSymbol != null);

                // A constant field of type decimal needs a field initializer, so
                // check if it is a metadata constant, not just a constant to exclude
                // decimals. Other constants do not need field initializers.
                if (!fieldSymbol.IsMetadataConstant)
                {
                    //Can't assert that this is a regular C# compilation, because we could be in a nested type of a script class.
                    SyntaxReference syntaxRef = initializer.Syntax;
                    var initializerNode = (EqualsValueClauseSyntax)syntaxRef.GetSyntax();

                    if (binderFactory == null)
                    {
                        binderFactory = compilation.GetBinderFactory(syntaxRef.SyntaxTree);
                    }

                    Binder parentBinder = binderFactory.GetBinder(initializerNode);
                    Debug.Assert(parentBinder.ContainingMemberOrLambda == fieldSymbol.ContainingType || //should be the binder for the type
                            fieldSymbol.ContainingType.IsImplicitClass); //however, we also allow fields in namespaces to help support script scenarios

                    if (generateDebugInfo && firstDebugImports == null)
                    {
                        firstDebugImports = parentBinder.ImportsList;
                    }

                    parentBinder = new LocalScopeBinder(parentBinder).WithAdditionalFlagsAndContainingMemberOrLambda(parentBinder.Flags | BinderFlags.FieldInitializer, fieldSymbol);

                    if (!fieldSymbol.IsConst && !fieldSymbol.IsStatic)
                    {
                        parentBinder = parentBinder.WithPrimaryConstructorParametersIfNecessary(fieldSymbol.ContainingType);
                    }

                    infos.Add(new FieldInitializerInfo(initializer, parentBinder, initializerNode));
                }
            }

            // See if there are locals that we need to bring into the scope.
            var locals = default(ImmutableArray<LocalSymbol>);
            if (siblingInitializers.TypeDeclarationSyntax != null)
            {
                locals = GetInitializationScopeLocals(infos);

                if (!locals.IsDefaultOrEmpty)
                {
                    for (int i = 0; i < infos.Count; i++)
                    {
                        FieldInitializerInfo info = infos[i];

                        // Constant initializers is not part of the initialization scope.
                        if (!info.Initializer.Field.IsConst)
                        {
                            infos[i] = new FieldInitializerInfo(info.Initializer,
                                                                new SimpleLocalScopeBinder(locals, info.Binder),
                                                                info.EqualsValue);
                        }
                    }
                }
            }

            return locals;
        }
        private UnboundLambda BindAnonymousFunction(CSharpSyntaxNode syntax, DiagnosticBag diagnostics)
        {
            Debug.Assert(syntax != null);
            Debug.Assert(syntax.IsAnonymousFunction());

            var results = AnalyzeAnonymousFunction(syntax, diagnostics);

            var refKinds = results.Item1;
            var types = results.Item2;
            var names = results.Item3;
            var isAsync = results.Item4;

            if (!types.IsDefault)
            {
                foreach (var type in types)
                {
                    // UNDONE: Where do we report improper use of pointer types?
                    if ((object)type != null && type.IsStatic)
                    {
                        Error(diagnostics, ErrorCode.ERR_ParameterIsStaticClass, syntax, type);
                    }
                }
            }

            var lambda = new UnboundLambda(syntax, this, refKinds, types, names, isAsync);
            if (!names.IsDefault)
            {
               var binder = new LocalScopeBinder(this);
                var pNames = PooledHashSet<string>.GetInstance();

                for (int i = 0; i < lambda.ParameterCount; i ++)
                {
                    var name = lambda.ParameterName(i);

                    if (string.IsNullOrEmpty(name))
                    {
                        continue;
                    }

                    if (pNames.Contains(name))
                    {
                        // The parameter name '{0}' is a duplicate
                        diagnostics.Add(ErrorCode.ERR_DuplicateParamName, lambda.ParameterLocation(i), name);
                    }
                    else
                    {
                        pNames.Add(name);
                        binder.ValidateLambdaParameterNameConflictsInScope(lambda.ParameterLocation(i), name, diagnostics);
                    }
                }
                pNames.Free();
            }

            return lambda;
        }
Exemplo n.º 16
0
        public static ImmutableArray <ParameterSymbol> MakeParameters(
            Binder binder,
            Symbol owner,
            BaseParameterListSyntax syntax,
            bool allowRefOrOut,
            out SyntaxToken arglistToken,
            DiagnosticBag diagnostics)
        {
            arglistToken = default(SyntaxToken);

            int parameterIndex = 0;
            int firstDefault   = -1;

            var builder = ArrayBuilder <ParameterSymbol> .GetInstance();

            ImmutableArray <ParameterSymbol> result;

            var parameterBinder = new LocalScopeBinder(binder);

            foreach (var parameterSyntax in syntax.Parameters)
            {
                SyntaxToken outKeyword;
                SyntaxToken refKeyword;
                SyntaxToken paramsKeyword;
                SyntaxToken thisKeyword;
                var         refKind = GetModifiers(parameterSyntax.Modifiers, out outKeyword, out refKeyword, out paramsKeyword, out thisKeyword);

                if (parameterSyntax.IsArgList)
                {
                    arglistToken = parameterSyntax.Identifier;
                    // The native compiler produces "Expected type" here, in the parser. Roslyn produces
                    // the somewhat more informative "arglist not valid" error.
                    if (paramsKeyword.CSharpKind() != SyntaxKind.None || outKeyword.CSharpKind() != SyntaxKind.None ||
                        refKeyword.CSharpKind() != SyntaxKind.None || thisKeyword.CSharpKind() != SyntaxKind.None)
                    {
                        // CS1669: __arglist is not valid in this context
                        diagnostics.Add(ErrorCode.ERR_IllegalVarArgs, arglistToken.GetLocation());
                    }
                    continue;
                }

                if (parameterSyntax.Default != null && firstDefault == -1)
                {
                    firstDefault = parameterIndex;
                }

                Debug.Assert(parameterSyntax.Type != null);
                var parameterType = binder.BindType(parameterSyntax.Type, diagnostics);

                if (!allowRefOrOut && (refKind != RefKind.None))
                {
                    var outOrRefKeyword = (outKeyword.CSharpKind() != SyntaxKind.None) ? outKeyword : refKeyword;
                    Debug.Assert(outOrRefKeyword.CSharpKind() != SyntaxKind.None);

                    // error CS0631: ref and out are not valid in this context
                    diagnostics.Add(ErrorCode.ERR_IllegalRefParam, outOrRefKeyword.GetLocation());
                }

                var parameter = SourceParameterSymbol.Create(
                    binder,
                    owner,
                    parameterType,
                    parameterSyntax,
                    refKind,
                    parameterSyntax.Identifier,
                    parameterIndex,
                    (paramsKeyword.CSharpKind() != SyntaxKind.None),
                    parameterIndex == 0 && thisKeyword.CSharpKind() != SyntaxKind.None,
                    diagnostics);

                ReportParameterErrors(owner, parameterSyntax, parameter, firstDefault, diagnostics);

                builder.Add(parameter);
                ++parameterIndex;
            }

            result = builder.ToImmutableAndFree();
            parameterBinder.EnterParameters(owner as MethodSymbol, result, diagnostics);
            return(result);
        }