public override BoundNode VisitHostObjectMemberReference(BoundHostObjectMemberReference node)
        {
            Debug.Assert(previousSubmissionFields != null);
            Debug.Assert(!containingSymbol.IsStatic);

            var hostObjectReference = previousSubmissionFields.GetHostObjectField();
            var thisReference = new BoundThisReference(null, null, containingSymbol.ThisParameter, containingType);
            return new BoundFieldAccess(null, null, thisReference, hostObjectReference, constantValueOpt: null);
        }
        public override BoundNode VisitPreviousSubmissionReference(BoundPreviousSubmissionReference node)
        {
            var targetType = (ImplicitTypeSymbol)node.Type;
            Debug.Assert(targetType.IsScriptClass);
            Debug.Assert(!containingSymbol.IsStatic);

            Debug.Assert(previousSubmissionFields != null);

            var targetScriptReference = previousSubmissionFields.GetOrMakeField(targetType);
            var thisReference = new BoundThisReference(null, null, containingSymbol.ThisParameter, containingType);
            return new BoundFieldAccess(null, null, thisReference, targetScriptReference, constantValueOpt: null);
        }
예제 #3
0
        /// <summary>
        /// In embedded statements, returns a BoundLocal when the type was explicit.
        /// In global statements, returns a BoundFieldAccess when the type was explicit.
        /// Otherwise returns a DeconstructionVariablePendingInference when the type is implicit.
        /// </summary>
        private BoundExpression BindDeconstructionVariable(
            TypeSymbol declType,
            SingleVariableDesignationSyntax designation,
            DiagnosticBag diagnostics)
        {
            SourceLocalSymbol localSymbol = LookupLocal(designation.Identifier);

            // is this a local?
            if ((object)localSymbol != null)
            {
                // Check for variable declaration errors.
                // Use the binder that owns the scope for the local because this (the current) binder
                // might own nested scope.
                var hasErrors = localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics);

                if ((object)declType != null)
                {
                    return(new BoundLocal(designation, localSymbol, isDeclaration: true, constantValueOpt: null, type: declType, hasErrors: hasErrors));
                }

                return(new DeconstructionVariablePendingInference(designation, localSymbol, receiverOpt: null));
            }

            // Is this a field?
            GlobalExpressionVariable field = LookupDeclaredField(designation);

            if ((object)field == null)
            {
                // We should have the right binder in the chain, cannot continue otherwise.
                throw ExceptionUtilities.Unreachable;
            }

            BoundThisReference receiver = ThisReference(designation, this.ContainingType, hasErrors: false,
                                                        wasCompilerGenerated: true);

            if ((object)declType != null)
            {
                TypeSymbol fieldType = field.GetFieldType(this.FieldsBeingBound);
                Debug.Assert(declType == fieldType);
                return(new BoundFieldAccess(designation,
                                            receiver,
                                            field,
                                            constantValueOpt: null,
                                            resultKind: LookupResultKind.Viable,
                                            type: fieldType));
            }

            return(new DeconstructionVariablePendingInference(designation, field, receiver));
        }
