public MethodToStateMachineRewriter(
            SyntheticBoundNodeFactory F,
            MethodSymbol originalMethod,
            FieldSymbol state,
            IReadOnlySet<Symbol> variablesCaptured,
            IReadOnlyDictionary<Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
            DiagnosticBag diagnostics,
            bool useFinalizerBookkeeping)
            : base(F.CompilationState, diagnostics)
        {
            Debug.Assert(F != null);
            Debug.Assert(originalMethod != null);
            Debug.Assert(state != null);
            Debug.Assert(nonReusableLocalProxies != null);
            Debug.Assert(diagnostics != null);
            Debug.Assert(variablesCaptured != null);

            this.F = F;
            this.stateField = state;
            this.cachedState = F.SynthesizedLocal(F.SpecialType(SpecialType.System_Int32), kind: SynthesizedLocalKind.StateMachineCachedState);
            this.useFinalizerBookkeeping = useFinalizerBookkeeping;
            this.hasFinalizerState = useFinalizerBookkeeping;
            this.originalMethod = originalMethod;
            this.variablesCaptured = variablesCaptured;

            foreach (var proxy in nonReusableLocalProxies)
            {
                this.proxies.Add(proxy.Key, proxy.Value);
            }
        }
 protected override void ReportUnassigned(FieldSymbol fieldSymbol, int unassignedSlot, SyntaxNode node)
 {
     if (node.Parent.Kind() == SyntaxKind.AddressOfExpression)
     {
         _result.Add((PrefixUnaryExpressionSyntax)node.Parent);
     }
 }
예제 #3
0
            internal AsyncMethodToClassRewriter(
                MethodSymbol method,
                AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
                SyntheticBoundNodeFactory F,
                FieldSymbol state,
                FieldSymbol builder,
                HashSet<Symbol> variablesCaptured,
                Dictionary<Symbol, CapturedSymbolReplacement> initialProxies,
                DiagnosticBag diagnostics,
                bool generateDebugInfo)
                : base(F, method, state, variablesCaptured, initialProxies, diagnostics,
                      useFinalizerBookkeeping: false,
                      generateDebugInfo: generateDebugInfo)
            {
                this.method = method;
                this.asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection;
                this.asyncMethodBuilderField = builder;
                this.exprReturnLabel = F.GenerateLabel("exprReturn");
                this.exitLabel = F.GenerateLabel("exitLabel");

                this.exprRetValue = method.IsGenericTaskReturningAsync(F.Compilation)
                    ? F.SynthesizedLocal(asyncMethodBuilderMemberCollection.ResultType, GeneratedNames.AsyncExprRetValueFieldName())
                    : null;

                this.dynamicFactory = new LoweredDynamicOperationFactory(F);
            }
