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 transform(self, expr):
     unary_expr = expr
     if unary_expr.operator == "!":
         self.main.process_expression(expr)
         type = unary_expr.operand.actual_type
         lit_types = self.main.current_file.literal_types
         if isinstance(type, astTypes.ClassType) and type.decl != lit_types.boolean.decl and type.decl != lit_types.numeric.decl:
             return exprs.BinaryExpression(unary_expr.operand, "==", exprs.NullLiteral())
     
     return expr
示例#3
0
    def class_(self, cls_):
        self.current_class = cls_
        res_list = []

        static_constructor_stmts = []
        complex_field_inits = []
        field_reprs = []
        prop_reprs = []
        for field in cls_.fields:
            is_initializer_complex = field.initializer != None and not (
                isinstance(field.initializer, exprs.StringLiteral)) and not (
                    isinstance(field.initializer,
                               exprs.BooleanLiteral)) and not (isinstance(
                                   field.initializer, exprs.NumericLiteral))

            prefix = f'''{self.vis(field.visibility)} {self.pre_if("static ", field.is_static)}'''
            if len(field.interface_declarations) > 0:
                var_type = self.var_type(field, field)
                name = self.name_(field.name)
                pname = self.uc_first(field.name)
                set_to_false = astTypes.TypeHelper.equals(
                    field.type,
                    self.current_class.parent_file.literal_types.boolean)
                prop_reprs.append(
                    f'''{var_type} {name}{(" = false" if set_to_false else f' = {self.expr(field.initializer)}' if field.initializer != None else "")};\n'''
                    +
                    f'''{prefix}{var_type} get{pname}() {{ return this.{name}; }}\n'''
                    +
                    f'''{prefix}void set{pname}({var_type} value) {{ this.{name} = value; }}'''
                )
            elif is_initializer_complex:
                if field.is_static:
                    static_constructor_stmts.append(
                        stats.ExpressionStatement(
                            exprs.BinaryExpression(
                                refs.StaticFieldReference(field), "=",
                                field.initializer)))
                else:
                    complex_field_inits.append(
                        stats.ExpressionStatement(
                            exprs.BinaryExpression(
                                refs.InstanceFieldReference(
                                    refs.ThisReference(cls_), field), "=",
                                field.initializer)))

                field_reprs.append(
                    f'''{prefix}{self.var_wo_init(field, field)};''')
            else:
                field_reprs.append(f'''{prefix}{self.var(field, field)};''')
        res_list.append("\n".join(field_reprs))
        res_list.append("\n\n".join(prop_reprs))

        for prop in cls_.properties:
            prefix = f'''{self.vis(prop.visibility)} {self.pre_if("static ", prop.is_static)}'''
            if prop.getter != None:
                res_list.append(
                    f'''{prefix}{self.type(prop.type)} get{self.uc_first(prop.name)}(){self.block(prop.getter, False)}'''
                )

            if prop.setter != None:
                res_list.append(
                    f'''{prefix}void set{self.uc_first(prop.name)}({self.type(prop.type)} value){self.block(prop.setter, False)}'''
                )

        if len(static_constructor_stmts) > 0:
            res_list.append(
                f'''static {{\n{self.pad(self.stmts(static_constructor_stmts))}\n}}'''
            )

        if cls_.constructor_ != None:
            constr_field_inits = []
            for field in list(
                    filter(lambda x: x.constructor_param != None,
                           cls_.fields)):
                field_ref = refs.InstanceFieldReference(
                    refs.ThisReference(cls_), field)
                mp_ref = refs.MethodParameterReference(field.constructor_param)
                # TODO: decide what to do with "after-TypeEngine" transformations
                mp_ref.set_actual_type(field.type, False, False)
                constr_field_inits.append(
                    stats.ExpressionStatement(
                        exprs.BinaryExpression(field_ref, "=", mp_ref)))

            super_call = f'''super({", ".join(list(map(lambda x: self.expr(x), cls_.constructor_.super_call_args)))});\n''' if cls_.constructor_.super_call_args != None else ""

            # @java var stmts = Stream.of(constrFieldInits, complexFieldInits, cls.constructor_.getBody().statements).flatMap(Collection::stream).toArray(Statement[]::new);
            # @java-import java.util.Collection
            # @java-import java.util.stream.Stream
            stmts = constr_field_inits + complex_field_inits + cls_.constructor_.body.statements

            # TODO: super calls
            res_list.append(
                self.method_gen(
                    "public " +
                    self.pre_if("/* throws */ ", cls_.constructor_.throws) +
                    self.name_(cls_.name), cls_.constructor_.parameters,
                    f'''\n{{\n{self.pad(super_call + self.stmts(stmts))}\n}}'''
                ))
        elif len(complex_field_inits) > 0:
            res_list.append(
                f'''public {self.name_(cls_.name)}()\n{{\n{self.pad(self.stmts(complex_field_inits))}\n}}'''
            )

        methods = []
        for method in cls_.methods:
            if method.body == None:
                continue
            # declaration only
            methods.append(self.method(method, True))
        res_list.append("\n\n".join(methods))
        return self.pad("\n\n".join(list(filter(lambda x: x != "", res_list))))