예제 #4
0
        /// <summary>
        /// Construct a body for an auto-property accessor (updating or returning the backing field).
        /// </summary>
        internal static BoundBlock ConstructAutoPropertyAccessorBody(SourceMemberMethodSymbol accessor)
        {
            Debug.Assert(accessor.MethodKind == MethodKind.PropertyGet || accessor.MethodKind == MethodKind.PropertySet);

            var property                   = (SourcePropertySymbol)accessor.AssociatedSymbol;
            CSharpSyntaxNode syntax        = property.CSharpSyntaxNode;
            BoundExpression  thisReference = null;

            if (!accessor.IsStatic)
            {
                var thisSymbol = accessor.ThisParameter;
                thisReference = new BoundThisReference(syntax, thisSymbol.Type.TypeSymbol)
                {
                    WasCompilerGenerated = true
                };
            }

            var field       = property.BackingField;
            var fieldAccess = new BoundFieldAccess(syntax, thisReference, field, ConstantValue.NotAvailable)
            {
                WasCompilerGenerated = true
            };
            BoundStatement statement;

            if (accessor.MethodKind == MethodKind.PropertyGet)
            {
                statement = new BoundReturnStatement(accessor.SyntaxNode, RefKind.None, fieldAccess);
            }
            else
            {
                Debug.Assert(accessor.MethodKind == MethodKind.PropertySet);
                var parameter = accessor.Parameters[0];
                statement = new BoundExpressionStatement(
                    accessor.SyntaxNode,
                    new BoundAssignmentOperator(
                        syntax,
                        fieldAccess,
                        new BoundParameter(syntax, parameter)
                {
                    WasCompilerGenerated = true
                },
                        property.Type.TypeSymbol)
                {
                    WasCompilerGenerated = true
                });
            }

            return(BoundBlock.SynthesizedNoLocals(syntax, statement));
        }
        public override BoundNode VisitPreviousSubmissionReference(BoundPreviousSubmissionReference node)
        {
            var targetType = (ImplicitNamedTypeSymbol)node.Type;

            Debug.Assert(targetType.TypeKind == TypeKind.Submission);
            Debug.Assert(!_factory.TopLevelMethod.IsStatic);

            Debug.Assert(_previousSubmissionFields != null);

            var syntax = node.Syntax;
            var targetScriptReference = _previousSubmissionFields.GetOrMakeField(targetType);
            var thisReference         = new BoundThisReference(syntax, _factory.CurrentType);

            return(new BoundFieldAccess(syntax, thisReference, targetScriptReference, ConstantValue.NotAvailable));
        }
예제 #6
0
        public override BoundNode VisitThisReference(BoundThisReference node)
        {
            // "topLevelMethod.ThisParameter == null" can occur in a delegate creation expression because the method group
            // in the argument can have a "this" receiver even when "this"
            // is not captured because a static method is selected.  But we do preserve
            // the method group and its receiver in the bound tree.
            // No need to capture "this" in such case.

            // TODO: Why don't we drop "this" while lowering if method is static?
            //       Actually, considering that method group expression does not evaluate to a particular value
            //       why do we have it in the lowered tree at all?

            return(currentMethod == topLevelMethod || topLevelMethod.ThisParameter == null ?
                   node :
                   FramePointer(node.Syntax, (NamedTypeSymbol)node.Type));
        }
예제 #7
0
            public override BoundNode VisitThisReference(BoundThisReference node)
            {
                var thisParam = _topLevelMethod.ThisParameter;

                if (thisParam != null)
                {
                    ReferenceVariable(node.Syntax, thisParam);
                }
                else
                {
                    // This can occur in a delegate creation expression because the method group
                    // in the argument can have a "this" receiver even when "this"
                    // is not captured because a static method is selected.  But we do preserve
                    // the method group and its receiver in the bound tree.
                    // No need to capture "this" in such case.

                    // TODO: Why don't we drop "this" while lowering if method is static?
                    //       Actually, considering that method group expression does not evaluate to a particular value
                    //       why do we have it in the lowered tree at all?
                }

                return(base.VisitThisReference(node));
            }
예제 #8
0
 public override BoundNode VisitThisReference(BoundThisReference node)
 {
     return(RewriteParameter(node.Syntax, _targetMethodThisParameter, node));
 }
예제 #9
0
 private EEMethodSymbol GetThisMethod(EENamedTypeSymbol container, string methodName)
 {
     var syntax = SyntaxFactory.ThisExpression();
     return this.CreateMethod(container, methodName, syntax, (method, diagnostics) =>
     {
         var expression = new BoundThisReference(syntax, GetNonDisplayClassContainer(container.SubstitutedSourceType));
         return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
     });
 }
예제 #10
0
 public override BoundNode VisitThisReference(BoundThisReference node)
 {
     return RewriteParameter(node.Syntax, _targetMethodThisParameter, node);
 }
예제 #11
0
 public override object VisitThisReference(BoundThisReference node, object arg)
 {
     // TODO: in a struct constructor, "this" is not initially assigned.
     CheckAssigned(ThisSymbol, node.Syntax);
     return(null);
 }
