예제 #1
0
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_))
예제 #2
0
    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
        )
예제 #3
0
 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,
     )
예제 #4
0
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
예제 #5
0
    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