예제 #4
0
        private BoundExpression MakeFieldAccess(
            CSharpSyntaxNode syntax,
            BoundExpression rewrittenReceiver,
            FieldSymbol fieldSymbol,
            ConstantValue constantValueOpt,
            LookupResultKind resultKind,
            TypeSymbol type,
            BoundFieldAccess oldNodeOpt = null)
        {

            if (fieldSymbol.IsTupleField)
            {
                return MakeTupleFieldAccess(syntax, fieldSymbol, rewrittenReceiver, constantValueOpt, resultKind);
            }
            
            BoundExpression result = oldNodeOpt != null ?
                oldNodeOpt.Update(rewrittenReceiver, fieldSymbol, constantValueOpt, resultKind, type) :
                new BoundFieldAccess(syntax, rewrittenReceiver, fieldSymbol, constantValueOpt, resultKind, type);

            if (fieldSymbol.IsFixed)
            {
                // a reference to a fixed buffer is translated into its address
                result = new BoundConversion(syntax,
                    new BoundAddressOfOperator(syntax, result, syntax != null && SyntaxFacts.IsFixedStatementExpression(syntax), type, false),
                    new Conversion(ConversionKind.PointerToPointer), false, false, default(ConstantValue), type, false);
            }

            return result;
        }
        internal AsyncMethodToStateMachineRewriter(
            MethodSymbol method,
            int methodOrdinal,
            AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
            SyntheticBoundNodeFactory F,
            FieldSymbol state,
            FieldSymbol builder,
            IReadOnlySet<Symbol> hoistedVariables,
            IReadOnlyDictionary<Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
            SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals,
            VariableSlotAllocator slotAllocatorOpt,
            int nextFreeHoistedLocalSlot,
            DiagnosticBag diagnostics)
            : base(F, method, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics, useFinalizerBookkeeping: false)
        {
            _method = method;
            _asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection;
            _asyncMethodBuilderField = builder;
            _exprReturnLabel = F.GenerateLabel("exprReturn");
            _exitLabel = F.GenerateLabel("exitLabel");

            _exprRetValue = method.IsGenericTaskReturningAsync(F.Compilation)
                ? F.SynthesizedLocal(asyncMethodBuilderMemberCollection.ResultType, syntax: F.Syntax, kind: SynthesizedLocalKind.AsyncMethodReturnValue)
                : null;

            _dynamicFactory = new LoweredDynamicOperationFactory(F, methodOrdinal);
            _awaiterFields = new Dictionary<TypeSymbol, FieldSymbol>(TypeSymbol.EqualsIgnoringDynamicComparer);
            _nextAwaiterId = slotAllocatorOpt?.PreviousAwaiterSlotCount ?? 0;
        }
예제 #6
0
        protected BoundStatement Rewrite()
        {
            if (this.body.HasErrors)
            {
                return this.body;
            }

            F.OpenNestedType(stateMachineClass);

            // Add a field: int _state
            var intType = F.SpecialType(SpecialType.System_Int32);
            stateField = F.StateMachineField(intType, GeneratedNames.MakeStateMachineStateName(), IsStateFieldPublic);

            GenerateFields();

            // and fields for the initial values of all the parameters of the method
            if (PreserveInitialParameterValues)
            {
                initialParameters = new Dictionary<Symbol, CapturedSymbolReplacement>();
            }

            // add fields for the captured variables of the method
            var captured = IteratorAndAsyncCaptureWalker.Analyze(compilationState.ModuleBuilderOpt.Compilation, method, body);

            this.variablesCaptured = new HashSet<Symbol>(captured.Keys);

            this.variableProxies = new Dictionary<Symbol, CapturedSymbolReplacement>();

            CreateInitialProxies(captured);

            GenerateMethodImplementations();

            // Return a replacement body for the original method
            return ReplaceOriginalMethod();
        }
예제 #7
0
        protected override void GenerateControlFields()
        {
            // the fields are initialized from async method, so they need to be public:

            this.stateField = F.StateMachineField(F.SpecialType(SpecialType.System_Int32), GeneratedNames.MakeStateMachineStateFieldName(), isPublic: true);
            _builderField = F.StateMachineField(_asyncMethodBuilderMemberCollection.BuilderType, GeneratedNames.AsyncBuilderFieldName(), isPublic: true);
        }
        public FieldOrPropertyInitializer(FieldSymbol fieldOpt, SyntaxNode syntax, int precedingInitializersLength)
        {
            Debug.Assert(syntax.IsKind(SyntaxKind.EqualsValueClause) && fieldOpt != null || syntax is StatementSyntax);

            FieldOpt = fieldOpt;
            Syntax = syntax.GetReference();
            PrecedingInitializersLength = precedingInitializersLength;
        }
예제 #9
0
        private DiagnosticInfo _lazyUseSiteDiagnostic = CSDiagnosticInfo.EmptyErrorInfo; // Indicates unknown state. 

        public RetargetingFieldSymbol(RetargetingModuleSymbol retargetingModule, FieldSymbol underlyingField)
            : base (underlyingField)
        {
            Debug.Assert((object)retargetingModule != null);
            Debug.Assert(!(underlyingField is RetargetingFieldSymbol));

            _retargetingModule = retargetingModule;
        }
