Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
            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);
                }
            }
Ejemplo n.º 3
0
            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);
                }
            }