Ejemplo n.º 1
0
 private ParameterSymbol MakeParameterSymbol(int ordinal, string name, ParameterSymbol sourceParameter)
 {
     return(new SynthesizedParameterSymbol(this, sourceParameter.Type, ordinal, sourceParameter.RefKind, name, sourceParameter.CustomModifiers));
 }
Ejemplo n.º 2
0
        internal EEMethodSymbol(
            EENamedTypeSymbol container,
            string name,
            Location location,
            MethodSymbol sourceMethod,
            ImmutableArray <LocalSymbol> sourceLocals,
            ImmutableArray <LocalSymbol> sourceLocalsForBinding,
            ImmutableDictionary <string, DisplayClassVariable> sourceDisplayClassVariables,
            GenerateMethodBody generateMethodBody)
        {
            Debug.Assert(sourceMethod.IsDefinition);
            Debug.Assert(sourceMethod.ContainingSymbol == container.SubstitutedSourceType.OriginalDefinition);
            Debug.Assert(sourceLocals.All(l => l.ContainingSymbol == sourceMethod));

            _container = container;
            _name      = name;
            _locations = ImmutableArray.Create(location);

            // What we want is to map all original type parameters to the corresponding new type parameters
            // (since the old ones have the wrong owners).  Unfortunately, we have a circular dependency:
            //   1) Each new type parameter requires the entire map in order to be able to construct its constraint list.
            //   2) The map cannot be constructed until all new type parameters exist.
            // Our solution is to pass each new type parameter a lazy reference to the type map.  We then
            // initialize the map as soon as the new type parameters are available - and before they are
            // handed out - so that there is never a period where they can require the type map and find
            // it uninitialized.

            var sourceMethodTypeParameters = sourceMethod.TypeParameters;
            var allSourceTypeParameters    = container.SourceTypeParameters.Concat(sourceMethodTypeParameters);

            var getTypeMap = new Func <TypeMap>(() => this.TypeMap);

            _typeParameters = sourceMethodTypeParameters.SelectAsArray(
                (tp, i, arg) => (TypeParameterSymbol) new EETypeParameterSymbol(this, tp, i, getTypeMap),
                (object)null);
            _allTypeParameters = container.TypeParameters.Concat(_typeParameters);
            this.TypeMap       = new TypeMap(allSourceTypeParameters, _allTypeParameters);

            EENamedTypeSymbol.VerifyTypeParameters(this, _typeParameters);

            var substitutedSourceType = container.SubstitutedSourceType;

            this.SubstitutedSourceMethod = sourceMethod.AsMember(substitutedSourceType);
            if (sourceMethod.Arity > 0)
            {
                this.SubstitutedSourceMethod = this.SubstitutedSourceMethod.Construct(_typeParameters.As <TypeSymbol>());
            }
            TypeParameterChecker.Check(this.SubstitutedSourceMethod, _allTypeParameters);

            // Create a map from original parameter to target parameter.
            var parameterBuilder = ArrayBuilder <ParameterSymbol> .GetInstance();

            var substitutedSourceThisParameter    = this.SubstitutedSourceMethod.ThisParameter;
            var substitutedSourceHasThisParameter = (object)substitutedSourceThisParameter != null;

            if (substitutedSourceHasThisParameter)
            {
                _thisParameter = MakeParameterSymbol(0, GeneratedNames.ThisProxyFieldName(), substitutedSourceThisParameter);
                Debug.Assert(_thisParameter.Type == this.SubstitutedSourceMethod.ContainingType);
                parameterBuilder.Add(_thisParameter);
            }

            var ordinalOffset = (substitutedSourceHasThisParameter ? 1 : 0);

            foreach (var substitutedSourceParameter in this.SubstitutedSourceMethod.Parameters)
            {
                var ordinal = substitutedSourceParameter.Ordinal + ordinalOffset;
                Debug.Assert(ordinal == parameterBuilder.Count);
                var parameter = MakeParameterSymbol(ordinal, substitutedSourceParameter.Name, substitutedSourceParameter);
                parameterBuilder.Add(parameter);
            }

            _parameters = parameterBuilder.ToImmutableAndFree();

            var localsBuilder = ArrayBuilder <LocalSymbol> .GetInstance();

            var localsMap = PooledDictionary <LocalSymbol, LocalSymbol> .GetInstance();

            foreach (var sourceLocal in sourceLocals)
            {
                var local = sourceLocal.ToOtherMethod(this, this.TypeMap);
                localsMap.Add(sourceLocal, local);
                localsBuilder.Add(local);
            }
            this.Locals   = localsBuilder.ToImmutableAndFree();
            localsBuilder = ArrayBuilder <LocalSymbol> .GetInstance();

            foreach (var sourceLocal in sourceLocalsForBinding)
            {
                LocalSymbol local;
                if (!localsMap.TryGetValue(sourceLocal, out local))
                {
                    local = sourceLocal.ToOtherMethod(this, this.TypeMap);
                    localsMap.Add(sourceLocal, local);
                }
                localsBuilder.Add(local);
            }
            this.LocalsForBinding = localsBuilder.ToImmutableAndFree();

            // Create a map from variable name to display class field.
            var displayClassVariables = PooledDictionary <string, DisplayClassVariable> .GetInstance();

            foreach (var pair in sourceDisplayClassVariables)
            {
                var variable = pair.Value;
                var displayClassInstanceFromLocal = variable.DisplayClassInstance as DisplayClassInstanceFromLocal;
                var displayClassInstance          = (displayClassInstanceFromLocal == null) ?
                                                    (DisplayClassInstance) new DisplayClassInstanceFromThis(_parameters[0]) :
                                                    new DisplayClassInstanceFromLocal((EELocalSymbol)localsMap[displayClassInstanceFromLocal.Local]);
                variable = variable.SubstituteFields(displayClassInstance, this.TypeMap);
                displayClassVariables.Add(pair.Key, variable);
            }

            _displayClassVariables = displayClassVariables.ToImmutableDictionary();
            displayClassVariables.Free();
            localsMap.Free();

            _generateMethodBody = generateMethodBody;
        }