예제 #12
0
        internal static ImmutableArray <BoundStatement> ConstructScriptConstructorBody(
            BoundStatement loweredBody,
            MethodSymbol constructor,
            SynthesizedSubmissionFields previousSubmissionFields,
            CSharpCompilation compilation
            )
        {
            // Script field initializers have to be emitted after the call to the base constructor because they can refer to "this" instance.
            //
            // Unlike regular field initializers, initializers of global script variables can access "this" instance.
            // If the base class had a constructor that initializes its state a global variable would access partially initialized object.
            // For this reason Script class must always derive directly from a class that has no state (System.Object).

            SyntaxNode syntax = loweredBody.Syntax;

            // base constructor call:
            Debug.Assert(
                (object)constructor.ContainingType.BaseTypeNoUseSiteDiagnostics == null ||
                constructor.ContainingType.BaseTypeNoUseSiteDiagnostics.SpecialType
                == SpecialType.System_Object
                );
            var objectType = constructor.ContainingAssembly.GetSpecialType(
                SpecialType.System_Object
                );

            BoundExpression receiver = new BoundThisReference(syntax, constructor.ContainingType)
            {
                WasCompilerGenerated = true
            };

            BoundStatement baseConstructorCall = new BoundExpressionStatement(
                syntax,
                new BoundCall(
                    syntax,
                    receiverOpt: receiver,
                    method: objectType.InstanceConstructors[0],
                    arguments: ImmutableArray <BoundExpression> .Empty,
                    argumentNamesOpt: ImmutableArray <string> .Empty,
                    argumentRefKindsOpt: ImmutableArray <RefKind> .Empty,
                    isDelegateCall: false,
                    expanded: false,
                    invokedAsExtensionMethod: false,
                    argsToParamsOpt: ImmutableArray <int> .Empty,
                    defaultArguments: BitVector.Empty,
                    resultKind: LookupResultKind.Viable,
                    type: objectType
                    )
            {
                WasCompilerGenerated = true
            }
                )
            {
                WasCompilerGenerated = true
            };

            var statements = ArrayBuilder <BoundStatement> .GetInstance();

            statements.Add(baseConstructorCall);

            if (constructor.IsSubmissionConstructor)
            {
                // submission initialization:
                MakeSubmissionInitialization(
                    statements,
                    syntax,
                    constructor,
                    previousSubmissionFields,
                    compilation
                    );
            }

            statements.Add(loweredBody);
            return(statements.ToImmutableAndFree());
        }
예제 #13
0
        /// <summary>
        /// Generate a thread-safe accessor for a regular field-like event.
        ///
        /// DelegateType tmp0 = _event; //backing field
        /// DelegateType tmp1;
        /// DelegateType tmp2;
        /// do {
        ///     tmp1 = tmp0;
        ///     tmp2 = (DelegateType)Delegate.Combine(tmp1, value); //Remove for -=
        ///     tmp0 = Interlocked.CompareExchange&lt;DelegateType&gt;(ref _event, tmp2, tmp1);
        /// } while ((object)tmp0 != (object)tmp1);
        ///
        /// Note, if System.Threading.Interlocked.CompareExchange&lt;T&gt; is not available,
        /// we emit the following code and mark the method Synchronized (unless it is a struct).
        ///
        /// _event = (DelegateType)Delegate.Combine(_event, value); //Remove for -=
        ///
        /// </summary>
        internal static BoundBlock ConstructFieldLikeEventAccessorBody_Regular(SourceEventSymbol eventSymbol, bool isAddMethod, CSharpCompilation compilation, DiagnosticBag 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,
                                                              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(new BoundBlock(syntax,
                                      locals: ImmutableArray <LocalSymbol> .Empty,
                                      statements: ImmutableArray.Create <BoundStatement>(@return))
                {
                    WasCompilerGenerated = true
                });
            }

            Binder.ReportUseSiteDiagnostics(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)),
                                                                           kind: ConversionKind.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(new BoundBlock(syntax,
                                      locals: ImmutableArray <LocalSymbol> .Empty,
                                      statements: ImmutableArray.Create <BoundStatement>(
                                          eventUpdate,
                                          @return))
                {
                    WasCompilerGenerated = true
                });
            }

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

            Binder.ReportUseSiteDiagnostics(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, delegateType, SynthesizedLocalKind.LoweringTemp);
                boundTmps[i] = new BoundLocal(syntax, tmps[i], null, delegateType);
            }

            // 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)),
                                                                       kind: ConversionKind.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
            });
        }
 public override BoundNode VisitThisReference(BoundThisReference node)
 {
     variablesCaptured.Add(topLevelMethod.ThisParameter, node.Syntax);
     return(base.VisitThisReference(node));
 }
