internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies) { int forcedArity = emittedName.ForcedArity; if (emittedName.UseCLSCompliantNameArityEncoding) { if (forcedArity == -1) { forcedArity = emittedName.InferredArity; } else if (forcedArity != emittedName.InferredArity) { return(null); } Debug.Assert(forcedArity == emittedName.InferredArity); } //if (_lazyForwardedTypesFromSource == null) //{ // IDictionary<string, NamedTypeSymbol> forwardedTypesFromSource; // CommonAssemblyWellKnownAttributeData<NamedTypeSymbol> wellKnownAttributeData = GetSourceDecodedWellKnownAttributeData(); // if (wellKnownAttributeData != null && wellKnownAttributeData.ForwardedTypes != null) // { // forwardedTypesFromSource = new Dictionary<string, NamedTypeSymbol>(); // foreach (NamedTypeSymbol forwardedType in wellKnownAttributeData.ForwardedTypes) // { // NamedTypeSymbol originalDefinition = forwardedType.OriginalDefinition; // Debug.Assert((object)originalDefinition.ContainingType == null, "How did a nested type get forwarded?"); // string fullEmittedName = MetadataHelpers.BuildQualifiedName(originalDefinition.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat), // originalDefinition.MetadataName); // // Since we need to allow multiple constructions of the same generic type at the source // // level, we need to de-dup the original definitions. // forwardedTypesFromSource[fullEmittedName] = originalDefinition; // } // } // else // { // forwardedTypesFromSource = SpecializedCollections.EmptyDictionary<string, NamedTypeSymbol>(); // } // _lazyForwardedTypesFromSource = forwardedTypesFromSource; //} //NamedTypeSymbol result; //if (_lazyForwardedTypesFromSource.TryGetValue(emittedName.FullName, out result)) //{ // if ((forcedArity == -1 || result.Arity == forcedArity) && // (!emittedName.UseCLSCompliantNameArityEncoding || result.Arity == 0 || result.MangleName)) // { // return result; // } //} //else if (!_compilation.Options.OutputKind.IsNetModule()) //{ // // See if any of added modules forward the type. // // Similar to attributes, type forwarders from the second added module should override type forwarders from the first added module, etc. // for (int i = _modules.Length - 1; i > 0; i--) // { // var peModuleSymbol = (Metadata.PE.PEModuleSymbol)_modules[i]; // var forwardedToAssembly = peModuleSymbol.GetAssemblyForForwardedType(ref emittedName); // if ((object)forwardedToAssembly != null) // { // // Don't bother to check the forwarded-to assembly if we've already seen it. // if (visitedAssemblies != null && visitedAssemblies.Contains(forwardedToAssembly)) // { // return CreateCycleInTypeForwarderErrorTypeSymbol(ref emittedName); // } // else // { // visitedAssemblies = new ConsList<AssemblySymbol>(this, visitedAssemblies ?? ConsList<AssemblySymbol>.Empty); // return forwardedToAssembly.LookupTopLevelMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies, digThroughForwardedTypes: true); // } // } // } //} return(null); }
internal override NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName) { return new MissingMetadataTypeSymbol.TopLevel(this, ref emittedName); }
/// <summary> /// If this module forwards the given type to another assembly, return that assembly; /// otherwise, return null. /// </summary> /// <param name="fullName">Type to look up.</param> /// <returns>Assembly symbol or null.</returns> /// <remarks> /// The returned assembly may also forward the type. /// </remarks> internal AssemblySymbol GetAssemblyForForwardedType(ref MetadataTypeName fullName) { string matchedName; AssemblyReferenceHandle assemblyRef = Module.GetAssemblyForForwardedType(fullName.FullName, ignoreCase: false, matchedName: out matchedName); return assemblyRef.IsNil ? null : this.GetReferencedAssemblySymbol(assemblyRef); }
public Nested(NamedTypeSymbol containingType, ref MetadataTypeName emittedName) : this(containingType, ref emittedName, emittedName.ForcedArity == -1 || emittedName.ForcedArity == emittedName.InferredArity) { }
internal NamedTypeSymbol LookupMetadataType(ref MetadataTypeName emittedTypeName, out bool isNoPiaLocalType) { NamedTypeSymbol result = LookupMetadataType(ref emittedTypeName); isNoPiaLocalType = false; if (result is MissingMetadataTypeSymbol) { EnsureAllMembersLoaded(); TypeDefinitionHandle typeDef; // See if this is a NoPia local type, which we should unify. // Note, VB should use FullName. if (_lazyNoPiaLocalTypes != null && _lazyNoPiaLocalTypes.TryGetValue(emittedTypeName.TypeName, out typeDef)) { result = (NamedTypeSymbol)new MetadataDecoder(ContainingPEModule).GetTypeOfToken(typeDef, out isNoPiaLocalType); Debug.Assert(isNoPiaLocalType); } } return result; }
internal override NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList<AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes) { var result = this.moduleSymbol.LookupTopLevelMetadataType(ref emittedName); Debug.Assert(result is MissingMetadataTypeSymbol); return result; }
public TopLevel(ModuleSymbol module, ref MetadataTypeName fullName, WellKnownType wellKnownType) : this(module, ref fullName, (int)wellKnownType) { }
/// <summary> /// This method handles duplicate types in a few different ways: /// - for types before C# 7, the first candidate is returned with a warning /// - for types after C# 7, the type is considered missing /// - in both cases, when BinderFlags.IgnoreCorLibraryDuplicatedTypes is set, any duplicate coming from corlib will be ignored (ie not count as a duplicate) /// </summary> internal NamedTypeSymbol GetWellKnownType(WellKnownType type) { Debug.Assert(type.IsValid()); bool ignoreCorLibraryDuplicatedTypes = this.Options.TopLevelBinderFlags.Includes(BinderFlags.IgnoreCorLibraryDuplicatedTypes); int index = (int)type - (int)WellKnownType.First; if (_lazyWellKnownTypes == null || (object)_lazyWellKnownTypes[index] == null) { if (_lazyWellKnownTypes == null) { Interlocked.CompareExchange(ref _lazyWellKnownTypes, new NamedTypeSymbol[(int)WellKnownTypes.Count], null); } string mdName = type.GetMetadataName(); var warnings = DiagnosticBag.GetInstance(); NamedTypeSymbol result; (AssemblySymbol, AssemblySymbol)conflicts = default; if (IsTypeMissing(type)) { result = null; } else { // well-known types introduced before CSharp7 allow lookup ambiguity and report a warning DiagnosticBag legacyWarnings = (type <= WellKnownType.CSharp7Sentinel) ? warnings : null; result = this.Assembly.GetTypeByMetadataName( mdName, includeReferences: true, useCLSCompliantNameArityEncoding: true, isWellKnownType: true, conflicts: out conflicts, warnings: legacyWarnings, ignoreCorLibraryDuplicatedTypes: ignoreCorLibraryDuplicatedTypes); } if ((object)result == null) { // TODO: should GetTypeByMetadataName rather return a missing symbol? MetadataTypeName emittedName = MetadataTypeName.FromFullName(mdName, useCLSCompliantNameArityEncoding: true); if (type.IsValueTupleType()) { CSDiagnosticInfo errorInfo; if (conflicts.Item1 is null) { Debug.Assert(conflicts.Item2 is null); errorInfo = new CSDiagnosticInfo(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, emittedName.FullName); } else { errorInfo = new CSDiagnosticInfo(ErrorCode.ERR_PredefinedValueTupleTypeAmbiguous3, emittedName.FullName, conflicts.Item1, conflicts.Item2); } result = new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(this.Assembly.Modules[0], ref emittedName, errorInfo, type); } else { result = new MissingMetadataTypeSymbol.TopLevel(this.Assembly.Modules[0], ref emittedName, type); } } if ((object)Interlocked.CompareExchange(ref _lazyWellKnownTypes[index], result, null) != null) { Debug.Assert( TypeSymbol.Equals(result, _lazyWellKnownTypes[index], TypeCompareKind.ConsiderEverything2) || (_lazyWellKnownTypes[index].IsErrorType() && result.IsErrorType()) ); } else { AdditionalCodegenWarnings.AddRange(warnings); } warnings.Free(); } return(_lazyWellKnownTypes[index]); }
/// <summary> /// Lookup a top level type referenced from metadata, names should be /// compared case-sensitively. /// </summary> /// <param name="emittedName"> /// Full type name, possibly with generic name mangling. /// </param> /// <returns> /// Symbol for the type, or MissingMetadataSymbol if the type isn't found. /// </returns> /// <remarks></remarks> internal abstract NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName);
internal NamedTypeSymbol GetTopLevelTypeByMetadataName( ref MetadataTypeName metadataName, AssemblyIdentity assemblyOpt, bool includeReferences, bool isWellKnownType, DiagnosticBag warnings = null) { NamedTypeSymbol result; // First try this assembly result = GetTopLevelTypeByMetadataName(this, ref metadataName, assemblyOpt); if (isWellKnownType && !IsValidWellKnownType(result)) { result = null; } // ignore any types of the same name that might be in referenced assemblies (prefer the current assembly): if ((object)result != null || !includeReferences) { return result; } Debug.Assert(this is SourceAssemblySymbol, "Never include references for a non-source assembly, because they don't know about aliases."); // Lookup in references foreach (var reference in GetUnaliasedReferencedAssemblies()) { Debug.Assert(!(this is SourceAssemblySymbol && reference.IsMissing)); // Non-source assemblies can have missing references NamedTypeSymbol candidate = GetTopLevelTypeByMetadataName(reference, ref metadataName, assemblyOpt); if (isWellKnownType && !IsValidWellKnownType(candidate)) { candidate = null; } if ((object)candidate == null) { continue; } Debug.Assert(candidate != result); if ((object)result != null) { // duplicate if (warnings == null) { return null; } else { // The predefined type '{0}' is defined in multiple assemblies in the global alias; using definition from '{1}' warnings.Add(ErrorCode.WRN_MultiplePredefTypes, NoLocation.Singleton, result, result.ContainingAssembly); return result; } } result = candidate; } return result; }
public string Type(MetadataTypeName typeName) => Type(typeName.Name, typeName.GenericArgs);
internal void AssertDeclaresType(PEModuleSymbol peModule, WellKnownType type, Accessibility expectedAccessibility) { var name = MetadataTypeName.FromFullName(type.GetMetadataName()); Assert.Equal(expectedAccessibility, peModule.LookupTopLevelMetadataType(ref name).DeclaredAccessibility); }
internal override NamedTypeSymbol LookupMetadataType(ref MetadataTypeName typeName) { return(this.RetargetingTranslator.Retarget(_underlyingType.LookupMetadataType(ref typeName), RetargetOptions.RetargetPrimitiveTypesByName)); }
private void CacheTopLevelMetadataType( ref MetadataTypeName emittedName, NamedTypeSymbol result) { NamedTypeSymbol result1 = null; result1 = this.emittedNameToTypeMap.GetOrAdd(emittedName.ToKey(), result); System.Diagnostics.Debug.Assert(result1 == result); // object identity may differ in error cases }
internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies) { NamedTypeSymbol underlying = _underlyingAssembly.TryLookupForwardedMetadataType(ref emittedName); if ((object)underlying == null) { return(null); } return(this.RetargetingTranslator.Retarget(underlying, RetargetOptions.RetargetPrimitiveTypesByName)); }
public TopLevelWithCustomErrorInfo(ModuleSymbol module, ref MetadataTypeName emittedName, DiagnosticInfo errorInfo) : base(module, ref emittedName) { Debug.Assert(errorInfo != null); this.errorInfo = errorInfo; }
/// <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.Kind == SymbolKind.NamedType // we don't have proper namese symbols, only global one so FullName it is ? scope.GetTypeMembers(emittedTypeName.UnmangledTypeName) : scope.GetTypeMembers(emittedTypeName.FullName); 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.FullName); 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) { return(new MissingMetadataTypeSymbol(emittedTypeName.FullName, emittedTypeName.ForcedArity, emittedTypeName.IsMangled)); //if (isTopLevel) //{ // return new MissingMetadataTypeSymbol.TopLevel(scope.ContainingModule, ref emittedTypeName); //} //else //{ // return new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName); //} } return(namedType); }
public TopLevel(ModuleSymbol module, ref MetadataTypeName fullName) : this(module, ref fullName, -1) { }
internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies) { // Check if it is a forwarded type. var forwardedToAssembly = LookupAssemblyForForwardedMetadataType(ref emittedName); if ((object)forwardedToAssembly != null) { // Don't bother to check the forwarded-to assembly if we've already seen it. if (visitedAssemblies != null && visitedAssemblies.Contains(forwardedToAssembly)) { return(CreateCycleInTypeForwarderErrorTypeSymbol(ref emittedName)); } else { visitedAssemblies = new ConsList <AssemblySymbol>(this, visitedAssemblies ?? ConsList <AssemblySymbol> .Empty); return(forwardedToAssembly.LookupTopLevelMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies, digThroughForwardedTypes: true)); } } return(null); }
private TopLevel(ModuleSymbol module, ref MetadataTypeName fullName, bool mangleName) : this(module, fullName.NamespaceName, mangleName ? fullName.UnmangledTypeName : fullName.TypeName, mangleName ? fullName.InferredArity : fullName.ForcedArity, mangleName) { }
protected override TypeSymbol LookupNestedTypeDefSymbol(TypeSymbol container, ref MetadataTypeName emittedName) { return(container.LookupMetadataType(ref emittedName)); }
internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList<AssemblySymbol> visitedAssemblies) { return null; }
protected override TypeSymbol LookupTopLevelTypeDefSymbol(int referencedAssemblyIndex, ref MetadataTypeName emittedName) { var assembly = this.GetAssemblies()[referencedAssemblyIndex]; return(assembly.LookupTopLevelMetadataType(ref emittedName, digThroughForwardedTypes: true)); }
/// <summary> /// Look up the assembly to which the given metadata type is forwarded. /// </summary> /// <param name="emittedName"></param> /// <returns> /// The assembly to which the given type is forwarded or null, if there isn't one. /// </returns> /// <remarks> /// The returned assembly may also forward the type. /// </remarks> internal AssemblySymbol LookupAssemblyForForwardedMetadataType(ref MetadataTypeName emittedName) { // Look in the type forwarders of the primary module of this assembly, clr does not honor type forwarder // in non-primary modules. // Examine the type forwarders, but only from the primary module. return this.PrimaryModule.GetAssemblyForForwardedType(ref emittedName); }
public string Type(MetadataTypeName typeName, bool includeNested = false) { return(Type(typeName.Name, typeName.GenericArgs, includeNested: includeNested)); }
private MetadataType FindMetadataTypeByMetadataTypeName(List<MetadataType> allTypes, MetadataTypeName metadataTypeName) { if (metadataTypeName == null) return null; var metaDataType = allTypes.Where(x => x.Name == metadataTypeName.Name && x.Namespace == metadataTypeName.Namespace) .FirstNonDefault(); return metaDataType; }
public string Type(MetadataTypeName typeName) { return(Type(typeName.Name, typeName.GenericArgs)); }
public MetadataType FindType(MetadataTypeName typeName) { if (typeName == null) return null; var foundType = AllTypes .FirstOrDefault(x => (typeName.Namespace == null || x.Namespace == typeName.Namespace) && x.Name == typeName.Name && x.GenericArgs.Safe().Count() == typeName.GenericArgs.Safe().Count()); if (foundType != null) return foundType; if (typeName.Name == typeof(QueryBase).Name || typeName.Name == typeof(QueryBase<>).Name) return CreateType(typeof(QueryBase)); //Properties are on QueryBase if (typeName.Name == typeof(AuthUserSession).Name) return CreateType(typeof(AuthUserSession)); return null; }
protected override TypeSymbol LookupNestedTypeDefSymbol(TypeSymbol container, ref MetadataTypeName emittedName) { var result = container.LookupMetadataType(ref emittedName); Debug.Assert((object)result != null); return(result); }
private NamedTypeSymbol LookupTopLevelMetadataTypeInCache(ref MetadataTypeName emittedName) { NamedTypeSymbol result = null; if (this.emittedNameToTypeMap.TryGetValue(emittedName.ToKey(), out result)) { return result; } return null; }
/// <summary> /// Lookup a type defined in this module. /// This method will be called only if the type we are /// looking for hasn't been loaded yet. Otherwise, MetadataDecoder /// would have found the type in TypeDefRowIdToTypeMap based on its /// TypeDef row id. /// </summary> protected override TypeSymbol LookupTopLevelTypeDefSymbol(ref MetadataTypeName emittedName, out bool isNoPiaLocalType) { return(moduleSymbol.LookupTopLevelMetadataType(ref emittedName, out isNoPiaLocalType)); }
/// <summary> /// Lookup a top level type referenced from metadata, names should be /// compared case-sensitively. Detect cycles during lookup. /// </summary> /// <param name="emittedName"> /// Full type name, possibly with generic name mangling. /// </param> /// <param name="visitedAssemblies"> /// List of assemblies lookup has already visited (since type forwarding can introduce cycles). /// </param> /// <param name="digThroughForwardedTypes"> /// Take forwarded types into account. /// </param> internal sealed override NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList<AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes) { NamedTypeSymbol result = null; // This is a cache similar to the one used by MetaImport::GetTypeByName in native // compiler. The difference is that native compiler pre-populates the cache when it // loads types. Here we are populating the cache only with things we looked for, so that // next time we are looking for the same thing, the lookup is fast. This cache also // takes care of TypeForwarders. Gives about 8% win on subsequent lookups in some // scenarios. // // CONSIDER !!! // // However, it is questionable how often subsequent lookup by name is going to happen. // Currently it doesn't happen for TypeDef tokens at all, for TypeRef tokens, the // lookup by name is done once and the result is cached. So, multiple lookups by name // for the same type are going to happen only in these cases: // 1) Resolving GetType() in attribute application, type is encoded by name. // 2) TypeRef token isn't reused within the same module, i.e. multiple TypeRefs point to // the same type. // 3) Different Module refers to the same type, lookup once per Module (with exception of #2). // 4) Multitargeting - retargeting the type to a different version of assembly result = LookupTopLevelMetadataTypeInCache(ref emittedName); if ((object)result != null) { // We only cache result equivalent to digging through type forwarders, which // might produce an forwarder specific ErrorTypeSymbol. We don't want to // return that error symbol, unless digThroughForwardedTypes is true. if (digThroughForwardedTypes || (!result.IsErrorType() && (object)result.ContainingAssembly == (object)this)) { return result; } // According to the cache, the type wasn't found, or isn't declared in this assembly (forwarded). return new MissingMetadataTypeSymbol.TopLevel(this.Modules[0], ref emittedName); } else { // Now we will look for the type in each module of the assembly and pick the first type // we find, this is what native VB compiler does. var modules = this.Modules; var count = modules.Length; var i = 0; result = modules[i].LookupTopLevelMetadataType(ref emittedName); if (result is MissingMetadataTypeSymbol) { for (i = 1; i < count; i++) { var newResult = modules[i].LookupTopLevelMetadataType(ref emittedName); // Hold on to the first missing type result, unless we found the type. if (!(newResult is MissingMetadataTypeSymbol)) { result = newResult; break; } } } bool foundMatchInThisAssembly = (i < count); Debug.Assert(!foundMatchInThisAssembly || (object)result.ContainingAssembly == (object)this); if (!foundMatchInThisAssembly && digThroughForwardedTypes) { // We didn't find the type System.Diagnostics.Debug.Assert(result is MissingMetadataTypeSymbol); NamedTypeSymbol forwarded = TryLookupForwardedMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies); if ((object)forwarded != null) { result = forwarded; } } System.Diagnostics.Debug.Assert((object)result != null); // Add result of the lookup into the cache if (digThroughForwardedTypes || foundMatchInThisAssembly) { CacheTopLevelMetadataType(ref emittedName, result); } return result; } }
/// <summary> /// Find canonical type for NoPia embedded type. /// </summary> /// <returns> /// Symbol for the canonical type or an ErrorTypeSymbol. Never returns null. /// </returns> internal static NamedTypeSymbol SubstituteNoPiaLocalType( ref MetadataTypeName name, bool isInterface, TypeSymbol baseType, string interfaceGuid, string scope, string identifier, AssemblySymbol referringAssembly) { NamedTypeSymbol result = null; Guid interfaceGuidValue = new Guid(); bool haveInterfaceGuidValue = false; Guid scopeGuidValue = new Guid(); bool haveScopeGuidValue = false; if (isInterface && interfaceGuid != null) { haveInterfaceGuidValue = Guid.TryParse(interfaceGuid, out interfaceGuidValue); if (haveInterfaceGuidValue) { // To have consistent errors. scope = null; identifier = null; } } if (scope != null) { haveScopeGuidValue = Guid.TryParse(scope, out scopeGuidValue); } foreach (AssemblySymbol assembly in referringAssembly.GetNoPiaResolutionAssemblies()) { Debug.Assert((object)assembly != null); if (ReferenceEquals(assembly, referringAssembly)) { continue; } NamedTypeSymbol candidate = assembly.LookupTopLevelMetadataType(ref name, digThroughForwardedTypes: false); Debug.Assert(!candidate.IsGenericType); // Ignore type forwarders, error symbols and non-public types if (candidate.Kind == SymbolKind.ErrorType || !ReferenceEquals(candidate.ContainingAssembly, assembly) || candidate.DeclaredAccessibility != Accessibility.Public) { continue; } // Ignore NoPia local types. // If candidate is coming from metadata, we don't need to do any special check, // because we do not create symbols for local types. However, local types defined in source // is another story. However, if compilation explicitly defines a local type, it should be // represented by a retargeting assembly, which is supposed to hide the local type. Debug.Assert(!(assembly is SourceAssemblySymbol) || !((SourceAssemblySymbol)assembly).SourceModule.MightContainNoPiaLocalTypes()); string candidateGuid; bool haveCandidateGuidValue = false; Guid candidateGuidValue = new Guid(); // The type must be of the same kind (interface, struct, delegate or enum). switch (candidate.TypeKind) { case TypeKind.Interface: if (!isInterface) { continue; } // Get candidate's Guid if (candidate.GetGuidString(out candidateGuid) && candidateGuid != null) { haveCandidateGuidValue = Guid.TryParse(candidateGuid, out candidateGuidValue); } break; case TypeKind.Delegate: case TypeKind.Enum: case TypeKind.Struct: if (isInterface) { continue; } // Let's use a trick. To make sure the kind is the same, make sure // base type is the same. if (!ReferenceEquals(baseType, candidate.BaseTypeNoUseSiteDiagnostics)) { continue; } break; default: continue; } if (haveInterfaceGuidValue || haveCandidateGuidValue) { if (!haveInterfaceGuidValue || !haveCandidateGuidValue || candidateGuidValue != interfaceGuidValue) { continue; } } else { if (!haveScopeGuidValue || identifier == null || !identifier.Equals(name.FullName)) { continue; } // Scope guid must match candidate's assembly guid. haveCandidateGuidValue = false; if (assembly.GetGuidString(out candidateGuid) && candidateGuid != null) { haveCandidateGuidValue = Guid.TryParse(candidateGuid, out candidateGuidValue); } if (!haveCandidateGuidValue || scopeGuidValue != candidateGuidValue) { continue; } } // OK. It looks like we found canonical type definition. if ((object)result != null) { // Ambiguity result = new NoPiaAmbiguousCanonicalTypeSymbol(referringAssembly, result, candidate); break; } result = candidate; } if ((object)result == null) { result = new NoPiaMissingCanonicalTypeSymbol( referringAssembly, name.FullName, interfaceGuid, scope, identifier); } return(result); }
internal override NamedTypeSymbol LookupMetadataType(ref MetadataTypeName typeName) { return this.RetargetingTranslator.Retarget(this.underlyingType.LookupMetadataType(ref typeName), RetargetOptions.RetargetPrimitiveTypesByName); }
/// <summary> /// For test purposes only. /// </summary> internal NamedTypeSymbol CachedTypeByEmittedName(string emittedname) { MetadataTypeName mdName = MetadataTypeName.FromFullName(emittedname); return(_emittedNameToTypeMap[mdName.ToKey()]); }
/// <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; }
/// <summary> /// Lookup a top level type referenced from metadata, names should be /// compared case-sensitively. Detect cycles during lookup. /// </summary> /// <param name="emittedName"> /// Full type name, possibly with generic name mangling. /// </param> /// <param name="visitedAssemblies"> /// List of assemblies lookup has already visited (since type forwarding can introduce cycles). /// </param> /// <param name="digThroughForwardedTypes"> /// Take forwarded types into account. /// </param> internal sealed override NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes) { NamedTypeSymbol result = null; // This is a cache similar to the one used by MetaImport::GetTypeByName in native // compiler. The difference is that native compiler pre-populates the cache when it // loads types. Here we are populating the cache only with things we looked for, so that // next time we are looking for the same thing, the lookup is fast. This cache also // takes care of TypeForwarders. Gives about 8% win on subsequent lookups in some // scenarios. // // CONSIDER !!! // // However, it is questionable how often subsequent lookup by name is going to happen. // Currently it doesn't happen for TypeDef tokens at all, for TypeRef tokens, the // lookup by name is done once and the result is cached. So, multiple lookups by name // for the same type are going to happen only in these cases: // 1) Resolving GetType() in attribute application, type is encoded by name. // 2) TypeRef token isn't reused within the same module, i.e. multiple TypeRefs point to // the same type. // 3) Different Module refers to the same type, lookup once per Module (with exception of #2). // 4) Multitargeting - retargeting the type to a different version of assembly result = LookupTopLevelMetadataTypeInCache(ref emittedName); if ((object)result != null) { // We only cache result equivalent to digging through type forwarders, which // might produce an forwarder specific ErrorTypeSymbol. We don't want to // return that error symbol, unless digThroughForwardedTypes is true. if (digThroughForwardedTypes || (!result.IsErrorType() && (object)result.ContainingAssembly == (object)this)) { return(result); } // According to the cache, the type wasn't found, or isn't declared in this assembly (forwarded). throw new NotImplementedException(); //return new MissingMetadataTypeSymbol.TopLevel(this.Modules[0], ref emittedName); } else { // Now we will look for the type in each module of the assembly and pick the first type // we find, this is what native VB compiler does. var modules = this.Modules; var count = modules.Length; var i = 0; result = modules[i].LookupTopLevelMetadataType(ref emittedName); if (result is ErrorTypeSymbol) { for (i = 1; i < count; i++) { var newResult = modules[i].LookupTopLevelMetadataType(ref emittedName); // Hold on to the first missing type result, unless we found the type. if (!(newResult is ErrorTypeSymbol)) { result = newResult; break; } } } bool foundMatchInThisAssembly = (i < count); Debug.Assert(!foundMatchInThisAssembly || (object)result.ContainingAssembly == (object)this); if (!foundMatchInThisAssembly && digThroughForwardedTypes) { // We didn't find the type Debug.Assert(result is ErrorTypeSymbol); NamedTypeSymbol forwarded = TryLookupForwardedMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies); if ((object)forwarded != null) { result = forwarded; } } Debug.Assert((object)result != null); // Add result of the lookup into the cache if (digThroughForwardedTypes || foundMatchInThisAssembly) { CacheTopLevelMetadataType(ref emittedName, result); } return(result); } }
public TopLevel(ModuleSymbol module, ref MetadataTypeName fullName, SpecialType specialType) : this(module, ref fullName, (int)specialType) { }
/// <summary> /// Lookup a top level type referenced from metadata, names should be /// compared case-sensitively. /// </summary> /// <param name="emittedName"> /// Full type name with generic name mangling. /// </param> /// <param name="digThroughForwardedTypes"> /// Take forwarded types into account. /// </param> /// <remarks></remarks> internal NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName, bool digThroughForwardedTypes) { return(LookupTopLevelMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies: null, digThroughForwardedTypes: digThroughForwardedTypes)); }
private TopLevel(ModuleSymbol module, ref MetadataTypeName fullName, int typeId) : this(module, ref fullName, fullName.ForcedArity == -1 || fullName.ForcedArity == fullName.InferredArity) { Debug.Assert(typeId == -1 || typeId == (int)SpecialType.None || Arity == 0 || MangleName); _lazyTypeId = typeId; }
/// <summary> /// Lookup a top level type referenced from metadata, names should be /// compared case-sensitively. Detect cycles during lookup. /// </summary> /// <param name="emittedName"> /// Full type name, possibly with generic name mangling. /// </param> /// <param name="visitedAssemblies"> /// List of assemblies lookup has already visited (since type forwarding can introduce cycles). /// </param> /// <param name="digThroughForwardedTypes"> /// Take forwarded types into account. /// </param> internal abstract NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes);
public TopLevelWithCustomErrorInfo(ModuleSymbol module, ref MetadataTypeName emittedName, DiagnosticInfo errorInfo, WellKnownType typeId) : base(module, ref emittedName, typeId) { Debug.Assert(errorInfo != null); _errorInfo = errorInfo; }
/// <summary> /// Look up the given metadata type, if it is forwarded. /// </summary> internal NamedTypeSymbol TryLookupForwardedMetadataType(ref MetadataTypeName emittedName) { return(TryLookupForwardedMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies: null)); }
private Nested(NamedTypeSymbol containingType, ref MetadataTypeName emittedName, bool mangleName) : this(containingType, mangleName ? emittedName.UnmangledTypeName : emittedName.TypeName, mangleName ? emittedName.InferredArity : emittedName.ForcedArity, mangleName) { }
/// <summary> /// Look up the given metadata type, if it is forwarded. /// </summary> internal virtual NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies) { return(null); }
/// <summary> /// Lookup a top level type referenced from metadata, names should be /// compared case-sensitively. /// </summary> /// <param name="emittedName"> /// Full type name, possibly with generic name mangling. /// </param> /// <returns> /// Symbol for the type, or MissingMetadataSymbol if the type isn't found. /// </returns> /// <remarks></remarks> internal sealed override NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName) { NamedTypeSymbol result; NamespaceSymbol scope = this.GlobalNamespace.LookupNestedNamespace(emittedName.NamespaceSegments); if ((object)scope == null) { // We failed to locate the namespace result = new MissingMetadataTypeSymbol.TopLevel(this, ref emittedName); } else { result = scope.LookupMetadataType(ref emittedName); } Debug.Assert((object)result != null); return result; }
internal ErrorTypeSymbol CreateCycleInTypeForwarderErrorTypeSymbol(ref MetadataTypeName emittedName) { DiagnosticInfo diagnosticInfo = new CSDiagnosticInfo(ErrorCode.ERR_CycleInTypeForwarder, emittedName.FullName, this.Name); return(new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(this.Modules[0], ref emittedName, diagnosticInfo)); }
internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList<AssemblySymbol> visitedAssemblies) { NamedTypeSymbol underlying = _underlyingAssembly.TryLookupForwardedMetadataType(ref emittedName); if ((object)underlying == null) { return null; } return this.RetargetingTranslator.Retarget(underlying, RetargetOptions.RetargetPrimitiveTypesByName); }
internal ErrorTypeSymbol CreateMultipleForwardingErrorTypeSymbol(ref MetadataTypeName emittedName, ModuleSymbol forwardingModule, AssemblySymbol destination1, AssemblySymbol destination2) { var diagnosticInfo = new CSDiagnosticInfo(ErrorCode.ERR_TypeForwardedToMultipleAssemblies, forwardingModule, this, emittedName.FullName, destination1, destination2); return(new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(forwardingModule, ref emittedName, diagnosticInfo)); }
internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList<AssemblySymbol> visitedAssemblies) { // Check if it is a forwarded type. var forwardedToAssembly = LookupAssemblyForForwardedMetadataType(ref emittedName); if ((object)forwardedToAssembly != null) { // Don't bother to check the forwarded-to assembly if we've already seen it. if (visitedAssemblies != null && visitedAssemblies.Contains(forwardedToAssembly)) { return CreateCycleInTypeForwarderErrorTypeSymbol(ref emittedName); } else { visitedAssemblies = new ConsList<AssemblySymbol>(this, visitedAssemblies ?? ConsList<AssemblySymbol>.Empty); return forwardedToAssembly.LookupTopLevelMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies, digThroughForwardedTypes: true); } } return null; }
/// <summary> /// Resolves <see cref="System.Type"/> to a <see cref="TypeSymbol"/> available in this assembly /// its referenced assemblies. /// </summary> /// <param name="type">The type to resolve.</param> /// <param name="includeReferences">Use referenced assemblies for resolution.</param> /// <returns>The resolved symbol if successful or null on failure.</returns> internal TypeSymbol GetTypeByReflectionType(Type type, bool includeReferences) { System.Reflection.TypeInfo typeInfo = type.GetTypeInfo(); Debug.Assert(!typeInfo.IsByRef); // not supported (we don't accept open types as submission results nor host types): Debug.Assert(!typeInfo.ContainsGenericParameters); if (typeInfo.IsArray) { TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences); if ((object)symbol == null) { return(null); } int rank = typeInfo.GetArrayRank(); return(ArrayTypeSymbol.CreateCSharpArray(this, symbol, ImmutableArray <CustomModifier> .Empty, rank)); } else if (typeInfo.IsPointer) { TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences); if ((object)symbol == null) { return(null); } return(new PointerTypeSymbol(symbol)); } else if (typeInfo.DeclaringType != null) { Debug.Assert(!typeInfo.IsArray); // consolidated generic arguments (includes arguments of all declaring types): Type[] genericArguments = typeInfo.GenericTypeArguments; int typeArgumentIndex = 0; var currentTypeInfo = typeInfo.IsGenericType ? typeInfo.GetGenericTypeDefinition().GetTypeInfo() : typeInfo; var nestedTypes = ArrayBuilder <System.Reflection.TypeInfo> .GetInstance(); while (true) { Debug.Assert(currentTypeInfo.IsGenericTypeDefinition || !currentTypeInfo.IsGenericType); nestedTypes.Add(currentTypeInfo); if (currentTypeInfo.DeclaringType == null) { break; } currentTypeInfo = currentTypeInfo.DeclaringType.GetTypeInfo(); } int i = nestedTypes.Count - 1; var symbol = (NamedTypeSymbol)GetTypeByReflectionType(nestedTypes[i].AsType(), includeReferences); if ((object)symbol == null) { return(null); } while (--i >= 0) { int forcedArity = nestedTypes[i].GenericTypeParameters.Length - nestedTypes[i + 1].GenericTypeParameters.Length; MetadataTypeName mdName = MetadataTypeName.FromTypeName(nestedTypes[i].Name, forcedArity: forcedArity); symbol = symbol.LookupMetadataType(ref mdName); if ((object)symbol == null || symbol.IsErrorType()) { return(null); } symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences); if ((object)symbol == null) { return(null); } } nestedTypes.Free(); Debug.Assert(typeArgumentIndex == genericArguments.Length); return(symbol); } else { AssemblyIdentity assemblyId = AssemblyIdentity.FromAssemblyDefinition(typeInfo.Assembly); MetadataTypeName mdName = MetadataTypeName.FromNamespaceAndTypeName( typeInfo.Namespace ?? string.Empty, typeInfo.Name, forcedArity: typeInfo.GenericTypeArguments.Length); NamedTypeSymbol symbol = GetTopLevelTypeByMetadataName(ref mdName, assemblyId, includeReferences, isWellKnownType: false); if ((object)symbol == null || symbol.IsErrorType()) { return(null); } int typeArgumentIndex = 0; Type[] genericArguments = typeInfo.GenericTypeArguments; symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences); Debug.Assert(typeArgumentIndex == genericArguments.Length); return(symbol); } }
/// <summary> /// If this module forwards the given type to another assembly, return that assembly; /// otherwise, return null. /// </summary> /// <param name="fullName">Type to look up.</param> /// <returns>Assembly symbol or null.</returns> /// <remarks> /// The returned assembly may also forward the type. /// </remarks> internal AssemblySymbol GetAssemblyForForwardedType(ref MetadataTypeName fullName) { try { string matchedName; AssemblyReferenceHandle assemblyRef = Module.GetAssemblyForForwardedType(fullName.FullName, ignoreCase: false, matchedName: out matchedName); return assemblyRef.IsNil ? null : this.GetReferencedAssemblySymbols()[Module.GetAssemblyReferenceIndexOrThrow(assemblyRef)]; } catch (BadImageFormatException) { return null; } }
internal NamedTypeSymbol GetTopLevelTypeByMetadataName( ref MetadataTypeName metadataName, AssemblyIdentity assemblyOpt, bool includeReferences, bool isWellKnownType, DiagnosticBag warnings = null, bool ignoreCorLibraryDuplicatedTypes = false) { NamedTypeSymbol result; // First try this assembly result = GetTopLevelTypeByMetadataName(this, ref metadataName, assemblyOpt); if (isWellKnownType && !IsValidWellKnownType(result)) { result = null; } // ignore any types of the same name that might be in referenced assemblies (prefer the current assembly): if ((object)result != null || !includeReferences) { return(result); } Debug.Assert(this is SourceAssemblySymbol, "Never include references for a non-source assembly, because they don't know about aliases."); var assemblies = ArrayBuilder <AssemblySymbol> .GetInstance(); // ignore reference aliases if searching for a type from a specific assembly: if (assemblyOpt != null) { assemblies.AddRange(DeclaringCompilation.GetBoundReferenceManager().ReferencedAssemblies); } else { DeclaringCompilation.GetUnaliasedReferencedAssemblies(assemblies); } // Lookup in references foreach (var assembly in assemblies) { Debug.Assert(!(this is SourceAssemblySymbol && assembly.IsMissing)); // Non-source assemblies can have missing references NamedTypeSymbol candidate = GetTopLevelTypeByMetadataName(assembly, ref metadataName, assemblyOpt); if (isWellKnownType && !IsValidWellKnownType(candidate)) { candidate = null; } if ((object)candidate == null) { continue; } Debug.Assert(candidate != result); if ((object)result != null) { // duplicate if (ignoreCorLibraryDuplicatedTypes) { if (IsInCorLib(candidate)) { // ignore candidate continue; } if (IsInCorLib(result)) { // drop previous result result = candidate; continue; } } if (warnings == null) { result = null; } else { // The predefined type '{0}' is defined in multiple assemblies in the global alias; using definition from '{1}' warnings.Add(ErrorCode.WRN_MultiplePredefTypes, NoLocation.Singleton, result, result.ContainingAssembly); } break; } result = candidate; } assemblies.Free(); return(result); }
internal NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName, out bool isNoPiaLocalType) { NamedTypeSymbol result; PENamespaceSymbol scope = (PENamespaceSymbol)this.GlobalNamespace.LookupNestedNamespace(emittedName.NamespaceSegments); if ((object)scope == null) { // We failed to locate the namespace isNoPiaLocalType = false; result = new MissingMetadataTypeSymbol.TopLevel(this, ref emittedName); } else { result = scope.LookupMetadataType(ref emittedName, out isNoPiaLocalType); Debug.Assert((object)result != null); } return result; }
private static NamedTypeSymbol GetTopLevelTypeByMetadataName(AssemblySymbol assembly, ref MetadataTypeName metadataName, AssemblyIdentity assemblyOpt) { var result = assembly.LookupTopLevelMetadataType(ref metadataName, digThroughForwardedTypes: false); if (!IsAcceptableMatchForGetTypeByMetadataName(result)) { return(null); } if (assemblyOpt != null && !assemblyOpt.Equals(assembly.Identity)) { return(null); } return(result); }
public string Type(MetadataTypeName typeName, bool includeNested = false) { return Type(typeName.Name, typeName.GenericArgs, includeNested: includeNested); }
internal override NamedTypeSymbol LookupMetadataType(ref MetadataTypeName typeName) { // This method is invoked when looking up a type by metadata type // name through a RetargetingAssemblySymbol. For instance, in // UnitTests.Symbols.Metadata.PE.NoPia.LocalTypeSubstitution2. NamedTypeSymbol underlying = this.underlyingNamespace.LookupMetadataType(ref typeName); Debug.Assert((object)underlying.ContainingModule == (object)retargetingModule.UnderlyingModule); if (!underlying.IsErrorType() && underlying.IsExplicitDefinitionOfNoPiaLocalType) { // Explicitly defined local types should be hidden. return new MissingMetadataTypeSymbol.TopLevel(retargetingModule, ref typeName); } return this.RetargetingTranslator.Retarget(underlying, RetargetOptions.RetargetPrimitiveTypesByName); }
public string Type(MetadataTypeName typeName) { return Type(typeName.Name, typeName.GenericArgs); }
internal override NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes) { return(new MissingMetadataTypeSymbol(emittedName.FullName, emittedName.ForcedArity, emittedName.IsMangled)); }