예제 #10
0
        public TupleFieldSymbol(TupleTypeSymbol container, FieldSymbol underlyingField, int tupleElementIndex)
            : base(underlyingField)
        {
            Debug.Assert(container.UnderlyingNamedType.Equals(underlyingField.ContainingType, TypeCompareKind.IgnoreDynamicAndTupleNames) || this is TupleVirtualElementFieldSymbol,
                                            "virtual fields should be represented by " + nameof(TupleVirtualElementFieldSymbol));

            _containingTuple = container;
            _tupleElementIndex = tupleElementIndex;
        }
 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;
 }
예제 #12
0
        private DiagnosticInfo lazyUseSiteDiagnostic = CSDiagnosticInfo.EmptyErrorInfo; // Indicates unknown state. 

        public RetargetingFieldSymbol(RetargetingModuleSymbol retargetingModule, FieldSymbol underlyingField)
        {
            Debug.Assert((object)retargetingModule != null);
            Debug.Assert((object)underlyingField != null);
            Debug.Assert(!(underlyingField is RetargetingFieldSymbol));

            this.retargetingModule = retargetingModule;
            this.underlyingField = underlyingField;
        }
예제 #13
0
 public BoundFieldAccess Update(
     BoundExpression receiver,
     FieldSymbol fieldSymbol,
     ConstantValue constantValueOpt,
     LookupResultKind resultKind,
     TypeSymbol typeSymbol)
 {
     return this.Update(receiver, fieldSymbol, constantValueOpt, resultKind, this.IsByValue, typeSymbol);
 }
예제 #14
0
 public BoundFieldAccess(
     CSharpSyntaxNode syntax,
     BoundExpression receiver,
     FieldSymbol fieldSymbol,
     ConstantValue constantValueOpt,
     bool hasErrors = false)
     : this(syntax, receiver, fieldSymbol, constantValueOpt, LookupResultKind.Viable, fieldSymbol.Type, hasErrors)
 {
 }
 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);
 }
예제 #16
0
        private static XElement LoadField(FieldSymbol f)
        {
            XElement elem = new XElement("field");

            elem.Add(new XAttribute("name", f.Name));
            elem.Add(new XAttribute("type", f.Type.ToTestDisplayString()));

            return elem;
        }
예제 #17
0
        protected override void GenerateFields()
        {
            // Add a field: T current
            currentField = F.SynthesizeField(elementType, GeneratedNames.MakeIteratorCurrentBackingFieldName());

            // if it is an iterable, add a field: int initialThreadId
            var threadType = F.Compilation.GetWellKnownType(WellKnownType.System_Threading_Thread);
            initialThreadIdField = isEnumerable && (object)threadType != null && !threadType.IsErrorType()
                ? F.SynthesizeField(F.SpecialType(SpecialType.System_Int32), GeneratedNames.MakeIteratorCurrentThreadIdName())
                : null;
        }
