internal ExtendedErrorTypeSymbol(NamespaceOrTypeSymbol containingSymbol, ImmutableArray<Symbol> candidateSymbols, LookupResultKind resultKind, DiagnosticInfo errorInfo, int arity, bool unreported = false)
     : this(containingSymbol, candidateSymbols[0].Name, arity, errorInfo, unreported)
 {
     _candidateSymbols = UnwrapErrorCandidates(candidateSymbols);
     _resultKind = resultKind;
     Debug.Assert(candidateSymbols.IsEmpty || resultKind != LookupResultKind.Viable, "Shouldn't use LookupResultKind.Viable with candidate symbols");
 }
 internal SynthesizedContainer(MethodSymbol topLevelMethod, string name, TypeKind typeKind)
 {
     this.typeKind = typeKind;
     this.containingSymbol = topLevelMethod.ContainingType;
     this.name = name;
     this.TypeMap = TypeMap.Empty.WithAlphaRename(topLevelMethod, this, out this.typeParameters);
 }
Exemple #3
0
        /// <summary>
        /// Creates a binder with given import computation function.
        /// </summary>
        internal InContainerBinder(Binder next, Func<ConsList<Symbol>, Imports> computeImports)
            : base(next)
        {
            Debug.Assert(computeImports != null);

            _container = null;
            _computeImports = computeImports;
        }
 internal SynthesizedContainer(NamedTypeSymbol containingType, string name, TypeKind typeKind)
 {
     this.typeKind = typeKind;
     this.containingSymbol = containingType;
     this.name = name;
     this.TypeMap = TypeMap.Empty;
     this.typeParameters = ImmutableArray<TypeParameterSymbol>.Empty;
 }
        /// <summary>
        /// Creates a binder with given imports.
        /// </summary>
        internal InContainerBinder(NamespaceOrTypeSymbol container, Binder next, Imports imports = null)
            : base(next)
        {
            Debug.Assert((object)container != null);

            _container = container;
            _imports = imports ?? Imports.Empty;
        }
Exemple #6
0
 internal List<ISymbol> GetLookupSymbols(string testSrc, NamespaceOrTypeSymbol container = null, string name = null, int? arity = null, bool isScript = false, IEnumerable<string> globalUsings = null)
 {
     var tree = Parse(testSrc, options: isScript ? TestOptions.Script : TestOptions.Regular);
     var compilation = CreateCompilationWithMscorlib(tree, options: TestOptions.ReleaseDll.WithUsings(globalUsings));
     var model = compilation.GetSemanticModel(tree);
     var position = testSrc.Contains("/*<bind>*/") ? GetPositionForBinding(tree) : GetPositionForBinding(testSrc);
     return model.LookupSymbols(position, container, name).Where(s => !arity.HasValue || arity == ((Symbol)s).GetMemberArity()).ToList();
 }
        internal ImplicitNamedTypeSymbol(NamespaceOrTypeSymbol containingSymbol, MergedTypeDeclaration declaration, DiagnosticBag diagnostics)
            : base(containingSymbol, declaration, diagnostics)
        {
            Debug.Assert(declaration.Kind == DeclarationKind.ImplicitClass ||
                         declaration.Kind == DeclarationKind.Submission ||
                         declaration.Kind == DeclarationKind.Script);

            state.NotePartComplete(CompletionPart.EnumUnderlyingType); // No work to do for this.
        }
