/// <summary> /// Verify if the attribute type can be applied to given owner symbol. /// Generate a diagnostic if it cannot be applied /// </summary> /// <param name="ownerSymbol">Symbol on which the attribute is applied</param> /// <param name="attributeType">Attribute class for the attribute</param> /// <param name="node">Syntax node for attribute specification</param> /// <param name="attributeLocation">Attribute target specifier location</param> /// <param name="diagnostics">Diagnostics</param> /// <returns>Whether attribute specification is allowed for the given symbol</returns> internal bool VerifyAttributeUsageTarget(Symbol ownerSymbol, NamedTypeSymbol attributeType, AttributeSyntax node, AttributeLocation attributeLocation, DiagnosticBag diagnostics) { var attributeUsageInfo = attributeType.AttributeUsageInfo(Compilation); if (attributeUsageInfo != null) { AttributeTargets attributeTarget; if (attributeLocation == AttributeLocation.Return) { // attribute on return type attributeTarget = AttributeTargets.ReturnValue; } else { attributeTarget = ownerSymbol.GetAttributeTarget(); } if ((attributeTarget & attributeUsageInfo.ValidTargets) != 0) { return true; } // generate error Error(diagnostics, ErrorCode.ERR_AttributeOnBadSymbolType, node, GetAttributeNameFromSyntax(node), attributeUsageInfo.GetValidTargetsString()); } return false; }
private CallRewriter(MethodSymbol containingSymbol, NamedTypeSymbol containingType, SynthesizedSubmissionFields previousSubmissionFields, Compilation compilation) { this.compilation = compilation; this.containingSymbol = containingSymbol; this.containingType = containingType ?? containingSymbol.ContainingType; this.previousSubmissionFields = previousSubmissionFields; }
public static BoundStatement Rewrite(BoundStatement node, MethodSymbol containingSymbol, NamedTypeSymbol containingType, SynthesizedSubmissionFields previousSubmissionFields, Compilation compilation) { Debug.Assert(node != null); var rewriter = new CallRewriter(containingSymbol, containingType, previousSubmissionFields, compilation); var result = (BoundStatement)rewriter.Visit(node); return result; }
public AnonRewriter(NamedTypeSymbol type, SemanticModel model, Compilation comp, TypeSyntax newType) { Type = type; Model = model; Comp = comp; NewType = newType; }
internal FieldMemberBuilder(NamedTypeSymbol owner, Binder enclosing, FieldDeclarationSyntax declaration, TypeSymbol type, VariableDeclaratorSyntax declarator) : base(enclosing.Location(declarator) as SourceLocation, owner, enclosing) { this.owner = owner; this.declaration = declaration; this.declarator = declarator; this.Type = type; }
internal Submission( CommonSubmission previous, NamedTypeSymbol scriptClass, Imports imports, Delegate factory) : base(previous, factory) { Debug.Assert(imports != null); this.scriptClass = scriptClass; this.imports = imports; }
public TypeExtraInfo(Chunk chunk, SemanticModel model, NamedTypeSymbol cls) { Chunk = chunk; Model = model; Type = cls; Fields = new List<FieldExtraInfo>(); StaticFields = new List<FieldExtraInfo>(); FieldNames = new Dictionary<string, int>(); StaticFieldNames = new Dictionary<string, int>(); MetadataGenerator = new ClassMetadataGenerator(chunk, model, cls); if (Type.ContainingType != null) { Parent = Chunk.AddTypeExtraInfo(Type.ContainingType, Model); } }
// compares by namespace and type name, ignores signatures private static bool EarlyDecodeIsTargetAttribute(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax, AttributeDescription description, bool skipParamCheck = false) { if (!skipParamCheck) { int parameterCount = description.GetParameterCount(signatureIndex: 0); int argumentCount = (attributeSyntax.ArgumentList != null) ? attributeSyntax.ArgumentList.Arguments.Count : 0; if (argumentCount != parameterCount) { return false; } } Debug.Assert(!attributeType.IsErrorType()); string actualNamespaceName = attributeType.ContainingNamespace.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat); return actualNamespaceName.Equals(description.Namespace) && attributeType.Name.Equals(description.Name); }
/// <summary> /// Adds a new internal class with the given name equivalent to the passed type to the given syntax tree. /// /// Sets `created` to a reference to the newly created type. /// </summary> private static SyntaxNode AddType(NamedTypeSymbol equivTo, string withName, SyntaxNode tree, out TypeSyntax created) { created = Syntax.ParseTypeName(withName); var members = equivTo.GetMembers() .OfType<PropertySymbol>() .Select( s => { var prop = Syntax.PropertyDeclaration( null, Syntax.TokenList(Syntax.ParseToken("public")), Syntax.ParseTypeName(s.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)).WithLeadingTrivia(Syntax.ParseLeadingTrivia(" ")).WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), null, Syntax.Identifier(s.Name), Syntax.AccessorList( Syntax.List( Syntax.AccessorDeclaration( SyntaxKind.GetAccessorDeclaration, null, Syntax.TokenList(), Syntax.ParseToken("get"), null, Syntax.ParseToken(";") ), Syntax.AccessorDeclaration( SyntaxKind.SetAccessorDeclaration, null, Syntax.TokenList(), Syntax.ParseToken("set"), null, Syntax.ParseToken(";") ) ) ) ); return prop; } ) .Cast<MemberDeclarationSyntax>().ToList(); var separators = new List<SyntaxToken>(); for(var i = 0; i < members.Count - 1; i++) separators.Add(Syntax.ParseToken(",")); var obj = Syntax.AnonymousObjectCreationExpression( Syntax.SeparatedList( equivTo.GetMembers() .OfType<PropertySymbol>() .Select( p => { var exp = Syntax.IdentifierName(p.Name); return Syntax.AnonymousObjectMemberDeclarator(exp); } ), separators ) ).WithLeadingTrivia(Syntax.ParseLeadingTrivia(" ")); // Build the ToString() method that anonymous types have to have var toStringRef = Syntax.MemberAccessExpression(SyntaxKind.MemberAccessExpression, obj, Syntax.ParseToken("."), Syntax.IdentifierName("ToString")); var toStringAccess = Syntax.InvocationExpression(toStringRef); var toStringRet = Syntax.ReturnStatement(toStringAccess); var toStringStatements = Syntax.List<StatementSyntax>(toStringRet); var toStringBody = Syntax.Block( Syntax.ParseToken("{"), toStringStatements, Syntax.ParseToken("}") ); var toString = Syntax.MethodDeclaration( null, Syntax.TokenList(Syntax.ParseToken("public").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), Syntax.ParseToken("override").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" "))), Syntax.ParseTypeName("string").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), null, Syntax.Identifier("ToString"), null, Syntax.ParameterList(), null, toStringBody ); members.Add(toString); // Adding GetHashCode override anonymous types must have var hashCodeRef = Syntax.MemberAccessExpression(SyntaxKind.MemberAccessExpression, obj, Syntax.ParseToken("."), Syntax.IdentifierName("GetHashCode")); var hashCodeAccess = Syntax.InvocationExpression(hashCodeRef); var hashCodeRet = Syntax.ReturnStatement(hashCodeAccess); var hashCodeStatements = Syntax.List<StatementSyntax>(hashCodeRet); var hashCodeBody = Syntax.Block( Syntax.ParseToken("{"), hashCodeStatements, Syntax.ParseToken("}") ); var hashCode = Syntax.MethodDeclaration( null, Syntax.TokenList(Syntax.ParseToken("public").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), Syntax.ParseToken("override").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" "))), Syntax.ParseTypeName("int").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), null, Syntax.Identifier("GetHashCode"), null, Syntax.ParameterList(), null, hashCodeBody ); members.Add(hashCode); // Adding Equals method anonymous types must have var equalsAs = Syntax.ParseExpression("o as " + withName); var equalsAssign = Syntax.VariableDeclaration( created.WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), Syntax.SeparatedList( Syntax.VariableDeclarator( Syntax.Identifier("other"), null, Syntax.EqualsValueClause(equalsAs) ) ) ); var equalsEqualsRef = Syntax.MemberAccessExpression(SyntaxKind.MemberAccessExpression, obj, Syntax.ParseToken("."), Syntax.IdentifierName("Equals")); var equalsAccess = Syntax.InvocationExpression(equalsEqualsRef, Syntax.ArgumentList(Syntax.SeparatedList(Syntax.Argument(Syntax.ParseExpression("o"))))); var equalsIf = Syntax.IfStatement( Syntax.ParseExpression("other == null"), Syntax.ReturnStatement(equalsAccess) ); var equalsEqualsExps = equivTo.GetMembers() .OfType<PropertySymbol>() .Select( p => { var n = p.Name; ExpressionSyntax ret; if (p.Type.IsReferenceType) { var strExp = "(" + n + " != null ? " + n + ".Equals(other." + n + ") : (other." + n + " != null ? other." + n + ".Equals(" + n + ") : true ))"; ret = Syntax.ParseExpression(strExp); } else { ret = Syntax.ParseExpression(n + " == other." + n); } return ret.WithLeadingTrivia(Syntax.ParseLeadingTrivia(" ")).WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")); } ).ToList(); ExpressionSyntax equalsBinary = equalsEqualsExps.First(); for (var i = 1; i < equalsEqualsExps.Count; i++) equalsBinary = Syntax.BinaryExpression(SyntaxKind.LogicalAndExpression, equalsBinary, equalsEqualsExps[i]); var equalsBinaryRet = Syntax.ReturnStatement(equalsBinary.WithLeadingTrivia(Syntax.ParseLeadingTrivia(" "))); var equalsStatements = Syntax.List( (StatementSyntax)Syntax.LocalDeclarationStatement(equalsAssign), (StatementSyntax)equalsIf, (StatementSyntax)equalsBinaryRet ); var equalsBody = Syntax.Block( Syntax.ParseToken("{"), equalsStatements, Syntax.ParseToken("}") ); var equals = Syntax.MethodDeclaration( null, Syntax.TokenList(Syntax.ParseToken("public").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), Syntax.ParseToken("override").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" "))), Syntax.ParseTypeName("bool").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), null, Syntax.Identifier("Equals"), null, Syntax.ParameterList( Syntax.SeparatedList( Syntax.Parameter( null, Syntax.TokenList(), Syntax.ParseTypeName("object").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), Syntax.Identifier("o"), null ) ) ), null, equalsBody ); members.Add(equals); var equiv = Syntax.ClassDeclaration( null, Syntax.ParseToken("internal").WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), Syntax.Identifier(withName).WithLeadingTrivia(Syntax.ParseLeadingTrivia(" ")).WithTrailingTrivia(Syntax.ParseTrailingTrivia(" ")), null, null, null, Syntax.List<MemberDeclarationSyntax>(members) ); var namespaces = tree.ChildNodes().OfType<NamespaceDeclarationSyntax>(); if (namespaces.Count() == 0 || namespaces.Count() > 1) { // HACK, better way to insert classes should be considered throw new Exception("Making some assumptions about namespaces, you can only have 1"); } var @namespace = namespaces.Single(); var updated = @namespace.WithMembers( @namespace.Members.Add(equiv) ); return tree.ReplaceNode(@namespace, updated); }
protected override void InitializeStateMachine(ArrayBuilder <BoundStatement> bodyBuilder, NamedTypeSymbol frameType, LocalSymbol stateMachineLocal) { // var stateMachineLocal = new IteratorImplementationClass(N) // where N is either 0 (if we're producing an enumerator) or -2 (if we're producing an enumerable) int initialState = isEnumerable ? StateMachineStates.FinishedStateMachine : StateMachineStates.FirstUnusedState; bodyBuilder.Add( F.Assignment( F.Local(stateMachineLocal), F.New(stateMachineType.Constructor.AsMember(frameType), F.Literal(initialState)))); }
public override Symbol VisitNamedType(NamedTypeSymbol sourceType) { var originalDef = sourceType.OriginalDefinition; if ((object)originalDef != (object)sourceType) { HashSet <DiagnosticInfo> useSiteDiagnostics = null; var typeArguments = sourceType.GetAllTypeArguments(ref useSiteDiagnostics); var otherDef = (NamedTypeSymbol)this.Visit(originalDef); if ((object)otherDef == null) { return(null); } var otherTypeParameters = otherDef.GetAllTypeParameters(); var otherTypeArguments = typeArguments.SelectAsArray((t, v) => (TypeSymbol)v.Visit(t), this); Debug.Assert(otherTypeArguments.All(t => (object)t != null)); // TODO: LambdaFrame has alpha renamed type parameters, should we rather fix that? var typeMap = new TypeMap(otherTypeParameters, otherTypeArguments, allowAlpha: true); return(typeMap.SubstituteNamedType(otherDef)); } Debug.Assert(sourceType.IsDefinition); var otherContainer = this.Visit(sourceType.ContainingSymbol); // Containing type will be missing from other assembly // if the type was added in the (newer) source assembly. if ((object)otherContainer == null) { return(null); } switch (otherContainer.Kind) { case SymbolKind.Namespace: if (AnonymousTypeManager.IsAnonymousTypeTemplate(sourceType)) { Debug.Assert((object)otherContainer == (object)_otherAssembly.GlobalNamespace); AnonymousTypeValue value; this.TryFindAnonymousType(sourceType, out value); return((NamedTypeSymbol)value.Type); } else if (sourceType.IsAnonymousType) { return(this.Visit(AnonymousTypeManager.TranslateAnonymousTypeSymbol(sourceType))); } else { return(FindMatchingNamespaceMember((NamespaceSymbol)otherContainer, sourceType, AreNamedTypesEqual)); } case SymbolKind.NamedType: return(FindMatchingNamedTypeMember((NamedTypeSymbol)otherContainer, sourceType, AreNamedTypesEqual)); default: throw ExceptionUtilities.UnexpectedValue(otherContainer.Kind); } }
private static bool IsAcceptableSystemTypeSymbol(NamedTypeSymbol candidate) { return candidate.Kind != SymbolKind.ErrorType || !(candidate is MissingMetadataTypeSymbol); }
public TypeExtraInfo AddTypeExtraInfo(NamedTypeSymbol sym) { TypeExtraInfo tei; if (TypeExtraInfo.TryGetValue(sym, out tei)) return tei; tei = new TypeExtraInfo(this,sym); TypeExtraInfo.Add(sym, tei); return tei; }
internal Microsoft.Cci.INamedTypeReference Translate(NamedTypeSymbol namedTypeSymbol, bool needDeclaration) { System.Diagnostics.Debug.Assert(ReferenceEquals(namedTypeSymbol, namedTypeSymbol.OriginalDefinition) || !namedTypeSymbol.Equals(namedTypeSymbol.OriginalDefinition)); if (!ReferenceEquals(namedTypeSymbol, namedTypeSymbol.OriginalDefinition)) { // generic instantiation for sure System.Diagnostics.Debug.Assert(!needDeclaration); return namedTypeSymbol; } else if (!needDeclaration) { object reference; Microsoft.Cci.INamedTypeReference typeRef; NamedTypeSymbol container = namedTypeSymbol.ContainingType; if (namedTypeSymbol.Arity > 0) { if (genericInstanceMap.TryGetValue(namedTypeSymbol, out reference)) { return (Microsoft.Cci.INamedTypeReference)reference; } if (container != null) { if (IsGenericType(container)) { // Container is a generic instance too. typeRef = new SpecializedGenericNestedTypeInstanceReference(namedTypeSymbol); } else { typeRef = new GenericNestedTypeInstanceReference(namedTypeSymbol); } } else { typeRef = new GenericNamespaceTypeInstanceReference(namedTypeSymbol); } genericInstanceMap.Add(namedTypeSymbol, typeRef); return typeRef; } else if (IsGenericType(container)) { System.Diagnostics.Debug.Assert(container != null); if (genericInstanceMap.TryGetValue(namedTypeSymbol, out reference)) { return (Microsoft.Cci.INamedTypeReference)reference; } typeRef = new SpecializedNestedTypeReference(namedTypeSymbol); genericInstanceMap.Add(namedTypeSymbol, typeRef); return typeRef; } } return namedTypeSymbol; }
/// <summary> /// Method to early decode the type of well-known attribute which can be queried during the BindAttributeType phase. /// This method is called first during attribute binding so that any attributes that affect semantics of type binding /// can be decoded here. /// </summary> /// <remarks> /// NOTE: If you are early decoding any new well-known attribute, make sure to update PostEarlyDecodeWellKnownAttributeTypes /// to default initialize this data. /// </remarks> internal virtual void EarlyDecodeWellKnownAttributeType(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax) { }
/// <summary> /// Creates a speculative AttributeSemanticModel that allows asking semantic questions about an attribute node that did not appear in the original source code. /// </summary> public static AttributeSemanticModel CreateSpeculative(SyntaxTreeSemanticModel parentSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, ImmutableDictionary <Symbol, Symbol> parentRemappedSymbolsOpt, int position) { Debug.Assert(parentSemanticModel != null); Debug.Assert(rootBinder != null); Debug.Assert(rootBinder.IsSemanticModelBinder); return(new AttributeSemanticModel(syntax, attributeType, aliasOpt, rootBinder, parentSemanticModelOpt: parentSemanticModel, parentRemappedSymbolsOpt: parentRemappedSymbolsOpt, speculatedPosition: position)); }
/// <summary> /// Creates an AttributeSemanticModel that allows asking semantic questions about an attribute node. /// </summary> public static AttributeSemanticModel Create(SyntaxTreeSemanticModel containingSemanticModel, AttributeSyntax syntax, NamedTypeSymbol attributeType, AliasSymbol aliasOpt, Binder rootBinder, ImmutableDictionary <Symbol, Symbol> parentRemappedSymbolsOpt) { return(new AttributeSemanticModel(syntax, attributeType, aliasOpt, rootBinder, containingSemanticModel, parentRemappedSymbolsOpt: parentRemappedSymbolsOpt)); }
/// <summary> /// Determine whether there is any substitution of type parameters that will /// make two types identical. /// </summary> /// <param name="t1">LHS</param> /// <param name="t2">RHS</param> /// <param name="substitution"> /// Substitutions performed so far (or null for none). /// Keys are type parameters, values are types (possibly type parameters). /// Will be updated with new substitutions by the callee. /// Should be ignored when false is returned. /// </param> /// <returns>True if there exists a type map such that Map(LHS) == Map(RHS).</returns> /// <remarks> /// Derived from Dev10's BSYMMGR::UnifyTypes. /// Two types will not unify if they have different custom modifiers. /// </remarks> private static bool CanUnifyHelper(TypeWithAnnotations t1, TypeWithAnnotations t2, ref MutableTypeMap substitution) { if (!t1.HasType || !t2.HasType) { return(t1.IsSameAs(t2)); } if (TypeSymbol.Equals(t1.Type, t2.Type, TypeCompareKind.ConsiderEverything2) && t1.CustomModifiers.SequenceEqual(t2.CustomModifiers)) { return(true); } if (substitution != null) { t1 = t1.SubstituteType(substitution); t2 = t2.SubstituteType(substitution); } // If one of the types is a type parameter, then the substitution could make them equal. if (TypeSymbol.Equals(t1.Type, t2.Type, TypeCompareKind.ConsiderEverything2) && t1.CustomModifiers.SequenceEqual(t2.CustomModifiers)) { return(true); } // We can avoid a lot of redundant checks if we ensure that we only have to check // for type parameters on the LHS if (!t1.Type.IsTypeParameter() && t2.Type.IsTypeParameter()) { TypeWithAnnotations tmp = t1; t1 = t2; t2 = tmp; } // If t1 is not a type parameter, then neither is t2 Debug.Assert(t1.Type.IsTypeParameter() || !t2.Type.IsTypeParameter()); switch (t1.Type.Kind) { case SymbolKind.ArrayType: { if (t2.TypeKind != t1.TypeKind || !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers)) { return(false); } ArrayTypeSymbol at1 = (ArrayTypeSymbol)t1.Type; ArrayTypeSymbol at2 = (ArrayTypeSymbol)t2.Type; if (!at1.HasSameShapeAs(at2)) { return(false); } return(CanUnifyHelper(at1.ElementTypeWithAnnotations, at2.ElementTypeWithAnnotations, ref substitution)); } case SymbolKind.PointerType: { if (t2.TypeKind != t1.TypeKind || !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers)) { return(false); } PointerTypeSymbol pt1 = (PointerTypeSymbol)t1.Type; PointerTypeSymbol pt2 = (PointerTypeSymbol)t2.Type; return(CanUnifyHelper(pt1.PointedAtTypeWithAnnotations, pt2.PointedAtTypeWithAnnotations, ref substitution)); } case SymbolKind.NamedType: case SymbolKind.ErrorType: { if (t2.TypeKind != t1.TypeKind || !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers)) { return(false); } NamedTypeSymbol nt1 = (NamedTypeSymbol)t1.Type; NamedTypeSymbol nt2 = (NamedTypeSymbol)t2.Type; if (!nt1.IsGenericType) { return(!nt2.IsGenericType && TypeSymbol.Equals(nt1, nt2, TypeCompareKind.ConsiderEverything2)); } else if (!nt2.IsGenericType) { return(false); } int arity = nt1.Arity; if (nt2.Arity != arity || !TypeSymbol.Equals(nt2.OriginalDefinition, nt1.OriginalDefinition, TypeCompareKind.ConsiderEverything2)) { return(false); } var nt1Arguments = nt1.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics; var nt2Arguments = nt2.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics; for (int i = 0; i < arity; i++) { if (!CanUnifyHelper(nt1Arguments[i], nt2Arguments[i], ref substitution)) { return(false); } } // Note: Dev10 folds this into the loop since GetTypeArgsAll includes type args for containing types // TODO: Calling CanUnifyHelper for the containing type is an overkill, we simply need to go through type arguments for all containers. return((object)nt1.ContainingType == null || CanUnifyHelper(nt1.ContainingType, nt2.ContainingType, ref substitution)); } case SymbolKind.TypeParameter: { // These substitutions are not allowed in C# if (t2.Type.IsPointerOrFunctionPointer() || t2.IsVoidType()) { return(false); } TypeParameterSymbol tp1 = (TypeParameterSymbol)t1.Type; // Perform the "occurs check" - i.e. ensure that t2 doesn't contain t1 to avoid recursive types // Note: t2 can't be the same type param - we would have caught that with ReferenceEquals above if (Contains(t2.Type, tp1)) { return(false); } if (t1.CustomModifiers.IsDefaultOrEmpty) { AddSubstitution(ref substitution, tp1, t2); return(true); } if (t1.CustomModifiers.SequenceEqual(t2.CustomModifiers)) { AddSubstitution(ref substitution, tp1, TypeWithAnnotations.Create(t2.Type)); return(true); } if (t1.CustomModifiers.Length < t2.CustomModifiers.Length && t1.CustomModifiers.SequenceEqual(t2.CustomModifiers.Take(t1.CustomModifiers.Length))) { AddSubstitution(ref substitution, tp1, TypeWithAnnotations.Create(t2.Type, customModifiers: ImmutableArray.Create(t2.CustomModifiers, t1.CustomModifiers.Length, t2.CustomModifiers.Length - t1.CustomModifiers.Length))); return(true); } if (t2.Type.IsTypeParameter()) { var tp2 = (TypeParameterSymbol)t2.Type; if (t2.CustomModifiers.IsDefaultOrEmpty) { AddSubstitution(ref substitution, tp2, t1); return(true); } if (t2.CustomModifiers.Length < t1.CustomModifiers.Length && t2.CustomModifiers.SequenceEqual(t1.CustomModifiers.Take(t2.CustomModifiers.Length))) { AddSubstitution(ref substitution, tp2, TypeWithAnnotations.Create(t1.Type, customModifiers: ImmutableArray.Create(t1.CustomModifiers, t2.CustomModifiers.Length, t1.CustomModifiers.Length - t2.CustomModifiers.Length))); return(true); } } return(false); } default: { return(false); } } }
public DeepTranslator(NamedTypeSymbol systemObject) { _matches = new ConcurrentDictionary <Symbol, Symbol>(ReferenceEqualityComparer.Instance); _systemObject = systemObject; }
public override Symbol VisitNamedType(NamedTypeSymbol sourceType) { var originalDef = sourceType.OriginalDefinition; if ((object)originalDef != (object)sourceType) { HashSet <DiagnosticInfo> useSiteDiagnostics = null; var typeArguments = sourceType.GetAllTypeArguments(ref useSiteDiagnostics); var otherDef = (NamedTypeSymbol)Visit(originalDef); if (otherDef is null) { return(null); } var otherTypeParameters = otherDef.GetAllTypeParameters(); bool translationFailed = false; var otherTypeArguments = typeArguments.SelectAsArray((t, v) => { var newType = (TypeSymbol)v.Visit(t.Type); if (newType is null) { // For a newly added type, there is no match in the previous generation, so it could be null. translationFailed = true; newType = t.Type; } return(t.WithTypeAndModifiers(newType, v.VisitCustomModifiers(t.CustomModifiers))); }, this); if (translationFailed) { // For a newly added type, there is no match in the previous generation, so it could be null. return(null); } // TODO: LambdaFrame has alpha renamed type parameters, should we rather fix that? var typeMap = new TypeMap(otherTypeParameters, otherTypeArguments, allowAlpha: true); return(typeMap.SubstituteNamedType(otherDef)); } Debug.Assert(sourceType.IsDefinition); var otherContainer = this.Visit(sourceType.ContainingSymbol); // Containing type will be missing from other assembly // if the type was added in the (newer) source assembly. if (otherContainer is null) { return(null); } switch (otherContainer.Kind) { case SymbolKind.Namespace: if (sourceType is AnonymousTypeManager.AnonymousTypeTemplateSymbol template) { Debug.Assert((object)otherContainer == (object)_otherAssembly.GlobalNamespace); TryFindAnonymousType(template, out var value); return((NamedTypeSymbol)value.Type); } if (sourceType.IsAnonymousType) { return(Visit(AnonymousTypeManager.TranslateAnonymousTypeSymbol(sourceType))); } return(FindMatchingMember(otherContainer, sourceType, AreNamedTypesEqual)); case SymbolKind.NamedType: return(FindMatchingMember(otherContainer, sourceType, AreNamedTypesEqual)); default: throw ExceptionUtilities.UnexpectedValue(otherContainer.Kind); } }
private IReadOnlyDictionary <string, ImmutableArray <Cci.ITypeDefinitionMember> > GetOtherTypeMembers(NamedTypeSymbol otherType) { var members = ArrayBuilder <Cci.ITypeDefinitionMember> .GetInstance(); members.AddRange(otherType.GetEventsToEmit()); members.AddRange(otherType.GetFieldsToEmit()); members.AddRange(otherType.GetMethodsToEmit()); members.AddRange(otherType.GetTypeMembers()); members.AddRange(otherType.GetPropertiesToEmit()); ImmutableArray <Cci.ITypeDefinitionMember> synthesizedMembers; if (_otherSynthesizedMembersOpt != null && _otherSynthesizedMembersOpt.TryGetValue(otherType, out synthesizedMembers)) { members.AddRange(synthesizedMembers); } var result = members.ToDictionary(s => ((Symbol)s).Name, s_nameComparer); members.Free(); return(result); }
public static bool EarlyDecodeIsObsoleteAttribute(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax) { return EarlyDecodeIsTargetAttribute(attributeType, attributeSyntax, AttributeDescription.ObsoleteAttribute, skipParamCheck:true); }
public string CompileShaderBoilerplate(NamedTypeSymbol Symbol, List<Dictionary<Symbol, string>> Specializations) { ClearString(); WriteLine("namespace {0}", Symbol.ContainingNamespace); WriteLine("{"); var PrevIndent1 = Indent(); WriteBoilerplateClass(Symbol, Specializations); RestoreIndent(PrevIndent1); WriteLine("}"); WriteLine(); string boilerplate = GetString(); return boilerplate; }
internal SynthesizedClosureMethod( NamedTypeSymbol containingType, ImmutableArray <SynthesizedClosureEnvironment> structEnvironments, ClosureKind closureKind, MethodSymbol topLevelMethod, DebugId topLevelMethodId, MethodSymbol originalMethod, SyntaxReference blockSyntax, DebugId lambdaId, DiagnosticBag diagnostics) : base(containingType, originalMethod, blockSyntax, originalMethod.DeclaringSyntaxReferences[0].GetLocation(), originalMethod is LocalFunctionSymbol ? MakeName(topLevelMethod.Name, originalMethod.Name, topLevelMethodId, closureKind, lambdaId) : MakeName(topLevelMethod.Name, topLevelMethodId, closureKind, lambdaId), MakeDeclarationModifiers(closureKind, originalMethod)) { _topLevelMethod = topLevelMethod; ClosureKind = closureKind; LambdaId = lambdaId; TypeMap typeMap; ImmutableArray <TypeParameterSymbol> typeParameters; ImmutableArray <TypeParameterSymbol> constructedFromTypeParameters; var lambdaFrame = ContainingType as SynthesizedClosureEnvironment; switch (closureKind) { case ClosureKind.Singleton: // all type parameters on method (except the top level method's) case ClosureKind.General: // only lambda's type parameters on method (rest on class) Debug.Assert((object)lambdaFrame != null); typeMap = lambdaFrame.TypeMap.WithConcatAlphaRename( originalMethod, this, out typeParameters, out constructedFromTypeParameters, lambdaFrame.OriginalContainingMethodOpt); break; case ClosureKind.ThisOnly: // all type parameters on method case ClosureKind.Static: Debug.Assert((object)lambdaFrame == null); typeMap = TypeMap.Empty.WithConcatAlphaRename( originalMethod, this, out typeParameters, out constructedFromTypeParameters, stopAt: null); break; default: throw ExceptionUtilities.UnexpectedValue(closureKind); } if (!structEnvironments.IsDefaultOrEmpty && typeParameters.Length != 0) { var constructedStructClosures = ArrayBuilder <NamedTypeSymbol> .GetInstance(); foreach (var env in structEnvironments) { NamedTypeSymbol constructed; if (env.Arity == 0) { constructed = env; } else { var originals = env.ConstructedFromTypeParameters; var newArgs = typeMap.SubstituteTypeParameters(originals); constructed = env.Construct(newArgs); } constructedStructClosures.Add(constructed); } _structEnvironments = constructedStructClosures.ToImmutableAndFree(); } else { _structEnvironments = ImmutableArray <NamedTypeSymbol> .CastUp(structEnvironments); } AssignTypeMapAndTypeParameters(typeMap, typeParameters); }
public override Microsoft.Cci.IReference VisitNamedType(NamedTypeSymbol symbol, bool a) { return Translate(symbol, false); }
internal bool TryGetAnonymousTypeName(NamedTypeSymbol template, out string name, out int index) { return(this.symbols.TryGetAnonymousTypeName(template, out name, out index)); }
public ClassMetadataGenerator(Chunk chunk, NamedTypeSymbol cls) { Chunk = chunk; Class = cls; Members = new List<FlatValue>(); }
public NamedTypeDefinition(Module moduleBeingBuilt, NamedTypeSymbol underlyingNamedType) : base(moduleBeingBuilt, underlyingNamedType) { System.Diagnostics.Debug.Assert(underlyingNamedType is SourceNamedTypeSymbol); }
/// <summary> /// This method does the following set of operations in the specified order: /// (1) GetAttributesToBind: Merge attributes from the given attributesSyntaxLists and filter out attributes by attribute target. /// (2) BindAttributeTypes: Bind all the attribute types to enable early decode of certain well-known attributes by type. /// (3) EarlyDecodeWellKnownAttributes: Perform early decoding of certain well-known attributes that could be queried by the binder in subsequent steps. /// (NOTE: This step has the side effect of updating the symbol state based on the data extracted from well known attributes). /// (4) GetAttributes: Bind the attributes (attribute arguments and constructor) using bound attribute types. /// (5) DecodeWellKnownAttributes: Decode and validate bound well known attributes. /// (NOTE: This step has the side effect of updating the symbol state based on the data extracted from well known attributes). /// (6) StoreBoundAttributesAndDoPostValidation: /// (a) Store the bound attributes in lazyCustomAttributes in a thread safe manner. /// (b) Perform some additional post attribute validations, such as /// 1) Duplicate attributes, attribute usage target validation, etc. /// 2) Post validation for attributes dependent on other attributes /// These validations cannot be performed prior to step 6(a) as we might need to /// perform a GetAttributes() call on a symbol which can introduce a cycle in attribute binding. /// We avoid this cycle by performing such validations in PostDecodeWellKnownAttributes after lazyCustomAttributes have been set. /// NOTE: PostDecodeWellKnownAttributes SHOULD NOT change the symbol state. /// </summary> /// <remarks> /// Current design of early decoding well-known attributes doesn't permit decoding attribute arguments/constructor as this can lead to binding cycles. /// For well-known attributes used by the binder, where we need the decoded arguments, we must handle them specially in one of the following possible ways: /// (a) Avoid decoding the attribute arguments during binding and delay the corresponding binder tasks to a separate post-pass executed after binding. /// (b) As the cycles can be caused only when we are binding attribute arguments/constructor, special case the corresponding binder tasks based on the current BinderFlags. /// </remarks> /// <param name="attributesSyntaxLists"></param> /// <param name="lazyCustomAttributesBag"></param> /// <param name="symbolPart">Specific part of the symbol to which the attributes apply, or <see cref="AttributeLocation.None"/> if the attributes apply to the symbol itself.</param> /// <param name="earlyDecodingOnly">Indicates that only early decoding should be performed. WARNING: the resulting bag will not be sealed.</param> /// <returns>Flag indicating whether lazyCustomAttributes were stored on this thread. Caller should check for this flag and perform NotePartComplete if true.</returns> internal bool LoadAndValidateAttributes( OneOrMany <SyntaxList <AttributeListSyntax> > attributesSyntaxLists, ref CustomAttributesBag <CSharpAttributeData> lazyCustomAttributesBag, AttributeLocation symbolPart = AttributeLocation.None, bool earlyDecodingOnly = false) { var diagnostics = DiagnosticBag.GetInstance(); var compilation = this.DeclaringCompilation; ImmutableArray <Binder> binders; ImmutableArray <AttributeSyntax> attributesToBind = this.GetAttributesToBind(attributesSyntaxLists, symbolPart, diagnostics, compilation, out binders); Debug.Assert(!attributesToBind.IsDefault); ImmutableArray <CSharpAttributeData> boundAttributes; WellKnownAttributeData wellKnownAttributeData; if (attributesToBind.Any()) { Debug.Assert(!binders.IsDefault); Debug.Assert(binders.Length == attributesToBind.Length); // Initialize the bag so that data decoded from early attributes can be stored onto it. if (lazyCustomAttributesBag == null) { Interlocked.CompareExchange(ref lazyCustomAttributesBag, new CustomAttributesBag <CSharpAttributeData>(), null); } // Bind the attribute types and then early decode them. int totalAttributesCount = attributesToBind.Length; var attributeTypesBuilder = new NamedTypeSymbol[totalAttributesCount]; Binder.BindAttributeTypes(binders, attributesToBind, this, attributeTypesBuilder, diagnostics); ImmutableArray <NamedTypeSymbol> boundAttributeTypes = attributeTypesBuilder.AsImmutableOrNull(); this.EarlyDecodeWellKnownAttributeTypes(boundAttributeTypes, attributesToBind); this.PostEarlyDecodeWellKnownAttributeTypes(); // Bind the attribute in two stages - early and normal. var attributesBuilder = new CSharpAttributeData[totalAttributesCount]; // Early bind and decode some well-known attributes. EarlyWellKnownAttributeData earlyData = this.EarlyDecodeWellKnownAttributes(binders, boundAttributeTypes, attributesToBind, symbolPart, attributesBuilder); Debug.Assert(!attributesBuilder.Contains((attr) => attr != null && attr.HasErrors)); // Store data decoded from early bound well-known attributes. // TODO: what if this succeeds on another thread, not ours? lazyCustomAttributesBag.SetEarlyDecodedWellKnownAttributeData(earlyData); if (earlyDecodingOnly) { diagnostics.Free(); //NOTE: dropped. return(false); } // Bind attributes. Binder.GetAttributes(binders, attributesToBind, boundAttributeTypes, attributesBuilder, diagnostics); boundAttributes = attributesBuilder.AsImmutableOrNull(); // All attributes must be bound by now. Debug.Assert(!boundAttributes.Any((attr) => attr == null)); // Validate attribute usage and Decode remaining well-known attributes. wellKnownAttributeData = this.ValidateAttributeUsageAndDecodeWellKnownAttributes(binders, attributesToBind, boundAttributes, diagnostics, symbolPart); // Store data decoded from remaining well-known attributes. // TODO: what if this succeeds on another thread but not this thread? lazyCustomAttributesBag.SetDecodedWellKnownAttributeData(wellKnownAttributeData); } else if (earlyDecodingOnly) { diagnostics.Free(); //NOTE: dropped. return(false); } else { boundAttributes = ImmutableArray <CSharpAttributeData> .Empty; wellKnownAttributeData = null; Interlocked.CompareExchange(ref lazyCustomAttributesBag, CustomAttributesBag <CSharpAttributeData> .WithEmptyData(), null); this.PostEarlyDecodeWellKnownAttributeTypes(); } this.PostDecodeWellKnownAttributes(boundAttributes, attributesToBind, diagnostics, symbolPart, wellKnownAttributeData); // Store attributes into the bag. bool lazyAttributesStoredOnThisThread = false; if (lazyCustomAttributesBag.SetAttributes(boundAttributes)) { this.RecordPresenceOfBadAttributes(boundAttributes); this.AddDeclarationDiagnostics(diagnostics); lazyAttributesStoredOnThisThread = true; if (lazyCustomAttributesBag.IsEmpty) { lazyCustomAttributesBag = CustomAttributesBag <CSharpAttributeData> .Empty; } } Debug.Assert(lazyCustomAttributesBag.IsSealed); diagnostics.Free(); return(lazyAttributesStoredOnThisThread); }
internal SynthesizedLambdaMethod( NamedTypeSymbol containingType, ImmutableArray <TypeSymbol> structClosures, ClosureKind closureKind, MethodSymbol topLevelMethod, DebugId topLevelMethodId, IBoundLambdaOrFunction lambdaNode, DebugId lambdaId) : base(containingType, lambdaNode.Symbol, null, lambdaNode.Syntax.SyntaxTree.GetReference(lambdaNode.Body.Syntax), lambdaNode.Syntax.GetLocation(), lambdaNode is BoundLocalFunctionStatement ? MakeName(topLevelMethod.Name, lambdaNode.Symbol.Name, topLevelMethodId, closureKind, lambdaId) : MakeName(topLevelMethod.Name, topLevelMethodId, closureKind, lambdaId), (closureKind == ClosureKind.ThisOnly ? DeclarationModifiers.Private : DeclarationModifiers.Internal) | (closureKind == ClosureKind.Static ? DeclarationModifiers.Static : 0) | (lambdaNode.Symbol.IsAsync ? DeclarationModifiers.Async : 0)) { _topLevelMethod = topLevelMethod; TypeMap typeMap; ImmutableArray <TypeParameterSymbol> typeParameters; ImmutableArray <TypeParameterSymbol> constructedFromTypeParameters; LambdaFrame lambdaFrame; lambdaFrame = this.ContainingType as LambdaFrame; switch (closureKind) { case ClosureKind.Singleton: // all type parameters on method (except the top level method's) case ClosureKind.General: // only lambda's type parameters on method (rest on class) Debug.Assert(lambdaFrame != null); typeMap = lambdaFrame.TypeMap.WithConcatAlphaRename(lambdaNode.Symbol, this, out typeParameters, out constructedFromTypeParameters, lambdaFrame.ContainingMethod); break; case ClosureKind.ThisOnly: // all type parameters on method case ClosureKind.Static: Debug.Assert(lambdaFrame == null); typeMap = TypeMap.Empty.WithConcatAlphaRename(lambdaNode.Symbol, this, out typeParameters, out constructedFromTypeParameters, null); break; default: throw ExceptionUtilities.Unreachable; } if (!structClosures.IsDefaultOrEmpty && typeParameters.Length != 0) { var constructedStructClosures = ArrayBuilder <TypeSymbol> .GetInstance(); foreach (var closure in structClosures) { var frame = (LambdaFrame)closure; NamedTypeSymbol constructed; if (frame.Arity == 0) { constructed = frame; } else { var originals = frame.ConstructedFromTypeParameters; var newArgs = typeMap.SubstituteTypeParameters(originals); constructed = frame.Construct(newArgs); } constructedStructClosures.Add(constructed); } structClosures = constructedStructClosures.ToImmutableAndFree(); } _structClosures = structClosures; AssignTypeMapAndTypeParameters(typeMap, typeParameters); }
private bool AreNamedTypesEqual(NamedTypeSymbol type, NamedTypeSymbol other) { Debug.Assert(NameComparer.Equals(type.Name, other.Name)); return(type.TypeArgumentsNoUseSiteDiagnostics.SequenceEqual(other.TypeArgumentsNoUseSiteDiagnostics, AreTypesEqual)); }
private static bool HasUniqueInterface(TypeSymbol instanceType, NamedTypeSymbol interfaceType, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { bool nonUnique = false; return(HasUniqueInterface(instanceType, interfaceType, ref nonUnique, ref useSiteDiagnostics)); }
private static IReadOnlyDictionary <string, ImmutableArray <Symbol> > GetTypeMembers(NamedTypeSymbol type) { var members = ArrayBuilder <Symbol> .GetInstance(); members.AddRange(type.GetEventsToEmit()); members.AddRange(type.GetFieldsToEmit()); members.AddRange(type.GetMethodsToEmit()); members.AddRange(type.GetTypeMembers()); members.AddRange(type.GetPropertiesToEmit()); var result = members.ToDictionary(s => s.Name, NameComparer); members.Free(); return(result); }
private static PropertySymbol FindIndexerWithParameterCount(NamedTypeSymbol type, int parameterCount) { return(type.GetMembers().Where(s => s.Kind == SymbolKind.Property).Cast <PropertySymbol>().Single(p => p.Parameters.Length == parameterCount)); }
public SynthesizedExplicitImplementationForwardingMethod(MethodSymbol interfaceMethod, MethodSymbol implementingMethod, NamedTypeSymbol implementingType) : base(interfaceMethod, implementingType, generateDebugInfo: false) { this.implementingMethod = implementingMethod; }
public SynthesizedContextMethodSymbol(NamedTypeSymbol container) { _container = container; }
private Symbol GetBackingField(AccessorDeclarationSyntax getter, NamedTypeSymbol containingType) { var statements = getter.Body.Statements; if (statements.Count == 1) { var returnStatement = statements.FirstOrDefault() as ReturnStatementSyntax; if (returnStatement != null && returnStatement.Expression != null) { var symbolInfo = document.GetSemanticModel().GetSymbolInfo(returnStatement.Expression); var fieldSymbol = symbolInfo.Symbol as FieldSymbol; if (fieldSymbol != null && fieldSymbol.OriginalDefinition.ContainingType == containingType) { return fieldSymbol; } } } return null; }
protected abstract void InitializeStateMachine(ArrayBuilder <BoundStatement> bodyBuilder, NamedTypeSymbol frameType, LocalSymbol stateMachineLocal);
private static void GetGenericTypeArgumentSymbol(int position, NamedTypeSymbol namedType, out int cumulativeArity, out TypeSymbol typeArgument) { cumulativeArity = namedType.Arity; typeArgument = null; int arityOffset = 0; var containingType = namedType.ContainingType; if ((object)containingType != null) { int containingTypeCumulativeArity; GetGenericTypeArgumentSymbol(position, containingType, out containingTypeCumulativeArity, out typeArgument); cumulativeArity += containingTypeCumulativeArity; arityOffset = containingTypeCumulativeArity; } if (arityOffset <= position && position < cumulativeArity) { Debug.Assert((object)typeArgument == null); typeArgument = namedType.TypeArgumentsNoUseSiteDiagnostics[position - arityOffset]; } }
protected abstract BoundStatement GenerateStateMachineCreation(LocalSymbol stateMachineVariable, NamedTypeSymbol frameType, IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> proxies);
private void EnsureSignatureIsLoaded() { if ((object)_lazyType == null) { var moduleSymbol = _containingType.ContainingPEModule; bool isVolatile; ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers; TypeSymbol type = (new MetadataDecoder(moduleSymbol, _containingType)).DecodeFieldSignature(_handle, out isVolatile, out customModifiers); ImmutableArray<CustomModifier> customModifiersArray = CSharpCustomModifier.Convert(customModifiers); type = DynamicTypeDecoder.TransformType(type, customModifiersArray.Length, _handle, moduleSymbol); _lazyIsVolatile = isVolatile; TypeSymbol fixedElementType; int fixedSize; if (customModifiersArray.IsEmpty && IsFixedBuffer(out fixedSize, out fixedElementType)) { _lazyFixedSize = fixedSize; _lazyFixedImplementationType = type as NamedTypeSymbol; type = new PointerTypeSymbol(fixedElementType); } ImmutableInterlocked.InterlockedCompareExchange(ref _lazyCustomModifiers, customModifiersArray, default(ImmutableArray<CustomModifier>)); Interlocked.CompareExchange(ref _lazyType, type, null); } }
private void AddNameAndTypeArgumentsOrParameters(INamedTypeSymbol symbol) { if (symbol.IsAnonymousType) { AddAnonymousTypeName(symbol); return; } else if (symbol.IsTupleType && !ShouldDisplayAsValueTuple(symbol)) { AddTupleTypeName(symbol); return; } string symbolName = null; // It would be nice to handle VB NoPia symbols too, but it's not worth the effort. NamedTypeSymbol underlyingTypeSymbol = (symbol as Symbols.PublicModel.NamedTypeSymbol)?.UnderlyingNamedTypeSymbol; var illegalGenericInstantiationSymbol = underlyingTypeSymbol as NoPiaIllegalGenericInstantiationSymbol; if ((object)illegalGenericInstantiationSymbol != null) { symbol = illegalGenericInstantiationSymbol.UnderlyingSymbol.GetPublicSymbol(); } else { var ambiguousCanonicalTypeSymbol = underlyingTypeSymbol as NoPiaAmbiguousCanonicalTypeSymbol; if ((object)ambiguousCanonicalTypeSymbol != null) { symbol = ambiguousCanonicalTypeSymbol.FirstCandidate.GetPublicSymbol(); } else { var missingCanonicalTypeSymbol = underlyingTypeSymbol as NoPiaMissingCanonicalTypeSymbol; if ((object)missingCanonicalTypeSymbol != null) { symbolName = missingCanonicalTypeSymbol.FullTypeName; } } } var partKind = GetPartKind(symbol); if (symbolName == null) { symbolName = symbol.Name; } if (format.MiscellaneousOptions.IncludesOption(SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName) && partKind == SymbolDisplayPartKind.ErrorTypeName && string.IsNullOrEmpty(symbolName)) { builder.Add(CreatePart(partKind, symbol, "?")); } else { symbolName = RemoveAttributeSufficeIfNecessary(symbol, symbolName); builder.Add(CreatePart(partKind, symbol, symbolName)); } if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes)) { // Only the compiler can set the internal option and the compiler doesn't use other implementations of INamedTypeSymbol. if (underlyingTypeSymbol?.MangleName == true) { Debug.Assert(symbol.Arity > 0); builder.Add(CreatePart(InternalSymbolDisplayPartKind.Arity, null, MetadataHelpers.GetAritySuffix(symbol.Arity))); } } else if (symbol.Arity > 0 && format.GenericsOptions.IncludesOption(SymbolDisplayGenericsOptions.IncludeTypeParameters)) { // It would be nice to handle VB symbols too, but it's not worth the effort. if (underlyingTypeSymbol is UnsupportedMetadataTypeSymbol || underlyingTypeSymbol is MissingMetadataTypeSymbol || symbol.IsUnboundGenericType) { AddPunctuation(SyntaxKind.LessThanToken); for (int i = 0; i < symbol.Arity - 1; i++) { AddPunctuation(SyntaxKind.CommaToken); } AddPunctuation(SyntaxKind.GreaterThanToken); } else { ImmutableArray <ImmutableArray <CustomModifier> > modifiers = GetTypeArgumentsModifiers(underlyingTypeSymbol); AddTypeArguments(symbol, modifiers); AddDelegateParameters(symbol); // TODO: do we want to skip these if we're being visited as a containing type? AddTypeParameterConstraints(symbol.TypeArguments); } } else { AddDelegateParameters(symbol); } // Only the compiler can set the internal option and the compiler doesn't use other implementations of INamedTypeSymbol. if (underlyingTypeSymbol?.OriginalDefinition is MissingMetadataTypeSymbol && format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.FlagMissingMetadataTypes)) { //add it as punctuation - it's just for testing AddPunctuation(SyntaxKind.OpenBracketToken); builder.Add(CreatePart(InternalSymbolDisplayPartKind.Other, symbol, "missing")); AddPunctuation(SyntaxKind.CloseBracketToken); } }
public static bool EarlyDecodeIsConditionalAttribute(NamedTypeSymbol attributeType, AttributeSyntax attributeSyntax) { return EarlyDecodeIsTargetAttribute(attributeType, attributeSyntax, AttributeDescription.ConditionalAttribute); }
private ImmutableArray <ImmutableArray <CustomModifier> > GetTypeArgumentsModifiers(NamedTypeSymbol underlyingTypeSymbol) { if (this.format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.IncludeCustomModifiers)) { if ((object)underlyingTypeSymbol != null) { return(underlyingTypeSymbol.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics.SelectAsArray(a => a.CustomModifiers)); } } return(default);
public string CompileShader(NamedTypeSymbol Symbol, MethodDeclarationSyntax vertex_method, MethodDeclarationSyntax fragment_method) { ClearString(); // Declare samplers and other relevant structures needed for the Fragment Shader Write(SpaceFormat(FileBegin)); EndLine(); WriteLine(); WriteLine(VertexMethodParameters); CompileVertexSignature(vertex_method); EndLine(); WriteLine(FragmentMethodParameters); var LocalFragmentLookup = CompileFragmentSignature(fragment_method); EndLine(); // Referenced foreign variables Write(SpaceFormat(ReferencedForeignVarsPreamble)); EndLine(); Write("<$0$>"); // This is where we will insert referenced foreign variables. WriteLine(); // Referenced methods Write(SpaceFormat(ReferencedMethodsPreamble)); EndLine(); Write("<$1$>"); // This is where we will insert referenced methods. WriteLine(); // Vertex Shader method CurrentMethod = Compiling.VertexMethod; Write(SpaceFormat(VertexShaderBegin)); EndLine(); var PrevIndent = Indent(); FunctionParameterPrefix = VertexShaderParameterPrefix; CompileStatement(vertex_method.Body); RestoreIndent(PrevIndent); Write(SpaceFormat(VertexShaderEnd)); EndLine(); WriteLine(); // Fragment Shader method UseLocalSymbolMap(LocalFragmentLookup); CurrentMethod = Compiling.FragmentMethod; Write(FragmentShaderBegin, Tab, LineBreak, VertexToPixelDecl); EndLine(); PrevIndent = Indent(); FunctionParameterPrefix = FragmentShaderParameterPrefix; CompileStatement(fragment_method.Body); RestoreIndent(PrevIndent); Write(SpaceFormat(FragmentShaderEnd)); EndLine(); UseLocalSymbolMap(null); WriteLine(); Write(SpaceFormat(FileEnd)); // We must wait until after compiling the shader to know which methods that shader references. string methods = GetReferencedMethods(); // We must wait until after compiling the shader to know which foreign variables that shader references. string foreign_vars = GetForeignVars(); // Now get the full string written so far and insert the referenced methods. string fragment = GetString(); fragment = SpecialFormat(fragment, foreign_vars, methods); return fragment; }
protected override void InitializeStateMachine(ArrayBuilder <BoundStatement> bodyBuilder, NamedTypeSymbol frameType, LocalSymbol stateMachineLocal) { if (frameType.TypeKind == TypeKind.Class) { // local = new {state machine type}(); bodyBuilder.Add( F.Assignment( F.Local(stateMachineLocal), F.New(frameType.InstanceConstructors[0]))); } }
void WriteBoilerplateClass(NamedTypeSymbol symbol, List<Dictionary<Symbol, string>> Specializations) { WriteLine("public partial class {0}", symbol.Name); WriteLine("{"); var PrevIndent = Indent(); // If there are no specializations (count == 1) then we only need a single Effect. if (Specializations.Count == 1) { WriteLine("public static Effect CompiledEffect;"); } else { // Otherwise we need an Effect for each specialization. foreach (var specialization in Specializations) { WriteLine("public static Effect CompiledEffect{0};", ShaderClass.SpecializationVarSuffix(specialization)); } } WriteLine(); WriteBoilerplateSignature(ApplyName, "RenderTarget2D Output, Color Clear"); WriteBoilerplateApplyFunc("Output", "Clear"); WriteBoilerplateSignature(ApplyName, "RenderTarget2D Output"); WriteBoilerplateApplyFunc("Output", "Color.Transparent"); WriteBoilerplateSignature(UsingName, "RenderTarget2D Output, Color Clear"); WriteBoilerplateUsingFuncOverload("Output", "Clear"); WriteBoilerplateSignature(UsingName, "RenderTarget2D Output"); WriteBoilerplateUsingFuncOverload("Output", "Color.Transparent"); WriteBoilerplateSignature(UsingName); WriteBoilerplateUsingFunc(Specializations); RestoreIndent(PrevIndent); WriteLine("}"); }
protected override BoundStatement GenerateStateMachineCreation(LocalSymbol stateMachineVariable, NamedTypeSymbol frameType) { // If the async method's result type is a type parameter of the method, then the AsyncTaskMethodBuilder<T> // needs to use the method's type parameters inside the rewritten method body. All other methods generated // during async rewriting are members of the synthesized state machine struct, and use the type parameters // structs type parameters. AsyncMethodBuilderMemberCollection methodScopeAsyncMethodBuilderMemberCollection; if (!AsyncMethodBuilderMemberCollection.TryCreate(F, method, null, out methodScopeAsyncMethodBuilderMemberCollection)) { return(new BoundBadStatement(F.Syntax, ImmutableArray <BoundNode> .Empty, hasErrors: true)); } var bodyBuilder = ArrayBuilder <BoundStatement> .GetInstance(); var builderVariable = F.SynthesizedLocal(methodScopeAsyncMethodBuilderMemberCollection.BuilderType, null); // local.$builder = System.Runtime.CompilerServices.AsyncTaskMethodBuilder<typeArgs>.Create(); bodyBuilder.Add( F.Assignment( F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)), F.StaticCall( null, methodScopeAsyncMethodBuilderMemberCollection.CreateBuilder))); // local.$stateField = NotStartedStateMachine bodyBuilder.Add( F.Assignment( F.Field(F.Local(stateMachineVariable), stateField.AsMember(frameType)), F.Literal(StateMachineStates.NotStartedStateMachine))); bodyBuilder.Add( F.Assignment( F.Local(builderVariable), F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)))); // local.$builder.Start(ref local) -- binding to the method AsyncTaskMethodBuilder<typeArgs>.Start() var startMethod = methodScopeAsyncMethodBuilderMemberCollection.Start.Construct(frameType); if (methodScopeAsyncMethodBuilderMemberCollection.CheckGenericMethodConstraints) { startMethod.CheckConstraints(F.Compilation.Conversions, F.Syntax, F.Compilation, diagnostics); } bodyBuilder.Add( F.ExpressionStatement( F.Call( F.Local(builderVariable), startMethod, ImmutableArray.Create <BoundExpression>(F.Local(stateMachineVariable))))); bodyBuilder.Add(method.IsVoidReturningAsync() ? F.Return() : F.Return( F.Property( F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)), methodScopeAsyncMethodBuilderMemberCollection.Task))); return(F.Block( ImmutableArray.Create(builderVariable), bodyBuilder.ToImmutableAndFree())); }
public static bool IsGenericType(NamedTypeSymbol toCheck) { while (toCheck != null) { if (toCheck.Arity > 0) { return true; } toCheck = toCheck.ContainingType; } return false; }
protected override void InitializeStateMachine(ArrayBuilder <BoundStatement> bodyBuilder, NamedTypeSymbol frameType, LocalSymbol stateMachineLocal) { // var stateMachineLocal = new {StateMachineType}({initialState}) int initialState = _isEnumerable ? StateMachineStates.FinishedStateMachine : StateMachineStates.InitialAsyncIteratorStateMachine; bodyBuilder.Add( F.Assignment( F.Local(stateMachineLocal), F.New(stateMachineType.Constructor.AsMember(frameType), F.Literal(initialState)))); }
private NamedTypeSymbol DecodeNamedType(NamedTypeSymbol type) { // First decode the type arguments var typeArgs = type.TypeArgumentsNoUseSiteDiagnostics; var decodedArgs = DecodeTypeArguments(typeArgs); NamedTypeSymbol decodedType = type; // Now check the container NamedTypeSymbol containingType = type.ContainingType; NamedTypeSymbol decodedContainingType; if ((object)containingType != null && containingType.IsGenericType) { decodedContainingType = DecodeNamedType(containingType); Debug.Assert(decodedContainingType.IsGenericType); } else { decodedContainingType = containingType; } // Replace the type if necessary var containerChanged = !ReferenceEquals(decodedContainingType, containingType); var typeArgsChanged = typeArgs != decodedArgs; if (typeArgsChanged || containerChanged) { var newTypeArgs = type.HasTypeArgumentsCustomModifiers ? decodedArgs.ZipAsArray(type.TypeArgumentsCustomModifiers, (t, m) => new TypeWithModifiers(t, m)) : decodedArgs.SelectAsArray(TypeMap.TypeSymbolAsTypeWithModifiers); if (containerChanged) { decodedType = decodedType.OriginalDefinition.AsMember(decodedContainingType); // If the type is nested, e.g. Outer<T>.Inner<V>, then Inner is definitely // not a tuple, since we know all tuple-compatible types (System.ValueTuple) // are not nested types. Thus, it is safe to return without checking if // Inner is a tuple. return decodedType.ConstructIfGeneric(newTypeArgs); } decodedType = type.ConstructedFrom.Construct(newTypeArgs, unbound: false); } // Now decode into a tuple, if it is one int tupleCardinality; if (decodedType.IsTupleCompatible(out tupleCardinality)) { var elementNames = EatElementNamesIfAvailable(tupleCardinality); Debug.Assert(elementNames.IsDefault || elementNames.Length == tupleCardinality); decodedType = elementNames.IsDefault ? TupleTypeSymbol.Create(decodedType) : TupleTypeSymbol.Create(decodedType, elementNames); } return decodedType; }
protected override BoundStatement GenerateStateMachineCreation(LocalSymbol stateMachineVariable, NamedTypeSymbol frameType) { // return local; return(F.Block(F.Return(F.Local(stateMachineVariable)))); }
public TypeExtraInfo GetTypeExtraInfo(NamedTypeSymbol sym) { TypeExtraInfo tei; if (!TypeExtraInfo.TryGetValue(sym, out tei)) return null; return tei; }
private void GenerateIAsyncEnumeratorImplementation_MoveNextAsync() { // Produce: // if (state == StateMachineStates.FinishedStateMachine) // { // return default; // } // _valueOrEndPromise.Reset(); // var inst = this; // _builder.Start(ref inst); // var version = _valueOrEndPromise.Version; // if (_valueOrEndPromise.GetStatus(version) == ValueTaskSourceStatus.Succeeded) // { // return new ValueTask<bool>(_valueOrEndPromise.GetResult(version)); // } // return new ValueTask<bool>(this, version); NamedTypeSymbol IAsyncEnumeratorOfElementType = F.WellKnownType(WellKnownType.System_Collections_Generic_IAsyncEnumerator_T) .Construct(_currentField.Type); MethodSymbol IAsyncEnumerableOfElementType_MoveNextAsync = F.WellKnownMethod(WellKnownMember.System_Collections_Generic_IAsyncEnumerator_T__MoveNextAsync) .AsMember(IAsyncEnumeratorOfElementType); var promiseType = (NamedTypeSymbol)_promiseOfValueOrEndField.Type; MethodSymbol promise_GetStatus = F.WellKnownMethod(WellKnownMember.System_Threading_Tasks_Sources_ManualResetValueTaskSourceCore_T__GetStatus) .AsMember(promiseType); MethodSymbol promise_GetResult = F.WellKnownMethod(WellKnownMember.System_Threading_Tasks_Sources_ManualResetValueTaskSourceCore_T__GetResult) .AsMember(promiseType); var moveNextAsyncReturnType = (NamedTypeSymbol)IAsyncEnumerableOfElementType_MoveNextAsync.ReturnType; MethodSymbol valueTaskT_ctorValue = F.WellKnownMethod(WellKnownMember.System_Threading_Tasks_ValueTask_T__ctorValue) .AsMember(moveNextAsyncReturnType); MethodSymbol valueTaskT_ctor = F.WellKnownMethod(WellKnownMember.System_Threading_Tasks_ValueTask_T__ctorSourceAndToken) .AsMember(moveNextAsyncReturnType); // The implementation doesn't depend on the method body of the iterator method. OpenMethodImplementation(IAsyncEnumerableOfElementType_MoveNextAsync, hasMethodBodyDependency: false); GetPartsForStartingMachine(out BoundExpressionStatement callReset, out LocalSymbol instSymbol, out BoundStatement instAssignment, out BoundExpressionStatement startCall, out MethodSymbol promise_get_Version); BoundStatement ifFinished = F.If( // if (state == StateMachineStates.FinishedStateMachine) F.IntEqual(F.InstanceField(stateField), F.Literal(StateMachineStates.FinishedStateMachine)), // return default; thenClause: F.Return(F.Default(moveNextAsyncReturnType))); // var version = _valueOrEndPromise.Version; var versionSymbol = F.SynthesizedLocal(F.SpecialType(SpecialType.System_Int16)); var versionLocal = F.Local(versionSymbol); var versionInit = F.Assignment(versionLocal, F.Call(F.Field(F.This(), _promiseOfValueOrEndField), promise_get_Version)); var ifPromiseReady = F.If( // if (_valueOrEndPromise.GetStatus(version) == ValueTaskSourceStatus.Succeeded) F.IntEqual( F.Call(F.Field(F.This(), _promiseOfValueOrEndField), promise_GetStatus, versionLocal), F.Literal(1)), // return new ValueTask<bool>(_valueOrEndPromise.GetResult(version)); thenClause: F.Return(F.New(valueTaskT_ctorValue, F.Call(F.Field(F.This(), _promiseOfValueOrEndField), promise_GetResult, versionLocal)))); // return new ValueTask<bool>(this, version); // Note: we fall back to this slower method of returning when the promise doesn't yet have a value. // This method of returning relies on two interface calls (`IValueTaskSource<bool>.GetStatus(version)` and `IValueTaskSource<bool>.GetResult(version)`). var returnStatement = F.Return(F.New(valueTaskT_ctor, F.This(), versionLocal)); F.CloseMethod(F.Block( ImmutableArray.Create(instSymbol, versionSymbol), ifFinished, callReset, // _promiseOfValueOrEnd.Reset(); instAssignment, // var inst = this; startCall, // _builder.Start(ref inst); versionInit, ifPromiseReady, returnStatement)); }
internal SynthesizedStruct(NamedTypeSymbol containingType, string name) : base(containingType, name) { }
private BoundExpression BindAnonymousObjectCreation(AnonymousObjectCreationExpressionSyntax node, DiagnosticBag diagnostics) { // prepare var initializers = node.Initializers; int fieldCount = initializers.Count; bool hasError = false; // bind field initializers BoundExpression[] boundExpressions = new BoundExpression[fieldCount]; AnonymousTypeField[] fields = new AnonymousTypeField[fieldCount]; CSharpSyntaxNode[] fieldSyntaxNodes = new CSharpSyntaxNode[fieldCount]; // WARNING: Note that SemanticModel.GetDeclaredSymbol for field initializer node relies on // the fact that the order of properties in anonymous type template corresponds // 1-to-1 to the appropriate filed initializer syntax nodes; This means such // correspondence must be preserved all the time including erroneous scenarios // set of names already used var uniqueFieldNames = PooledHashSet <string> .GetInstance(); for (int i = 0; i < fieldCount; i++) { AnonymousObjectMemberDeclaratorSyntax fieldInitializer = initializers[i]; NameEqualsSyntax?nameEquals = fieldInitializer.NameEquals; ExpressionSyntax expression = fieldInitializer.Expression; SyntaxToken nameToken = default(SyntaxToken); if (nameEquals != null) { nameToken = nameEquals.Name.Identifier; } else { if (!IsAnonymousTypeMemberExpression(expression)) { hasError = true; diagnostics.Add(ErrorCode.ERR_InvalidAnonymousTypeMemberDeclarator, expression.GetLocation()); } nameToken = expression.ExtractAnonymousTypeMemberName(); } hasError |= expression.HasErrors; boundExpressions[i] = BindRValueWithoutTargetType(expression, diagnostics); // check the name to be unique string?fieldName = null; if (nameToken.Kind() == SyntaxKind.IdentifierToken) { fieldName = nameToken.ValueText; if (!uniqueFieldNames.Add(fieldName !)) { // name duplication Error(diagnostics, ErrorCode.ERR_AnonymousTypeDuplicatePropertyName, fieldInitializer); hasError = true; fieldName = null; } } else { // there is something wrong with field's name hasError = true; } // calculate the expression's type and report errors if needed TypeSymbol fieldType = GetAnonymousTypeFieldType(boundExpressions[i], fieldInitializer, diagnostics, ref hasError); // build anonymous type field descriptor fieldSyntaxNodes[i] = (nameToken.Kind() == SyntaxKind.IdentifierToken) ? (CSharpSyntaxNode)nameToken.Parent ! : fieldInitializer; fields[i] = new AnonymousTypeField( fieldName == null ? "$" + i.ToString() : fieldName, fieldSyntaxNodes[i].Location, TypeWithAnnotations.Create(fieldType)); // NOTE: ERR_InvalidAnonymousTypeMemberDeclarator (CS0746) would be generated by parser if needed } uniqueFieldNames.Free(); // Create anonymous type AnonymousTypeManager manager = this.Compilation.AnonymousTypeManager; AnonymousTypeDescriptor descriptor = new AnonymousTypeDescriptor(fields.AsImmutableOrNull(), node.NewKeyword.GetLocation()); NamedTypeSymbol anonymousType = manager.ConstructAnonymousTypeSymbol(descriptor); // declarators - bound nodes created for providing semantic info // on anonymous type fields having explicitly specified name ArrayBuilder <BoundAnonymousPropertyDeclaration> declarators = ArrayBuilder <BoundAnonymousPropertyDeclaration> .GetInstance(); for (int i = 0; i < fieldCount; i++) { NameEqualsSyntax?explicitName = initializers[i].NameEquals; if (explicitName != null) { AnonymousTypeField field = fields[i]; if (field.Name != null) { // get property symbol and create a bound property declaration node foreach (var symbol in anonymousType.GetMembers(field.Name)) { if (symbol.Kind == SymbolKind.Property) { declarators.Add(new BoundAnonymousPropertyDeclaration(fieldSyntaxNodes[i], (PropertySymbol)symbol, field.Type)); break; } } } } } // check if anonymous object creation is allowed in this context if (!this.IsAnonymousTypesAllowed()) { Error(diagnostics, ErrorCode.ERR_AnonymousTypeNotAvailable, node.NewKeyword); hasError = true; } // Finally create a bound node return(new BoundAnonymousObjectCreationExpression( node, anonymousType.InstanceConstructors[0], boundExpressions.AsImmutableOrNull(), declarators.ToImmutableAndFree(), anonymousType, hasError)); }
internal ConstructedAnonymousTypeSymbol(NamedTypeSymbol constructedFrom, ReadOnlyArray<TypeSymbol> typeArguments, AnonymousTypeDescriptor typeDescr) : base(constructedFrom, typeArguments) { this.TypeDescr = typeDescr; }
internal LoweredDynamicOperation MakeDynamicOperation( BoundExpression binderConstruction, BoundExpression loweredReceiver, RefKind receiverRefKind, ImmutableArray <BoundExpression> loweredArguments, ImmutableArray <RefKind> refKinds, BoundExpression loweredRight, TypeSymbol resultType) { Debug.Assert(!loweredArguments.IsDefault); // get well-known types and members we need: NamedTypeSymbol delegateTypeOverMethodTypeParameters = GetDelegateType(loweredReceiver, receiverRefKind, loweredArguments, refKinds, loweredRight, resultType); NamedTypeSymbol callSiteTypeGeneric = _factory.WellKnownType(WellKnownType.System_Runtime_CompilerServices_CallSite_T); MethodSymbol callSiteFactoryGeneric = _factory.WellKnownMethod(WellKnownMember.System_Runtime_CompilerServices_CallSite_T__Create); FieldSymbol callSiteTargetFieldGeneric = (FieldSymbol)_factory.WellKnownMember(WellKnownMember.System_Runtime_CompilerServices_CallSite_T__Target); MethodSymbol delegateInvoke; if (binderConstruction == null || (object)delegateTypeOverMethodTypeParameters == null || delegateTypeOverMethodTypeParameters.IsErrorType() || (object)(delegateInvoke = delegateTypeOverMethodTypeParameters.DelegateInvokeMethod) == null || callSiteTypeGeneric.IsErrorType() || (object)callSiteFactoryGeneric == null || (object)callSiteTargetFieldGeneric == null) { // CS1969: One or more types required to compile a dynamic expression cannot be found. // Dev11 reports it with source location for each dynamic operation, which results in many error messages. // The diagnostic that names the specific missing type or member has already been reported. _factory.Diagnostics.Add(ErrorCode.ERR_DynamicRequiredTypesMissing, NoLocation.Singleton); return(LoweredDynamicOperation.Bad(loweredReceiver, loweredArguments, loweredRight, resultType)); } if ((object)_currentDynamicCallSiteContainer == null) { _currentDynamicCallSiteContainer = CreateCallSiteContainer(_factory, _methodOrdinal); } var containerDef = (SynthesizedContainer)_currentDynamicCallSiteContainer.OriginalDefinition; var methodToContainerTypeParametersMap = containerDef.TypeMap; var callSiteType = callSiteTypeGeneric.Construct(new[] { delegateTypeOverMethodTypeParameters }); var callSiteFactoryMethod = callSiteFactoryGeneric.AsMember(callSiteType); var callSiteTargetField = callSiteTargetFieldGeneric.AsMember(callSiteType); var callSiteField = DefineCallSiteStorageSymbol(containerDef, delegateTypeOverMethodTypeParameters, methodToContainerTypeParametersMap); var callSiteFieldAccess = _factory.Field(null, callSiteField); var callSiteArguments = GetCallSiteArguments(callSiteFieldAccess, loweredReceiver, loweredArguments, loweredRight); var nullCallSite = _factory.Null(callSiteField.Type); var siteInitialization = _factory.Conditional( _factory.ObjectEqual(callSiteFieldAccess, nullCallSite), _factory.AssignmentExpression(callSiteFieldAccess, _factory.Call(null, callSiteFactoryMethod, binderConstruction)), nullCallSite, callSiteField.Type); var siteInvocation = _factory.Call( _factory.Field(callSiteFieldAccess, callSiteTargetField), delegateInvoke, callSiteArguments); return(new LoweredDynamicOperation(_factory, siteInitialization, siteInvocation, resultType)); }
public NamespaceTypeDefinition(Module moduleBeingBuilt, NamedTypeSymbol underlyingNamedType) : base(moduleBeingBuilt, underlyingNamedType) { }
internal FieldSymbol DefineCallSiteStorageSymbol(NamedTypeSymbol containerDefinition, NamedTypeSymbol delegateTypeOverMethodTypeParameters, TypeMap methodToContainerTypeParametersMap) { var fieldName = GeneratedNames.MakeDynamicCallSiteFieldName(_callSiteIdDispenser++); var delegateTypeOverContainerTypeParameters = methodToContainerTypeParametersMap.SubstituteNamedType(delegateTypeOverMethodTypeParameters); var callSiteType = _factory.Compilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_CallSite_T).Construct(new[] { delegateTypeOverContainerTypeParameters }); var field = new SynthesizedFieldSymbol(containerDefinition, callSiteType, fieldName, isPublic: true, isStatic: true); _factory.AddField(containerDefinition, field); return(_currentDynamicCallSiteContainer.IsGenericType ? field.AsMember(_currentDynamicCallSiteContainer) : field); }