예제 #18
0
 public BoundFieldAccess(
     CSharpSyntaxNode syntax,
     BoundExpression receiver,
     FieldSymbol fieldSymbol,
     ConstantValue constantValueOpt,
     LookupResultKind resultKind,
     TypeSymbol type,
     bool hasErrors = false)
     : this(syntax, receiver, fieldSymbol, constantValueOpt, resultKind, NeedsByValueFieldAccess(receiver, fieldSymbol), type, hasErrors)
 {
 }
        private int nextFinalizeState = StateMachineStates.FinishedStateMachine - 1;  // -3

        internal IteratorMethodToStateMachineRewriter(
            SyntheticBoundNodeFactory F,
            MethodSymbol originalMethod,
            FieldSymbol state,
            FieldSymbol current,
            IReadOnlySet<Symbol> variablesCaptured,
            IReadOnlyDictionary<Symbol, CapturedSymbolReplacement> initialProxies,
            DiagnosticBag diagnostics)
            : base(F, originalMethod, state, variablesCaptured, initialProxies, diagnostics, useFinalizerBookkeeping: false)
        {
            this.current = current;
        }
        private int nextFinalizeState = StateMachineStates.FinishedStateMachine - 1;  // -3

        internal IteratorMethodToClassRewriter(
            SyntheticBoundNodeFactory F,
            MethodSymbol originalMethod,
            FieldSymbol state,
            FieldSymbol current,
            HashSet<Symbol> variablesCaptured,
            Dictionary<Symbol, CapturedSymbolReplacement> initialProxies,
            DiagnosticBag diagnostics,
            bool generateDebugInfo)
            : base(F, originalMethod, state, variablesCaptured, initialProxies, diagnostics,
                  useFinalizerBookkeeping: false,
                  generateDebugInfo: generateDebugInfo)
        {
            this.current = current;
        }
        private int _nextFinalizeState = StateMachineStates.FinishedStateMachine - 1;  // -3

        internal IteratorMethodToStateMachineRewriter(
            SyntheticBoundNodeFactory F,
            MethodSymbol originalMethod,
            FieldSymbol state,
            FieldSymbol current,
            IReadOnlySet<Symbol> hoistedVariables,
            IReadOnlyDictionary<Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
            SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals,
            VariableSlotAllocator slotAllocatorOpt,
            int nextFreeHoistedLocalSlot,
            DiagnosticBag diagnostics)
            : base(F, originalMethod, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics, useFinalizerBookkeeping: false)
        {
            _current = current;
        }
예제 #22
0
        internal FieldSymbol GetHostObjectField()
        {
            if ((object)_hostObjectField != null)
            {
                return _hostObjectField;
            }

            var hostObjectTypeSymbol = _compilation.GetHostObjectTypeSymbol();
            if ((object)hostObjectTypeSymbol != null && hostObjectTypeSymbol.Kind != SymbolKind.ErrorType)
            {
                return _hostObjectField = new SynthesizedFieldSymbol(
                    _declaringSubmissionClass, hostObjectTypeSymbol, "<host-object>", isPublic: false, isReadOnly: true, isStatic: false);
            }

            return null;
        }
예제 #23
0
        internal static GlobalExpressionVariable Create(
                SourceMemberContainerTypeSymbol containingType,
                DeclarationModifiers modifiers,
                TypeSyntax typeSyntax,
                string name,
                SyntaxNode syntax,
                Location location,
                FieldSymbol containingFieldOpt,
                SyntaxNode nodeToBind)
        {
            Debug.Assert(nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind is ExpressionSyntax);

            var syntaxReference = syntax.GetReference();
            return typeSyntax.IsVar
                ? new InferrableGlobalExpressionVariable(containingType, modifiers, typeSyntax, name, syntaxReference, location, containingFieldOpt, nodeToBind)
                : new GlobalExpressionVariable(containingType, modifiers, typeSyntax, name, syntaxReference, location);
        }
예제 #24
0
        public IFieldReference Map(Microsoft.CodeAnalysis.CSharp.Symbols.FieldSymbol fieldSymbol)
        {
            IFieldReference fr = null;

            if (!fieldSymbolCache.TryGetValue(fieldSymbol, out fr))
            {
                fr = new FieldReference()
                {
                    ContainingType = Map(fieldSymbol.ContainingType),
                    InternFactory  = this.host.InternFactory,
                    Name           = this.nameTable.GetNameFor(fieldSymbol.Name),
                    Type           = Map(fieldSymbol.Type),
                };
                this.fieldSymbolCache[fieldSymbol] = fr;
            }
            return(fr);
        }
 private static BoundExpression BindFieldOrEnumInitializer(
     Binder binder,
     FieldSymbol fieldSymbol,
     EqualsValueClauseSyntax initializer,
     DiagnosticBag diagnostics)
 {
     var enumConstant = fieldSymbol as SourceEnumConstantSymbol;
     var collisionDetector = new LocalScopeBinder(binder);
     if ((object)enumConstant != null)
     {
         return collisionDetector.BindEnumConstantInitializer(enumConstant, initializer.Value, diagnostics);
     }
     else
     {
         return collisionDetector.BindVariableOrAutoPropInitializer(initializer, fieldSymbol.Type, diagnostics);
     }
 }
