internal AnonymousTypePropertySymbol(AnonymousTypeTemplateSymbol container, AnonymousTypeField field, TypeSymbol fieldTypeSymbol)
 {
     this.containingType = container;
     this.type = fieldTypeSymbol;
     this.name = field.Name;
     this.locations = ImmutableArray<Location>.Empty;
     this.getMethod = new AnonymousTypePropertyGetAccessorSymbol(this);
     this.backingField = new AnonymousTypeFieldSymbol(this);
 }
 internal AnonymousTypePropertySymbol(AnonymousTypePublicSymbol container, AnonymousTypeField field)
 {
     this.containingType = container;
     this.type = field.Type;
     this.name = field.Name;
     this.locations = ImmutableArray.Create<Location>(field.Location);
     this.getMethod = new AnonymousTypePropertyGetAccessorSymbol(this);
     this.backingField = null;
 }
            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));
            }
示例#4
0
        /// <summary>
        /// Creates a new anonymous type descriptor based on 'this' one,
        /// but having field types passed as an argument.
        /// </summary>
        internal AnonymousTypeDescriptor WithNewFieldsTypes(ImmutableArray <TypeSymbol> newFieldTypes)
        {
            Debug.Assert(!newFieldTypes.IsDefault);
            Debug.Assert(newFieldTypes.Length == this.Fields.Length);

            AnonymousTypeField[] newFields = new AnonymousTypeField[this.Fields.Length];
            for (int i = 0; i < newFields.Length; i++)
            {
                var field = this.Fields[i];
                newFields[i] = new AnonymousTypeField(field.Name, field.Location, newFieldTypes[i]);
            }

            return(new AnonymousTypeDescriptor(newFields.AsImmutable(), this.Location));
        }
示例#5
0
 internal AnonymousTypePropertySymbol(
     AnonymousTypePublicSymbol container,
     AnonymousTypeField field,
     int index
     )
     : this(
         container,
         field,
         field.TypeWithAnnotations,
         index,
         ImmutableArray.Create <Location>(field.Location),
         includeBackingField : false
         )
 {
 }
示例#6
0
 internal AnonymousTypePropertySymbol(
     AnonymousTypeTemplateSymbol container,
     AnonymousTypeField field,
     TypeWithAnnotations fieldTypeWithAnnotations,
     int index
     )
     : this(
         container,
         field,
         fieldTypeWithAnnotations,
         index,
         ImmutableArray <Location> .Empty,
         includeBackingField : true
         )
 {
 }
            private AnonymousTypePropertySymbol(
                NamedTypeSymbol container,
                AnonymousTypeField field,
                TypeWithAnnotations fieldTypeWithAnnotations,
                int index,
                ImmutableArray <Location> locations,
                bool includeBackingField)
            {
                Debug.Assert((object)container != null);
                Debug.Assert((object)field != null);
                Debug.Assert(fieldTypeWithAnnotations.HasType);
                Debug.Assert(index >= 0);
                Debug.Assert(!locations.IsDefault);

                _containingType      = container;
                _typeWithAnnotations = fieldTypeWithAnnotations;
                _name         = field.Name;
                _index        = index;
                _locations    = locations;
                _getMethod    = new AnonymousTypePropertyGetAccessorSymbol(this);
                _backingField = includeBackingField ? new AnonymousTypeFieldSymbol(this) : null;
            }
示例#8
0
 internal AnonymousTypePropertySymbol(AnonymousTypePublicSymbol container, AnonymousTypeField field)
 {
     _containingType = container;
     _type           = field.Type;
     _name           = field.Name;
     _locations      = ImmutableArray.Create <Location>(field.Location);
     _getMethod      = new AnonymousTypePropertyGetAccessorSymbol(this);
     _backingField   = null;
 }
示例#9
0
 internal AnonymousTypePropertySymbol(AnonymousTypeTemplateSymbol container, AnonymousTypeField field, TypeSymbol fieldTypeSymbol)
 {
     _containingType = container;
     _type           = fieldTypeSymbol;
     _name           = field.Name;
     _locations      = ImmutableArray <Location> .Empty;
     _getMethod      = new AnonymousTypePropertyGetAccessorSymbol(this);
     _backingField   = new AnonymousTypeFieldSymbol(this);
 }
示例#10
0
        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 erroneos scenarios

            // set of names already used
            HashSet<string> uniqueFieldNames = new HashSet<string>();

            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
                {
                    nameToken = expression.ExtractAnonymousTypeMemberName();
                }

                hasError = hasError || expression.HasErrors;
                boundExpressions[i] = this.BindValue(expression, diagnostics, BindValueKind.RValue);

                //  check the name to be unique
                string fieldName = null;
                if (nameToken.Kind() == SyntaxKind.IdentifierToken)
                {
                    fieldName = nameToken.ValueText;
                    if (uniqueFieldNames.Contains(fieldName))
                    {
                        //  name duplication
                        Error(diagnostics, ErrorCode.ERR_AnonymousTypeDuplicatePropertyName, fieldInitializer);
                        hasError = true;
                        fieldName = null;
                    }
                    else
                    {
                        uniqueFieldNames.Add(fieldName);
                    }
                }
                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, fieldType);

                //  NOTE: ERR_InvalidAnonymousTypeMemberDeclarator (CS0746) would be generated by parser if needed
            }

            //  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);
        }
示例#11
0
            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();
            }
示例#12
0
            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();
            }