Ejemplo n.º 3
0
        internal static BoundBlock ConstructFieldLikeEventAccessorBody_Regular(
            SourceEventSymbol eventSymbol,
            bool isAddMethod,
            CSharpCompilation compilation,
            BindingDiagnosticBag diagnostics
            )
        {
            CSharpSyntaxNode syntax = eventSymbol.CSharpSyntaxNode;

            TypeSymbol      delegateType  = eventSymbol.Type;
            MethodSymbol    accessor      = isAddMethod ? eventSymbol.AddMethod : eventSymbol.RemoveMethod;
            ParameterSymbol thisParameter = accessor.ThisParameter;

            TypeSymbol boolType = compilation.GetSpecialType(SpecialType.System_Boolean);

            SpecialMember updateMethodId = isAddMethod
                ? SpecialMember.System_Delegate__Combine
                : SpecialMember.System_Delegate__Remove;
            MethodSymbol updateMethod = (MethodSymbol)compilation.GetSpecialTypeMember(
                updateMethodId
                );

            BoundStatement @return = new BoundReturnStatement(
                syntax,
                refKind: RefKind.None,
                expressionOpt: null
                )
            {
                WasCompilerGenerated = true
            };

            if (updateMethod == null)
            {
                MemberDescriptor memberDescriptor = SpecialMembers.GetDescriptor(updateMethodId);
                diagnostics.Add(
                    new CSDiagnostic(
                        new CSDiagnosticInfo(
                            ErrorCode.ERR_MissingPredefinedMember,
                            memberDescriptor.DeclaringTypeMetadataName,
                            memberDescriptor.Name
                            ),
                        syntax.Location
                        )
                    );

                return(BoundBlock.SynthesizedNoLocals(syntax, @return));
            }

            Binder.ReportUseSite(updateMethod, diagnostics, syntax);

            BoundThisReference fieldReceiver = eventSymbol.IsStatic
                ? null
                : new BoundThisReference(syntax, thisParameter.Type)
            {
                WasCompilerGenerated = true
            };

            BoundFieldAccess boundBackingField = new BoundFieldAccess(
                syntax,
                receiver: fieldReceiver,
                fieldSymbol: eventSymbol.AssociatedField,
                constantValueOpt: null
                )
            {
                WasCompilerGenerated = true
            };

            BoundParameter boundParameter = new BoundParameter(
                syntax,
                parameterSymbol: accessor.Parameters[0]
                )
            {
                WasCompilerGenerated = true
            };

            BoundExpression delegateUpdate;

            MethodSymbol compareExchangeMethod = (MethodSymbol)compilation.GetWellKnownTypeMember(
                WellKnownMember.System_Threading_Interlocked__CompareExchange_T
                );

            if ((object)compareExchangeMethod == null)
            {
                // (DelegateType)Delegate.Combine(_event, value)
                delegateUpdate = BoundConversion.SynthesizedNonUserDefined(
                    syntax,
                    operand: BoundCall.Synthesized(
                        syntax,
                        receiverOpt: null,
                        method: updateMethod,
                        arguments: ImmutableArray.Create <BoundExpression>(
                            boundBackingField,
                            boundParameter
                            )
                        ),
                    conversion: Conversion.ExplicitReference,
                    type: delegateType
                    );

                // _event = (DelegateType)Delegate.Combine(_event, value);
                BoundStatement eventUpdate = new BoundExpressionStatement(
                    syntax,
                    expression: new BoundAssignmentOperator(
                        syntax,
                        left: boundBackingField,
                        right: delegateUpdate,
                        type: delegateType
                        )
                {
                    WasCompilerGenerated = true
                }
                    )
                {
                    WasCompilerGenerated = true
                };

                return(BoundBlock.SynthesizedNoLocals(
                           syntax,
                           statements: ImmutableArray.Create <BoundStatement>(eventUpdate, @return)
                           ));
            }

            compareExchangeMethod = compareExchangeMethod.Construct(
                ImmutableArray.Create <TypeSymbol>(delegateType)
                );

            Binder.ReportUseSite(compareExchangeMethod, diagnostics, syntax);

            GeneratedLabelSymbol loopLabel = new GeneratedLabelSymbol("loop");

            const int numTemps = 3;

            LocalSymbol[] tmps      = new LocalSymbol[numTemps];
            BoundLocal[]  boundTmps = new BoundLocal[numTemps];

            for (int i = 0; i < numTemps; i++)
            {
                tmps[i] = new SynthesizedLocal(
                    accessor,
                    TypeWithAnnotations.Create(delegateType),
                    SynthesizedLocalKind.LoweringTemp
                    );
                boundTmps[i] = new BoundLocal(syntax, tmps[i], null, delegateType)
                {
                    WasCompilerGenerated = true
                };
            }

            // tmp0 = _event;
            BoundStatement tmp0Init = new BoundExpressionStatement(
                syntax,
                expression: new BoundAssignmentOperator(
                    syntax,
                    left: boundTmps[0],
                    right: boundBackingField,
                    type: delegateType
                    )
            {
                WasCompilerGenerated = true
            }
                )
            {
                WasCompilerGenerated = true
            };

            // LOOP:
            BoundStatement loopStart = new BoundLabelStatement(syntax, label: loopLabel)
            {
                WasCompilerGenerated = true
            };

            // tmp1 = tmp0;
            BoundStatement tmp1Update = new BoundExpressionStatement(
                syntax,
                expression: new BoundAssignmentOperator(
                    syntax,
                    left: boundTmps[1],
                    right: boundTmps[0],
                    type: delegateType
                    )
            {
                WasCompilerGenerated = true
            }
                )
            {
                WasCompilerGenerated = true
            };

            // (DelegateType)Delegate.Combine(tmp1, value)
            delegateUpdate = BoundConversion.SynthesizedNonUserDefined(
                syntax,
                operand: BoundCall.Synthesized(
                    syntax,
                    receiverOpt: null,
                    method: updateMethod,
                    arguments: ImmutableArray.Create <BoundExpression>(boundTmps[1], boundParameter)
                    ),
                conversion: Conversion.ExplicitReference,
                type: delegateType
                );

            // tmp2 = (DelegateType)Delegate.Combine(tmp1, value);
            BoundStatement tmp2Update = new BoundExpressionStatement(
                syntax,
                expression: new BoundAssignmentOperator(
                    syntax,
                    left: boundTmps[2],
                    right: delegateUpdate,
                    type: delegateType
                    )
            {
                WasCompilerGenerated = true
            }
                )
            {
                WasCompilerGenerated = true
            };

            // Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1)
            BoundExpression compareExchange = BoundCall.Synthesized(
                syntax,
                receiverOpt: null,
                method: compareExchangeMethod,
                arguments: ImmutableArray.Create <BoundExpression>(
                    boundBackingField,
                    boundTmps[2],
                    boundTmps[1]
                    )
                );

            // tmp0 = Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1);
            BoundStatement tmp0Update = new BoundExpressionStatement(
                syntax,
                expression: new BoundAssignmentOperator(
                    syntax,
                    left: boundTmps[0],
                    right: compareExchange,
                    type: delegateType
                    )
            {
                WasCompilerGenerated = true
            }
                )
            {
                WasCompilerGenerated = true
            };

            // tmp0 == tmp1 // i.e. exit when they are equal, jump to start otherwise
            BoundExpression loopExitCondition = new BoundBinaryOperator(
                syntax,
                operatorKind: BinaryOperatorKind.ObjectEqual,
                left: boundTmps[0],
                right: boundTmps[1],
                constantValueOpt: null,
                methodOpt: null,
                resultKind: LookupResultKind.Viable,
                type: boolType
                )
            {
                WasCompilerGenerated = true
            };

            // branchfalse (tmp0 == tmp1) LOOP
            BoundStatement loopEnd = new BoundConditionalGoto(
                syntax,
                condition: loopExitCondition,
                jumpIfTrue: false,
                label: loopLabel
                )
            {
                WasCompilerGenerated = true
            };

            return(new BoundBlock(
                       syntax,
                       locals: tmps.AsImmutable(),
                       statements: ImmutableArray.Create <BoundStatement>(
                           tmp0Init,
                           loopStart,
                           tmp1Update,
                           tmp2Update,
                           tmp0Update,
                           loopEnd,
                           @return
                           )
                       )
            {
                WasCompilerGenerated = true
            });
        }