Exemple #8
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);
        }
 private ExtendedErrorTypeSymbol(NamespaceOrTypeSymbol containingSymbol, string name, int arity, DiagnosticInfo errorInfo, bool unreported, bool variableUsedBeforeDeclaration, ImmutableArray<Symbol> candidateSymbols, LookupResultKind resultKind)
 {
     _name = name;
     _errorInfo = errorInfo;
     _containingSymbol = containingSymbol;
     _arity = arity;
     _unreported = unreported;
     this.VariableUsedBeforeDeclaration = variableUsedBeforeDeclaration;
     _candidateSymbols = candidateSymbols;
     _resultKind = resultKind;
 }
        /// <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 allowStaticClassUsings, bool inUsing)
            : base(next)
        {
            Debug.Assert((object)container != null);
            Debug.Assert(declarationSyntax != null);

            _declarationSyntax = declarationSyntax;
            _container = container;
            _allowStaticClassUsings = allowStaticClassUsings;
            _inUsing = inUsing;
        }
 // constructor for dynamic call-site delegate:
 public SynthesizedDelegateSymbol(
     NamespaceOrTypeSymbol containingSymbol,
     string name,
     TypeSymbol objectType,
     TypeSymbol intPtrType,
     TypeSymbol voidReturnTypeOpt,
     int parameterCount,
     BitArray byRefParameters)
     : base(containingSymbol, name, parameterCount, returnsVoid: (object)voidReturnTypeOpt != null)
 {
     this.constructor = new DelegateConstructor(this, objectType, intPtrType);
     this.invoke = new InvokeMethod(this, byRefParameters, voidReturnTypeOpt);
 }
        internal SourceNamedTypeSymbol(NamespaceOrTypeSymbol containingSymbol, MergedTypeDeclaration declaration, DiagnosticBag diagnostics)
            : base(containingSymbol, declaration, diagnostics)
        {
            Debug.Assert(declaration.Kind == DeclarationKind.Struct ||
                         declaration.Kind == DeclarationKind.Interface ||
                         declaration.Kind == DeclarationKind.Enum ||
                         declaration.Kind == DeclarationKind.Delegate ||
                         declaration.Kind == DeclarationKind.Class);

            if (containingSymbol.Kind == SymbolKind.NamedType)
            {
                // Nested types are never unified.
                _lazyIsExplicitDefinitionOfNoPiaLocalType = ThreeState.False;
            }
        }
        internal SourceNamedTypeSymbol(NamespaceOrTypeSymbol containingSymbol, MergedTypeDeclaration declaration, DiagnosticBag diagnostics)
            : base(containingSymbol, declaration, diagnostics)
        {
            Debug.Assert(declaration.Kind == DeclarationKind.Struct ||
                         declaration.Kind == DeclarationKind.Interface ||
                         declaration.Kind == DeclarationKind.Enum ||
                         declaration.Kind == DeclarationKind.Delegate ||
                         declaration.Kind == DeclarationKind.Class);

            if (containingSymbol.Kind == SymbolKind.NamedType)
            {
                // Nested types are never unified.
                _lazyIsExplicitDefinitionOfNoPiaLocalType = ThreeState.False;
            }
        }
        internal static NamespaceOrTypeSymbol OfMinimalArity(this IEnumerable <NamespaceOrTypeSymbol> symbols)
        {
            NamespaceOrTypeSymbol minAritySymbol = null;
            int minArity = Int32.MaxValue;

            foreach (var symbol in symbols)
            {
                int arity = GetMemberArity(symbol);
                if (arity < minArity)
                {
                    minArity       = arity;
                    minAritySymbol = symbol;
                }
            }

            return(minAritySymbol);
        }
        internal ExtendedErrorTypeSymbol(NamespaceOrTypeSymbol containingSymbol, string name, int arity, DiagnosticInfo errorInfo, bool unreported = false, bool variableUsedBeforeDeclaration = false)
        {
            Debug.Assert(((object)containingSymbol == null) ||
                (containingSymbol.Kind == SymbolKind.Namespace) ||
                (containingSymbol.Kind == SymbolKind.NamedType) ||
                (containingSymbol.Kind == SymbolKind.ErrorType));

            Debug.Assert(name != null);
            Debug.Assert(unreported == false || errorInfo != null);

            _name = name;
            _errorInfo = errorInfo;
            _containingSymbol = containingSymbol;
            _arity = arity;
            _unreported = unreported;
            this.VariableUsedBeforeDeclaration = variableUsedBeforeDeclaration;
            _resultKind = LookupResultKind.Empty;
        }
        /// <summary>
        /// Used for <see cref="SynthesizedDelegateSymbol"/> construction.
        /// </summary>
        protected SynthesizedContainer(NamespaceOrTypeSymbol containingSymbol, string name, int parameterCount, bool returnsVoid)
        {
            var typeParameters = new TypeParameterSymbol[parameterCount + (returnsVoid ? 0 : 1)];
            for (int i = 0; i < parameterCount; i++)
            {
                typeParameters[i] = new AnonymousTypeManager.AnonymousTypeParameterSymbol(this, i, "T" + (i + 1));
            }

            if (!returnsVoid)
            {
                typeParameters[parameterCount] = new AnonymousTypeManager.AnonymousTypeParameterSymbol(this, parameterCount, "TResult");
            }

            this.containingSymbol = containingSymbol;
            this.name = name;
            this.TypeMap = TypeMap.Empty;
            this.typeParameters = typeParameters.AsImmutableOrNull();
        }
        internal ExtendedErrorTypeSymbol(NamespaceOrTypeSymbol containingSymbol, string name, int arity, DiagnosticInfo errorInfo, bool unreported = false, bool variableUsedBeforeDeclaration = false)
        {
            Debug.Assert(((object)containingSymbol == null) ||
                         (containingSymbol.Kind == SymbolKind.Namespace) ||
                         (containingSymbol.Kind == SymbolKind.NamedType) ||
                         (containingSymbol.Kind == SymbolKind.ErrorType));

            Debug.Assert(name != null);
            Debug.Assert(unreported == false || errorInfo != null);

            _name             = name;
            _errorInfo        = errorInfo;
            _containingSymbol = containingSymbol;
            _arity            = arity;
            _unreported       = unreported;
            this.VariableUsedBeforeDeclaration = variableUsedBeforeDeclaration;
            _resultKind = LookupResultKind.Empty;
        }
        /// <summary>
        /// Used for <see cref="SynthesizedDelegateSymbol"/> construction.
        /// </summary>
        protected SynthesizedContainer(NamespaceOrTypeSymbol containingSymbol, string name, int parameterCount, bool returnsVoid)
        {
            var typeParameters = new TypeParameterSymbol[parameterCount + (returnsVoid ? 0 : 1)];

            for (int i = 0; i < parameterCount; i++)
            {
                typeParameters[i] = new AnonymousTypeManager.AnonymousTypeParameterSymbol(this, i, "T" + (i + 1));
            }

            if (!returnsVoid)
            {
                typeParameters[parameterCount] = new AnonymousTypeManager.AnonymousTypeParameterSymbol(this, parameterCount, "TResult");
            }

            this.containingSymbol = containingSymbol;
            this.name             = name;
            this.TypeMap          = TypeMap.Empty;
            this.typeParameters   = typeParameters.AsImmutableOrNull();
        }
