internal static NamespaceSymbol BuildSymbol(
     this MergedNamespaceDeclaration declaration,
     NamespaceOrTypeSymbol parent,
     DiagnosticBag diagnostics)
 {
     return new SourceNamespaceSymbol(parent, declaration, diagnostics);
 }
        internal QualifiedNameBinder(NamespaceOrTypeSymbol qualifier, Binder outer)
            : base(qualifier, new BuckStopsHereBinder(outer.Compilation, outer.SourceTree))
        {
            if (outer == null || qualifier == null)
                throw new ArgumentNullException();

            this.ambient = outer;
            this.qualifier = qualifier;
        }
Пример #3
0
        private ImmutableArray <Symbol> BindMemberCref(MemberCrefSyntax syntax, NamespaceOrTypeSymbol containerOpt, out Symbol ambiguityWinner, DiagnosticBag diagnostics)
        {
            if ((object)containerOpt != null && containerOpt.Kind == SymbolKind.TypeParameter)
            {
                // As in normal lookup (see CreateErrorIfLookupOnTypeParameter), you can't dot into a type parameter
                // (though you can dot into an expression of type parameter type).
                CrefSyntax crefSyntax = GetRootCrefSyntax(syntax);
                diagnostics.Add(ErrorCode.WRN_BadXMLRef, crefSyntax.Location, crefSyntax.ToFullString());

                ambiguityWinner = null;
                return(ImmutableArray <Symbol> .Empty);
            }

            ImmutableArray <Symbol> result;

            switch (syntax.Kind)
            {
            case SyntaxKind.NameMemberCref:
                result = BindNameMemberCref((NameMemberCrefSyntax)syntax, containerOpt, out ambiguityWinner, diagnostics);
                break;

            case SyntaxKind.IndexerMemberCref:
                result = BindIndexerMemberCref((IndexerMemberCrefSyntax)syntax, containerOpt, out ambiguityWinner, diagnostics);
                break;

            case SyntaxKind.OperatorMemberCref:
                result = BindOperatorMemberCref((OperatorMemberCrefSyntax)syntax, containerOpt, out ambiguityWinner, diagnostics);
                break;

            case SyntaxKind.ConversionOperatorMemberCref:
                result = BindConversionOperatorMemberCref((ConversionOperatorMemberCrefSyntax)syntax, containerOpt, out ambiguityWinner, diagnostics);
                break;

            default:
                Debug.Assert(false, "Unexpected member cref kind " + syntax.Kind);
                ambiguityWinner = null;
                result          = ImmutableArray <Symbol> .Empty;
                break;
            }

            if (!result.Any())
            {
                CrefSyntax crefSyntax = GetRootCrefSyntax(syntax);
                diagnostics.Add(ErrorCode.WRN_BadXMLRef, crefSyntax.Location, crefSyntax.ToFullString());
            }

            return(result);
        }
Пример #4
0
        public static Symbol GetMember(this NamespaceOrTypeSymbol container, string qualifiedName)
        {
            NamespaceOrTypeSymbol lastContainer;
            var members = GetMembers(container, qualifiedName, out lastContainer);

            if (members.Length == 0)
            {
                return(null);
            }
            else if (members.Length > 1)
            {
                Assert.True(false, "Found multiple members of specified name:\r\n" + string.Join("\r\n", members));
            }

            return(members.Single());
        }