예제 #26
0
        internal LambdaFrame(MethodSymbol topLevelMethod, CSharpSyntaxNode scopeSyntaxOpt, DebugId methodId, DebugId closureId)
            : base(MakeName(scopeSyntaxOpt, methodId, closureId), topLevelMethod)
        {
            _topLevelMethod = topLevelMethod;
            _constructor = new LambdaFrameConstructor(this);
            this.ClosureOrdinal = closureId.Ordinal;

            // static lambdas technically have the class scope so the scope syntax is null 
            if (scopeSyntaxOpt == null)
            {
                _staticConstructor = new SynthesizedStaticConstructor(this);
                var cacheVariableName = GeneratedNames.MakeCachedFrameInstanceFieldName();
                _singletonCache = new SynthesizedLambdaCacheFieldSymbol(this, this, cacheVariableName, topLevelMethod, isReadOnly: true, isStatic: true);
            }

            AssertIsClosureScopeSyntax(scopeSyntaxOpt);
            this.ScopeSyntaxOpt = scopeSyntaxOpt;
        }
예제 #27
0
        /// <summary>
        /// Converts access to a tuple instance into access into the underlying ValueTuple(s).
        ///
        /// For instance, tuple.Item8
        /// produces fieldAccess(field=Item1, receiver=fieldAccess(field=Rest, receiver=ValueTuple for tuple))
        /// </summary>
        private BoundExpression MakeTupleFieldAccess(
            CSharpSyntaxNode syntax,
            FieldSymbol tupleField, 
            BoundExpression rewrittenReceiver,
            ConstantValue constantValueOpt,
            LookupResultKind resultKind,
            TypeSymbol type)
        {
            var tupleType = tupleField.ContainingType;

            NamedTypeSymbol currentLinkType = tupleType.TupleUnderlyingType;
            FieldSymbol underlyingField = tupleField.TupleUnderlyingField;

            if ((object)underlyingField == null)
            {
                // Use-site error must have been reported elsewhere.
                return new BoundFieldAccess(syntax, rewrittenReceiver, tupleField, constantValueOpt, resultKind, type, hasErrors: true);
            }

            if (underlyingField.ContainingType != currentLinkType)
            {
                WellKnownMember wellKnownTupleRest = TupleTypeSymbol.GetTupleTypeMember(TupleTypeSymbol.RestPosition, TupleTypeSymbol.RestPosition);
                var tupleRestField = (FieldSymbol)TupleTypeSymbol.GetWellKnownMemberInType(currentLinkType.OriginalDefinition, wellKnownTupleRest, _diagnostics, syntax);

                if ((object)tupleRestField == null)
                {
                    // error tolerance for cases when Rest is missing
                    return new BoundFieldAccess(syntax, rewrittenReceiver, tupleField, constantValueOpt, resultKind, type, hasErrors: true);
                }

                // make nested field accesses to Rest
                do
                {
                    FieldSymbol nestedFieldSymbol = tupleRestField.AsMember(currentLinkType);

                    currentLinkType = currentLinkType.TypeArgumentsNoUseSiteDiagnostics[TupleTypeSymbol.RestPosition - 1].TupleUnderlyingType;
                    rewrittenReceiver = new BoundFieldAccess(syntax, rewrittenReceiver, nestedFieldSymbol, ConstantValue.NotAvailable, LookupResultKind.Viable, currentLinkType);
                }
                while (underlyingField.ContainingType != currentLinkType);
            }

            // make a field access for the most local access
            return new BoundFieldAccess(syntax, rewrittenReceiver, underlyingField, constantValueOpt, resultKind, type);
        }
 public StateMachineMethodToClassRewriter(
     SyntheticBoundNodeFactory F,
     MethodSymbol originalMethod,
     FieldSymbol state,
     HashSet<Symbol> variablesCaptured,
     Dictionary<Symbol, CapturedSymbolReplacement> initialProxies,
     DiagnosticBag diagnostics,
     bool useFinalizerBookkeeping,
     bool generateDebugInfo)
     : base(F.CompilationState, diagnostics, generateDebugInfo)
 {
     this.F = F;
     this.stateField = state;
     this.cachedState = F.SynthesizedLocal(F.SpecialType(SpecialType.System_Int32), "cachedState");
     this.variablesCaptured = variablesCaptured;
     this.useFinalizerBookkeeping = useFinalizerBookkeeping;
     this.hasFinalizerState = useFinalizerBookkeeping;
     this.originalMethod = originalMethod;
     foreach (var p in initialProxies) this.proxies.Add(p.Key, p.Value);
 }