Exemple #19
0
            public Dictionary <String, ImmutableArray <NamespaceOrTypeSymbol> > CreateMap()
            {
                var result = new Dictionary <String, ImmutableArray <NamespaceOrTypeSymbol> >(_dictionary.Count, StringOrdinalComparer.Instance);

                foreach (var kvp in _dictionary)
                {
                    object value = kvp.Value;
                    ImmutableArray <NamespaceOrTypeSymbol> members;

                    var builder = value as ArrayBuilder <NamespaceOrTypeSymbol>;
                    if (builder != null)
                    {
                        Debug.Assert(builder.Count > 1);
                        bool hasNamespaces = false;
                        for (int i = 0; (i < builder.Count) && !hasNamespaces; i++)
                        {
                            hasNamespaces |= (builder[i].Kind == SymbolKind.Namespace);
                        }

                        members = hasNamespaces
                            ? builder.ToImmutable()
                            : StaticCast <NamespaceOrTypeSymbol> .From(builder.ToDowncastedImmutable <NamedTypeSymbol>());

                        builder.Free();
                    }
                    else
                    {
                        NamespaceOrTypeSymbol symbol = (NamespaceOrTypeSymbol)value;

                        #region PackageTemplate - SourceNamespaceSymbol - SymbolKind.Template
                        members = (symbol.Kind == SymbolKind.Namespace || symbol.Kind == SymbolKind.Template)
                            ? ImmutableArray.Create <NamespaceOrTypeSymbol>(symbol)
                            : StaticCast <NamespaceOrTypeSymbol> .From(ImmutableArray.Create <NamedTypeSymbol>((NamedTypeSymbol)symbol));

                        #endregion
                    }

                    result.Add(kvp.Key, members);
                }

                return(result);
            }
Exemple #20
0
        /// <summary>
        /// Finds types or namespaces described by a qualified name.
        /// </summary>
        /// <param name="qualifiedName">Sequence of simple plain names.</param>
        /// <returns>
        /// A set of namespace or type symbols with given qualified name (might comprise of types with multiple generic arities),
        /// or an empty set if the member can't be found (the qualified name is ambiguous or the symbol doesn't exist).
        /// </returns>
        /// <remarks>
        /// "C.D" matches C.D, C{T}.D, C{S,T}.D{U}, etc.
        /// </remarks>
        internal IEnumerable <NamespaceOrTypeSymbol> GetNamespaceOrTypeByQualifiedName(IEnumerable <string> qualifiedName)
        {
            NamespaceOrTypeSymbol namespaceOrType       = this;
            IEnumerable <NamespaceOrTypeSymbol> symbols = null;

            foreach (string name in qualifiedName)
            {
                if (symbols != null)
                {
                    // there might be multiple types of different arity, prefer a non-generic type:
                    namespaceOrType = symbols.OfMinimalArity();
                    if ((object)namespaceOrType == null)
                    {
                        return(SpecializedCollections.EmptyEnumerable <NamespaceOrTypeSymbol>());
                    }
                }

                symbols = namespaceOrType.GetMembers(name).OfType <NamespaceOrTypeSymbol>();
            }

            return(symbols);
        }
Exemple #21
0
            public void Add(NamespaceOrTypeSymbol symbol)
            {
                string name = symbol.Name;
                object item;

                if (_dictionary.TryGetValue(name, out item))
                {
                    var builder = item as ArrayBuilder <NamespaceOrTypeSymbol>;
                    if (builder == null)
                    {
                        builder = ArrayBuilder <NamespaceOrTypeSymbol> .GetInstance();

                        builder.Add((NamespaceOrTypeSymbol)item);
                        _dictionary[name] = builder;
                    }
                    builder.Add(symbol);
                }
                else
                {
                    _dictionary[name] = symbol;
                }
            }
