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
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
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
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
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
def create_reference(self): return refs.GlobalFunctionReference(self)
def create_reference(self): return refs.MethodParameterReference(self)
def create_reference(self): return refs.ClassReference(self)
def create_reference(self): return refs.EnumReference(self)
def create_reference(self): return refs.ForeachVariableReference(self)
def create_reference(self): return refs.VariableDeclarationReference(self)
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))))
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 "")