def get_single_type_annotation(definitions: DefinitionType, property_: PropertyType) -> ast.AST: # If no property definition, use any if property_ is None: return ast.AnyTypeAnnotation() # Parse type type_name = property_.get("type") ref_key = property_.get("$ref") if type_name is None and ref_key is None: return ast.AnyTypeAnnotation() elif type_name in ("integer", "number"): return ast.NumberTypeAnnotation() elif type_name == "string": return ast.StringTypeAnnotation() elif type_name == "boolean": return ast.BooleanTypeAnnotation() elif type_name == "object": return get_object_type_annotation(definitions, property_) elif type_name == "array": items_definition = property_.get("items") parameter = get_single_type_annotation(definitions, items_definition) return ast.GenericTypeAnnotation( ast.Identifier("Array"), type_parameters=ast.TypeParameterInstantiation([parameter])) elif ref_key is not None: definition = definitions[ref_key] return ast.GenericTypeAnnotation(ast.Identifier(definition["title"])) # Nothing matches raise NotImplementedError("{}: {}".format(definitions, property_))
def klass_constructor(self, properties: PropertiesType, requireds: RequiredType): # Build constructor body body = [] for key in sorted(properties.keys()): property_ = properties[key] required = key in requireds # Left assignment assign_left = ast.MemberExpression(ast.ThisExpression(), ast.Identifier(key)) # Right assignment assign_right = self.get_member_right_assignment(key, property_, required) # Add property assignment klass_property = ast.ExpressionStatement( ast.AssignmentExpression(assign_left, assign_right) ) body.append(klass_property) # Build constructor parameters param_type = ast.TypeAnnotation(ast.GenericTypeAnnotation(id_=ast.Identifier("Object"))) param = ast.AssignmentPattern( left=ast.Identifier("data", type_annotation=param_type), right=ast.ObjectExpression() ) params = [param] # Return constructor method block = ast.BlockStatement(body=body) return ast.ClassMethod( key=ast.Identifier("constructor"), kind="constructor", params=params, body=block )
def klass_constructor(self): return ast.ObjectTypeProperty( key=ast.Identifier("constructor"), value=ast.FunctionTypeAnnotation( params=[ ast.FunctionTypeParam( ast.Identifier("data"), type_annotation=ast.NullableTypeAnnotation( ast.GenericTypeAnnotation( ast.Identifier("Object"))), ) ], return_type=ast.VoidTypeAnnotation(), ), method=True, )
def get_object_type_annotation(definitions: DefinitionType, property_: PropertyType) -> ast.AST: additionalProperties = property_.get("additionalProperties") if additionalProperties: annotation = ast.ObjectTypeAnnotation( properties=[], indexers=[ ast.ObjectTypeIndexer( id_=ast.Identifier("key"), key=ast.StringTypeAnnotation(), value=get_type_annotation(definitions, additionalProperties, required=True), ) ], ) elif "oneOf" in property_: annotation = get_oneof_type_annotion(definitions, property_) else: annotation = ast.GenericTypeAnnotation(ast.Identifier("Object")) return annotation
def _get_reducer_for_property(self, key, property_): # Object.entries() object_entries = ast.CallExpression( ast.MemberExpression(ast.Identifier("Object"), ast.Identifier("entries")), [ast.MemberExpression(ast.Identifier("data"), ast.Identifier(key))], ) # reduce() # ...deconstruct `entry`... deconstruct_entry = ast.VariableDeclaration( [ ast.VariableDeclarator( id_=ast.ArrayPattern( [ ast.Identifier( "key", type_annotation=ast.TypeAnnotation(ast.StringTypeAnnotation()), ), ast.Identifier( "value", type_annotation=ast.TypeAnnotation( ast.GenericTypeAnnotation(ast.Identifier("Object")) ), ), ] ), init=ast.TypeCastExpression( ast.Identifier("entry"), ast.TypeAnnotation(ast.AnyTypeAnnotation()) ), ) ] ) # ...assign newValue... ref_title = self.definitions[property_["$ref"]]["title"] new_value = ast.VariableDeclaration( [ ast.VariableDeclarator( ast.Identifier("newValue"), ast.NewExpression( ast.Identifier(ref_title), arguments=[ast.Identifier("value")] ), ) ] ) # ...update acc... update_acc = ast.ExpressionStatement( ast.AssignmentExpression( left=ast.MemberExpression( ast.Identifier("acc"), ast.Identifier("key"), computed=True ), right=ast.Identifier("newValue"), ) ) # ...return acc... return_acc = ast.ReturnStatement(ast.Identifier("acc")) # ...bound together reduce = ast.CallExpression( callee=ast.MemberExpression(object_entries, ast.Identifier("reduce")), arguments=[ ast.ArrowFunctionExpression( params=[ast.Identifier("acc"), ast.Identifier("entry")], body=ast.BlockStatement( [deconstruct_entry, new_value, update_acc, return_acc] ), ), ast.ObjectExpression(), ], ) # Return reduce return reduce