Coverage for phml\core\parser\json.py: 100%

35 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-12-08 11:07 -0600

1"""Helper method to parse a dict to a phml ast.""" 

2 

3from phml.nodes import Comment, DocType, Element, Point, Position, Root, Text 

4 

5__all__ = ["json_to_ast"] 

6 

7 

8def construct_node_type(node_type: str): 

9 """Takes a node type and returns a base constructed instance of the node.""" 

10 if node_type == "root": 

11 return Root() 

12 

13 if node_type == "element": 

14 return Element() 

15 

16 if node_type == "doctype": 

17 return DocType() 

18 

19 if node_type == "text": 

20 return Text() 

21 

22 if node_type == "comment": 

23 return Comment() 

24 

25 return None 

26 

27 

28def json_to_ast(json_obj: dict): 

29 """Convert a json object to a string.""" 

30 

31 def recurse(obj: dict): 

32 """Recursivly construct ast from json.""" 

33 if 'type' in obj: 

34 val = construct_node_type(obj['type']) 

35 if val is not None: 

36 for key in obj: 

37 if key not in ["children", "type", "position"] and hasattr(val, key): 

38 setattr(val, key, obj[key]) 

39 if 'children' in obj and hasattr(val, "children"): 

40 for child in obj["children"]: 

41 new_child = recurse(child) 

42 new_child.parent = val 

43 val.children.append(new_child) 

44 if 'position' in obj and hasattr(val, 'position') and obj["position"] is not None: 

45 # start, end, indent 

46 # line, column, offset 

47 start = obj["position"]["start"] 

48 end = obj["position"]["end"] 

49 val.position = Position( 

50 Point(start["line"], start["column"], start["offset"]), 

51 Point(end["line"], end["column"], end["offset"]), 

52 obj["position"]["indent"], 

53 ) 

54 return val 

55 raise Exception(f"Unkown node type <{obj['type']}>") 

56 raise Exception( 

57 'Invalid json for phml. Every node must have a type. Nodes may only have the types; \ 

58root, element, doctype, text, or comment' 

59 ) 

60 

61 return recurse(json_obj)