コード例 #1
0
        public void ExecuteAction()
        {
            IExpression exp = Parser.Parse(PropertyExpression);

            if (exp is PropertyAccessExpression)
            {
                IExpression expVal = Parser.Parse(ValueExpression);
                expVal.CheckSemantics(Parser.ParsingContext);


                PropertyAccessExpression paexp = (PropertyAccessExpression)exp;
                paexp.CheckSemantics(Parser.ParsingContext);

                if (paexp.ExpressionType != expVal.ExpressionType)
                {
                    throw new Exception.ActionExecutionException("Tipos incompatíveis");
                }

                paexp.Property.SetValue(paexp.ObjectExpression.Eval(), expVal.Eval(), null);
            }
            else
            {
                throw new Exception.ActionExecutionException("Não é uma propriedade");
            }
        }
コード例 #2
0
        private EntityExpression GetParentExpression(MemberExpression expr, out string memberName, out IType nhibernateType)
        {
            memberName     = null;
            nhibernateType = null;

            CollectionAccessExpression collectionExpr = expr.Expression as CollectionAccessExpression;

            if (collectionExpr != null)
            {
                return(null);
            }

            PropertyAccessExpression propExpr = expr.Expression as PropertyAccessExpression;

            if (propExpr != null)
            {
                memberName     = propExpr.Name + "." + expr.Member.Name;
                nhibernateType = propExpr.Expression.MetaData.GetPropertyType(memberName);
                return(propExpr.Expression);
            }

            EntityExpression entityExpr = expr.Expression as EntityExpression;

            if (entityExpr != null)
            {
                memberName     = expr.Member.Name;
                nhibernateType = entityExpr.MetaData.GetPropertyType(memberName);
                return(entityExpr);
            }

            return(null);
        }
コード例 #3
0
        protected override Expression VisitPropertyAccess(PropertyAccessExpression expr)
        {
            string memberName = MemberNameVisitor.GetMemberName(_rootCriteria, expr);

            _projections.Add(NHProjections.Property(memberName));
            return(expr);
        }
コード例 #4
0
        public void TwoStringList()
        {
            var node = new PropertyAccessExpression(new List <string> {
                "first", "second"
            });

            Assert.Equal("first.second", node.GetFormattedText());
        }
コード例 #5
0
        public void FourStringList()
        {
            var node = new PropertyAccessExpression(new List <string> {
                "first", "second", "third", "fourth"
            });

            Assert.Equal("first.second.third.fourth", node.GetFormattedText());
        }
コード例 #6
0
        public virtual Expression VisitPropertyAccessExpression(PropertyAccessExpression expression)
        {
            Check.NotNull(expression, "expression");

            _sql.Append(expression.Property.StorageName);

            return(expression);
        }
コード例 #7
0
        protected virtual Expression VisitPropertyAccess(PropertyAccessExpression expr)
        {
            EntityExpression e = (EntityExpression)Visit(expr.Expression);

            if (e != expr.Expression)
            {
                return(new PropertyAccessExpression(expr.Name, expr.Type, expr.NHibernateType, e));
            }
            return(expr);
        }
コード例 #8
0
        protected override Expression VisitPropertyAccess(PropertyAccessExpression expr)
        {
            expr = (PropertyAccessExpression)base.VisitPropertyAccess(expr);
            memberNameBuilder.Append(expr.Name + ".");

            currentExpression = expr;
            isQueringEntity   = false;

            return(expr);
        }
コード例 #9
0
        protected override Expression VisitPropertyAccess(PropertyAccessExpression expr)
        {
            if (expr.Type == typeof(bool))
            {
                string name = MemberNameVisitor.GetMemberName(rootCriteria, expr);
                CurrentCriterions.Add(Restrictions.Eq(name, true));
            }

            return(expr);
        }
コード例 #10
0
        public CSharpSyntaxNode Convert(Identifier node)
        {
            string text = node.Text;

            if (IdentifierMappings.ContainsKey(text))
            {
                text = IdentifierMappings[text];
            }

            if (text == "length" && node.Parent.Kind == NodeKind.PropertyAccessExpression)
            {
                PropertyAccessExpression parent = node.Parent as PropertyAccessExpression;
                Node type = TypeHelper.GetNodeType(parent.Expression);
                if (type != null)
                {
                    type = TypeHelper.TrimNullUnionType(type);
                    if (TypeHelper.IsStringType(type))
                    {
                        text = "Length";
                    }
                    else if (TypeHelper.IsArrayType(type))
                    {
                        if (type.Parent != null && type.Parent.Kind == NodeKind.Parameter && (type.Parent as Parameter).IsVariable)
                        {
                            text = "Length";
                        }
                        else
                        {
                            text = "Count";
                        }
                    }
                }
            }

            NameSyntax  csNameSyntax  = null;
            List <Node> typeArguments = node.Parent == null ? null : node.Parent.GetValue("TypeArguments") as List <Node>;
            List <Node> arguments     = node.Parent == null ? null : node.Parent.GetValue("Arguments") as List <Node>;

            if (typeArguments != null && typeArguments.Count > 0 && (arguments == null || !arguments.Contains(node))) //not in arguments
            {
                csNameSyntax = SyntaxFactory
                               .GenericName(text)
                               .AddTypeArgumentListArguments(typeArguments.ToCsNodes <TypeSyntax>());
            }
            else
            {
                csNameSyntax = SyntaxFactory.IdentifierName(text);
            }

            //
            return(this.As(csNameSyntax, node.As));
        }
