|
1 | 1 | from textmate_grammar.parsers.matlab import MatlabParser
|
2 | 2 |
|
3 |
| -rpath = "../tests/test_data/ClassWithPropertyValidators.m" |
| 3 | +rpath = "../../../syscop/software/nosnoc/+nosnoc/Options.m" |
4 | 4 |
|
5 | 5 |
|
6 | 6 | def find_first_child(curr, tok):
|
@@ -49,71 +49,119 @@ def __init__(self, path):
|
49 | 49 | pdb.set_trace()
|
50 | 50 |
|
51 | 51 | def _find_class_docstring(self):
|
52 |
| - if self.cls.children[1].token == "comment.line.percentage.matlab": |
| 52 | + try: |
| 53 | + possible_comment_tok = self.cls.children[1] |
| 54 | + except IndexError: |
| 55 | + print("found no docstring") |
| 56 | + return |
| 57 | + |
| 58 | + if possible_comment_tok.token == "comment.line.percentage.matlab": |
53 | 59 | self._docstring_lines()
|
54 |
| - elif self.cls.children[1].token == "comment.block.percentage.matlab": |
55 |
| - self.docstring = ( |
56 |
| - self.cls.children[1].content.strip()[2:-2].strip() |
57 |
| - ) # [2,-2] strips out block comment delimiters |
| 60 | + elif possible_comment_tok.token == "comment.block.percentage.matlab": |
| 61 | + self.docstring = possible_comment_tok.content.strip()[ |
| 62 | + 2:-2 |
| 63 | + ].strip() # [2,-2] strips out block comment delimiters |
58 | 64 | else:
|
59 | 65 | print("found no docstring")
|
60 | 66 |
|
61 | 67 | def _docstring_lines(self):
|
62 | 68 | idx = 1
|
63 |
| - while self.cls.children[idx].token == "comment.line.percentage.matlab": |
| 69 | + cls_children = self.cls.children |
| 70 | + |
| 71 | + while ( |
| 72 | + idx < len(cls_children) |
| 73 | + and cls_children[idx].token == "comment.line.percentage.matlab" |
| 74 | + ): |
64 | 75 | self.docstring += (
|
65 |
| - self.cls.children[idx].content[1:] + "\n" |
| 76 | + cls_children[idx].content[1:] + "\n" |
66 | 77 | ) # [1:] strips out percent sign
|
67 | 78 | idx += 1
|
68 | 79 | self.docstring = self.docstring.strip()
|
69 | 80 |
|
70 | 81 | def _parse_clsdef(self):
|
71 |
| - for child in self.clsdef.children: |
72 |
| - child.print() |
| 82 | + # Try parsing attrs |
| 83 | + attrs_tok_gen = self.clsdef.find(tokens="storage.modifier.section.class.matlab") |
| 84 | + try: |
| 85 | + attrs_tok, _ = next(attrs_tok_gen) |
| 86 | + self._parse_class_attributes(attrs_tok) |
| 87 | + except StopIteration: |
| 88 | + pass |
73 | 89 |
|
| 90 | + # Parse classname |
| 91 | + classname_tok_gen = self.clsdef.find(tokens="entity.name.type.class.matlab") |
| 92 | + try: |
| 93 | + classname_tok, _ = next(classname_tok_gen) |
| 94 | + self.name = classname_tok.content |
| 95 | + except StopIteration: |
| 96 | + print("ClassName not found") # TODO this is probably fatal |
| 97 | + |
| 98 | + # Parse interited classes |
| 99 | + parent_class_toks = self.clsdef.findall(tokens="meta.inherited-class.matlab") |
| 100 | + |
| 101 | + for parent_class_tok, _ in parent_class_toks: |
| 102 | + sections = parent_class_tok.findall( |
| 103 | + tokens=[ |
| 104 | + "entity.name.namespace.matlab", |
| 105 | + "entity.other.inherited-class.matlab", |
| 106 | + ] |
| 107 | + ) |
| 108 | + super_cls = tuple([sec.content for sec, _ in sections]) |
| 109 | + self.supers.append(super_cls) |
74 | 110 | # Parse Attributes TODO maybe there is a smarter way to do this?
|
75 | 111 | idx = 0
|
76 | 112 | while self.clsdef.children[idx].token == "storage.modifier.class.matlab":
|
77 |
| - attr = self.clsdef.children[idx].content |
| 113 | + attr_tok = self.clsdef.children[idx] |
| 114 | + attr = atter_tok.content |
78 | 115 | val = None # TODO maybe do some typechecking here or we can assume that you give us valid Matlab
|
79 | 116 | idx += 1
|
80 |
| - if ( |
81 |
| - self.clsdef.children[idx].token == "keyword.operator.assignment.matlab" |
82 |
| - ): # pull out r.h.s |
| 117 | + if attr_tok.token == "keyword.operator.assignment.matlab": # pull out r.h.s |
83 | 118 | idx += 1
|
84 | 119 | val = self.clsdef.children[idx].content
|
85 | 120 | idx += 1
|
86 | 121 | if (
|
87 |
| - self.clsdef.children[idx].token |
88 |
| - == "punctuation.separator.modifier.comma.matlab" |
| 122 | + attr_tok.token == "punctuation.separator.modifier.comma.matlab" |
89 | 123 | ): # skip commas
|
90 | 124 | idx += 1
|
91 | 125 | self.attrs[attr] = val
|
92 | 126 |
|
93 |
| - if ( |
94 |
| - self.clsdef.children[idx].token == "punctuation.section.parens.end.matlab" |
95 |
| - ): # Skip end of attrs |
96 |
| - idx += 1 |
97 |
| - |
98 |
| - # name must be next |
99 |
| - self.name = self.clsdef.children[idx].content |
100 |
| - idx += 1 |
101 |
| - |
102 |
| - while idx < len( |
103 |
| - self.clsdef.children |
104 |
| - ): # No children we care about after this except inherited classes |
105 |
| - if self.clsdef.children[idx].token == "meta.inherited-class.matlab": |
106 |
| - super_cls_tok = self.clsdef.children[idx] |
107 |
| - # collect superclass as a tuple |
108 |
| - super_cls = tuple( |
109 |
| - [ |
110 |
| - child.content |
111 |
| - for child in super_cls_tok.children |
112 |
| - if not child.token.startswith("punctuation") |
113 |
| - ] |
114 |
| - ) |
115 |
| - self.supers.append(super_cls) |
116 |
| - idx += 1 |
| 127 | + def _parse_class_attributes(self, attrs_tok): |
| 128 | + # walk down child list and parse manually |
| 129 | + # TODO perhaps contribute a delimited list find to textmate-grammar-python |
| 130 | + children = attrs_tok.children |
| 131 | + idx = 0 |
| 132 | + while idx < len(children): |
| 133 | + child_tok = children[idx] |
| 134 | + if child_tok.token == "storage.modifier.class.matlab": |
| 135 | + attr = child_tok.content |
| 136 | + val = None |
| 137 | + idx += 1 # walk to next token |
| 138 | + maybe_assign_tok = children[idx] |
| 139 | + if maybe_assign_tok.token == "keyword.operator.assignment.matlab": |
| 140 | + idx += 1 |
| 141 | + rhs_tok = children[idx] # parse right hand side |
| 142 | + if rhs_tok.token == "meta.cell.literal.matlab": |
| 143 | + # A cell. For now just take the whole cell as value. |
| 144 | + # TODO parse out the cell array of metaclass literals. |
| 145 | + val = "{" + rhs_tok.content + "}" |
| 146 | + idx += 1 |
| 147 | + elif rhs_tok.token == "constant.language.boolean.matlab": |
| 148 | + val = rhs_tok.content |
| 149 | + idx += 1 |
| 150 | + elif rhs_tok.token == "keyword.operator.other.question.matlab": |
| 151 | + idx += 1 |
| 152 | + metaclass_tok = children[idx] |
| 153 | + metaclass_components = metaclass_tok.findall( |
| 154 | + tokens=[ |
| 155 | + "entity.name.namespace.matlab", |
| 156 | + "entity.other.class.matlab", |
| 157 | + ] |
| 158 | + ) |
| 159 | + val = tuple([comp.content for comp, _ in metaclass_components]) |
| 160 | + else: |
| 161 | + pass |
| 162 | + self.attrs[attr] = val |
| 163 | + else: # Comma or continuation therefore skip |
| 164 | + idx += 1 |
117 | 165 |
|
118 | 166 | def _parse_property_section(self, section):
|
119 | 167 | # TODO parse property section attrs
|
@@ -241,12 +289,13 @@ def _parse_property_validation(self, prop_name, prop):
|
241 | 289 | # Now find list of validators
|
242 | 290 | validator_gen = prop.find(tokens="meta.block.validation.matlab", depth=1)
|
243 | 291 | try:
|
244 |
| - import pdb |
245 |
| - |
246 |
| - pdb.set_trace() |
247 | 292 | validator_tok, _ = next(validator_gen)
|
248 | 293 | validator_toks = validator_tok.findall(
|
249 |
| - tokens="variable.other.readwrite.matlab", depth=1 |
| 294 | + tokens=[ |
| 295 | + "variable.other.readwrite.matlab", |
| 296 | + "meta.function-call.parens.matlab", |
| 297 | + ], |
| 298 | + depth=1, |
250 | 299 | ) # TODO Probably bug here in MATLAB-Language-grammar
|
251 | 300 | self.properties[prop_name]["validators"] = [
|
252 | 301 | tok[0].content for tok in validator_toks
|
|
0 commit comments