Ejemplo n.º 1
0
        /// <summary>
        /// Creates a speculative AttributeSemanticModel that allows asking semantic questions about an attribute node that did not appear in the original source code.
        /// </summary>
        public static AttributeSemanticModel CreateSpeculative(SyntaxTreeSemanticModel parentSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, int position)
        {
            Debug.Assert(parentSemanticModel != null);
            Debug.Assert(rootBinder != null);
            Debug.Assert(rootBinder.IsSemanticModelBinder);

            return new AttributeSemanticModel(parentSemanticModel.Compilation, syntax, attributeType, aliasOpt, rootBinder, parentSemanticModel, position);
        }
Ejemplo n.º 2
0
 public AliasAndExternAliasDirective(
     AliasSymbol alias,
     ExternAliasDirectiveSyntax externAliasDirective
     )
 {
     this.Alias = alias;
     this.ExternAliasDirective = externAliasDirective;
 }
Ejemplo n.º 3
0
        private static void AddAliasSymbolToResult(LookupSymbolsInfo result, AliasSymbol aliasSymbol, LookupConstraints constraints)
        {
            var targetSymbol = aliasSymbol.GetAliasTarget(basesBeingResolved: null);

            if (constraints.OriginalBinder.CanAddLookupSymbolInfo(targetSymbol, result, constraints.WithAccessThroughType(null), aliasSymbol: aliasSymbol))
            {
                result.AddSymbol(aliasSymbol, aliasSymbol.Name, aliasSymbol.Name);
            }
        }
Ejemplo n.º 4
0
        private static void AddAliasSymbolToResult(LookupSymbolsInfo result, AliasSymbol aliasSymbol, LookupOptions options, Binder originalBinder)
        {
            var targetSymbol = aliasSymbol.GetAliasTarget(basesBeingResolved: null);

            if (originalBinder.CanAddLookupSymbolInfo(targetSymbol, options, result, accessThroughType: null, aliasSymbol: aliasSymbol))
            {
                result.AddSymbol(aliasSymbol, aliasSymbol.Name, 0);
            }
        }
Ejemplo n.º 5
0
        public void ConcatCollidingExternAliases()
        {
            var comp = CreateCompilation(
                "extern alias A; extern alias B;",
                targetFramework: TargetFramework.Mscorlib40,
                references: new[]
            {
                SystemCoreRef.WithAliases(new[] { "A" }),
                SystemDataRef.WithAliases(new[] { "B" }),
            }
                );

            var tree   = comp.SyntaxTrees.Single();
            var binder = comp.GetBinderFactory(tree)
                         .GetImportsBinder((CSharpSyntaxNode)tree.GetRoot(), inUsing: false);
            var scratchImports       = binder.GetImports(basesBeingResolved: null);
            var scratchExternAliases = scratchImports.ExternAliases;

            Assert.Equal(2, scratchExternAliases.Length);

            var externAlias1 = scratchExternAliases[0];
            var externAlias2 = new AliasAndExternAliasDirective(
                AliasSymbol.CreateCustomDebugInfoAlias(
                    scratchExternAliases[1].Alias.Target,
                    externAlias1.ExternAliasDirective.Identifier,
                    binder
                    ),
                externAlias1.ExternAliasDirective
                );

            var imports1 = Imports.FromCustomDebugInfo(
                comp,
                ImmutableDictionary <string, AliasAndUsingDirective> .Empty,
                ImmutableArray <NamespaceOrTypeAndUsingDirective> .Empty,
                ImmutableArray.Create(externAlias1)
                );

            var imports2 = Imports.FromCustomDebugInfo(
                comp,
                ImmutableDictionary <string, AliasAndUsingDirective> .Empty,
                ImmutableArray <NamespaceOrTypeAndUsingDirective> .Empty,
                ImmutableArray.Create(externAlias2)
                );

            var concat1 = imports1.Concat(imports2);

            Assert.Equal(externAlias2.Alias.Target, concat1.ExternAliases.Single().Alias.Target);

            var concat2 = imports2.Concat(imports1);

            Assert.Equal(externAlias1.Alias.Target, concat2.ExternAliases.Single().Alias.Target);
        }
Ejemplo n.º 6
0
 private AttributeSemanticModel(
     AttributeSyntax syntax,
     NamedTypeSymbol attributeType,
     AliasSymbol aliasOpt,
     Binder rootBinder,
     SyntaxTreeSemanticModel containingSemanticModelOpt = null,
     SyntaxTreeSemanticModel parentSemanticModelOpt     = null,
     int speculatedPosition = 0)
     : base(syntax, attributeType, new ExecutableCodeBinder(syntax, rootBinder.ContainingMember(), rootBinder), containingSemanticModelOpt, parentSemanticModelOpt, speculatedPosition)
 {
     Debug.Assert(syntax != null);
     _aliasOpt = aliasOpt;
 }