Exemple #22
0
            public Dictionary <String, ImmutableArray <NamespaceOrTypeSymbol> > CreateMap()
            {
                var result = new Dictionary <String, ImmutableArray <NamespaceOrTypeSymbol> >(this.dictionary.Count);

                foreach (var kvp in this.dictionary)
                {
                    object value = kvp.Value;
                    ImmutableArray <NamespaceOrTypeSymbol> members;

                    var builder = value as ArrayBuilder <NamespaceOrTypeSymbol>;
                    if (builder != null)
                    {
                        Debug.Assert(builder.Count > 1);
                        bool hasNamespaces = false;
                        for (int i = 0; (i < builder.Count) && !hasNamespaces; i++)
                        {
                            hasNamespaces |= (builder[i].Kind == SymbolKind.Namespace);
                        }

                        members = hasNamespaces
                            ? builder.ToImmutable()
                            : StaticCast <NamespaceOrTypeSymbol> .From(builder.ToDowncastedImmutable <NamedTypeSymbol>());

                        builder.Free();
                    }
                    else
                    {
                        NamespaceOrTypeSymbol symbol = (NamespaceOrTypeSymbol)value;
                        members = symbol.Kind == SymbolKind.Namespace
                            ? ImmutableArray.Create <NamespaceOrTypeSymbol>(symbol)
                            : StaticCast <NamespaceOrTypeSymbol> .From(ImmutableArray.Create <NamedTypeSymbol>((NamedTypeSymbol)symbol));
                    }

                    result.Add(kvp.Key, members);
                }

                return(result);
            }
Exemple #23
0
        internal SourceNamedTypeSymbol(NamespaceOrTypeSymbol containingSymbol, MergedTypeDeclaration declaration, DiagnosticBag diagnostics)
            : base(containingSymbol, declaration, diagnostics)
        {
            Debug.Assert(declaration.Kind == DeclarationKind.Struct ||
                         declaration.Kind == DeclarationKind.Interface ||
                         declaration.Kind == DeclarationKind.Enum ||
                         declaration.Kind == DeclarationKind.Delegate ||
                         declaration.Kind == DeclarationKind.Class);

            if (containingSymbol.Kind == SymbolKind.NamedType)
            {
                // Nested types are never unified.
                _lazyIsExplicitDefinitionOfNoPiaLocalType = ThreeState.False;
            }

            if (declaration.Arity == 0 && declaration.HasConstraints)
            {
                foreach (var syntaxRef in this.SyntaxReferences)
                {
                    var constraintClauses = GetConstraintClauses((CSharpSyntaxNode)syntaxRef.GetSyntax());
                    ReportErrorIfHasConstraints(constraintClauses, diagnostics);
                }
            }
        }
Exemple #24
0
        /// <summary>
        /// Lookup an immediately nested type referenced from metadata, names should be
        /// compared case-sensitively.
        /// </summary>
        /// <param name="emittedTypeName">
        /// Simple type name, possibly with generic name mangling.
        /// </param>
        /// <returns>
        /// Symbol for the type, or MissingMetadataSymbol if the type isn't found.
        /// </returns>
        internal virtual NamedTypeSymbol LookupMetadataType(ref MetadataTypeName emittedTypeName)
        {
            Debug.Assert(!emittedTypeName.IsNull);

            NamespaceOrTypeSymbol scope = this;

            if (scope.Kind == SymbolKind.ErrorType)
            {
                return(new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName));
            }

            NamedTypeSymbol namedType = null;

            ImmutableArray <NamedTypeSymbol> namespaceOrTypeMembers;
            bool isTopLevel = scope.IsNamespace;

            Debug.Assert(!isTopLevel || scope.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat) == emittedTypeName.NamespaceName);

            if (emittedTypeName.IsMangled)
            {
                Debug.Assert(!emittedTypeName.UnmangledTypeName.Equals(emittedTypeName.TypeName) && emittedTypeName.InferredArity > 0);

                if (emittedTypeName.ForcedArity == -1 || emittedTypeName.ForcedArity == emittedTypeName.InferredArity)
                {
                    // Let's handle mangling case first.
                    namespaceOrTypeMembers = scope.GetTypeMembers(emittedTypeName.UnmangledTypeName);

                    foreach (var named in namespaceOrTypeMembers)
                    {
                        if (emittedTypeName.InferredArity == named.Arity && named.MangleName)
                        {
                            if ((object)namedType != null)
                            {
                                namedType = null;
                                break;
                            }

                            namedType = named;
                        }
                    }
                }
            }
            else
            {
                Debug.Assert(ReferenceEquals(emittedTypeName.UnmangledTypeName, emittedTypeName.TypeName) && emittedTypeName.InferredArity == 0);
            }

            // Now try lookup without removing generic arity mangling.
            int forcedArity = emittedTypeName.ForcedArity;

            if (emittedTypeName.UseCLSCompliantNameArityEncoding)
            {
                // Only types with arity 0 are acceptable, we already examined types with mangled names.
                if (emittedTypeName.InferredArity > 0)
                {
                    goto Done;
                }
                else if (forcedArity == -1)
                {
                    forcedArity = 0;
                }
                else if (forcedArity != 0)
                {
                    goto Done;
                }
                else
                {
                    Debug.Assert(forcedArity == emittedTypeName.InferredArity);
                }
            }

            namespaceOrTypeMembers = scope.GetTypeMembers(emittedTypeName.TypeName);

            foreach (var named in namespaceOrTypeMembers)
            {
                if (!named.MangleName && (forcedArity == -1 || forcedArity == named.Arity))
                {
                    if ((object)namedType != null)
                    {
                        namedType = null;
                        break;
                    }

                    namedType = named;
                }
            }

