@eslint/css-tree 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +194 -0
  3. package/cjs/convertor/create.cjs +32 -0
  4. package/cjs/convertor/index.cjs +8 -0
  5. package/cjs/data-patch.cjs +7 -0
  6. package/cjs/data.cjs +120 -0
  7. package/cjs/definition-syntax/SyntaxError.cjs +16 -0
  8. package/cjs/definition-syntax/generate.cjs +139 -0
  9. package/cjs/definition-syntax/index.cjs +13 -0
  10. package/cjs/definition-syntax/parse.cjs +556 -0
  11. package/cjs/definition-syntax/scanner.cjs +113 -0
  12. package/cjs/definition-syntax/walk.cjs +57 -0
  13. package/cjs/generator/create.cjs +102 -0
  14. package/cjs/generator/index.cjs +8 -0
  15. package/cjs/generator/sourceMap.cjs +96 -0
  16. package/cjs/generator/token-before.cjs +170 -0
  17. package/cjs/index.cjs +65 -0
  18. package/cjs/lexer/Lexer.cjs +517 -0
  19. package/cjs/lexer/error.cjs +128 -0
  20. package/cjs/lexer/generic-an-plus-b.cjs +235 -0
  21. package/cjs/lexer/generic-const.cjs +12 -0
  22. package/cjs/lexer/generic-urange.cjs +149 -0
  23. package/cjs/lexer/generic.cjs +589 -0
  24. package/cjs/lexer/index.cjs +7 -0
  25. package/cjs/lexer/match-graph.cjs +530 -0
  26. package/cjs/lexer/match.cjs +632 -0
  27. package/cjs/lexer/prepare-tokens.cjs +54 -0
  28. package/cjs/lexer/search.cjs +65 -0
  29. package/cjs/lexer/structure.cjs +173 -0
  30. package/cjs/lexer/trace.cjs +73 -0
  31. package/cjs/lexer/units.cjs +38 -0
  32. package/cjs/parser/SyntaxError.cjs +74 -0
  33. package/cjs/parser/create.cjs +378 -0
  34. package/cjs/parser/index.cjs +8 -0
  35. package/cjs/parser/parse-selector.cjs +8 -0
  36. package/cjs/parser/sequence.cjs +47 -0
  37. package/cjs/syntax/atrule/container.cjs +32 -0
  38. package/cjs/syntax/atrule/font-face.cjs +12 -0
  39. package/cjs/syntax/atrule/import.cjs +101 -0
  40. package/cjs/syntax/atrule/index.cjs +27 -0
  41. package/cjs/syntax/atrule/layer.cjs +16 -0
  42. package/cjs/syntax/atrule/media.cjs +16 -0
  43. package/cjs/syntax/atrule/nest.cjs +16 -0
  44. package/cjs/syntax/atrule/page.cjs +16 -0
  45. package/cjs/syntax/atrule/scope.cjs +16 -0
  46. package/cjs/syntax/atrule/starting-style.cjs +12 -0
  47. package/cjs/syntax/atrule/supports.cjs +16 -0
  48. package/cjs/syntax/config/generator.cjs +9 -0
  49. package/cjs/syntax/config/lexer.cjs +14 -0
  50. package/cjs/syntax/config/mix.cjs +126 -0
  51. package/cjs/syntax/config/parser-selector.cjs +19 -0
  52. package/cjs/syntax/config/parser.cjs +49 -0
  53. package/cjs/syntax/config/walker.cjs +9 -0
  54. package/cjs/syntax/create.cjs +58 -0
  55. package/cjs/syntax/function/expression.cjs +11 -0
  56. package/cjs/syntax/function/var.cjs +43 -0
  57. package/cjs/syntax/index.cjs +14 -0
  58. package/cjs/syntax/node/AnPlusB.cjs +293 -0
  59. package/cjs/syntax/node/Atrule.cjs +103 -0
  60. package/cjs/syntax/node/AtrulePrelude.cjs +52 -0
  61. package/cjs/syntax/node/AttributeSelector.cjs +148 -0
  62. package/cjs/syntax/node/Block.cjs +96 -0
  63. package/cjs/syntax/node/Brackets.cjs +38 -0
  64. package/cjs/syntax/node/CDC.cjs +26 -0
  65. package/cjs/syntax/node/CDO.cjs +26 -0
  66. package/cjs/syntax/node/ClassSelector.cjs +31 -0
  67. package/cjs/syntax/node/Combinator.cjs +61 -0
  68. package/cjs/syntax/node/Comment.cjs +40 -0
  69. package/cjs/syntax/node/Condition.cjs +120 -0
  70. package/cjs/syntax/node/Declaration.cjs +166 -0
  71. package/cjs/syntax/node/DeclarationList.cjs +62 -0
  72. package/cjs/syntax/node/Dimension.cjs +30 -0
  73. package/cjs/syntax/node/Feature.cjs +101 -0
  74. package/cjs/syntax/node/FeatureFunction.cjs +67 -0
  75. package/cjs/syntax/node/FeatureRange.cjs +133 -0
  76. package/cjs/syntax/node/Function.cjs +45 -0
  77. package/cjs/syntax/node/GeneralEnclosed.cjs +68 -0
  78. package/cjs/syntax/node/Hash.cjs +30 -0
  79. package/cjs/syntax/node/IdSelector.cjs +33 -0
  80. package/cjs/syntax/node/Identifier.cjs +25 -0
  81. package/cjs/syntax/node/Layer.cjs +35 -0
  82. package/cjs/syntax/node/LayerList.cjs +43 -0
  83. package/cjs/syntax/node/MediaQuery.cjs +100 -0
  84. package/cjs/syntax/node/MediaQueryList.cjs +41 -0
  85. package/cjs/syntax/node/NestingSelector.cjs +29 -0
  86. package/cjs/syntax/node/Nth.cjs +54 -0
  87. package/cjs/syntax/node/Number.cjs +25 -0
  88. package/cjs/syntax/node/Operator.cjs +28 -0
  89. package/cjs/syntax/node/Parentheses.cjs +38 -0
  90. package/cjs/syntax/node/Percentage.cjs +25 -0
  91. package/cjs/syntax/node/PseudoClassSelector.cjs +67 -0
  92. package/cjs/syntax/node/PseudoElementSelector.cjs +69 -0
  93. package/cjs/syntax/node/Ratio.cjs +71 -0
  94. package/cjs/syntax/node/Raw.cjs +48 -0
  95. package/cjs/syntax/node/Rule.cjs +58 -0
  96. package/cjs/syntax/node/Scope.cjs +69 -0
  97. package/cjs/syntax/node/Selector.cjs +38 -0
  98. package/cjs/syntax/node/SelectorList.cjs +43 -0
  99. package/cjs/syntax/node/String.cjs +26 -0
  100. package/cjs/syntax/node/StyleSheet.cjs +83 -0
  101. package/cjs/syntax/node/SupportsDeclaration.cjs +38 -0
  102. package/cjs/syntax/node/TypeSelector.cjs +59 -0
  103. package/cjs/syntax/node/UnicodeRange.cjs +158 -0
  104. package/cjs/syntax/node/Url.cjs +54 -0
  105. package/cjs/syntax/node/Value.cjs +26 -0
  106. package/cjs/syntax/node/WhiteSpace.cjs +34 -0
  107. package/cjs/syntax/node/index-generate.cjs +103 -0
  108. package/cjs/syntax/node/index-parse-selector.cjs +39 -0
  109. package/cjs/syntax/node/index-parse.cjs +103 -0
  110. package/cjs/syntax/node/index.cjs +103 -0
  111. package/cjs/syntax/pseudo/index.cjs +60 -0
  112. package/cjs/syntax/pseudo/lang.cjs +37 -0
  113. package/cjs/syntax/scope/atrulePrelude.cjs +9 -0
  114. package/cjs/syntax/scope/default.cjs +76 -0
  115. package/cjs/syntax/scope/index.cjs +11 -0
  116. package/cjs/syntax/scope/selector.cjs +88 -0
  117. package/cjs/syntax/scope/value.cjs +29 -0
  118. package/cjs/tokenizer/OffsetToLocation.cjs +91 -0
  119. package/cjs/tokenizer/TokenStream.cjs +358 -0
  120. package/cjs/tokenizer/adopt-buffer.cjs +13 -0
  121. package/cjs/tokenizer/char-code-definitions.cjs +236 -0
  122. package/cjs/tokenizer/index.cjs +554 -0
  123. package/cjs/tokenizer/names.cjs +32 -0
  124. package/cjs/tokenizer/types.cjs +57 -0
  125. package/cjs/tokenizer/utils.cjs +261 -0
  126. package/cjs/utils/List.cjs +473 -0
  127. package/cjs/utils/clone.cjs +25 -0
  128. package/cjs/utils/create-custom-error.cjs +18 -0
  129. package/cjs/utils/ident.cjs +102 -0
  130. package/cjs/utils/index.cjs +20 -0
  131. package/cjs/utils/names.cjs +113 -0
  132. package/cjs/utils/string.cjs +99 -0
  133. package/cjs/utils/url.cjs +108 -0
  134. package/cjs/version.cjs +5 -0
  135. package/cjs/walker/create.cjs +291 -0
  136. package/cjs/walker/index.cjs +8 -0
  137. package/data/patch.json +874 -0
  138. package/dist/csstree.esm.js +12 -0
  139. package/dist/csstree.js +12 -0
  140. package/dist/data.cjs +1341 -0
  141. package/dist/data.js +1341 -0
  142. package/dist/version.cjs +1 -0
  143. package/dist/version.js +1 -0
  144. package/lib/convertor/create.js +28 -0
  145. package/lib/convertor/index.js +4 -0
  146. package/lib/data-patch.js +6 -0
  147. package/lib/data.js +118 -0
  148. package/lib/definition-syntax/SyntaxError.js +12 -0
  149. package/lib/definition-syntax/generate.js +135 -0
  150. package/lib/definition-syntax/index.js +4 -0
  151. package/lib/definition-syntax/parse.js +552 -0
  152. package/lib/definition-syntax/scanner.js +109 -0
  153. package/lib/definition-syntax/walk.js +53 -0
  154. package/lib/generator/create.js +97 -0
  155. package/lib/generator/index.js +4 -0
  156. package/lib/generator/sourceMap.js +92 -0
  157. package/lib/generator/token-before.js +182 -0
  158. package/lib/index.d.ts +3016 -0
  159. package/lib/index.js +30 -0
  160. package/lib/lexer/Lexer.js +511 -0
  161. package/lib/lexer/error.js +123 -0
  162. package/lib/lexer/generic-an-plus-b.js +238 -0
  163. package/lib/lexer/generic-const.js +8 -0
  164. package/lib/lexer/generic-urange.js +151 -0
  165. package/lib/lexer/generic.js +622 -0
  166. package/lib/lexer/index.js +1 -0
  167. package/lib/lexer/match-graph.js +527 -0
  168. package/lib/lexer/match.js +630 -0
  169. package/lib/lexer/prepare-tokens.js +50 -0
  170. package/lib/lexer/search.js +61 -0
  171. package/lib/lexer/structure.js +169 -0
  172. package/lib/lexer/trace.js +66 -0
  173. package/lib/lexer/units.js +27 -0
  174. package/lib/parser/SyntaxError.js +70 -0
  175. package/lib/parser/create.js +388 -0
  176. package/lib/parser/index.js +4 -0
  177. package/lib/parser/parse-selector.js +4 -0
  178. package/lib/parser/sequence.js +43 -0
  179. package/lib/syntax/atrule/container.js +28 -0
  180. package/lib/syntax/atrule/font-face.js +8 -0
  181. package/lib/syntax/atrule/import.js +104 -0
  182. package/lib/syntax/atrule/index.js +23 -0
  183. package/lib/syntax/atrule/layer.js +12 -0
  184. package/lib/syntax/atrule/media.js +12 -0
  185. package/lib/syntax/atrule/nest.js +12 -0
  186. package/lib/syntax/atrule/page.js +12 -0
  187. package/lib/syntax/atrule/scope.js +12 -0
  188. package/lib/syntax/atrule/starting-style.js +8 -0
  189. package/lib/syntax/atrule/supports.js +12 -0
  190. package/lib/syntax/config/generator.js +5 -0
  191. package/lib/syntax/config/lexer.js +10 -0
  192. package/lib/syntax/config/mix.js +122 -0
  193. package/lib/syntax/config/parser-selector.js +15 -0
  194. package/lib/syntax/config/parser.js +45 -0
  195. package/lib/syntax/config/walker.js +5 -0
  196. package/lib/syntax/create.js +55 -0
  197. package/lib/syntax/function/expression.js +7 -0
  198. package/lib/syntax/function/var.js +39 -0
  199. package/lib/syntax/index.js +10 -0
  200. package/lib/syntax/node/AnPlusB.js +292 -0
  201. package/lib/syntax/node/Atrule.js +100 -0
  202. package/lib/syntax/node/AtrulePrelude.js +47 -0
  203. package/lib/syntax/node/AttributeSelector.js +147 -0
  204. package/lib/syntax/node/Block.js +95 -0
  205. package/lib/syntax/node/Brackets.js +35 -0
  206. package/lib/syntax/node/CDC.js +19 -0
  207. package/lib/syntax/node/CDO.js +19 -0
  208. package/lib/syntax/node/ClassSelector.js +24 -0
  209. package/lib/syntax/node/Combinator.js +54 -0
  210. package/lib/syntax/node/Comment.js +33 -0
  211. package/lib/syntax/node/Condition.js +123 -0
  212. package/lib/syntax/node/Declaration.js +165 -0
  213. package/lib/syntax/node/DeclarationList.js +62 -0
  214. package/lib/syntax/node/Dimension.js +23 -0
  215. package/lib/syntax/node/Feature.js +103 -0
  216. package/lib/syntax/node/FeatureFunction.js +63 -0
  217. package/lib/syntax/node/FeatureRange.js +133 -0
  218. package/lib/syntax/node/Function.js +41 -0
  219. package/lib/syntax/node/GeneralEnclosed.js +66 -0
  220. package/lib/syntax/node/Hash.js +23 -0
  221. package/lib/syntax/node/IdSelector.js +26 -0
  222. package/lib/syntax/node/Identifier.js +18 -0
  223. package/lib/syntax/node/Layer.js +28 -0
  224. package/lib/syntax/node/LayerList.js +36 -0
  225. package/lib/syntax/node/MediaQuery.js +102 -0
  226. package/lib/syntax/node/MediaQueryList.js +34 -0
  227. package/lib/syntax/node/NestingSelector.js +22 -0
  228. package/lib/syntax/node/Nth.js +47 -0
  229. package/lib/syntax/node/Number.js +18 -0
  230. package/lib/syntax/node/Operator.js +21 -0
  231. package/lib/syntax/node/Parentheses.js +34 -0
  232. package/lib/syntax/node/Percentage.js +18 -0
  233. package/lib/syntax/node/PseudoClassSelector.js +65 -0
  234. package/lib/syntax/node/PseudoElementSelector.js +66 -0
  235. package/lib/syntax/node/Ratio.js +68 -0
  236. package/lib/syntax/node/Raw.js +41 -0
  237. package/lib/syntax/node/Rule.js +51 -0
  238. package/lib/syntax/node/Scope.js +66 -0
  239. package/lib/syntax/node/Selector.js +31 -0
  240. package/lib/syntax/node/SelectorList.js +35 -0
  241. package/lib/syntax/node/String.js +19 -0
  242. package/lib/syntax/node/StyleSheet.js +82 -0
  243. package/lib/syntax/node/SupportsDeclaration.js +34 -0
  244. package/lib/syntax/node/TypeSelector.js +52 -0
  245. package/lib/syntax/node/UnicodeRange.js +156 -0
  246. package/lib/syntax/node/Url.js +52 -0
  247. package/lib/syntax/node/Value.js +19 -0
  248. package/lib/syntax/node/WhiteSpace.js +27 -0
  249. package/lib/syntax/node/index-generate.js +49 -0
  250. package/lib/syntax/node/index-parse-selector.js +17 -0
  251. package/lib/syntax/node/index-parse.js +49 -0
  252. package/lib/syntax/node/index.js +49 -0
  253. package/lib/syntax/pseudo/index.js +56 -0
  254. package/lib/syntax/pseudo/lang.js +33 -0
  255. package/lib/syntax/scope/atrulePrelude.js +5 -0
  256. package/lib/syntax/scope/default.js +85 -0
  257. package/lib/syntax/scope/index.js +3 -0
  258. package/lib/syntax/scope/selector.js +94 -0
  259. package/lib/syntax/scope/value.js +25 -0
  260. package/lib/tokenizer/OffsetToLocation.js +87 -0
  261. package/lib/tokenizer/TokenStream.js +366 -0
  262. package/lib/tokenizer/adopt-buffer.js +9 -0
  263. package/lib/tokenizer/char-code-definitions.js +212 -0
  264. package/lib/tokenizer/index.js +513 -0
  265. package/lib/tokenizer/names.js +28 -0
  266. package/lib/tokenizer/types.js +28 -0
  267. package/lib/tokenizer/utils.js +254 -0
  268. package/lib/utils/List.js +469 -0
  269. package/lib/utils/clone.js +21 -0
  270. package/lib/utils/create-custom-error.js +14 -0
  271. package/lib/utils/ident.js +101 -0
  272. package/lib/utils/index.js +6 -0
  273. package/lib/utils/names.js +106 -0
  274. package/lib/utils/string.js +99 -0
  275. package/lib/utils/url.js +108 -0
  276. package/lib/version.js +5 -0
  277. package/lib/walker/create.js +287 -0
  278. package/lib/walker/index.js +4 -0
  279. package/package.json +133 -0