Ejemplo n.º 4
0
 public override Symbol VisitParameter(ParameterSymbol parameter)
 {
     // Should never reach here. Should be matched as a result of matching the container.
     throw ExceptionUtilities.Unreachable;
 }
 public RetargetingPropertyParameterSymbol(RetargetingPropertySymbol retargetingProperty, ParameterSymbol underlyingParameter)
     : base(underlyingParameter)
 {
     Debug.Assert((object)retargetingProperty != null);
     _retargetingProperty = retargetingProperty;
 }
 protected ProblemCollection CheckParameter([NotNull] Parameter parameter)
 {
     var symbol = new ParameterSymbol(parameter);
     return CheckSymbol(symbol);
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Called when visiting a <see cref="ParameterSymbol" />; Override this with specific
 /// implementation; Calling default <see cref="DefaultVisit" /> if it's not overridden
 /// </summary>
 /// <param name="symbol">The visited symbol</param>
 /// <param name="argument">Additional argument</param>
 /// <returns></returns>
 public virtual TResult VisitParameter(ParameterSymbol symbol, TArgument argument)
 {
     return(DefaultVisit(symbol, argument));
 }
Ejemplo n.º 8
0
 protected RetargetingParameterSymbol(ParameterSymbol underlyingParameter)
 {
     Debug.Assert(!(underlyingParameter is RetargetingParameterSymbol));
     this.underlyingParameter = underlyingParameter;
 }
Ejemplo n.º 9
0
        private static void GenerateEvent(ScriptGenerator generator, string typeName, EventSymbol eventSymbol)
        {
            ScriptTextWriter writer = generator.Writer;

            ParameterSymbol valueParameter = eventSymbol.Parameters[0];

            string eventName = eventSymbol.GeneratedName;
            string fieldName = eventName;

            if (eventSymbol.DefaultImplementation)
            {
                fieldName = "__" + Utility.CreateCamelCaseName(eventSymbol.Name);

                Debug.Assert(eventSymbol.Parent.Type == SymbolType.Class);

                Symbol fieldSymbol = ((ClassSymbol)eventSymbol.Parent).GetMember(fieldName);
                Debug.Assert((fieldSymbol != null) && (fieldSymbol.Type == SymbolType.Field));

                fieldName = fieldSymbol.GeneratedName;
            }

            string fieldReference;

            if ((eventSymbol.Visibility & MemberVisibility.Static) == 0)
            {
                fieldReference = "this.";
            }
            else
            {
                fieldReference = typeName + ".";
            }
            fieldReference += fieldName;

            bool instanceMember = true;

            if ((eventSymbol.Visibility & MemberVisibility.Static) != 0)
            {
                instanceMember = false;
                writer.Write(typeName);
                writer.Write(".");
            }

            writer.Write("add_");
            writer.Write(eventName);
            if (instanceMember)
            {
                writer.Write(": ");
            }
            else
            {
                writer.Write(" = ");
            }

            writer.Write("function(");
            writer.Write(valueParameter.GeneratedName);
            writer.WriteLine(") {");
            writer.Indent++;

            if (generator.Options.EnableDocComments)
            {
                DocCommentGenerator.GenerateComment(generator, eventSymbol);
            }

            if (eventSymbol.DefaultImplementation)
            {
                writer.Write(fieldReference);
                writer.Write(" = ss.bindAdd(");
                writer.Write(fieldReference);
                writer.Write(", ");
                writer.Write(valueParameter.GeneratedName);
                writer.WriteLine(");");
            }
            else
            {
                CodeGenerator.GenerateScript(generator, eventSymbol, /* add */ true);
            }
            writer.Indent--;
            writer.Write("}");

            if (instanceMember == false)
            {
                writer.WriteLine(";");
            }

            if (instanceMember)
            {
                writer.WriteLine(",");
            }
            else
            {
                writer.Write(typeName);
                writer.Write(".");
            }
            writer.Write("remove_");
            writer.Write(eventName);
            if (instanceMember)
            {
                writer.Write(": ");
            }
            else
            {
                writer.Write(" = ");
            }
            writer.Write("function(");
            writer.Write(valueParameter.GeneratedName);
            writer.WriteLine(") {");
            writer.Indent++;

            if (generator.Options.EnableDocComments)
            {
                DocCommentGenerator.GenerateComment(generator, eventSymbol);
            }

            if (eventSymbol.DefaultImplementation)
            {
                writer.Write(fieldReference);
                writer.Write(" = ss.bindSub(");
                writer.Write(fieldReference);
                writer.Write(", ");
                writer.Write(valueParameter.GeneratedName);
                writer.WriteLine(");");
            }
            else
            {
                CodeGenerator.GenerateScript(generator, eventSymbol, /* add */ false);
            }
            writer.Indent--;
            writer.Write("}");

            if (instanceMember == false)
            {
                writer.WriteLine(";");
            }
        }
Ejemplo n.º 10
0
        private static void GenerateIndexer(ScriptGenerator generator, string typeName, PropertySymbol indexerSymbol)
        {
            if (indexerSymbol.IsAbstract)
            {
                return;
            }

            Debug.Assert((indexerSymbol.Visibility & MemberVisibility.Static) == 0);

            ScriptTextWriter writer = generator.Writer;

            writer.Write("get_");
            writer.Write(indexerSymbol.GeneratedName);
            writer.Write(": function(");

            for (int i = 0; i < indexerSymbol.Parameters.Count - 1; i++)
            {
                ParameterSymbol parameterSymbol = indexerSymbol.Parameters[i];
                if (i > 0)
                {
                    writer.Write(", ");
                }
                writer.Write(parameterSymbol.GeneratedName);
            }

            writer.WriteLine(") {");
            writer.Indent++;

            if (generator.Options.EnableDocComments)
            {
                DocCommentGenerator.GenerateComment(generator, indexerSymbol);
            }

            CodeGenerator.GenerateScript(generator, (IndexerSymbol)indexerSymbol, /* getter */ true);
            writer.Indent--;
            writer.Write("}");

            if (indexerSymbol.IsReadOnly == false)
            {
                writer.WriteLine(",");

                writer.Write("set_");
                writer.Write(indexerSymbol.GeneratedName);
                writer.Write(": function(");
                for (int i = 0; i < indexerSymbol.Parameters.Count; i++)
                {
                    ParameterSymbol parameterSymbol = indexerSymbol.Parameters[i];
                    if (i > 0)
                    {
                        writer.Write(", ");
                    }
                    writer.Write(parameterSymbol.GeneratedName);
                }
                writer.WriteLine(") {");
                writer.Indent++;

                if (generator.Options.EnableDocComments)
                {
                    DocCommentGenerator.GenerateComment(generator, indexerSymbol);
                }

                CodeGenerator.GenerateScript(generator, (IndexerSymbol)indexerSymbol, /* getter */ false);
                writer.Write("return ");
                writer.Write(indexerSymbol.Parameters[indexerSymbol.Parameters.Count - 1].GeneratedName);
                writer.WriteLine(";");
                writer.Indent--;
                writer.Write("}");
            }
        }
 protected override void EnterParameter(ParameterSymbol parameter)
 {
     // parameters are NOT intitially assigned here - if that is a problem, then
     // the parameters must be captured.
     MakeSlot(parameter);
 }
Ejemplo n.º 12
0
 public override Symbol VisitParameter(ParameterSymbol parameter)
 {
     // Should never reach here. Should be matched as a result of matching the container.
     throw new InvalidOperationException();
 }
Ejemplo n.º 13
0
 internal bool DeriveUseSiteDiagnosticFromParameter(ref DiagnosticInfo result, ParameterSymbol param)
 {
     return(DeriveUseSiteDiagnosticFromType(ref result, param.Type) ||
            DeriveUseSiteDiagnosticFromCustomModifiers(ref result, param.CustomModifiers));
 }
Ejemplo n.º 14
0
        protected virtual void ReportUnassignedOutParameter(ParameterSymbol parameter, SyntaxNode node, Location location)
        {
            if (Diagnostics != null)
            {
                if (location == null)
                {
                    location = new SourceLocation(tree, node);
                }

                Diagnostics.Add(ErrorCode.ERR_ParamUnassigned, location, parameter.Name);
            }
        }
Ejemplo n.º 15
0
        private void LoadSignature()
        {
            var moduleSymbol = _containingType.ContainingPEModule;

            SignatureHeader         signatureHeader;
            BadImageFormatException mrEx;

            ParamInfo <TypeSymbol>[] paramInfo = new MetadataDecoder(moduleSymbol, this).GetSignatureForMethod(_handle, out signatureHeader, out mrEx);
            bool makeBad = (mrEx != null);

            // If method is not generic, let's assign empty list for type parameters
            if (!signatureHeader.IsGeneric &&
                _lazyTypeParameters.IsDefault)
            {
                ImmutableInterlocked.InterlockedCompareExchange(ref _lazyTypeParameters,
                                                                ImmutableArray <TypeParameterSymbol> .Empty, default(ImmutableArray <TypeParameterSymbol>));
            }

            int count = paramInfo.Length - 1;
            ImmutableArray <ParameterSymbol> @params;
            bool isBadParameter;

            if (count > 0)
            {
                ParameterSymbol[] parameterCreation = new ParameterSymbol[count];

                for (int i = 0; i < count; i++)
                {
                    parameterCreation[i] = new PEParameterSymbol(moduleSymbol, this, i, paramInfo[i + 1], out isBadParameter);
                    if (isBadParameter)
                    {
                        makeBad = true;
                    }
                }

                @params = parameterCreation.AsImmutableOrNull();
            }
            else
            {
                @params = ImmutableArray <ParameterSymbol> .Empty;
            }

            // paramInfo[0] contains information about return "parameter"
            Debug.Assert(!paramInfo[0].IsByRef);

            // Dynamify object type if necessary
            paramInfo[0].Type = paramInfo[0].Type.AsDynamicIfNoPia(_containingType);

            var returnParam = new PEParameterSymbol(moduleSymbol, this, 0, paramInfo[0], out isBadParameter);

            if (makeBad || isBadParameter)
            {
                var old = Interlocked.CompareExchange(ref _lazyUseSiteDiagnostic, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo);
                Debug.Assert((object)old == (object)CSDiagnosticInfo.EmptyErrorInfo ||
                             ((object)old != null && old.Code == (int)ErrorCode.ERR_BindToBogus && old.Arguments.Length == 1 && old.Arguments[0] == (object)this));
            }

            var signature = new SignatureData(signatureHeader, @params, returnParam);

            Interlocked.CompareExchange(ref _lazySignature, signature, null);
        }
        private void LoadSignature()
        {
            var moduleSymbol = this.containingType.ContainingPEModule;

            byte callingConvention;
            BadImageFormatException mrEx;
            MetadataDecoder.ParamInfo[] paramInfo = new MetadataDecoder(moduleSymbol, this).GetSignatureForMethod(this.handle, out callingConvention, out mrEx);
            bool makeBad = (mrEx != null);

            // If method is not generic, let's assign empty list for type parameters
            if (!SignatureHeader.IsGeneric(callingConvention) &&
                lazyTypeParameters.IsDefault)
            {
                ImmutableInterlocked.InterlockedCompareExchange(ref lazyTypeParameters,
                                        ImmutableArray<TypeParameterSymbol>.Empty, default(ImmutableArray<TypeParameterSymbol>));
            }

            int count = paramInfo.Length - 1;
            ImmutableArray<ParameterSymbol> @params;
            bool isBadParameter;

            if (count > 0)
            {
                ParameterSymbol[] parameterCreation = new ParameterSymbol[count];

                for (int i = 0; i < count; i++)
                {
                    parameterCreation[i] = new PEParameterSymbol(moduleSymbol, this, i, paramInfo[i + 1], out isBadParameter);
                    if (isBadParameter)
                    {
                        makeBad = true;
                    }
                }

                @params = parameterCreation.AsImmutableOrNull();
            }
            else
            {
                @params = ImmutableArray<ParameterSymbol>.Empty;
            }

            // paramInfo[0] contains information about return "parameter"
            Debug.Assert(!paramInfo[0].IsByRef);

            // Dynamify object type if necessary
            paramInfo[0].Type = paramInfo[0].Type.AsDynamicIfNoPia(this.containingType);

            var returnParam = new PEParameterSymbol(moduleSymbol, this, 0, paramInfo[0], out isBadParameter);

            if (makeBad || isBadParameter)
            {
                var old = Interlocked.CompareExchange(ref lazyUseSiteDiagnostic, new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this), CSDiagnosticInfo.EmptyErrorInfo);
                Debug.Assert((object)old == (object)CSDiagnosticInfo.EmptyErrorInfo ||
                             ((object)old != null && old.Code == (int)ErrorCode.ERR_BindToBogus && old.Arguments.Length == 1 && old.Arguments[0] == (object)this));
            }

            var signature = new SignatureData(callingConvention, @params, returnParam);

            Interlocked.CompareExchange(ref lazySignature, signature, null);
        }