Done:
            if ((object)namedType == null)
            {
                if (isTopLevel)
                {
                    return(new MissingMetadataTypeSymbol.TopLevel(scope.ContainingModule, ref emittedTypeName));
                }
                else
                {
                    return(new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName));
                }
            }

            return(namedType);
        }
 public void Add(NamespaceOrTypeSymbol symbol)
 {
     string name = symbol.Name;
     object item;
     if (_dictionary.TryGetValue(name, out item))
     {
         var builder = item as ArrayBuilder<NamespaceOrTypeSymbol>;
         if (builder == null)
         {
             builder = ArrayBuilder<NamespaceOrTypeSymbol>.GetInstance();
             builder.Add((NamespaceOrTypeSymbol)item);
             _dictionary[name] = builder;
         }
         builder.Add(symbol);
     }
     else
     {
         _dictionary[name] = symbol;
     }
 }
        private Symbol GetDeclaredMember(NamespaceOrTypeSymbol container, TextSpan declarationSpan, NameSyntax name)
        {
            switch (name.Kind())
            {
                case SyntaxKind.GenericName:
                case SyntaxKind.IdentifierName:
                    return GetDeclaredMember(container, declarationSpan, ((SimpleNameSyntax)name).Identifier.ValueText);

                case SyntaxKind.QualifiedName:
                    var qn = (QualifiedNameSyntax)name;
                    var left = GetDeclaredMember(container, declarationSpan, qn.Left) as NamespaceOrTypeSymbol;
                    Debug.Assert((object)left != null);
                    return GetDeclaredMember(left, declarationSpan, qn.Right);

                case SyntaxKind.AliasQualifiedName:
                    // this is not supposed to happen, but we allow for errors don't we!
                    var an = (AliasQualifiedNameSyntax)name;
                    return GetDeclaredMember(container, declarationSpan, an.Name);

                default:
                    throw ExceptionUtilities.UnexpectedValue(name.Kind());
            }
        }
Exemple #27
0
        private static bool TryAddImport(
            string alias,
            NamespaceOrTypeSymbol targetSymbol,
            ArrayBuilder<NamespaceOrTypeAndUsingDirective> usingsBuilder,
            ImmutableDictionary<string, AliasAndUsingDirective>.Builder usingAliases,
            InContainerBinder binder,
            ImportRecord importRecord)
        {
            if (alias == null)
            {
                usingsBuilder.Add(new NamespaceOrTypeAndUsingDirective(targetSymbol, usingDirective: null));
            }
            else
            {
                IdentifierNameSyntax aliasSyntax;
                if (!TryParseIdentifierNameSyntax(alias, out aliasSyntax))
                {
                    Debug.WriteLine($"Import record '{importRecord}' has syntactically invalid alias '{alias}'");
                    return false;
                }

                var aliasSymbol = AliasSymbol.CreateCustomDebugInfoAlias(targetSymbol, aliasSyntax.Identifier, binder);
                usingAliases.Add(alias, new AliasAndUsingDirective(aliasSymbol, usingDirective: null));
            }

            return true;
        }
 internal ExtendedErrorTypeSymbol(NamespaceOrTypeSymbol guessSymbol, LookupResultKind resultKind, DiagnosticInfo errorInfo, bool unreported = false)
     : this(guessSymbol.ContainingNamespaceOrType(), guessSymbol, resultKind, errorInfo, unreported)
 {
 }
Exemple #29
0
        private void AppendSymbolsWithNameAndArity(
            ArrayBuilder<Symbol> results,
            string name,
            int arity,
            Binder binder,
            NamespaceOrTypeSymbol container,
            LookupOptions options)
        {
            Debug.Assert(results != null);

            // Don't need to de-dup since AllMethodsOnArityZero can't be set at this point (not exposed in CommonLookupOptions).
            Debug.Assert((options & LookupOptions.AllMethodsOnArityZero) == 0);

            var lookupResult = LookupResult.GetInstance();

            HashSet<DiagnosticInfo> useSiteDiagnostics = null;
            binder.LookupSymbolsSimpleName(
                lookupResult,
                container,
                name,
                arity,
                basesBeingResolved: null,
                options: options & ~LookupOptions.IncludeExtensionMethods,
                diagnose: false,
                useSiteDiagnostics: ref useSiteDiagnostics);

            if (lookupResult.IsMultiViable)
            {
                if (lookupResult.Symbols.Any(t => t.Kind == SymbolKind.NamedType || t.Kind == SymbolKind.Namespace || t.Kind == SymbolKind.ErrorType))
                {
                    // binder.ResultSymbol is defined only for type/namespace lookups
                    bool wasError;
                    var diagnostics = DiagnosticBag.GetInstance();  // client code never expects a null diagnostic bag.
                    Symbol singleSymbol = binder.ResultSymbol(lookupResult, name, arity, this.Root, diagnostics, true, out wasError, container, options);
                    diagnostics.Free();

                    if (!wasError)
                    {
                        results.Add(singleSymbol);
                    }
                    else
                    {
                        results.AddRange(lookupResult.Symbols);
                    }
                }
                else
                {
                    results.AddRange(lookupResult.Symbols);
                }
            }

            lookupResult.Free();
        }