コード例 #11
0
        protected Expression transformPA(PropertyAccessExpression expr)
        {
            if (expr.object_ is ClassReference classRef)
            {
                return(this.getStaticRef(classRef.decl, expr.propertyName));
            }

            if (expr.object_ is StaticThisReference statThisRef)
            {
                return(this.getStaticRef(statThisRef.cls, expr.propertyName));
            }

            expr.object_ = this.main.runPluginsOn(expr.object_);

            if (expr.object_ is ThisReference thisRef)
            {
                return(this.getInstanceRef(thisRef.cls, expr.propertyName, thisRef));
            }

            var type = expr.object_.getType();

            if (type is ClassType classType)
            {
                return(this.getInstanceRef(classType.decl, expr.propertyName, expr.object_));
            }
            else if (type is InterfaceType intType)
            {
                var ref_ = this.getInterfaceRef(intType.decl, expr.propertyName, expr.object_);
                if (ref_ == null)
                {
                    this.errorMan.throw_($"Could not resolve instance member access of a interface: {intType.repr()}::{expr.propertyName}");
                }
                return(ref_);
            }
            else if (type == null)
            {
                this.errorMan.throw_($"Type was not inferred yet (prop=\"{expr.propertyName}\")");
            }
            else if (type is AnyType)
            {
                //this.errorMan.throw(`Object has any type (prop="${expr.propertyName}")`);
                expr.setActualType(AnyType.instance);
            }
            else
            {
                this.errorMan.throw_($"Expected class as variable type, but got: {type.repr()} (prop=\"{expr.propertyName}\")");
            }

            return(expr);
        }
コード例 #12
0
        private bool WithInStaticMethod(PropertyAccessExpression node)
        {
            Node parent = node.Parent;

            while (parent != null)
            {
                if (parent.Kind == NodeKind.MethodDeclaration || parent.Kind == NodeKind.ClassDeclaration)
                {
                    break;
                }
                parent = parent.Parent;
            }

            return(!(parent is MethodDeclaration method) ? false : method.IsStatic);
        }
コード例 #13
0
        public CSharpSyntaxNode Convert(PropertyAccessExpression node)
        {
            Node parent = node.Parent;

            if (parent != null && parent.Kind == NodeKind.EnumMember && node.Text.Trim() == "Number.MAX_VALUE")
            {
                return(SyntaxFactory.MemberAccessExpression(
                           SyntaxKind.SimpleMemberAccessExpression,
                           SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
                           SyntaxFactory.IdentifierName("MaxValue")));
            }

            SimpleNameSyntax csName = null;

            if (parent != null)
            {
                Node        expression    = parent.GetValue("Expression") as Node;
                List <Node> typeArguments = parent.GetValue("TypeArguments") as List <Node>;
                if (expression != null && expression == node && typeArguments != null && typeArguments.Count > 0)
                {
                    csName = SyntaxFactory
                             .GenericName(node.Name.Text)
                             .AddTypeArgumentListArguments(typeArguments.ToCsNodes <TypeSyntax>());
                }
            }
            if (csName == null)
            {
                csName = node.Name.ToCsNode <SimpleNameSyntax>();
            }

            // omit this
            if (node.Expression.Kind == NodeKind.ThisKeyword && WithInStaticMethod(node))
            {
                return(csName);
            }
            // omit names(dv. core.)
            List <string> omittedNames = this.Context.Config.OmittedQualifiedNames;

            if (omittedNames.Count > 0 && omittedNames.Contains(node.Expression.Text.Trim()))
            {
                return(csName);
            }
            //
            MemberAccessExpressionSyntax accessExprSyntax = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, node.Expression.ToCsNode <ExpressionSyntax>(), csName);

            return(this.As(accessExprSyntax, node.As));
        }
コード例 #14
0
ファイル: Interpreter.cs プロジェクト: stanac/JsonPathway
        private static IEnumerable <JsonElement> ExecuteInternal(PropertyAccessExpression expr, JsonElement e)
        {
            if (expr.ChildProperties)
            {
                return(PropertyAccessor.GetChildPropertyValues(e));
            }
            else if (expr.RecursiveProperties)
            {
                return(PropertyAccessor.GetRecursiveProperties(e));
            }
            else if (expr.Properties != null && expr.Properties.Any())
            {
                return(PropertyAccessor.GetPropertyValueFromChain(e, expr.Properties));
            }

            throw new InvalidOperationException($"PropertyAccessExpression");
        }
コード例 #15
0
        private string AssociationPathForEntity(MemberExpression expr)
        {
            PropertyAccessExpression propExpr = expr.Expression as PropertyAccessExpression;

            if (propExpr != null)
            {
                return(propExpr.Name + "." + expr.Member.Name);
            }

            EntityExpression entityExpr = expr.Expression as EntityExpression;

            if (entityExpr != null && entityExpr.Expression != null)
            {
                return(entityExpr.Alias + "." + expr.Member.Name);
            }

            return(expr.Member.Name);
        }
