Exemplo n.º 1
0
    def visit_identifier(self, id):
        super().visit_identifier(id)
        symbol = self.symbol_lookup.get_symbol(id.text)
        if symbol == None:
            self.error_man.throw(
                f'''Identifier \'{id.text}\' was not found in available symbols'''
            )
            return id

        ref = None
        if isinstance(symbol, types.Class) and id.text == "this":
            within_static_method = isinstance(
                self.current_method,
                types.Method) and self.current_method.is_static
            ref = refs.StaticThisReference(
                symbol) if within_static_method else refs.ThisReference(symbol)
        elif isinstance(symbol, types.Class) and id.text == "super":
            ref = refs.SuperReference(symbol)
        else:
            ref = symbol.create_reference()
            if ref == None:
                self.error_man.throw(
                    "createReference() should not return null!")
        ref.parent_node = id.parent_node
        return ref
Exemplo n.º 2
0
    def get_static_ref(self, cls_, member_name):
        field = next(filter(lambda x: x.name == member_name, cls_.fields),
                     None)
        if field != None and field.is_static:
            return refs.StaticFieldReference(field)

        prop = next(filter(lambda x: x.name == member_name, cls_.properties),
                    None)
        if prop != None and prop.is_static:
            return refs.StaticPropertyReference(prop)

        self.error_man.throw(
            f'''Could not resolve static member access of a class: {cls_.name}::{member_name}'''
        )
        return None
Exemplo n.º 3
0
    def get_interface_ref(self, intf, member_name, obj):
        field = next(filter(lambda x: x.name == member_name, intf.fields),
                     None)
        if field != None and not field.is_static:
            return refs.InstanceFieldReference(obj, field)

        for base_intf in intf.base_interfaces:
            res = self.get_interface_ref((base_intf).decl, member_name, obj)
            if res != None:
                return res
        return None
Exemplo n.º 4
0
    def get_instance_ref(self, cls_, member_name, obj):
        while True:
            field = next(filter(lambda x: x.name == member_name, cls_.fields),
                         None)
            if field != None and not field.is_static:
                return refs.InstanceFieldReference(obj, field)

            prop = next(
                filter(lambda x: x.name == member_name, cls_.properties), None)
            if prop != None and not prop.is_static:
                return refs.InstancePropertyReference(obj, prop)

            if cls_.base_class == None:
                break

            cls_ = (cls_.base_class).decl

        self.error_man.throw(
            f'''Could not resolve instance member access of a class: {cls_.name}::{member_name}'''
        )
        return None
 def transform(self, expr):
     pa = expr
     enum_member_ref = pa.object
     member = next(
         filter(lambda x: x.name == pa.property_name,
                enum_member_ref.decl.values), None)
     if member == None:
         self.error_man.throw(
             f'''Enum member was not found: {enum_member_ref.decl.name}::{pa.property_name}'''
         )
         return expr
     return refs.EnumMemberReference(member)
    def transform_method_call(self, expr):
        if isinstance(expr.object, refs.ClassReference) or isinstance(
                expr.object, refs.StaticThisReference):
            cls_ = expr.object.decl if isinstance(
                expr.object,
                refs.ClassReference) else expr.object.cls_ if isinstance(
                    expr.object, refs.StaticThisReference) else None
            method = self.find_method(cls_, expr.method_name, True, expr.args)
            result = exprs.StaticMethodCallExpression(
                method, expr.type_args, expr.args,
                isinstance(expr.object, refs.StaticThisReference))
            self.resolve_return_type(result, genRes.GenericsResolver())
            return result
        else:
            resolved_object = expr.object if expr.object.actual_type != None else self.main.run_plugins_on(
                expr.object)
            object_type = resolved_object.get_type()
            intf_type = object_type.decl if isinstance(
                object_type,
                astTypes.ClassType) else object_type.decl if isinstance(
                    object_type, astTypes.InterfaceType) else None

            if intf_type != None:
                lambda_field = next(
                    filter(
                        lambda x: x.name == expr.method_name and isinstance(
                            x.type, astTypes.LambdaType) and len(
                                x.type.parameters) == len(expr.args),
                        intf_type.fields), None)
                if lambda_field != None:
                    lambda_call = exprs.LambdaCallExpression(
                        refs.InstanceFieldReference(expr.object, lambda_field),
                        expr.args)
                    lambda_call.set_actual_type(
                        (lambda_field.type).return_type, True)
                    return lambda_call

                method = self.find_method(intf_type, expr.method_name, False,
                                          expr.args)
                result = exprs.InstanceMethodCallExpression(
                    resolved_object, method, expr.type_args, expr.args)
                self.resolve_return_type(
                    result,
                    genRes.GenericsResolver.from_object(resolved_object))
                return result
            elif isinstance(object_type, astTypes.AnyType):
                expr.set_actual_type(astTypes.AnyType.instance)
                return expr
            else:
                pass
            return resolved_object
Exemplo n.º 7
0
    def visit_expression(self, expr):
        expr = super().visit_expression(expr)
        if isinstance(expr, exprs.NullCoalesceExpression):
            if isinstance(expr.default_expr,
                          refs.InstanceFieldReference) or isinstance(
                              expr.default_expr, refs.StaticFieldReference):
                return expr

            var_name = self.var_names.use_name(
                self.expr_naming.get_name_for(expr.default_expr))

            var_decl = stats.VariableDeclaration(var_name,
                                                 expr.default_expr.get_type(),
                                                 expr.default_expr)
            var_decl.mutability = types.MutabilityInfo(False, False, False)
            self.statements.append(var_decl)

            expr.default_expr = refs.VariableDeclarationReference(var_decl)
        return expr
Exemplo n.º 8
0
 def create_reference(self):
     return refs.GlobalFunctionReference(self)
Exemplo n.º 9
0
 def create_reference(self):
     return refs.MethodParameterReference(self)
Exemplo n.º 10
0
 def create_reference(self):
     return refs.ClassReference(self)
Exemplo n.º 11
0
 def create_reference(self):
     return refs.EnumReference(self)
Exemplo n.º 12
0
 def create_reference(self):
     return refs.ForeachVariableReference(self)
Exemplo n.º 13
0
 def create_reference(self):
     return refs.VariableDeclarationReference(self)
Exemplo n.º 14
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))))
Exemplo n.º 15
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))))
Exemplo n.º 16
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, 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 "")