예제 #15
0
        private void EmitThisStore(BoundThisReference thisRef)
        {
            Debug.Assert(thisRef.Type.IsValueType);

            _builder.EmitOpCode(ILOpCode.Stobj);
            EmitSymbolToken(thisRef.Type, thisRef.Syntax);
        }
예제 #16
0
 internal void Parse(BoundThisReference boundThisReference)
 {
     base.Parse(boundThisReference);
 }
예제 #17
0
        /// <summary>
        /// Generates a submission initialization part of a Script type constructor that represents an interactive submission.
        /// </summary>
        /// <remarks>
        /// The constructor takes a parameter of type Roslyn.Scripting.Session - the session reference.
        /// It adds the object being constructed into the session by calling Microsoft.CSharp.RuntimeHelpers.SessionHelpers.SetSubmission,
        /// and retrieves strongly typed references on all previous submission script classes whose members are referenced by this submission.
        /// The references are stored to fields of the submission (<paramref name="synthesizedFields"/>).
        /// </remarks>
        private static ImmutableArray <BoundStatement> MakeSubmissionInitialization(CSharpSyntaxNode syntax, MethodSymbol submissionConstructor, SynthesizedSubmissionFields synthesizedFields, CSharpCompilation compilation)
        {
            Debug.Assert(submissionConstructor.ParameterCount == 2);

            BoundStatement[] result = new BoundStatement[1 + synthesizedFields.Count];

            var sessionReference = new BoundParameter(syntax, submissionConstructor.Parameters[0])
            {
                WasCompilerGenerated = true
            };
            var submissionGetter = (MethodSymbol)compilation.GetWellKnownTypeMember(
                WellKnownMember.Microsoft_CSharp_RuntimeHelpers_SessionHelpers__GetSubmission
                );
            var submissionAdder = (MethodSymbol)compilation.GetWellKnownTypeMember(
                WellKnownMember.Microsoft_CSharp_RuntimeHelpers_SessionHelpers__SetSubmission
                );

            // TODO: report missing adder/getter
            Debug.Assert((object)submissionAdder != null && (object)submissionGetter != null);

            var intType       = compilation.GetSpecialType(SpecialType.System_Int32);
            var thisReference = new BoundThisReference(syntax, submissionConstructor.ContainingType)
            {
                WasCompilerGenerated = true
            };

            int i = 0;

            // hostObject = (THostObject)SessionHelpers.SetSubmission(<session>, <slot index>, this);
            var slotIndex = compilation.GetSubmissionSlotIndex();

            Debug.Assert(slotIndex >= 0);

            BoundExpression setSubmission = BoundCall.Synthesized(syntax,
                                                                  null,
                                                                  submissionAdder,
                                                                  sessionReference,
                                                                  new BoundLiteral(syntax, ConstantValue.Create(slotIndex), intType)
            {
                WasCompilerGenerated = true
            },
                                                                  thisReference
                                                                  );

            var hostObjectField = synthesizedFields.GetHostObjectField();

            if ((object)hostObjectField != null)
            {
                setSubmission = new BoundAssignmentOperator(syntax,
                                                            new BoundFieldAccess(syntax, thisReference, hostObjectField, ConstantValue.NotAvailable)
                {
                    WasCompilerGenerated = true
                },
                                                            BoundConversion.Synthesized(syntax,
                                                                                        setSubmission,
                                                                                        Conversion.ExplicitReference,
                                                                                        false,
                                                                                        true,
                                                                                        ConstantValue.NotAvailable,
                                                                                        hostObjectField.Type
                                                                                        ),
                                                            hostObjectField.Type
                                                            )
                {
                    WasCompilerGenerated = true
                };
            }

            result[i++] = new BoundExpressionStatement(syntax, setSubmission)
            {
                WasCompilerGenerated = true
            };

            foreach (var field in synthesizedFields.FieldSymbols)
            {
                var targetScriptClass  = (ImplicitNamedTypeSymbol)field.Type;
                var targetSubmissionId = targetScriptClass.DeclaringCompilation.GetSubmissionSlotIndex();
                Debug.Assert(targetSubmissionId >= 0);

                // this.<field> = (<FieldType>)SessionHelpers.GetSubmission(<session>, <i>);
                result[i++] =
                    new BoundExpressionStatement(syntax,
                                                 new BoundAssignmentOperator(syntax,
                                                                             new BoundFieldAccess(syntax, thisReference, field, ConstantValue.NotAvailable)
                {
                    WasCompilerGenerated = true
                },
                                                                             BoundConversion.Synthesized(syntax,
                                                                                                         BoundCall.Synthesized(syntax,
                                                                                                                               null,
                                                                                                                               submissionGetter,
                                                                                                                               sessionReference,
                                                                                                                               new BoundLiteral(syntax, ConstantValue.Create(targetSubmissionId), intType)
                {
                    WasCompilerGenerated = true
                }),
                                                                                                         Conversion.ExplicitReference,
                                                                                                         false,
                                                                                                         true,
                                                                                                         ConstantValue.NotAvailable,
                                                                                                         targetScriptClass
                                                                                                         ),
                                                                             targetScriptClass
                                                                             )
                {
                    WasCompilerGenerated = true
                })
                {
                    WasCompilerGenerated = true
                };
            }

            Debug.Assert(i == result.Length);

            return(result.AsImmutableOrNull());
        }