Exemple #30
0
        private void AppendSymbolsWithName(ArrayBuilder<Symbol> results, string name, Binder binder, NamespaceOrTypeSymbol container, LookupOptions options, LookupSymbolsInfo info)
        {
            LookupSymbolsInfo.IArityEnumerable arities;
            Symbol uniqueSymbol;

            if (info.TryGetAritiesAndUniqueSymbol(name, out arities, out uniqueSymbol))
            {
                if ((object)uniqueSymbol != null)
                {
                    // This name mapped to something unique.  We don't need to proceed
                    // with a costly lookup.  Just add it straight to the results.
                    results.Add(uniqueSymbol);
                }
                else
                {
                    // The name maps to multiple symbols. Actually do a real lookup so 
                    // that we will properly figure out hiding and whatnot.
                    if (arities != null)
                    {
                        foreach (var arity in arities)
                        {
                            this.AppendSymbolsWithNameAndArity(results, name, arity, binder, container, options);
                        }
                    }
                    else
                    {
                        //non-unique symbol with non-zero arity doesn't seem possible.
                        this.AppendSymbolsWithNameAndArity(results, name, 0, binder, container, options);
                    }
                }
            }
        }
Exemple #31
0
        /// <summary>
        /// Gets the available named symbols in the context of the specified location and optional
        /// container. Only symbols that are accessible and visible from the given location are
        /// returned.
        /// </summary>
        /// <param name="position">The character position for determining the enclosing declaration
        /// scope and accessibility.</param>
        /// <param name="container">The container to search for symbols within. If null then the
        /// enclosing declaration scope around position is used.</param>
        /// <param name="name">The name of the symbol to find. If null is specified then symbols
        /// with any names are returned.</param>
        /// <param name="options">Additional options that affect the lookup process.</param>
        /// <param name="useBaseReferenceAccessibility">Ignore 'throughType' in accessibility checking. 
        /// Used in checking accessibility of symbols accessed via 'MyBase' or 'base'.</param>
        /// <remarks>
        /// The "position" is used to determine what variables are visible and accessible. Even if
        /// "container" is specified, the "position" location is significant for determining which
        /// members of "containing" are accessible. 
        /// </remarks>
        /// <exception cref="ArgumentException">Throws an argument exception if the passed lookup options are invalid.</exception>
        private ImmutableArray<Symbol> LookupSymbolsInternal(
            int position,
            NamespaceOrTypeSymbol container,
            string name,
            LookupOptions options,
            bool useBaseReferenceAccessibility)
        {
            Debug.Assert((options & LookupOptions.UseBaseReferenceAccessibility) == 0, "Use the useBaseReferenceAccessibility parameter.");
            if (useBaseReferenceAccessibility)
            {
                options |= LookupOptions.UseBaseReferenceAccessibility;
            }
            Debug.Assert(!options.IsAttributeTypeLookup()); // Not exposed publicly.

            options.ThrowIfInvalid();

            SyntaxToken token;
            position = CheckAndAdjustPosition(position, out token);

            if ((object)container == null || container.Kind == SymbolKind.Namespace)
            {
                options &= ~LookupOptions.IncludeExtensionMethods;
            }

            var binder = GetEnclosingBinder(position);
            if (binder == null)
            {
                return ImmutableArray<Symbol>.Empty;
            }

            if (useBaseReferenceAccessibility)
            {
                Debug.Assert((object)container == null);
                TypeSymbol containingType = binder.ContainingType;
                TypeSymbol baseType = null;

                // For a script class or a submission class base should have no members.
                if ((object)containingType != null && containingType.Kind == SymbolKind.NamedType && ((NamedTypeSymbol)containingType).IsScriptClass)
                {
                    return ImmutableArray<Symbol>.Empty;
                }

                if ((object)containingType == null || (object)(baseType = containingType.BaseTypeNoUseSiteDiagnostics) == null)
                {
                    throw new ArgumentException(
                        "Not a valid position for a call to LookupBaseMembers (must be in a type with a base type)",
                        nameof(position));
                }
                container = baseType;
            }

            if (!binder.IsInMethodBody &&
                (options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.NamespacesOrTypesOnly | LookupOptions.LabelsOnly)) == 0)
            {
                // Method type parameters are not in scope outside a method
                // body unless the position is either:
                // a) in a type-only context inside an expression, or
                // b) inside of an XML name attribute in an XML doc comment.
                var parentExpr = token.Parent as ExpressionSyntax;
                if (parentExpr != null && !(parentExpr.Parent is XmlNameAttributeSyntax) && !SyntaxFacts.IsInTypeOnlyContext(parentExpr))
                {
                    options |= LookupOptions.MustNotBeMethodTypeParameter;
                }
            }

            var info = LookupSymbolsInfo.GetInstance();

            if ((object)container == null)
            {
                binder.AddLookupSymbolsInfo(info, options);
            }
            else
            {
                binder.AddMemberLookupSymbolsInfo(info, container, options, binder);
            }

            var results = ArrayBuilder<Symbol>.GetInstance(info.Count);

            if (name == null)
            {
                // If they didn't provide a name, then look up all names and associated arities 
                // and find all the corresponding symbols.
                foreach (string foundName in info.Names)
                {
                    AppendSymbolsWithName(results, foundName, binder, container, options, info);
                }
            }
            else
            {
                // They provided a name.  Find all the arities for that name, and then look all of those up.
                AppendSymbolsWithName(results, name, binder, container, options, info);
            }

            info.Free();


            if ((options & LookupOptions.IncludeExtensionMethods) != 0)
            {
                var lookupResult = LookupResult.GetInstance();

                options |= LookupOptions.AllMethodsOnArityZero;
                options &= ~LookupOptions.MustBeInstance;

                HashSet<DiagnosticInfo> useSiteDiagnostics = null;
                binder.LookupExtensionMethods(lookupResult, name, 0, options, ref useSiteDiagnostics);

                if (lookupResult.IsMultiViable)
                {
                    TypeSymbol containingType = (TypeSymbol)container;
                    foreach (MethodSymbol extensionMethod in lookupResult.Symbols)
                    {
                        var reduced = extensionMethod.ReduceExtensionMethod(containingType);
                        if ((object)reduced != null)
                        {
                            results.Add(reduced);
                        }
                    }
                }

                lookupResult.Free();
            }

            ImmutableArray<Symbol> sealedResults = results.ToImmutableAndFree();
            return name == null
                ? FilterNotReferencable(sealedResults)
                : sealedResults;
        }
        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);
        }
        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);
        }
 internal ExtendedErrorTypeSymbol(NamespaceOrTypeSymbol containingSymbol, Symbol guessSymbol, LookupResultKind resultKind, DiagnosticInfo errorInfo, bool unreported = false)
     : this(containingSymbol, ImmutableArray.Create <Symbol>(guessSymbol), resultKind, errorInfo, GetArity(guessSymbol), unreported)
 {
 }
        // 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.CSharpKind();
            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);
        }