예제 #29
0
            internal AsyncMethodToClassRewriter(
               MethodSymbol method,
               AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
               SyntheticBoundNodeFactory factory,
               FieldSymbol state,
               FieldSymbol builder,
               Dictionary<Symbol, CapturedSymbol> localProxies,
               DiagnosticBag diagnostics)
                : base(factory, state, localProxies, diagnostics)
            {
                this.method = method;
                this.asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection;
                this.asyncMethodBuilderField = builder;
                this.exprReturnLabel = factory.GenerateLabel("exprReturn");

                this.exprRetValue = method.IsGenericTaskReturningAsync()
                    ? factory.SynthesizedLocal(asyncMethodBuilderMemberCollection.ResultType, GeneratedNames.AsyncExprRetValueFieldName())
                    : null;

                this.dynamicFactory = new LoweredDynamicOperationFactory(factory);
            }
예제 #30
0
        private static bool NeedsByValueFieldAccess(BoundExpression receiver, FieldSymbol fieldSymbol)
        {
            if (fieldSymbol.IsStatic ||
                !fieldSymbol.ContainingType.IsValueType ||
                (object)receiver == null) // receiver may be null in error cases
            {
                return false;
            }

            switch (receiver.Kind)
            {
                case BoundKind.FieldAccess:
                    return ((BoundFieldAccess)receiver).IsByValue;

                case BoundKind.Local:
                    return !((BoundLocal)receiver).LocalSymbol.IsWritable;

                default:
                    return false;
            }
        }
예제 #31
0
        protected BoundStatement Rewrite()
        {
            if (this.body.HasErrors)
            {
                return this.body;
            }

            TypeMap TypeMap = stateMachineClass.TypeMap;
            F.OpenNestedType(stateMachineClass);
            F.CompilationState.SetStateMachineType(method, stateMachineClass);

            // Add a field: int _state
            var intType = F.SpecialType(SpecialType.System_Int32);
            stateField = F.StateMachineField(intType, GeneratedNames.MakeStateMachineStateName(), IsStateFieldPublic);

            GenerateFields();

            // and fields for the initial values of all the parameters of the method
            if (PreserveInitialLocals)
            {
                initialParameters = new Dictionary<Symbol, CapturedSymbolReplacement>();
            }

            // add fields for the captured variables of the method
            var dictionary = IteratorAndAsyncCaptureWalker.Analyze(compilationState.ModuleBuilderOpt.Compilation, method, body);
            IOrderedEnumerable<Symbol> captured =
                from local in dictionary.Keys
                orderby local.Name, local.Locations.Length == 0 ? 0 : local.Locations[0].SourceSpan.Start
                select local;
            this.variablesCaptured = new HashSet<Symbol>(captured);
            this.variableProxies = new Dictionary<Symbol, CapturedSymbolReplacement>();

            CreateInitialProxies(TypeMap, captured, dictionary);
            GenerateMethodImplementations();

            // Return a replacement body for the original method
            return ReplaceOriginalMethod();
        }