예제 #18
0
 public override BoundNode VisitThisReference(BoundThisReference node)
 {
     CheckReferenceToThisOrBase(node);
     return(base.VisitThisReference(node));
 }
예제 #19
0
 private EEMethodSymbol GetThisMethod(EENamedTypeSymbol container, string methodName)
 {
     var syntax = SyntaxFactory.ThisExpression();
     return this.CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray<LocalSymbol> declaredLocals) =>
     {
         declaredLocals = ImmutableArray<LocalSymbol>.Empty;
         var expression = new BoundThisReference(syntax, GetNonDisplayClassContainer(container.SubstitutedSourceType));
         return new BoundReturnStatement(syntax, RefKind.None, expression) { WasCompilerGenerated = true };
     });
 }
예제 #20
0
        private void EmitThisReferenceExpression(BoundThisReference thisRef)
        {
            var thisType = thisRef.Type;
            Debug.Assert(thisType.TypeKind != TypeKind.TypeParameter);

            _builder.EmitOpCode(ILOpCode.Ldarg_0);
            if (thisType.IsValueType)
            {
                EmitLoadIndirect(thisType, thisRef.Syntax);
            }
        }
예제 #21
0
        /// <summary>
        /// In embedded statements, returns a BoundLocal when the type was explicit.
        /// In global statements, returns a BoundFieldAccess when the type was explicit.
        /// Otherwise returns a DeconstructionVariablePendingInference when the type is implicit.
        /// </summary>
        private BoundExpression BindDeconstructionDeclarationVariable(
            TypeSyntax typeSyntax,
            SingleVariableDesignationSyntax designation,
            DiagnosticBag diagnostics)
        {
            SourceLocalSymbol localSymbol = LookupLocal(designation.Identifier);

            bool        hasErrors = false;
            bool        isVar;
            bool        isConst = false;
            AliasSymbol alias;
            TypeSymbol  declType = BindVariableType(designation, diagnostics, typeSyntax, ref isConst, out isVar, out alias);

            if (!isVar)
            {
                if (designation.Parent.Kind() == SyntaxKind.ParenthesizedVariableDesignation)
                {
                    // An explicit type can only be provided next to the variable
                    Error(diagnostics, ErrorCode.ERR_DeconstructionVarFormDisallowsSpecificType, designation);
                    hasErrors = true;
                }
            }

            // is this a local?
            if (localSymbol != null)
            {
                // Check for variable declaration errors.
                // Use the binder that owns the scope for the local because this (the current) binder
                // might own nested scope.
                hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics);

                if (!isVar)
                {
                    return(new BoundLocal(designation, localSymbol, constantValueOpt: null, type: declType, hasErrors: hasErrors));
                }

                return(new DeconstructionVariablePendingInference(designation, localSymbol, receiverOpt: null));
            }

            // Is this a field?
            GlobalExpressionVariable field = LookupDeclaredField(designation);

            if ((object)field == null)
            {
                // We should have the right binder in the chain, cannot continue otherwise.
                throw ExceptionUtilities.Unreachable;
            }

            BoundThisReference receiver = ThisReference(designation, this.ContainingType, hasErrors: false,
                                                        wasCompilerGenerated: true);

            if (!isVar)
            {
                TypeSymbol fieldType = field.GetFieldType(this.FieldsBeingBound);
                return(new BoundFieldAccess(designation,
                                            receiver,
                                            field,
                                            constantValueOpt: null,
                                            resultKind: LookupResultKind.Viable,
                                            type: fieldType,
                                            hasErrors: hasErrors));
            }

            return(new DeconstructionVariablePendingInference(designation, field, receiver));
        }
 public override BoundNode VisitThisReference(BoundThisReference node)
 {
     Capture(this.topLevelMethod.ThisParameter, node.Syntax);
     return(base.VisitThisReference(node));
 }
