( node: SyntaxNode, patterns: Pattern[] )
| 144 | } |
| 145 | |
| 146 | function tryPatternMatch( |
| 147 | node: SyntaxNode, |
| 148 | patterns: Pattern[] |
| 149 | ): SyntaxNode | null { |
| 150 | const firstPattern = patterns[0]; |
| 151 | const lastPattern = patterns[patterns.length - 1]; |
| 152 | let resultNode: SyntaxNode | null = null; |
| 153 | let resultPattern; |
| 154 | // Only one type try to match current node. |
| 155 | if (patterns.length === 1) { |
| 156 | if (firstPattern.typeEquals(node)) { |
| 157 | resultNode = node; |
| 158 | resultPattern = firstPattern; |
| 159 | } |
| 160 | } else { |
| 161 | // Matched last. Ascending search. |
| 162 | if (lastPattern.typeEquals(node)) { |
| 163 | const result = searchNodeAscending(node, lastPattern, patterns); |
| 164 | if (result != null) { |
| 165 | [resultNode, resultPattern] = result; |
| 166 | } |
| 167 | } |
| 168 | // Matched first. Descending search. |
| 169 | if (resultNode == null && firstPattern.typeEquals(node)) { |
| 170 | const result = searchNodeDescending(node, firstPattern, patterns); |
| 171 | if (result != null) { |
| 172 | [resultNode, resultPattern] = result; |
| 173 | } |
| 174 | } |
| 175 | } |
| 176 | // Use field name child if field name is given |
| 177 | if ( |
| 178 | resultNode != null && |
| 179 | resultPattern != null && |
| 180 | resultPattern.fields != null |
| 181 | ) { |
| 182 | resultPattern.fields.forEach((field) => { |
| 183 | resultNode = resultNode?.childForFieldName(field) ?? null; |
| 184 | }); |
| 185 | } |
| 186 | return resultNode; |
| 187 | } |
| 188 | |
| 189 | type NodePattern = [SyntaxNode, Pattern] | null; |
| 190 |
no test coverage detected