Ejemplo n.º 7
0
        private static TypeSymbol GetTypeSymbol(SingleMeaning meaning)
        {
            Symbol     symbol = meaning.Symbol;
            TypeSymbol type   = symbol as TypeSymbol;

            if ((object)type != null)
            {
                return(type);
            }

            AliasSymbol alias = symbol as AliasSymbol;

            return((object)alias == null ? null : alias.Target as TypeSymbol);
        }
 private AttributeSemanticModel(
     AttributeSyntax syntax,
     NamedTypeSymbol attributeType,
     AliasSymbol aliasOpt,
     Binder rootBinder,
     SyntaxTreeSemanticModel?containingSemanticModelOpt            = null,
     SyntaxTreeSemanticModel?parentSemanticModelOpt                = null,
     ImmutableDictionary <Symbol, Symbol>?parentRemappedSymbolsOpt = null,
     int speculatedPosition = 0)
     : base(syntax, attributeType, new ExecutableCodeBinder(syntax, rootBinder.ContainingMember(), rootBinder), containingSemanticModelOpt, parentSemanticModelOpt, snapshotManagerOpt: null, parentRemappedSymbolsOpt: parentRemappedSymbolsOpt, speculatedPosition)
 {
     Debug.Assert(syntax != null);
     _aliasOpt = aliasOpt;
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Creates an AttributeSemanticModel that allows asking semantic questions about an attribute node.
 /// </summary>
 public static AttributeSemanticModel Create(
     SyntaxTreeSemanticModel containingSemanticModel,
     AttributeSyntax syntax,
     NamedTypeSymbol attributeType,
     AliasSymbol aliasOpt,
     Binder rootBinder,
     ImmutableDictionary <Symbol, Symbol> parentRemappedSymbolsOpt
     )
 {
     return(new AttributeSemanticModel(
                syntax,
                attributeType,
                aliasOpt,
                rootBinder,
                containingSemanticModel,
                parentRemappedSymbolsOpt: parentRemappedSymbolsOpt
                ));
 }
Ejemplo n.º 10
0
        private static ImmutableArray <AliasAndExternAliasDirective> BuildExternAliases(
            ImmutableArray <ExternAliasDirective> directiveList,
            InContainerBinder binder,
            DiagnosticBag diagnostics)
        {
            LanguageCompilation compilation = binder.Compilation;
            SyntaxFacts         syntaxFacts = compilation.Language.SyntaxFacts;

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

            foreach (ExternAliasDirective aliasSyntax in directiveList)
            {
                compilation.RecordImport(aliasSyntax);

                // Extern aliases not allowed in interactive submissions:
                if (compilation.IsSubmission)
                {
                    diagnostics.Add(InternalErrorCode.ERR_ExternAliasNotAllowed, aliasSyntax.Location);
                    continue;
                }

                string aliasName = syntaxFacts.ExtractName(aliasSyntax.AliasName);
                // some n^2 action, but n should be very small.
                foreach (var existingAlias in builder)
                {
                    if (existingAlias.Alias.Name == aliasName)
                    {
                        diagnostics.Add(InternalErrorCode.ERR_DuplicateAlias, existingAlias.Alias.Locations[0], existingAlias.Alias.Name);
                        break;
                    }
                }

                /* TODO:MetaDslx?
                 * if (aliasSyntax.Identifier.ContextualKind() == SyntaxKind.GlobalKeyword)
                 * {
                 *  diagnostics.Add(InternalErrorCode.ERR_GlobalExternAlias, aliasSyntax.Identifier.GetLocation());
                 * }
                 */

                builder.Add(new AliasAndExternAliasDirective(AliasSymbol.CreateExternAlias(aliasName, aliasSyntax, binder), aliasSyntax));
            }

            return(builder.ToImmutableAndFree());
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Creates a speculative AttributeSemanticModel that allows asking semantic questions about an attribute node that did not appear in the original source code.
        /// </summary>
        public static AttributeSemanticModel CreateSpeculative(
            SyntaxTreeSemanticModel parentSemanticModel,
            AttributeSyntax syntax,
            NamedTypeSymbol attributeType,
            AliasSymbol aliasOpt,
            Binder rootBinder,
            ImmutableDictionary <Symbol, Symbol> parentRemappedSymbolsOpt,
            int position
            )
        {
            Debug.Assert(parentSemanticModel != null);
            Debug.Assert(rootBinder != null);
            Debug.Assert(rootBinder.IsSemanticModelBinder);

            return(new AttributeSemanticModel(
                       syntax,
                       attributeType,
                       aliasOpt,
                       rootBinder,
                       parentSemanticModelOpt: parentSemanticModel,
                       parentRemappedSymbolsOpt: parentRemappedSymbolsOpt,
                       speculatedPosition: position
                       ));
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Creates an AttributeSemanticModel that allows asking semantic questions about an attribute node.
 /// </summary>
 public static AttributeSemanticModel Create(CSharpCompilation compilation, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder)
 {
     return new AttributeSemanticModel(compilation, syntax, attributeType, aliasOpt, rootBinder);
 }
Ejemplo n.º 14
0
 public virtual TResult VisitAlias(AliasSymbol symbol)
 {
     return(DefaultVisit(symbol));
 }
Ejemplo n.º 15
0
 public BoundTypeExpression(CSharpSyntaxNode syntax, AliasSymbol aliasOpt, bool inferredType, TypeSymbol type, bool hasErrors = false)
     : this(syntax, aliasOpt, inferredType, null, type, hasErrors)
 {
 }
Ejemplo n.º 16
0
        protected override void LookupSymbolsInSingleBinder(LookupResult result, string name, int arity, ConsList <Symbol> basesBeingResolved, LookupOptions options, bool diagnose)
        {
            LookupResult tmp       = LookupResult.GetInstance();
            LookupResult nonViable = LookupResult.GetInstance();

            // Member definitions of different kinds hide each other (field defs hide method defs, etc.).
            // So even if the caller asks only for invocable members find any member first and then reject the result if a non-invokable is found.
            LookupOptions anyMemberLookupOptions = options & ~LookupOptions.MustBeInvocableMember;

            // TODO: optimize lookup (there might be many interactions in the chain)
            for (ICompilation commonSubmission = Compilation.PreviousSubmission; commonSubmission != null; commonSubmission = commonSubmission.PreviousSubmission)
            {
                // TODO (tomat): cross-language binding - for now, skip non-C# submissions
                Compilation submission = commonSubmission as Compilation;
                if (submission == null)
                {
                    continue;
                }

                tmp.Clear();

                Imports imports = GetImports(submission);
                imports.LookupSymbolInAliases(this, tmp, name, arity, basesBeingResolved, anyMemberLookupOptions, diagnose);

                // If a viable using alias and a matching member are both defined in the submission an error is reported elsewhere.
                // Ignore the member in such case.
                if (!tmp.IsMultiViable && (options & LookupOptions.NamespaceAliasesOnly) == 0)
                {
                    this.LookupMembers(tmp, submission.ScriptClass, name, arity, basesBeingResolved, anyMemberLookupOptions, diagnose);
                }

                // found a non-method in the current submission:
                if (tmp.Symbols.Count > 0 && tmp.Symbols.First().Kind != SymbolKind.Method)
                {
                    if (!tmp.IsMultiViable)
                    {
                        // skip non-viable members, but remember them in case no viable members are found in previous submissions:
                        nonViable.MergePrioritized(tmp);
                        continue;
                    }

                    if (result.Symbols.Count == 0)
                    {
                        result.MergeEqual(tmp);
                    }

                    break;
                }

                // merge overloads:
                Debug.Assert(result.Symbols.Count == 0 || result.Symbols.All(s => s.Kind == SymbolKind.Method));
                result.MergeEqual(tmp);
            }

            // Set a proper error if we found a symbol that is not invocable but were asked for invocable only.
            // Only a single non-method can be present in the result; methods are always invocable.
            if ((options & LookupOptions.MustBeInvocableMember) != 0 && result.Symbols.Count == 1)
            {
                Symbol      symbol = result.Symbols.First();
                AliasSymbol alias  = symbol as AliasSymbol;
                if (alias != null)
                {
                    symbol = alias.GetAliasTarget(basesBeingResolved);
                }

                if (IsNonInvocableMember(symbol))
                {
                    result.SetFrom(LookupResult.NotInvocable(symbol, result.Symbols.First(), diagnose));
                }
            }
            else if (result.Symbols.Count == 0)
            {
                result.SetFrom(nonViable);
            }

            tmp.Free();
            nonViable.Free();
        }
Ejemplo n.º 17
0
 public BoundTypeExpression(SyntaxNode syntax, AliasSymbol aliasOpt, TypeSymbol type)
     : this(syntax, aliasOpt, false, null, type)
 {
 }
Ejemplo n.º 18
0
 public BoundTypeExpression(SyntaxNode syntax, AliasSymbol aliasOpt, TypeSymbol type, bool hasErrors = false)
     : this(syntax, aliasOpt, false, null, type, hasErrors)
 {
 }
Ejemplo n.º 19
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);
            Debug.Assert((object)declTypeOpt != null || isVar);
            Debug.Assert(typeSyntax != null);

            // if we are not given desired syntax, we use declarator
            associatedSyntaxNode = associatedSyntaxNode ?? declarator;

            bool hasErrors = false;

            BoundExpression initializerOpt;

            SourceLocalSymbol localSymbol = this.LookupLocal(declarator.Identifier);

            // In error scenarios with misplaced code, it is possible we can't bind the local declaration.
            // This occurs through the semantic model.  In that case concoct a plausible result.
            if ((object)localSymbol == null)
            {
                localSymbol = SourceLocalSymbol.MakeLocal(
                    ContainingMemberOrLambda as MethodSymbol, this, typeSyntax,
                    declarator.Identifier, declarator.Initializer, LocalDeclarationKind.Variable);
            }

            // Check for variable declaration errors.
            hasErrors |= this.EnsureDeclarationInvariantMeaningInScope(localSymbol, diagnostics);

            EqualsValueClauseSyntax equalsValueClauseSyntax = declarator.Initializer;
            if (isVar)
            {
                aliasOpt = null;

                var binder = new ImplicitlyTypedLocalBinder(this, localSymbol);
                initializerOpt = binder.BindInferredVariableInitializer(diagnostics, equalsValueClauseSyntax, declarator);

                // If we got a good result then swap the inferred type for the "var" 
                if (initializerOpt != null && (object)initializerOpt.Type != null)
                {
                    declTypeOpt = initializerOpt.Type;

                    if (declTypeOpt.SpecialType == SpecialType.System_Void)
                    {
                        Error(diagnostics, ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, declarator, declTypeOpt);
                        declTypeOpt = CreateErrorType("var");
                        hasErrors = true;
                    }

                    if (!declTypeOpt.IsErrorType())
                    {
                        if (declTypeOpt.IsStatic)
                        {
                            Error(diagnostics, 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, diagnostics);
                    if (kind != LocalDeclarationKind.Fixed)
                    {
                        // If this is for a fixed statement, we'll do our own conversion since there are some special cases.
                        initializerOpt = GenerateConversionForAssignment(declTypeOpt, initializerOpt, diagnostics);
                    }
                }
            }

            Debug.Assert((object)declTypeOpt != null);

            if (kind == LocalDeclarationKind.Fixed)
            {
                // NOTE: this is an error, but it won't prevent further binding.
                if (isVar)
                {
                    if (!hasErrors)
                    {
                        Error(diagnostics, ErrorCode.ERR_ImplicitlyTypedLocalCannotBeFixed, declarator);
                        hasErrors = true;
                    }
                }

                if (!declTypeOpt.IsPointerType())
                {
                    if (!hasErrors)
                    {
                        Error(diagnostics, ErrorCode.ERR_BadFixedInitType, declarator);
                        hasErrors = true;
                    }
                }
                else if (!IsValidFixedVariableInitializer(declTypeOpt, localSymbol, ref initializerOpt, diagnostics))
                {
                    hasErrors = true;
                }
            }

            if (this.ContainingMemberOrLambda.Kind == SymbolKind.Method
                && ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync
                && declTypeOpt.IsRestrictedType())
            {
                Error(diagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declTypeOpt);
                hasErrors = true;
            }

            DeclareLocalVariable(
                localSymbol,
                declarator.Identifier,
                declTypeOpt);

            Debug.Assert((object)localSymbol != null);

            // It is possible that we have a bracketed argument list, like "int x[];" or "int x[123];" 
            // in a non-fixed-size-array declaration . This is a common error made by C++ programmers. 
            // We have already given a good error at parse time telling the user to either make it "fixed"
            // or to move the brackets to the type. However, we should still do semantic analysis of
            // the arguments, so that errors in them are discovered, hovering over them in the IDE
            // gives good results, and so on.

            var arguments = default(ImmutableArray<BoundExpression>);

            if (declarator.ArgumentList != null)
            {
                var builder = ArrayBuilder<BoundExpression>.GetInstance();
                foreach (var argument in declarator.ArgumentList.Arguments)
                {
                    var boundArgument = BindValue(argument.Expression, diagnostics, BindValueKind.RValue);
                    builder.Add(boundArgument);
                }
                arguments = builder.ToImmutableAndFree();
            }

            if (kind == LocalDeclarationKind.Fixed || kind == LocalDeclarationKind.Using)
            {
                // 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(diagnostics, ErrorCode.ERR_FixedMustInit, declarator);
                    hasErrors = true;
                }
            }
            else if (kind == LocalDeclarationKind.Constant && initializerOpt != null)
            {
                foreach (var diagnostic in localSymbol.GetConstantValueDiagnostics(initializerOpt))
                {
                    diagnostics.Add(diagnostic);
                    hasErrors = true;
                }
            }

            var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declTypeOpt);
            return new BoundLocalDeclaration(associatedSyntaxNode, localSymbol, boundDeclType, initializerOpt, arguments, hasErrors);
        }
Ejemplo n.º 20
0
        private static Imports BuildImports(CSharpCompilation compilation, ImmutableArray<string> importStrings, InContainerBinder binder, MetadataDecoder metadataDecoder)
        {
            // We make a first pass to extract all of the extern aliases because other imports may depend on them.
            var externsBuilder = ArrayBuilder<AliasAndExternAliasDirective>.GetInstance();
            foreach (var importString in importStrings)
            {
                string alias;
                string externAlias;
                string target;
                ImportTargetKind kind;
                if (!CustomDebugInfoReader.TryParseCSharpImportString(importString, out alias, out externAlias, out target, out kind))
                {
                    Debug.WriteLine("Unable to parse import string '{0}'", (object)importString);
                    continue;
                }
                else if (kind != ImportTargetKind.Assembly)
                {
                    continue;
                }

                Debug.Assert(alias == null);
                Debug.Assert(externAlias != null);
                Debug.Assert(target == null);

                NameSyntax aliasNameSyntax;
                if (!SyntaxHelpers.TryParseDottedName(externAlias, out aliasNameSyntax) || aliasNameSyntax.Kind() != SyntaxKind.IdentifierName)
                {
                    Debug.WriteLine("Import string '{0}' has syntactically invalid extern alias '{1}'", importString, externAlias);
                    continue;
                }

                var aliasToken = ((IdentifierNameSyntax)aliasNameSyntax).Identifier;
                var externAliasSyntax = SyntaxFactory.ExternAliasDirective(aliasToken);
                var aliasSymbol = new AliasSymbol(binder, externAliasSyntax); // Binder is only used to access compilation.
                externsBuilder.Add(new AliasAndExternAliasDirective(aliasSymbol, externAliasSyntax));
            }

            var externs = externsBuilder.ToImmutableAndFree();

            if (externs.Any())
            {
                // NB: This binder (and corresponding Imports) is only used to bind the other imports.
                // We'll merge the externs into a final Imports object and return that to be used in
                // the actual binder chain.
                binder = new InContainerBinder(
                    binder.Container,
                    binder,
                    Imports.FromCustomDebugInfo(binder.Compilation, new Dictionary<string, AliasAndUsingDirective>(), ImmutableArray<NamespaceOrTypeAndUsingDirective>.Empty, externs));
            }

            var usingAliases = new Dictionary<string, AliasAndUsingDirective>();
            var usingsBuilder = ArrayBuilder<NamespaceOrTypeAndUsingDirective>.GetInstance();

            foreach (var importString in importStrings)
            {
                string alias;
                string externAlias;
                string target;
                ImportTargetKind kind;
                if (!CustomDebugInfoReader.TryParseCSharpImportString(importString, out alias, out externAlias, out target, out kind))
                {
                    Debug.WriteLine("Unable to parse import string '{0}'", (object)importString);
                    continue;
                }

                switch (kind)
                {
                    case ImportTargetKind.Type:
                        {
                            Debug.Assert(target != null, string.Format("Type import string '{0}' has no target", importString));
                            Debug.Assert(externAlias == null, string.Format("Type import string '{0}' has an extern alias (should be folded into target)", importString));

                            TypeSymbol typeSymbol = metadataDecoder.GetTypeSymbolForSerializedType(target);
                            Debug.Assert((object)typeSymbol != null);
                            if (typeSymbol.IsErrorType())
                            {
                                // Type is unrecognized. The import may have been
                                // valid in the original source but unnecessary.
                                continue; // Don't add anything for this import.
                            }
                            else if (alias == null && !typeSymbol.IsStatic)
                            {
                                // Only static types can be directly imported.
                                continue;
                            }

                            NameSyntax typeSyntax = SyntaxFactory.ParseName(typeSymbol.ToDisplayString(s_fullNameFormat));
                            if (!TryAddImport(alias, typeSyntax, typeSymbol, usingsBuilder, usingAliases, binder, importString))
                            {
                                continue;
                            }

                            break;
                        }
                    case ImportTargetKind.Namespace:
                        {
                            Debug.Assert(target != null, string.Format("Namespace import string '{0}' has no target", importString));

                            NameSyntax targetSyntax;
                            if (!SyntaxHelpers.TryParseDottedName(target, out targetSyntax))
                            {
                                // DevDiv #999086: Some previous version of VS apparently generated type aliases as "UA{alias} T{alias-qualified type name}". 
                                // Neither Roslyn nor Dev12 parses such imports.  However, Roslyn discards them, rather than interpreting them as "UA{alias}"
                                // (which will rarely work and never be correct).
                                Debug.WriteLine("Import string '{0}' has syntactically invalid target '{1}'", importString, target);
                                continue;
                            }

                            if (externAlias != null)
                            {
                                IdentifierNameSyntax externAliasSyntax;
                                if (!TryParseIdentifierNameSyntax(externAlias, out externAliasSyntax))
                                {
                                    Debug.WriteLine("Import string '{0}' has syntactically invalid extern alias '{1}'", importString, externAlias);
                                    continue;
                                }

                                // This is the case that requires the binder to already know about extern aliases.
                                targetSyntax = SyntaxHelpers.PrependExternAlias(externAliasSyntax, targetSyntax);
                            }

                            var unusedDiagnostics = DiagnosticBag.GetInstance();
                            var namespaceSymbol = binder.BindNamespaceOrType(targetSyntax, unusedDiagnostics).ExpressionSymbol as NamespaceSymbol;
                            unusedDiagnostics.Free();
                            if ((object)namespaceSymbol == null)
                            {
                                // Namespace is unrecognized. The import may have been
                                // valid in the original source but unnecessary.
                                continue; // Don't add anything for this import.
                            }

                            if (!TryAddImport(alias, targetSyntax, namespaceSymbol, usingsBuilder, usingAliases, binder, importString))
                            {
                                continue;
                            }

                            break;
                        }
                    case ImportTargetKind.Assembly:
                        {
                            // Handled in first pass (above).
                            break;
                        }
                    default:
                        {
                            throw ExceptionUtilities.UnexpectedValue(kind);
                        }
                }
            }

            return Imports.FromCustomDebugInfo(binder.Compilation, usingAliases, usingsBuilder.ToImmutableAndFree(), externs);
        }
Ejemplo n.º 21
0
 public BoundTypeExpression(SyntaxNode syntax, AliasSymbol aliasOpt, TypeSymbol type, bool hasErrors = false)
     : this(syntax, aliasOpt, null, TypeWithAnnotations.Create(type), hasErrors)
 {
 }
Ejemplo n.º 22
0
 public BoundTypeExpression(SyntaxNode syntax, AliasSymbol aliasOpt, BoundTypeExpression boundContainingTypeOpt, TypeWithAnnotations typeWithAnnotations, bool hasErrors = false)
     : this(syntax, aliasOpt, boundContainingTypeOpt, ImmutableArray <BoundExpression> .Empty, typeWithAnnotations, hasErrors)
 {
 }
Ejemplo n.º 23
0
 public BoundTypeExpression(SyntaxNode syntax, AliasSymbol aliasOpt, BoundTypeExpression boundContainingTypeOpt, ImmutableArray <BoundExpression> boundDimensionsOpt, TypeWithAnnotations typeWithAnnotations, bool hasErrors = false)
     : this(syntax, aliasOpt, boundContainingTypeOpt, boundDimensionsOpt, typeWithAnnotations, typeWithAnnotations.Type, hasErrors)
 {
     Debug.Assert((object)typeWithAnnotations.Type != null, "Field 'type' cannot be null");
 }
Ejemplo n.º 24
0
 public virtual void VisitAlias(AliasSymbol symbol)
 {
     DefaultVisit(symbol);
 }
Ejemplo n.º 25
0
 private AttributeSemanticModel(CSharpCompilation compilation, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, SyntaxTreeSemanticModel parentSemanticModelOpt = null, int speculatedPosition = 0)
     : base(compilation, syntax, attributeType, new ExecutableCodeBinder(syntax, rootBinder.ContainingMember(), rootBinder), parentSemanticModelOpt, speculatedPosition)
 {
     Debug.Assert(syntax != null);
     _aliasOpt = aliasOpt;
 }
 /// <summary>
 /// Creates an AttributeSemanticModel that allows asking semantic questions about an attribute node.
 /// </summary>
 public static AttributeSemanticModel Create(SyntaxTreeSemanticModel containingSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Symbol?attributeTarget, Binder rootBinder, ImmutableDictionary <Symbol, Symbol> parentRemappedSymbolsOpt)
 {
     rootBinder = attributeTarget is null ? rootBinder : new ContextualAttributeBinder(rootBinder, attributeTarget);
     return(new AttributeSemanticModel(syntax, attributeType, aliasOpt, rootBinder, containingSemanticModel, parentRemappedSymbolsOpt: parentRemappedSymbolsOpt));
 }
Ejemplo n.º 27
0
 public AliasAndExternAliasDirective(AliasSymbol alias, ExternAliasDirectiveSyntax externAliasDirective)
 {
     this.Alias = alias;
     this.ExternAliasDirective = externAliasDirective;
 }
Ejemplo n.º 28
0
 private AttributeSemanticModel(CSharpCompilation compilation, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, SyntaxTreeSemanticModel parentSemanticModelOpt = null, int speculatedPosition = 0)
     : base(compilation, syntax, attributeType, rootBinder, parentSemanticModelOpt, speculatedPosition)
 {
     Debug.Assert(syntax != null);
     this.aliasOpt = aliasOpt;
 }
Ejemplo n.º 29
0
        public static Imports FromSyntax(
            LanguageSyntaxNode declarationSyntax,
            InContainerBinder binder,
            ConsList <TypeSymbol> basesBeingResolved,
            bool inUsing)
        {
            SyntaxFacts syntaxFacts = declarationSyntax.Language.SyntaxFacts;
            ImmutableArray <UsingDirective>       usingDirectives       = inUsing ? ImmutableArray <UsingDirective> .Empty : syntaxFacts.GetUsingDirectives(declarationSyntax);
            ImmutableArray <ExternAliasDirective> externAliasDirectives = syntaxFacts.GetExternAliasDirectives(declarationSyntax);

            if (usingDirectives.Length == 0 && externAliasDirectives.Length == 0)
            {
                return(Empty);
            }

            // define all of the extern aliases first. They may used by the target of a using

            // using Bar=Goo::Bar;
            // using Goo::Baz;
            // extern alias Goo;

            var diagnostics = new DiagnosticBag();

            var compilation = binder.Compilation;

            var externAliases = BuildExternAliases(externAliasDirectives, binder, diagnostics);
            var usings        = ArrayBuilder <NamespaceOrTypeAndUsingDirective> .GetInstance();

            ImmutableDictionary <string, AliasAndUsingDirective> .Builder usingAliases = null;
            if (usingDirectives.Length > 0)
            {
                // A binder that contains the extern aliases but not the usings. The resolution of the target of a using directive or alias
                // should not make use of other peer usings.
                Binder usingsBinder;
                if (declarationSyntax.SyntaxTree.Options.Kind != SourceCodeKind.Regular)
                {
                    usingsBinder = compilation.GetBinderFactory(declarationSyntax.SyntaxTree).GetImportsBinder(declarationSyntax, inUsing: true);
                }
                else
                {
                    var imports = externAliases.Length == 0
                        ? Empty
                        : new Imports(
                        compilation,
                        ImmutableDictionary <string, AliasAndUsingDirective> .Empty,
                        ImmutableArray <NamespaceOrTypeAndUsingDirective> .Empty,
                        externAliases,
                        diagnostics: null);
                    usingsBinder = new InContainerBinder(binder.Container, binder.Next, imports);
                }

                var uniqueUsings = PooledHashSet <NamespaceOrTypeSymbol> .GetInstance();

                foreach (var usingDirective in usingDirectives)
                {
                    compilation.RecordImport(usingDirective);

                    if (usingDirective.AliasName != null)
                    {
                        if (usingDirective.IsGlobal)
                        {
                            diagnostics.Add(InternalErrorCode.WRN_GlobalAliasDefn, usingDirective.AliasName.GetLocation());
                        }

                        if (usingDirective.IsStatic)
                        {
                            diagnostics.Add(InternalErrorCode.ERR_NoAliasHere, usingDirective.AliasName.GetLocation());
                        }

                        string identifierValueText = syntaxFacts.ExtractName(usingDirective.AliasName);
                        if (usingAliases != null && usingAliases.ContainsKey(identifierValueText))
                        {
                            // Suppress diagnostics if we're already broken.
                            if (!usingDirective.TargetName.IsMissing)
                            {
                                // The using alias '{0}' appeared previously in this namespace
                                diagnostics.Add(InternalErrorCode.ERR_DuplicateAlias, usingDirective.AliasName.GetLocation(), identifierValueText);
                            }
                        }
                        else
                        {
                            // an O(m*n) algorithm here but n (number of extern aliases) will likely be very small.
                            foreach (var externAlias in externAliases)
                            {
                                if (externAlias.Alias.Name == identifierValueText)
                                {
                                    // The using alias '{0}' appeared previously in this namespace
                                    diagnostics.Add(InternalErrorCode.ERR_DuplicateAlias, usingDirective.Location, identifierValueText);
                                    break;
                                }
                            }

                            if (usingAliases == null)
                            {
                                usingAliases = ImmutableDictionary.CreateBuilder <string, AliasAndUsingDirective>();
                            }

                            // construct the alias sym with the binder for which we are building imports. That
                            // way the alias target can make use of extern alias definitions.
                            usingAliases.Add(identifierValueText, new AliasAndUsingDirective(AliasSymbol.CreateUsing(identifierValueText, usingDirective, usingsBinder), usingDirective));
                        }
                    }
                    else
                    {
                        if (usingDirective.TargetName.IsMissing)
                        {
                            //don't try to lookup namespaces inserted by parser error recovery
                            continue;
                        }

                        var declarationBinder = usingsBinder.WithAdditionalFlags(BinderFlags.SuppressConstraintChecks);
                        var imported          = declarationBinder.BindNamespaceOrTypeSymbol(usingDirective.TargetName, diagnostics, basesBeingResolved);
                        if (imported.Kind == LanguageSymbolKind.Namespace)
                        {
                            if (usingDirective.IsStatic)
                            {
                                diagnostics.Add(InternalErrorCode.ERR_BadUsingType, usingDirective.TargetName.GetLocation(), imported);
                            }
                            else if (uniqueUsings.Contains(imported))
                            {
                                diagnostics.Add(InternalErrorCode.WRN_DuplicateUsing, usingDirective.TargetName.GetLocation(), imported);
                            }
                            else
                            {
                                uniqueUsings.Add(imported);
                                usings.Add(new NamespaceOrTypeAndUsingDirective(imported, usingDirective));
                            }
                        }
                        else if (imported.Kind == LanguageSymbolKind.NamedType)
                        {
                            if (usingDirective.IsStatic)
                            {
                                diagnostics.Add(InternalErrorCode.ERR_BadUsingNamespace, usingDirective.TargetName.GetLocation(), imported);
                            }
                            else
                            {
                                var importedType = (NamedTypeSymbol)imported;
                                if (uniqueUsings.Contains(importedType))
                                {
                                    diagnostics.Add(InternalErrorCode.WRN_DuplicateUsing, usingDirective.TargetName.GetLocation(), importedType);
                                }
                                else
                                {
                                    declarationBinder.ReportDiagnosticsIfObsolete(diagnostics, importedType, usingDirective.TargetName, hasBaseReceiver: false);

                                    uniqueUsings.Add(importedType);
                                    usings.Add(new NamespaceOrTypeAndUsingDirective(importedType, usingDirective));
                                }
                            }
                        }
                        else if (imported.Kind != LanguageSymbolKind.ErrorType)
                        {
                            // Do not report additional error if the symbol itself is erroneous.

                            // error: '<symbol>' is a '<symbol kind>' but is used as 'type or namespace'
                            diagnostics.Add(InternalErrorCode.ERR_BadSKknown, usingDirective.TargetName.GetLocation(), usingDirective.TargetName, imported.GetKindText(), "type or namespace");
                        }
                    }
                }

                uniqueUsings.Free();
            }

            var boundSymbolDef = compilation.GetBoundNode <BoundSymbolDef>(declarationSyntax);

            if (boundSymbolDef != null)
            {
                foreach (var symbol in boundSymbolDef.Symbols)
                {
                    var importProps = symbol.ModelSymbolInfo.Properties.Where(p => p.IsImport).ToImmutableArray();
                    foreach (var prop in importProps)
                    {
                        var boundProps = boundSymbolDef.GetChildProperties(prop.Name);
                        foreach (var boundProp in boundProps)
                        {
                            foreach (var boundValue in boundProp.BoundValues)
                            {
                                foreach (var value in boundValue.Values)
                                {
                                    var importedSymbol = value as NamespaceOrTypeSymbol;
                                    if (symbol != null)
                                    {
                                        bool isStaticImport = importedSymbol is NamedTypeSymbol;
                                        usings.Add(new NamespaceOrTypeAndUsingDirective(importedSymbol, new UsingDirective(declarationSyntax, null, boundValue.Syntax, isStaticImport, false)));
                                    }
                                    else
                                    {
                                        diagnostics.Add(ModelErrorCode.ERR_InvalidImport, boundValue.Syntax.Location, value);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (diagnostics.IsEmptyWithoutResolution)
            {
                diagnostics = null;
            }

            return(new Imports(compilation, usingAliases.ToImmutableDictionaryOrEmpty(), usings.ToImmutableAndFree(), externAliases, diagnostics));
        }
Ejemplo n.º 30
0
 /// <summary>
 /// Creates an AttributeSemanticModel that allows asking semantic questions about an attribute node.
 /// </summary>
 public static AttributeSemanticModel Create(CSharpCompilation compilation, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder)
 {
     var executableBinder = new ExecutableCodeBinder(syntax, attributeType, rootBinder);
     return new AttributeSemanticModel(compilation, syntax, attributeType, aliasOpt, new LocalScopeBinder(executableBinder));
 }
Ejemplo n.º 31
0
 public BoundTypeExpression(CSharpSyntaxNode syntax, AliasSymbol aliasOpt, TypeSymbol type)
     : this(syntax, aliasOpt, false, null, type)
 {
 }
Ejemplo n.º 32
0
 public AliasAndUsingDirective(AliasSymbol alias, UsingDirectiveSyntax usingDirective)
 {
     this.Alias = alias;
     this.UsingDirective = usingDirective;
 }
Ejemplo n.º 33
0
        private static Imports BuildImports(CSharpCompilation compilation, PEModuleSymbol module, ImmutableArray<ImportRecord> importRecords, InContainerBinder binder)
        {
            // We make a first pass to extract all of the extern aliases because other imports may depend on them.
            var externsBuilder = ArrayBuilder<AliasAndExternAliasDirective>.GetInstance();
            foreach (var importRecord in importRecords)
            {
                if (importRecord.TargetKind != ImportTargetKind.Assembly)
                {
                    continue;
                }

                var alias = importRecord.Alias;
                IdentifierNameSyntax aliasNameSyntax;
                if (!TryParseIdentifierNameSyntax(alias, out aliasNameSyntax))
                {
                    Debug.WriteLine($"Import record '{importRecord}' has syntactically invalid extern alias '{alias}'");
                    continue;
                }

                var externAliasSyntax = SyntaxFactory.ExternAliasDirective(aliasNameSyntax.Identifier);
                var aliasSymbol = new AliasSymbol(binder, externAliasSyntax); // Binder is only used to access compilation.
                externsBuilder.Add(new AliasAndExternAliasDirective(aliasSymbol, externAliasDirective: null)); // We have one, but we pass null for consistency.
            }

            var externs = externsBuilder.ToImmutableAndFree();

            if (externs.Any())
            {
                // NB: This binder (and corresponding Imports) is only used to bind the other imports.
                // We'll merge the externs into a final Imports object and return that to be used in
                // the actual binder chain.
                binder = new InContainerBinder(
                    binder.Container,
                    binder,
                    Imports.FromCustomDebugInfo(binder.Compilation, ImmutableDictionary<string, AliasAndUsingDirective>.Empty, ImmutableArray<NamespaceOrTypeAndUsingDirective>.Empty, externs));
            }

            var usingAliases = ImmutableDictionary.CreateBuilder<string, AliasAndUsingDirective>();
            var usingsBuilder = ArrayBuilder<NamespaceOrTypeAndUsingDirective>.GetInstance();

            foreach (var importRecord in importRecords)
            {
                switch (importRecord.TargetKind)
                {
                    case ImportTargetKind.Type:
                        {
                            TypeSymbol typeSymbol = (TypeSymbol)importRecord.TargetType;
                            Debug.Assert((object)typeSymbol != null);

                            if (typeSymbol.IsErrorType())
                            {
                                // Type is unrecognized. The import may have been
                                // valid in the original source but unnecessary.
                                continue; // Don't add anything for this import.
                            }
                            else if (importRecord.Alias == null && !typeSymbol.IsStatic)
                            {
                                // Only static types can be directly imported.
                                continue;
                            }

                            if (!TryAddImport(importRecord.Alias, typeSymbol, usingsBuilder, usingAliases, binder, importRecord))
                            {
                                continue;
                            }

                            break;
                        }
                    case ImportTargetKind.Namespace:
                        {
                            var namespaceName = importRecord.TargetString;
                            NameSyntax targetSyntax;
                            if (!SyntaxHelpers.TryParseDottedName(namespaceName, out targetSyntax))
                            {
                                // DevDiv #999086: Some previous version of VS apparently generated type aliases as "UA{alias} T{alias-qualified type name}". 
                                // Neither Roslyn nor Dev12 parses such imports.  However, Roslyn discards them, rather than interpreting them as "UA{alias}"
                                // (which will rarely work and never be correct).
                                Debug.WriteLine($"Import record '{importRecord}' has syntactically invalid target '{importRecord.TargetString}'");
                                continue;
                            }

                            NamespaceSymbol globalNamespace;
                            AssemblySymbol targetAssembly = (AssemblySymbol)importRecord.TargetAssembly;

                            if (targetAssembly != null)
                            {
                                if (targetAssembly.IsMissing)
                                {
                                    Debug.WriteLine($"Import record '{importRecord}' has invalid assembly reference '{targetAssembly.Identity}'");
                                    continue;
                                }

                                globalNamespace = targetAssembly.GlobalNamespace;
                            }
                            else if (importRecord.TargetAssemblyAlias != null)
                            {
                                IdentifierNameSyntax externAliasSyntax = null;
                                if (!TryParseIdentifierNameSyntax(importRecord.TargetAssemblyAlias, out externAliasSyntax))
                                {
                                    Debug.WriteLine($"Import record '{importRecord}' has syntactically invalid extern alias '{importRecord.TargetAssemblyAlias}'");
                                    continue;
                                }

                                var unusedDiagnostics = DiagnosticBag.GetInstance();
                                var aliasSymbol = (AliasSymbol)binder.BindNamespaceAliasSymbol(externAliasSyntax, unusedDiagnostics);
                                unusedDiagnostics.Free();

                                if ((object)aliasSymbol == null)
                                {
                                    Debug.WriteLine($"Import record '{importRecord}' requires unknown extern alias '{importRecord.TargetAssemblyAlias}'");
                                    continue;
                                }

                                globalNamespace = (NamespaceSymbol)aliasSymbol.Target;
                            }
                            else
                            {
                                globalNamespace = compilation.GlobalNamespace;
                            }

                            var namespaceSymbol = BindNamespace(namespaceName, globalNamespace);

                            if ((object)namespaceSymbol == null)
                            {
                                // Namespace is unrecognized. The import may have been
                                // valid in the original source but unnecessary.
                                continue; // Don't add anything for this import.
                            }

                            if (!TryAddImport(importRecord.Alias, namespaceSymbol, usingsBuilder, usingAliases, binder, importRecord))
                            {
                                continue;
                            }

                            break;
                        }
                    case ImportTargetKind.Assembly:
                        {
                            // Handled in first pass (above).
                            break;
                        }
                    default:
                        {
                            throw ExceptionUtilities.UnexpectedValue(importRecord.TargetKind);
                        }
                }
            }

            return Imports.FromCustomDebugInfo(binder.Compilation, usingAliases.ToImmutableDictionary(), usingsBuilder.ToImmutableAndFree(), externs);
        }
Ejemplo n.º 34
0
 public BoundTypeExpression(SyntaxNode syntax, AliasSymbol aliasOpt, TypeSymbol type)
     : this(syntax, aliasOpt, null, ImmutableArray <BoundExpression> .Empty, type)
 {
 }
Ejemplo n.º 35
0
 public virtual TResult VisitAlias(AliasSymbol symbol, TArgument argument)
 {
     return(DefaultVisit(symbol, argument));
 }
Ejemplo n.º 36
0
 public BoundTypeExpression(SyntaxNode syntax, AliasSymbol aliasOpt, ImmutableArray <BoundExpression> dimensionsOpt, TypeSymbol type, bool hasErrors = false)
     : this(syntax, aliasOpt, null, dimensionsOpt, type, hasErrors)
 {
 }
Ejemplo n.º 37
0
        private TypeSymbol BindVariableType(CSharpSyntaxNode declarationNode, DiagnosticBag diagnostics, TypeSyntax typeSyntax, ref bool isConst, out bool isVar, out AliasSymbol alias)
        {
            Debug.Assert(declarationNode.Kind() == SyntaxKind.LocalDeclarationStatement);

            // If the type is "var" then suppress errors when binding it. "var" might be a legal type
            // or it might not; if it is not then we do not want to report an error. If it is, then
            // we want to treat the declaration as an explicitly typed declaration.

            TypeSymbol declType = BindType(typeSyntax, diagnostics, out isVar, out alias);
            Debug.Assert((object)declType != null || isVar);

            if (isVar)
            {
                // 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.

                if (isConst)
                {
                    Error(diagnostics, ErrorCode.ERR_ImplicitlyTypedVariableCannotBeConst, declarationNode);
                    // Keep processing it as a non-const local.
                    isConst = false;
                }

                // In the dev10 compiler the error recovery semantics for the illegal case
                // "var x = 10, y = 123.4;" are somewhat undesirable.
                //
                // First off, this is an error because a straw poll of language designers and
                // users showed that there was no consensus on whether the above should mean
                // "double x = 10, y = 123.4;", taking the best type available and substituting
                // that for "var", or treating it as "var x = 10; var y = 123.4;" -- since there
                // was no consensus we decided to simply make it illegal. 
                //
                // In dev10 for error recovery in the IDE we do an odd thing -- we simply take
                // the type of the first variable and use it. So that is "int x = 10, y = 123.4;".
                // 
                // This seems less than ideal. In the error recovery scenario it probably makes
                // more sense to treat that as "var x = 10; var y = 123.4;" and do each inference
                // separately.

                if (declarationNode.Kind() == SyntaxKind.LocalDeclarationStatement && ((LocalDeclarationStatementSyntax)declarationNode).Declaration.Variables.Count > 1 && !declarationNode.HasErrors)
                {
                    Error(diagnostics, ErrorCode.ERR_ImplicitlyTypedVariableMultipleDeclarator, declarationNode);
                }
            }
            else
            {
                // In the native compiler when given a situation like
                //
                // D[] x;
                // 
                // where D is a static type we report both that D cannot be an element type
                // of an array, and that D[] is not a valid type for a local variable.
                // This seems silly; the first error is entirely sufficient. We no longer
                // produce additional errors for local variables of arrays of static types.

                if (declType.IsStatic)
                {
                    Error(diagnostics, ErrorCode.ERR_VarDeclIsStaticClass, typeSyntax, declType);
                }

                if (isConst && !declType.CanBeConst())
                {
                    Error(diagnostics, ErrorCode.ERR_BadConstType, typeSyntax, declType);
                    // Keep processing it as a non-const local.
                    isConst = false;
                }
            }

            return declType;
        }
Ejemplo n.º 38
0
 private AttributeSemanticModel(CSharpCompilation compilation, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, SyntaxTreeSemanticModel parentSemanticModelOpt = null, int speculatedPosition = 0)
     : base(compilation, syntax, attributeType, rootBinder, parentSemanticModelOpt, speculatedPosition)
 {
     Debug.Assert(syntax != null);
     this.aliasOpt = aliasOpt;
 }
Ejemplo n.º 39
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);
        }
Ejemplo n.º 40
0
        /// <summary>
        /// Creates an AttributeSemanticModel that allows asking semantic questions about an attribute node.
        /// </summary>
        public static AttributeSemanticModel Create(CSharpCompilation compilation, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder)
        {
            var executableBinder = new ExecutableCodeBinder(syntax, attributeType, rootBinder);

            return(new AttributeSemanticModel(compilation, syntax, attributeType, aliasOpt, new LocalScopeBinder(executableBinder)));
        }
Ejemplo n.º 41
0
 public AliasAndUsingDirective(AliasSymbol alias, UsingDirective usingDirective)
 {
     this.Alias          = alias;
     this.UsingDirective = usingDirective;
 }
Ejemplo n.º 42
0
        /// <summary>
        /// Creates a speculative AttributeSemanticModel that allows asking semantic questions about an attribute node that did not appear in the original source code.
        /// </summary>
        public static AttributeSemanticModel CreateSpeculative(SyntaxTreeSemanticModel parentSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, int position)
        {
            Debug.Assert(parentSemanticModel != null);
            Debug.Assert(rootBinder != null);
            Debug.Assert(rootBinder.IsSemanticModelBinder);

            return(new AttributeSemanticModel(parentSemanticModel.Compilation, syntax, attributeType, aliasOpt, rootBinder, parentSemanticModel, position));
        }
Ejemplo n.º 43
0
 /// <summary>
 /// Creates an AttributeSemanticModel that allows asking semantic questions about an attribute node.
 /// </summary>
 public static AttributeSemanticModel Create(SyntaxTreeSemanticModel containingSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder)
 {
     return(new AttributeSemanticModel(syntax, attributeType, aliasOpt, rootBinder, containingSemanticModel));
 }
Ejemplo n.º 44
0
 public BoundTypeExpression(CSharpSyntaxNode syntax, AliasSymbol aliasOpt, TypeSymbol type, bool hasErrors = false)
     : this(syntax, aliasOpt, false, null, type, hasErrors)
 {
 }
Ejemplo n.º 45
0
 public BoundTypeExpression(SyntaxNode syntax, AliasSymbol aliasOpt, bool inferredType, TypeSymbol type, bool hasErrors = false)
     : this(syntax, aliasOpt, inferredType, null, type, hasErrors)
 {
 }
Ejemplo n.º 46
0
 public AliasAndImportDirective(AliasSymbol alias, ImportDirectiveSyntax usingDirective)
 {
     this.Alias           = alias;
     this.ImportDirective = usingDirective;
 }