Example #1
0
        protected override void Populate()
        {
            var constantPattern = Syntax.Pattern as ConstantPatternSyntax;

            if (constantPattern != null)
            {
                Create(cx, Syntax.Expression, this, 0);
                Create(cx, constantPattern.Expression, this, 3);
                return;
            }

            var pattern = Syntax.Pattern as DeclarationPatternSyntax;

            if (pattern == null)
            {
                throw new InternalError(Syntax, "Is-pattern not handled");
            }

            Create(cx, Syntax.Expression, this, 0);
            TypeAccess.Create(cx, pattern.Type, this, 1);

            var symbol = cx.Model(Syntax).GetDeclaredSymbol(pattern.Designation) as ILocalSymbol;

            if (symbol != null)
            {
                var type  = Type.Create(cx, symbol.Type);
                var isVar = pattern.Type.IsVar;
                VariableDeclaration.Create(cx, symbol, type, cx.Create(pattern.GetLocation()), cx.Create(pattern.Designation.GetLocation()), isVar, this, 2);
            }
        }
Example #2
0
        public static Expression Create(ExpressionNodeInfo info)
        {
            var symbolInfo = info.Context.GetSymbolInfo(info.Node);

            var target = symbolInfo.Symbol;

            if (target == null && symbolInfo.CandidateReason == CandidateReason.OverloadResolutionFailure)
            {
                // The expression is probably a cast
                target = info.Context.GetSymbolInfo((CSharpSyntaxNode)info.Node.Parent).Symbol;
            }

            if (target == null && (symbolInfo.CandidateReason == CandidateReason.Ambiguous || symbolInfo.CandidateReason == CandidateReason.MemberGroup))
            {
                // Pick one at random - they probably resolve to the same ID
                target = symbolInfo.CandidateSymbols.First();
            }

            if (target == null)
            {
                info.Context.ModelError(info.Node, "Failed to resolve name");
                return(new Unknown(info));
            }

            // There is a very strange bug in Microsoft.CodeAnalysis whereby
            // target.Kind throws System.InvalidOperationException for Discard symbols.
            // So, short-circuit that test here.
            // Ideally this would be another case in the switch statement below.
            if (target is IDiscardSymbol)
            {
                return(new Discard(info));
            }

            switch (target.Kind)
            {
            case SymbolKind.TypeParameter:
            case SymbolKind.NamedType:
            case SymbolKind.DynamicType:
                return(TypeAccess.Create(info));

            case SymbolKind.Property:
            case SymbolKind.Field:
            case SymbolKind.Event:
            case SymbolKind.Method:
                return(Access.Create(info, target, true, info.Context.CreateEntity(target)));

            case SymbolKind.Local:
            case SymbolKind.RangeVariable:
                return(Access.Create(info, target, false, LocalVariable.Create(info.Context, target)));

            case SymbolKind.Parameter:
                return(Access.Create(info, target, false, Parameter.Create(info.Context, (IParameterSymbol)target)));

            case SymbolKind.Namespace:
                return(Access.Create(info, target, false, Namespace.Create(info.Context, (INamespaceSymbol)target)));

            default:
                throw new InternalError(info.Node, $"Unhandled identifier kind '{target.Kind}'");
            }
        }
Example #3
0
        protected override void PopulateExpression(TextWriter trapFile)
        {
            Create(Context, Syntax.Expression, this, ExpressionIndex);

            if (Kind == ExprKind.CAST)
            {  // Type cast
                TypeAccess.Create(new ExpressionNodeInfo(Context, Syntax.Type, this, TypeAccessIndex));
            }
            else
            {
                // Type conversion
                OperatorCall(trapFile, Syntax);
                TypeMention.Create(Context, Syntax.Type, this, Type);
            }
        }
Example #4
0
        protected override void Populate()
        {
            Create(cx, Syntax.Expression, this, 0);

            if (Kind == ExprKind.CAST)
            {
                // Type cast
                TypeAccess.Create(new ExpressionNodeInfo(cx, Syntax.Type, this, 1));
            }
            else
            {
                // Type conversion
                OperatorCall(Syntax);
                TypeMention.Create(cx, Syntax.Type, this, Type);
            }
        }
Example #5
0
        static Expression Create(ExpressionNodeInfo info, ExpressionSyntax expression, SimpleNameSyntax name)
        {
            if (IsDynamic(info.Context, expression))
            {
                var expr = new MemberAccess(info.SetKind(ExprKind.DYNAMIC_MEMBER_ACCESS), expression, null);
                info.Context.Emit(Tuples.dynamic_member_name(expr, name.Identifier.Text));
                return(expr);
            }

            var target = info.SymbolInfo;

            if (target.CandidateReason == CandidateReason.OverloadResolutionFailure)
            {
                // Roslyn workaround. Even if we can't resolve a method, we know it's a method.
                return(Create(info.Context, expression, info.Parent, info.Child));
            }

            var symbol = target.Symbol ?? info.Context.GetSymbolInfo(name).Symbol;

            if (symbol == null && target.CandidateSymbols.Length >= 1)
            {
                // Pick the first symbol. This could occur for something like `nameof(Foo.Bar)`
                // where `Bar` is a method group. Technically, we don't know which symbol is accessed.
                symbol = target.CandidateSymbols[0];
            }

            if (symbol == null)
            {
                info.Context.ModelError(info.Node, "Failed to determine symbol for member access");
                return(new MemberAccess(info.SetKind(ExprKind.UNKNOWN), expression, symbol));
            }

            ExprKind kind;

            switch (symbol.Kind)
            {
            case SymbolKind.Property:
                kind = ExprKind.PROPERTY_ACCESS;
                break;

            case SymbolKind.Method:
                kind = ExprKind.METHOD_ACCESS;
                break;

            case SymbolKind.Field:
                kind = ExprKind.FIELD_ACCESS;
                break;

            case SymbolKind.NamedType:
                return(TypeAccess.Create(info));

            case SymbolKind.Event:
                kind = ExprKind.EVENT_ACCESS;
                break;

            default:
                info.Context.ModelError(info.Node, "Unhandled symbol for member access");
                kind = ExprKind.UNKNOWN;
                break;
            }
            return(new MemberAccess(info.SetKind(kind), expression, symbol));
        }
Example #6
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));
                }
            }
        }
Example #7
0
 protected override void PopulateExpression(TextWriter trapFile)
 {
     TypeAccess.Create(cx, Syntax.Type, this, 0);
 }
Example #8
0
 protected override void Populate()
 {
     TypeAccess.Create(cx, Syntax.Type, this, 0);
 }
Example #9
0
 protected override void PopulateExpression(TextWriter trapFile)
 {
     TypeAccess.Create(Context, Syntax.Type, this, TypeAccessIndex);
 }