@@ -0,0 +1,517 @@
1
+ 'use strict';
2
+
3
+ const error = require('./error.cjs');
4
+ const names = require('../utils/names.cjs');
5
+ const genericConst = require('./generic-const.cjs');
6
+ const generic = require('./generic.cjs');
7
+ const units = require('./units.cjs');
8
+ const prepareTokens = require('./prepare-tokens.cjs');
9
+ const matchGraph = require('./match-graph.cjs');
10
+ const match = require('./match.cjs');
11
+ const trace = require('./trace.cjs');
12
+ const search = require('./search.cjs');
13
+ const structure = require('./structure.cjs');
14
+ const parse = require('../definition-syntax/parse.cjs');
15
+ const generate = require('../definition-syntax/generate.cjs');
16
+ const walk = require('../definition-syntax/walk.cjs');
17
+
18
+ function dumpMapSyntax(map, compact, syntaxAsAst) {
19
+ const result = {};
20
+
21
+ for (const name in map) {
22
+ if (map[name].syntax) {
23
+ result[name] = syntaxAsAst
24
+ ? map[name].syntax
25
+ : generate.generate(map[name].syntax, { compact });
26
+ }
27
+ }
28
+
29
+ return result;
30
+ }
31
+
32
+ function dumpAtruleMapSyntax(map, compact, syntaxAsAst) {
33
+ const result = {};
34
+
35
+ for (const [name, atrule] of Object.entries(map)) {
36
+ result[name] = {
37
+ prelude: atrule.prelude && (
38
+ syntaxAsAst
39
+ ? atrule.prelude.syntax
40
+ : generate.generate(atrule.prelude.syntax, { compact })
41
+ ),
42
+ descriptors: atrule.descriptors && dumpMapSyntax(atrule.descriptors, compact, syntaxAsAst)
43
+ };
44
+ }
45
+
46
+ return result;
47
+ }
48
+
49
+ function valueHasVar(tokens) {
50
+ for (let i = 0; i < tokens.length; i++) {
51
+ if (tokens[i].value.toLowerCase() === 'var(') {
52
+ return true;
53
+ }
54
+ }
55
+
56
+ return false;
57
+ }
58
+
59
+ function syntaxHasTopLevelCommaMultiplier(syntax) {
60
+ const singleTerm = syntax.terms[0];
61
+
62
+ return (
63
+ syntax.explicit === false &&
64
+ syntax.terms.length === 1 &&
65
+ singleTerm.type === 'Multiplier' &&
66
+ singleTerm.comma === true
67
+ );
68
+ }
69
+
70
+ function buildMatchResult(matched, error, iterations) {
71
+ return {
72
+ matched,
73
+ iterations,
74
+ error,
75
+ ...trace
76
+ };
77
+ }
78
+
79
+ function matchSyntax(lexer, syntax, value, useCssWideKeywords) {
80
+ const tokens = prepareTokens(value, lexer.syntax);
81
+ let result;
82
+
83
+ if (valueHasVar(tokens)) {
84
+ return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));
85
+ }
86
+
87
+ if (useCssWideKeywords) {
88
+ result = match.matchAsTree(tokens, lexer.cssWideKeywordsSyntax, lexer);
89
+ }
90
+
91
+ if (!useCssWideKeywords || !result.match) {
92
+ result = match.matchAsTree(tokens, syntax.match, lexer);
93
+ if (!result.match) {
94
+ return buildMatchResult(
95
+ null,
96
+ new error.SyntaxMatchError(result.reason, syntax.syntax, value, result),
97
+ result.iterations
98
+ );
99
+ }
100
+ }
101
+
102
+ return buildMatchResult(result.match, null, result.iterations);
103
+ }
104
+
105
+ class Lexer {
106
+ constructor(config, syntax, structure$1) {
107
+ this.cssWideKeywords = genericConst.cssWideKeywords;
108
+ this.syntax = syntax;
109
+ this.generic = false;
110
+ this.units = { ...units };
111
+ this.atrules = Object.create(null);
112
+ this.properties = Object.create(null);
113
+ this.types = Object.create(null);
114
+ this.structure = structure$1 || structure.getStructureFromConfig(config);
115
+
116
+ if (config) {
117
+ if (config.cssWideKeywords) {
118
+ this.cssWideKeywords = config.cssWideKeywords;
119
+ }
120
+
121
+ if (config.units) {
122
+ for (const group of Object.keys(units)) {
123
+ if (Array.isArray(config.units[group])) {
124
+ this.units[group] = config.units[group];
125
+ }
126
+ }
127
+ }
128
+
129
+ if (config.types) {
130
+ for (const [name, type] of Object.entries(config.types)) {
131
+ this.addType_(name, type);
132
+ }
133
+ }
134
+
135
+ if (config.generic) {
136
+ this.generic = true;
137
+ for (const [name, value] of Object.entries(generic.createGenericTypes(this.units))) {
138
+ this.addType_(name, value);
139
+ }
140
+ }
141
+
142
+ if (config.atrules) {
143
+ for (const [name, atrule] of Object.entries(config.atrules)) {
144
+ this.addAtrule_(name, atrule);
145
+ }
146
+ }
147
+
148
+ if (config.properties) {
149
+ for (const [name, property] of Object.entries(config.properties)) {
150
+ this.addProperty_(name, property);
151
+ }
152
+ }
153
+ }
154
+
155
+ this.cssWideKeywordsSyntax = matchGraph.buildMatchGraph(this.cssWideKeywords.join(' | '));
156
+ }
157
+
158
+ checkStructure(ast) {
159
+ function collectWarning(node, message) {
160
+ warns.push({ node, message });
161
+ }
162
+
163
+ const structure = this.structure;
164
+ const warns = [];
165
+
166
+ this.syntax.walk(ast, function(node) {
167
+ if (structure.hasOwnProperty(node.type)) {
168
+ structure[node.type].check(node, collectWarning);
169
+ } else {
170
+ collectWarning(node, 'Unknown node type `' + node.type + '`');
171
+ }
172
+ });
173
+
174
+ return warns.length ? warns : false;
175
+ }
176
+
177
+ createDescriptor(syntax, type, name, parent = null) {
178
+ const ref = {
179
+ type,
180
+ name
181
+ };
182
+ const descriptor = {
183
+ type,
184
+ name,
185
+ parent,
186
+ serializable: typeof syntax === 'string' || (syntax && typeof syntax.type === 'string'),
187
+ syntax: null,
188
+ match: null,
189
+ matchRef: null // used for properties when a syntax referenced as <'property'> in other syntax definitions
190
+ };
191
+
192
+ if (typeof syntax === 'function') {
193
+ descriptor.match = matchGraph.buildMatchGraph(syntax, ref);
194
+ } else {
195
+ if (typeof syntax === 'string') {
196
+ // lazy parsing on first access
197
+ Object.defineProperty(descriptor, 'syntax', {
198
+ get() {
199
+ Object.defineProperty(descriptor, 'syntax', {
200
+ value: parse.parse(syntax)
201
+ });
202
+
203
+ return descriptor.syntax;
204
+ }
205
+ });
206
+ } else {
207
+ descriptor.syntax = syntax;
208
+ }
209
+
210
+ // lazy graph build on first access
211
+ Object.defineProperty(descriptor, 'match', {
212
+ get() {
213
+ Object.defineProperty(descriptor, 'match', {
214
+ value: matchGraph.buildMatchGraph(descriptor.syntax, ref)
215
+ });
216
+
217
+ return descriptor.match;
218
+ }
219
+ });
220
+
221
+ if (type === 'Property') {
222
+ Object.defineProperty(descriptor, 'matchRef', {
223
+ get() {
224
+ const syntax = descriptor.syntax;
225
+ const value = syntaxHasTopLevelCommaMultiplier(syntax)
226
+ ? matchGraph.buildMatchGraph({
227
+ ...syntax,
228
+ terms: [syntax.terms[0].term]
229
+ }, ref)
230
+ : null;
231
+
232
+ Object.defineProperty(descriptor, 'matchRef', {
233
+ value
234
+ });
235
+
236
+ return value;
237
+ }
238
+ });
239
+ }
240
+ }
241
+
242
+ return descriptor;
243
+ }
244
+ addAtrule_(name, syntax) {
245
+ if (!syntax) {
246
+ return;
247
+ }
248
+
249
+ this.atrules[name] = {
250
+ type: 'Atrule',
251
+ name: name,
252
+ prelude: syntax.prelude ? this.createDescriptor(syntax.prelude, 'AtrulePrelude', name) : null,
253
+ descriptors: syntax.descriptors
254
+ ? Object.keys(syntax.descriptors).reduce(
255
+ (map, descName) => {
256
+ map[descName] = this.createDescriptor(syntax.descriptors[descName], 'AtruleDescriptor', descName, name);
257
+ return map;
258
+ },
259
+ Object.create(null)
260
+ )
261
+ : null
262
+ };
263
+ }
264
+ addProperty_(name, syntax) {
265
+ if (!syntax) {
266
+ return;
267
+ }
268
+
269
+ this.properties[name] = this.createDescriptor(syntax, 'Property', name);
270
+ }
271
+ addType_(name, syntax) {
272
+ if (!syntax) {
273
+ return;
274
+ }
275
+
276
+ this.types[name] = this.createDescriptor(syntax, 'Type', name);
277
+ }
278
+
279
+ checkAtruleName(atruleName) {
280
+ if (!this.getAtrule(atruleName)) {
281
+ return new error.SyntaxReferenceError('Unknown at-rule', '@' + atruleName);
282
+ }
283
+ }
284
+ checkAtrulePrelude(atruleName, prelude) {
285
+ const error = this.checkAtruleName(atruleName);
286
+
287
+ if (error) {
288
+ return error;
289
+ }
290
+
291
+ const atrule = this.getAtrule(atruleName);
292
+
293
+ if (!atrule.prelude && prelude) {
294
+ return new SyntaxError('At-rule `@' + atruleName + '` should not contain a prelude');
295
+ }
296
+
297
+ if (atrule.prelude && !prelude) {
298
+ if (!matchSyntax(this, atrule.prelude, '', false).matched) {
299
+ return new SyntaxError('At-rule `@' + atruleName + '` should contain a prelude');
300
+ }
301
+ }
302
+ }
303
+ checkAtruleDescriptorName(atruleName, descriptorName) {
304
+ const error$1 = this.checkAtruleName(atruleName);
305
+
306
+ if (error$1) {
307
+ return error$1;
308
+ }
309
+
310
+ const atrule = this.getAtrule(atruleName);
311
+ const descriptor = names.keyword(descriptorName);
312
+
313
+ if (!atrule.descriptors) {
314
+ return new SyntaxError('At-rule `@' + atruleName + '` has no known descriptors');
315
+ }
316
+
317
+ if (!atrule.descriptors[descriptor.name] &&
318
+ !atrule.descriptors[descriptor.basename]) {
319
+ return new error.SyntaxReferenceError('Unknown at-rule descriptor', descriptorName);
320
+ }
321
+ }
322
+ checkPropertyName(propertyName) {
323
+ if (!this.getProperty(propertyName)) {
324
+ return new error.SyntaxReferenceError('Unknown property', propertyName);
325
+ }
326
+ }
327
+
328
+ matchAtrulePrelude(atruleName, prelude) {
329
+ const error = this.checkAtrulePrelude(atruleName, prelude);
330
+
331
+ if (error) {
332
+ return buildMatchResult(null, error);
333
+ }
334
+
335
+ const atrule = this.getAtrule(atruleName);
336
+
337
+ if (!atrule.prelude) {
338
+ return buildMatchResult(null, null);
339
+ }
340
+
341
+ return matchSyntax(this, atrule.prelude, prelude || '', false);
342
+ }
343
+ matchAtruleDescriptor(atruleName, descriptorName, value) {
344
+ const error = this.checkAtruleDescriptorName(atruleName, descriptorName);
345
+
346
+ if (error) {
347
+ return buildMatchResult(null, error);
348
+ }
349
+
350
+ const atrule = this.getAtrule(atruleName);
351
+ const descriptor = names.keyword(descriptorName);
352
+
353
+ return matchSyntax(this, atrule.descriptors[descriptor.name] || atrule.descriptors[descriptor.basename], value, false);
354
+ }
355
+ matchDeclaration(node) {
356
+ if (node.type !== 'Declaration') {
357
+ return buildMatchResult(null, new Error('Not a Declaration node'));
358
+ }
359
+
360
+ return this.matchProperty(node.property, node.value);
361
+ }
362
+ matchProperty(propertyName, value) {
363
+ // don't match syntax for a custom property at the moment
364
+ if (names.property(propertyName).custom) {
365
+ return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties'));
366
+ }
367
+
368
+ const error = this.checkPropertyName(propertyName);
369
+
370
+ if (error) {
371
+ return buildMatchResult(null, error);
372
+ }
373
+
374
+ return matchSyntax(this, this.getProperty(propertyName), value, true);
375
+ }
376
+ matchType(typeName, value) {
377
+ const typeSyntax = this.getType(typeName);
378
+
379
+ if (!typeSyntax) {
380
+ return buildMatchResult(null, new error.SyntaxReferenceError('Unknown type', typeName));
381
+ }
382
+
383
+ return matchSyntax(this, typeSyntax, value, false);
384
+ }
385
+ match(syntax, value) {
386
+ if (typeof syntax !== 'string' && (!syntax || !syntax.type)) {
387
+ return buildMatchResult(null, new error.SyntaxReferenceError('Bad syntax'));
388
+ }
389
+
390
+ if (typeof syntax === 'string' || !syntax.match) {
391
+ syntax = this.createDescriptor(syntax, 'Type', 'anonymous');
392
+ }
393
+
394
+ return matchSyntax(this, syntax, value, false);
395
+ }
396
+
397
+ findValueFragments(propertyName, value, type, name) {
398
+ return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name);
399
+ }
400
+ findDeclarationValueFragments(declaration, type, name) {
401
+ return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);
402
+ }
403
+ findAllFragments(ast, type, name) {
404
+ const result = [];
405
+
406
+ this.syntax.walk(ast, {
407
+ visit: 'Declaration',
408
+ enter: (declaration) => {
409
+ result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));
410
+ }
411
+ });
412
+
413
+ return result;
414
+ }
415
+
416
+ getAtrule(atruleName, fallbackBasename = true) {
417
+ const atrule = names.keyword(atruleName);
418
+ const atruleEntry = atrule.vendor && fallbackBasename
419
+ ? this.atrules[atrule.name] || this.atrules[atrule.basename]
420
+ : this.atrules[atrule.name];
421
+
422
+ return atruleEntry || null;
423
+ }
424
+ getAtrulePrelude(atruleName, fallbackBasename = true) {
425
+ const atrule = this.getAtrule(atruleName, fallbackBasename);
426
+
427
+ return atrule && atrule.prelude || null;
428
+ }
429
+ getAtruleDescriptor(atruleName, name) {
430
+ return this.atrules.hasOwnProperty(atruleName) && this.atrules.declarators
431
+ ? this.atrules[atruleName].declarators[name] || null
432
+ : null;
433
+ }
434
+ getProperty(propertyName, fallbackBasename = true) {
435
+ const property = names.property(propertyName);
436
+ const propertyEntry = property.vendor && fallbackBasename
437
+ ? this.properties[property.name] || this.properties[property.basename]
438
+ : this.properties[property.name];
439
+
440
+ return propertyEntry || null;
441
+ }
442
+ getType(name) {
443
+ return hasOwnProperty.call(this.types, name) ? this.types[name] : null;
444
+ }
445
+
446
+ validate() {
447
+ function syntaxRef(name, isType) {
448
+ return isType ? `<${name}>` : `<'${name}'>`;
449
+ }
450
+
451
+ function validate(syntax, name, broken, descriptor) {
452
+ if (broken.has(name)) {
453
+ return broken.get(name);
454
+ }
455
+
456
+ broken.set(name, false);
457
+ if (descriptor.syntax !== null) {
458
+ walk.walk(descriptor.syntax, function(node) {
459
+ if (node.type !== 'Type' && node.type !== 'Property') {
460
+ return;
461
+ }
462
+
463
+ const map = node.type === 'Type' ? syntax.types : syntax.properties;
464
+ const brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;
465
+
466
+ if (!hasOwnProperty.call(map, node.name)) {
467
+ errors.push(`${syntaxRef(name, broken === brokenTypes)} used missed syntax definition ${syntaxRef(node.name, node.type === 'Type')}`);
468
+ broken.set(name, true);
469
+ } else if (validate(syntax, node.name, brokenMap, map[node.name])) {
470
+ errors.push(`${syntaxRef(name, broken === brokenTypes)} used broken syntax definition ${syntaxRef(node.name, node.type === 'Type')}`);
471
+ broken.set(name, true);
472
+ }
473
+ }, this);
474
+ }
475
+ }
476
+
477
+ const errors = [];
478
+ let brokenTypes = new Map();
479
+ let brokenProperties = new Map();
480
+
481
+ for (const key in this.types) {
482
+ validate(this, key, brokenTypes, this.types[key]);
483
+ }
484
+
485
+ for (const key in this.properties) {
486
+ validate(this, key, brokenProperties, this.properties[key]);
487
+ }
488
+
489
+ const brokenTypesArray = [...brokenTypes.keys()].filter(name => brokenTypes.get(name));
490
+ const brokenPropertiesArray = [...brokenProperties.keys()].filter(name => brokenProperties.get(name));
491
+
492
+ if (brokenTypesArray.length || brokenPropertiesArray.length) {
493
+ return {
494
+ errors,
495
+ types: brokenTypesArray,
496
+ properties: brokenPropertiesArray
497
+ };
498
+ }
499
+
500
+ return null;
501
+ }
502
+ dump(syntaxAsAst, pretty) {
503
+ return {
504
+ generic: this.generic,
505
+ cssWideKeywords: this.cssWideKeywords,
506
+ units: this.units,
507
+ types: dumpMapSyntax(this.types, !pretty, syntaxAsAst),
508
+ properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst),
509
+ atrules: dumpAtruleMapSyntax(this.atrules, !pretty, syntaxAsAst)
510
+ };
511
+ }
512
+ toString() {
513
+ return JSON.stringify(this.dump());
514
+ }
515
+ }
516
+
517
+ exports.Lexer = Lexer;
@@ -0,0 +1,128 @@
1
+ 'use strict';
2
+
3
+ const createCustomError = require('../utils/create-custom-error.cjs');
4
+ const generate = require('../definition-syntax/generate.cjs');
5
+
6
+ const defaultLoc = { offset: 0, line: 1, column: 1 };
7
+
8
+ function locateMismatch(matchResult, node) {
9
+ const tokens = matchResult.tokens;
10
+ const longestMatch = matchResult.longestMatch;
11
+ const mismatchNode = longestMatch < tokens.length ? tokens[longestMatch].node || null : null;
12
+ const badNode = mismatchNode !== node ? mismatchNode : null;
13
+ let mismatchOffset = 0;
14
+ let mismatchLength = 0;
15
+ let entries = 0;
16
+ let css = '';
17
+ let start;
18
+ let end;
19
+
20
+ for (let i = 0; i < tokens.length; i++) {
21
+ const token = tokens[i].value;
22
+
23
+ if (i === longestMatch) {
24
+ mismatchLength = token.length;
25
+ mismatchOffset = css.length;
26
+ }
27
+
28
+ if (badNode !== null && tokens[i].node === badNode) {
29
+ if (i <= longestMatch) {
30
+ entries++;
31
+ } else {
32
+ entries = 0;
33
+ }
34
+ }
35
+
36
+ css += token;
37
+ }
38
+
39
+ if (longestMatch === tokens.length || entries > 1) { // last
40
+ start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css);
41
+ end = buildLoc(start);
42
+ } else {
43
+ start = fromLoc(badNode, 'start') ||
44
+ buildLoc(fromLoc(node, 'start') || defaultLoc, css.slice(0, mismatchOffset));
45
+ end = fromLoc(badNode, 'end') ||
46
+ buildLoc(start, css.substr(mismatchOffset, mismatchLength));
47
+ }
48
+
49
+ return {
50
+ css,
51
+ mismatchOffset,
52
+ mismatchLength,
53
+ start,
54
+ end
55
+ };
56
+ }
57
+
58
+ function fromLoc(node, point) {
59
+ const value = node && node.loc && node.loc[point];
60
+
61
+ if (value) {
62
+ return 'line' in value ? buildLoc(value) : value;
63
+ }
64
+
65
+ return null;
66
+ }
67
+
68
+ function buildLoc({ offset, line, column }, extra) {
69
+ const loc = {
70
+ offset,
71
+ line,
72
+ column
73
+ };
74
+
75
+ if (extra) {
76
+ const lines = extra.split(/\n|\r\n?|\f/);
77
+
78
+ loc.offset += extra.length;
79
+ loc.line += lines.length - 1;
80
+ loc.column = lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1;
81
+ }
82
+
83
+ return loc;
84
+ }
85
+
86
+ const SyntaxReferenceError = function(type, referenceName) {
87
+ const error = createCustomError.createCustomError(
88
+ 'SyntaxReferenceError',
89
+ type + (referenceName ? ' `' + referenceName + '`' : '')
90
+ );
91
+
92
+ error.reference = referenceName;
93
+
94
+ return error;
95
+ };
96
+
97
+ const SyntaxMatchError = function(message, syntax, node, matchResult) {
98
+ const error = createCustomError.createCustomError('SyntaxMatchError', message);
99
+ const {
100
+ css,
101
+ mismatchOffset,
102
+ mismatchLength,
103
+ start,
104
+ end
105
+ } = locateMismatch(matchResult, node);
106
+
107
+ error.rawMessage = message;
108
+ error.syntax = syntax ? generate.generate(syntax) : '<generic>';
109
+ error.css = css;
110
+ error.mismatchOffset = mismatchOffset;
111
+ error.mismatchLength = mismatchLength;
112
+ error.message = message + '\n' +
113
+ ' syntax: ' + error.syntax + '\n' +
114
+ ' value: ' + (css || '<empty string>') + '\n' +
115
+ ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^';
116
+
117
+ Object.assign(error, start);
118
+ error.loc = {
119
+ source: (node && node.loc && node.loc.source) || '<unknown>',
120
+ start,
121
+ end
122
+ };
123
+
124
+ return error;
125
+ };
126
+
127
+ exports.SyntaxMatchError = SyntaxMatchError;
128
+ exports.SyntaxReferenceError = SyntaxReferenceError;