예제 #32
0
 internal SubstitutedFieldSymbol(SubstitutedNamedTypeSymbol containingType, FieldSymbol substitutedFrom)
     : base((FieldSymbol)substitutedFrom.OriginalDefinition)
 {
     _containingType = containingType;
 }
예제 #33
0
 // NOTE: If we do not check HasPointerType, we will unconditionally
 //       bind Type and that may cause infinite recursion.
 //       HasPointerType can use syntax directly and break recursion.
 internal static TypeSymbol NonPointerType(this FieldSymbol field) =>
 field.HasPointerType ? null : field.Type;
예제 #34
0
 public TupleElementFieldSymbol(TupleTypeSymbol container, FieldSymbol underlyingField, int tupleFieldId, Location location)
     : base(container, underlyingField, tupleFieldId)
 {
     _locations = location == null ? ImmutableArray <Location> .Empty : ImmutableArray.Create(location);
 }
예제 #35
0
            internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics)
            {
                AnonymousTypeManager      manager = ((AnonymousTypeTemplateSymbol)this.ContainingType).Manager;
                SyntheticBoundNodeFactory F       = this.CreateBoundNodeFactory(compilationState, diagnostics);

                //  Method body:
                //
                //  {
                //      $anonymous$ local = value as $anonymous$;
                //      return local != null
                //             && System.Collections.Generic.EqualityComparer<T_1>.Default.Equals(this.backingFld_1, local.backingFld_1)
                //             ...
                //             && System.Collections.Generic.EqualityComparer<T_N>.Default.Equals(this.backingFld_N, local.backingFld_N);
                //  }

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

                //  local
                BoundAssignmentOperator assignmentToTemp;
                BoundLocal boundLocal = F.StoreToTemp(F.As(F.Parameter(_parameters[0]), anonymousType), out assignmentToTemp);

                //  Generate: statement <= 'local = value as $anonymous$'
                BoundStatement assignment = F.ExpressionStatement(assignmentToTemp);

                //  Generate expression for return statement
                //      retExpression <= 'local != null'
                BoundExpression retExpression = F.Binary(BinaryOperatorKind.ObjectNotEqual,
                                                         manager.System_Boolean,
                                                         F.Convert(manager.System_Object, boundLocal),
                                                         F.Null(manager.System_Object));

                //  prepare symbols
                MethodSymbol    equalityComparer_Equals      = manager.System_Collections_Generic_EqualityComparer_T__Equals;
                MethodSymbol    equalityComparer_get_Default = manager.System_Collections_Generic_EqualityComparer_T__get_Default;
                NamedTypeSymbol equalityComparerType         = equalityComparer_Equals.ContainingType;

                // Compare fields
                for (int index = 0; index < anonymousType.Properties.Length; index++)
                {
                    // Prepare constructed symbols
                    TypeParameterSymbol typeParameter = anonymousType.TypeParameters[index];
                    FieldSymbol         fieldSymbol   = anonymousType.Properties[index].BackingField;
                    NamedTypeSymbol     constructedEqualityComparer = equalityComparerType.Construct(typeParameter);

                    // Generate 'retExpression' = 'retExpression && System.Collections.Generic.EqualityComparer<T_index>.
                    //                                                  Default.Equals(this.backingFld_index, local.backingFld_index)'
                    retExpression = F.LogicalAnd(retExpression,
                                                 F.Call(F.StaticCall(constructedEqualityComparer,
                                                                     equalityComparer_get_Default.AsMember(constructedEqualityComparer)),
                                                        equalityComparer_Equals.AsMember(constructedEqualityComparer),
                                                        F.Field(F.This(), fieldSymbol),
                                                        F.Field(boundLocal, fieldSymbol)));
                }

                // Final return statement
                BoundStatement retStatement = F.Return(retExpression);

                // Create a bound block
                F.CloseMethod(F.Block(ImmutableArray.Create <LocalSymbol>(boundLocal.LocalSymbol), assignment, retStatement));
            }
