Пример #1
0
        Access(ExpressionNodeInfo info, ISymbol symbol, bool implicitThis, IEntity target)
            : base(info.SetKind(AccessKind(info.Context, symbol)))
        {
            cx.TrapWriter.Writer.expr_access(this, target);

            if (implicitThis && !symbol.IsStatic)
            {
                This.CreateImplicit(cx, Entities.Type.Create(cx, symbol.ContainingType), Location, this, -1);
            }
        }
Пример #2
0
        private Access(ExpressionNodeInfo info, ISymbol symbol, bool implicitThis, IEntity target)
            : base(info.SetKind(AccessKind(info.Context, symbol)))
        {
            if (!(target is null))
            {
                Context.TrapWriter.Writer.expr_access(this, target);
            }

            if (implicitThis && !symbol.IsStatic)
            {
                This.CreateImplicit(Context, symbol.ContainingType, Location, this, -1);
            }
        }
        protected override void PopulateExpression(TextWriter trapFile)
        {
            if (IsNameof(Syntax))
            {
                PopulateArguments(trapFile, Syntax.ArgumentList, 0);
                return;
            }

            var    child      = -1;
            string?memberName = null;
            var    target     = TargetSymbol;

            switch (Syntax.Expression)
            {
            case MemberAccessExpressionSyntax memberAccess:
                memberName = memberAccess.Name.Identifier.Text;
                if (Syntax.Expression.Kind() == SyntaxKind.SimpleMemberAccessExpression)
                {
                    // Qualified method call; `x.M()`
                    Create(Context, memberAccess.Expression, this, child++);
                }
                else
                {
                    // Pointer member access; `x->M()`
                    Create(Context, Syntax.Expression, this, child++);
                }
                break;

            case MemberBindingExpressionSyntax memberBinding:
                // Conditionally qualified method call; `x?.M()`
                memberName = memberBinding.Name.Identifier.Text;
                Create(Context, FindConditionalQualifier(memberBinding), this, child++);
                MakeConditional(trapFile);
                break;

            case SimpleNameSyntax simpleName when(Kind == ExprKind.METHOD_INVOCATION):
                // Unqualified method call; `M()`
                memberName = simpleName.Identifier.Text;

                if (target is not null && !target.IsStatic)
                {
                    // Implicit `this` qualifier; add explicitly
                    if (Location.Symbol is not null &&
                        Context.GetModel(Syntax).GetEnclosingSymbol(Location.Symbol.SourceSpan.Start) is IMethodSymbol callingMethod)
                    {
                        This.CreateImplicit(Context, callingMethod.ContainingType, Location, this, child++);
                    }
Пример #4
0
        internal static Expression Create(ExpressionNodeInfo info)
        {
            // Some expressions can be extremely deep (e.g. string + string + string ...)
            // to the extent that the stack has been known to overflow.
            using (info.Context.StackGuard)
            {
                if (info.Node is null)
                {
                    info.Context.ModelError(info.Location, "Attempt to create a null expression");
                    return(new Unknown(info));
                }

                switch (info.Node.Kind())
                {
                case SyntaxKind.AddExpression:
                case SyntaxKind.SubtractExpression:
                case SyntaxKind.LessThanExpression:
                case SyntaxKind.LessThanOrEqualExpression:
                case SyntaxKind.GreaterThanExpression:
                case SyntaxKind.GreaterThanOrEqualExpression:
                case SyntaxKind.MultiplyExpression:
                case SyntaxKind.LogicalAndExpression:
                case SyntaxKind.EqualsExpression:
                case SyntaxKind.ModuloExpression:
                case SyntaxKind.BitwiseAndExpression:
                case SyntaxKind.BitwiseOrExpression:
                case SyntaxKind.DivideExpression:
                case SyntaxKind.NotEqualsExpression:
                case SyntaxKind.LogicalOrExpression:
                case SyntaxKind.IsExpression:
                case SyntaxKind.AsExpression:
                case SyntaxKind.RightShiftExpression:
                case SyntaxKind.LeftShiftExpression:
                case SyntaxKind.ExclusiveOrExpression:
                case SyntaxKind.CoalesceExpression:
                    return(Binary.Create(info));

                case SyntaxKind.FalseLiteralExpression:
                case SyntaxKind.TrueLiteralExpression:
                case SyntaxKind.StringLiteralExpression:
                case SyntaxKind.NullLiteralExpression:
                case SyntaxKind.NumericLiteralExpression:
                case SyntaxKind.CharacterLiteralExpression:
                case SyntaxKind.DefaultLiteralExpression:
                    return(Literal.Create(info));

                case SyntaxKind.InvocationExpression:
                    return(Invocation.Create(info));

                case SyntaxKind.PostIncrementExpression:
                    return(PostfixUnary.Create(info.SetKind(ExprKind.POST_INCR), ((PostfixUnaryExpressionSyntax)info.Node).Operand));

                case SyntaxKind.PostDecrementExpression:
                    return(PostfixUnary.Create(info.SetKind(ExprKind.POST_DECR), ((PostfixUnaryExpressionSyntax)info.Node).Operand));

                case SyntaxKind.AwaitExpression:
                    return(Await.Create(info));

                case SyntaxKind.ElementAccessExpression:
                    return(NormalElementAccess.Create(info));

                case SyntaxKind.SimpleAssignmentExpression:
                case SyntaxKind.OrAssignmentExpression:
                case SyntaxKind.AndAssignmentExpression:
                case SyntaxKind.SubtractAssignmentExpression:
                case SyntaxKind.AddAssignmentExpression:
                case SyntaxKind.MultiplyAssignmentExpression:
                case SyntaxKind.ExclusiveOrAssignmentExpression:
                case SyntaxKind.LeftShiftAssignmentExpression:
                case SyntaxKind.RightShiftAssignmentExpression:
                case SyntaxKind.DivideAssignmentExpression:
                case SyntaxKind.ModuloAssignmentExpression:
                case SyntaxKind.CoalesceAssignmentExpression:
                    return(Assignment.Create(info));

                case SyntaxKind.ObjectCreationExpression:
                    return(ExplicitObjectCreation.Create(info));

                case SyntaxKind.ImplicitObjectCreationExpression:
                    return(ImplicitObjectCreation.Create(info));

                case SyntaxKind.ArrayCreationExpression:
                    return(NormalArrayCreation.Create(info));

                case SyntaxKind.ObjectInitializerExpression:
                    return(ObjectInitializer.Create(info));

                case SyntaxKind.ArrayInitializerExpression:
                    return(ImplicitArrayInitializer.Create(info));

                case SyntaxKind.CollectionInitializerExpression:
                    return(CollectionInitializer.Create(info));

                case SyntaxKind.ConditionalAccessExpression:
                    return(MemberAccess.Create(info, (ConditionalAccessExpressionSyntax)info.Node));

                case SyntaxKind.SimpleMemberAccessExpression:
                    return(MemberAccess.Create(info, (MemberAccessExpressionSyntax)info.Node));

                case SyntaxKind.UnaryMinusExpression:
                    return(Unary.Create(info.SetKind(ExprKind.MINUS)));

                case SyntaxKind.UnaryPlusExpression:
                    return(Unary.Create(info.SetKind(ExprKind.PLUS)));

                case SyntaxKind.SimpleLambdaExpression:
                    return(Lambda.Create(info, (SimpleLambdaExpressionSyntax)info.Node));

                case SyntaxKind.ParenthesizedLambdaExpression:
                    return(Lambda.Create(info, (ParenthesizedLambdaExpressionSyntax)info.Node));

                case SyntaxKind.ConditionalExpression:
                    return(Conditional.Create(info));

                case SyntaxKind.CastExpression:
                    return(Cast.Create(info));

                case SyntaxKind.ParenthesizedExpression:
                    return(Create(info.SetNode(((ParenthesizedExpressionSyntax)info.Node).Expression)));

                case SyntaxKind.PointerType:
                case SyntaxKind.ArrayType:
                case SyntaxKind.PredefinedType:
                case SyntaxKind.NullableType:
                case SyntaxKind.TupleType:
                    return(TypeAccess.Create(info));

                case SyntaxKind.TypeOfExpression:
                    return(TypeOf.Create(info));

                case SyntaxKind.QualifiedName:
                case SyntaxKind.IdentifierName:
                case SyntaxKind.AliasQualifiedName:
                case SyntaxKind.GenericName:
                    return(Name.Create(info));

                case SyntaxKind.LogicalNotExpression:
                    return(Unary.Create(info.SetKind(ExprKind.LOG_NOT)));

                case SyntaxKind.BitwiseNotExpression:
                    return(Unary.Create(info.SetKind(ExprKind.BIT_NOT)));

                case SyntaxKind.PreIncrementExpression:
                    return(Unary.Create(info.SetKind(ExprKind.PRE_INCR)));

                case SyntaxKind.PreDecrementExpression:
                    return(Unary.Create(info.SetKind(ExprKind.PRE_DECR)));

                case SyntaxKind.ThisExpression:
                    return(This.CreateExplicit(info));

                case SyntaxKind.AddressOfExpression:
                    return(Unary.Create(info.SetKind(ExprKind.ADDRESS_OF)));

                case SyntaxKind.PointerIndirectionExpression:
                    return(Unary.Create(info.SetKind(ExprKind.POINTER_INDIRECTION)));

                case SyntaxKind.DefaultExpression:
                    return(Default.Create(info));

                case SyntaxKind.CheckedExpression:
                    return(Checked.Create(info));

                case SyntaxKind.UncheckedExpression:
                    return(Unchecked.Create(info));

                case SyntaxKind.BaseExpression:
                    return(Base.Create(info));

                case SyntaxKind.AnonymousMethodExpression:
                    return(Lambda.Create(info, (AnonymousMethodExpressionSyntax)info.Node));

                case SyntaxKind.ImplicitArrayCreationExpression:
                    return(ImplicitArrayCreation.Create(info));

                case SyntaxKind.AnonymousObjectCreationExpression:
                    return(AnonymousObjectCreation.Create(info));

                case SyntaxKind.ComplexElementInitializerExpression:
                    return(CollectionInitializer.Create(info));

                case SyntaxKind.SizeOfExpression:
                    return(SizeOf.Create(info));

                case SyntaxKind.PointerMemberAccessExpression:
                    return(PointerMemberAccess.Create(info));

                case SyntaxKind.QueryExpression:
                    return(Query.Create(info));

                case SyntaxKind.InterpolatedStringExpression:
                    return(InterpolatedString.Create(info));

                case SyntaxKind.MemberBindingExpression:
                    return(MemberAccess.Create(info, (MemberBindingExpressionSyntax)info.Node));

                case SyntaxKind.ElementBindingExpression:
                    return(BindingElementAccess.Create(info));

                case SyntaxKind.StackAllocArrayCreationExpression:
                    return(StackAllocArrayCreation.Create(info));

                case SyntaxKind.ImplicitStackAllocArrayCreationExpression:
                    return(ImplicitStackAllocArrayCreation.Create(info));

                case SyntaxKind.ArgListExpression:
                    return(ArgList.Create(info));

                case SyntaxKind.RefTypeExpression:
                    return(RefType.Create(info));

                case SyntaxKind.RefValueExpression:
                    return(RefValue.Create(info));

                case SyntaxKind.MakeRefExpression:
                    return(MakeRef.Create(info));

                case SyntaxKind.ThrowExpression:
                    return(Throw.Create(info));

                case SyntaxKind.DeclarationExpression:
                    return(VariableDeclaration.Create(info.Context, (DeclarationExpressionSyntax)info.Node, info.Parent, info.Child));

                case SyntaxKind.TupleExpression:
                    return(Tuple.Create(info));

                case SyntaxKind.RefExpression:
                    return(Ref.Create(info));

                case SyntaxKind.IsPatternExpression:
                    return(IsPattern.Create(info));

                case SyntaxKind.RangeExpression:
                    return(RangeExpression.Create(info));

                case SyntaxKind.IndexExpression:
                    return(Unary.Create(info.SetKind(ExprKind.INDEX)));

                case SyntaxKind.SwitchExpression:
                    return(Switch.Create(info));

                case SyntaxKind.SuppressNullableWarningExpression:
                    return(PostfixUnary.Create(info.SetKind(ExprKind.SUPPRESS_NULLABLE_WARNING), ((PostfixUnaryExpressionSyntax)info.Node).Operand));

                case SyntaxKind.WithExpression:
                    return(WithExpression.Create(info));

                default:
                    info.Context.ModelError(info.Node, $"Unhandled expression '{info.Node}' of kind '{info.Node.Kind()}'");
                    return(new Unknown(info));
                }
            }
        }
Пример #5
0
        protected override void PopulateExpression(TextWriter trapFile)
        {
            if (IsNameof(Syntax))
            {
                PopulateArguments(trapFile, Syntax.ArgumentList, 0);
                return;
            }

            var    child      = -1;
            string memberName = null;
            var    target     = TargetSymbol;

            switch (Syntax.Expression)
            {
            case MemberAccessExpressionSyntax memberAccess:
                memberName = memberAccess.Name.Identifier.Text;
                if (Syntax.Expression.Kind() == SyntaxKind.SimpleMemberAccessExpression)
                {
                    // Qualified method call; `x.M()`
                    Create(cx, memberAccess.Expression, this, child++);
                }
                else
                {
                    // Pointer member access; `x->M()`
                    Create(cx, Syntax.Expression, this, child++);
                }
                break;

            case MemberBindingExpressionSyntax memberBinding:
                // Conditionally qualified method call; `x?.M()`
                memberName = memberBinding.Name.Identifier.Text;
                Create(cx, FindConditionalQualifier(memberBinding), this, child++);
                MakeConditional(trapFile);
                break;

            case SimpleNameSyntax simpleName when(Kind == ExprKind.METHOD_INVOCATION):
                // Unqualified method call; `M()`
                memberName = simpleName.Identifier.Text;

                if (target != null && !target.IsStatic)
                {
                    // Implicit `this` qualifier; add explicitly

                    if (cx.GetModel(Syntax).GetEnclosingSymbol(Location.symbol.SourceSpan.Start) is IMethodSymbol callingMethod)
                    {
                        This.CreateImplicit(cx, callingMethod.ContainingType, Location, this, child++);
                    }
                    else
                    {
                        cx.ModelError(Syntax, "Couldn't determine implicit this type");
                    }
                }
                else
                {
                    // No implicit `this` qualifier
                    child++;
                }
                break;

            default:
                // Delegate or function pointer call; `d()`
                Create(cx, Syntax.Expression, this, child++);
                break;
            }

            var isDynamicCall = IsDynamicCall(info);

            if (isDynamicCall)
            {
                if (memberName != null)
                {
                    trapFile.dynamic_member_name(this, memberName);
                }
                else
                {
                    cx.ModelError(Syntax, "Unable to get name for dynamic call.");
                }
            }

            PopulateArguments(trapFile, Syntax.ArgumentList, child);

            if (target == null)
            {
                if (!isDynamicCall && !IsDelegateLikeCall(info))
                {
                    cx.ModelError(Syntax, "Unable to resolve target for call. (Compilation error?)");
                }
                return;
            }

            var targetKey = Method.Create(cx, target);

            trapFile.expr_call(this, targetKey);
        }