コード例 #16
0
        private void NormalizeInstanceOf(BinaryExpression instanceOf)
        {
            Node leftNode     = instanceOf.Left;
            Node leftNodeType = TypeHelper.GetNodeType(leftNode);

            if (leftNodeType != null && TypeHelper.ToShortName(leftNodeType.Text) == "DataValueType")
            {
                PropertyAccessExpression newLeft = NodeHelper.CreateNode(NodeKind.PropertyAccessExpression) as PropertyAccessExpression;
                newLeft.Parent  = leftNode.Parent;
                leftNode.Parent = newLeft;

                newLeft.SetExpression(leftNode);
                newLeft.SetName(NodeHelper.CreateNode(NodeKind.Identifier, "Value"));
                instanceOf.SetLeft(newLeft);
                return;
            }

            NodeKind    variableKind = instanceOf.Left.Kind;
            string      variableName = instanceOf.Left.Text.Trim();
            string      typeName     = instanceOf.Right.Text;
            List <Node> asNodes      = new List <Node>();
            Node        parent       = instanceOf.Parent;

            while (parent != null)
            {
                if (parent.Kind == NodeKind.Block || parent.Kind == NodeKind.CaseBlock)
                {
                    break;
                }
                else if (parent.Kind == NodeKind.IfStatement)
                {
                    List <Node> multiInstanceOf = (parent as IfStatement).Expression.DescendantsAndSelf(n =>
                    {
                        if (n.Kind == NodeKind.BinaryExpression && n != instanceOf)
                        {
                            BinaryExpression binary = n as BinaryExpression;
                            return(binary.OperatorToken.Kind == NodeKind.InstanceOfKeyword && binary.Left.Text.Trim() == variableName);
                        }
                        return(false);
                    });
                    if (multiInstanceOf.Count == 0)
                    {
                        asNodes.AddRange((parent as IfStatement).ThenStatement.Descendants(n => n.Kind == variableKind && n.Text.Trim() == variableName));
                    }
                    break;
                }
                else if (parent.Kind == NodeKind.BinaryExpression)
                {
                    BinaryExpression binaryExpr           = parent as BinaryExpression;
                    bool             instanceOfIsLeftNode = (binaryExpr.Left.DescendantsAndSelfOnce(n => n == instanceOf).Count > 0);
                    if (instanceOfIsLeftNode)
                    {
                        asNodes.AddRange(binaryExpr.Right.Descendants(n =>
                        {
                            bool isInInstanceOf = (n.Parent.Kind == NodeKind.BinaryExpression && (n.Parent as BinaryExpression).OperatorToken.Kind == NodeKind.InstanceOfKeyword);
                            return(n.Kind == variableKind && n.Text.Trim() == variableName && !isInInstanceOf);
                        }));
                    }
                }
                parent = parent.Parent;
            }

            foreach (Node asNode in asNodes)
            {
                switch (asNode.Kind)
                {
                case NodeKind.Identifier:
                    if (asNode.Parent.Kind == NodeKind.PropertyAccessExpression)
                    {
                        if (asNode == (asNode.Parent as PropertyAccessExpression).Expression)
                        {
                            (asNode as Identifier).As = typeName;
                        }
                    }
                    else
                    {
                        (asNode as Identifier).As = typeName;
                    }
                    break;

                case NodeKind.PropertyAccessExpression:
                    if (!(asNode.Parent.Kind == NodeKind.BinaryExpression && (asNode.Parent as BinaryExpression).Left == asNode))
                    {
                        (asNode as PropertyAccessExpression).As = typeName;
                    }
                    break;

                default:
                    break;
                }
            }
        }
コード例 #17
0
 internal virtual void VisitPropertyAccessExpr(PropertyAccessExpression prop)
 {
 }
コード例 #18
0
 protected override Expression VisitPropertyAccess(PropertyAccessExpression expr)
 {
     Type = BinaryCriterionType.Property;
     return(expr);
 }
コード例 #19
0
        public Expression parse(int precedence = 0, bool required = true)
        {
            this.reader.skipWhitespace();
            var leftStart = this.reader.offset;
            var left      = this.parseLeft(required);

            if (left == null)
            {
                return(null);
            }
            this.addNode(left, leftStart);

            while (true)
            {
                if (this.hooks != null)
                {
                    var parsed = this.hooks.infixPrehook(left);
                    if (parsed != null)
                    {
                        left = parsed;
                        this.addNode(left, leftStart);
                        continue;
                    }
                }

                var op = this.parseOperator();
                if (op == null || op.precedence <= precedence)
                {
                    break;
                }
                this.reader.expectToken(op.text);
                var opText = this.config.aliases.hasKey(op.text) ? this.config.aliases.get(op.text) : op.text;

                if (op.isBinary)
                {
                    var right = this.parse(op.isRightAssoc ? op.precedence - 1 : op.precedence);
                    left = new BinaryExpression(left, opText, right);
                }
                else if (op.isPostfix)
                {
                    left = new UnaryExpression(UnaryType.Postfix, opText, left);
                }
                else if (op.text == "?")
                {
                    var whenTrue = this.parse();
                    this.reader.expectToken(":");
                    var whenFalse = this.parse(op.precedence - 1);
                    left = new ConditionalExpression(left, whenTrue, whenFalse);
                }
                else if (op.text == "(")
                {
                    var args = this.parseCallArguments();
                    left = new UnresolvedCallExpression(left, new IType[0], args);
                }
                else if (op.text == "[")
                {
                    var elementExpr = this.parse();
                    this.reader.expectToken("]");
                    left = new ElementAccessExpression(left, elementExpr);
                }
                else if (this.config.propertyAccessOps.includes(op.text))
                {
                    var prop = this.reader.expectIdentifier("expected identifier as property name");
                    left = new PropertyAccessExpression(left, prop);
                }
                else
                {
                    this.reader.fail($"parsing '{op.text}' is not yet implemented");
                }

                this.addNode(left, leftStart);
            }

            if (left is ParenthesizedExpression parExpr && parExpr.expression is Identifier ident)
            {
                var expr = this.parse(0, false);
                if (expr != null)
                {
                    return(new CastExpression(new UnresolvedType(ident.text, new IType[0]), expr));
                }
            }

            return(left);
        }
コード例 #20
0
 protected virtual Expression VisitPropertyAccess(PropertyAccessExpression node) => base.VisitExtension(node);
コード例 #21
0
        public void TwoStringParams()
        {
            var node = new PropertyAccessExpression("first", "second");

            Assert.Equal("first.second", node.GetFormattedText());
        }
コード例 #22
0
 protected override Expression VisitPropertyAccess(PropertyAccessExpression expr)
 {
     Type = BinaryCriterionType.Property;
     Name = MemberNameVisitor.GetMemberName(rootCriteria, expr);
     return(expr);
 }