Ejemplo n.º 17
0
 public RetargetingMethodParameterSymbol(RetargetingMethodSymbol retargetingMethod, ParameterSymbol underlyingParameter)
     : base(underlyingParameter)
 {
     Debug.Assert((object)retargetingMethod != null);
     _retargetingMethod = retargetingMethod;
 }
        protected internal override object VisitParameter(ParameterSymbol symbol, ArrayBuilder<SymbolDescriptionPart> builder)
        {
            //decorations are handled by methods and properties (for consistency with type parameters)
            builder.Add(new SymbolDescriptionPart
            {
                Kind = SymbolDescriptionPartKind.Identifier,
                Text = symbol.Name,
            });

            return null;
        }
Ejemplo n.º 19
0
 public RetargetingPropertyParameterSymbol(RetargetingPropertySymbol retargetingProperty, ParameterSymbol underlyingParameter)
     : base(underlyingParameter)
 {
     Debug.Assert((object)retargetingProperty != null);
     _retargetingProperty = retargetingProperty;
 }
Ejemplo n.º 20
0
 private static void AppendParameterSymbolInfo(this ICollection<SymbolMarkupToken> markup, ParameterSymbol symbol)
 {
     markup.AppendType(symbol.ValueType);
     markup.AppendSpace();
     markup.AppendParameterName(symbol.Name);
 }