예제 #23
0
        internal static BoundCall GenerateObjectConstructorInitializer(MethodSymbol constructor, DiagnosticBag diagnostics)
        {
            NamedTypeSymbol objectType = constructor.ContainingType.BaseTypeNoUseSiteDiagnostics;

            Debug.Assert(objectType.SpecialType == SpecialType.System_Object);
            MethodSymbol     objectConstructor = null;
            LookupResultKind resultKind        = LookupResultKind.Viable;

            foreach (MethodSymbol objectCtor in objectType.InstanceConstructors)
            {
                if (objectCtor.ParameterCount == 0)
                {
                    objectConstructor = objectCtor;
                    break;
                }
            }

            // UNDONE: If this happens then something is deeply wrong. Should we give a better error?
            if ((object)objectConstructor == null)
            {
                diagnostics.Add(ErrorCode.ERR_BadCtorArgCount, constructor.Locations[0], objectType, /*desired param count*/ 0);
                return(null);
            }

            // UNDONE: If this happens then something is deeply wrong. Should we give a better error?
            bool hasErrors = false;
            HashSet <DiagnosticInfo> useSiteDiagnostics = null;

            if (!AccessCheck.IsSymbolAccessible(objectConstructor, constructor.ContainingType, ref useSiteDiagnostics))
            {
                diagnostics.Add(ErrorCode.ERR_BadAccess, constructor.Locations[0], objectConstructor);
                resultKind = LookupResultKind.Inaccessible;
                hasErrors  = true;
            }

            if (!useSiteDiagnostics.IsNullOrEmpty())
            {
                diagnostics.Add(constructor.Locations.IsEmpty ? NoLocation.Singleton : constructor.Locations[0], useSiteDiagnostics);
            }

            CSharpSyntaxNode syntax = constructor.GetNonNullSyntaxNode();

            BoundExpression receiver = new BoundThisReference(syntax, constructor.ContainingType)
            {
                WasCompilerGenerated = true
            };

            return(new BoundCall(
                       syntax: syntax,
                       receiverOpt: receiver,
                       method: objectConstructor,
                       arguments: ImmutableArray <BoundExpression> .Empty,
                       argumentNamesOpt: ImmutableArray <string> .Empty,
                       argumentRefKindsOpt: ImmutableArray <RefKind> .Empty,
                       isDelegateCall: false,
                       expanded: false,
                       invokedAsExtensionMethod: false,
                       argsToParamsOpt: ImmutableArray <int> .Empty,
                       resultKind: resultKind,
                       type: objectType,
                       hasErrors: hasErrors)
            {
                WasCompilerGenerated = true
            });
        }
