| export function getTrace(node) { |
| function shouldPutToTrace(syntax) { |
| if (syntax === null) { |
| return false; |
| } |
| |
| return ( |
| syntax.type === 'Type' || |
| syntax.type === 'Property' || |
| syntax.type === 'Keyword' |
| ); |
| } |
| |
| function hasMatch(matchNode) { |
| if (Array.isArray(matchNode.match)) { |
| // use for-loop for better perfomance |
| for (let i = 0; i < matchNode.match.length; i++) { |
| if (hasMatch(matchNode.match[i])) { |
| if (shouldPutToTrace(matchNode.syntax)) { |
| result.unshift(matchNode.syntax); |
| } |
| |
| return true; |
| } |
| } |
| } else if (matchNode.node === node) { |
| result = shouldPutToTrace(matchNode.syntax) |
| ? [matchNode.syntax] |
| : []; |
| |
| return true; |
| } |
| |
| return false; |
| } |
| |
| let result = null; |
| |
| if (this.matched !== null) { |
| hasMatch(this.matched); |
| } |
| |
| return result; |
| } |
| |
| export function isType(node, type) { |
| return testNode(this, node, match => match.type === 'Type' && match.name === type); |
| } |
| |
| export function isProperty(node, property) { |
| return testNode(this, node, match => match.type === 'Property' && match.name === property); |
| } |
| |
| export function isKeyword(node) { |
| return testNode(this, node, match => match.type === 'Keyword'); |
| } |
| |
| function testNode(match, node, fn) { |
| const trace = getTrace.call(match, node); |
| |
| if (trace === null) { |
| return false; |
| } |
| |
| return trace.some(fn); |
| } |