/// <summary> /// Given anonymous type provided constructs an implementation type symbol to be used in emit phase; /// if the anonymous type has at least one field the implementation type symbol will be created based on /// a generic type template generated for each 'unique' anonymous type structure, otherwise the template /// type will be non-generic. /// </summary> 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); }
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); } }
internal AnonymousTypeOrDelegatePublicSymbol(AnonymousTypeManager manager, AnonymousTypeDescriptor typeDescr) { typeDescr.AssertIsGood(); this.Manager = manager; this.TypeDescriptor = typeDescr; }
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); } }