예제 #24
0
        /// <summary>
        /// Generates a submission initialization part of a Script type constructor that represents an interactive submission.
        /// </summary>
        /// <remarks>
        /// The constructor takes a parameter of type Roslyn.Scripting.Session - the session reference.
        /// It adds the object being constructed into the session by calling Microsoft.CSharp.RuntimeHelpers.SessionHelpers.SetSubmission,
        /// and retrieves strongly typed references on all previous submission script classes whose members are referenced by this submission.
        /// The references are stored to fields of the submission (<paramref name="synthesizedFields"/>).
        /// </remarks>
        private static ImmutableArray <BoundStatement> MakeSubmissionInitialization(CSharpSyntaxNode syntax, MethodSymbol submissionConstructor, SynthesizedSubmissionFields synthesizedFields, CSharpCompilation compilation)
        {
            Debug.Assert(submissionConstructor.ParameterCount == 2);

            var statements = new List <BoundStatement>(2 + synthesizedFields.Count);

            var submissionArrayReference = new BoundParameter(syntax, submissionConstructor.Parameters[0])
            {
                WasCompilerGenerated = true
            };

            var intType       = compilation.GetSpecialType(SpecialType.System_Int32);
            var objectType    = compilation.GetSpecialType(SpecialType.System_Object);
            var thisReference = new BoundThisReference(syntax, submissionConstructor.ContainingType)
            {
                WasCompilerGenerated = true
            };

            var slotIndex = compilation.GetSubmissionSlotIndex();

            Debug.Assert(slotIndex >= 0);

            // <submission_array>[<slot_index] = this;
            statements.Add(new BoundExpressionStatement(syntax,
                                                        new BoundAssignmentOperator(syntax,
                                                                                    new BoundArrayAccess(syntax,
                                                                                                         submissionArrayReference,
                                                                                                         ImmutableArray.Create <BoundExpression>(new BoundLiteral(syntax, ConstantValue.Create(slotIndex), intType)
            {
                WasCompilerGenerated = true
            }),
                                                                                                         objectType)
            {
                WasCompilerGenerated = true
            },
                                                                                    thisReference,
                                                                                    RefKind.None,
                                                                                    thisReference.Type)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            });

            var hostObjectField = synthesizedFields.GetHostObjectField();

            if ((object)hostObjectField != null)
            {
                // <host_object> = (<host_object_type>)<submission_array>[0]
                statements.Add(
                    new BoundExpressionStatement(syntax,
                                                 new BoundAssignmentOperator(syntax,
                                                                             new BoundFieldAccess(syntax, thisReference, hostObjectField, ConstantValue.NotAvailable)
                {
                    WasCompilerGenerated = true
                },
                                                                             BoundConversion.Synthesized(syntax,
                                                                                                         new BoundArrayAccess(syntax,
                                                                                                                              submissionArrayReference,
                                                                                                                              ImmutableArray.Create <BoundExpression>(new BoundLiteral(syntax, ConstantValue.Create(0), intType)
                {
                    WasCompilerGenerated = true
                }),
                                                                                                                              objectType),
                                                                                                         Conversion.ExplicitReference,
                                                                                                         false,
                                                                                                         true,
                                                                                                         ConstantValue.NotAvailable,
                                                                                                         hostObjectField.Type
                                                                                                         ),
                                                                             hostObjectField.Type)
                {
                    WasCompilerGenerated = true
                })
                {
                    WasCompilerGenerated = true
                });
            }

            foreach (var field in synthesizedFields.FieldSymbols)
            {
                var targetScriptType      = (ImplicitNamedTypeSymbol)field.Type;
                var targetSubmissionIndex = targetScriptType.DeclaringCompilation.GetSubmissionSlotIndex();
                Debug.Assert(targetSubmissionIndex >= 0);

                // this.<field> = (<target_script_type>)<submission_array>[<target_submission_index>];
                statements.Add(
                    new BoundExpressionStatement(syntax,
                                                 new BoundAssignmentOperator(syntax,
                                                                             new BoundFieldAccess(syntax, thisReference, field, ConstantValue.NotAvailable)
                {
                    WasCompilerGenerated = true
                },
                                                                             BoundConversion.Synthesized(syntax,
                                                                                                         new BoundArrayAccess(syntax,
                                                                                                                              submissionArrayReference,
                                                                                                                              ImmutableArray.Create <BoundExpression>(new BoundLiteral(syntax, ConstantValue.Create(targetSubmissionIndex), intType)
                {
                    WasCompilerGenerated = true
                }),
                                                                                                                              objectType)
                {
                    WasCompilerGenerated = true
                },
                                                                                                         Conversion.ExplicitReference,
                                                                                                         false,
                                                                                                         true,
                                                                                                         ConstantValue.NotAvailable,
                                                                                                         targetScriptType
                                                                                                         ),
                                                                             targetScriptType
                                                                             )
                {
                    WasCompilerGenerated = true
                })
                {
                    WasCompilerGenerated = true
                });
            }

            return(statements.AsImmutableOrNull());
        }
예제 #25
0
 public override BoundNode VisitThisReference(BoundThisReference node)
 {
     var rewrittenThis = GenerateThisReference(node);
     Debug.Assert(rewrittenThis.Type.Equals(node.Type, TypeCompareKind.IgnoreDynamicAndTupleNames));
     return rewrittenThis;
 }