Ejemplo n.º 21
0
 protected RetargetingParameterSymbol(ParameterSymbol underlyingParameter)
     : base(underlyingParameter)
 {
     Debug.Assert(!(underlyingParameter is RetargetingParameterSymbol));
 }
Ejemplo n.º 22
0
        private static ImmutableArray<ParameterSymbol> GetParameters(
            PEModuleSymbol moduleSymbol,
            PEPropertySymbol property,
            MetadataDecoder.ParamInfo[] propertyParams,
            MetadataDecoder.ParamInfo[] accessorParams,
            out bool anyParameterIsBad)
        {
            anyParameterIsBad = false;

            // First parameter is the property type.
            if (propertyParams.Length < 2)
            {
                return ImmutableArray<ParameterSymbol>.Empty;
            }

            var numAccessorParams = accessorParams.Length;

            var parameters = new ParameterSymbol[propertyParams.Length - 1];
            for (int i = 1; i < propertyParams.Length; i++) // from 1 to skip property/return type
            {
                // NOTE: this is a best guess at the Dev10 behavior.  The actual behavior is
                // in the unmanaged helper code that Dev10 uses to load the metadata.
                var propertyParam = propertyParams[i];
                var paramHandle = i < numAccessorParams ? accessorParams[i].Handle : propertyParam.Handle;
                var ordinal = i - 1;
                bool isBad;
                parameters[ordinal] = new PEParameterSymbol(moduleSymbol, property, ordinal, paramHandle, propertyParam, out isBad);

                if (isBad)
                {
                    anyParameterIsBad = true;
                }
            }
            return parameters.AsImmutableOrNull();
        }
Ejemplo n.º 23
0
        private void EmitParameter(ParameterSymbol parameterSymbol)
        {
            // local function
            bool IsSecure(SyntaxBase?value) => value is BooleanLiteralSyntax boolLiteral && boolLiteral.Value;

            if (!(SyntaxHelper.TryGetPrimitiveType(parameterSymbol.DeclaringParameter) is TypeSymbol primitiveType))
            {
                // this should have been caught by the type checker long ago
                throw new ArgumentException($"Unable to find primitive type for parameter {parameterSymbol.Name}");
            }

            writer.WriteStartObject();

            if (parameterSymbol.DeclaringParameter.Decorators.Any())
            {
                var parameterType   = SyntaxFactory.CreateStringLiteral(primitiveType.Name);
                var parameterObject = SyntaxFactory.CreateObject(SyntaxFactory.CreateObjectProperty("type", parameterType).AsEnumerable());

                if (parameterSymbol.Modifier is ParameterDefaultValueSyntax defaultValueSyntax)
                {
                    parameterObject.MergeProperty("defaultValue", defaultValueSyntax.DefaultValue);
                }

                foreach (var decoratorSyntax in parameterSymbol.DeclaringParameter.Decorators.Reverse())
                {
                    var symbol = this.context.SemanticModel.GetSymbolInfo(decoratorSyntax.Expression);

                    if (symbol is FunctionSymbol decoratorSymbol)
                    {
                        var argumentTypes = decoratorSyntax.Arguments
                                            .Select(argument => this.context.SemanticModel.TypeManager.GetTypeInfo(argument))
                                            .ToArray();

                        // There should be exact one matching decorator since there's no errors.
                        Decorator decorator = this.context.SemanticModel.Root.ImportedNamespaces
                                              .SelectMany(ns => ns.Value.Type.DecoratorResolver.GetMatches(decoratorSymbol, argumentTypes))
                                              .Single();

                        parameterObject = decorator.Evaluate(decoratorSyntax, primitiveType, parameterObject);
                    }
                }

                foreach (var property in parameterObject.Properties)
                {
                    if (property.TryGetKeyText() is string propertyName)
                    {
                        this.emitter.EmitProperty(propertyName, property.Value);
                    }
                }
            }
            else
            {
                // TODO: remove this before the 0.3 release.
                switch (parameterSymbol.Modifier)
                {
                case null:
                    this.emitter.EmitProperty("type", GetTemplateTypeName(primitiveType, secure: false));

                    break;

                case ParameterDefaultValueSyntax defaultValueSyntax:
                    this.emitter.EmitProperty("type", GetTemplateTypeName(primitiveType, secure: false));
                    this.emitter.EmitProperty("defaultValue", defaultValueSyntax.DefaultValue);

                    break;

                case ObjectSyntax modifierSyntax:
                    // this would throw on duplicate properties in the object node - we are relying on emitter checking for errors at the beginning
                    var properties = modifierSyntax.ToKnownPropertyValueDictionary();

                    this.emitter.EmitProperty("type", GetTemplateTypeName(primitiveType, IsSecure(properties.TryGetValue("secure"))));

                    // relying on validation here as well (not all of the properties are valid in all contexts)
                    foreach (string modifierPropertyName in ParameterModifierPropertiesToEmitDirectly)
                    {
                        this.emitter.EmitOptionalPropertyExpression(modifierPropertyName, properties.TryGetValue(modifierPropertyName));
                    }

                    this.emitter.EmitOptionalPropertyExpression("defaultValue", properties.TryGetValue(LanguageConstants.ParameterDefaultPropertyName));
                    this.emitter.EmitOptionalPropertyExpression("allowedValues", properties.TryGetValue(LanguageConstants.ParameterAllowedPropertyName));

                    break;
                }
            }

            writer.WriteEndObject();
        }