Пример #5
0
        /// <summary>
        /// Gets all concept instances directly declared in a container.
        /// </summary>
        /// <param name="container">
        /// The container to visit.
        /// </param>
        /// <param name="instances">
        /// The instance array to populate.
        /// </param>
        /// <param name="originalBinder">
        /// The call-site binder.
        /// </param>
        /// <param name="useSiteDiagnostics">
        /// The set of use-site diagnostics to populate with any errors.
        /// </param>
        private void GetConceptInstancesInContainer(NamespaceOrTypeSymbol container, ArrayBuilder <TypeSymbol> instances, Binder originalBinder, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
        {
            foreach (var member in container.GetTypeMembers())
            {
                if (!originalBinder.IsAccessible(member, ref useSiteDiagnostics, originalBinder.ContainingType))
                {
                    continue;
                }

                // Assuming that instances don't contain sub-instances.
                if (member.IsInstance)
                {
                    instances.Add(member);
                }
            }
        }
Пример #6
0
    public static void LookupSymbolsSimpleName(
        this Microsoft.CodeAnalysis.CSharp.Binder binder,
        LookupResult result,
        NamespaceOrTypeSymbol qualifierOpt,
        string plainName,
        int arity,
        ConsList <TypeSymbol> basesBeingResolved,
        LookupOptions options,
        bool diagnose,
        ref HashSet <DiagnosticInfo> useSiteDiagnostics)
    {
        CompoundUseSiteInfo <AssemblySymbol> useSiteInfo = default;

        binder.LookupSymbolsSimpleName(result, qualifierOpt, plainName, arity, basesBeingResolved, options, diagnose, ref useSiteInfo);
        AddDiagnosticInfos(ref useSiteDiagnostics, useSiteInfo);
    }
Пример #7
0
        private ImmutableArray <Symbol> BindTypeCref(TypeCrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics)
        {
            NamespaceOrTypeSymbol result = BindNamespaceOrTypeSymbolInCref(syntax.Type);

            // NOTE: we don't have to worry about the case where a non-error type is constructed
            // with erroneous type arguments, because only MemberCrefs have type arguments -
            // all other crefs only have type parameters.
            if (result.Kind == SymbolKind.ErrorType)
            {
                diagnostics.Add(ErrorCode.WRN_BadXMLRef, syntax.Location, syntax.ToFullString());
            }

            // We'll never have more than one type, but it is conceivable that result could
            // be an ExtendedErrorTypeSymbol with multiple candidates.
            ambiguityWinner = null;
            return(ImmutableArray.Create <Symbol>(result));
        }
Пример #8
0
        /// <summary>
        /// We can't use BindNamespaceOrTypeSymbol, since it doesn't return inaccessible symbols (directly).
        /// </summary>
        /// <remarks>
        /// Guaranteed not to return null.
        ///
        /// CONSIDER: As in dev11, we don't handle ambiguity at this level.  Hypothetically,
        /// we could just pick one, though an "ideal" solution would probably involve a search
        /// down all ambiguous branches.
        /// </remarks>
        private NamespaceOrTypeSymbol BindNamespaceOrTypeSymbolInCref(TypeSyntax syntax)
        {
            Debug.Assert(Flags.Includes(BinderFlags.Cref));

            // BREAK: Dev11 used to do a second lookup, ignoring accessibility, if the first lookup failed.
            //   VS BUG#3321137: we need to try to find accessible members first
            //   especially for compiler generated events (the backing field is private
            //   but has the same name as the public event, and there is no easy way to
            //   set the isEvent field on imported MEMBVARSYMs)

            // Diagnostics that don't prevent us from getting a symbol don't matter - the caller will report
            // an umbrella diagnostic if the result is an error type.
            NamespaceOrTypeSymbol namespaceOrTypeSymbol = BindNamespaceOrTypeSymbol(syntax, BindingDiagnosticBag.Discarded).NamespaceOrTypeSymbol;

            Debug.Assert((object)namespaceOrTypeSymbol != null);
            return(namespaceOrTypeSymbol);
        }
Пример #9
0
        internal BinderContext BaseContext(NamespaceOrTypeSymbol current)
        {
            var typeContainer = current as NamedTypeSymbol;

            if (typeContainer == null)
            {
                return(Next);
            }

            var decl = Declaration.Syntax.GetSyntax() as TypeDeclarationSyntax;

            if (decl == null)
            {
                return(Next);
            }

            return(new WithClassTypeParametersBinderContext(Next.Location(Declaration.Syntax.GetSyntax()), Declaration.Syntax, typeContainer, Next));
        }
Пример #10
0
 internal static NamespaceOrTypeSymbol BuildSymbol(
     this MergedNamespaceOrTypeDeclaration declaration,
     NamespaceOrTypeSymbol parent,
     DiagnosticBag diagnostics)
 {
     if (declaration is MergedNamespaceDeclaration)
     {
         return(BuildSymbol((MergedNamespaceDeclaration)declaration, parent, diagnostics));
     }
     else if (declaration is MergedTypeDeclaration)
     {
         return(BuildSymbol((MergedTypeDeclaration)declaration, parent, diagnostics));
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
 internal static NamespaceOrTypeSymbol BuildSymbol(
     this MergedNamespaceOrTypeDeclaration declaration,
     NamespaceOrTypeSymbol parent,
     DiagnosticBag diagnostics)
 {
     if (declaration is MergedNamespaceDeclaration)
     {
         return BuildSymbol((MergedNamespaceDeclaration)declaration, parent, diagnostics);
     }
     else if (declaration is MergedTypeDeclaration)
     {
         return BuildSymbol((MergedTypeDeclaration)declaration, parent, diagnostics);
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
Пример #12
0
        /// <summary>
        /// Gets all concepts directly declared in a container.
        /// </summary>
        /// <param name="container">
        /// The container to visit.
        /// </param>
        /// <param name="concepts">
        /// The instance array to populate.
        /// </param>
        /// <param name="originalBinder">
        /// The call-site binder.
        /// </param>
        /// <param name="useSiteDiagnostics">
        /// The set of use-site diagnostics to populate with any errors.
        /// </param>
        /// <param name="options">
        /// The concept look-up options to use.
        /// </param>
        private void GetConceptsInContainer(NamespaceOrTypeSymbol container, ArrayBuilder <NamedTypeSymbol> concepts, Binder originalBinder, ref HashSet <DiagnosticInfo> useSiteDiagnostics, ConceptSearchOptions options)
        {
            Debug.Assert(container != null, "container being searched should not be null: this should have been checked earlier");
            var useStandaloneInstances = (options & ConceptSearchOptions.AllowStandaloneInstances) != 0;

            foreach (var member in container.GetTypeMembers())
            {
                if (!originalBinder.IsAccessible(member, ref useSiteDiagnostics, originalBinder.ContainingType))
                {
                    continue;
                }

                // Concepts can declare sub-concepts, but (for now) we don't
                // consider them.
                if (member.IsConcept || (useStandaloneInstances && member.IsStandaloneInstance))
                {
                    concepts.Add(member);
                }
            }
        }
Пример #13
0
        internal IEnumerable <TypeParameterBuilder> TypeParameterBinders(NamespaceOrTypeSymbol current)
        {
            var type = current as NamedTypeSymbol;

            if (type == null)
            {
                return(Enumerable.Empty <TypeParameterBuilder>());
            }

            var baseBinder = BaseContext(type) as WithClassTypeParametersBinderContext;

            if (baseBinder == null)
            {
                return(Enumerable.Empty <TypeParameterBuilder>()); // no params in declaration
            }

            return
                (baseBinder.TypeParameters
                 .Select(ta => new TypeParameterBuilder(ta, type, baseBinder)));
        }
Пример #14
0
 public virtual LookupConstraints Update(
     string name,
     string metadataName,
     ImmutableArray <ModelObjectDescriptor> kinds,
     NamespaceOrTypeSymbol qualifierOpt,
     ConsList <TypeSymbol> basesBeingResolved,
     Binder originalBinder,
     TypeSymbol accessThroughType,
     LookupOptions options,
     bool diagnose,
     HashSet <DiagnosticInfo> useSiteDiagnostics)
 {
     if (!ReferenceEquals(qualifierOpt, this.QualifierOpt) || name != this.Name || metadataName != this.MetadataName ||
         kinds != this.Kinds || !ReferenceEquals(basesBeingResolved, this.BasesBeingResolved) || !ReferenceEquals(originalBinder, this.OriginalBinder) ||
         !ReferenceEquals(accessThroughType, this.AccessThroughType) ||
         options != this.Options || diagnose != this.Diagnose || !ReferenceEquals(useSiteDiagnostics, this.UseSiteDiagnostics))
     {
         return(new LookupConstraints(name, metadataName, kinds, qualifierOpt, basesBeingResolved, originalBinder, accessThroughType, options, diagnose, useSiteDiagnostics));
     }
     return(this);
 }
Пример #15
0
        internal override IEnumerable <MemberBuilder> NonContainerBuilders(NamespaceOrTypeSymbol current)
        {
            SyntaxNode syntax = Declaration.Syntax.GetSyntax();

            switch (syntax.Kind)
            {
            case SyntaxKind.EnumDeclaration:
            case SyntaxKind.DelegateDeclaration:
                ReportDiagnostic(syntax, ErrorCode.ERR_UnimplementedOp);
                return(Enumerable.Empty <MemberBuilder>());

            case SyntaxKind.ClassDeclaration:
            case SyntaxKind.InterfaceDeclaration:
            case SyntaxKind.StructDeclaration:
                var visitor = new MemberBinderVisitor(current as NamedTypeSymbol, BodyContext(current));
                TypeDeclarationSyntax typeDecl = syntax as TypeDeclarationSyntax;
                return(typeDecl.Members.SelectMany(member => visitor.BinderForMember(member)).Where(b => b != null));

            default:
                throw new NotSupportedException();
            }
        }
Пример #16
0
        private static ImmutableArray <Symbol> GetMembers(NamespaceOrTypeSymbol container, string qualifiedName, out NamespaceOrTypeSymbol lastContainer)
        {
            var parts = SplitMemberName(qualifiedName);

            lastContainer = container;
            for (int i = 0; i < parts.Length - 1; i++)
            {
                var nestedContainer = (NamespaceOrTypeSymbol)lastContainer.GetMember(parts[i]);
                if (nestedContainer == null)
                {
                    // If there wasn't a nested namespace or type with that name, assume it's a
                    // member name that includes dots (e.g. explicit interface implementation).
                    return(lastContainer.GetMembers(string.Join(".", parts.Skip(i))));
                }
                else
                {
                    lastContainer = nestedContainer;
                }
            }

            return(lastContainer.GetMembers(parts[parts.Length - 1]));
        }
Пример #17
0
        /// <summary>
        /// Creates a binder for a container with imports (usings and extern aliases) that can be
        /// retrieved from <paramref name="declarationSyntax"/>.
        /// </summary>
        internal InContainerBinder(NamespaceOrTypeSymbol container, Binder next, CSharpSyntaxNode declarationSyntax, bool inUsing)
            : base(next)
        {
            Debug.Assert((object)container != null);
            Debug.Assert(declarationSyntax != null);

            _container      = container;
            _computeImports = basesBeingResolved => Imports.FromSyntax(declarationSyntax, this, basesBeingResolved, inUsing);

            if (!inUsing)
            {
                if (declarationSyntax.Kind() == SyntaxKind.CompilationUnit)
                {
                    var compilationUnit = (CompilationUnitSyntax)declarationSyntax;
                    _usingsSyntax = compilationUnit.Usings;
                }
                else if (declarationSyntax.Kind() == SyntaxKind.NamespaceDeclaration)
                {
                    var namespaceDecl = (NamespaceDeclarationSyntax)declarationSyntax;
                    _usingsSyntax = namespaceDecl.Usings;
                }
            }
        }
Пример #18
0
 public LookupConstraints(
     string name         = null,
     string metadataName = null,
     ImmutableArray <ModelObjectDescriptor> kinds = default,
     NamespaceOrTypeSymbol qualifierOpt           = null,
     ConsList <TypeSymbol> basesBeingResolved     = null,
     Binder originalBinder        = null,
     TypeSymbol accessThroughType = null,
     LookupOptions options        = LookupOptions.Default,
     bool diagnose = true,
     HashSet <DiagnosticInfo> useSiteDiagnostics = null)
 {
     QualifierOpt       = qualifierOpt;
     Name               = name;
     MetadataName       = metadataName ?? name;
     Kinds              = kinds;
     BasesBeingResolved = basesBeingResolved;
     OriginalBinder     = originalBinder;
     AccessThroughType  = accessThroughType;
     Options            = options;
     Diagnose           = diagnose;
     UseSiteDiagnostics = useSiteDiagnostics;
 }
        internal override IEnumerable<NamespaceOrTypeBuilder> TypeOrNamespaceBuilders(NamespaceOrTypeSymbol current)
        {
            BinderContext next; // push diagnostics to the top level
            NamespaceOrTypeSymbol merged; // lookup in a merged context
            if (this is TopLevelBuilder1)
            {
                next = this;
                merged = Compilation.GlobalNamespace;
            }
            else
            {
                next = this.Next;
                merged = (next as InContainerBinderContext).Container.GetMembers(current.Name).OfType<Symbol, NamespaceSymbol>().Single();
            }

            BinderContext bodyContext = new InContainerBinderContext(declaration, merged, next);
            foreach (var d in declaration.SingleChildren)
            {
              yield return d.Kind == DeclarationKind.Namespace
                  ? (NamespaceOrTypeBuilder)new NamespaceBuilder1(current, d, bodyContext)
                  : (NamespaceOrTypeBuilder)new NamedTypeBuilder(current, d, bodyContext);
            }
        }
Пример #20
0
        private static void GetSourceMemberSymbols(NamespaceOrTypeSymbol symbol, List <ISymbol> list, LocalSymbolDumper localDumper)
        {
            foreach (var memberSymbol in symbol.GetMembers())
            {
                list.Add(memberSymbol);

                switch (memberSymbol.Kind)
                {
                case SymbolKind.NamedType:
                case SymbolKind.Namespace:
                    GetSourceMemberSymbols((NamespaceOrTypeSymbol)memberSymbol, list, localDumper);
                    break;

                case SymbolKind.Method:
                    var method = (MethodSymbol)memberSymbol;
                    foreach (var parameter in method.Parameters)
                    {
                        list.Add(parameter);
                    }

                    if (localDumper != null)
                    {
                        localDumper.GetLocalSymbols(method, list);
                    }

                    break;

                case SymbolKind.Field:
                    if (localDumper != null)
                    {
                        localDumper.GetLocalSymbols((FieldSymbol)memberSymbol, list);
                    }

                    break;
                }
            }
        }
Пример #21
0
        private ImmutableArray <Symbol> ComputeSortedCrefMembers(NamespaceOrTypeSymbol containerOpt, string memberName, int arity, bool hasParameterList, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
        {
            // Since we may find symbols without going through the lookup API,
            // expose the symbols via an ArrayBuilder.
            ArrayBuilder <Symbol> builder;

            {
                LookupResult result = LookupResult.GetInstance();
                this.LookupSymbolsOrMembersInternal(
                    result,
                    containerOpt,
                    name: memberName,
                    arity: arity,
                    basesBeingResolved: null,
                    options: LookupOptions.AllMethodsOnArityZero,
                    diagnose: false,
                    useSiteDiagnostics: ref useSiteDiagnostics);

                // CONSIDER: Dev11 also checks for a constructor in the event of an ambiguous result.
                if (result.IsMultiViable)
                {
                    // Dev11 doesn't consider members from System.Object when the container is an interface.
                    // Lookup should already have dropped such members.
                    builder = ArrayBuilder <Symbol> .GetInstance();

                    builder.AddRange(result.Symbols);
                    result.Free();
                }
                else
                {
                    result.Free(); // Won't be using this.

                    // Dev11 has a complicated two-stage process for determining when a cref is really referring to a constructor.
                    // Under two sets of conditions, XmlDocCommentBinder::bindXMLReferenceName will decide that a name refers
                    // to a constructor and under one set of conditions, the calling method, XmlDocCommentBinder::bindXMLReference,
                    // will roll back that decision and return null.

                    // In XmlDocCommentBinder::bindXMLReferenceName:
                    //   1) If an unqualified, non-generic name didn't bind to anything and the name matches the name of the type
                    //      to which the doc comment is applied, then bind to a constructor.
                    //   2) If a qualified, non-generic name didn't bind to anything and the LHS of the qualified name is a type
                    //      with the same name, then bind to a constructor.

                    // Quoted from XmlDocCommentBinder::bindXMLReference:
                    //   Filtering out the case where specifying the name of a generic type without specifying
                    //   any arity returns a constructor. This case shouldn't return anything. Note that
                    //   returning the constructors was a fix for the wonky constructor behavior, but in order
                    //   to not introduce a regression and breaking change we return NULL in this case.
                    //   e.g.
                    //
                    //   /// <see cref="Goo"/>
                    //   class Goo<T> { }
                    //
                    //   This cref used not to bind to anything, because before it was looking for a type and
                    //   since there was no arity, it didn't find Goo<T>. Now however, it finds Goo<T>.ctor,
                    //   which is arguably correct, but would be a breaking change (albeit with minimal impact)
                    //   so we catch this case and chuck out the symbol found.

                    // In Roslyn, we're doing everything in one pass, rather than guessing and rolling back.

                    // As in the native compiler, we treat this as a fallback case - something that actually has the
                    // specified name is preferred.

                    NamedTypeSymbol constructorType = null;

                    if (arity == 0) // Member arity
                    {
                        NamedTypeSymbol containerType = containerOpt as NamedTypeSymbol;
                        if ((object)containerType != null)
                        {
                            // Case 1: If the name is qualified by a type with the same name, then we want a
                            // constructor (unless the type is generic, the cref is on/in the type (but not
                            // on/in a nested type), and there were no parens after the member name).

                            if (containerType.Name == memberName && (hasParameterList || containerType.Arity == 0 || this.ContainingType != containerType.OriginalDefinition))
                            {
                                constructorType = containerType;
                            }
                        }
                        else if ((object)containerOpt == null && hasParameterList)
                        {
                            // Case 2: If the name is not qualified by anything, but we're in the scope
                            // of a type with the same name (regardless of arity), then we want a constructor,
                            // as long as there were parens after the member name.

                            NamedTypeSymbol binderContainingType = this.ContainingType;
                            if ((object)binderContainingType != null && memberName == binderContainingType.Name)
                            {
                                constructorType = binderContainingType;
                            }
                        }
                    }

                    if ((object)constructorType != null)
                    {
                        ImmutableArray <MethodSymbol> instanceConstructors = constructorType.InstanceConstructors;
                        int numInstanceConstructors = instanceConstructors.Length;

                        if (numInstanceConstructors == 0)
                        {
                            return(ImmutableArray <Symbol> .Empty);
                        }

                        builder = ArrayBuilder <Symbol> .GetInstance(numInstanceConstructors);

                        builder.AddRange(instanceConstructors);
                    }
                    else
                    {
                        return(ImmutableArray <Symbol> .Empty);
                    }
                }
            }

            Debug.Assert(builder != null);

            // Since we resolve ambiguities by just picking the first symbol we encounter,
            // the order of the symbols matters for repeatability.
            if (builder.Count > 1)
            {
                builder.Sort(ConsistentSymbolOrder.Instance);
            }

            return(builder.ToImmutableAndFree());
        }
Пример #22
0
        // NOTE: not guaranteed to be a method (e.g. class op_Implicit)
        private ImmutableArray <Symbol> BindConversionOperatorMemberCref(ConversionOperatorMemberCrefSyntax syntax, NamespaceOrTypeSymbol containerOpt, out Symbol ambiguityWinner, DiagnosticBag diagnostics)
        {
            const int arity = 0;

            string memberName = syntax.ImplicitOrExplicitKeyword.Kind() == SyntaxKind.ImplicitKeyword
                ? WellKnownMemberNames.ImplicitConversionName
                : WellKnownMemberNames.ExplicitConversionName;

            ImmutableArray <Symbol> sortedSymbols = ComputeSortedCrefMembers(syntax, containerOpt, memberName, arity, syntax.Parameters != null, diagnostics);

            if (sortedSymbols.IsEmpty)
            {
                ambiguityWinner = null;
                return(ImmutableArray <Symbol> .Empty);
            }

            TypeSymbol returnType = BindCrefParameterOrReturnType(syntax.Type, syntax, diagnostics);

            // Filter out methods with the wrong return type, since overload resolution won't catch these.
            sortedSymbols = sortedSymbols.WhereAsArray(symbol =>
                                                       symbol.Kind != SymbolKind.Method || ((MethodSymbol)symbol).ReturnType.TypeSymbol == returnType);

            if (!sortedSymbols.Any())
            {
                ambiguityWinner = null;
                return(ImmutableArray <Symbol> .Empty);
            }

            return(ProcessCrefMemberLookupResults(
                       sortedSymbols,
                       arity,
                       syntax,
                       typeArgumentListSyntax: null,
                       parameterListSyntax: syntax.Parameters,
                       ambiguityWinner: out ambiguityWinner,
                       diagnostics: diagnostics));
        }
Пример #23
0
        /// <summary>
        /// Perform lookup (optionally, in a specified container).  If nothing is found and the member name matches the containing type
        /// name, then use the instance constructors of the type instead.  The resulting symbols are sorted since tie-breaking is based
        /// on order and we want cref binding to be repeatable.
        /// </summary>
        /// <remarks>
        /// Never returns null.
        /// </remarks>
        private ImmutableArray <Symbol> ComputeSortedCrefMembers(CSharpSyntaxNode syntax, NamespaceOrTypeSymbol containerOpt, string memberName, int arity, bool hasParameterList, DiagnosticBag diagnostics)
        {
            HashSet <DiagnosticInfo> useSiteDiagnostics = null;
            var result = ComputeSortedCrefMembers(containerOpt, memberName, arity, hasParameterList, ref useSiteDiagnostics);

            diagnostics.Add(syntax, useSiteDiagnostics);
            return(result);
        }
Пример #24
0
        private ImmutableArray <Symbol> BindIndexerMemberCref(IndexerMemberCrefSyntax syntax, NamespaceOrTypeSymbol containerOpt, out Symbol ambiguityWinner, DiagnosticBag diagnostics)
        {
            const int arity = 0;

            ImmutableArray <Symbol> sortedSymbols = ComputeSortedCrefMembers(syntax, containerOpt, WellKnownMemberNames.Indexer, arity, syntax.Parameters != null, diagnostics);

            if (sortedSymbols.IsEmpty)
            {
                ambiguityWinner = null;
                return(ImmutableArray <Symbol> .Empty);
            }

            // Since only indexers are named WellKnownMemberNames.Indexer.
            Debug.Assert(sortedSymbols.All(SymbolExtensions.IsIndexer));

            // NOTE: guaranteed to be a property, because only indexers are considered.
            return(ProcessCrefMemberLookupResults(
                       sortedSymbols,
                       arity,
                       syntax,
                       typeArgumentListSyntax: null,
                       parameterListSyntax: syntax.Parameters,
                       ambiguityWinner: out ambiguityWinner,
                       diagnostics: diagnostics));
        }
Пример #25
0
        // NOTE: not guaranteed to be a method (e.g. class op_Addition)
        // NOTE: constructor fallback logic applies
        private ImmutableArray <Symbol> BindOperatorMemberCref(OperatorMemberCrefSyntax syntax, NamespaceOrTypeSymbol containerOpt, out Symbol ambiguityWinner, DiagnosticBag diagnostics)
        {
            const int arity = 0;

            CrefParameterListSyntax parameterListSyntax = syntax.Parameters;

            // NOTE: Prefer binary to unary, unless there is exactly one parameter.
            // CONSIDER: we're following dev11 by never using a binary operator name if there's
            // exactly one parameter, but doing so would allow us to match single-parameter constructors.
            SyntaxKind operatorTokenKind = syntax.OperatorToken.Kind();
            string     memberName        = parameterListSyntax != null && parameterListSyntax.Parameters.Count == 1
                ? null
                : OperatorFacts.BinaryOperatorNameFromSyntaxKindIfAny(operatorTokenKind);

            memberName = memberName ?? OperatorFacts.UnaryOperatorNameFromSyntaxKindIfAny(operatorTokenKind);

            if (memberName == null)
            {
                ambiguityWinner = null;
                return(ImmutableArray <Symbol> .Empty);
            }

            ImmutableArray <Symbol> sortedSymbols = ComputeSortedCrefMembers(syntax, containerOpt, memberName, arity, syntax.Parameters != null, diagnostics);

            if (sortedSymbols.IsEmpty)
            {
                ambiguityWinner = null;
                return(ImmutableArray <Symbol> .Empty);
            }

            return(ProcessCrefMemberLookupResults(
                       sortedSymbols,
                       arity,
                       syntax,
                       typeArgumentListSyntax: null,
                       parameterListSyntax: parameterListSyntax,
                       ambiguityWinner: out ambiguityWinner,
                       diagnostics: diagnostics));
        }
Пример #26
0
        private void AppendMembers(StringBuilder result, NamespaceOrTypeSymbol container, string indent)
        {
            string memberIndent;

            if (container is NamedTypeSymbol)
            {
                memberIndent = indent + "  ";

                result.Append(indent);
                result.AppendLine("{");

                AppendCustomAttributes(result, container, indent, inBlock: true);

                if (container.GetAttributes().Length > 0)
                {
                    result.AppendLine();
                }
            }
            else
            {
                memberIndent = indent;
            }


            foreach (var member in container.GetMembers().OrderBy(m => m.Name, System.StringComparer.InvariantCulture))
            {
                switch (member.Kind)
                {
                case SymbolKind.NamedType:
                    var namedType = (PENamedTypeSymbol)member;
                    result.Append(memberIndent);
                    result.Append(".class ");
                    MetadataSignatureHelper.AppendTypeAttributes(result, namedType.Flags);
                    result.Append(" ");
                    result.Append(member);

                    if (namedType.BaseType() != null)
                    {
                        result.AppendLine();
                        result.Append(memberIndent);
                        result.Append("       extends ");
                        result.Append(namedType.BaseType());
                    }

                    if (namedType.Interfaces().Length > 0)
                    {
                        result.AppendLine();
                        result.Append(memberIndent);
                        result.Append("       implements ");
                        result.Append(string.Join(", ", namedType.Interfaces()));
                    }

                    result.AppendLine();

                    AppendMembers(result, namedType, memberIndent);
                    break;

                case SymbolKind.Namespace:
                    var ns = member as PENamespaceSymbol;
                    if ((object)ns != null)
                    {
                        AppendMembers(result, ns, indent);
                    }
                    break;

                case SymbolKind.Method:
                    var method = member as PEMethodSymbol;
                    if ((object)method != null && method.AssociatedSymbol == null)
                    {
                        result.Append(memberIndent);
                        result.Append(".method ");
                        AppendMethod(result, method, memberIndent);

                        AppendCustomAttributes(result, member, memberIndent, inBlock: false);
                    }
                    break;

                case SymbolKind.Field:
                    var field = (PEFieldSymbol)member;
                    result.Append(memberIndent);
                    result.Append(".field ");

                    MetadataSignatureHelper.AppendFieldAttributes(result, field.Flags);
                    result.Append(" ");

                    result.Append(field.Type);
                    result.Append(" ");
                    result.Append(member.Name);
                    result.AppendLine();

                    AppendCustomAttributes(result, member, memberIndent, inBlock: false);
                    break;

                case SymbolKind.Property:
                    var    property = (PEPropertySymbol)member;
                    string propertyName;

                    result.Append(memberIndent);
                    result.Append(".property ");

                    PropertyAttributes propertyAttrs;
                    ((PEModuleSymbol)container.ContainingModule).Module.GetPropertyDefPropsOrThrow(property.Handle, out propertyName, out propertyAttrs);
                    if (MetadataSignatureHelper.AppendPropertyAttributes(result, propertyAttrs))
                    {
                        result.Append(" ");
                    }

                    result.Append(property.Type);
                    result.Append(" ");
                    result.Append(property.Name);
                    result.AppendLine();

                    result.Append(memberIndent);
                    result.AppendLine("{");

                    AppendCustomAttributes(result, member, memberIndent, inBlock: true);

                    if (property.GetMethod != null)
                    {
                        result.Append(memberIndent);
                        result.Append("  .get ");
                        AppendMethod(result, (PEMethodSymbol)property.GetMethod, memberIndent);
                    }

                    if (property.SetMethod != null)
                    {
                        result.Append(memberIndent);
                        result.Append("  .set ");
                        AppendMethod(result, (PEMethodSymbol)property.SetMethod, memberIndent);
                    }

                    result.Append(memberIndent);
                    result.AppendLine("}");
                    break;

                case SymbolKind.Event:
                    var evnt = (PEEventSymbol)member;

                    result.Append(memberIndent);
                    result.Append(".event ");

                    string          eventName;
                    EventAttributes eventAttrs;
                    EntityHandle    type;
                    ((PEModuleSymbol)container.ContainingModule).Module.GetEventDefPropsOrThrow(evnt.Handle, out eventName, out eventAttrs, out type);

                    if (MetadataSignatureHelper.AppendEventAttributes(result, eventAttrs))
                    {
                        result.Append(" ");
                    }

                    result.Append(evnt.Type);
                    result.Append(" ");
                    result.Append(evnt.Name);
                    result.AppendLine();

                    result.Append(memberIndent);
                    result.Append("{");
                    result.AppendLine();

                    AppendCustomAttributes(result, member, memberIndent, inBlock: true);

                    if (evnt.RemoveMethod != null)
                    {
                        result.Append(memberIndent);
                        result.Append("  .removeon ");
                        AppendMethod(result, (PEMethodSymbol)evnt.RemoveMethod, memberIndent);
                    }

                    if (evnt.AddMethod != null)
                    {
                        result.Append(memberIndent);
                        result.Append("  .addon ");
                        AppendMethod(result, (PEMethodSymbol)evnt.AddMethod, memberIndent);
                    }

                    result.Append(memberIndent);
                    result.AppendLine("}");
                    break;
                }
            }

            if (container is NamedTypeSymbol)
            {
                result.Append(indent);
                result.AppendLine("}");
            }
        }
Пример #27
0
 public static Symbol ChildSymbol(this NamespaceOrTypeSymbol parent, string name)
 {
     return(parent.GetMembers(name).First());
 }
Пример #28
0
 public static NamedTypeSymbol GetTypeMember(this NamespaceOrTypeSymbol symbol, string name)
 {
     return(symbol.GetTypeMembers(name).Single());
 }
 internal override void LookupMembers(LookupResult result, NamespaceOrTypeSymbol nsOrType, string name, int arity, Utilities.ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose)
 {
     options |= LookupOptions.NamespacesOrTypesOnly | LookupOptions.MustNotBeNestedType;
     base.LookupMembers(result, nsOrType, name, arity, basesBeingResolved, options, originalBinder, diagnose);
 }
Пример #30
0
 internal ImplicitTypeSymbol(NamespaceOrTypeSymbol containingSymbol, MergedTypeDeclaration declaration, DiagnosticBag diagnostics)
     : base(containingSymbol, declaration, diagnostics)
 {
 }
Пример #31
0
 public static T GetMember <T>(this NamespaceOrTypeSymbol symbol, string qualifiedName) where T : Symbol
 {
     return((T)symbol.GetMember(qualifiedName));
 }
 internal NamedTypeSymbolBase(NamespaceOrTypeSymbol containingSymbol, string name, int arity, bool isSerializable = false)
 {
     this.containingSymbol = containingSymbol;
     this.name = name;
     this.arity = arity;
 }
Пример #33
0
 private string GetNamespaceOrTypeString(NamespaceOrTypeSymbol symbol)
 {
     return(stringCache.GetOrAdd(symbol, buildNamespaceOrTypeString));
 }
Пример #34
0
        private ImmutableArray <Cci.NamespaceScope> BuildNamespaceScopes(ConsList <Imports> debugImports)
        {
            var namespaceScopes = ArrayBuilder <Cci.NamespaceScope> .GetInstance();

            foreach (Imports imports in debugImports)
            {
                var usedNamespaces = ArrayBuilder <Cci.UsedNamespaceOrType> .GetInstance();

                // NOTE: order based on dev10: extern aliases, then usings, then aliases namespaces and types

                ImmutableArray <AliasAndExternAliasDirective> externAliases = imports.ExternAliases;
                if (!externAliases.IsDefault)
                {
                    foreach (var alias in externAliases)
                    {
                        usedNamespaces.Add(Cci.UsedNamespaceOrType.CreateCSharpExternNamespace(alias.Alias.Name));
                    }
                }

                ImmutableArray <NamespaceOrTypeAndUsingDirective> usings = imports.Usings;
                if (!usings.IsDefault)
                {
                    foreach (var nsOrType in usings)
                    {
                        NamespaceOrTypeSymbol namespaceOrType = nsOrType.NamespaceOrType;
                        if (namespaceOrType.IsNamespace)
                        {
                            NamespaceSymbol @namespace      = (NamespaceSymbol)namespaceOrType;
                            string          namespaceString = GetNamespaceOrTypeString(@namespace);

                            // TODO: incorrect, see bug #913022
                            string externAlias = GetExternAliases(@namespace).FirstOrDefault();

                            usedNamespaces.Add(Cci.UsedNamespaceOrType.CreateCSharpNamespace(namespaceString, externAlias));
                        }
                        else
                        {
                            // This is possible in C# scripts, but the EE doesn't support the meaning intended by script files.
                            // Specifically, when a script includes "using System.Console;" the intended meaning is that the
                            // static methods of System.Console are available but System.Console itself is not.  Even if we output
                            // "TSystem.Console" - which the EE may or may not support - we would only see System.Console become
                            // available.
                        }
                    }
                }

                Dictionary <string, AliasAndUsingDirective> aliasSymbols = imports.UsingAliases;
                if (aliasSymbols != null)
                {
                    foreach (var pair in aliasSymbols)
                    {
                        var alias  = pair.Key;
                        var symbol = pair.Value.Alias;
                        Debug.Assert(!symbol.IsExtern);

                        var target       = symbol.Target;
                        var targetString = GetNamespaceOrTypeString(target);
                        if (target.Kind == SymbolKind.Namespace)
                        {
                            // TODO: incorrect, see bug #913022
                            string externAlias = GetExternAliases((NamespaceSymbol)target).FirstOrDefault();

                            usedNamespaces.Add(Cci.UsedNamespaceOrType.CreateCSharpNamespaceAlias(targetString, alias, externAlias));
                        }
                        else
                        {
                            Debug.Assert(target is TypeSymbol);
                            usedNamespaces.Add(Cci.UsedNamespaceOrType.CreateCSharpTypeAlias(targetString, alias));
                        }
                    }
                }

                namespaceScopes.Add(new Cci.NamespaceScope(usedNamespaces.ToImmutableAndFree()));
            }

            return(namespaceScopes.ToImmutableAndFree()); //NOTE: inner-to-outer order matches dev10
        }
 public NamespaceOrTypeAndUsingDirective(NamespaceOrTypeSymbol namespaceOrType, UsingDirectiveSyntax usingDirective)
 {
     this.NamespaceOrType = namespaceOrType;
     this.UsingDirective  = usingDirective;
 }
 internal override IEnumerable<MemberBuilder> NonContainerBuilders(NamespaceOrTypeSymbol current)
 {
     return ConsList<MemberBuilder>.Empty;
 }
Пример #37
0
 internal abstract IEnumerable<MemberBuilder> NonContainerBuilders(NamespaceOrTypeSymbol current);
Пример #38
0
        private ImmutableArray <Symbol> BindNameMemberCref(NameMemberCrefSyntax syntax, NamespaceOrTypeSymbol containerOpt, out Symbol ambiguityWinner, DiagnosticBag diagnostics)
        {
            SimpleNameSyntax nameSyntax = syntax.Name as SimpleNameSyntax;

            int    arity;
            string memberName;

            if (nameSyntax != null)
            {
                arity      = nameSyntax.Arity;
                memberName = nameSyntax.Identifier.ValueText;
            }
            else
            {
                // If the name isn't a SimpleNameSyntax, then we must have a type name followed by a parameter list.
                // Thus, we're looking for a constructor.
                Debug.Assert((object)containerOpt == null);

                // Could be an error type, but we'll just lookup fail below.
                containerOpt = BindNamespaceOrTypeSymbolInCref(syntax.Name);

                arity      = 0;
                memberName = WellKnownMemberNames.InstanceConstructorName;
            }

            if (string.IsNullOrEmpty(memberName))
            {
                ambiguityWinner = null;
                return(ImmutableArray <Symbol> .Empty);
            }

            ImmutableArray <Symbol> sortedSymbols = ComputeSortedCrefMembers(syntax, containerOpt, memberName, arity, syntax.Parameters != null, diagnostics);

            if (sortedSymbols.IsEmpty)
            {
                ambiguityWinner = null;
                return(ImmutableArray <Symbol> .Empty);
            }

            return(ProcessCrefMemberLookupResults(
                       sortedSymbols,
                       arity,
                       syntax,
                       typeArgumentListSyntax: arity == 0 ? null : ((GenericNameSyntax)nameSyntax).TypeArgumentList,
                       parameterListSyntax: syntax.Parameters,
                       ambiguityWinner: out ambiguityWinner,
                       diagnostics: diagnostics));
        }
Пример #39
0
        /// <summary>
        /// Look for a type forwarder for the given type in any referenced assemblies, checking any using namespaces in
        /// the current imports.
        /// </summary>
        /// <param name="name">The metadata name of the (potentially) forwarded type, without qualifiers.</param>
        /// <param name="qualifierOpt">Will be used to return the namespace of the found forwarder,
        /// if any.</param>
        /// <param name="diagnostics">Will be used to report non-fatal errors during look up.</param>
        /// <param name="location">Location to report errors on.</param>
        /// <returns>Returns the Assembly to which the type is forwarded, or null if none is found.</returns>
        /// <remarks>
        /// Since this method is intended to be used for error reporting, it stops as soon as it finds
        /// any type forwarder (or an error to report). It does not check other assemblies for consistency or better results.
        /// </remarks>
        protected override AssemblySymbol GetForwardedToAssemblyInUsingNamespaces(string name, ref NamespaceOrTypeSymbol qualifierOpt, DiagnosticBag diagnostics, Location location)
        {
            var imports = GetImports(basesBeingResolved: null);

            foreach (var typeOrNamespace in imports.Usings)
            {
                var fullName = typeOrNamespace.NamespaceOrType + "." + name;
                var result   = GetForwardedToAssembly(fullName, diagnostics, location);
                if (result != null)
                {
                    qualifierOpt = typeOrNamespace.NamespaceOrType;
                    return(result);
                }
            }

            return(base.GetForwardedToAssemblyInUsingNamespaces(name, ref qualifierOpt, diagnostics, location));
        }
Пример #40
0
 /// <summary>
 /// the member binders returned from TypeOrNamespaceMemberBinderContexts and
 /// NonContainerMemberBinderContexts are first grouped (be Equals/HashCode)
 /// </summary>
 /// <returns></returns>
 internal abstract IEnumerable<NamespaceOrTypeBuilder> TypeOrNamespaceBuilders(NamespaceOrTypeSymbol current);