示例#4
0
    def class_like(self, cls_):
        self.current_class = cls_
        res_list = []

        static_constructor_stmts = []
        complex_field_inits = []
        if isinstance(cls_, types.Class):
            field_reprs = []
            for field in cls_.fields:
                is_initializer_complex = field.initializer != None and not (
                    isinstance(field.initializer, exprs.StringLiteral)
                ) and not (isinstance(
                    field.initializer, exprs.BooleanLiteral)) and not (
                        isinstance(field.initializer, exprs.NumericLiteral))

                prefix = f'''{self.vis(field.visibility)} {self.pre_if("static ", field.is_static)}'''
                if len(field.interface_declarations) > 0:
                    init = f''' = {self.expr(field.initializer)};''' if field.initializer != None else ""
                    field_reprs.append(
                        f'''{prefix}{self.var_wo_init(field, field)} {{ get; set; }}{init}'''
                    )
                elif is_initializer_complex:
                    if field.is_static:
                        static_constructor_stmts.append(
                            stats.ExpressionStatement(
                                exprs.BinaryExpression(
                                    refs.StaticFieldReference(field), "=",
                                    field.initializer)))
                    else:
                        complex_field_inits.append(
                            stats.ExpressionStatement(
                                exprs.BinaryExpression(
                                    refs.InstanceFieldReference(
                                        refs.ThisReference(cls_), field), "=",
                                    field.initializer)))

                    field_reprs.append(
                        f'''{prefix}{self.var_wo_init(field, field)};''')
                else:
                    field_reprs.append(
                        f'''{prefix}{self.var(field, field)};''')
            res_list.append("\n".join(field_reprs))

            res_list.append("\n".join(
                list(
                    map(
                        lambda prop:
                        f'''{self.vis(prop.visibility)} {self.pre_if("static ", prop.is_static)}'''
                        + self.var_wo_init(prop, prop) +
                        (f''' {{\n    get {{\n{self.pad(self.block(prop.getter))}\n    }}\n}}'''
                         if prop.getter != None else "") +
                        (f''' {{\n    set {{\n{self.pad(self.block(prop.setter))}\n    }}\n}}'''
                         if prop.setter != None else ""), cls_.properties))))

            if len(static_constructor_stmts) > 0:
                res_list.append(
                    f'''static {self.name_(cls_.name)}()\n{{\n{self.pad(self.stmts(static_constructor_stmts))}\n}}'''
                )

            if cls_.constructor_ != None:
                constr_field_inits = []
                for field in list(
                        filter(lambda x: x.constructor_param != None,
                               cls_.fields)):
                    field_ref = refs.InstanceFieldReference(
                        refs.ThisReference(cls_), field)
                    mp_ref = refs.MethodParameterReference(
                        field.constructor_param)
                    # TODO: decide what to do with "after-TypeEngine" transformations
                    mp_ref.set_actual_type(field.type, False, False)
                    constr_field_inits.append(
                        stats.ExpressionStatement(
                            exprs.BinaryExpression(field_ref, "=", mp_ref)))

                # @java var stmts = Stream.concat(Stream.concat(constrFieldInits.stream(), complexFieldInits.stream()), ((Class)cls).constructor_.getBody().statements.stream()).toArray(Statement[]::new);
                # @java-import java.util.stream.Stream
                stmts = constr_field_inits + complex_field_inits + cls_.constructor_.body.statements
                res_list.append(
                    "public " +
                    self.pre_if("/* throws */ ", cls_.constructor_.throws) +
                    self.name_(cls_.name) +
                    f'''({", ".join(list(map(lambda p: self.var(p, p), cls_.constructor_.parameters)))})'''
                    +
                    (f''': base({", ".join(list(map(lambda x: self.expr(x), cls_.constructor_.super_call_args)))})'''
                     if cls_.constructor_.super_call_args != None else "") +
                    f'''\n{{\n{self.pad(self.stmts(stmts))}\n}}''')
            elif len(complex_field_inits) > 0:
                res_list.append(
                    f'''public {self.name_(cls_.name)}()\n{{\n{self.pad(self.stmts(complex_field_inits))}\n}}'''
                )
        elif isinstance(cls_, types.Interface):
            res_list.append("\n".join(
                list(
                    map(
                        lambda field:
                        f'''{self.var_wo_init(field, field)} {{ get; set; }}''',
                        cls_.fields))))

        methods = []
        for method in cls_.methods:
            if isinstance(cls_, types.Class) and method.body == None:
                continue
            # declaration only
            methods.append(
                ("" if isinstance(method.parent_interface, types.Interface
                                  ) else self.vis(method.visibility) + " ") +
                self.pre_if("static ", method.is_static) + self.pre_if(
                    "virtual ", method.overrides == None
                    and len(method.overridden_by) > 0) +
                self.pre_if("override ", method.overrides != None) +
                self.pre_if("async ", method.async_) +
                self.pre_if("/* throws */ ", method.throws) +
                f'''{self.type(method.returns, False)} ''' +
                self.name_(method.name) +
                self.type_args(method.type_arguments) +
                f'''({", ".join(list(map(lambda p: self.var(p, None), method.parameters)))})'''
                +
                (f'''\n{{\n{self.pad(self.stmts(method.body.statements))}\n}}'''
                 if method.body != None else ";"))
        res_list.append("\n\n".join(methods))
        return self.pad("\n\n".join(list(filter(lambda x: x != "", res_list))))
 def class_like(self, cls_):
     self.current_class = cls_
     res_list = []
     
     static_constructor_stmts = []
     complex_field_inits = []
     if isinstance(cls_, types.Class):
         field_reprs = []
         for field in cls_.fields:
             is_initializer_complex = field.initializer != None and not (isinstance(field.initializer, exprs.StringLiteral)) and not (isinstance(field.initializer, exprs.BooleanLiteral)) and not (isinstance(field.initializer, exprs.NumericLiteral))
             
             prefix = f'''{self.vis(field.visibility, True)}{self.pre_if("static ", field.is_static)}'''
             if is_initializer_complex:
                 if field.is_static:
                     static_constructor_stmts.append(stats.ExpressionStatement(exprs.BinaryExpression(refs.StaticFieldReference(field), "=", field.initializer)))
                 else:
                     complex_field_inits.append(stats.ExpressionStatement(exprs.BinaryExpression(refs.InstanceFieldReference(refs.ThisReference(cls_), field), "=", field.initializer)))
                 
                 field_reprs.append(f'''{prefix}{self.var_wo_init(field, field)};''')
             else:
                 field_reprs.append(f'''{prefix}{self.var(field, field)};''')
         res_list.append("\n".join(field_reprs))
         
         for prop in cls_.properties:
             if prop.getter != None:
                 res_list.append(self.vis(prop.visibility, False) + self.pre_if("static ", prop.is_static) + f'''function get_{self.name_(prop.name)}(){self.block(prop.getter, False)}''')
             if prop.setter != None:
                 res_list.append(self.vis(prop.visibility, False) + self.pre_if("static ", prop.is_static) + f'''function set_{self.name_(prop.name)}($value){self.block(prop.setter, False)}''')
         
         if len(static_constructor_stmts) > 0:
             res_list.append(f'''static function StaticInit()\n{{\n{self.pad(self.stmts(static_constructor_stmts))}\n}}''')
         
         if cls_.constructor_ != None:
             constr_field_inits = []
             for field in list(filter(lambda x: x.constructor_param != None, cls_.fields)):
                 field_ref = refs.InstanceFieldReference(refs.ThisReference(cls_), field)
                 mp_ref = refs.MethodParameterReference(field.constructor_param)
                 # TODO: decide what to do with "after-TypeEngine" transformations
                 mp_ref.set_actual_type(field.type, False, False)
                 constr_field_inits.append(stats.ExpressionStatement(exprs.BinaryExpression(field_ref, "=", mp_ref)))
             
             parent_call = f'''parent::__construct({", ".join(list(map(lambda x: self.expr(x), cls_.constructor_.super_call_args)))});\n''' if cls_.constructor_.super_call_args != None else ""
             
             # @java var stmts = Stream.of(constrFieldInits, complexFieldInits, ((Class)cls).constructor_.getBody().statements).flatMap(Collection::stream).toArray(Statement[]::new);
             # @java-import java.util.Collection
             # @java-import java.util.stream.Stream
             stmts = constr_field_inits + complex_field_inits + cls_.constructor_.body.statements
             
             res_list.append(self.pre_if("/* throws */ ", cls_.constructor_.throws) + "function __construct" + f'''({", ".join(list(map(lambda p: self.var(p, p), cls_.constructor_.parameters)))})''' + f''' {{\n{self.pad(parent_call + self.stmts(stmts))}\n}}''')
         elif len(complex_field_inits) > 0:
             res_list.append(f'''function __construct()\n{{\n{self.pad(self.stmts(complex_field_inits))}\n}}''')
     elif isinstance(cls_, types.Interface):
         pass
     
     methods = []
     for method in cls_.methods:
         if isinstance(cls_, types.Class) and method.body == None:
             continue
         # declaration only
         methods.append(("" if isinstance(method.parent_interface, types.Interface) else self.vis(method.visibility, False)) + self.pre_if("static ", method.is_static) + self.pre_if("/* throws */ ", method.throws) + f'''function ''' + self.name_(method.name) + self.type_args(method.type_arguments) + f'''({", ".join(list(map(lambda p: self.var(p, None), method.parameters)))})''' + (f''' {{\n{self.pad(self.stmts(method.body.statements))}\n}}''' if method.body != None else ";"))
     res_list.append("\n\n".join(methods))
     
     res_list_joined = self.pad("\n\n".join(list(filter(lambda x: x != "", res_list))))
     return f''' {{\n{res_list_joined}\n}}''' + (f'''\n{self.name_(cls_.name)}::StaticInit();''' if len(static_constructor_stmts) > 0 else "")