def parse(self, precedence=0, required=True): self.reader.skip_whitespace() left_start = self.reader.offset left = self.parse_left(required) if left == None: return None self.add_node(left, left_start) while True: if self.hooks != None: parsed = self.hooks.infix_prehook(left) if parsed != None: left = parsed self.add_node(left, left_start) continue op = self.parse_operator() if op == None or op.precedence <= precedence: break self.reader.expect_token(op.text) op_text = self.config.aliases.get( op.text) if op.text in self.config.aliases else op.text if op.is_binary: right = self.parse(op.precedence - 1 if op.is_right_assoc else op.precedence) left = exprs.BinaryExpression(left, op_text, right) elif op.is_postfix: left = exprs.UnaryExpression(exprs.UNARY_TYPE.POSTFIX, op_text, left) elif op.text == "?": when_true = self.parse() self.reader.expect_token(":") when_false = self.parse(op.precedence - 1) left = exprs.ConditionalExpression(left, when_true, when_false) elif op.text == "(": args = self.parse_call_arguments() left = exprs.UnresolvedCallExpression(left, [], args) elif op.text == "[": element_expr = self.parse() self.reader.expect_token("]") left = exprs.ElementAccessExpression(left, element_expr) elif op.text in self.config.property_access_ops: prop = self.reader.expect_identifier( "expected identifier as property name") left = exprs.PropertyAccessExpression(left, prop) else: self.reader.fail( f'''parsing \'{op.text}\' is not yet implemented''') self.add_node(left, left_start) if isinstance(left, exprs.ParenthesizedExpression) and isinstance( left.expression, exprs.Identifier): expr = self.parse(0, False) if expr != None: return exprs.CastExpression( astTypes.UnresolvedType(left.expression.text, []), expr) return left
def visit_expression(self, expr): orig_expr = expr expr = super().visit_expression(expr) if isinstance(expr, exprs.BinaryExpression) and expr.operator == "in": expr = exprs.UnresolvedCallExpression( exprs.PropertyAccessExpression(expr.right, "hasKey"), [], [expr.left]) expr.parent_node = orig_expr.parent_node return expr
def transform(self, expr): # TODO: convert ElementAccess to ElementGet and ElementSet expressions if isinstance(expr, exprs.BinaryExpression) and isinstance( expr.left, exprs.ElementAccessExpression): expr.left.object = self.main.run_plugins_on(expr.left.object) if self.is_map_or_array_type(expr.left.object.get_type()): #const right = expr.operator === "=" ? expr.right : new BinaryExpression(<Expression>expr.left.clone(), expr.operator === "+=" ? "+" : "-", expr.right); return exprs.UnresolvedMethodCallExpression( expr.left.object, "set", [], [expr.left.element_expr, expr.right]) elif isinstance(expr, exprs.ElementAccessExpression): expr.object = self.main.run_plugins_on(expr.object) if self.is_map_or_array_type(expr.object.get_type()): return exprs.UnresolvedMethodCallExpression( expr.object, "get", [], [expr.element_expr]) elif isinstance(expr.element_expr, exprs.StringLiteral): return exprs.PropertyAccessExpression( expr.object, expr.element_expr.string_value) return expr