private LocalRewriter( CSharpCompilation compilation, MethodSymbol containingMethod, int containingMethodOrdinal, BoundStatement rootStatement, NamedTypeSymbol?containingType, SyntheticBoundNodeFactory factory, SynthesizedSubmissionFields previousSubmissionFields, bool allowOmissionOfConditionalCalls, DiagnosticBag diagnostics, Instrumenter instrumenter) { _compilation = compilation; _factory = factory; _factory.CurrentFunction = containingMethod; Debug.Assert(TypeSymbol.Equals(factory.CurrentType, (containingType ?? containingMethod.ContainingType), TypeCompareKind.ConsiderEverything2)); _dynamicFactory = new LoweredDynamicOperationFactory(factory, containingMethodOrdinal); _previousSubmissionFields = previousSubmissionFields; _allowOmissionOfConditionalCalls = allowOmissionOfConditionalCalls; _diagnostics = diagnostics; Debug.Assert(instrumenter != null); #if DEBUG // Ensure that only expected kinds of instrumenters are in use _ = RemoveDynamicAnalysisInjectors(instrumenter); #endif _instrumenter = instrumenter; _rootStatement = rootStatement; }
internal EventSymbol GetLeastOverriddenEvent(NamedTypeSymbol?accessingTypeOpt) { accessingTypeOpt = accessingTypeOpt?.OriginalDefinition; EventSymbol e = this; while (e.IsOverride && !e.HidesBaseEventsByName) { // NOTE: We might not be able to access the overridden event. For example, // // .assembly A // { // InternalsVisibleTo("B") // public class A { internal virtual event Action E { add; remove; } } // } // // .assembly B // { // InternalsVisibleTo("C") // public class B : A { internal override event Action E { add; remove; } } // } // // .assembly C // { // public class C : B { ... new B().E += null ... } // A.E is not accessible from here // } // // See InternalsVisibleToAndStrongNameTests: IvtVirtualCall1, IvtVirtualCall2, IvtVirtual_ParamsAndDynamic. EventSymbol?overridden = e.OverriddenEvent; var discardedUseSiteInfo = CompoundUseSiteInfo <AssemblySymbol> .Discarded; if ((object?)overridden == null || (accessingTypeOpt is { } && !AccessCheck.IsSymbolAccessible(overridden, accessingTypeOpt, ref discardedUseSiteInfo)))
internal SourceAttributeData( SyntaxReference?applicationNode, NamedTypeSymbol?attributeClass, MethodSymbol?attributeConstructor, ImmutableArray <TypedConstant> constructorArguments, ImmutableArray <int> constructorArgumentsSourceIndices, ImmutableArray <KeyValuePair <string, TypedConstant> > namedArguments, bool hasErrors, bool isConditionallyOmitted) { Debug.Assert(!isConditionallyOmitted || attributeClass is object && attributeClass.IsConditional); Debug.Assert(!constructorArguments.IsDefault); Debug.Assert(!namedArguments.IsDefault); Debug.Assert(constructorArgumentsSourceIndices.IsDefault || constructorArgumentsSourceIndices.Any() && constructorArgumentsSourceIndices.Length == constructorArguments.Length); Debug.Assert(attributeConstructor is object || hasErrors); _attributeClass = attributeClass; _attributeConstructor = attributeConstructor; _constructorArguments = constructorArguments; _constructorArgumentsSourceIndices = constructorArgumentsSourceIndices; _namedArguments = namedArguments; _isConditionallyOmitted = isConditionallyOmitted; _hasErrors = hasErrors; _applicationNode = applicationNode; }
public TypeCompilationState( NamedTypeSymbol?typeOpt, CSharpCompilation compilation, PEModuleBuilder?moduleBuilderOpt ) { this.Compilation = compilation; _typeOpt = typeOpt; this.ModuleBuilderOpt = moduleBuilderOpt; }
/// <summary> /// Returns true if the members of superType are accessible from subType due to inheritance. /// </summary> public static bool IsAccessibleViaInheritance( this NamedTypeSymbol superType, NamedTypeSymbol subType, ref CompoundUseSiteInfo <AssemblySymbol> useSiteInfo ) { // NOTE: we don't use strict inheritance. Instead we ignore constructed generic types // and only consider the unconstructed types. Ecma-334, 4th edition contained the // following text supporting this (although, for instance members) in 10.5.3 Protected // access for instance members: // In the context of generics (25.1.6), the rules for accessing protected and // protected internal instance members are augmented by the following: // o Within a generic class G, access to an inherited protected instance member M // using a primary-expression of the form E.M is permitted if the type of E is a // class type constructed from G or a class type derived from a class type // constructed from G. // This text is missing in the current version of the spec, but we believe this is accidental. NamedTypeSymbol originalSuperType = superType.OriginalDefinition; for ( NamedTypeSymbol?current = subType; (object?)current != null; current = current.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteInfo) ) { if (ReferenceEquals(current.OriginalDefinition, originalSuperType)) { return(true); } } if (originalSuperType.IsInterface) { foreach ( NamedTypeSymbol current in subType.AllInterfacesWithDefinitionUseSiteDiagnostics( ref useSiteInfo ) ) { if (ReferenceEquals(current.OriginalDefinition, originalSuperType)) { return(true); } } } // The method returns true for superType == subType. // Two different submission type symbols semantically represent a single type, so we should also return true. return(superType.TypeKind == TypeKind.Submission && subType.TypeKind == TypeKind.Submission); }
/// <summary> /// Replace any named type in the symbol list with its instance constructors. /// Construct all candidates with the implicitly-declared CrefTypeParameterSymbols. /// </summary> private void GetCrefOverloadResolutionCandidates(ImmutableArray <Symbol> symbols, int arity, TypeArgumentListSyntax?typeArgumentListSyntax, ArrayBuilder <Symbol> candidates) { foreach (Symbol candidate in symbols) { Symbol constructedCandidate = ConstructWithCrefTypeParameters(arity, typeArgumentListSyntax, candidate); NamedTypeSymbol?constructedCandidateType = constructedCandidate as NamedTypeSymbol; if ((object?)constructedCandidateType == null) { // Construct before overload resolution so the signatures will match. candidates.Add(constructedCandidate); } else { candidates.AddRange(constructedCandidateType.InstanceConstructors); } } }
internal EventSymbol GetLeastOverriddenEvent(NamedTypeSymbol?accessingTypeOpt) { var accessingType = ((object?)accessingTypeOpt == null ? this.ContainingType : accessingTypeOpt).OriginalDefinition; EventSymbol e = this; while (e.IsOverride && !e.HidesBaseEventsByName) { // NOTE: We might not be able to access the overridden event. For example, // // .assembly A // { // InternalsVisibleTo("B") // public class A { internal virtual event Action E { add; remove; } } // } // // .assembly B // { // InternalsVisibleTo("C") // public class B : A { internal override event Action E { add; remove; } } // } // // .assembly C // { // public class C : B { ... new B().E += null ... } // A.E is not accessible from here // } // // See InternalsVisibleToAndStrongNameTests: IvtVirtualCall1, IvtVirtualCall2, IvtVirtual_ParamsAndDynamic. EventSymbol?overridden = e.OverriddenEvent; HashSet <DiagnosticInfo>?useSiteDiagnostics = null; if ((object?)overridden == null || !AccessCheck.IsSymbolAccessible(overridden, accessingType, ref useSiteDiagnostics)) { break; } e = overridden; } return(e); }
private ImmutableArray <Symbol> ComputeSortedCrefMembers(NamespaceOrTypeSymbol?containerOpt, string memberName, int arity, bool hasParameterList, ref CompoundUseSiteInfo <AssemblySymbol> useSiteInfo) { // 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, useSiteInfo: ref useSiteInfo); // 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 || !TypeSymbol.Equals(this.ContainingType, containerType.OriginalDefinition, TypeCompareKind.ConsiderEverything2))) { 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()); }
/// <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); }
internal FunctionTypeSymbol(NamedTypeSymbol delegateType) { _lazyDelegateType = delegateType; }
private FunctionTypeSymbol(Binder binder, Func <Binder, BoundExpression, NamedTypeSymbol?> calculateDelegate) { _binder = binder; _calculateDelegate = calculateDelegate; _lazyDelegateType = Uninitialized; }
internal static INamedTypeSymbol? GetPublicSymbol(this NamedTypeSymbol? symbol) { return symbol.GetPublicSymbol<INamedTypeSymbol>(); }