コード例 #23
0
        public void BlockProcess(DecompileContext context, Block block,
                                 Dictionary <int, Expression> exps)
        {
            if (block.Statements != null)
            {
                return;
            }

            if (block.From.Count > 1)
            {
                //get from.Output && from.Def
                var commonInput = block.From.Select(b => b.Output).Union(block.From.Select(b => b.Def)).GetIntersection();
                commonInput.IntersectWith(block.Input);
                //flag can be phi
                if (commonInput.Count > 0)
                {
                    foreach (var inSlot in commonInput)
                    {
                        //Generate Phi
                        var phi = new PhiExpression(inSlot);
                        //From must be sorted since we need first condition
                        if (block.From[0].Statements?.Last() is ConditionExpression condition)
                        {
                            phi.Condition = condition;
                            //var thenBlock = context.BlockTable[condition.JumpTo];
                            var elseBlock = context.BlockTable[condition.ElseTo];
                            //phi.ThenBranch = context.BlockFinalStates[trueBlock][inSlot];
                            phi.ThenBranch =
                                context.BlockFinalStates[block.From[0]]
                                [inSlot];     //if jump, use the state from the jump-from block
                            phi.ElseBranch = context.BlockFinalStates[elseBlock][inSlot];
                            //Next: Merge condition: if (v1) then v1 else v2 => v1 || v2 (infer v1 is bool)
                            if (phi.ThenBranch != phi.ElseBranch)
                            {
                                exps[inSlot] = phi;
                            }
                        }
                    }
                }
            }

            Expression retExp  = null;
            var        ex      = new Dictionary <int, Expression>(exps);
            var        flag    = ex.ContainsKey(Const.FlagReg) ? ex[Const.FlagReg] : null;
            var        expList = new List <IAstNode>();

            block.Statements = expList;
            InstructionData insData = null;

            for (var i = 0; i < block.Instructions.Count; i++)
            {
                ex[0] = Void;
                var ins = block.Instructions[i];
                insData = block.InstructionDatas[i];

                switch (ins.OpCode)
                {
                case OpCode.NOP:
                    break;

                case OpCode.CONST:
                {
                    var data     = (OperandData)ins.Data;
                    var constExp = new ConstantExpression(data.Variant);
                    ex[ins.GetRegisterSlot(0)] = constExp;
                }
                break;

                case OpCode.CL:
                {
                    ex[ins.GetRegisterSlot(0)] = null;
                }
                break;

                case OpCode.CCL:
                    break;

                case OpCode.CEQ:
                case OpCode.CDEQ:
                case OpCode.CLT:
                case OpCode.CGT:
                {
                    var      left  = ex[ins.GetRegisterSlot(0)];
                    var      right = ex[ins.GetRegisterSlot(1)];
                    BinaryOp op    = BinaryOp.Unknown;
                    switch (ins.OpCode)
                    {
                    case OpCode.CEQ:
                        op = BinaryOp.Equal;
                        break;

                    case OpCode.CDEQ:
                        op = BinaryOp.Congruent;
                        break;

                    case OpCode.CLT:
                        op = BinaryOp.LessThan;
                        break;

                    case OpCode.CGT:
                        op = BinaryOp.GreaterThan;
                        break;
                    }

                    var b = new BinaryExpression(left, right, op);
                    flag = b;
                }
                break;

                case OpCode.SETF:
                case OpCode.SETNF:
                {
                    var dst = ins.GetRegisterSlot(0);
                    switch (ins.OpCode)
                    {
                    case OpCode.SETF:
                        ex[dst] = flag;
                        break;

                    case OpCode.SETNF:
                        ex[dst] = flag.Invert();
                        break;
                    }
                }
                break;

                case OpCode.TT:
                {
                    flag = ex[ins.GetRegisterSlot(0)];
                }
                break;

                case OpCode.TF:
                {
                    flag = ex[ins.GetRegisterSlot(0)].Invert();
                }
                break;

                case OpCode.NF:
                {
                    flag = flag.Invert();
                }
                break;

                case OpCode.JF:
                case OpCode.JNF:
                {
                    bool jmpFlag = ins.OpCode == OpCode.JF;
                    expList.Add(new ConditionExpression(flag, jmpFlag)
                        {
                            JumpTo = ((JumpData)ins.Data).Goto.Line, ElseTo = ins.Line + 1
                        });
                }
                break;

                case OpCode.JMP:
                {
                    expList.Add(new GotoExpression {
                            JumpTo = ((JumpData)ins.Data).Goto.Line
                        });
                }
                break;

                case OpCode.CHS:
                case OpCode.INT:
                case OpCode.REAL:
                case OpCode.STR:
                case OpCode.NUM:
                case OpCode.OCTET:
                case OpCode.LNOT:
                case OpCode.INC:
                case OpCode.DEC:
                case OpCode.BNOT:
                case OpCode.TYPEOF:
                case OpCode.INV:
                {
                    var dstSlot = ins.GetRegisterSlot(0);
                    var dst     = ex[dstSlot];
                    var op      = UnaryOp.Unknown;
                    switch (ins.OpCode)
                    {
                    case OpCode.INC:
                        op = UnaryOp.Inc;
                        break;

                    case OpCode.DEC:
                        op = UnaryOp.Dec;
                        break;

                    case OpCode.CHS:
                        op = UnaryOp.InvertSign;
                        break;

                    case OpCode.INT:
                        op = UnaryOp.ToInt;
                        break;

                    case OpCode.REAL:
                        op = UnaryOp.ToReal;
                        break;

                    case OpCode.STR:
                        op = UnaryOp.ToString;
                        break;

                    case OpCode.NUM:
                        op = UnaryOp.ToNumber;
                        break;

                    case OpCode.BNOT:
                        op = UnaryOp.BitNot;
                        break;

                    case OpCode.OCTET:
                        op = UnaryOp.ToByteArray;
                        break;

                    case OpCode.LNOT:
                        op = UnaryOp.Not;
                        break;

                    case OpCode.TYPEOF:
                        op = UnaryOp.TypeOf;
                        break;

                    case OpCode.INV:
                        op = UnaryOp.Invalidate;
                        break;
                    }

                    var u = new UnaryExpression(dst, op);
                    //ex[dstSlot] = u;
                    expList.Add(u);
                }
                break;

                case OpCode.INCPD:
                case OpCode.DECPD:
                case OpCode.TYPEOFD:
                {
                    var res  = ins.GetRegisterSlot(0);
                    var obj  = ins.GetRegisterSlot(1);
                    var name = ins.Data.AsString();
                    var op   = UnaryOp.Unknown;
                    switch (ins.OpCode)
                    {
                    case OpCode.INCPI:
                        op = UnaryOp.Inc;
                        break;

                    case OpCode.DECPI:
                        op = UnaryOp.Dec;
                        break;

                    case OpCode.TYPEOFD:
                        op = UnaryOp.TypeOf;
                        break;
                    }

                    //var u = new UnaryExpression(new IdentifierExpression(name), op) {Instance = ex[obj]};
                    var u = new UnaryExpression(new IdentifierExpression(name)
                        {
                            Instance = ex[obj]
                        }, op);
                    if (res != 0)     //copy to %res
                    {
                        ex[res] = u;
                    }

                    expList.Add(u);
                }
                break;

                case OpCode.INCPI:
                case OpCode.DECPI:
                case OpCode.TYPEOFI:
                {
                    var res  = ins.GetRegisterSlot(0);
                    var obj  = ins.GetRegisterSlot(1);
                    var name = ins.GetRegisterSlot(2);
                    var op   = UnaryOp.Unknown;
                    switch (ins.OpCode)
                    {
                    case OpCode.INCPI:
                        op = UnaryOp.Inc;
                        break;

                    case OpCode.DECPI:
                        op = UnaryOp.Dec;
                        break;

                    case OpCode.TYPEOFI:
                        op = UnaryOp.TypeOf;
                        break;
                    }

                    var u = new UnaryExpression(new PropertyAccessExpression(ex[name], ex[obj]), op);
                    if (res != 0)     //copy to %res
                    {
                        ex[res] = u;
                    }

                    expList.Add(u);
                }
                break;

                case OpCode.INCP:
                case OpCode.DECP:
                    break;

                case OpCode.LORP:
                    break;

                case OpCode.LANDP:
                    break;

                case OpCode.BORP:
                    break;

                case OpCode.BXORP:
                    break;

                case OpCode.BANDP:
                    break;

                case OpCode.SARP:
                    break;

                case OpCode.SALP:
                    break;

                case OpCode.SRP:
                    break;

                case OpCode.CP:
                {
                    var dstSlot = ins.GetRegisterSlot(0);
                    var srcSlot = ins.GetRegisterSlot(1);

                    Expression src;
                    if (ex.ContainsKey(srcSlot))
                    {
                        src = ex[srcSlot];
                    }
                    else
                    {
                        src = new LocalExpression(context.Object, srcSlot);
                    }

                    Expression dst = null;
                    if (ex.ContainsKey(dstSlot))
                    {
                        //dst = ex[dstSlot];
                        ex[dstSlot] = src;
                    }
                    else if (dstSlot < -2)
                    {
                        var l = new LocalExpression(context.Object, dstSlot);
                        //if (!l.IsParameter)
                        //{
                        //    expList.Add(l);
                        //}
                        dst         = l;
                        ex[dstSlot] = l;     //assignment -> statements, local -> expressions

                        BinaryExpression b = new BinaryExpression(dst, src, BinaryOp.Assign)
                        {
                            IsDeclaration = true
                        };
                        //ex[dstSlot] = b;
                        expList.Add(b);
                    }
                    else if (dstSlot != 0)
                    {
                        ex[dstSlot] = src;
                    }
                }
                break;

                //Binary Operation
                case OpCode.ADD:
                case OpCode.SUB:
                case OpCode.MOD:
                case OpCode.DIV:
                case OpCode.IDIV:
                case OpCode.MUL:
                case OpCode.BAND:
                case OpCode.BOR:
                case OpCode.BXOR:
                case OpCode.LAND:
                case OpCode.LOR:
                case OpCode.SAR:
                case OpCode.SAL:
                case OpCode.SR:
                case OpCode.CHKINS:
                {
                    var dstSlot = ins.GetRegisterSlot(0);
                    var srcSlot = ins.GetRegisterSlot(1);
                    var store   = false;   //Set to Expression
                    var declare = false;   //Is declaration

                    Expression dst = null;
                    if (ex.ContainsKey(dstSlot))
                    {
                        dst = ex[dstSlot];
                    }
                    else if (dstSlot < -2)
                    {
                        var l = new LocalExpression(context.Object, dstSlot);
                        //if (!l.IsParameter)
                        //{
                        //    expList.Add(l);
                        //}
                        dst         = l;
                        ex[dstSlot] = l;
                        store       = false;
                        declare     = true;
                    }

                    Expression src;
                    if (ex.ContainsKey(srcSlot))
                    {
                        src = ex[srcSlot];
                    }
                    else
                    {
                        src = new LocalExpression(context.Object, srcSlot);
                    }

                    var op = BinaryOp.Unknown;
                    switch (ins.OpCode)
                    {
                    case OpCode.ADD:
                        op = BinaryOp.Add;
                        break;

                    case OpCode.SUB:
                        op = BinaryOp.Sub;
                        break;

                    case OpCode.MOD:
                        op = BinaryOp.Mod;
                        break;

                    case OpCode.DIV:
                        op = BinaryOp.Div;
                        break;

                    case OpCode.IDIV:
                        op = BinaryOp.Idiv;
                        break;

                    case OpCode.MUL:
                        op = BinaryOp.Mul;
                        break;

                    case OpCode.BAND:
                        op = BinaryOp.BitAnd;
                        break;

                    case OpCode.BOR:
                        op = BinaryOp.BitOr;
                        break;

                    case OpCode.BXOR:
                        op = BinaryOp.BitXor;
                        break;

                    case OpCode.LAND:
                        op = BinaryOp.LogicAnd;
                        break;

                    case OpCode.LOR:
                        op = BinaryOp.LogicOr;
                        break;

                    case OpCode.SAR:
                        op = BinaryOp.NumberShiftRight;
                        break;

                    case OpCode.SAL:
                        op = BinaryOp.NumberShiftLeft;
                        break;

                    case OpCode.SR:
                        op = BinaryOp.BitShiftRight;
                        break;

                    //case OpCode.CP: //moved!
                    //    op = BinaryOp.Assign;
                    //    push = true;
                    //break;
                    case OpCode.CHKINS:
                        op = BinaryOp.InstanceOf;
                        break;
                    }

                    BinaryExpression b = new BinaryExpression(dst, src, op)
                    {
                        IsDeclaration = declare
                    };

                    if (store)
                    {
                        ex[dstSlot] = b;
                    }

                    expList.Add(b);
                }
                break;

                case OpCode.ADDPD:
                case OpCode.SUBPD:
                case OpCode.MODPD:
                case OpCode.DIVPD:
                case OpCode.IDIVPD:
                case OpCode.MULPD:
                case OpCode.BANDPD:
                case OpCode.BORPD:
                case OpCode.BXORPD:
                case OpCode.LANDPD:
                case OpCode.LORPD:
                case OpCode.SARPD:
                case OpCode.SALPD:
                case OpCode.SRPD:
                {
                    var res  = ins.GetRegisterSlot(0);
                    var obj  = ins.GetRegisterSlot(1);
                    var name = ins.Data.AsString();
                    var op   = BinaryOp.Unknown;

                    var src = ex[ins.GetRegisterSlot(3)];
                    switch (ins.OpCode)
                    {
                    case OpCode.ADDPD:
                        op = BinaryOp.Add;
                        break;

                    case OpCode.SUBPD:
                        op = BinaryOp.Sub;
                        break;

                    case OpCode.MODPD:
                        op = BinaryOp.Mod;
                        break;

                    case OpCode.DIVPD:
                        op = BinaryOp.Div;
                        break;

                    case OpCode.IDIVPD:
                        op = BinaryOp.Idiv;
                        break;

                    case OpCode.MULPD:
                        op = BinaryOp.Mul;
                        break;

                    case OpCode.BANDPD:
                        op = BinaryOp.BitAnd;
                        break;

                    case OpCode.BORPD:
                        op = BinaryOp.BitOr;
                        break;

                    case OpCode.BXORPD:
                        op = BinaryOp.BitXor;
                        break;

                    case OpCode.LANDPD:
                        op = BinaryOp.LogicAnd;
                        break;

                    case OpCode.LORPD:
                        op = BinaryOp.LogicOr;
                        break;

                    case OpCode.SARPD:
                        op = BinaryOp.NumberShiftRight;
                        break;

                    case OpCode.SALPD:
                        op = BinaryOp.NumberShiftLeft;
                        break;

                    case OpCode.SRPD:
                        op = BinaryOp.BitShiftRight;
                        break;
                    }

                    BinaryExpression b = new BinaryExpression(new IdentifierExpression(name)
                        {
                            Instance = ex[obj]
                        },
                                                              src, op);

                    if (res != 0)
                    {
                        ex[res] = b;
                    }

                    expList.Add(b);
                }
                break;

                case OpCode.ADDPI:
                case OpCode.SUBPI:
                case OpCode.MODPI:
                case OpCode.DIVPI:
                case OpCode.IDIVPI:
                case OpCode.MULPI:
                case OpCode.BANDPI:
                case OpCode.BORPI:
                case OpCode.BXORPI:
                case OpCode.LANDPI:
                case OpCode.LORPI:
                case OpCode.SARPI:
                case OpCode.SALPI:
                case OpCode.SRPI:
                {
                    var res  = ins.GetRegisterSlot(0);
                    var obj  = ins.GetRegisterSlot(1);
                    var name = ins.GetRegisterSlot(2);
                    var op   = BinaryOp.Unknown;

                    var src = ex[ins.GetRegisterSlot(3)];
                    switch (ins.OpCode)
                    {
                    case OpCode.ADDPI:
                        op = BinaryOp.Add;
                        break;

                    case OpCode.SUBPI:
                        op = BinaryOp.Sub;
                        break;

                    case OpCode.MODPI:
                        op = BinaryOp.Mod;
                        break;

                    case OpCode.DIVPI:
                        op = BinaryOp.Div;
                        break;

                    case OpCode.IDIVPI:
                        op = BinaryOp.Idiv;
                        break;

                    case OpCode.MULPI:
                        op = BinaryOp.Mul;
                        break;

                    case OpCode.BANDPI:
                        op = BinaryOp.BitAnd;
                        break;

                    case OpCode.BORPI:
                        op = BinaryOp.BitOr;
                        break;

                    case OpCode.BXORPI:
                        op = BinaryOp.BitXor;
                        break;

                    case OpCode.LANDPI:
                        op = BinaryOp.LogicAnd;
                        break;

                    case OpCode.LORPI:
                        op = BinaryOp.LogicOr;
                        break;

                    case OpCode.SARPI:
                        op = BinaryOp.NumberShiftRight;
                        break;

                    case OpCode.SALPI:
                        op = BinaryOp.NumberShiftLeft;
                        break;

                    case OpCode.SRPI:
                        op = BinaryOp.BitShiftRight;
                        break;
                    }

                    BinaryExpression b =
                        new BinaryExpression(new PropertyAccessExpression(ex[name], ex[obj]), src, op);

                    if (res != 0)
                    {
                        ex[res] = b;
                    }

                    expList.Add(b);
                }
                break;

                case OpCode.ADDP:
                    break;

                case OpCode.SUBP:
                    break;

                case OpCode.MODP:
                    break;

                case OpCode.DIVP:
                    break;

                case OpCode.IDIVP:
                    break;

                case OpCode.MULP:
                    break;

                case OpCode.EVAL:
                    break;

                case OpCode.EEXP:
                    break;

                case OpCode.ASC:
                    break;

                case OpCode.CHR:
                    break;

                case OpCode.CHKINV:
                    break;

                //Invoke
                case OpCode.CALL:
                {
                    var call = new InvokeExpression(((OperandData)ins.Data).Variant as TjsCodeObject);
                    var dst  = ins.GetRegisterSlot(0);
                    call.Instance = null;
                    var paramCount = ins.GetRegisterSlot(2);
                    if (paramCount == -1)
                    {
                        //...
                        //do nothing
                    }
                    else
                    {
                        for (int j = 0; j < paramCount; j++)
                        {
                            var pSlot = ins.GetRegisterSlot(3 + j);
                            call.Parameters.Add(ex[pSlot]);
                        }
                    }

                    ex[dst] = call;
                    //if (dst == 0) //just execute and discard result
                    //{
                    //    expList.Add(call);
                    //}
                    expList.Add(call);
                }
                break;

                case OpCode.CALLD:
                {
                    var callMethodName = ins.Data.AsString();
                    var call           = new InvokeExpression(callMethodName);
                    var dst            = ins.GetRegisterSlot(0);
                    var callerSlot     = ins.GetRegisterSlot(1);
                    call.Instance = ex[callerSlot];
                    var paramCount = ins.GetRegisterSlot(3);
                    if (paramCount == -1)
                    {
                        //...
                        //do nothing
                    }
                    else
                    {
                        for (int j = 0; j < paramCount; j++)
                        {
                            var pSlot = ins.GetRegisterSlot(4 + j);
                            ex[pSlot].Parent = call;
                            call.Parameters.Add(ex[pSlot]);
                        }
                    }

                    ex[dst] = call;
                    if (dst == 0)     //just execute and discard result
                    {
                        //Handle RegExp()._compile("//g/[^A-Za-z]")
                        if (callMethodName == Const.RegExpCompile)
                        {
                            if (call.Instance is InvokeExpression invoke && invoke.Method == Const.RegExp)
                            {
                                call.InvokeType = InvokeType.RegExpCompile;
                                ex[callerSlot]  = call;
                                break;
                            }
                        }

                        expList.Add(call);
                    }
                }
                break;

                case OpCode.CALLI:
                {
                    //InvokeExpression call = null;
                    //var operand = ((OperandData) ins.Data).Variant;
                    //if (operand is TjsString str)
                    //{
                    //    call = new InvokeExpression(str.StringValue);
                    //}
                    //else
                    //{
                    //    call = new InvokeExpression(operand as TjsCodeObject);
                    //}
                    InvokeExpression call = new InvokeExpression(ex[ins.GetRegisterSlot(2)]);
                    var dst        = ins.GetRegisterSlot(0);
                    var callerSlot = ins.GetRegisterSlot(1);
                    call.Instance = ex[callerSlot];
                    var paramCount = ins.GetRegisterSlot(3);
                    if (paramCount == -1)
                    {
                        //...
                        //do nothing
                    }
                    else
                    {
                        for (int j = 0; j < paramCount; j++)
                        {
                            var pSlot = ins.GetRegisterSlot(4 + j);
                            ex[pSlot].Parent = call;
                            call.Parameters.Add(ex[pSlot]);
                        }
                    }

                    ex[dst] = call;
                    //if (dst == 0) //just execute and discard result
                    //{
                    //    expList.Add(call);
                    //}
                    expList.Add(call);
                }
                break;

                case OpCode.NEW:
                {
                    InvokeExpression call = new InvokeExpression(ex[ins.GetRegisterSlot(1)])
                    {
                        InvokeType = InvokeType.Ctor
                    };
                    var dst = ins.GetRegisterSlot(0);
                    call.Instance = null;
                    var paramCount = ins.GetRegisterSlot(2);
                    if (paramCount == -1)
                    {
                        //...
                        //do nothing
                    }
                    else
                    {
                        for (int j = 0; j < paramCount; j++)
                        {
                            var pSlot = ins.GetRegisterSlot(3 + j);
                            ex[pSlot].Parent = call;
                            call.Parameters.Add(ex[pSlot]);
                        }
                    }

                    ex[dst] = call;
                    //if (dst == 0) //just execute and discard result
                    //{
                    //    expList.Add(call);
                    //}
                    expList.Add(call);
                }
                break;

                case OpCode.GPD:
                case OpCode.GPDS:
                {
                    var dst      = ins.GetRegisterSlot(0);
                    var slot     = ins.GetRegisterSlot(1);
                    var instance = ex[slot];
                    var name     = ins.Data.AsString();
                    var newId    = new IdentifierExpression(name)
                    {
                        Instance = instance
                    };
                    ex[dst] = newId;
                }
                break;

                case OpCode.GPI:
                case OpCode.GPIS:
                {
                    var dst  = ins.GetRegisterSlot(0);
                    var obj  = ins.GetRegisterSlot(1);
                    var name = ins.GetRegisterSlot(2);

                    PropertyAccessExpression p = new PropertyAccessExpression(ex[name], ex[obj]);
                    ex[dst] = p;
                }
                break;

                case OpCode.SPI:
                case OpCode.SPIE:
                case OpCode.SPIS:
                {
                    var obj  = ins.GetRegisterSlot(0);
                    var name = ins.GetRegisterSlot(1);
                    var src  = ins.GetRegisterSlot(2);

                    BinaryExpression b = new BinaryExpression(new PropertyAccessExpression(ex[name], ex[obj]),
                                                              ex[src], BinaryOp.Assign);
                    expList.Add(b);     //there is no other way to find this expression
                }
                break;

                //Set
                case OpCode.SPD:
                case OpCode.SPDE:
                case OpCode.SPDEH:
                case OpCode.SPDS:
                {
                    var left = new IdentifierExpression(ins.Data.AsString())
                    {
                        Instance = ex[ins.GetRegisterSlot(0)]
                    };
                    var right          = ex[ins.GetRegisterSlot(2)];
                    BinaryExpression b = new BinaryExpression(left, right, BinaryOp.Assign);
                    //check declare
                    if (context.Object.ContextType == TjsContextType.TopLevel)
                    {
                        if (!context.RegisteredMembers.ContainsKey(left.Name))
                        {
                            b.IsDeclaration = true;
                            var stub = new TjsStub();
                            if (right is ConstantExpression con)     //TODO: better type check
                            {
                                stub.Type = con.DataType;
                            }

                            context.RegisteredMembers[left.Name] = stub;
                        }
                    }

                    expList.Add(b);
                }
                break;

                case OpCode.SETP:
                {
                }
                break;

                case OpCode.GETP:
                {
                }
                break;

                //Delete
                case OpCode.DELD:
                    DeleteExpression d = new DeleteExpression(ins.Data.AsString());
                    d.Instance = ex[ins.GetRegisterSlot(1)];
                    expList.Add(d);
                    break;

                case OpCode.DELI:
                    DeleteExpression d2 = new DeleteExpression(ex[ins.GetRegisterSlot(2)]);
                    d2.Instance = ex[ins.GetRegisterSlot(1)];
                    //Check declare
                    if (d2.Instance is IdentifierExpression toDel)
                    {
                        if (context.RegisteredMembers.ContainsKey(toDel.Name))
                        {
                            context.RegisteredMembers.Remove(toDel.Name);
                        }
                    }

                    expList.Add(d2);
                    break;

                case OpCode.SRV:
                {
                    var srv = ins.GetRegisterSlot(0);
                    retExp = srv == 0 ? null : ex[srv];
                }
                break;

                case OpCode.RET:
                {
                    expList.Add(new ReturnExpression(retExp));
                }
                break;

                case OpCode.ENTRY:
                    break;

                case OpCode.EXTRY:
                    break;

                case OpCode.THROW:
                {
                    var th = new ThrowExpression(ex[ins.GetRegisterSlot(0)]);
                    expList.Add(th);
                }
                break;

                case OpCode.CHGTHIS:
                    break;

                case OpCode.GLOBAL:
                {
                    ex[ins.GetRegisterSlot(0)] = Global;
                }
                break;

                case OpCode.ADDCI:
                    break;

                case OpCode.REGMEMBER:
                    break;

                case OpCode.DEBUGGER:
                    break;

                case OpCode.LAST:
                    break;

                case OpCode.PreDec:
                    break;

                case OpCode.PostInc:
                    break;

                case OpCode.PostDec:
                    break;

                case OpCode.Delete:
                    break;

                case OpCode.FuncCall:
                    break;

                case OpCode.IgnorePropGet:
                    break;

                case OpCode.IgnorePropSet:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            expList.RemoveAll(node => node is Expression exp && exp.Parent != null);

            //Save states
            ex[Const.FlagReg] = flag;
            context.BlockFinalStates[block] = ex;

            //Process next
            foreach (var succ in block.To)
            {
                BlockProcess(context, succ, ex); //TODO: deep copy flag?
            }
        }
コード例 #24
0
        private IExpression ParseUnaryExpression(ref IToken token)
        {
            IExpression unaryExpression = ParseLiteralExpression(ref token);

            if (unaryExpression != null)
            {
                token = tokenParser.GetNextToken();
            }
            else if (token is MinusToken)
            {
                token = tokenParser.GetNextToken();
                return(new UnaryMinusExpression(ParseUnaryExpression(ref token)));
            }
            else if (token is IdentifierToken)
            {
                IdentifierToken idToken = token as IdentifierToken;
                token = tokenParser.GetNextToken();
                if (token is OpenParenthesisToken)
                {
                    try
                    {
                        ParameterExpression[] args = ParseArgumentList(ref token);
                        unaryExpression = new FunctionExpression(idToken, args);
                    }
                    catch (SyntaxErrorException e)
                    {
                        throw new SyntaxErrorException(e.Message, e, e.Expression, new FunctionExpression(idToken, e.Args));
                    }
                }
                else if (token is LambdaInvokeToken)
                {
                    try
                    {
                        token = tokenParser.GetNextToken();
                        IExpression rightExpression = ParseExpression(ref token);
                        unaryExpression = new LambdaExpression(idToken, rightExpression);
                    }
                    catch (SyntaxErrorException e)
                    {
                        throw new SyntaxErrorException(e.Message, e, e.Expression, new LambdaExpression(idToken, e.RootExpression));
                    }
                }
                else
                {
                    unaryExpression = new IdentifierExpression(idToken);
                }
            }
            else if (token is OpenParenthesisToken)
            {
                token = tokenParser.GetNextToken();
                IExpression complexExpression = ParseLogicalOrExpression(ref token);
                if (!(token is CloseParenthesisToken))
                {
                    throw new SyntaxErrorException("')' experado.");
                }
                token           = tokenParser.GetNextToken();
                unaryExpression = complexExpression;
            }
            else
            {
                throw new SyntaxErrorException("expressão esperada.");
            }

            //decide se é uma propery access expression
            while (token is DotToken)
            {
                token = tokenParser.GetNextToken();
                if (!(token is IdentifierToken))
                {
                    token = tokenParser.GetNextToken();
                    throw new SyntaxErrorException("identificador esperado", unaryExpression, unaryExpression);
                }

                IdentifierToken id = token as IdentifierToken;
                unaryExpression = new PropertyAccessExpression(unaryExpression, id.IdentifierName);

                token = tokenParser.GetNextToken();
            }

            return(unaryExpression);
        }