Exemple #36
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("}");
            }
        }
        // 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.CSharpKind() == 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 == 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);
        }
        /// <summary>
        /// Finds the member in the containing symbol which is inside the given declaration span.
        /// </summary>
        private Symbol GetDeclaredMember(NamespaceOrTypeSymbol container, TextSpan declarationSpan, string name = null)
        {
            if ((object)container == null)
            {
                return null;
            }

            // look for any member with same declaration location
            var collection = name != null ? container.GetMembers(name) : container.GetMembersUnordered();

            Symbol zeroWidthMatch = null;
            foreach (var symbol in collection)
            {
                var namedType = symbol as ImplicitNamedTypeSymbol;
                if ((object)namedType != null && namedType.IsImplicitClass)
                {
                    // look inside wrapper around illegally placed members in namespaces
                    var result = GetDeclaredMember(namedType, declarationSpan, name);
                    if ((object)result != null)
                    {
                        return result;
                    }
                }

                foreach (var loc in symbol.Locations)
                {
                    if (loc.IsInSource && loc.SourceTree == this.SyntaxTree && declarationSpan.Contains(loc.SourceSpan))
                    {
                        if (loc.SourceSpan.IsEmpty && loc.SourceSpan.End == declarationSpan.Start)
                        {
                            // exclude decls created via syntax recovery
                            zeroWidthMatch = symbol;
                        }
                        else
                        {
                            return symbol;
                        }
                    }
                }

                // Handle the case of the implementation of a partial method.
                var partial = symbol.Kind == SymbolKind.Method
                    ? ((MethodSymbol)symbol).PartialImplementationPart
                    : null;
                if ((object)partial != null)
                {
                    var loc = partial.Locations[0];
                    if (loc.IsInSource && loc.SourceTree == this.SyntaxTree && declarationSpan.Contains(loc.SourceSpan))
                    {
                        return partial;
                    }
                }
            }

            // If we didn't find anything better than the symbol that matched because of syntax error recovery, then return that.
            // Otherwise, if there's a name, try again without a name.
            // Otherwise, give up.
            return zeroWidthMatch ??
                (name != null ? GetDeclaredMember(container, declarationSpan) : null);
        }
 /// <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;
 }
        /// <summary>
        /// Lookup an immediately nested type referenced from metadata, names should be
        /// compared case-sensitively.
        /// </summary>
        /// <param name="emittedTypeName">
        /// Simple type name, possibly with generic name mangling.
        /// </param>
        /// <returns>
        /// Symbol for the type, or MissingMetadataSymbol if the type isn't found.
        /// </returns>
        internal virtual NamedTypeSymbol LookupMetadataType(ref MetadataTypeName emittedTypeName)
        {
            Debug.Assert(!emittedTypeName.IsNull);

            NamespaceOrTypeSymbol scope = this;

            Debug.Assert(scope is not MergedNamespaceSymbol);

            if (scope.Kind == SymbolKind.ErrorType)
            {
                return(new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName));
            }

            NamedTypeSymbol?namedType = null;

            ImmutableArray <NamedTypeSymbol> namespaceOrTypeMembers;
            bool isTopLevel = scope.IsNamespace;

            Debug.Assert(!isTopLevel || scope.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat) == emittedTypeName.NamespaceName);

            if (emittedTypeName.IsMangled)
            {
                Debug.Assert(!emittedTypeName.UnmangledTypeName.Equals(emittedTypeName.TypeName) && emittedTypeName.InferredArity > 0);

                if (emittedTypeName.ForcedArity == -1 || emittedTypeName.ForcedArity == emittedTypeName.InferredArity)
                {
                    // Let's handle mangling case first.
                    namespaceOrTypeMembers = scope.GetTypeMembers(emittedTypeName.UnmangledTypeName);

                    foreach (var named in namespaceOrTypeMembers)
                    {
                        if (emittedTypeName.InferredArity == named.Arity && named.MangleName)
                        {
                            if ((object?)namedType != null)
                            {
                                namedType = null;
                                break;
                            }

                            namedType = named;
                        }
                    }
                }
            }
            else
            {
                Debug.Assert(ReferenceEquals(emittedTypeName.UnmangledTypeName, emittedTypeName.TypeName) && emittedTypeName.InferredArity == 0);
            }

            // Now try lookup without removing generic arity mangling.
            int forcedArity = emittedTypeName.ForcedArity;

            if (emittedTypeName.UseCLSCompliantNameArityEncoding)
            {
                // Only types with arity 0 are acceptable, we already examined types with mangled names.
                if (emittedTypeName.InferredArity > 0)
                {
                    goto Done;
                }
                else if (forcedArity == -1)
                {
                    forcedArity = 0;
                }
                else if (forcedArity != 0)
                {
                    goto Done;
                }
                else
                {
                    Debug.Assert(forcedArity == emittedTypeName.InferredArity);
                }
            }

            namespaceOrTypeMembers = scope.GetTypeMembers(emittedTypeName.TypeName);

            foreach (var named in namespaceOrTypeMembers)
            {
                if (!named.MangleName && (forcedArity == -1 || forcedArity == named.Arity))
                {
                    if ((object?)namedType != null)
                    {
                        namedType = null;
                        break;
                    }

                    namedType = named;
                }
            }

