def type_to_tree(tree, t): """ Converts a type to its respective AST Tree representation. """ if isinstance(t, ListType): inner = SymbolExpressionVisitor.type_to_tree(tree, t.inner) return Tree('list_type', [ Tree('types', [inner]) ]) if isinstance(t, MapType): key = SymbolExpressionVisitor.type_to_tree(tree, t.key) value = SymbolExpressionVisitor.type_to_tree(tree, t.value) return Tree('map_type', [ key, Tree('types', [value]), ]) if t == BooleanType.instance(): base_type = tree.create_token('BOOLEAN_TYPE', 'boolean') elif t == IntType.instance(): base_type = tree.create_token('INTEGER_TYPE', 'int') elif t == FloatType.instance(): base_type = tree.create_token('FLOAT_TYPE', 'float') elif t == StringType.instance(): base_type = tree.create_token('STRING_TYPE', 'string') elif t == TimeType.instance(): base_type = tree.create_token('TIME_TYPE', 'time') elif t == RegExpType.instance(): base_type = tree.create_token('REGEXP_TYPE', 'regex') else: assert t == AnyType.instance() base_type = tree.create_token('ANY_TYPE', 'any') return Tree('base_type', [base_type])
def type_to_tree(tree, t): """ Converts a type to its respective AST Tree representation. """ if isinstance(t, ListType): inner = SymbolExpressionVisitor.type_to_tree(tree, t.inner) return Tree("list_type", [Tree("types", [inner])]) if isinstance(t, MapType): key = SymbolExpressionVisitor.type_to_tree(tree, t.key) value = SymbolExpressionVisitor.type_to_tree(tree, t.value) return Tree("map_type", [key, Tree("types", [value]),]) if t == BooleanType.instance(): base_type = tree.create_token("BOOLEAN_TYPE", "boolean") elif t == IntType.instance(): base_type = tree.create_token("INTEGER_TYPE", "int") elif t == FloatType.instance(): base_type = tree.create_token("FLOAT_TYPE", "float") elif t == StringType.instance(): base_type = tree.create_token("STRING_TYPE", "string") elif t == TimeType.instance(): base_type = tree.create_token("TIME_TYPE", "time") elif t == RegExpType.instance(): base_type = tree.create_token("REGEXP_TYPE", "regex") else: assert t == AnyType.instance() base_type = tree.create_token("ANY_TYPE", "any") return Tree("base_type", [base_type])
def base_type(self, tree): """ Resolves a base type expression to a type """ assert tree.data == 'base_type' tok = tree.first_child() if tok.type == 'BOOLEAN_TYPE': return base_symbol(BooleanType.instance()) elif tok.type == 'INT_TYPE': return base_symbol(IntType.instance()) elif tok.type == 'FLOAT_TYPE': return base_symbol(FloatType.instance()) elif tok.type == 'STRING_TYPE': return base_symbol(StringType.instance()) elif tok.type == 'ANY_TYPE': return base_symbol(AnyType.instance()) elif tok.type == 'OBJECT_TYPE': return base_symbol(ObjectType.instance()) elif tok.type == 'FUNCTION_TYPE': return base_symbol(AnyType.instance()) elif tok.type == 'TIME_TYPE': return base_symbol(TimeType.instance()) else: assert tok.type == 'REGEXP_TYPE' return base_symbol(RegExpType.instance())
def parse_type(type_): """ Parses a type string and returns its parsed type which can be a: - BaseType (e.g. `IntType`) - TypeSymbol (e.g. `TypeSymbol(A)`) - GenericType (e.g. `ListGenericType(TypeSymbol(A))`) """ assert len(type_) > 0 type_ = type_.strip() if type_ == "boolean": return BooleanType.instance() if type_ == "int": return IntType.instance() if type_ == "float": return FloatType.instance() if type_ == "string": return StringType.instance() if type_ == "time": return TimeType.instance() if type_ == "none": return NoneType.instance() if type_ == "regexp": return RegExpType.instance() if type_ == "any": return AnyType.instance() if "[" in type_: types = [] for t in parse_type_inner(type_).split(","): t2 = parse_type(t) types.append(t2) if type_.startswith("List["): return ListGenericType(types) else: assert type_.startswith("Map[") return MapGenericType(types) assert "]" not in type_ return TypeSymbol(type_)
def time(self, tree): """ Compiles a time tree. """ assert tree.data == 'time' return base_symbol(TimeType.instance())
['foo[a, b]', 'arg:list[int]', 'a2:bar']), ('foo[a, b] arg:foo[bar]', ['foo[a, b]', 'arg:foo[bar]']), ('foo[bar[abc]] arg:foo[bar]', ['foo[bar[abc]]', 'arg:foo[bar]']), ]) def test_split_args(text, expected): assert [*split_type_arguments(text)] == expected @mark.parametrize('text,expected', [ ('any', AnyType.instance()), ('boolean', BooleanType.instance()), ('float', FloatType.instance()), ('int', IntType.instance()), ('none', NoneType.instance()), ('string', StringType.instance()), ('time', TimeType.instance()), ('A', TypeSymbol('A')), ]) def test_parse_type_base(text, expected): t = parse_type(text) assert str(t) == str(expected) @mark.parametrize('text,expected_type,expected_symbols', [ ('List[int]', ListGenericType, [IntType.instance()]), ('List[float]', ListGenericType, [FloatType.instance()]), ('Map[int,string]', MapGenericType, [IntType.instance(), StringType.instance()]), ('List[A]', ListGenericType, [TypeSymbol('A')]), ('Map[A,B]', MapGenericType, [TypeSymbol('A'), TypeSymbol('B')]),
def test_parse_end_error(): with raises(AssertionError): parse_type_inner("foo[bar") @mark.parametrize( "text,expected", [ ("any", AnyType.instance()), ("boolean", BooleanType.instance()), ("float", FloatType.instance()), ("int", IntType.instance()), ("none", NoneType.instance()), ("string", StringType.instance()), ("time", TimeType.instance()), ("A", TypeSymbol("A")), ], ) def test_parse_type_base(text, expected): t = parse_type(text) assert str(t) == str(expected) @mark.parametrize( "text,expected_type,expected_symbols", [ ("List[int]", ListGenericType, [IntType.instance()]), ("List[float]", ListGenericType, [FloatType.instance()]), ( "Map[int,string]",
def test_type_to_tree_time(magic): tree = magic() bt = TimeType.instance() se = SymbolExpressionVisitor.type_to_tree(tree, bt) assert se.data == "base_type" tree.create_token.assert_called_with("TIME_TYPE", "time")