* Create a matcher function for `selector`, * @param {?SelectorAST} selector * @returns {SelectorMatcher}
(selector)
| 115 | * @returns {SelectorMatcher} |
| 116 | */ |
| 117 | function generateMatcher(selector) { |
| 118 | switch(selector.type) { |
| 119 | case 'wildcard': |
| 120 | return () => true; |
| 121 | |
| 122 | case 'identifier': { |
| 123 | const value = selector.value.toLowerCase(); |
| 124 | return (node, ancestry, options) => { |
| 125 | const nodeTypeKey = (options && options.nodeTypeKey) || 'type'; |
| 126 | return value === node[nodeTypeKey].toLowerCase(); |
| 127 | }; |
| 128 | } |
| 129 | |
| 130 | case 'exactNode': |
| 131 | return (node, ancestry) => { |
| 132 | return ancestry.length === 0; |
| 133 | }; |
| 134 | |
| 135 | case 'field': { |
| 136 | const path = selector.name.split('.'); |
| 137 | return (node, ancestry) => { |
| 138 | const ancestor = ancestry[path.length - 1]; |
| 139 | return inPath(node, ancestor, path, 0); |
| 140 | }; |
| 141 | } |
| 142 | |
| 143 | case 'matches': { |
| 144 | const matchers = selector.selectors.map(getMatcher); |
| 145 | return (node, ancestry, options) => { |
| 146 | for (let i = 0; i < matchers.length; ++i) { |
| 147 | if (matchers[i](node, ancestry, options)) { return true; } |
| 148 | } |
| 149 | return false; |
| 150 | }; |
| 151 | } |
| 152 | |
| 153 | case 'compound': { |
| 154 | const matchers = selector.selectors.map(getMatcher); |
| 155 | return (node, ancestry, options) => { |
| 156 | for (let i = 0; i < matchers.length; ++i) { |
| 157 | if (!matchers[i](node, ancestry, options)) { return false; } |
| 158 | } |
| 159 | return true; |
| 160 | }; |
| 161 | } |
| 162 | |
| 163 | case 'not': { |
| 164 | const matchers = selector.selectors.map(getMatcher); |
| 165 | return (node, ancestry, options) => { |
| 166 | for (let i = 0; i < matchers.length; ++i) { |
| 167 | if (matchers[i](node, ancestry, options)) { return false; } |
| 168 | } |
| 169 | return true; |
| 170 | }; |
| 171 | } |
| 172 | |
| 173 | case 'has': { |
| 174 | const matchers = selector.selectors.map(getMatcher); |
no test coverage detected