Done:
            if (isTopLevel &&
                scope is not PENamespaceSymbol &&
                (emittedTypeName.ForcedArity == -1 || emittedTypeName.ForcedArity == emittedTypeName.InferredArity) &&
                GeneratedNameParser.TryParseFileTypeName(
                    emittedTypeName.UnmangledTypeName,
                    out string?displayFileName,
                    out int ordinal,
                    out string?sourceName))
            {
                // also do a lookup for file types from source.
                namespaceOrTypeMembers = scope.GetTypeMembers(sourceName);
                foreach (var named in namespaceOrTypeMembers)
                {
                    if (named.AssociatedSyntaxTree is SyntaxTree tree &&
                        getDisplayName(tree) == displayFileName &&
                        named.DeclaringCompilation.GetSyntaxTreeOrdinal(tree) == ordinal &&
                        named.Arity == emittedTypeName.InferredArity)
                    {
                        if ((object?)namedType != null)
                        {
                            namedType = null;
                            break;
                        }

                        namedType = named;
                    }
                }
            }

            if ((object?)namedType == null)
            {
                if (isTopLevel)
                {
                    return(new MissingMetadataTypeSymbol.TopLevel(scope.ContainingModule, ref emittedTypeName));
                }
                else
                {
                    return(new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName));
                }
            }

            return(namedType);
        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="Foo"/>
                    //   class Foo<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 Foo<T>. Now however, it finds Foo<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();
        }
 public NamespaceOrTypeAndUsingDirective(NamespaceOrTypeSymbol namespaceOrType, UsingDirectiveSyntax usingDirective)
 {
     this.NamespaceOrType = namespaceOrType;
     this.UsingDirective = usingDirective;
 }
        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);
                var noTrivia = syntax.WithLeadingTrivia(null).WithTrailingTrivia(null);
                diagnostics.Add(ErrorCode.WRN_BadXMLRef, crefSyntax.Location, noTrivia.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);
                var noTrivia = syntax.WithLeadingTrivia(null).WithTrailingTrivia(null);
                diagnostics.Add(ErrorCode.WRN_BadXMLRef, crefSyntax.Location, noTrivia.ToFullString());
            }

            return result;
        }
Exemple #44
0
 internal static AliasSymbol CreateCustomDebugInfoAlias(NamespaceOrTypeSymbol targetSymbol, SyntaxToken aliasToken, InContainerBinder binder)
 {
     return(new AliasSymbol(binder, targetSymbol, aliasToken, ImmutableArray.Create(aliasToken.GetLocation())));
 }
Exemple #45
0
 internal static AliasSymbol CreateCustomDebugInfoAlias(NamespaceOrTypeSymbol targetSymbol, SyntaxToken aliasToken, Symbol containingSymbol, bool isExtern)
 {
     return(new AliasSymbolFromResolvedTarget(targetSymbol, aliasToken.ValueText, containingSymbol, ImmutableArray.Create(aliasToken.GetLocation()), isExtern));
 }