internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics)
            {
                AnonymousTypeManager      manager = ((AnonymousTypeTemplateSymbol)this.ContainingType).Manager;
                SyntheticBoundNodeFactory F       = this.CreateBoundNodeFactory(compilationState, diagnostics);

                //  Method body:
                //
                //  {
                //      return String.Format(
                //          "{ <name1> = {0}", <name2> = {1}", ... <nameN> = {N-1}",
                //          this.backingFld_1,
                //          this.backingFld_2,
                //          ...
                //          this.backingFld_N
                //  }

                // Type expression
                AnonymousTypeTemplateSymbol anonymousType = (AnonymousTypeTemplateSymbol)this.ContainingType;

                //  build arguments
                int             fieldCount    = anonymousType.Properties.Length;
                BoundExpression retExpression = null;

                if (fieldCount > 0)
                {
                    //  we do have fields, so have to use String.Format(...)
                    BoundExpression[] arguments = new BoundExpression[fieldCount];

                    //  process properties
                    PooledStringBuilder formatString = PooledStringBuilder.GetInstance();
                    for (int i = 0; i < fieldCount; i++)
                    {
                        AnonymousTypePropertySymbol property = anonymousType.Properties[i];

                        // build format string
                        formatString.Builder.AppendFormat(i == 0 ? "{{{{ {0} = {{{1}}}" : ", {0} = {{{1}}}", property.Name, i);

                        // build argument
                        arguments[i] = F.Convert(manager.System_Object, F.Field(F.This(), property.BackingField), ConversionKind.Boxing);
                    }
                    formatString.Builder.Append(" }}");

                    //  add format string argument
                    BoundExpression format = F.Literal(formatString.ToStringAndFree());

                    //  Generate expression for return statement
                    //      retExpression <= System.String.Format(args)
                    retExpression = F.StaticCall(manager.System_String, manager.System_String__Format, format, F.Array(manager.System_Object, arguments));
                }
                else
                {
                    //  this is an empty anonymous type, just return "{ }"
                    retExpression = F.Literal("{ }");
                }

                F.CloseMethod(F.Block(F.Return(retExpression)));
            }
            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));
            }
Пример #3
0
 internal AnonymousTypePropertyGetAccessorSymbol(AnonymousTypePropertySymbol property)
 // winmdobj output only effects setters, so we can always set this to false
     : base(
         property.ContainingType,
         SourcePropertyAccessorSymbol.GetAccessorName(
             property.Name,
             getNotSet: true,
             isWinMdOutput: false
             )
         )
 {
     _property = property;
 }
            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);
                }
            }
            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);
                }
            }
Пример #6
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();
            }
Пример #7
0
            internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics)
            {
                AnonymousTypeManager      manager = ((AnonymousTypeTemplateSymbol)this.ContainingType).Manager;
                SyntheticBoundNodeFactory F       = this.CreateBoundNodeFactory(compilationState, diagnostics);

                //  Method body:
                //
                //  {
                //      return String.Format(
                //          "{ <name1> = {0}", <name2> = {1}", ... <nameN> = {N-1}",
                //          this.backingFld_1,
                //          this.backingFld_2,
                //          ...
                //          this.backingFld_N
                //  }

                // Type expression
                AnonymousTypeTemplateSymbol anonymousType = (AnonymousTypeTemplateSymbol)this.ContainingType;

                //  build arguments
                int             fieldCount    = anonymousType.Properties.Length;
                BoundExpression retExpression = null;

#if XSHARP
                if ((ContainingType as AnonymousTypeTemplateSymbol)?.IsCodeblock == true)
                {
                    AnonymousTypePropertySymbol property = anonymousType.Properties[0];
                    retExpression = F.Field(F.This(), property.BackingField);
                }
                else
#endif
                if (fieldCount > 0)
                {
                    //  we do have fields, so have to use String.Format(...)
                    BoundExpression[] arguments = new BoundExpression[fieldCount];

                    //  process properties
                    PooledStringBuilder formatString = PooledStringBuilder.GetInstance();
                    for (int i = 0; i < fieldCount; i++)
                    {
                        AnonymousTypePropertySymbol property = anonymousType.Properties[i];

                        // build format string
                        formatString.Builder.AppendFormat(i == 0 ? "{{{{ {0} = {{{1}}}" : ", {0} = {{{1}}}", property.Name, i);

                        // build argument
                        arguments[i] = F.Convert(manager.System_Object,
                                                 new BoundLoweredConditionalAccess(F.Syntax,
                                                                                   F.Field(F.This(), property.BackingField),
                                                                                   null,
                                                                                   F.Call(new BoundConditionalReceiver(
                                                                                              F.Syntax,
                                                                                              id: i,
                                                                                              type: property.BackingField.Type), manager.System_Object__ToString),
                                                                                   null,
                                                                                   id: i,
                                                                                   type: manager.System_String),
                                                 Conversion.ImplicitReference);
                    }
                    formatString.Builder.Append(" }}");

                    //  add format string argument
                    BoundExpression format = F.Literal(formatString.ToStringAndFree());

                    //  Generate expression for return statement
                    //      retExpression <= System.String.Format(args)
                    var formatMethod = manager.System_String__Format_IFormatProvider;
                    retExpression = F.StaticCall(manager.System_String, formatMethod, F.Null(formatMethod.Parameters[0].Type), format, F.ArrayOrEmpty(manager.System_Object, arguments));
                }
                else
                {
                    //  this is an empty anonymous type, just return "{ }"
                    retExpression = F.Literal("{ }");
                }

                F.CloseMethod(F.Block(F.Return(retExpression)));
            }
            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, 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();
            }
Пример #9
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();
            }
 internal AnonymousTypePropertyGetAccessorSymbol(AnonymousTypePropertySymbol property)
     // winmdobj output only effects setters, so we can always set this to false
     : base(property.ContainingType, SourcePropertyAccessorSymbol.GetAccessorName(property.Name, getNotSet: true, isWinMdOutput: false))
 {
     _property = property;
 }