예제 #36
0
 private FieldSymbol VisitFieldSymbol(FieldSymbol field)
 {
     //  Property of a regular type
     return(((FieldSymbol)field.OriginalDefinition)
            .AsMember((NamedTypeSymbol)TypeMap.SubstituteType(field.ContainingType).AsTypeSymbolOnly()));
 }
예제 #37
0
 internal SubstitutedFieldSymbol(SubstitutedNamedTypeSymbol containingType, FieldSymbol substitutedFrom)
 {
     _containingType     = containingType;
     _originalDefinition = substitutedFrom.OriginalDefinition as FieldSymbol;
 }
예제 #38
0
 public WrappedFieldSymbol(FieldSymbol underlyingField)
 {
     Debug.Assert((object)underlyingField != null);
     _underlyingField = underlyingField;
 }
예제 #39
0
 public EmbeddedField(EmbeddedType containingType, FieldSymbolAdapter underlyingField) :
     base(containingType, underlyingField)
 {
 }
예제 #40
0
 public FieldOrPropertyInitializer(FieldSymbol field, SyntaxReference syntax)
 {
     Debug.Assert(((object)field != null) || (syntax != null));
     Field  = field;
     Syntax = syntax;
 }
예제 #41
0
 public TupleElementFieldSymbol(TupleTypeSymbol container, FieldSymbol underlyingField, int tupleElementIndex, Location location, bool isImplicitlyDeclared)
     : base(container, underlyingField, tupleElementIndex)
 {
     _locations            = location == null ? ImmutableArray <Location> .Empty : ImmutableArray.Create(location);
     _isImplicitlyDeclared = isImplicitlyDeclared;
 }
예제 #42
0
        private static bool DependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet <Symbol> partialClosure)
        {
            Debug.Assert(!ReferenceEquals(type, null));

            // NOTE: unlike in StructDependsClosure, we don't have to check for expanding cycles,
            // because as soon as we see something with non-zero arity we kick out (generic => managed).
            if (partialClosure.Add(type))
            {
                foreach (var member in type.GetMembersUnordered())
                {
                    // Only instance fields (including field-like events) affect the outcome.
                    if (member.IsStatic)
                    {
                        continue;
                    }

                    FieldSymbol field = null;

                    switch (member.Kind)
                    {
                    case SymbolKind.Field:
                        field = (FieldSymbol)member;
                        Debug.Assert(ReferenceEquals(field.AssociatedSymbol as EventSymbol, null),
                                     "Didn't expect to find a field-like event backing field in the member list.");
                        break;

                    case SymbolKind.Event:
                        field = ((EventSymbol)member).AssociatedField;
                        break;
                    }

                    if ((object)field == null)
                    {
                        continue;
                    }

                    // pointers are unmanaged
                    // NOTE: If we do not check HasPointerType, we will unconditionally
                    //       bind Type and that may cause infinite recursion.
                    //       HasPointerType can use syntax directly and break recursion.
                    if (field.HasPointerType)
                    {
                        continue;
                    }

                    TypeSymbol      fieldType      = field.Type;
                    NamedTypeSymbol fieldNamedType = fieldType as NamedTypeSymbol;
                    if ((object)fieldNamedType == null)
                    {
                        if (fieldType.IsManagedType)
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        // NOTE: don't use IsManagedType on a NamedTypeSymbol - that could lead
                        // to infinite recursion.
                        switch (IsManagedTypeHelper(fieldNamedType))
                        {
                        case ThreeState.True:
                            return(true);

                        case ThreeState.False:
                            continue;

                        case ThreeState.Unknown:
                            if (DependsOnDefinitelyManagedType(fieldNamedType, partialClosure))
                            {
                                return(true);
                            }
                            continue;
                        }
                    }
                }
            }

            return(false);
        }