Ejemplo n.º 24
0
 public EmbeddedParameter(EmbeddedTypesManager.CommonEmbeddedMember containingPropertyOrMethod, ParameterSymbol underlyingParameter) :
     base(containingPropertyOrMethod, underlyingParameter)
 {
     Debug.Assert(underlyingParameter.IsDefinition);
 }
Ejemplo n.º 25
0
        public void Test1()
        {
            var assemblies = MetadataTestHelpers.GetSymbolsForReferences(new[]
            {
                TestReferences.SymbolsTests.CustomModifiers.Modifiers.dll,
                TestReferences.NetFx.v4_0_21006.mscorlib
            });

            var modifiersModule = assemblies[0].Modules[0];


            var modifiers = modifiersModule.GlobalNamespace.GetTypeMembers("Modifiers").Single();

            FieldSymbol f0 = modifiers.GetMembers("F0").OfType <FieldSymbol>().Single();

            Assert.Equal(1, f0.TypeWithAnnotations.CustomModifiers.Length);

            var f0Mod = f0.TypeWithAnnotations.CustomModifiers[0];

            Assert.True(f0Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", f0Mod.Modifier.ToTestDisplayString());

            MethodSymbol    m1 = modifiers.GetMembers("F1").OfType <MethodSymbol>().Single();
            ParameterSymbol p1 = m1.Parameters[0];
            ParameterSymbol p2 = modifiers.GetMembers("F2").OfType <MethodSymbol>().Single().Parameters[0];

            ParameterSymbol p4 = modifiers.GetMembers("F4").OfType <MethodSymbol>().Single().Parameters[0];

            MethodSymbol    m5 = modifiers.GetMembers("F5").OfType <MethodSymbol>().Single();
            ParameterSymbol p5 = m5.Parameters[0];

            ParameterSymbol p6 = modifiers.GetMembers("F6").OfType <MethodSymbol>().Single().Parameters[0];

            MethodSymbol m7 = modifiers.GetMembers("F7").OfType <MethodSymbol>().Single();

            Assert.Equal(0, m1.ReturnTypeWithAnnotations.CustomModifiers.Length);

            Assert.Equal(1, p1.TypeWithAnnotations.CustomModifiers.Length);

            var p1Mod = p1.TypeWithAnnotations.CustomModifiers[0];

            Assert.True(p1Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", p1Mod.Modifier.ToTestDisplayString());

            Assert.Equal(2, p2.TypeWithAnnotations.CustomModifiers.Length);

            foreach (var p2Mod in p2.TypeWithAnnotations.CustomModifiers)
            {
                Assert.True(p2Mod.IsOptional);
                Assert.Equal("System.Runtime.CompilerServices.IsConst", p2Mod.Modifier.ToTestDisplayString());
            }

            Assert.Equal(SymbolKind.ErrorType, p4.Type.Kind);

            Assert.True(m5.ReturnsVoid);
            Assert.Equal(1, m5.ReturnTypeWithAnnotations.CustomModifiers.Length);

            var m5Mod = m5.ReturnTypeWithAnnotations.CustomModifiers[0];

            Assert.True(m5Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", m5Mod.Modifier.ToTestDisplayString());

            Assert.Equal(0, p5.TypeWithAnnotations.CustomModifiers.Length);

            ArrayTypeSymbol p5Type = (ArrayTypeSymbol)p5.Type;

            Assert.Equal("System.Int32", p5Type.ElementType.ToTestDisplayString());

            Assert.Equal(1, p5Type.ElementTypeWithAnnotations.CustomModifiers.Length);
            var p5TypeMod = p5Type.ElementTypeWithAnnotations.CustomModifiers[0];

            Assert.True(p5TypeMod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", p5TypeMod.Modifier.ToTestDisplayString());

            Assert.Equal(0, p6.TypeWithAnnotations.CustomModifiers.Length);

            PointerTypeSymbol p6Type = (PointerTypeSymbol)p6.Type;

            Assert.Equal("System.Int32", p6Type.PointedAtType.ToTestDisplayString());

            Assert.Equal(1, p6Type.PointedAtTypeWithAnnotations.CustomModifiers.Length);
            var p6TypeMod = p6Type.PointedAtTypeWithAnnotations.CustomModifiers[0];

            Assert.True(p6TypeMod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", p6TypeMod.Modifier.ToTestDisplayString());

            Assert.False(m7.ReturnsVoid);
            Assert.Equal(1, m7.ReturnTypeWithAnnotations.CustomModifiers.Length);

            var m7Mod = m7.ReturnTypeWithAnnotations.CustomModifiers[0];

            Assert.True(m7Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", m7Mod.Modifier.ToTestDisplayString());
        }
Ejemplo n.º 26
0
 private bool FlowsOut(ParameterSymbol param)
 {
     return((object)param != null && param.RefKind != RefKind.None && !param.IsImplicitlyDeclared && !RegionContains(param.Locations[0].SourceSpan));
 }
 /// <summary>
 /// </summary>
 /// <param name="paramDef">
 /// </param>
 internal MetadataParameterAdapter(ParameterSymbol paramDef)
 {
     this.paramDef = paramDef;
 }
Ejemplo n.º 28
0
 internal override bool TryGetThisParameter(out ParameterSymbol thisParameter)
 {
     thisParameter = null;
     return(true);
 }
Ejemplo n.º 29
0
 /// <summary>
 /// Creates a SemanticModel for a parameter default value.
 /// </summary>
 internal static InitializerSemanticModel Create(CSharpCompilation compilation, ParameterSyntax syntax, ParameterSymbol parameterSymbol, Binder rootBinder)
 {
     return(new InitializerSemanticModel(compilation, syntax, parameterSymbol, rootBinder));
 }
 public ParameterDefinition(Module moduleBeingBuilt, ParameterSymbol underlyingParameter)
     : base(moduleBeingBuilt, underlyingParameter)
 { 
 }
Ejemplo n.º 31
0
 protected override void ReportUnassignedOutParameter(ParameterSymbol parameter, SyntaxNode node, Location location)
 {
     _result.Add(parameter);
     base.ReportUnassignedOutParameter(parameter, node, location);
 }
        internal sealed override bool TryGetThisParameter(out ParameterSymbol thisParameter)
        {
            thisParameter = lazyThisParameter;
            if ((object)thisParameter != null || IsStatic)
            {
                return true;
            }

            Interlocked.CompareExchange(ref lazyThisParameter, new ThisParameterSymbol(this), null);
            thisParameter = lazyThisParameter;
            return true;
        }
Ejemplo n.º 33
0
 public BoundParameter(CSharpSyntaxNode syntax, ParameterSymbol parameterSymbol, bool hasErrors = false)
     : this(syntax, parameterSymbol, parameterSymbol.Type, hasErrors)
 {
 }
Ejemplo n.º 34
0
        private static bool ParametersMatch(ParameterSymbol candidateParam, TypeMap candidateMethodTypeMap, ref ParamInfo<TypeSymbol> targetParam)
        {
            Debug.Assert(candidateMethodTypeMap != null);

            // This could be combined into a single return statement with a more complicated expression, but that would
            // be harder to debug.

            if ((candidateParam.RefKind != RefKind.None) != targetParam.IsByRef)
            {
                return false;
            }

            // CONSIDER: Do we want to add special handling for error types?  Right now, we expect they'll just fail to match.
            var substituted = new TypeWithModifiers(candidateParam.Type, candidateParam.CustomModifiers).SubstituteType(candidateMethodTypeMap);
            if (substituted.Type != targetParam.Type)
            {
                return false;
            }

            if (!CustomModifiersMatch(substituted.CustomModifiers, targetParam.CustomModifiers) ||
                !CustomModifiersMatch(candidateMethodTypeMap.SubstituteCustomModifiers(candidateParam.RefCustomModifiers), targetParam.RefCustomModifiers))
            {
                return false;
            }

            return true;
        }
Ejemplo n.º 35
0
 public BoundParameter(CSharpSyntaxNode syntax, ParameterSymbol parameterSymbol)
     : this(syntax, parameterSymbol, parameterSymbol.Type)
 {
 }
Ejemplo n.º 36
0
        private static void AppendParameterSymbolInfo(this ICollection<SymbolMarkupToken> markup, ParameterSymbol symbol, bool includeInfo)
        {
            if (includeInfo)
            {
                markup.AppendPlainText("(parameter)");
                markup.AppendSpace();
            }

            if (symbol.Direction == ParameterDirection.Inout)
            {
                markup.AppendKeyword("inout");
                markup.AppendSpace();
            }
            else if (symbol.Direction == ParameterDirection.Out)
            {
                markup.AppendKeyword("out");
                markup.AppendSpace();
            }

            markup.AppendType(symbol.ValueType, false);
            markup.AppendSpace();
            markup.AppendParameterName(symbol.Name);
        }
Ejemplo n.º 37
0
 /// <summary>
 /// Creates a SemanticModel for a parameter default value.
 /// </summary>
 internal static InitializerSemanticModel Create(SyntaxTreeSemanticModel containingSemanticModel, ParameterSyntax syntax, ParameterSymbol parameterSymbol, Binder rootBinder)
 {
     Debug.Assert(containingSemanticModel != null);
     return(new InitializerSemanticModel(syntax, parameterSymbol, rootBinder, containingSemanticModel));
 }
 public RetargetingMethodParameterSymbol(RetargetingMethodSymbol retargetingMethod, ParameterSymbol underlyingParameter)
     : base(underlyingParameter)
 {
     Debug.Assert((object)retargetingMethod != null);
     _retargetingMethod = retargetingMethod;
 }
Ejemplo n.º 39
0
 internal override bool TryGetThisParameter(out ParameterSymbol thisParameter)
 {
     thisParameter = IsStatic ? null :
                     _uncommonFields?._lazyThisParameter ?? InterlockedOperations.Initialize(ref AccessUncommonFields()._lazyThisParameter, new ThisParameterSymbol(this));
     return(true);
 }
 protected RetargetingParameterSymbol(ParameterSymbol underlyingParameter)
     : base(underlyingParameter)
 {
     Debug.Assert(!(underlyingParameter is RetargetingParameterSymbol));
 }
Ejemplo n.º 41
0
        public ParameterTypeInformation(ParameterSymbol underlyingParameter)
        {
            Debug.Assert((object)underlyingParameter != null);

            _underlyingParameter = underlyingParameter;
        }
        internal Microsoft.Cci.IParameterTypeInformation Translate(ParameterSymbol param, bool needDeclaration)
        {
            System.Diagnostics.Debug.Assert(ReferenceEquals(param, param.OriginalDefinition) ||
                !param.Equals(param.OriginalDefinition));

            if (!ReferenceEquals(param, param.OriginalDefinition))
            {
                return param;
            }
            else if (!needDeclaration)
            {
                Symbol container = param.ContainingSymbol;
                bool containerIsGeneric = false;

                if (container.Kind == SymbolKind.Method)
                {
                    if (((MethodSymbol)container).IsGeneric)
                    {
                        containerIsGeneric = true;
                    }
                    else
                    {
                        containerIsGeneric = IsGenericType(container.ContainingType);
                    }
                }
                else
                {
                    containerIsGeneric = IsGenericType(container.ContainingType);
                }

                if (containerIsGeneric)
                {
                    object reference;
                    Microsoft.Cci.IParameterTypeInformation paramRef;

                    if (genericInstanceMap.TryGetValue(param, out reference))
                    {
                        return (Microsoft.Cci.IParameterTypeInformation)reference;
                    }

                    paramRef = new ParameterTypeInformation(param);

                    genericInstanceMap.Add(param, paramRef);

                    return paramRef;
                }
            }

            return param;
        }
Ejemplo n.º 43
0
 private ParameterSymbol MakeParameterSymbol(int ordinal, string name, ParameterSymbol sourceParameter)
 {
     return(SynthesizedParameterSymbol.Create(this, sourceParameter.TypeWithAnnotations, ordinal, sourceParameter.RefKind, name, sourceParameter.RefCustomModifiers));
 }
        private static Symbol SymbolFromClangCursor(ClangCursor cursor)
        {
            var result = new Symbol();

            switch (cursor.Kind)
            {
                case NClang.CursorKind.CXXAccessSpecifier:
                    result.Name = "(Access Specifier) " + cursor.CxxAccessSpecifier;
                    break;

                default:
                    result.Name = cursor.Spelling;
                    break;
            }

            result.Kind = (CursorKind)cursor.Kind;
            result.BriefComment = cursor.BriefCommentText;
            result.TypeDescription = cursor.CursorType?.Spelling;
            result.EnumDescription = cursor.EnumConstantDeclValue.ToString();
            result.Definition = cursor.Definition.DisplayName;
            result.Linkage = (LinkageKind)cursor.Linkage;
            result.IsBuiltInType = IsBuiltInType(cursor.CursorType);
            result.SymbolType = cursor.CursorType?.Spelling.Replace(" &", "&").Replace(" *", "*") + " ";
            result.ResultType = cursor.ResultType?.Spelling;
            result.Arguments = new List<ParameterSymbol>();
            result.Access = (AccessType)cursor.CxxAccessSpecifier;
            result.IsVariadic = cursor.IsVariadic;

            switch (result.Kind)
            {
                case CursorKind.FunctionDeclaration:
                case CursorKind.CXXMethod:
                case CursorKind.Constructor:
                case CursorKind.Destructor:
                    for (var i = 0; i < cursor.ArgumentCount; i++)
                    {
                        var argument = cursor.GetArgument(i);

                        var arg = new ParameterSymbol();
                        arg.IsBuiltInType = IsBuiltInType(argument.CursorType);
                        arg.Name = argument.Spelling;

                        arg.TypeDescription = argument.CursorType.Spelling;
                        result.Arguments.Add(arg);
                    }

                    if (cursor.IsVariadic)
                    {
                        result.Arguments.Last().Name += ", ";
                        result.Arguments.Add(new ParameterSymbol { Name = "... variadic" });
                    }

                    if (cursor.ParsedComment.FullCommentAsXml != null)
                    {
                        var documentation = XDocument.Parse(cursor.ParsedComment.FullCommentAsXml);

                        var function = documentation.Element("Function");

                        var parameters = function.Element("Parameters");

                        if (parameters != null)
                        {
                            var arguments = parameters.Elements("Parameter");

                            foreach (var argument in arguments)
                            {
                                var isVarArgs = argument.Element("IsVarArg");

                                var discussion = argument.Element("Discussion");

                                var paragraph = discussion.Element("Para");

                                if (isVarArgs != null)
                                {
                                    result.Arguments.Last().Comment = paragraph.Value;
                                }
                                else
                                {
                                    var inx = argument.Element("Index");

                                    if (inx != null)    // This happens when documentation for an argument was left in, but the argument no longer exists.
                                    {
                                        var index = int.Parse(inx.Value);

                                        result.Arguments[index].Comment = paragraph.Value;
                                    }
                                }
                            }
                        }
                    }

                    if (result.Arguments.Count == 0)
                    {
                        result.Arguments.Add(new ParameterSymbol { Name = "void" });
                    }
                    break;
            }

            return result;
        }
            protected BoundExpression LowerEvaluation(BoundDagEvaluation evaluation)
            {
                BoundExpression input = _tempAllocator.GetTemp(evaluation.Input);

                switch (evaluation)
                {
                case BoundDagFieldEvaluation f:
                {
                    FieldSymbol     field      = f.Field;
                    var             outputTemp = new BoundDagTemp(f.Syntax, field.Type, f);
                    BoundExpression output     = _tempAllocator.GetTemp(outputTemp);
                    BoundExpression access     = _localRewriter.MakeFieldAccess(f.Syntax, input, field, null, LookupResultKind.Viable, field.Type);
                    access.WasCompilerGenerated = true;
                    return(_factory.AssignmentExpression(output, access));
                }

                case BoundDagPropertyEvaluation p:
                {
                    PropertySymbol  property   = p.Property;
                    var             outputTemp = new BoundDagTemp(p.Syntax, property.Type, p);
                    BoundExpression output     = _tempAllocator.GetTemp(outputTemp);
                    return(_factory.AssignmentExpression(output, _localRewriter.MakePropertyAccess(_factory.Syntax, input, property, LookupResultKind.Viable, property.Type, isLeftOfAssignment: false)));
                }

                case BoundDagDeconstructEvaluation d:
                {
                    MethodSymbol method         = d.DeconstructMethod;
                    var          refKindBuilder = ArrayBuilder <RefKind> .GetInstance();

                    var argBuilder = ArrayBuilder <BoundExpression> .GetInstance();

                    BoundExpression receiver;
                    void addArg(RefKind refKind, BoundExpression expression)
                    {
                        refKindBuilder.Add(refKind);
                        argBuilder.Add(expression);
                    }

                    Debug.Assert(method.Name == WellKnownMemberNames.DeconstructMethodName);
                    int extensionExtra;
                    if (method.IsStatic)
                    {
                        Debug.Assert(method.IsExtensionMethod);
                        receiver = _factory.Type(method.ContainingType);
                        addArg(method.ParameterRefKinds[0], input);
                        extensionExtra = 1;
                    }
                    else
                    {
                        receiver       = input;
                        extensionExtra = 0;
                    }

                    for (int i = extensionExtra; i < method.ParameterCount; i++)
                    {
                        ParameterSymbol parameter = method.Parameters[i];
                        Debug.Assert(parameter.RefKind == RefKind.Out);
                        var outputTemp = new BoundDagTemp(d.Syntax, parameter.Type, d, i - extensionExtra);
                        addArg(RefKind.Out, _tempAllocator.GetTemp(outputTemp));
                    }

                    return(_factory.Call(receiver, method, refKindBuilder.ToImmutableAndFree(), argBuilder.ToImmutableAndFree()));
                }

                case BoundDagTypeEvaluation t:
                {
                    TypeSymbol inputType = input.Type;
                    Debug.Assert(inputType is { });
                    if (inputType.IsDynamic())
                    {
                        // Avoid using dynamic conversions for pattern-matching.
                        inputType = _factory.SpecialType(SpecialType.System_Object);
                        input     = _factory.Convert(inputType, input);
                    }

                    TypeSymbol      type       = t.Type;
                    var             outputTemp = new BoundDagTemp(t.Syntax, type, t);
                    BoundExpression output     = _tempAllocator.GetTemp(outputTemp);
                    CompoundUseSiteInfo <AssemblySymbol> useSiteInfo = _localRewriter.GetNewCompoundUseSiteInfo();
                    Conversion conversion = _factory.Compilation.Conversions.ClassifyBuiltInConversion(inputType, output.Type, ref useSiteInfo);
                    _localRewriter._diagnostics.Add(t.Syntax, useSiteInfo);
                    BoundExpression evaluated;
                    if (conversion.Exists)
                    {
                        if (conversion.Kind == ConversionKind.ExplicitNullable &&
                            inputType.GetNullableUnderlyingType().Equals(output.Type, TypeCompareKind.AllIgnoreOptions) &&
                            _localRewriter.TryGetNullableMethod(t.Syntax, inputType, SpecialMember.System_Nullable_T_GetValueOrDefault, out MethodSymbol getValueOrDefault))
                        {
                            // As a special case, since the null test has already been done we can use Nullable<T>.GetValueOrDefault
                            evaluated = _factory.Call(input, getValueOrDefault);
                        }
                        else
                        {
                            evaluated = _factory.Convert(type, input, conversion);
                        }
                    }
                    else
                    {
                        evaluated = _factory.As(input, type);
                    }

                    return(_factory.AssignmentExpression(output, evaluated));
                }
Ejemplo n.º 46
0
 internal override bool TryGetThisParameter(out ParameterSymbol thisParameter)
 {
     thisParameter = IsStatic ? null :
                    _uncommonFields?._lazyThisParameter ?? InterlockedOperations.Initialize(ref AccessUncommonFields()._lazyThisParameter, new ThisParameterSymbol(this));
     return true;
 }
Ejemplo n.º 47
0
        protected virtual BoundStatement InitializeParameterField(MethodSymbol getEnumeratorMethod, ParameterSymbol parameter, BoundExpression resultParameter, BoundExpression parameterProxy)
        {
            Debug.Assert(!method.IsIterator || !method.IsAsync); // an override handles async-iterators

            // result.parameter = this.parameterProxy;
            return(F.Assignment(resultParameter, parameterProxy));
        }