|
| 1 | + |
1 | 2 | ; PREPROCESSOR
|
2 | 3 | ; ============
|
3 | 4 |
|
|
16 | 17 | (["#if" "#ifdef" "#ifndef" "#endif" "#elif" "#else" "#define" "#include"] @punctuation.definition.directive.c
|
17 | 18 | (#set! adjust.endAfterFirstMatchOf "^#"))
|
18 | 19 |
|
19 |
| - |
20 |
| -; This will match if the more specific rules above haven't matched. The |
21 |
| -; anonymous nodes will match under ideal conditions, but might not be present |
22 |
| -; if the parser is flummoxed. |
| 20 | +; `preproc_directive` will be used when the parser doesn't recognize the |
| 21 | +; directive as one of the above. It's permissive; `#afdfafsdfdfad` would be |
| 22 | +; parsed as a `preproc_directive`. |
| 23 | +; |
| 24 | +; Hence this rule will match if the more specific rules above haven't matched. |
| 25 | +; The anonymous nodes will match under ideal conditions, but might not be |
| 26 | +; present even when they ought to be _if_ the parser is flummoxed; so this'll |
| 27 | +; sometimes catch `#ifdef` and others. |
23 | 28 | ((preproc_directive) @keyword.control.directive.c
|
24 | 29 | (#set! capture.shy true))
|
25 | 30 |
|
26 |
| -((preproc_ifdef |
27 |
| - (identifier) @entity.name.function.preprocessor.c |
28 |
| - (#match? @entity.name.function.preprocessor.c "[a-zA-Z_$][\\w$]*"))) |
| 31 | +((preproc_directive) @punctuation.definition.directive.c |
| 32 | + (#set! capture.shy true) |
| 33 | + (#set! adjust.endAfterFirstMatchOf "^#")) |
29 | 34 |
|
| 35 | +; Macro functions are definitely entities. |
30 | 36 | (preproc_function_def
|
31 | 37 | (identifier) @entity.name.function.preprocessor.c
|
32 | 38 | (#set! capture.final true))
|
33 | 39 |
|
| 40 | +; Identifiers in macro definitions are definitely constants. |
| 41 | +((preproc_def |
| 42 | + name: (identifier) @constant.preprocessor.c)) |
| 43 | + |
| 44 | +; We can also safely treat identifiers as constants in `#ifdef`… |
| 45 | +((preproc_ifdef |
| 46 | + (identifier) @constant.preprocessor.c)) |
| 47 | + |
| 48 | +; …and `#if` and `#elif`… |
| 49 | +(preproc_if |
| 50 | + (binary_expression |
| 51 | + (identifier) @constant.preprocessor.c)) |
| 52 | +(preproc_elif |
| 53 | + (binary_expression |
| 54 | + (identifier) @constant.preprocessor.c)) |
| 55 | + |
| 56 | +; …and `#undef`. |
| 57 | +((preproc_call |
| 58 | + directive: (preproc_directive) @_IGNORE_ |
| 59 | + argument: (preproc_arg) @constant.preprocessor.c) |
| 60 | + (#eq? @_IGNORE_ "#undef")) |
| 61 | + |
34 | 62 | (system_lib_string) @string.quoted.other.lt-gt.include.c
|
35 | 63 | ((system_lib_string) @punctuation.definition.string.begin.c
|
36 | 64 | (#set! adjust.endAfterFirstMatchOf "^<"))
|
|
48 | 76 | (#set! capture.final true))
|
49 | 77 |
|
50 | 78 | (primitive_type) @support.storage.type.builtin.c
|
| 79 | + |
| 80 | +; When the user has typed `#define FOO`, the macro injection thinks that `FOO` |
| 81 | +; is a type declaration (for some reason). This node structure seems to exist |
| 82 | +; only in that unusual and incorrect scenario, so we'll stop it from happening |
| 83 | +; so that it doesn't override the underlying `constant.other.c` scope. |
| 84 | +(translation_unit |
| 85 | + (type_identifier) @_IGNORE_ |
| 86 | + (#set! capture.final)) |
| 87 | + |
51 | 88 | (type_identifier) @support.other.storage.type.c
|
52 | 89 |
|
53 | 90 | ; These types are all reserved words; if we see an identifier with this name,
|
|
133 | 170 |
|
134 | 171 | ; The "x" in `int x;`
|
135 | 172 | (declaration
|
136 |
| - declarator: (identifier) @variable.declaration.c) |
| 173 | + declarator: (identifier) @variable.other.declaration.c) |
137 | 174 |
|
138 | 175 | ; The "x" in `int x = y;`
|
139 | 176 | (init_declarator
|
140 |
| - declarator: (identifier) @variable.declaration.c) |
| 177 | + declarator: (identifier) @variable.other.declaration.c) |
141 | 178 |
|
142 | 179 | ; The "x" in `SomeType *x;`
|
143 | 180 | ; (Should work no matter how many pointers deep we are.)
|
144 | 181 | (pointer_declarator
|
145 |
| - declarator: [(identifier) (field_identifier)] @variable.declaration.pointer.c |
| 182 | + declarator: [(identifier) (field_identifier)] @variable.other.declaration.pointer.c |
146 | 183 | (#is? test.descendantOfType "declaration field_declaration"))
|
147 | 184 |
|
| 185 | +; An array declarator: the "table" in `int table[4];` |
| 186 | +(array_declarator |
| 187 | + declarator: (identifier) @variable.other.declaration.c) |
| 188 | + |
148 | 189 | ; A member of a struct.
|
149 | 190 | (field_declaration
|
150 |
| - (field_identifier) @variable.declaration.member.c) |
| 191 | + (field_identifier) @variable.other.declaration.member.c) |
151 | 192 |
|
152 | 193 | ; An attribute in a C99 struct designated initializer:
|
153 | 194 | ; the "foo" in `MY_TYPE a = { .foo = true };
|
154 | 195 | (initializer_pair
|
155 | 196 | (field_designator
|
156 |
| - (field_identifier) @variable.declaration.member.c)) |
| 197 | + (field_identifier) @variable.other.declaration.member.c)) |
157 | 198 |
|
158 | 199 | ; (and the associated ".")
|
159 | 200 | (initializer_pair
|
|
162 | 203 |
|
163 | 204 | (field_declaration
|
164 | 205 | (pointer_declarator
|
165 |
| - (field_identifier) @variable.declaration.member.c)) |
| 206 | + (field_identifier) @variable.other.declaration.member.c)) |
166 | 207 |
|
167 | 208 | (field_declaration
|
168 | 209 | (array_declarator
|
169 |
| - (field_identifier) @variable.declaration.member.c)) |
| 210 | + (field_identifier) @variable.other.declaration.member.c)) |
170 | 211 |
|
171 | 212 | (init_declarator
|
172 | 213 | (pointer_declarator
|
173 |
| - (identifier) @variable.declaration.member.c)) |
| 214 | + (identifier) @variable.other.declaration.member.c)) |
174 | 215 |
|
175 | 216 | ; The "x" in `x = y;`
|
176 | 217 | (assignment_expression
|
|
253 | 294 | (false)
|
254 | 295 | ] @constant.language._TYPE_.c
|
255 | 296 |
|
256 |
| -((identifier) @constant.c |
257 |
| - (#match? @constant.c "[_A-Z][_A-Z0-9]*$")) |
| 297 | +; Don't try to scope (e.g.) `int FOO = 1` as a constant when the user types `=` |
| 298 | +; but has not typed the value yet. |
| 299 | +(ERROR |
| 300 | + (identifier) @_IGNORE_ |
| 301 | + (#set! capture.final)) |
| 302 | + |
| 303 | +; In most languages we wouldn't be making the assumption that an all-caps |
| 304 | +; identifier should be treated as a constant. But those languages don't have |
| 305 | +; macro preprocessors. The convention is decently strong in C/C++ that all-caps |
| 306 | +; identifiers will refer to `#define`d things. |
| 307 | +((identifier) @constant.other.c |
| 308 | + (#match? @constant.other.c "[_A-Z][_A-Z0-9]*$") |
| 309 | + (#set! capture.shy)) |
258 | 310 |
|
259 | 311 |
|
260 | 312 | ; COMMENTS
|
|
0 commit comments