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; }
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); }
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()); }
/// <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); } } }
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); }
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)); }
/// <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); }
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)); }
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(); } }
/// <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); } } }
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))); }
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); }
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(); } }
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])); }
/// <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; } } }
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); } }
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; } } }
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()); }
// 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)); }
/// <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); }
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)); }
// 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)); }
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("}"); } }
public static Symbol ChildSymbol(this NamespaceOrTypeSymbol parent, string name) { return(parent.GetMembers(name).First()); }
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); }
internal ImplicitTypeSymbol(NamespaceOrTypeSymbol containingSymbol, MergedTypeDeclaration declaration, DiagnosticBag diagnostics) : base(containingSymbol, declaration, diagnostics) { }
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; }
private string GetNamespaceOrTypeString(NamespaceOrTypeSymbol symbol) { return(stringCache.GetOrAdd(symbol, buildNamespaceOrTypeString)); }
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; }
internal abstract IEnumerable<MemberBuilder> NonContainerBuilders(NamespaceOrTypeSymbol current);
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)); }
/// <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)); }
/// <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);