internal AnonymousTypePublicSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) { typeDescr.AssertIsGood(); this.Manager = manager; this.TypeDescriptor = typeDescr; var fields = typeDescr.Fields; var properties = fields.SelectAsArray((field, i, type) => new AnonymousTypePropertySymbol(type, field, i), this); // members int membersCount = fields.Length * 2 + 1; var members = ArrayBuilder <Symbol> .GetInstance(membersCount); foreach (var property in properties) { // Property related symbols members.Add(property); members.Add(property.GetMethod); } this.Properties = properties; // Add a constructor members.Add(new AnonymousTypeConstructorSymbol(this, properties)); _members = members.ToImmutableAndFree(); Debug.Assert(membersCount == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } }
private AnonymousTypeTemplateSymbol CreatePlaceholderTemplate(Microsoft.CodeAnalysis.Emit.AnonymousTypeKey key) { var fields = key.Fields.SelectAsArray(f => new AnonymousTypeField(f.Name, Location.None, (TypeSymbol)null)); var typeDescr = new AnonymousTypeDescriptor(fields, Location.None); return(new AnonymousTypeTemplateSymbol(this, typeDescr)); }
internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) : base(manager, typeDescr.Location) { this.TypeDescriptorKey = typeDescr.Key; int fieldsCount = typeDescr.Fields.Length; int membersCount = fieldsCount * 3 + 1; // members var membersBuilder = ArrayBuilder <Symbol> .GetInstance(membersCount); var propertiesBuilder = ArrayBuilder <AnonymousTypePropertySymbol> .GetInstance(fieldsCount); var typeParametersBuilder = ArrayBuilder <TypeParameterSymbol> .GetInstance(fieldsCount); // Process fields for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++) { AnonymousTypeField field = typeDescr.Fields[fieldIndex]; // Add a type parameter AnonymousTypeParameterSymbol typeParameter = new AnonymousTypeParameterSymbol(this, fieldIndex, GeneratedNames.MakeAnonymousTypeParameterName(field.Name)); typeParametersBuilder.Add(typeParameter); // Add a property AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, TypeWithAnnotations.Create(typeParameter), fieldIndex); propertiesBuilder.Add(property); // Property related symbols membersBuilder.Add(property); membersBuilder.Add(property.BackingField); membersBuilder.Add(property.GetMethod); } _typeParameters = typeParametersBuilder.ToImmutableAndFree(); this.Properties = propertiesBuilder.ToImmutableAndFree(); // Add a constructor membersBuilder.Add(new AnonymousTypeConstructorSymbol(this, this.Properties)); _members = membersBuilder.ToImmutableAndFree(); Debug.Assert(membersCount == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } // special members: Equals, GetHashCode, ToString this.SpecialMembers = ImmutableArray.Create <MethodSymbol>( new AnonymousTypeEqualsMethodSymbol(this), new AnonymousTypeGetHashCodeMethodSymbol(this), new AnonymousTypeToStringMethodSymbol(this)); }
internal AnonymousTypePublicSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) { typeDescr.AssertIsGood(); this.Manager = manager; this.TypeDescriptor = typeDescr; int fieldsCount = typeDescr.Fields.Length; // members Symbol[] members = new Symbol[fieldsCount * 2 + 1]; int memberIndex = 0; // The array storing property symbols to be used in // generation of constructor and other methods if (fieldsCount > 0) { AnonymousTypePropertySymbol[] propertiesArray = new AnonymousTypePropertySymbol[fieldsCount]; // Process fields for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++) { // Add a property AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, typeDescr.Fields[fieldIndex]); propertiesArray[fieldIndex] = property; // Property related symbols members[memberIndex++] = property; members[memberIndex++] = property.GetMethod; } this.Properties = propertiesArray.AsImmutableOrNull(); } else { this.Properties = ImmutableArray <AnonymousTypePropertySymbol> .Empty; } // Add a constructor members[memberIndex++] = new AnonymousTypeConstructorSymbol(this, this.Properties); _members = members.AsImmutableOrNull(); Debug.Assert(memberIndex == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } }
private NamedTypeSymbol ConstructAnonymousTypeImplementationSymbol( AnonymousTypePublicSymbol anonymous ) { Debug.Assert(ReferenceEquals(this, anonymous.Manager)); CheckSourceLocationSeen(anonymous); AnonymousTypeDescriptor typeDescr = anonymous.TypeDescriptor; typeDescr.AssertIsGood(); // Get anonymous type template AnonymousTypeTemplateSymbol template; if (!this.AnonymousTypeTemplates.TryGetValue(typeDescr.Key, out template)) { // NOTE: the newly created template may be thrown away if another thread wins template = this.AnonymousTypeTemplates.GetOrAdd( typeDescr.Key, new AnonymousTypeTemplateSymbol(this, typeDescr) ); } // Adjust template location if the template is owned by this manager if (ReferenceEquals(template.Manager, this)) { template.AdjustLocation(typeDescr.Location); } // In case template is not generic, just return it if (template.Arity == 0) { return(template); } // otherwise construct type using the field types var typeArguments = typeDescr.Fields.SelectAsArray(f => f.Type); return(template.Construct(typeArguments)); }
public NamedTypeSymbol ConstructAnonymousTypeSymbol(AnonymousTypeDescriptor typeDescr) { return(new AnonymousTypePublicSymbol(this, typeDescr)); }
/// <summary> /// Resets numbering in anonymous type names and compiles the /// anonymous type methods. Also seals the collection of templates. /// </summary> public void AssignTemplatesNamesAndCompile(MethodCompiler compiler, PEModuleBuilder moduleBeingBuilt, DiagnosticBag diagnostics) { // Ensure all previous anonymous type templates are included so the // types are available for subsequent edit and continue generations. foreach (var key in moduleBeingBuilt.GetPreviousAnonymousTypes()) { var templateKey = AnonymousTypeDescriptor.ComputeKey(key.Fields, f => f.Name); this.AnonymousTypeTemplates.GetOrAdd(templateKey, k => this.CreatePlaceholderTemplate(key)); } // Get all anonymous types owned by this manager var builder = ArrayBuilder <AnonymousTypeTemplateSymbol> .GetInstance(); GetCreatedAnonymousTypeTemplates(builder); // If the collection is not sealed yet we should assign // new indexes to the created anonymous type templates if (!this.AreTemplatesSealed) { // If we are emitting .NET module, include module's name into type's name to ensure // uniqueness across added modules. string moduleId; if (moduleBeingBuilt.OutputKind == OutputKind.NetModule) { moduleId = moduleBeingBuilt.Name; string extension = OutputKind.NetModule.GetDefaultExtension(); if (moduleId.EndsWith(extension, StringComparison.OrdinalIgnoreCase)) { moduleId = moduleId.Substring(0, moduleId.Length - extension.Length); } moduleId = MetadataHelpers.MangleForTypeNameIfNeeded(moduleId); } else { moduleId = string.Empty; } int nextIndex = moduleBeingBuilt.GetNextAnonymousTypeIndex(); foreach (var template in builder) { string name; int index; if (!moduleBeingBuilt.TryGetAnonymousTypeName(template, out name, out index)) { index = nextIndex++; name = GeneratedNames.MakeAnonymousTypeTemplateName(index, this.Compilation.GetSubmissionSlotIndex(), moduleId); } // normally it should only happen once, but in case there is a race // NameAndIndex.set has an assert which guarantees that the // template name provided is the same as the one already assigned template.NameAndIndex = new NameAndIndex(name, index); } this.SealTemplates(); } if (builder.Count > 0 && !ReportMissingOrErroneousSymbols(diagnostics)) { // Process all the templates foreach (var template in builder) { foreach (var method in template.SpecialMembers) { moduleBeingBuilt.AddSynthesizedDefinition(template, method); } compiler.Visit(template, null); } } builder.Free(); var synthesizedDelegates = ArrayBuilder <SynthesizedDelegateSymbol> .GetInstance(); GetCreatedSynthesizedDelegates(synthesizedDelegates); foreach (var synthesizedDelegate in synthesizedDelegates) { compiler.Visit(synthesizedDelegate, null); } synthesizedDelegates.Free(); }
internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) { this.Manager = manager; this.TypeDescriptorKey = typeDescr.Key; _smallestLocation = typeDescr.Location; // Will be set when the type's metadata is ready to be emitted, // <anonymous-type>.Name will throw exception if requested // before that moment. _nameAndIndex = null; int fieldsCount = typeDescr.Fields.Length; // members Symbol[] members = new Symbol[fieldsCount * 3 + 1]; int memberIndex = 0; // The array storing property symbols to be used in // generation of constructor and other methods if (fieldsCount > 0) { AnonymousTypePropertySymbol[] propertiesArray = new AnonymousTypePropertySymbol[fieldsCount]; TypeParameterSymbol[] typeParametersArray = new TypeParameterSymbol[fieldsCount]; // Process fields for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++) { AnonymousTypeField field = typeDescr.Fields[fieldIndex]; // Add a type parameter AnonymousTypeParameterSymbol typeParameter = new AnonymousTypeParameterSymbol(this, fieldIndex, GeneratedNames.MakeAnonymousTypeParameterName(field.Name)); typeParametersArray[fieldIndex] = typeParameter; // Add a property AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, TypeSymbolWithAnnotations.Create(typeParameter)); propertiesArray[fieldIndex] = property; // Property related symbols members[memberIndex++] = property; members[memberIndex++] = property.BackingField; members[memberIndex++] = property.GetMethod; } _typeParameters = typeParametersArray.AsImmutable(); this.Properties = propertiesArray.AsImmutable(); } else { _typeParameters = ImmutableArray <TypeParameterSymbol> .Empty; this.Properties = ImmutableArray <AnonymousTypePropertySymbol> .Empty; } // Add a constructor members[memberIndex++] = new AnonymousTypeConstructorSymbol(this, this.Properties); _members = members.AsImmutable(); Debug.Assert(memberIndex == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } // special members: Equals, GetHashCode, ToString MethodSymbol[] specialMembers = new MethodSymbol[3]; specialMembers[0] = new AnonymousTypeEqualsMethodSymbol(this); specialMembers[1] = new AnonymousTypeGetHashCodeMethodSymbol(this); specialMembers[2] = new AnonymousTypeToStringMethodSymbol(this); this.SpecialMembers = specialMembers.AsImmutable(); }
public SynthesizedDelegateKey(AnonymousTypeDescriptor typeDescr) { Name = null; ParameterCount = -1; TypeDescriptor = typeDescr; }
public SynthesizedDelegateKey(int parameterCount, RefKindVector byRefs, bool returnsVoid, int generation) { Name = GeneratedNames.MakeSynthesizedDelegateName(byRefs, returnsVoid, generation); ParameterCount = parameterCount; TypeDescriptor = default; }
internal AnonymousTypeTemplateSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) { this.Manager = manager; this.TypeDescriptorKey = typeDescr.Key; _smallestLocation = typeDescr.Location; // Will be set when the type's metadata is ready to be emitted, // <anonymous-type>.Name will throw exception if requested // before that moment. _nameAndIndex = null; #if XSHARP IsCodeblock = typeDescr.Fields.Length > 0 && typeDescr.Fields[0].Name.StartsWith("Cb$Param$"); _baseType = IsCodeblock ? manager.CodeblockType : manager.System_Object; if (IsCodeblock) { _baseType = manager.CodeblockType; int cbParamCount = typeDescr.Fields.Length; NamedTypeSymbol[] cbParameters = new NamedTypeSymbol[cbParamCount]; for (int i = 0; i < cbParamCount; i++) { cbParameters[i] = manager.UsualType; } var cbDelegate = manager.SynthesizeDelegate(typeDescr.Fields.Length - 1, default(BitVector), false, 0).Construct(cbParameters); Symbol[] cbMembers = new Symbol[7]; int cbMemberIndex = 0; var eval = new AnonymousTypePropertySymbol(this, new AnonymousTypeField("Cb$Eval$", typeDescr.Location, cbDelegate), cbDelegate); var source = new AnonymousTypePropertySymbol(this, new AnonymousTypeField("Cb$Src$", typeDescr.Location, manager.System_String), manager.System_String); this.Properties = new[] { source }.ToImmutableArray(); // Property related symbols cbMembers[cbMemberIndex++] = eval; cbMembers[cbMemberIndex++] = eval.BackingField; cbMembers[cbMemberIndex++] = eval.GetMethod; cbMembers[cbMemberIndex++] = source; cbMembers[cbMemberIndex++] = source.BackingField; cbMembers[cbMemberIndex++] = source.GetMethod; cbMembers[cbMemberIndex++] = new AnonymousTypeConstructorSymbol(this, new[] { eval, source }.ToImmutableArray()); _typeParameters = ImmutableArray <TypeParameterSymbol> .Empty; _members = cbMembers.AsImmutable(); Debug.Assert(cbMemberIndex == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } MethodSymbol[] cbSpecialMembers = new MethodSymbol[2]; cbSpecialMembers[0] = new CodeblockEvalMethod(this); cbSpecialMembers[1] = new AnonymousTypeToStringMethodSymbol(this); this.SpecialMembers = cbSpecialMembers.AsImmutable(); return; } _baseType = manager.System_Object; #endif int fieldsCount = typeDescr.Fields.Length; // members Symbol[] members = new Symbol[fieldsCount * 3 + 1]; int memberIndex = 0; // The array storing property symbols to be used in // generation of constructor and other methods if (fieldsCount > 0) { AnonymousTypePropertySymbol[] propertiesArray = new AnonymousTypePropertySymbol[fieldsCount]; TypeParameterSymbol[] typeParametersArray = new TypeParameterSymbol[fieldsCount]; // Process fields for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++) { AnonymousTypeField field = typeDescr.Fields[fieldIndex]; // Add a type parameter AnonymousTypeParameterSymbol typeParameter = new AnonymousTypeParameterSymbol(this, fieldIndex, GeneratedNames.MakeAnonymousTypeParameterName(field.Name)); typeParametersArray[fieldIndex] = typeParameter; // Add a property AnonymousTypePropertySymbol property = new AnonymousTypePropertySymbol(this, field, typeParameter); propertiesArray[fieldIndex] = property; // Property related symbols members[memberIndex++] = property; members[memberIndex++] = property.BackingField; members[memberIndex++] = property.GetMethod; } _typeParameters = typeParametersArray.AsImmutable(); this.Properties = propertiesArray.AsImmutable(); } else { _typeParameters = ImmutableArray <TypeParameterSymbol> .Empty; this.Properties = ImmutableArray <AnonymousTypePropertySymbol> .Empty; } // Add a constructor members[memberIndex++] = new AnonymousTypeConstructorSymbol(this, this.Properties); _members = members.AsImmutable(); Debug.Assert(memberIndex == _members.Length); // fill nameToSymbols map foreach (var symbol in _members) { _nameToSymbols.Add(symbol.Name, symbol); } // special members: Equals, GetHashCode, ToString MethodSymbol[] specialMembers = new MethodSymbol[3]; specialMembers[0] = new AnonymousTypeEqualsMethodSymbol(this); specialMembers[1] = new AnonymousTypeGetHashCodeMethodSymbol(this); specialMembers[2] = new AnonymousTypeToStringMethodSymbol(this); this.SpecialMembers = specialMembers.AsImmutable(); }
internal AnonymousDelegatePublicSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) : base(manager, typeDescr) { }
internal AnonymousTypeOrDelegatePublicSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) { typeDescr.AssertIsGood(); this.Manager = manager; this.TypeDescriptor = typeDescr; }
/// <summary> /// Resets numbering in anonymous type names and compiles the /// anonymous type methods. Also seals the collection of templates. /// </summary> public void AssignTemplatesNamesAndCompile(MethodCompiler compiler, PEModuleBuilder moduleBeingBuilt, DiagnosticBag diagnostics) { // Ensure all previous anonymous type templates are included so the // types are available for subsequent edit and continue generations. foreach (var key in moduleBeingBuilt.GetPreviousAnonymousTypes()) { var templateKey = AnonymousTypeDescriptor.ComputeKey(key.Names, f => f); this.AnonymousTypeTemplates.GetOrAdd(templateKey, k => this.CreatePlaceholderTemplate(key)); } // Get all anonymous types owned by this manager var builder = ArrayBuilder <AnonymousTypeTemplateSymbol> .GetInstance(); var anonymousTypes = lazyAnonymousTypeTemplates; if (anonymousTypes != null) { foreach (var template in anonymousTypes.Values) { // NOTE: in interactive scenarios the cache may contain templates // from other compilation, those should be discarded here if (ReferenceEquals(template.Manager, this)) { builder.Add(template); } } } // If the collection is not sealed yet we should assign // new indexes to the created anonymous type templates if (this.anonymousTypeTemplatesIsSealed != ThreeState.True) { // Sort type templates using smallest location builder.Sort(new AnonymousTypeComparer(this.Compilation)); // If we are emitting .NET module, include module's name into type's name to ensure // uniqueness across added modules. string moduleId; if (moduleBeingBuilt.OutputKind == OutputKind.NetModule) { moduleId = moduleBeingBuilt.Name; string extension = OutputKind.NetModule.GetDefaultExtension(); if (moduleId.EndsWith(extension, StringComparison.OrdinalIgnoreCase)) { moduleId = moduleId.Substring(0, moduleId.Length - extension.Length); } moduleId = moduleId.Replace('.', '_'); } else { moduleId = string.Empty; } int nextIndex = moduleBeingBuilt.GetNextAnonymousTypeIndex(); foreach (var template in builder) { string name; int index; if (!moduleBeingBuilt.TryGetAnonymousTypeName(template, out name, out index)) { index = nextIndex++; name = GeneratedNames.MakeAnonymousTypeTemplateName(index, this.Compilation.GetSubmissionSlotIndex(), moduleId); } // normally it should only happen once, but in case there is a race // NameAndIndex.set has an assert which guarantees that the // template name provided is the same as the one already assigned template.NameAndIndex = new NameAndIndex(name, index); } this.anonymousTypeTemplatesIsSealed = ThreeState.True; } if (builder.Count > 0 && !ReportMissingOrErroneousSymbols(diagnostics)) { // Process all the templates foreach (var template in builder) { foreach (var method in template.SpecialMembers) { moduleBeingBuilt.AddSynthesizedDefinition(template, method); } compiler.Visit(template, null); } } builder.Free(); var delegates = lazySynthesizedDelegates; if (delegates != null) { foreach (var template in delegates.Values) { // NOTE: in interactive scenarios the cache may contain templates // from other compilation, those should be discarded here if (ReferenceEquals(template.Manager, this)) { compiler.Visit(template.Delegate, null); } } } }