├── COPYING.txt
├── README.md
├── colors
└── clamp.vim
├── plugin
└── clamp.vim
├── python
├── clamp_helper.py
├── clang
│ ├── __init__.py
│ ├── cindex.py
│ └── enumerations.py
├── compilation_database.py
└── engine.py
└── syntax
└── clamp.vim
/COPYING.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Clamp: NeoVim plugin to highlight C-family code
2 |
3 | ## Intro
4 |
5 | Clamp is a neovim plugin to support C-family code powered by libclang.
6 | Currently it can highlight and rename-refactor code semantically. Clamp takes
7 | the advantage of new plugin architecture of neovim and it runs very smooth.
8 |
9 | ## Requirements
10 |
11 | Clamp requires the following:
12 |
13 | * NeoVim
14 | * libclang, http://llvm.org/apt/
15 | * python-client of msg-pack, https://github.com/neovim/python-client
16 |
17 | ## Installation
18 |
19 | use vim plugin manager, for example
20 |
21 | * Vundle Install:
22 | ```vim
23 | Bundle 'bbchung/Clamp'
24 | ```
25 |
26 | ## Options
27 |
28 | ### g:clamp_autostart
29 |
30 | Start Clamp automatically.
31 |
32 | Default: `1`
33 | ```vim
34 | let g:clamp_autostart = 0
35 | ```
36 |
37 | ### g:clamp_libclang_path
38 |
39 | Config the libclang path if libclang is not in default path or Clamp can't
40 | find it.
41 |
42 | Default: `''`
43 | ```vim
44 | let g:clamp_libclang_file = '/usr/lib/libclang.so'
45 | ```
46 |
47 | ### g:clamp_highlight_blacklist
48 |
49 | Define the group of syntax NOT to be highlighted.
50 |
51 | Default: `['clampInclusionDirective']`
52 |
53 | The recommend setting to not be dazzled:
54 | ```vim
55 | let g:clamp_highlight_blacklist = ['clampNamespaceRef', 'clampFunctionDecl', 'clampFieldDecl', 'clampDeclRefExprCall', 'clampMemberRefExprCall', 'clampMemberRefExprVar', 'clampNamespace', 'clampNamespaceRef', 'cligherInclusionDirective', 'clampVarDecl']
56 | ```
57 |
58 | ### g:clamp_heuristic_compile_args
59 |
60 | Clamp search the compilation database to compile, but the compilation
61 | database the CMake generated doesn't include the header files. Clamp can
62 | heuristic search the compilation database to guess the most possible compile
63 | args if set this option.
64 |
65 | Default: `1`
66 | ```vim
67 | let g:clamp_heuristic_compile_args = 1
68 | ```
69 |
70 | ### g:clamp_compile_args
71 |
72 | The global compile args of Clamp.
73 |
74 | Default: `[]`
75 | ```vim
76 | let g:clamp_compile_args = []
77 | ```
78 |
79 | ### g:clamp_highlight_mode
80 |
81 | Set it to 1 only if you DON'T use autocomplete plugin like
82 | [YouCompleteMe][ycm].
83 |
84 | Default: `0`
85 | ```vim
86 | let g:clamp_highlight_mode = 1
87 | ```
88 |
89 | ## Commands and Functions
90 |
91 | Clamp provides these commands and functions.
92 |
93 | ### ClampStart
94 |
95 | ### ClampShutdown
96 |
97 | ### ClampRename()
98 |
99 | * An experimental function to do rename-refactor.
100 | * The scope is opened vim buffers.
101 | * There is no one-step undo/redo method.
102 | * Strongly recommend that backing up all files before calling this function.
103 | * For convenience, you can add key mapping in your vimrc:
104 | ```vim
105 | nmap r :call ClampRename()
106 | ```
107 |
108 | ## Compilation Database
109 |
110 | Clamp automatically load and parse the compilation database
111 | "compile_commands.json" if it exists in current working directory, then the
112 | compile options will be passed to libclang. For more information about
113 | compilation database, please reference [Compilation Database][cdb].
114 |
115 | ## Highlight Group
116 |
117 | Clamp defines these highlight groups corresponded to libclang.
118 |
119 | ```vim
120 | hi default link clampPrepro PreProc
121 | hi default link clampDecl Identifier
122 | hi default link clampRef Type
123 | hi default link clampInclusionDirective cIncluded
124 | hi default link clampMacroInstantiation Constant
125 | hi default link clampVarDecl Identifier
126 | hi default link clampStructDecl Identifier
127 | hi default link clampUnionDecl Identifier
128 | hi default link clampClassDecl Identifier
129 | hi default link clampEnumDecl Identifier
130 | hi default link clampParmDecl Identifier
131 | hi default link clampFunctionDecl Identifier
132 | hi default link clampFieldDecl Identifier
133 | hi default link clampEnumConstantDecl Constant
134 | hi default link clampDeclRefExprEnum Constant
135 | hi default link clampDeclRefExprCall Type
136 | hi default link clampMemberRefExprCall Type
137 | hi default link clampMemberRefExprVar Type
138 | hi default link clampTypeRef Type
139 | hi default link clampNamespace Identifier
140 | hi default link clampNamespaceRef Type
141 | hi default link clampTemplateTypeParameter Identifier
142 | hi default link clampTemplateNoneTypeParameter Identifier
143 | hi default link clampTemplateRef Type
144 | hi default link clampOccurrences IncSearch
145 | ```
146 |
147 | You can customize these colors in your colorscheme, for example:
148 | ```vim
149 | hi clampTypeRef term=NONE cterm=NONE ctermbg=232 ctermfg=255 gui=NONE
150 | ```
151 | ## FAQ
152 |
153 | ### The Clamp plugin doesn't work?
154 | Check the Requirements and Installation.
155 |
156 | ### Why rename-refactor function is an experimental function?
157 | Due to the character of c-family language, it's hard to do rename-refactor.
158 | Clamp only search the current opened buffer to do rename-refactor and it can't
159 | guarantee the correctness.
160 |
161 | ### Crash?
162 | Clamp may crashes in some cases. Call ClampStart again if it happens.
163 |
164 | ### Highlighting always are messed up as typing, can fix?
165 | No, Clamp use matchaddpos() api currently. Once NeoVim provides more powerful
166 | api, I will use it.
167 |
168 | ### How to set compile args?
169 | Clamp set the compile args for each file with (g:clamp_compile_args +
170 | "compilation database"). Compile args will affect the correctness of highlight
171 | and rename-refactor.
172 |
173 | ## LICENSE
174 |
175 | This software is licensed under the [GPL v3 license][gpl].
176 |
177 | Note: This license does not cover the files that come from the LLVM project.
178 |
179 |
180 | [gpl]: http://www.gnu.org/copyleft/gpl.html
181 | [ycm]: https://github.com/Valloric/YouCompleteMe
182 | [cdb]: http://clang.llvm.org/docs/JSONCompilationDatabase.html
183 |
--------------------------------------------------------------------------------
/colors/clamp.vim:
--------------------------------------------------------------------------------
1 | set background=dark
2 |
3 | hi clear
4 | if exists('syntax_on')
5 | syntax reset
6 | endif
7 |
8 | let g:colors_name = expand(':t:r')
9 |
10 | " default {
11 | hi Normal term=NONE cterm=NONE ctermbg=234 ctermfg=254 gui=NONE guibg=#151515 guifg=#e8e8d3
12 | hi IncSearch term=NONE cterm=NONE ctermbg=60 ctermfg=fg gui=None guibg=#4F4F4F guifg=None
13 | hi Search term=NONE cterm=NONE ctermbg=24 ctermfg=fg gui=None guibg=#606000 guifg=None
14 | hi SpellLocal term=NONE cterm=bold,undercurl ctermbg=NONE ctermfg=30 gui=undercurl guibg=bg guifg=fg guisp=DarkCyan
15 | hi SpellBad term=reverse cterm=bold,undercurl ctermbg=NONE ctermfg=1 gui=bold,undercurl,italic guibg=None guifg=#FF0000 guisp=Red
16 | hi SpellCap term=underline cterm=bold,undercurl ctermbg=NONE ctermfg=3 gui=bold,undercurl,italic guibg=None guifg=#FFFF00 guisp=Blue
17 | hi SpellRare term=reverse cterm=bold,undercurl ctermbg=NONE ctermfg=201 gui=undercurl guibg=bg guifg=fg guisp=Magenta
18 | hi DiffAdd term=bold cterm=NONE ctermbg=26 ctermfg=fg gui=NONE guibg=#005fd7 guifg=fg
19 | hi DiffChange term=bold cterm=NONE ctermbg=95 ctermfg=fg gui=NONE guibg=#875f5f guifg=fg
20 | hi DiffDelete term=bold cterm=bold ctermbg=152 ctermfg=fg gui=bold guibg=#afd7d7 guifg=fg
21 | hi DiffText term=reverse cterm=bold ctermbg=1 ctermfg=fg gui=bold guibg=#800000 guifg=fg
22 | hi Cursor term=NONE cterm=NONE ctermbg=NONE ctermfg=NONE gui=NONE guibg=None guifg=None
23 | hi CursorColumn term=NONE cterm=NONE ctermbg=16 ctermfg=NONE gui=NONE guibg=#1c1c1c guifg=fg
24 | hi CursorLine term=NONE cterm=NONE ctermbg=16 ctermfg=NONE gui=NONE guibg=#000000 guifg=fg
25 | hi CursorLineNr term=underline cterm=NONE ctermbg=bg ctermfg=130 gui=NONE guibg=None guifg=#CD9366
26 | hi LineNr term=underline cterm=NONE ctermbg=NONE ctermfg=241 gui=NONE guibg=None guifg=#605958
27 | hi Pmenu term=NONE cterm=NONE ctermbg=237 ctermfg=251 gui=NONE guibg=#292929 guifg=None
28 | hi PmenuSel term=NONE cterm=NONE ctermbg=24 ctermfg=fg gui=NONE guibg=#588080 guifg=None
29 | hi PmenuSbar term=NONE cterm=NONE ctermbg=250 ctermfg=fg gui=NONE guibg=DarkGrey guifg=None
30 | hi PmenuThumb term=NONE cterm=NONE ctermbg=237 ctermfg=NONE gui=None guibg=#606060 guifg=None
31 | hi StatusLine term=reverse,bold cterm=NONE ctermbg=235 ctermfg=229 gui=italic guibg=#1c1c1c guifg=#ffffaf
32 | hi StatusLineNC term=reverse cterm=NONE ctermbg=235 ctermfg=241 gui=italic guibg=#1c1c1c guifg=#626262
33 | hi VertSplit term=reverse cterm=NONE ctermbg=NONE ctermfg=242 gui=bold guibg=#293329 guifg=#0F330F
34 | hi Folded term=NONE cterm=italic ctermbg=235 ctermfg=109 gui=italic guibg=#272D33 guifg=#9FB7D0
35 | hi FoldColumn term=NONE cterm=NONE ctermbg=235 ctermfg=145 gui=NONE guibg=#384048 guifg=#a0a8b0
36 | hi Title term=bold cterm=bold ctermbg=bg ctermfg=71 gui=bold guibg=bg guifg=#70b950
37 | hi Visual term=reverse cterm=NONE ctermbg=237 ctermfg=NONE gui=NONE guibg=#3E3E3E guifg=fg
38 | hi VisualNOS term=bold cterm=bold,underline ctermbg=234 ctermfg=fg gui=bold,underline guibg=bg guifg=fg
39 | hi SpecialKey term=bold cterm=NONE ctermbg=236 ctermfg=244 gui=NONE guibg=#343434 guifg=#808080
40 | hi NonText term=bold cterm=bold ctermbg=NONE ctermfg=244 gui=bold guibg=NONE guifg=#808080
41 | hi Directory term=bold cterm=NONE ctermbg=bg ctermfg=186 gui=NONE guibg=bg guifg=#dad085
42 | hi ErrorMsg term=NONE cterm=NONE ctermbg=196 ctermfg=231 gui=NONE guibg=Red guifg=White
43 | hi MoreMsg term=bold cterm=bold ctermbg=bg ctermfg=29 gui=bold guibg=bg guifg=SeaGreen
44 | hi ModeMsg term=bold cterm=bold ctermbg=bg ctermfg=fg gui=bold guibg=bg guifg=fg
45 | hi TabLine term=underline cterm=NONE ctermbg=145 ctermfg=16 gui=italic guibg=#b0b8c0 guifg=black
46 | hi TabLineSel term=bold cterm=bold ctermbg=255 ctermfg=16 gui=bold,italic guibg=#f0f0f0 guifg=black
47 | hi TabLineFill term=reverse cterm=NONE ctermbg=103 ctermfg=bg gui=reverse guibg=bg guifg=#9098a0
48 | hi ColorColumn term=reverse cterm=NONE ctermbg=23 ctermfg=fg gui=NONE guibg=#4b5a00 guifg=fg
49 | hi MatchParen term=reverse cterm=bold ctermbg=108 ctermfg=231 gui=bold guibg=#80a090 guifg=white
50 | hi helpNormal term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
51 | hi helpGraphic term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
52 | hi helpLeadBlank term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
53 | hi Question term=NONE cterm=bold ctermbg=bg ctermfg=29 gui=bold guibg=bg guifg=SeaGreen
54 | hi StringDelimiter term=NONE cterm=NONE ctermbg=bg ctermfg=59 gui=NONE guibg=bg guifg=#556633
55 | hi NONE term=NONE cterm=NONE ctermbg=None ctermfg=None gui=NONE guibg=NONE guifg=None
56 | hi WarningMsg term=NONE cterm=NONE ctermbg=bg ctermfg=220 gui=NONE guibg=bg guifg=Red
57 | hi WildMenu term=NONE cterm=NONE ctermbg=226 ctermfg=16 gui=NONE guibg=Yellow guifg=Black
58 | hi SignColumn term=NONE cterm=NONE ctermbg=59 ctermfg=145 gui=NONE guibg=NONE guifg=#a0a8b0
59 | hi Conceal term=NONE cterm=NONE ctermbg=66 ctermfg=252 gui=NONE guibg=DarkGrey guifg=LightGrey
60 | " }
61 |
62 | " syncolor {
63 |
64 | hi Error term=reverse cterm=NONE ctermbg=None ctermfg=231 gui=NONE guibg=#602020 guifg=White
65 | hi Comment term=NONE cterm=NONE ctermbg=None ctermfg=102 gui=None guibg=None guifg=#888888
66 | hi Constant term=NONE cterm=NONE ctermbg=None ctermfg=167 gui=NONE guibg=None guifg=#cf6a4c
67 | hi Special term=NONE cterm=NONE ctermbg=None ctermfg=107 gui=NONE guibg=None guifg=#799d6a
68 | hi Identifier term=NONE cterm=NONE ctermbg=None ctermfg=183 gui=NONE guibg=None guifg=#c6b6ee
69 | hi Statement term=NONE cterm=NONE ctermbg=None ctermfg=103 gui=NONE guibg=None guifg=#8197bf
70 | hi PreProc term=NONE cterm=NONE ctermbg=None ctermfg=110 gui=NONE guibg=None guifg=#8fbfdc
71 | hi Type term=NONE cterm=NONE ctermbg=None ctermfg=215 gui=NONE guibg=None guifg=#ffb964
72 | hi Underlined term=underline cterm=underline ctermbg=None ctermfg=111 gui=underline guibg=None guifg=#80a0ff
73 | hi Ignore term=NONE cterm=NONE ctermbg=None ctermfg=233 gui=NONE guibg=None guifg=None
74 | hi Todo term=bold cterm=bold,italic ctermbg=None ctermfg=251 gui=bold,italic guibg=None guifg=#c7c7c7
75 | hi String term=NONE cterm=NONE ctermbg=None ctermfg=107 gui=NONE guibg=None guifg=#99ad6a
76 | hi Function term=NONE cterm=NONE ctermbg=None ctermfg=222 gui=NONE guibg=None guifg=#fad07a
77 | hi StorageClass term=NONE cterm=NONE ctermbg=None ctermfg=179 gui=NONE guibg=None guifg=#c59f6f
78 | hi Structure term=NONE cterm=NONE ctermbg=None ctermfg=110 gui=NONE guibg=None guifg=#8fbfdc
79 | hi Delimiter term=NONE cterm=NONE ctermbg=None ctermfg=66 gui=NONE guibg=None guifg=#668799
80 | " }
81 |
82 | " syntastic {
83 | hi SyntasticErrorSign guifg=RED guibg=None
84 | hi SyntasticWarningSign guifg=Yellow guibg=None
85 | hi SyntasticErrorLine guifg=NONE guibg=NONE
86 | hi SyntasticWarningLine guifg=None guibg=NONE
87 | hi SyntasticError term=reverse cterm=bold,undercurl ctermbg=NONE ctermfg=1 gui=bold,undercurl,italic guibg=None guifg=#FF0000 guisp=Red
88 | hi SyntasticWarning term=underline cterm=bold,undercurl ctermbg=NONE ctermfg=3 gui=bold,undercurl,italic guibg=None guifg=#FFFF00 guisp=Blue
89 | hi SyntasticStyleErrorSign guifg=#CD0000 guibg=None
90 | hi SyntasticStyleWarningSign guifg=#cdcd00 guibg=None
91 | "}
92 |
93 | " VimL {
94 | hi vimExtCmd term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
95 | hi vimFilter term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
96 | hi vimHiFontname term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
97 | hi vimNormCmds term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
98 | hi vimAugroupSyncA term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
99 | hi vimGroupList term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
100 | hi vimMapRhsExtend term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
101 | hi vimMenuPriority term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
102 | hi vimAutoEventList term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
103 | hi vimSet term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
104 | hi vimUserCmd term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
105 | hi vimCmdSep term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
106 | hi vimIsCommand term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
107 | hi vimVar term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
108 | hi vimFBVar term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
109 | hi vimAutoCmdSfxList term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
110 | hi vimFiletype term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
111 | hi vimFunction term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
112 | hi vimAuSyntax term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
113 | hi vimGroupName term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
114 | hi vimOperParen term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
115 | hi vimRegion term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
116 | hi vimSynLine term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
117 | hi vimSynKeyRegion term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
118 | hi vimSynMatchRegion term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
119 | hi VimSynMtchCchar term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
120 | hi vimAugroup term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
121 | hi vimAugroupError term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
122 | hi vimMenuBang term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
123 | hi vimSynPatMod term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
124 | hi vimSyncLines term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
125 | hi vimSyncLinebreak term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
126 | hi vimSyncLinecont term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
127 | hi vimSyncRegion term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
128 | hi vimMenuMap term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
129 | hi vimMenuRhs term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
130 | hi vimEcho term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
131 | hi vimExecute term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
132 | hi vimIf term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
133 | hi vimHiLink term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
134 | hi vimHiClear term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
135 | hi vimHiKeyList term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
136 | hi vimHiBang term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
137 | hi vimFuncBody term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
138 | hi vimFuncBlank term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
139 | hi vimEscapeBrace term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
140 | hi vimSetEqual term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
141 | hi vimSubstRep term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
142 | hi vimSubstRange term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
143 | hi vimClusterName term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
144 | hi vimHiCtermColor term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
145 | hi vimHiTermcap term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
146 | hi vimCommentTitleLeader term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
147 | hi vimPatRegion term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
148 | hi vimCollection term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
149 | hi vimSubstPat term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
150 | hi vimSynRegion term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
151 | hi vimGlobal term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
152 | hi vimHiGuiFontname term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
153 | hi vimAutoCmdSpace term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
154 | hi vimSubstRep4 term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
155 | hi vimCollClass term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
156 | hi vimMapRhs term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
157 | hi vimSyncMatch term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
158 | hi vimMapLhs term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
159 | " }
160 |
161 | "lua {
162 | hi vimLuaRegion term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
163 | hi luaTableBlock term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
164 | hi luaInnerComment term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
165 | hi luaCondElseif term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
166 | hi luaCondEnd term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
167 | hi luaCondStart term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
168 | hi luaBlock term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
169 | hi luaRepeatBlock term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
170 | hi luaParen term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
171 | hi luaFunctionBlock term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
172 | " }
173 |
174 | " Perl {
175 | hi vimPerlRegion term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
176 | hi perlGenericBlock term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
177 | hi perlVarBlock term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
178 | hi perlVarBlock2 term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
179 | hi perlSync term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
180 | hi perlSyncPOD term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
181 | hi perlFiledescStatementNocomma term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
182 | hi perlFiledescStatementComma term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
183 | hi perlStatementIndirObjWrap term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
184 | hi perlVarMember term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
185 | hi perlPackageConst term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
186 | hi perlSpecialStringU2 term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
187 | hi perlParensSQ term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
188 | hi perlBracketsSQ term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
189 | hi perlBracesSQ term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
190 | hi perlAnglesSQ term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
191 | hi perlParensDQ term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
192 | hi perlBracketsDQ term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
193 | hi perlBracesDQ term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
194 | hi perlAnglesDQ term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
195 | hi perlAutoload term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
196 | hi perlFormat term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
197 | " }
198 |
199 | " Ruby {
200 | hi vimRubyRegion term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
201 | hi rubyInterpolation term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
202 | hi rubyDelimEscape term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
203 | hi rubyNestedParentheses term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
204 | hi rubyNestedCurlyBraces term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
205 | hi rubyNestedAngleBrackets term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
206 | hi rubyNestedSquareBrackets term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
207 | hi rubyRegexpParens term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
208 | hi rubyRegexpBrackets term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
209 | hi rubyLocalVariableOrMethod term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
210 | hi rubyBlockArgument term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
211 | hi rubyBlockParameterList term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
212 | hi rubyHeredocStart term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
213 | hi rubyAliasDeclaration2 term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
214 | hi rubyMethodDeclaration term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
215 | hi rubyClassDeclaration term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
216 | hi rubyClass term=NONE cterm=NONE ctermbg=bg ctermfg=66 gui=NONE guibg=bg guifg=#447799
217 | hi rubyIdentifier term=NONE cterm=NONE ctermbg=bg ctermfg=183 gui=NONE guibg=bg guifg=#c6b6fe
218 | hi rubyMethodBlock term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
219 | hi rubyBlock term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
220 | hi rubyDoBlock term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
221 | hi rubyCurlyBlock term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
222 | hi rubyArrayDelimiter term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
223 | hi rubyKeywordAsMethod term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
224 | hi rubyInstanceVariable term=NONE cterm=NONE ctermbg=bg ctermfg=183 gui=NONE guibg=bg guifg=#c6b6fe
225 | hi rubySymbol term=NONE cterm=NONE ctermbg=bg ctermfg=104 gui=NONE guibg=bg guifg=#7697d6
226 | hi rubyControl term=NONE cterm=NONE ctermbg=bg ctermfg=104 gui=NONE guibg=bg guifg=#7597c6
227 | hi rubyRegexpDelimiter term=NONE cterm=NONE ctermbg=bg ctermfg=53 gui=NONE guibg=bg guifg=#540063
228 | hi rubyRegexp term=NONE cterm=NONE ctermbg=bg ctermfg=162 gui=NONE guibg=bg guifg=#dd0093
229 | hi rubyArrayLiteral term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
230 | hi rubyBlockExpression term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
231 | hi rubyCaseExpression term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
232 | hi rubyConditionalExpression term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
233 | hi rubyOptionalDoLine term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
234 | hi rubyRepeatExpression term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
235 | hi rubyMultilineComment term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
236 | hi rubyRegexpSpecial term=NONE cterm=NONE ctermbg=bg ctermfg=125 gui=NONE guibg=bg guifg=#a40073
237 | hi rubyPredefinedIdentifier term=NONE cterm=NONE ctermbg=bg ctermfg=168 gui=NONE guibg=bg guifg=#de5577
238 | hi rubyAliasDeclaration term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
239 | hi rubyModuleDeclaration term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
240 | " }
241 |
242 | " python {
243 | hi vimPythonRegion term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
244 | hi pythonSync term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
245 | hi pythonSpaceError term=NONE cterm=NONE ctermbg=bg ctermfg=fg gui=NONE guibg=bg guifg=fg
246 | " }
247 |
248 | " vim: tw=0 ts=4 sw=4 foldmarker={,} foldlevel=0 foldmethod=marker
249 |
--------------------------------------------------------------------------------
/plugin/clamp.vim:
--------------------------------------------------------------------------------
1 | if !has('nvim')
2 | echohl WarningMsg |
3 | \ echomsg 'Clamp unavailable: requires neovim' |
4 | \ echohl None
5 | finish
6 | endif
7 |
8 | if exists('g:loaded_clamp')
9 | finish
10 | endif
11 |
12 | let s:script_folder_path = escape( expand( ':p:h' ), '\' )
13 | execute('source '. s:script_folder_path . '/../syntax/clamp.vim')
14 |
15 | fun! ClampHighlight(bufname, highlights)
16 | if a:bufname != expand('%:p')
17 | return
18 | endif
19 |
20 | for [l:priority, l:matches] in a:highlights
21 | for l:m in getmatches()
22 | if l:priority == l:m['priority']
23 | call matchdelete(l:m['id'])
24 | endif
25 | endfor
26 |
27 | for [l:group, l:all_pos] in items(l:matches)
28 | let s:count = 0
29 | let s:match8 = []
30 |
31 | for l:pos in l:all_pos
32 | call add(s:match8, l:pos)
33 | let s:count = s:count + 1
34 | if s:count == 8
35 | call matchaddpos(l:group, s:match8, l:priority)
36 |
37 | let s:count = 0
38 | let s:match8 = []
39 | endif
40 | endfor
41 |
42 | call matchaddpos(l:group, s:match8, l:priority)
43 | endfor
44 | endfor
45 | endf
46 |
47 | fun! Shutdown()
48 | let a:wnr = winnr()
49 | windo call s:clear_match_by_priorities([g:clamp_occurrence_priority, g:clamp_syntax_priority])
50 | exe a:wnr.'wincmd w'
51 |
52 | silent! unlet g:clamp_channel
53 |
54 | endf
55 |
56 | fun! s:clear_match_by_priorities(priorities)
57 | for l:m in getmatches()
58 | if index(a:priorities, l:m['priority']) >= 0
59 | call matchdelete(l:m['id'])
60 | endif
61 | endfor
62 | endf
63 |
64 | fun! s:start_clamp()
65 | call s:request_shutdown()
66 | let g:clamp_channel = rpcstart('python', [s:script_folder_path.'/../python/engine.py'])
67 | "let g:clamp_channel = jobstart('python '.s:script_folder_path.'/../python/engine.py '.v:servername)
68 | call ClampOnTextChanged()
69 | call ClampReqHighlight()
70 | endf
71 |
72 | fun! s:request_shutdown()
73 | if exists('g:clamp_channel')
74 | silent! call rpcrequest(g:clamp_channel, 'shutdown')
75 | call rpcstop(g:clamp_channel)
76 | endif
77 |
78 | call Shutdown()
79 | endf
80 |
81 | fun! ClampReqHighlight()
82 | if index(['c', 'cpp', 'objc', 'objcpp'], &filetype) == -1
83 | return
84 | endif
85 |
86 | if exists('g:clamp_channel')
87 | let s:pos = getpos('.')
88 | silent! call rpcrequest(g:clamp_channel, 'highlight', expand('%:p'), line('w0'), line('w$'), s:pos[1], s:pos[2])
89 | endif
90 | endf
91 |
92 | fun! ClampOnTextChanged()
93 | if index(['c', 'cpp', 'objc', 'objcpp'], &filetype) == -1
94 | return
95 | endif
96 |
97 | if exists('g:clamp_channel')
98 | call rpcrequest(g:clamp_channel, 'parse', expand('%:p'), b:changedtick, join(getline(1,'$'), "\n"))
99 | endif
100 | endf
101 |
102 | fun! ClampCursorInfo()
103 | if !exists('g:clamp_channel')
104 | return
105 | endif
106 |
107 | let s:pos = getpos('.')
108 | let s:result = rpcrequest(g:clamp_channel, 'cursor_info', expand('%:p'), s:pos[1], s:pos[2])
109 |
110 | echo s:result
111 | endf
112 |
113 | fun! ClampRename()
114 | if !exists('g:clamp_channel')
115 | return
116 | endif
117 | let s:pos = getpos('.')
118 | let s:result = rpcrequest(g:clamp_channel, 'rename', expand('%:p'), s:pos[1], s:pos[2])
119 | if empty(s:result) || empty(s:result['renames'])
120 | return
121 | endif
122 |
123 | let s:old = s:result['old']
124 | echohl WildMenu
125 | let s:new = input('Rename ' . s:old . ' : ', s:old)
126 | echohl None
127 | if (empty(s:new) || s:old == s:new)
128 | return
129 | endif
130 |
131 | let l:wnr = winnr()
132 | let l:bufnr = bufnr('')
133 | let l:qflist = []
134 | bufdo! call s:clamp_replace(s:result['renames'], s:old, s:new, l:qflist)
135 | exe l:wnr.'wincmd w'
136 | exe 'buffer '.l:bufnr
137 | call setqflist(l:qflist)
138 |
139 | endf
140 |
141 | fun! s:clamp_replace(renames, old, new, qflist)
142 | if (!has_key(a:renames, expand('%:p')) || empty(a:renames[expand('%:p')]))
143 | return
144 | endif
145 | let l:locations = a:renames[expand('%:p')]
146 |
147 | let l:choice = confirm("rename '". a:old ."' to '" .a:new. "' in " .expand('%:p'). "?", "&Yes\n&No", 1)
148 | if (l:choice == 2)
149 | return
150 | endif
151 |
152 | let l:pattern = ''
153 | for [l:row, l:col] in l:locations
154 | if (!empty(l:pattern))
155 | let l:pattern = l:pattern . '\|'
156 | endif
157 |
158 | let l:pattern = l:pattern . '\%' . l:row . 'l' . '\%>' . (l:col - 1) . 'c\%<' . (l:col + strlen(a:old)) . 'c' . a:old
159 | call add(a:qflist, {'filename':bufname(''), 'bufnr':bufnr(''), 'lnum':l:row, 'text':"'".a:old."' was renamed to '".a:new."'"})
160 | endfor
161 |
162 | let l:cmd = '%s/' . l:pattern . '/' . a:new . '/gI'
163 |
164 | execute(l:cmd)
165 | copen
166 | endf
167 |
168 |
169 |
170 | let g:clamp_occurrence_priority = get(g:, 'clamp_occurrence_priority', -1)
171 | let g:clamp_syntax_priority = get(g:, 'clamp_syntax_priority', -2)
172 | let g:clamp_autostart = get(g:, 'clamp_autostart', 1)
173 | let g:clamp_libclang_path = get(g:, 'clamp_libclang_path', '')
174 | let g:clamp_highlight_blacklist = get(g:, 'clamp_highlight_blacklist', ['clampInclusionDirective'])
175 | let g:clamp_heuristic_compile_args = get(g:, 'clamp_heuristic_compile_args', 1)
176 | let g:clamp_compile_args = get(g:, 'clamp_compile_args', [])
177 | let g:clamp_highlight_mode = get(g:, 'clamp_highlight_mode', 0)
178 |
179 | command! ClampStart call s:start_clamp()
180 | command! ClampShutdown call s:request_shutdown()
181 |
182 | augroup Clamp
183 | if g:clamp_autostart
184 | au VimEnter *.c,*.cpp,*.h,*.hpp call s:start_clamp()
185 | endif
186 | au VimLeave * silent! call s:request_shutdown()
187 | au BufEnter,InsertLeave,TextChanged * call ClampOnTextChanged()
188 | au CursorMoved,CursorMovedI * call ClampReqHighlight()
189 | if (g:clamp_highlight_mode == 1)
190 | au TextChangedI * call ClampOnTextChanged()
191 | endif
192 | augroup END
193 |
194 | let g:loaded_clamp=1
195 |
--------------------------------------------------------------------------------
/python/clamp_helper.py:
--------------------------------------------------------------------------------
1 | from clang import cindex
2 |
3 | def get_cursor(tu, filepath, row, col):
4 | return cindex.Cursor.from_location(
5 | tu,
6 | cindex.SourceLocation.from_position(tu,
7 | tu.get_file(filepath),
8 | row,
9 | col))
10 |
11 | def get_semantic_symbol_from_location(tu, filepath, row, col):
12 | cursor = get_cursor(tu, filepath, row, col);
13 | if not cursor:
14 | return None
15 |
16 | tokens = cursor.get_tokens()
17 | for token in tokens:
18 | if token.kind.value == 2 and row == token.location.line and token.location.column <= col and col < token.location.column + \
19 | len(token.spelling):
20 | symbol = get_semantic_symbol(cursor)
21 | if symbol and symbol.spelling == token.spelling:
22 | return symbol
23 |
24 | return None
25 |
26 |
27 | def is_vim_buffer_allowed(buf):
28 | return buf.options['filetype'] in ["c", "cpp", "objc", "objcpp"]
29 |
30 |
31 | def is_global_symbol(symbol):
32 | return symbol.kind.is_preprocessing(
33 | ) or symbol.semantic_parent.kind != cindex.CursorKind.FUNCTION_DECL
34 |
35 |
36 | def search_cursor_by_usr(cursor, usr, result):
37 | if cursor.get_usr() == usr and cursor not in result:
38 | result.append(cursor)
39 |
40 | for c in cursor.get_children():
41 | search_cursor_by_usr(c, usr, result)
42 |
43 |
44 | def get_semantic_symbol(cursor):
45 | if cursor.kind == cindex.CursorKind.MACRO_DEFINITION:
46 | return cursor
47 |
48 | symbol = cursor.get_definition()
49 | if not symbol:
50 | symbol = cursor.referenced
51 |
52 | if not symbol:
53 | return None
54 |
55 | if symbol.kind == cindex.CursorKind.CONSTRUCTOR or symbol.kind == cindex.CursorKind.DESTRUCTOR:
56 | symbol = symbol.semantic_parent
57 |
58 | return symbol
59 |
60 |
61 | def search_referenced_tokens_by_usr(tu, usr, result, spelling):
62 | tokens = tu.cursor.get_tokens()
63 | for token in tokens:
64 | cursor = token.cursor
65 | cursor._tu = tu
66 |
67 | symbol = get_semantic_symbol(cursor)
68 | if token.spelling == spelling and symbol and symbol.get_usr() == usr:
69 | result.append((token.location.line, token.location.column))
70 |
--------------------------------------------------------------------------------
/python/clang/__init__.py:
--------------------------------------------------------------------------------
1 | #===- __init__.py - Clang Python Bindings --------------------*- python -*--===#
2 | #
3 | # The LLVM Compiler Infrastructure
4 | #
5 | # This file is distributed under the University of Illinois Open Source
6 | # License. See LICENSE.TXT for details.
7 | #
8 | #===------------------------------------------------------------------------===#
9 |
10 | r"""
11 | Clang Library Bindings
12 | ======================
13 |
14 | This package provides access to the Clang compiler and libraries.
15 |
16 | The available modules are:
17 |
18 | cindex
19 |
20 | Bindings for the Clang indexing library.
21 | """
22 |
23 | __all__ = ['cindex']
24 |
25 |
--------------------------------------------------------------------------------
/python/clang/cindex.py:
--------------------------------------------------------------------------------
1 | #===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===#
2 | #
3 | # The LLVM Compiler Infrastructure
4 | #
5 | # This file is distributed under the University of Illinois Open Source
6 | # License. See LICENSE.TXT for details.
7 | #
8 | #===------------------------------------------------------------------------===#
9 |
10 | r"""
11 | Clang Indexing Library Bindings
12 | ===============================
13 |
14 | This module provides an interface to the Clang indexing library. It is a
15 | low-level interface to the indexing library which attempts to match the Clang
16 | API directly while also being "pythonic". Notable differences from the C API
17 | are:
18 |
19 | * string results are returned as Python strings, not CXString objects.
20 |
21 | * null cursors are translated to None.
22 |
23 | * access to child cursors is done via iteration, not visitation.
24 |
25 | The major indexing objects are:
26 |
27 | Index
28 |
29 | The top-level object which manages some global library state.
30 |
31 | TranslationUnit
32 |
33 | High-level object encapsulating the AST for a single translation unit. These
34 | can be loaded from .ast files or parsed on the fly.
35 |
36 | Cursor
37 |
38 | Generic object for representing a node in the AST.
39 |
40 | SourceRange, SourceLocation, and File
41 |
42 | Objects representing information about the input source.
43 |
44 | Most object information is exposed using properties, when the underlying API
45 | call is efficient.
46 | """
47 |
48 | # TODO
49 | # ====
50 | #
51 | # o API support for invalid translation units. Currently we can't even get the
52 | # diagnostics on failure because they refer to locations in an object that
53 | # will have been invalidated.
54 | #
55 | # o fix memory management issues (currently client must hold on to index and
56 | # translation unit, or risk crashes).
57 | #
58 | # o expose code completion APIs.
59 | #
60 | # o cleanup ctypes wrapping, would be nice to separate the ctypes details more
61 | # clearly, and hide from the external interface (i.e., help(cindex)).
62 | #
63 | # o implement additional SourceLocation, SourceRange, and File methods.
64 |
65 | from ctypes import *
66 | import collections
67 |
68 | import clang.enumerations
69 |
70 | # ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
71 | # object. This is a problem, because it means that from_parameter will see an
72 | # integer and pass the wrong value on platforms where int != void*. Work around
73 | # this by marshalling object arguments as void**.
74 | c_object_p = POINTER(c_void_p)
75 |
76 | callbacks = {}
77 |
78 | ### Exception Classes ###
79 |
80 | class TranslationUnitLoadError(Exception):
81 | """Represents an error that occurred when loading a TranslationUnit.
82 |
83 | This is raised in the case where a TranslationUnit could not be
84 | instantiated due to failure in the libclang library.
85 |
86 | FIXME: Make libclang expose additional error information in this scenario.
87 | """
88 | pass
89 |
90 | class TranslationUnitSaveError(Exception):
91 | """Represents an error that occurred when saving a TranslationUnit.
92 |
93 | Each error has associated with it an enumerated value, accessible under
94 | e.save_error. Consumers can compare the value with one of the ERROR_
95 | constants in this class.
96 | """
97 |
98 | # Indicates that an unknown error occurred. This typically indicates that
99 | # I/O failed during save.
100 | ERROR_UNKNOWN = 1
101 |
102 | # Indicates that errors during translation prevented saving. The errors
103 | # should be available via the TranslationUnit's diagnostics.
104 | ERROR_TRANSLATION_ERRORS = 2
105 |
106 | # Indicates that the translation unit was somehow invalid.
107 | ERROR_INVALID_TU = 3
108 |
109 | def __init__(self, enumeration, message):
110 | assert isinstance(enumeration, int)
111 |
112 | if enumeration < 1 or enumeration > 3:
113 | raise Exception("Encountered undefined TranslationUnit save error "
114 | "constant: %d. Please file a bug to have this "
115 | "value supported." % enumeration)
116 |
117 | self.save_error = enumeration
118 | Exception.__init__(self, 'Error %d: %s' % (enumeration, message))
119 |
120 | ### Structures and Utility Classes ###
121 |
122 | class CachedProperty(object):
123 | """Decorator that lazy-loads the value of a property.
124 |
125 | The first time the property is accessed, the original property function is
126 | executed. The value it returns is set as the new value of that instance's
127 | property, replacing the original method.
128 | """
129 |
130 | def __init__(self, wrapped):
131 | self.wrapped = wrapped
132 | try:
133 | self.__doc__ = wrapped.__doc__
134 | except:
135 | pass
136 |
137 | def __get__(self, instance, instance_type=None):
138 | if instance is None:
139 | return self
140 |
141 | value = self.wrapped(instance)
142 | setattr(instance, self.wrapped.__name__, value)
143 |
144 | return value
145 |
146 |
147 | class _CXString(Structure):
148 | """Helper for transforming CXString results."""
149 |
150 | _fields_ = [("spelling", c_char_p), ("free", c_int)]
151 |
152 | def __del__(self):
153 | conf.lib.clang_disposeString(self)
154 |
155 | @staticmethod
156 | def from_result(res, fn, args):
157 | assert isinstance(res, _CXString)
158 | return conf.lib.clang_getCString(res)
159 |
160 | class SourceLocation(Structure):
161 | """
162 | A SourceLocation represents a particular location within a source file.
163 | """
164 | _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
165 | _data = None
166 |
167 | def _get_instantiation(self):
168 | if self._data is None:
169 | f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
170 | conf.lib.clang_getInstantiationLocation(self, byref(f), byref(l),
171 | byref(c), byref(o))
172 | if f:
173 | f = File(f)
174 | else:
175 | f = None
176 | self._data = (f, int(l.value), int(c.value), int(o.value))
177 | return self._data
178 |
179 | @staticmethod
180 | def from_position(tu, file, line, column):
181 | """
182 | Retrieve the source location associated with a given file/line/column in
183 | a particular translation unit.
184 | """
185 | return conf.lib.clang_getLocation(tu, file, line, column)
186 |
187 | @staticmethod
188 | def from_offset(tu, file, offset):
189 | """Retrieve a SourceLocation from a given character offset.
190 |
191 | tu -- TranslationUnit file belongs to
192 | file -- File instance to obtain offset from
193 | offset -- Integer character offset within file
194 | """
195 | return conf.lib.clang_getLocationForOffset(tu, file, offset)
196 |
197 | @property
198 | def file(self):
199 | """Get the file represented by this source location."""
200 | return self._get_instantiation()[0]
201 |
202 | @property
203 | def line(self):
204 | """Get the line represented by this source location."""
205 | return self._get_instantiation()[1]
206 |
207 | @property
208 | def column(self):
209 | """Get the column represented by this source location."""
210 | return self._get_instantiation()[2]
211 |
212 | @property
213 | def offset(self):
214 | """Get the file offset represented by this source location."""
215 | return self._get_instantiation()[3]
216 |
217 | def __eq__(self, other):
218 | return conf.lib.clang_equalLocations(self, other)
219 |
220 | def __ne__(self, other):
221 | return not self.__eq__(other)
222 |
223 | def __repr__(self):
224 | if self.file:
225 | filename = self.file.name
226 | else:
227 | filename = None
228 | return "" % (
229 | filename, self.line, self.column)
230 |
231 | class SourceRange(Structure):
232 | """
233 | A SourceRange describes a range of source locations within the source
234 | code.
235 | """
236 | _fields_ = [
237 | ("ptr_data", c_void_p * 2),
238 | ("begin_int_data", c_uint),
239 | ("end_int_data", c_uint)]
240 |
241 | # FIXME: Eliminate this and make normal constructor? Requires hiding ctypes
242 | # object.
243 | @staticmethod
244 | def from_locations(start, end):
245 | return conf.lib.clang_getRange(start, end)
246 |
247 | @property
248 | def start(self):
249 | """
250 | Return a SourceLocation representing the first character within a
251 | source range.
252 | """
253 | return conf.lib.clang_getRangeStart(self)
254 |
255 | @property
256 | def end(self):
257 | """
258 | Return a SourceLocation representing the last character within a
259 | source range.
260 | """
261 | return conf.lib.clang_getRangeEnd(self)
262 |
263 | def __eq__(self, other):
264 | return conf.lib.clang_equalRanges(self, other)
265 |
266 | def __ne__(self, other):
267 | return not self.__eq__(other)
268 |
269 | def __contains__(self, other):
270 | """Useful to detect the Token/Lexer bug"""
271 | if not isinstance(other, SourceLocation):
272 | return False
273 | if other.file is None and self.start.file is None:
274 | pass
275 | elif ( self.start.file.name != other.file.name or
276 | other.file.name != self.end.file.name):
277 | # same file name
278 | return False
279 | # same file, in between lines
280 | if self.start.line < other.line < self.end.line:
281 | return True
282 | elif self.start.line == other.line:
283 | # same file first line
284 | if self.start.column <= other.column:
285 | return True
286 | elif other.line == self.end.line:
287 | # same file last line
288 | if other.column <= self.end.column:
289 | return True
290 | return False
291 |
292 | def __repr__(self):
293 | return "" % (self.start, self.end)
294 |
295 | class Diagnostic(object):
296 | """
297 | A Diagnostic is a single instance of a Clang diagnostic. It includes the
298 | diagnostic severity, the message, the location the diagnostic occurred, as
299 | well as additional source ranges and associated fix-it hints.
300 | """
301 |
302 | Ignored = 0
303 | Note = 1
304 | Warning = 2
305 | Error = 3
306 | Fatal = 4
307 |
308 | def __init__(self, ptr):
309 | self.ptr = ptr
310 |
311 | def __del__(self):
312 | conf.lib.clang_disposeDiagnostic(self)
313 |
314 | @property
315 | def severity(self):
316 | return conf.lib.clang_getDiagnosticSeverity(self)
317 |
318 | @property
319 | def location(self):
320 | return conf.lib.clang_getDiagnosticLocation(self)
321 |
322 | @property
323 | def spelling(self):
324 | return conf.lib.clang_getDiagnosticSpelling(self)
325 |
326 | @property
327 | def ranges(self):
328 | class RangeIterator:
329 | def __init__(self, diag):
330 | self.diag = diag
331 |
332 | def __len__(self):
333 | return int(conf.lib.clang_getDiagnosticNumRanges(self.diag))
334 |
335 | def __getitem__(self, key):
336 | if (key >= len(self)):
337 | raise IndexError
338 | return conf.lib.clang_getDiagnosticRange(self.diag, key)
339 |
340 | return RangeIterator(self)
341 |
342 | @property
343 | def fixits(self):
344 | class FixItIterator:
345 | def __init__(self, diag):
346 | self.diag = diag
347 |
348 | def __len__(self):
349 | return int(conf.lib.clang_getDiagnosticNumFixIts(self.diag))
350 |
351 | def __getitem__(self, key):
352 | range = SourceRange()
353 | value = conf.lib.clang_getDiagnosticFixIt(self.diag, key,
354 | byref(range))
355 | if len(value) == 0:
356 | raise IndexError
357 |
358 | return FixIt(range, value)
359 |
360 | return FixItIterator(self)
361 |
362 | @property
363 | def category_number(self):
364 | """The category number for this diagnostic or 0 if unavailable."""
365 | return conf.lib.clang_getDiagnosticCategory(self)
366 |
367 | @property
368 | def category_name(self):
369 | """The string name of the category for this diagnostic."""
370 | return conf.lib.clang_getDiagnosticCategoryText(self)
371 |
372 | @property
373 | def option(self):
374 | """The command-line option that enables this diagnostic."""
375 | return conf.lib.clang_getDiagnosticOption(self, None)
376 |
377 | @property
378 | def disable_option(self):
379 | """The command-line option that disables this diagnostic."""
380 | disable = _CXString()
381 | conf.lib.clang_getDiagnosticOption(self, byref(disable))
382 |
383 | return conf.lib.clang_getCString(disable)
384 |
385 | def __repr__(self):
386 | return "" % (
387 | self.severity, self.location, self.spelling)
388 |
389 | def from_param(self):
390 | return self.ptr
391 |
392 | class FixIt(object):
393 | """
394 | A FixIt represents a transformation to be applied to the source to
395 | "fix-it". The fix-it shouldbe applied by replacing the given source range
396 | with the given value.
397 | """
398 |
399 | def __init__(self, range, value):
400 | self.range = range
401 | self.value = value
402 |
403 | def __repr__(self):
404 | return "" % (self.range, self.value)
405 |
406 | class TokenGroup(object):
407 | """Helper class to facilitate token management.
408 |
409 | Tokens are allocated from libclang in chunks. They must be disposed of as a
410 | collective group.
411 |
412 | One purpose of this class is for instances to represent groups of allocated
413 | tokens. Each token in a group contains a reference back to an instance of
414 | this class. When all tokens from a group are garbage collected, it allows
415 | this class to be garbage collected. When this class is garbage collected,
416 | it calls the libclang destructor which invalidates all tokens in the group.
417 |
418 | You should not instantiate this class outside of this module.
419 | """
420 | def __init__(self, tu, memory, count):
421 | self._tu = tu
422 | self._memory = memory
423 | self._count = count
424 |
425 | def __del__(self):
426 | conf.lib.clang_disposeTokens(self._tu, self._memory, self._count)
427 |
428 | @staticmethod
429 | def get_tokens(tu, extent):
430 | """Helper method to return all tokens in an extent.
431 |
432 | This functionality is needed multiple places in this module. We define
433 | it here because it seems like a logical place.
434 | """
435 | tokens_memory = POINTER(Token)()
436 | tokens_count = c_uint()
437 |
438 | conf.lib.clang_tokenize(tu, extent, byref(tokens_memory),
439 | byref(tokens_count))
440 |
441 | count = int(tokens_count.value)
442 |
443 | # If we get no tokens, no memory was allocated. Be sure not to return
444 | # anything and potentially call a destructor on nothing.
445 | if count < 1:
446 | return
447 |
448 | tokens_array = cast(tokens_memory, POINTER(Token * count)).contents
449 |
450 | token_group = TokenGroup(tu, tokens_memory, tokens_count)
451 |
452 | for i in xrange(0, count):
453 | token = Token()
454 | token.int_data = tokens_array[i].int_data
455 | token.ptr_data = tokens_array[i].ptr_data
456 | token._tu = tu
457 | token._group = token_group
458 |
459 | yield token
460 |
461 | class TokenKind(object):
462 | """Describes a specific type of a Token."""
463 |
464 | _value_map = {} # int -> TokenKind
465 |
466 | def __init__(self, value, name):
467 | """Create a new TokenKind instance from a numeric value and a name."""
468 | self.value = value
469 | self.name = name
470 |
471 | def __repr__(self):
472 | return 'TokenKind.%s' % (self.name,)
473 |
474 | @staticmethod
475 | def from_value(value):
476 | """Obtain a registered TokenKind instance from its value."""
477 | result = TokenKind._value_map.get(value, None)
478 |
479 | if result is None:
480 | raise ValueError('Unknown TokenKind: %d' % value)
481 |
482 | return result
483 |
484 | @staticmethod
485 | def register(value, name):
486 | """Register a new TokenKind enumeration.
487 |
488 | This should only be called at module load time by code within this
489 | package.
490 | """
491 | if value in TokenKind._value_map:
492 | raise ValueError('TokenKind already registered: %d' % value)
493 |
494 | kind = TokenKind(value, name)
495 | TokenKind._value_map[value] = kind
496 | setattr(TokenKind, name, kind)
497 |
498 | ### Cursor Kinds ###
499 | class BaseEnumeration(object):
500 | """
501 | Common base class for named enumerations held in sync with Index.h values.
502 |
503 | Subclasses must define their own _kinds and _name_map members, as:
504 | _kinds = []
505 | _name_map = None
506 | These values hold the per-subclass instances and value-to-name mappings,
507 | respectively.
508 |
509 | """
510 |
511 | def __init__(self, value):
512 | if value >= len(self.__class__._kinds):
513 | self.__class__._kinds += [None] * (value - len(self.__class__._kinds) + 1)
514 | if self.__class__._kinds[value] is not None:
515 | raise ValueError,'{0} value {1} already loaded'.format(
516 | str(self.__class__), value)
517 | self.value = value
518 | self.__class__._kinds[value] = self
519 | self.__class__._name_map = None
520 |
521 |
522 | def from_param(self):
523 | return self.value
524 |
525 | @property
526 | def name(self):
527 | """Get the enumeration name of this cursor kind."""
528 | if self._name_map is None:
529 | self._name_map = {}
530 | for key, value in self.__class__.__dict__.items():
531 | if isinstance(value, self.__class__):
532 | self._name_map[value] = key
533 | return self._name_map[self]
534 |
535 | @classmethod
536 | def from_id(cls, id):
537 | if id >= len(cls._kinds) or cls._kinds[id] is None:
538 | raise ValueError,'Unknown template argument kind %d' % id
539 | return cls._kinds[id]
540 |
541 | def __repr__(self):
542 | return '%s.%s' % (self.__class__, self.name,)
543 |
544 |
545 | class CursorKind(BaseEnumeration):
546 | """
547 | A CursorKind describes the kind of entity that a cursor points to.
548 | """
549 |
550 | # The required BaseEnumeration declarations.
551 | _kinds = []
552 | _name_map = None
553 |
554 | @staticmethod
555 | def get_all_kinds():
556 | """Return all CursorKind enumeration instances."""
557 | return filter(None, CursorKind._kinds)
558 |
559 | def is_declaration(self):
560 | """Test if this is a declaration kind."""
561 | return conf.lib.clang_isDeclaration(self)
562 |
563 | def is_reference(self):
564 | """Test if this is a reference kind."""
565 | return conf.lib.clang_isReference(self)
566 |
567 | def is_expression(self):
568 | """Test if this is an expression kind."""
569 | return conf.lib.clang_isExpression(self)
570 |
571 | def is_statement(self):
572 | """Test if this is a statement kind."""
573 | return conf.lib.clang_isStatement(self)
574 |
575 | def is_attribute(self):
576 | """Test if this is an attribute kind."""
577 | return conf.lib.clang_isAttribute(self)
578 |
579 | def is_invalid(self):
580 | """Test if this is an invalid kind."""
581 | return conf.lib.clang_isInvalid(self)
582 |
583 | def is_translation_unit(self):
584 | """Test if this is a translation unit kind."""
585 | return conf.lib.clang_isTranslationUnit(self)
586 |
587 | def is_preprocessing(self):
588 | """Test if this is a preprocessing kind."""
589 | return conf.lib.clang_isPreprocessing(self)
590 |
591 | def is_unexposed(self):
592 | """Test if this is an unexposed kind."""
593 | return conf.lib.clang_isUnexposed(self)
594 |
595 | def __repr__(self):
596 | return 'CursorKind.%s' % (self.name,)
597 |
598 | ###
599 | # Declaration Kinds
600 |
601 | # A declaration whose specific kind is not exposed via this interface.
602 | #
603 | # Unexposed declarations have the same operations as any other kind of
604 | # declaration; one can extract their location information, spelling, find their
605 | # definitions, etc. However, the specific kind of the declaration is not
606 | # reported.
607 | CursorKind.UNEXPOSED_DECL = CursorKind(1)
608 |
609 | # A C or C++ struct.
610 | CursorKind.STRUCT_DECL = CursorKind(2)
611 |
612 | # A C or C++ union.
613 | CursorKind.UNION_DECL = CursorKind(3)
614 |
615 | # A C++ class.
616 | CursorKind.CLASS_DECL = CursorKind(4)
617 |
618 | # An enumeration.
619 | CursorKind.ENUM_DECL = CursorKind(5)
620 |
621 | # A field (in C) or non-static data member (in C++) in a struct, union, or C++
622 | # class.
623 | CursorKind.FIELD_DECL = CursorKind(6)
624 |
625 | # An enumerator constant.
626 | CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
627 |
628 | # A function.
629 | CursorKind.FUNCTION_DECL = CursorKind(8)
630 |
631 | # A variable.
632 | CursorKind.VAR_DECL = CursorKind(9)
633 |
634 | # A function or method parameter.
635 | CursorKind.PARM_DECL = CursorKind(10)
636 |
637 | # An Objective-C @interface.
638 | CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
639 |
640 | # An Objective-C @interface for a category.
641 | CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
642 |
643 | # An Objective-C @protocol declaration.
644 | CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
645 |
646 | # An Objective-C @property declaration.
647 | CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
648 |
649 | # An Objective-C instance variable.
650 | CursorKind.OBJC_IVAR_DECL = CursorKind(15)
651 |
652 | # An Objective-C instance method.
653 | CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
654 |
655 | # An Objective-C class method.
656 | CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
657 |
658 | # An Objective-C @implementation.
659 | CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
660 |
661 | # An Objective-C @implementation for a category.
662 | CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
663 |
664 | # A typedef.
665 | CursorKind.TYPEDEF_DECL = CursorKind(20)
666 |
667 | # A C++ class method.
668 | CursorKind.CXX_METHOD = CursorKind(21)
669 |
670 | # A C++ namespace.
671 | CursorKind.NAMESPACE = CursorKind(22)
672 |
673 | # A linkage specification, e.g. 'extern "C"'.
674 | CursorKind.LINKAGE_SPEC = CursorKind(23)
675 |
676 | # A C++ constructor.
677 | CursorKind.CONSTRUCTOR = CursorKind(24)
678 |
679 | # A C++ destructor.
680 | CursorKind.DESTRUCTOR = CursorKind(25)
681 |
682 | # A C++ conversion function.
683 | CursorKind.CONVERSION_FUNCTION = CursorKind(26)
684 |
685 | # A C++ template type parameter
686 | CursorKind.TEMPLATE_TYPE_PARAMETER = CursorKind(27)
687 |
688 | # A C++ non-type template paramater.
689 | CursorKind.TEMPLATE_NON_TYPE_PARAMETER = CursorKind(28)
690 |
691 | # A C++ template template parameter.
692 | CursorKind.TEMPLATE_TEMPLATE_PARAMETER = CursorKind(29)
693 |
694 | # A C++ function template.
695 | CursorKind.FUNCTION_TEMPLATE = CursorKind(30)
696 |
697 | # A C++ class template.
698 | CursorKind.CLASS_TEMPLATE = CursorKind(31)
699 |
700 | # A C++ class template partial specialization.
701 | CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = CursorKind(32)
702 |
703 | # A C++ namespace alias declaration.
704 | CursorKind.NAMESPACE_ALIAS = CursorKind(33)
705 |
706 | # A C++ using directive
707 | CursorKind.USING_DIRECTIVE = CursorKind(34)
708 |
709 | # A C++ using declaration
710 | CursorKind.USING_DECLARATION = CursorKind(35)
711 |
712 | # A Type alias decl.
713 | CursorKind.TYPE_ALIAS_DECL = CursorKind(36)
714 |
715 | # A Objective-C synthesize decl
716 | CursorKind.OBJC_SYNTHESIZE_DECL = CursorKind(37)
717 |
718 | # A Objective-C dynamic decl
719 | CursorKind.OBJC_DYNAMIC_DECL = CursorKind(38)
720 |
721 | # A C++ access specifier decl.
722 | CursorKind.CXX_ACCESS_SPEC_DECL = CursorKind(39)
723 |
724 |
725 | ###
726 | # Reference Kinds
727 |
728 | CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
729 | CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
730 | CursorKind.OBJC_CLASS_REF = CursorKind(42)
731 |
732 | # A reference to a type declaration.
733 | #
734 | # A type reference occurs anywhere where a type is named but not
735 | # declared. For example, given:
736 | # typedef unsigned size_type;
737 | # size_type size;
738 | #
739 | # The typedef is a declaration of size_type (CXCursor_TypedefDecl),
740 | # while the type of the variable "size" is referenced. The cursor
741 | # referenced by the type of size is the typedef for size_type.
742 | CursorKind.TYPE_REF = CursorKind(43)
743 | CursorKind.CXX_BASE_SPECIFIER = CursorKind(44)
744 |
745 | # A reference to a class template, function template, template
746 | # template parameter, or class template partial specialization.
747 | CursorKind.TEMPLATE_REF = CursorKind(45)
748 |
749 | # A reference to a namespace or namepsace alias.
750 | CursorKind.NAMESPACE_REF = CursorKind(46)
751 |
752 | # A reference to a member of a struct, union, or class that occurs in
753 | # some non-expression context, e.g., a designated initializer.
754 | CursorKind.MEMBER_REF = CursorKind(47)
755 |
756 | # A reference to a labeled statement.
757 | CursorKind.LABEL_REF = CursorKind(48)
758 |
759 | # A reference to a set of overloaded functions or function templates
760 | # that has not yet been resolved to a specific function or function template.
761 | CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
762 |
763 | # A reference to a variable that occurs in some non-expression
764 | # context, e.g., a C++ lambda capture list.
765 | CursorKind.VARIABLE_REF = CursorKind(50)
766 |
767 | ###
768 | # Invalid/Error Kinds
769 |
770 | CursorKind.INVALID_FILE = CursorKind(70)
771 | CursorKind.NO_DECL_FOUND = CursorKind(71)
772 | CursorKind.NOT_IMPLEMENTED = CursorKind(72)
773 | CursorKind.INVALID_CODE = CursorKind(73)
774 |
775 | ###
776 | # Expression Kinds
777 |
778 | # An expression whose specific kind is not exposed via this interface.
779 | #
780 | # Unexposed expressions have the same operations as any other kind of
781 | # expression; one can extract their location information, spelling, children,
782 | # etc. However, the specific kind of the expression is not reported.
783 | CursorKind.UNEXPOSED_EXPR = CursorKind(100)
784 |
785 | # An expression that refers to some value declaration, such as a function,
786 | # varible, or enumerator.
787 | CursorKind.DECL_REF_EXPR = CursorKind(101)
788 |
789 | # An expression that refers to a member of a struct, union, class, Objective-C
790 | # class, etc.
791 | CursorKind.MEMBER_REF_EXPR = CursorKind(102)
792 |
793 | # An expression that calls a function.
794 | CursorKind.CALL_EXPR = CursorKind(103)
795 |
796 | # An expression that sends a message to an Objective-C object or class.
797 | CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
798 |
799 | # An expression that represents a block literal.
800 | CursorKind.BLOCK_EXPR = CursorKind(105)
801 |
802 | # An integer literal.
803 | CursorKind.INTEGER_LITERAL = CursorKind(106)
804 |
805 | # A floating point number literal.
806 | CursorKind.FLOATING_LITERAL = CursorKind(107)
807 |
808 | # An imaginary number literal.
809 | CursorKind.IMAGINARY_LITERAL = CursorKind(108)
810 |
811 | # A string literal.
812 | CursorKind.STRING_LITERAL = CursorKind(109)
813 |
814 | # A character literal.
815 | CursorKind.CHARACTER_LITERAL = CursorKind(110)
816 |
817 | # A parenthesized expression, e.g. "(1)".
818 | #
819 | # This AST node is only formed if full location information is requested.
820 | CursorKind.PAREN_EXPR = CursorKind(111)
821 |
822 | # This represents the unary-expression's (except sizeof and
823 | # alignof).
824 | CursorKind.UNARY_OPERATOR = CursorKind(112)
825 |
826 | # [C99 6.5.2.1] Array Subscripting.
827 | CursorKind.ARRAY_SUBSCRIPT_EXPR = CursorKind(113)
828 |
829 | # A builtin binary operation expression such as "x + y" or
830 | # "x <= y".
831 | CursorKind.BINARY_OPERATOR = CursorKind(114)
832 |
833 | # Compound assignment such as "+=".
834 | CursorKind.COMPOUND_ASSIGNMENT_OPERATOR = CursorKind(115)
835 |
836 | # The ?: ternary operator.
837 | CursorKind.CONDITIONAL_OPERATOR = CursorKind(116)
838 |
839 | # An explicit cast in C (C99 6.5.4) or a C-style cast in C++
840 | # (C++ [expr.cast]), which uses the syntax (Type)expr.
841 | #
842 | # For example: (int)f.
843 | CursorKind.CSTYLE_CAST_EXPR = CursorKind(117)
844 |
845 | # [C99 6.5.2.5]
846 | CursorKind.COMPOUND_LITERAL_EXPR = CursorKind(118)
847 |
848 | # Describes an C or C++ initializer list.
849 | CursorKind.INIT_LIST_EXPR = CursorKind(119)
850 |
851 | # The GNU address of label extension, representing &&label.
852 | CursorKind.ADDR_LABEL_EXPR = CursorKind(120)
853 |
854 | # This is the GNU Statement Expression extension: ({int X=4; X;})
855 | CursorKind.StmtExpr = CursorKind(121)
856 |
857 | # Represents a C11 generic selection.
858 | CursorKind.GENERIC_SELECTION_EXPR = CursorKind(122)
859 |
860 | # Implements the GNU __null extension, which is a name for a null
861 | # pointer constant that has integral type (e.g., int or long) and is the same
862 | # size and alignment as a pointer.
863 | #
864 | # The __null extension is typically only used by system headers, which define
865 | # NULL as __null in C++ rather than using 0 (which is an integer that may not
866 | # match the size of a pointer).
867 | CursorKind.GNU_NULL_EXPR = CursorKind(123)
868 |
869 | # C++'s static_cast<> expression.
870 | CursorKind.CXX_STATIC_CAST_EXPR = CursorKind(124)
871 |
872 | # C++'s dynamic_cast<> expression.
873 | CursorKind.CXX_DYNAMIC_CAST_EXPR = CursorKind(125)
874 |
875 | # C++'s reinterpret_cast<> expression.
876 | CursorKind.CXX_REINTERPRET_CAST_EXPR = CursorKind(126)
877 |
878 | # C++'s const_cast<> expression.
879 | CursorKind.CXX_CONST_CAST_EXPR = CursorKind(127)
880 |
881 | # Represents an explicit C++ type conversion that uses "functional"
882 | # notion (C++ [expr.type.conv]).
883 | #
884 | # Example:
885 | # \code
886 | # x = int(0.5);
887 | # \endcode
888 | CursorKind.CXX_FUNCTIONAL_CAST_EXPR = CursorKind(128)
889 |
890 | # A C++ typeid expression (C++ [expr.typeid]).
891 | CursorKind.CXX_TYPEID_EXPR = CursorKind(129)
892 |
893 | # [C++ 2.13.5] C++ Boolean Literal.
894 | CursorKind.CXX_BOOL_LITERAL_EXPR = CursorKind(130)
895 |
896 | # [C++0x 2.14.7] C++ Pointer Literal.
897 | CursorKind.CXX_NULL_PTR_LITERAL_EXPR = CursorKind(131)
898 |
899 | # Represents the "this" expression in C++
900 | CursorKind.CXX_THIS_EXPR = CursorKind(132)
901 |
902 | # [C++ 15] C++ Throw Expression.
903 | #
904 | # This handles 'throw' and 'throw' assignment-expression. When
905 | # assignment-expression isn't present, Op will be null.
906 | CursorKind.CXX_THROW_EXPR = CursorKind(133)
907 |
908 | # A new expression for memory allocation and constructor calls, e.g:
909 | # "new CXXNewExpr(foo)".
910 | CursorKind.CXX_NEW_EXPR = CursorKind(134)
911 |
912 | # A delete expression for memory deallocation and destructor calls,
913 | # e.g. "delete[] pArray".
914 | CursorKind.CXX_DELETE_EXPR = CursorKind(135)
915 |
916 | # Represents a unary expression.
917 | CursorKind.CXX_UNARY_EXPR = CursorKind(136)
918 |
919 | # ObjCStringLiteral, used for Objective-C string literals i.e. "foo".
920 | CursorKind.OBJC_STRING_LITERAL = CursorKind(137)
921 |
922 | # ObjCEncodeExpr, used for in Objective-C.
923 | CursorKind.OBJC_ENCODE_EXPR = CursorKind(138)
924 |
925 | # ObjCSelectorExpr used for in Objective-C.
926 | CursorKind.OBJC_SELECTOR_EXPR = CursorKind(139)
927 |
928 | # Objective-C's protocol expression.
929 | CursorKind.OBJC_PROTOCOL_EXPR = CursorKind(140)
930 |
931 | # An Objective-C "bridged" cast expression, which casts between
932 | # Objective-C pointers and C pointers, transferring ownership in the process.
933 | #
934 | # \code
935 | # NSString *str = (__bridge_transfer NSString *)CFCreateString();
936 | # \endcode
937 | CursorKind.OBJC_BRIDGE_CAST_EXPR = CursorKind(141)
938 |
939 | # Represents a C++0x pack expansion that produces a sequence of
940 | # expressions.
941 | #
942 | # A pack expansion expression contains a pattern (which itself is an
943 | # expression) followed by an ellipsis. For example:
944 | CursorKind.PACK_EXPANSION_EXPR = CursorKind(142)
945 |
946 | # Represents an expression that computes the length of a parameter
947 | # pack.
948 | CursorKind.SIZE_OF_PACK_EXPR = CursorKind(143)
949 |
950 | # Represents a C++ lambda expression that produces a local function
951 | # object.
952 | #
953 | # \code
954 | # void abssort(float *x, unsigned N) {
955 | # std::sort(x, x + N,
956 | # [](float a, float b) {
957 | # return std::abs(a) < std::abs(b);
958 | # });
959 | # }
960 | # \endcode
961 | CursorKind.LAMBDA_EXPR = CursorKind(144)
962 |
963 | # Objective-c Boolean Literal.
964 | CursorKind.OBJ_BOOL_LITERAL_EXPR = CursorKind(145)
965 |
966 | # Represents the "self" expression in a ObjC method.
967 | CursorKind.OBJ_SELF_EXPR = CursorKind(146)
968 |
969 |
970 | # A statement whose specific kind is not exposed via this interface.
971 | #
972 | # Unexposed statements have the same operations as any other kind of statement;
973 | # one can extract their location information, spelling, children, etc. However,
974 | # the specific kind of the statement is not reported.
975 | CursorKind.UNEXPOSED_STMT = CursorKind(200)
976 |
977 | # A labelled statement in a function.
978 | CursorKind.LABEL_STMT = CursorKind(201)
979 |
980 | # A compound statement
981 | CursorKind.COMPOUND_STMT = CursorKind(202)
982 |
983 | # A case statement.
984 | CursorKind.CASE_STMT = CursorKind(203)
985 |
986 | # A default statement.
987 | CursorKind.DEFAULT_STMT = CursorKind(204)
988 |
989 | # An if statement.
990 | CursorKind.IF_STMT = CursorKind(205)
991 |
992 | # A switch statement.
993 | CursorKind.SWITCH_STMT = CursorKind(206)
994 |
995 | # A while statement.
996 | CursorKind.WHILE_STMT = CursorKind(207)
997 |
998 | # A do statement.
999 | CursorKind.DO_STMT = CursorKind(208)
1000 |
1001 | # A for statement.
1002 | CursorKind.FOR_STMT = CursorKind(209)
1003 |
1004 | # A goto statement.
1005 | CursorKind.GOTO_STMT = CursorKind(210)
1006 |
1007 | # An indirect goto statement.
1008 | CursorKind.INDIRECT_GOTO_STMT = CursorKind(211)
1009 |
1010 | # A continue statement.
1011 | CursorKind.CONTINUE_STMT = CursorKind(212)
1012 |
1013 | # A break statement.
1014 | CursorKind.BREAK_STMT = CursorKind(213)
1015 |
1016 | # A return statement.
1017 | CursorKind.RETURN_STMT = CursorKind(214)
1018 |
1019 | # A GNU-style inline assembler statement.
1020 | CursorKind.ASM_STMT = CursorKind(215)
1021 |
1022 | # Objective-C's overall @try-@catch-@finally statement.
1023 | CursorKind.OBJC_AT_TRY_STMT = CursorKind(216)
1024 |
1025 | # Objective-C's @catch statement.
1026 | CursorKind.OBJC_AT_CATCH_STMT = CursorKind(217)
1027 |
1028 | # Objective-C's @finally statement.
1029 | CursorKind.OBJC_AT_FINALLY_STMT = CursorKind(218)
1030 |
1031 | # Objective-C's @throw statement.
1032 | CursorKind.OBJC_AT_THROW_STMT = CursorKind(219)
1033 |
1034 | # Objective-C's @synchronized statement.
1035 | CursorKind.OBJC_AT_SYNCHRONIZED_STMT = CursorKind(220)
1036 |
1037 | # Objective-C's autorealease pool statement.
1038 | CursorKind.OBJC_AUTORELEASE_POOL_STMT = CursorKind(221)
1039 |
1040 | # Objective-C's for collection statement.
1041 | CursorKind.OBJC_FOR_COLLECTION_STMT = CursorKind(222)
1042 |
1043 | # C++'s catch statement.
1044 | CursorKind.CXX_CATCH_STMT = CursorKind(223)
1045 |
1046 | # C++'s try statement.
1047 | CursorKind.CXX_TRY_STMT = CursorKind(224)
1048 |
1049 | # C++'s for (* : *) statement.
1050 | CursorKind.CXX_FOR_RANGE_STMT = CursorKind(225)
1051 |
1052 | # Windows Structured Exception Handling's try statement.
1053 | CursorKind.SEH_TRY_STMT = CursorKind(226)
1054 |
1055 | # Windows Structured Exception Handling's except statement.
1056 | CursorKind.SEH_EXCEPT_STMT = CursorKind(227)
1057 |
1058 | # Windows Structured Exception Handling's finally statement.
1059 | CursorKind.SEH_FINALLY_STMT = CursorKind(228)
1060 |
1061 | # A MS inline assembly statement extension.
1062 | CursorKind.MS_ASM_STMT = CursorKind(229)
1063 |
1064 | # The null statement.
1065 | CursorKind.NULL_STMT = CursorKind(230)
1066 |
1067 | # Adaptor class for mixing declarations with statements and expressions.
1068 | CursorKind.DECL_STMT = CursorKind(231)
1069 |
1070 | ###
1071 | # Other Kinds
1072 |
1073 | # Cursor that represents the translation unit itself.
1074 | #
1075 | # The translation unit cursor exists primarily to act as the root cursor for
1076 | # traversing the contents of a translation unit.
1077 | CursorKind.TRANSLATION_UNIT = CursorKind(300)
1078 |
1079 | ###
1080 | # Attributes
1081 |
1082 | # An attribute whoe specific kind is note exposed via this interface
1083 | CursorKind.UNEXPOSED_ATTR = CursorKind(400)
1084 |
1085 | CursorKind.IB_ACTION_ATTR = CursorKind(401)
1086 | CursorKind.IB_OUTLET_ATTR = CursorKind(402)
1087 | CursorKind.IB_OUTLET_COLLECTION_ATTR = CursorKind(403)
1088 |
1089 | CursorKind.CXX_FINAL_ATTR = CursorKind(404)
1090 | CursorKind.CXX_OVERRIDE_ATTR = CursorKind(405)
1091 | CursorKind.ANNOTATE_ATTR = CursorKind(406)
1092 | CursorKind.ASM_LABEL_ATTR = CursorKind(407)
1093 | CursorKind.PACKED_ATTR = CursorKind(408)
1094 | CursorKind.PURE_ATTR = CursorKind(409)
1095 | CursorKind.CONST_ATTR = CursorKind(410)
1096 | CursorKind.NODUPLICATE_ATTR = CursorKind(411)
1097 | CursorKind.CUDACONSTANT_ATTR = CursorKind(412)
1098 | CursorKind.CUDADEVICE_ATTR = CursorKind(413)
1099 | CursorKind.CUDAGLOBAL_ATTR = CursorKind(414)
1100 | CursorKind.CUDAHOST_ATTR = CursorKind(415)
1101 | CursorKind.CUDASHARED_ATTR = CursorKind(416)
1102 |
1103 | ###
1104 | # Preprocessing
1105 | CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500)
1106 | CursorKind.MACRO_DEFINITION = CursorKind(501)
1107 | CursorKind.MACRO_INSTANTIATION = CursorKind(502)
1108 | CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
1109 |
1110 | ###
1111 | # Extra declaration
1112 |
1113 | # A module import declaration.
1114 | CursorKind.MODULE_IMPORT_DECL = CursorKind(600)
1115 |
1116 |
1117 | ### Template Argument Kinds ###
1118 | class TemplateArgumentKind(BaseEnumeration):
1119 | """
1120 | A TemplateArgumentKind describes the kind of entity that a template argument
1121 | represents.
1122 | """
1123 |
1124 | # The required BaseEnumeration declarations.
1125 | _kinds = []
1126 | _name_map = None
1127 |
1128 | TemplateArgumentKind.NULL = TemplateArgumentKind(0)
1129 | TemplateArgumentKind.TYPE = TemplateArgumentKind(1)
1130 | TemplateArgumentKind.DECLARATION = TemplateArgumentKind(2)
1131 | TemplateArgumentKind.NULLPTR = TemplateArgumentKind(3)
1132 | TemplateArgumentKind.INTEGRAL = TemplateArgumentKind(4)
1133 |
1134 | ### Cursors ###
1135 |
1136 | class Cursor(Structure):
1137 | """
1138 | The Cursor class represents a reference to an element within the AST. It
1139 | acts as a kind of iterator.
1140 | """
1141 | _fields_ = [("_kind_id", c_int), ("xdata", c_int), ("data", c_void_p * 3)]
1142 |
1143 | @staticmethod
1144 | def from_location(tu, location):
1145 | # We store a reference to the TU in the instance so the TU won't get
1146 | # collected before the cursor.
1147 | cursor = conf.lib.clang_getCursor(tu, location)
1148 | cursor._tu = tu
1149 |
1150 | return cursor
1151 |
1152 | def __eq__(self, other):
1153 | return conf.lib.clang_equalCursors(self, other)
1154 |
1155 | def __ne__(self, other):
1156 | return not self.__eq__(other)
1157 |
1158 | def is_definition(self):
1159 | """
1160 | Returns true if the declaration pointed at by the cursor is also a
1161 | definition of that entity.
1162 | """
1163 | return conf.lib.clang_isCursorDefinition(self)
1164 |
1165 | def is_static_method(self):
1166 | """Returns True if the cursor refers to a C++ member function or member
1167 | function template that is declared 'static'.
1168 | """
1169 | return conf.lib.clang_CXXMethod_isStatic(self)
1170 |
1171 | def get_definition(self):
1172 | """
1173 | If the cursor is a reference to a declaration or a declaration of
1174 | some entity, return a cursor that points to the definition of that
1175 | entity.
1176 | """
1177 | # TODO: Should probably check that this is either a reference or
1178 | # declaration prior to issuing the lookup.
1179 | return conf.lib.clang_getCursorDefinition(self)
1180 |
1181 | def get_usr(self):
1182 | """Return the Unified Symbol Resultion (USR) for the entity referenced
1183 | by the given cursor (or None).
1184 |
1185 | A Unified Symbol Resolution (USR) is a string that identifies a
1186 | particular entity (function, class, variable, etc.) within a
1187 | program. USRs can be compared across translation units to determine,
1188 | e.g., when references in one translation refer to an entity defined in
1189 | another translation unit."""
1190 | return conf.lib.clang_getCursorUSR(self)
1191 |
1192 | @property
1193 | def kind(self):
1194 | """Return the kind of this cursor."""
1195 | return CursorKind.from_id(self._kind_id)
1196 |
1197 | @property
1198 | def spelling(self):
1199 | """Return the spelling of the entity pointed at by the cursor."""
1200 | if not hasattr(self, '_spelling'):
1201 | self._spelling = conf.lib.clang_getCursorSpelling(self)
1202 |
1203 | return self._spelling
1204 |
1205 | @property
1206 | def displayname(self):
1207 | """
1208 | Return the display name for the entity referenced by this cursor.
1209 |
1210 | The display name contains extra information that helps identify the
1211 | cursor, such as the parameters of a function or template or the
1212 | arguments of a class template specialization.
1213 | """
1214 | if not hasattr(self, '_displayname'):
1215 | self._displayname = conf.lib.clang_getCursorDisplayName(self)
1216 |
1217 | return self._displayname
1218 |
1219 | @property
1220 | def mangled_name(self):
1221 | """Return the mangled name for the entity referenced by this cursor."""
1222 | if not hasattr(self, '_mangled_name'):
1223 | self._mangled_name = conf.lib.clang_Cursor_getMangling(self)
1224 |
1225 | return self._mangled_name
1226 |
1227 | @property
1228 | def location(self):
1229 | """
1230 | Return the source location (the starting character) of the entity
1231 | pointed at by the cursor.
1232 | """
1233 | if not hasattr(self, '_loc'):
1234 | self._loc = conf.lib.clang_getCursorLocation(self)
1235 |
1236 | return self._loc
1237 |
1238 | @property
1239 | def extent(self):
1240 | """
1241 | Return the source range (the range of text) occupied by the entity
1242 | pointed at by the cursor.
1243 | """
1244 | if not hasattr(self, '_extent'):
1245 | self._extent = conf.lib.clang_getCursorExtent(self)
1246 |
1247 | return self._extent
1248 |
1249 | @property
1250 | def storage_class(self):
1251 | """
1252 | Retrieves the storage class (if any) of the entity pointed at by the
1253 | cursor.
1254 | """
1255 | if not hasattr(self, '_storage_class'):
1256 | self._storage_class = conf.lib.clang_Cursor_getStorageClass(self)
1257 |
1258 | return StorageClass.from_id(self._storage_class)
1259 |
1260 | @property
1261 | def access_specifier(self):
1262 | """
1263 | Retrieves the access specifier (if any) of the entity pointed at by the
1264 | cursor.
1265 | """
1266 | if not hasattr(self, '_access_specifier'):
1267 | self._access_specifier = conf.lib.clang_getCXXAccessSpecifier(self)
1268 |
1269 | return AccessSpecifier.from_id(self._access_specifier)
1270 |
1271 | @property
1272 | def type(self):
1273 | """
1274 | Retrieve the Type (if any) of the entity pointed at by the cursor.
1275 | """
1276 | if not hasattr(self, '_type'):
1277 | self._type = conf.lib.clang_getCursorType(self)
1278 |
1279 | return self._type
1280 |
1281 | @property
1282 | def canonical(self):
1283 | """Return the canonical Cursor corresponding to this Cursor.
1284 |
1285 | The canonical cursor is the cursor which is representative for the
1286 | underlying entity. For example, if you have multiple forward
1287 | declarations for the same class, the canonical cursor for the forward
1288 | declarations will be identical.
1289 | """
1290 | if not hasattr(self, '_canonical'):
1291 | self._canonical = conf.lib.clang_getCanonicalCursor(self)
1292 |
1293 | return self._canonical
1294 |
1295 | @property
1296 | def result_type(self):
1297 | """Retrieve the Type of the result for this Cursor."""
1298 | if not hasattr(self, '_result_type'):
1299 | self._result_type = conf.lib.clang_getResultType(self.type)
1300 |
1301 | return self._result_type
1302 |
1303 | @property
1304 | def underlying_typedef_type(self):
1305 | """Return the underlying type of a typedef declaration.
1306 |
1307 | Returns a Type for the typedef this cursor is a declaration for. If
1308 | the current cursor is not a typedef, this raises.
1309 | """
1310 | if not hasattr(self, '_underlying_type'):
1311 | assert self.kind.is_declaration()
1312 | self._underlying_type = \
1313 | conf.lib.clang_getTypedefDeclUnderlyingType(self)
1314 |
1315 | return self._underlying_type
1316 |
1317 | @property
1318 | def enum_type(self):
1319 | """Return the integer type of an enum declaration.
1320 |
1321 | Returns a Type corresponding to an integer. If the cursor is not for an
1322 | enum, this raises.
1323 | """
1324 | if not hasattr(self, '_enum_type'):
1325 | assert self.kind == CursorKind.ENUM_DECL
1326 | self._enum_type = conf.lib.clang_getEnumDeclIntegerType(self)
1327 |
1328 | return self._enum_type
1329 |
1330 | @property
1331 | def enum_value(self):
1332 | """Return the value of an enum constant."""
1333 | if not hasattr(self, '_enum_value'):
1334 | assert self.kind == CursorKind.ENUM_CONSTANT_DECL
1335 | # Figure out the underlying type of the enum to know if it
1336 | # is a signed or unsigned quantity.
1337 | underlying_type = self.type
1338 | if underlying_type.kind == TypeKind.ENUM:
1339 | underlying_type = underlying_type.get_declaration().enum_type
1340 | if underlying_type.kind in (TypeKind.CHAR_U,
1341 | TypeKind.UCHAR,
1342 | TypeKind.CHAR16,
1343 | TypeKind.CHAR32,
1344 | TypeKind.USHORT,
1345 | TypeKind.UINT,
1346 | TypeKind.ULONG,
1347 | TypeKind.ULONGLONG,
1348 | TypeKind.UINT128):
1349 | self._enum_value = \
1350 | conf.lib.clang_getEnumConstantDeclUnsignedValue(self)
1351 | else:
1352 | self._enum_value = conf.lib.clang_getEnumConstantDeclValue(self)
1353 | return self._enum_value
1354 |
1355 | @property
1356 | def objc_type_encoding(self):
1357 | """Return the Objective-C type encoding as a str."""
1358 | if not hasattr(self, '_objc_type_encoding'):
1359 | self._objc_type_encoding = \
1360 | conf.lib.clang_getDeclObjCTypeEncoding(self)
1361 |
1362 | return self._objc_type_encoding
1363 |
1364 | @property
1365 | def hash(self):
1366 | """Returns a hash of the cursor as an int."""
1367 | if not hasattr(self, '_hash'):
1368 | self._hash = conf.lib.clang_hashCursor(self)
1369 |
1370 | return self._hash
1371 |
1372 | @property
1373 | def semantic_parent(self):
1374 | """Return the semantic parent for this cursor."""
1375 | if not hasattr(self, '_semantic_parent'):
1376 | self._semantic_parent = conf.lib.clang_getCursorSemanticParent(self)
1377 |
1378 | return self._semantic_parent
1379 |
1380 | @property
1381 | def lexical_parent(self):
1382 | """Return the lexical parent for this cursor."""
1383 | if not hasattr(self, '_lexical_parent'):
1384 | self._lexical_parent = conf.lib.clang_getCursorLexicalParent(self)
1385 |
1386 | return self._lexical_parent
1387 |
1388 | @property
1389 | def translation_unit(self):
1390 | """Returns the TranslationUnit to which this Cursor belongs."""
1391 | # If this triggers an AttributeError, the instance was not properly
1392 | # created.
1393 | return self._tu
1394 |
1395 | @property
1396 | def referenced(self):
1397 | """
1398 | For a cursor that is a reference, returns a cursor
1399 | representing the entity that it references.
1400 | """
1401 | if not hasattr(self, '_referenced'):
1402 | self._referenced = conf.lib.clang_getCursorReferenced(self)
1403 |
1404 | return self._referenced
1405 |
1406 | @property
1407 | def brief_comment(self):
1408 | """Returns the brief comment text associated with that Cursor"""
1409 | return conf.lib.clang_Cursor_getBriefCommentText(self)
1410 |
1411 | @property
1412 | def raw_comment(self):
1413 | """Returns the raw comment text associated with that Cursor"""
1414 | return conf.lib.clang_Cursor_getRawCommentText(self)
1415 |
1416 | def get_arguments(self):
1417 | """Return an iterator for accessing the arguments of this cursor."""
1418 | num_args = conf.lib.clang_Cursor_getNumArguments(self)
1419 | for i in range(0, num_args):
1420 | yield conf.lib.clang_Cursor_getArgument(self, i)
1421 |
1422 | def get_num_template_arguments(self):
1423 | """Returns the number of template args associated with this cursor."""
1424 | return conf.lib.clang_Cursor_getNumTemplateArguments(self)
1425 |
1426 | def get_template_argument_kind(self, num):
1427 | """Returns the TemplateArgumentKind for the indicated template
1428 | argument."""
1429 | return conf.lib.clang_Cursor_getTemplateArgumentKind(self, num)
1430 |
1431 | def get_template_argument_type(self, num):
1432 | """Returns the CXType for the indicated template argument."""
1433 | return conf.lib.clang_Cursor_getTemplateArgumentType(self, num)
1434 |
1435 | def get_template_argument_value(self, num):
1436 | """Returns the value of the indicated arg as a signed 64b integer."""
1437 | return conf.lib.clang_Cursor_getTemplateArgumentValue(self, num)
1438 |
1439 | def get_template_argument_unsigned_value(self, num):
1440 | """Returns the value of the indicated arg as an unsigned 64b integer."""
1441 | return conf.lib.clang_Cursor_getTemplateArgumentUnsignedValue(self, num)
1442 |
1443 | def get_children(self):
1444 | """Return an iterator for accessing the children of this cursor."""
1445 |
1446 | # FIXME: Expose iteration from CIndex, PR6125.
1447 | def visitor(child, parent, children):
1448 | # FIXME: Document this assertion in API.
1449 | # FIXME: There should just be an isNull method.
1450 | assert child != conf.lib.clang_getNullCursor()
1451 |
1452 | # Create reference to TU so it isn't GC'd before Cursor.
1453 | child._tu = self._tu
1454 | children.append(child)
1455 | return 1 # continue
1456 | children = []
1457 | conf.lib.clang_visitChildren(self, callbacks['cursor_visit'](visitor),
1458 | children)
1459 | return iter(children)
1460 |
1461 | def walk_preorder(self):
1462 | """Depth-first preorder walk over the cursor and its descendants.
1463 |
1464 | Yields cursors.
1465 | """
1466 | yield self
1467 | for child in self.get_children():
1468 | for descendant in child.walk_preorder():
1469 | yield descendant
1470 |
1471 | def get_tokens(self):
1472 | """Obtain Token instances formulating that compose this Cursor.
1473 |
1474 | This is a generator for Token instances. It returns all tokens which
1475 | occupy the extent this cursor occupies.
1476 | """
1477 | return TokenGroup.get_tokens(self._tu, self.extent)
1478 |
1479 | def is_bitfield(self):
1480 | """
1481 | Check if the field is a bitfield.
1482 | """
1483 | return conf.lib.clang_Cursor_isBitField(self)
1484 |
1485 | def get_bitfield_width(self):
1486 | """
1487 | Retrieve the width of a bitfield.
1488 | """
1489 | return conf.lib.clang_getFieldDeclBitWidth(self)
1490 |
1491 | @staticmethod
1492 | def from_result(res, fn, args):
1493 | assert isinstance(res, Cursor)
1494 | # FIXME: There should just be an isNull method.
1495 | if res == conf.lib.clang_getNullCursor():
1496 | return None
1497 |
1498 | # Store a reference to the TU in the Python object so it won't get GC'd
1499 | # before the Cursor.
1500 | tu = None
1501 | for arg in args:
1502 | if isinstance(arg, TranslationUnit):
1503 | tu = arg
1504 | break
1505 |
1506 | if hasattr(arg, 'translation_unit'):
1507 | tu = arg.translation_unit
1508 | break
1509 |
1510 | assert tu is not None
1511 |
1512 | res._tu = tu
1513 | return res
1514 |
1515 | @staticmethod
1516 | def from_cursor_result(res, fn, args):
1517 | assert isinstance(res, Cursor)
1518 | if res == conf.lib.clang_getNullCursor():
1519 | return None
1520 |
1521 | res._tu = args[0]._tu
1522 | return res
1523 |
1524 | class StorageClass(object):
1525 | """
1526 | Describes the storage class of a declaration
1527 | """
1528 |
1529 | # The unique kind objects, index by id.
1530 | _kinds = []
1531 | _name_map = None
1532 |
1533 | def __init__(self, value):
1534 | if value >= len(StorageClass._kinds):
1535 | StorageClass._kinds += [None] * (value - len(StorageClass._kinds) + 1)
1536 | if StorageClass._kinds[value] is not None:
1537 | raise ValueError,'StorageClass already loaded'
1538 | self.value = value
1539 | StorageClass._kinds[value] = self
1540 | StorageClass._name_map = None
1541 |
1542 | def from_param(self):
1543 | return self.value
1544 |
1545 | @property
1546 | def name(self):
1547 | """Get the enumeration name of this storage class."""
1548 | if self._name_map is None:
1549 | self._name_map = {}
1550 | for key,value in StorageClass.__dict__.items():
1551 | if isinstance(value,StorageClass):
1552 | self._name_map[value] = key
1553 | return self._name_map[self]
1554 |
1555 | @staticmethod
1556 | def from_id(id):
1557 | if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]:
1558 | raise ValueError,'Unknown storage class %d' % id
1559 | return StorageClass._kinds[id]
1560 |
1561 | def __repr__(self):
1562 | return 'StorageClass.%s' % (self.name,)
1563 |
1564 | StorageClass.INVALID = StorageClass(0)
1565 | StorageClass.NONE = StorageClass(1)
1566 | StorageClass.EXTERN = StorageClass(2)
1567 | StorageClass.STATIC = StorageClass(3)
1568 | StorageClass.PRIVATEEXTERN = StorageClass(4)
1569 | StorageClass.OPENCLWORKGROUPLOCAL = StorageClass(5)
1570 | StorageClass.AUTO = StorageClass(6)
1571 | StorageClass.REGISTER = StorageClass(7)
1572 |
1573 |
1574 | ### C++ access specifiers ###
1575 |
1576 | class AccessSpecifier(BaseEnumeration):
1577 | """
1578 | Describes the access of a C++ class member
1579 | """
1580 |
1581 | # The unique kind objects, index by id.
1582 | _kinds = []
1583 | _name_map = None
1584 |
1585 | def from_param(self):
1586 | return self.value
1587 |
1588 | def __repr__(self):
1589 | return 'AccessSpecifier.%s' % (self.name,)
1590 |
1591 | AccessSpecifier.INVALID = AccessSpecifier(0)
1592 | AccessSpecifier.PUBLIC = AccessSpecifier(1)
1593 | AccessSpecifier.PROTECTED = AccessSpecifier(2)
1594 | AccessSpecifier.PRIVATE = AccessSpecifier(3)
1595 | AccessSpecifier.NONE = AccessSpecifier(4)
1596 |
1597 | ### Type Kinds ###
1598 |
1599 | class TypeKind(BaseEnumeration):
1600 | """
1601 | Describes the kind of type.
1602 | """
1603 |
1604 | # The unique kind objects, indexed by id.
1605 | _kinds = []
1606 | _name_map = None
1607 |
1608 | @property
1609 | def spelling(self):
1610 | """Retrieve the spelling of this TypeKind."""
1611 | return conf.lib.clang_getTypeKindSpelling(self.value)
1612 |
1613 | def __repr__(self):
1614 | return 'TypeKind.%s' % (self.name,)
1615 |
1616 | TypeKind.INVALID = TypeKind(0)
1617 | TypeKind.UNEXPOSED = TypeKind(1)
1618 | TypeKind.VOID = TypeKind(2)
1619 | TypeKind.BOOL = TypeKind(3)
1620 | TypeKind.CHAR_U = TypeKind(4)
1621 | TypeKind.UCHAR = TypeKind(5)
1622 | TypeKind.CHAR16 = TypeKind(6)
1623 | TypeKind.CHAR32 = TypeKind(7)
1624 | TypeKind.USHORT = TypeKind(8)
1625 | TypeKind.UINT = TypeKind(9)
1626 | TypeKind.ULONG = TypeKind(10)
1627 | TypeKind.ULONGLONG = TypeKind(11)
1628 | TypeKind.UINT128 = TypeKind(12)
1629 | TypeKind.CHAR_S = TypeKind(13)
1630 | TypeKind.SCHAR = TypeKind(14)
1631 | TypeKind.WCHAR = TypeKind(15)
1632 | TypeKind.SHORT = TypeKind(16)
1633 | TypeKind.INT = TypeKind(17)
1634 | TypeKind.LONG = TypeKind(18)
1635 | TypeKind.LONGLONG = TypeKind(19)
1636 | TypeKind.INT128 = TypeKind(20)
1637 | TypeKind.FLOAT = TypeKind(21)
1638 | TypeKind.DOUBLE = TypeKind(22)
1639 | TypeKind.LONGDOUBLE = TypeKind(23)
1640 | TypeKind.NULLPTR = TypeKind(24)
1641 | TypeKind.OVERLOAD = TypeKind(25)
1642 | TypeKind.DEPENDENT = TypeKind(26)
1643 | TypeKind.OBJCID = TypeKind(27)
1644 | TypeKind.OBJCCLASS = TypeKind(28)
1645 | TypeKind.OBJCSEL = TypeKind(29)
1646 | TypeKind.COMPLEX = TypeKind(100)
1647 | TypeKind.POINTER = TypeKind(101)
1648 | TypeKind.BLOCKPOINTER = TypeKind(102)
1649 | TypeKind.LVALUEREFERENCE = TypeKind(103)
1650 | TypeKind.RVALUEREFERENCE = TypeKind(104)
1651 | TypeKind.RECORD = TypeKind(105)
1652 | TypeKind.ENUM = TypeKind(106)
1653 | TypeKind.TYPEDEF = TypeKind(107)
1654 | TypeKind.OBJCINTERFACE = TypeKind(108)
1655 | TypeKind.OBJCOBJECTPOINTER = TypeKind(109)
1656 | TypeKind.FUNCTIONNOPROTO = TypeKind(110)
1657 | TypeKind.FUNCTIONPROTO = TypeKind(111)
1658 | TypeKind.CONSTANTARRAY = TypeKind(112)
1659 | TypeKind.VECTOR = TypeKind(113)
1660 | TypeKind.INCOMPLETEARRAY = TypeKind(114)
1661 | TypeKind.VARIABLEARRAY = TypeKind(115)
1662 | TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116)
1663 | TypeKind.MEMBERPOINTER = TypeKind(117)
1664 |
1665 | class RefQualifierKind(BaseEnumeration):
1666 | """Describes a specific ref-qualifier of a type."""
1667 |
1668 | # The unique kind objects, indexed by id.
1669 | _kinds = []
1670 | _name_map = None
1671 |
1672 | def from_param(self):
1673 | return self.value
1674 |
1675 | def __repr__(self):
1676 | return 'RefQualifierKind.%s' % (self.name,)
1677 |
1678 | RefQualifierKind.NONE = RefQualifierKind(0)
1679 | RefQualifierKind.LVALUE = RefQualifierKind(1)
1680 | RefQualifierKind.RVALUE = RefQualifierKind(2)
1681 |
1682 | class Type(Structure):
1683 | """
1684 | The type of an element in the abstract syntax tree.
1685 | """
1686 | _fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)]
1687 |
1688 | @property
1689 | def kind(self):
1690 | """Return the kind of this type."""
1691 | return TypeKind.from_id(self._kind_id)
1692 |
1693 | def argument_types(self):
1694 | """Retrieve a container for the non-variadic arguments for this type.
1695 |
1696 | The returned object is iterable and indexable. Each item in the
1697 | container is a Type instance.
1698 | """
1699 | class ArgumentsIterator(collections.Sequence):
1700 | def __init__(self, parent):
1701 | self.parent = parent
1702 | self.length = None
1703 |
1704 | def __len__(self):
1705 | if self.length is None:
1706 | self.length = conf.lib.clang_getNumArgTypes(self.parent)
1707 |
1708 | return self.length
1709 |
1710 | def __getitem__(self, key):
1711 | # FIXME Support slice objects.
1712 | if not isinstance(key, int):
1713 | raise TypeError("Must supply a non-negative int.")
1714 |
1715 | if key < 0:
1716 | raise IndexError("Only non-negative indexes are accepted.")
1717 |
1718 | if key >= len(self):
1719 | raise IndexError("Index greater than container length: "
1720 | "%d > %d" % ( key, len(self) ))
1721 |
1722 | result = conf.lib.clang_getArgType(self.parent, key)
1723 | if result.kind == TypeKind.INVALID:
1724 | raise IndexError("Argument could not be retrieved.")
1725 |
1726 | return result
1727 |
1728 | assert self.kind == TypeKind.FUNCTIONPROTO
1729 | return ArgumentsIterator(self)
1730 |
1731 | @property
1732 | def element_type(self):
1733 | """Retrieve the Type of elements within this Type.
1734 |
1735 | If accessed on a type that is not an array, complex, or vector type, an
1736 | exception will be raised.
1737 | """
1738 | result = conf.lib.clang_getElementType(self)
1739 | if result.kind == TypeKind.INVALID:
1740 | raise Exception('Element type not available on this type.')
1741 |
1742 | return result
1743 |
1744 | @property
1745 | def element_count(self):
1746 | """Retrieve the number of elements in this type.
1747 |
1748 | Returns an int.
1749 |
1750 | If the Type is not an array or vector, this raises.
1751 | """
1752 | result = conf.lib.clang_getNumElements(self)
1753 | if result < 0:
1754 | raise Exception('Type does not have elements.')
1755 |
1756 | return result
1757 |
1758 | @property
1759 | def translation_unit(self):
1760 | """The TranslationUnit to which this Type is associated."""
1761 | # If this triggers an AttributeError, the instance was not properly
1762 | # instantiated.
1763 | return self._tu
1764 |
1765 | @staticmethod
1766 | def from_result(res, fn, args):
1767 | assert isinstance(res, Type)
1768 |
1769 | tu = None
1770 | for arg in args:
1771 | if hasattr(arg, 'translation_unit'):
1772 | tu = arg.translation_unit
1773 | break
1774 |
1775 | assert tu is not None
1776 | res._tu = tu
1777 |
1778 | return res
1779 |
1780 | def get_canonical(self):
1781 | """
1782 | Return the canonical type for a Type.
1783 |
1784 | Clang's type system explicitly models typedefs and all the
1785 | ways a specific type can be represented. The canonical type
1786 | is the underlying type with all the "sugar" removed. For
1787 | example, if 'T' is a typedef for 'int', the canonical type for
1788 | 'T' would be 'int'.
1789 | """
1790 | return conf.lib.clang_getCanonicalType(self)
1791 |
1792 | def is_const_qualified(self):
1793 | """Determine whether a Type has the "const" qualifier set.
1794 |
1795 | This does not look through typedefs that may have added "const"
1796 | at a different level.
1797 | """
1798 | return conf.lib.clang_isConstQualifiedType(self)
1799 |
1800 | def is_volatile_qualified(self):
1801 | """Determine whether a Type has the "volatile" qualifier set.
1802 |
1803 | This does not look through typedefs that may have added "volatile"
1804 | at a different level.
1805 | """
1806 | return conf.lib.clang_isVolatileQualifiedType(self)
1807 |
1808 | def is_restrict_qualified(self):
1809 | """Determine whether a Type has the "restrict" qualifier set.
1810 |
1811 | This does not look through typedefs that may have added "restrict" at
1812 | a different level.
1813 | """
1814 | return conf.lib.clang_isRestrictQualifiedType(self)
1815 |
1816 | def is_function_variadic(self):
1817 | """Determine whether this function Type is a variadic function type."""
1818 | assert self.kind == TypeKind.FUNCTIONPROTO
1819 |
1820 | return conf.lib.clang_isFunctionTypeVariadic(self)
1821 |
1822 | def is_pod(self):
1823 | """Determine whether this Type represents plain old data (POD)."""
1824 | return conf.lib.clang_isPODType(self)
1825 |
1826 | def get_pointee(self):
1827 | """
1828 | For pointer types, returns the type of the pointee.
1829 | """
1830 | return conf.lib.clang_getPointeeType(self)
1831 |
1832 | def get_declaration(self):
1833 | """
1834 | Return the cursor for the declaration of the given type.
1835 | """
1836 | return conf.lib.clang_getTypeDeclaration(self)
1837 |
1838 | def get_result(self):
1839 | """
1840 | Retrieve the result type associated with a function type.
1841 | """
1842 | return conf.lib.clang_getResultType(self)
1843 |
1844 | def get_array_element_type(self):
1845 | """
1846 | Retrieve the type of the elements of the array type.
1847 | """
1848 | return conf.lib.clang_getArrayElementType(self)
1849 |
1850 | def get_array_size(self):
1851 | """
1852 | Retrieve the size of the constant array.
1853 | """
1854 | return conf.lib.clang_getArraySize(self)
1855 |
1856 | def get_class_type(self):
1857 | """
1858 | Retrieve the class type of the member pointer type.
1859 | """
1860 | return conf.lib.clang_Type_getClassType(self)
1861 |
1862 | def get_align(self):
1863 | """
1864 | Retrieve the alignment of the record.
1865 | """
1866 | return conf.lib.clang_Type_getAlignOf(self)
1867 |
1868 | def get_size(self):
1869 | """
1870 | Retrieve the size of the record.
1871 | """
1872 | return conf.lib.clang_Type_getSizeOf(self)
1873 |
1874 | def get_offset(self, fieldname):
1875 | """
1876 | Retrieve the offset of a field in the record.
1877 | """
1878 | return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname))
1879 |
1880 | def get_ref_qualifier(self):
1881 | """
1882 | Retrieve the ref-qualifier of the type.
1883 | """
1884 | return RefQualifierKind.from_id(
1885 | conf.lib.clang_Type_getCXXRefQualifier(self))
1886 |
1887 | @property
1888 | def spelling(self):
1889 | """Retrieve the spelling of this Type."""
1890 | return conf.lib.clang_getTypeSpelling(self)
1891 |
1892 | def __eq__(self, other):
1893 | if type(other) != type(self):
1894 | return False
1895 |
1896 | return conf.lib.clang_equalTypes(self, other)
1897 |
1898 | def __ne__(self, other):
1899 | return not self.__eq__(other)
1900 |
1901 | ## CIndex Objects ##
1902 |
1903 | # CIndex objects (derived from ClangObject) are essentially lightweight
1904 | # wrappers attached to some underlying object, which is exposed via CIndex as
1905 | # a void*.
1906 |
1907 | class ClangObject(object):
1908 | """
1909 | A helper for Clang objects. This class helps act as an intermediary for
1910 | the ctypes library and the Clang CIndex library.
1911 | """
1912 | def __init__(self, obj):
1913 | assert isinstance(obj, c_object_p) and obj
1914 | self.obj = self._as_parameter_ = obj
1915 |
1916 | def from_param(self):
1917 | return self._as_parameter_
1918 |
1919 |
1920 | class _CXUnsavedFile(Structure):
1921 | """Helper for passing unsaved file arguments."""
1922 | _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
1923 |
1924 | # Functions calls through the python interface are rather slow. Fortunately,
1925 | # for most symboles, we do not need to perform a function call. Their spelling
1926 | # never changes and is consequently provided by this spelling cache.
1927 | SpellingCache = {
1928 | # 0: CompletionChunk.Kind("Optional"),
1929 | # 1: CompletionChunk.Kind("TypedText"),
1930 | # 2: CompletionChunk.Kind("Text"),
1931 | # 3: CompletionChunk.Kind("Placeholder"),
1932 | # 4: CompletionChunk.Kind("Informative"),
1933 | # 5 : CompletionChunk.Kind("CurrentParameter"),
1934 | 6: '(', # CompletionChunk.Kind("LeftParen"),
1935 | 7: ')', # CompletionChunk.Kind("RightParen"),
1936 | 8: '[', # CompletionChunk.Kind("LeftBracket"),
1937 | 9: ']', # CompletionChunk.Kind("RightBracket"),
1938 | 10: '{', # CompletionChunk.Kind("LeftBrace"),
1939 | 11: '}', # CompletionChunk.Kind("RightBrace"),
1940 | 12: '<', # CompletionChunk.Kind("LeftAngle"),
1941 | 13: '>', # CompletionChunk.Kind("RightAngle"),
1942 | 14: ', ', # CompletionChunk.Kind("Comma"),
1943 | # 15: CompletionChunk.Kind("ResultType"),
1944 | 16: ':', # CompletionChunk.Kind("Colon"),
1945 | 17: ';', # CompletionChunk.Kind("SemiColon"),
1946 | 18: '=', # CompletionChunk.Kind("Equal"),
1947 | 19: ' ', # CompletionChunk.Kind("HorizontalSpace"),
1948 | # 20: CompletionChunk.Kind("VerticalSpace")
1949 | }
1950 |
1951 | class CompletionChunk:
1952 | class Kind:
1953 | def __init__(self, name):
1954 | self.name = name
1955 |
1956 | def __str__(self):
1957 | return self.name
1958 |
1959 | def __repr__(self):
1960 | return "" % self
1961 |
1962 | def __init__(self, completionString, key):
1963 | self.cs = completionString
1964 | self.key = key
1965 | self.__kindNumberCache = -1
1966 |
1967 | def __repr__(self):
1968 | return "{'" + self.spelling + "', " + str(self.kind) + "}"
1969 |
1970 | @CachedProperty
1971 | def spelling(self):
1972 | if self.__kindNumber in SpellingCache:
1973 | return SpellingCache[self.__kindNumber]
1974 | return conf.lib.clang_getCompletionChunkText(self.cs, self.key).spelling
1975 |
1976 | # We do not use @CachedProperty here, as the manual implementation is
1977 | # apparently still significantly faster. Please profile carefully if you
1978 | # would like to add CachedProperty back.
1979 | @property
1980 | def __kindNumber(self):
1981 | if self.__kindNumberCache == -1:
1982 | self.__kindNumberCache = \
1983 | conf.lib.clang_getCompletionChunkKind(self.cs, self.key)
1984 | return self.__kindNumberCache
1985 |
1986 | @CachedProperty
1987 | def kind(self):
1988 | return completionChunkKindMap[self.__kindNumber]
1989 |
1990 | @CachedProperty
1991 | def string(self):
1992 | res = conf.lib.clang_getCompletionChunkCompletionString(self.cs,
1993 | self.key)
1994 |
1995 | if (res):
1996 | return CompletionString(res)
1997 | else:
1998 | None
1999 |
2000 | def isKindOptional(self):
2001 | return self.__kindNumber == 0
2002 |
2003 | def isKindTypedText(self):
2004 | return self.__kindNumber == 1
2005 |
2006 | def isKindPlaceHolder(self):
2007 | return self.__kindNumber == 3
2008 |
2009 | def isKindInformative(self):
2010 | return self.__kindNumber == 4
2011 |
2012 | def isKindResultType(self):
2013 | return self.__kindNumber == 15
2014 |
2015 | completionChunkKindMap = {
2016 | 0: CompletionChunk.Kind("Optional"),
2017 | 1: CompletionChunk.Kind("TypedText"),
2018 | 2: CompletionChunk.Kind("Text"),
2019 | 3: CompletionChunk.Kind("Placeholder"),
2020 | 4: CompletionChunk.Kind("Informative"),
2021 | 5: CompletionChunk.Kind("CurrentParameter"),
2022 | 6: CompletionChunk.Kind("LeftParen"),
2023 | 7: CompletionChunk.Kind("RightParen"),
2024 | 8: CompletionChunk.Kind("LeftBracket"),
2025 | 9: CompletionChunk.Kind("RightBracket"),
2026 | 10: CompletionChunk.Kind("LeftBrace"),
2027 | 11: CompletionChunk.Kind("RightBrace"),
2028 | 12: CompletionChunk.Kind("LeftAngle"),
2029 | 13: CompletionChunk.Kind("RightAngle"),
2030 | 14: CompletionChunk.Kind("Comma"),
2031 | 15: CompletionChunk.Kind("ResultType"),
2032 | 16: CompletionChunk.Kind("Colon"),
2033 | 17: CompletionChunk.Kind("SemiColon"),
2034 | 18: CompletionChunk.Kind("Equal"),
2035 | 19: CompletionChunk.Kind("HorizontalSpace"),
2036 | 20: CompletionChunk.Kind("VerticalSpace")}
2037 |
2038 | class CompletionString(ClangObject):
2039 | class Availability:
2040 | def __init__(self, name):
2041 | self.name = name
2042 |
2043 | def __str__(self):
2044 | return self.name
2045 |
2046 | def __repr__(self):
2047 | return "" % self
2048 |
2049 | def __len__(self):
2050 | return self.num_chunks
2051 |
2052 | @CachedProperty
2053 | def num_chunks(self):
2054 | return conf.lib.clang_getNumCompletionChunks(self.obj)
2055 |
2056 | def __getitem__(self, key):
2057 | if self.num_chunks <= key:
2058 | raise IndexError
2059 | return CompletionChunk(self.obj, key)
2060 |
2061 | @property
2062 | def priority(self):
2063 | return conf.lib.clang_getCompletionPriority(self.obj)
2064 |
2065 | @property
2066 | def availability(self):
2067 | res = conf.lib.clang_getCompletionAvailability(self.obj)
2068 | return availabilityKinds[res]
2069 |
2070 | @property
2071 | def briefComment(self):
2072 | if conf.function_exists("clang_getCompletionBriefComment"):
2073 | return conf.lib.clang_getCompletionBriefComment(self.obj)
2074 | return _CXString()
2075 |
2076 | def __repr__(self):
2077 | return " | ".join([str(a) for a in self]) \
2078 | + " || Priority: " + str(self.priority) \
2079 | + " || Availability: " + str(self.availability) \
2080 | + " || Brief comment: " + str(self.briefComment.spelling)
2081 |
2082 | availabilityKinds = {
2083 | 0: CompletionChunk.Kind("Available"),
2084 | 1: CompletionChunk.Kind("Deprecated"),
2085 | 2: CompletionChunk.Kind("NotAvailable"),
2086 | 3: CompletionChunk.Kind("NotAccessible")}
2087 |
2088 | class CodeCompletionResult(Structure):
2089 | _fields_ = [('cursorKind', c_int), ('completionString', c_object_p)]
2090 |
2091 | def __repr__(self):
2092 | return str(CompletionString(self.completionString))
2093 |
2094 | @property
2095 | def kind(self):
2096 | return CursorKind.from_id(self.cursorKind)
2097 |
2098 | @property
2099 | def string(self):
2100 | return CompletionString(self.completionString)
2101 |
2102 | class CCRStructure(Structure):
2103 | _fields_ = [('results', POINTER(CodeCompletionResult)),
2104 | ('numResults', c_int)]
2105 |
2106 | def __len__(self):
2107 | return self.numResults
2108 |
2109 | def __getitem__(self, key):
2110 | if len(self) <= key:
2111 | raise IndexError
2112 |
2113 | return self.results[key]
2114 |
2115 | class CodeCompletionResults(ClangObject):
2116 | def __init__(self, ptr):
2117 | assert isinstance(ptr, POINTER(CCRStructure)) and ptr
2118 | self.ptr = self._as_parameter_ = ptr
2119 |
2120 | def from_param(self):
2121 | return self._as_parameter_
2122 |
2123 | def __del__(self):
2124 | conf.lib.clang_disposeCodeCompleteResults(self)
2125 |
2126 | @property
2127 | def results(self):
2128 | return self.ptr.contents
2129 |
2130 | @property
2131 | def diagnostics(self):
2132 | class DiagnosticsItr:
2133 | def __init__(self, ccr):
2134 | self.ccr= ccr
2135 |
2136 | def __len__(self):
2137 | return int(\
2138 | conf.lib.clang_codeCompleteGetNumDiagnostics(self.ccr))
2139 |
2140 | def __getitem__(self, key):
2141 | return conf.lib.clang_codeCompleteGetDiagnostic(self.ccr, key)
2142 |
2143 | return DiagnosticsItr(self)
2144 |
2145 |
2146 | class Index(ClangObject):
2147 | """
2148 | The Index type provides the primary interface to the Clang CIndex library,
2149 | primarily by providing an interface for reading and parsing translation
2150 | units.
2151 | """
2152 |
2153 | @staticmethod
2154 | def create(excludeDecls=False):
2155 | """
2156 | Create a new Index.
2157 | Parameters:
2158 | excludeDecls -- Exclude local declarations from translation units.
2159 | """
2160 | return Index(conf.lib.clang_createIndex(excludeDecls, 0))
2161 |
2162 | def __del__(self):
2163 | conf.lib.clang_disposeIndex(self)
2164 |
2165 | def read(self, path):
2166 | """Load a TranslationUnit from the given AST file."""
2167 | return TranslationUnit.from_ast_file(path, self)
2168 |
2169 | def parse(self, path, args=None, unsaved_files=None, options = 0):
2170 | """Load the translation unit from the given source code file by running
2171 | clang and generating the AST before loading. Additional command line
2172 | parameters can be passed to clang via the args parameter.
2173 |
2174 | In-memory contents for files can be provided by passing a list of pairs
2175 | to as unsaved_files, the first item should be the filenames to be mapped
2176 | and the second should be the contents to be substituted for the
2177 | file. The contents may be passed as strings or file objects.
2178 |
2179 | If an error was encountered during parsing, a TranslationUnitLoadError
2180 | will be raised.
2181 | """
2182 | return TranslationUnit.from_source(path, args, unsaved_files, options,
2183 | self)
2184 |
2185 | class TranslationUnit(ClangObject):
2186 | """Represents a source code translation unit.
2187 |
2188 | This is one of the main types in the API. Any time you wish to interact
2189 | with Clang's representation of a source file, you typically start with a
2190 | translation unit.
2191 | """
2192 |
2193 | # Default parsing mode.
2194 | PARSE_NONE = 0
2195 |
2196 | # Instruct the parser to create a detailed processing record containing
2197 | # metadata not normally retained.
2198 | PARSE_DETAILED_PROCESSING_RECORD = 1
2199 |
2200 | # Indicates that the translation unit is incomplete. This is typically used
2201 | # when parsing headers.
2202 | PARSE_INCOMPLETE = 2
2203 |
2204 | # Instruct the parser to create a pre-compiled preamble for the translation
2205 | # unit. This caches the preamble (included files at top of source file).
2206 | # This is useful if the translation unit will be reparsed and you don't
2207 | # want to incur the overhead of reparsing the preamble.
2208 | PARSE_PRECOMPILED_PREAMBLE = 4
2209 |
2210 | # Cache code completion information on parse. This adds time to parsing but
2211 | # speeds up code completion.
2212 | PARSE_CACHE_COMPLETION_RESULTS = 8
2213 |
2214 | # Flags with values 16 and 32 are deprecated and intentionally omitted.
2215 |
2216 | # Do not parse function bodies. This is useful if you only care about
2217 | # searching for declarations/definitions.
2218 | PARSE_SKIP_FUNCTION_BODIES = 64
2219 |
2220 | # Used to indicate that brief documentation comments should be included
2221 | # into the set of code completions returned from this translation unit.
2222 | PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION = 128
2223 |
2224 | @classmethod
2225 | def from_source(cls, filename, args=None, unsaved_files=None, options=0,
2226 | index=None):
2227 | """Create a TranslationUnit by parsing source.
2228 |
2229 | This is capable of processing source code both from files on the
2230 | filesystem as well as in-memory contents.
2231 |
2232 | Command-line arguments that would be passed to clang are specified as
2233 | a list via args. These can be used to specify include paths, warnings,
2234 | etc. e.g. ["-Wall", "-I/path/to/include"].
2235 |
2236 | In-memory file content can be provided via unsaved_files. This is an
2237 | iterable of 2-tuples. The first element is the str filename. The
2238 | second element defines the content. Content can be provided as str
2239 | source code or as file objects (anything with a read() method). If
2240 | a file object is being used, content will be read until EOF and the
2241 | read cursor will not be reset to its original position.
2242 |
2243 | options is a bitwise or of TranslationUnit.PARSE_XXX flags which will
2244 | control parsing behavior.
2245 |
2246 | index is an Index instance to utilize. If not provided, a new Index
2247 | will be created for this TranslationUnit.
2248 |
2249 | To parse source from the filesystem, the filename of the file to parse
2250 | is specified by the filename argument. Or, filename could be None and
2251 | the args list would contain the filename(s) to parse.
2252 |
2253 | To parse source from an in-memory buffer, set filename to the virtual
2254 | filename you wish to associate with this source (e.g. "test.c"). The
2255 | contents of that file are then provided in unsaved_files.
2256 |
2257 | If an error occurs, a TranslationUnitLoadError is raised.
2258 |
2259 | Please note that a TranslationUnit with parser errors may be returned.
2260 | It is the caller's responsibility to check tu.diagnostics for errors.
2261 |
2262 | Also note that Clang infers the source language from the extension of
2263 | the input filename. If you pass in source code containing a C++ class
2264 | declaration with the filename "test.c" parsing will fail.
2265 | """
2266 | if args is None:
2267 | args = []
2268 |
2269 | if unsaved_files is None:
2270 | unsaved_files = []
2271 |
2272 | if index is None:
2273 | index = Index.create()
2274 |
2275 | args_array = None
2276 | if len(args) > 0:
2277 | args_array = (c_char_p * len(args))(* args)
2278 |
2279 | unsaved_array = None
2280 | if len(unsaved_files) > 0:
2281 | unsaved_array = (_CXUnsavedFile * len(unsaved_files))()
2282 | for i, (name, contents) in enumerate(unsaved_files):
2283 | if hasattr(contents, "read"):
2284 | contents = contents.read()
2285 |
2286 | unsaved_array[i].name = name
2287 | unsaved_array[i].contents = contents
2288 | unsaved_array[i].length = len(contents)
2289 |
2290 | ptr = conf.lib.clang_parseTranslationUnit(index, filename, args_array,
2291 | len(args), unsaved_array,
2292 | len(unsaved_files), options)
2293 |
2294 | if not ptr:
2295 | raise TranslationUnitLoadError("Error parsing translation unit.")
2296 |
2297 | return cls(ptr, index=index)
2298 |
2299 | @classmethod
2300 | def from_ast_file(cls, filename, index=None):
2301 | """Create a TranslationUnit instance from a saved AST file.
2302 |
2303 | A previously-saved AST file (provided with -emit-ast or
2304 | TranslationUnit.save()) is loaded from the filename specified.
2305 |
2306 | If the file cannot be loaded, a TranslationUnitLoadError will be
2307 | raised.
2308 |
2309 | index is optional and is the Index instance to use. If not provided,
2310 | a default Index will be created.
2311 | """
2312 | if index is None:
2313 | index = Index.create()
2314 |
2315 | ptr = conf.lib.clang_createTranslationUnit(index, filename)
2316 | if not ptr:
2317 | raise TranslationUnitLoadError(filename)
2318 |
2319 | return cls(ptr=ptr, index=index)
2320 |
2321 | def __init__(self, ptr, index):
2322 | """Create a TranslationUnit instance.
2323 |
2324 | TranslationUnits should be created using one of the from_* @classmethod
2325 | functions above. __init__ is only called internally.
2326 | """
2327 | assert isinstance(index, Index)
2328 |
2329 | ClangObject.__init__(self, ptr)
2330 |
2331 | def __del__(self):
2332 | conf.lib.clang_disposeTranslationUnit(self)
2333 |
2334 | @property
2335 | def cursor(self):
2336 | """Retrieve the cursor that represents the given translation unit."""
2337 | return conf.lib.clang_getTranslationUnitCursor(self)
2338 |
2339 | @property
2340 | def spelling(self):
2341 | """Get the original translation unit source file name."""
2342 | return conf.lib.clang_getTranslationUnitSpelling(self)
2343 |
2344 | def get_includes(self):
2345 | """
2346 | Return an iterable sequence of FileInclusion objects that describe the
2347 | sequence of inclusions in a translation unit. The first object in
2348 | this sequence is always the input file. Note that this method will not
2349 | recursively iterate over header files included through precompiled
2350 | headers.
2351 | """
2352 | def visitor(fobj, lptr, depth, includes):
2353 | if depth > 0:
2354 | loc = lptr.contents
2355 | includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
2356 |
2357 | # Automatically adapt CIndex/ctype pointers to python objects
2358 | includes = []
2359 | conf.lib.clang_getInclusions(self,
2360 | callbacks['translation_unit_includes'](visitor), includes)
2361 |
2362 | return iter(includes)
2363 |
2364 | def get_file(self, filename):
2365 | """Obtain a File from this translation unit."""
2366 |
2367 | return File.from_name(self, filename)
2368 |
2369 | def get_location(self, filename, position):
2370 | """Obtain a SourceLocation for a file in this translation unit.
2371 |
2372 | The position can be specified by passing:
2373 |
2374 | - Integer file offset. Initial file offset is 0.
2375 | - 2-tuple of (line number, column number). Initial file position is
2376 | (0, 0)
2377 | """
2378 | f = self.get_file(filename)
2379 |
2380 | if isinstance(position, int):
2381 | return SourceLocation.from_offset(self, f, position)
2382 |
2383 | return SourceLocation.from_position(self, f, position[0], position[1])
2384 |
2385 | def get_extent(self, filename, locations):
2386 | """Obtain a SourceRange from this translation unit.
2387 |
2388 | The bounds of the SourceRange must ultimately be defined by a start and
2389 | end SourceLocation. For the locations argument, you can pass:
2390 |
2391 | - 2 SourceLocation instances in a 2-tuple or list.
2392 | - 2 int file offsets via a 2-tuple or list.
2393 | - 2 2-tuple or lists of (line, column) pairs in a 2-tuple or list.
2394 |
2395 | e.g.
2396 |
2397 | get_extent('foo.c', (5, 10))
2398 | get_extent('foo.c', ((1, 1), (1, 15)))
2399 | """
2400 | f = self.get_file(filename)
2401 |
2402 | if len(locations) < 2:
2403 | raise Exception('Must pass object with at least 2 elements')
2404 |
2405 | start_location, end_location = locations
2406 |
2407 | if hasattr(start_location, '__len__'):
2408 | start_location = SourceLocation.from_position(self, f,
2409 | start_location[0], start_location[1])
2410 | elif isinstance(start_location, int):
2411 | start_location = SourceLocation.from_offset(self, f,
2412 | start_location)
2413 |
2414 | if hasattr(end_location, '__len__'):
2415 | end_location = SourceLocation.from_position(self, f,
2416 | end_location[0], end_location[1])
2417 | elif isinstance(end_location, int):
2418 | end_location = SourceLocation.from_offset(self, f, end_location)
2419 |
2420 | assert isinstance(start_location, SourceLocation)
2421 | assert isinstance(end_location, SourceLocation)
2422 |
2423 | return SourceRange.from_locations(start_location, end_location)
2424 |
2425 | @property
2426 | def diagnostics(self):
2427 | """
2428 | Return an iterable (and indexable) object containing the diagnostics.
2429 | """
2430 | class DiagIterator:
2431 | def __init__(self, tu):
2432 | self.tu = tu
2433 |
2434 | def __len__(self):
2435 | return int(conf.lib.clang_getNumDiagnostics(self.tu))
2436 |
2437 | def __getitem__(self, key):
2438 | diag = conf.lib.clang_getDiagnostic(self.tu, key)
2439 | if not diag:
2440 | raise IndexError
2441 | return Diagnostic(diag)
2442 |
2443 | return DiagIterator(self)
2444 |
2445 | def reparse(self, unsaved_files=None, options=0):
2446 | """
2447 | Reparse an already parsed translation unit.
2448 |
2449 | In-memory contents for files can be provided by passing a list of pairs
2450 | as unsaved_files, the first items should be the filenames to be mapped
2451 | and the second should be the contents to be substituted for the
2452 | file. The contents may be passed as strings or file objects.
2453 | """
2454 | if unsaved_files is None:
2455 | unsaved_files = []
2456 |
2457 | unsaved_files_array = 0
2458 | if len(unsaved_files):
2459 | unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
2460 | for i,(name,value) in enumerate(unsaved_files):
2461 | if not isinstance(value, str):
2462 | # FIXME: It would be great to support an efficient version
2463 | # of this, one day.
2464 | value = value.read()
2465 | print value
2466 | if not isinstance(value, str):
2467 | raise TypeError,'Unexpected unsaved file contents.'
2468 | unsaved_files_array[i].name = name
2469 | unsaved_files_array[i].contents = value
2470 | unsaved_files_array[i].length = len(value)
2471 | ptr = conf.lib.clang_reparseTranslationUnit(self, len(unsaved_files),
2472 | unsaved_files_array, options)
2473 |
2474 | def save(self, filename):
2475 | """Saves the TranslationUnit to a file.
2476 |
2477 | This is equivalent to passing -emit-ast to the clang frontend. The
2478 | saved file can be loaded back into a TranslationUnit. Or, if it
2479 | corresponds to a header, it can be used as a pre-compiled header file.
2480 |
2481 | If an error occurs while saving, a TranslationUnitSaveError is raised.
2482 | If the error was TranslationUnitSaveError.ERROR_INVALID_TU, this means
2483 | the constructed TranslationUnit was not valid at time of save. In this
2484 | case, the reason(s) why should be available via
2485 | TranslationUnit.diagnostics().
2486 |
2487 | filename -- The path to save the translation unit to.
2488 | """
2489 | options = conf.lib.clang_defaultSaveOptions(self)
2490 | result = int(conf.lib.clang_saveTranslationUnit(self, filename,
2491 | options))
2492 | if result != 0:
2493 | raise TranslationUnitSaveError(result,
2494 | 'Error saving TranslationUnit.')
2495 |
2496 | def codeComplete(self, path, line, column, unsaved_files=None,
2497 | include_macros=False, include_code_patterns=False,
2498 | include_brief_comments=False):
2499 | """
2500 | Code complete in this translation unit.
2501 |
2502 | In-memory contents for files can be provided by passing a list of pairs
2503 | as unsaved_files, the first items should be the filenames to be mapped
2504 | and the second should be the contents to be substituted for the
2505 | file. The contents may be passed as strings or file objects.
2506 | """
2507 | options = 0
2508 |
2509 | if include_macros:
2510 | options += 1
2511 |
2512 | if include_code_patterns:
2513 | options += 2
2514 |
2515 | if include_brief_comments:
2516 | options += 4
2517 |
2518 | if unsaved_files is None:
2519 | unsaved_files = []
2520 |
2521 | unsaved_files_array = 0
2522 | if len(unsaved_files):
2523 | unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
2524 | for i,(name,value) in enumerate(unsaved_files):
2525 | if not isinstance(value, str):
2526 | # FIXME: It would be great to support an efficient version
2527 | # of this, one day.
2528 | value = value.read()
2529 | print value
2530 | if not isinstance(value, str):
2531 | raise TypeError,'Unexpected unsaved file contents.'
2532 | unsaved_files_array[i].name = name
2533 | unsaved_files_array[i].contents = value
2534 | unsaved_files_array[i].length = len(value)
2535 | ptr = conf.lib.clang_codeCompleteAt(self, path, line, column,
2536 | unsaved_files_array, len(unsaved_files), options)
2537 | if ptr:
2538 | return CodeCompletionResults(ptr)
2539 | return None
2540 |
2541 | def get_tokens(self, locations=None, extent=None):
2542 | """Obtain tokens in this translation unit.
2543 |
2544 | This is a generator for Token instances. The caller specifies a range
2545 | of source code to obtain tokens for. The range can be specified as a
2546 | 2-tuple of SourceLocation or as a SourceRange. If both are defined,
2547 | behavior is undefined.
2548 | """
2549 | if locations is not None:
2550 | extent = SourceRange(start=locations[0], end=locations[1])
2551 |
2552 | return TokenGroup.get_tokens(self, extent)
2553 |
2554 | class File(ClangObject):
2555 | """
2556 | The File class represents a particular source file that is part of a
2557 | translation unit.
2558 | """
2559 |
2560 | @staticmethod
2561 | def from_name(translation_unit, file_name):
2562 | """Retrieve a file handle within the given translation unit."""
2563 | return File(conf.lib.clang_getFile(translation_unit, file_name))
2564 |
2565 | @property
2566 | def name(self):
2567 | """Return the complete file and path name of the file."""
2568 | return conf.lib.clang_getCString(conf.lib.clang_getFileName(self))
2569 |
2570 | @property
2571 | def time(self):
2572 | """Return the last modification time of the file."""
2573 | return conf.lib.clang_getFileTime(self)
2574 |
2575 | def __str__(self):
2576 | return self.name
2577 |
2578 | def __repr__(self):
2579 | return "" % (self.name)
2580 |
2581 | @staticmethod
2582 | def from_cursor_result(res, fn, args):
2583 | assert isinstance(res, File)
2584 |
2585 | # Copy a reference to the TranslationUnit to prevent premature GC.
2586 | res._tu = args[0]._tu
2587 | return res
2588 |
2589 | class FileInclusion(object):
2590 | """
2591 | The FileInclusion class represents the inclusion of one source file by
2592 | another via a '#include' directive or as the input file for the translation
2593 | unit. This class provides information about the included file, the including
2594 | file, the location of the '#include' directive and the depth of the included
2595 | file in the stack. Note that the input file has depth 0.
2596 | """
2597 |
2598 | def __init__(self, src, tgt, loc, depth):
2599 | self.source = src
2600 | self.include = tgt
2601 | self.location = loc
2602 | self.depth = depth
2603 |
2604 | @property
2605 | def is_input_file(self):
2606 | """True if the included file is the input file."""
2607 | return self.depth == 0
2608 |
2609 | class CompilationDatabaseError(Exception):
2610 | """Represents an error that occurred when working with a CompilationDatabase
2611 |
2612 | Each error is associated to an enumerated value, accessible under
2613 | e.cdb_error. Consumers can compare the value with one of the ERROR_
2614 | constants in this class.
2615 | """
2616 |
2617 | # An unknown error occurred
2618 | ERROR_UNKNOWN = 0
2619 |
2620 | # The database could not be loaded
2621 | ERROR_CANNOTLOADDATABASE = 1
2622 |
2623 | def __init__(self, enumeration, message):
2624 | assert isinstance(enumeration, int)
2625 |
2626 | if enumeration > 1:
2627 | raise Exception("Encountered undefined CompilationDatabase error "
2628 | "constant: %d. Please file a bug to have this "
2629 | "value supported." % enumeration)
2630 |
2631 | self.cdb_error = enumeration
2632 | Exception.__init__(self, 'Error %d: %s' % (enumeration, message))
2633 |
2634 | class CompileCommand(object):
2635 | """Represents the compile command used to build a file"""
2636 | def __init__(self, cmd, ccmds):
2637 | self.cmd = cmd
2638 | # Keep a reference to the originating CompileCommands
2639 | # to prevent garbage collection
2640 | self.ccmds = ccmds
2641 |
2642 | @property
2643 | def directory(self):
2644 | """Get the working directory for this CompileCommand"""
2645 | return conf.lib.clang_CompileCommand_getDirectory(self.cmd)
2646 |
2647 | @property
2648 | def arguments(self):
2649 | """
2650 | Get an iterable object providing each argument in the
2651 | command line for the compiler invocation as a _CXString.
2652 |
2653 | Invariant : the first argument is the compiler executable
2654 | """
2655 | length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd)
2656 | for i in xrange(length):
2657 | yield conf.lib.clang_CompileCommand_getArg(self.cmd, i)
2658 |
2659 | class CompileCommands(object):
2660 | """
2661 | CompileCommands is an iterable object containing all CompileCommand
2662 | that can be used for building a specific file.
2663 | """
2664 | def __init__(self, ccmds):
2665 | self.ccmds = ccmds
2666 |
2667 | def __del__(self):
2668 | conf.lib.clang_CompileCommands_dispose(self.ccmds)
2669 |
2670 | def __len__(self):
2671 | return int(conf.lib.clang_CompileCommands_getSize(self.ccmds))
2672 |
2673 | def __getitem__(self, i):
2674 | cc = conf.lib.clang_CompileCommands_getCommand(self.ccmds, i)
2675 | if not cc:
2676 | raise IndexError
2677 | return CompileCommand(cc, self)
2678 |
2679 | @staticmethod
2680 | def from_result(res, fn, args):
2681 | if not res:
2682 | return None
2683 | return CompileCommands(res)
2684 |
2685 | class CompilationDatabase(ClangObject):
2686 | """
2687 | The CompilationDatabase is a wrapper class around
2688 | clang::tooling::CompilationDatabase
2689 |
2690 | It enables querying how a specific source file can be built.
2691 | """
2692 |
2693 | def __del__(self):
2694 | conf.lib.clang_CompilationDatabase_dispose(self)
2695 |
2696 | @staticmethod
2697 | def from_result(res, fn, args):
2698 | if not res:
2699 | raise CompilationDatabaseError(0,
2700 | "CompilationDatabase loading failed")
2701 | return CompilationDatabase(res)
2702 |
2703 | @staticmethod
2704 | def fromDirectory(buildDir):
2705 | """Builds a CompilationDatabase from the database found in buildDir"""
2706 | errorCode = c_uint()
2707 | try:
2708 | cdb = conf.lib.clang_CompilationDatabase_fromDirectory(buildDir,
2709 | byref(errorCode))
2710 | except CompilationDatabaseError as e:
2711 | raise CompilationDatabaseError(int(errorCode.value),
2712 | "CompilationDatabase loading failed")
2713 | return cdb
2714 |
2715 | def getCompileCommands(self, filename):
2716 | """
2717 | Get an iterable object providing all the CompileCommands available to
2718 | build filename. Returns None if filename is not found in the database.
2719 | """
2720 | return conf.lib.clang_CompilationDatabase_getCompileCommands(self,
2721 | filename)
2722 |
2723 | def getAllCompileCommands(self):
2724 | """
2725 | Get an iterable object providing all the CompileCommands available from
2726 | the database.
2727 | """
2728 | return conf.lib.clang_CompilationDatabase_getAllCompileCommands(self)
2729 |
2730 |
2731 | class Token(Structure):
2732 | """Represents a single token from the preprocessor.
2733 |
2734 | Tokens are effectively segments of source code. Source code is first parsed
2735 | into tokens before being converted into the AST and Cursors.
2736 |
2737 | Tokens are obtained from parsed TranslationUnit instances. You currently
2738 | can't create tokens manually.
2739 | """
2740 | _fields_ = [
2741 | ('int_data', c_uint * 4),
2742 | ('ptr_data', c_void_p)
2743 | ]
2744 |
2745 | @property
2746 | def spelling(self):
2747 | """The spelling of this token.
2748 |
2749 | This is the textual representation of the token in source.
2750 | """
2751 | return conf.lib.clang_getTokenSpelling(self._tu, self)
2752 |
2753 | @property
2754 | def kind(self):
2755 | """Obtain the TokenKind of the current token."""
2756 | return TokenKind.from_value(conf.lib.clang_getTokenKind(self))
2757 |
2758 | @property
2759 | def location(self):
2760 | """The SourceLocation this Token occurs at."""
2761 | return conf.lib.clang_getTokenLocation(self._tu, self)
2762 |
2763 | @property
2764 | def extent(self):
2765 | """The SourceRange this Token occupies."""
2766 | return conf.lib.clang_getTokenExtent(self._tu, self)
2767 |
2768 | @property
2769 | def cursor(self):
2770 | """The Cursor this Token corresponds to."""
2771 | cursor = Cursor()
2772 |
2773 | conf.lib.clang_annotateTokens(self._tu, byref(self), 1, byref(cursor))
2774 |
2775 | return cursor
2776 |
2777 | # Now comes the plumbing to hook up the C library.
2778 |
2779 | # Register callback types in common container.
2780 | callbacks['translation_unit_includes'] = CFUNCTYPE(None, c_object_p,
2781 | POINTER(SourceLocation), c_uint, py_object)
2782 | callbacks['cursor_visit'] = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
2783 |
2784 | # Functions strictly alphabetical order.
2785 | functionList = [
2786 | ("clang_annotateTokens",
2787 | [TranslationUnit, POINTER(Token), c_uint, POINTER(Cursor)]),
2788 |
2789 | ("clang_CompilationDatabase_dispose",
2790 | [c_object_p]),
2791 |
2792 | ("clang_CompilationDatabase_fromDirectory",
2793 | [c_char_p, POINTER(c_uint)],
2794 | c_object_p,
2795 | CompilationDatabase.from_result),
2796 |
2797 | ("clang_CompilationDatabase_getAllCompileCommands",
2798 | [c_object_p],
2799 | c_object_p,
2800 | CompileCommands.from_result),
2801 |
2802 | ("clang_CompilationDatabase_getCompileCommands",
2803 | [c_object_p, c_char_p],
2804 | c_object_p,
2805 | CompileCommands.from_result),
2806 |
2807 | ("clang_CompileCommands_dispose",
2808 | [c_object_p]),
2809 |
2810 | ("clang_CompileCommands_getCommand",
2811 | [c_object_p, c_uint],
2812 | c_object_p),
2813 |
2814 | ("clang_CompileCommands_getSize",
2815 | [c_object_p],
2816 | c_uint),
2817 |
2818 | ("clang_CompileCommand_getArg",
2819 | [c_object_p, c_uint],
2820 | _CXString,
2821 | _CXString.from_result),
2822 |
2823 | ("clang_CompileCommand_getDirectory",
2824 | [c_object_p],
2825 | _CXString,
2826 | _CXString.from_result),
2827 |
2828 | ("clang_CompileCommand_getNumArgs",
2829 | [c_object_p],
2830 | c_uint),
2831 |
2832 | ("clang_codeCompleteAt",
2833 | [TranslationUnit, c_char_p, c_int, c_int, c_void_p, c_int, c_int],
2834 | POINTER(CCRStructure)),
2835 |
2836 | ("clang_codeCompleteGetDiagnostic",
2837 | [CodeCompletionResults, c_int],
2838 | Diagnostic),
2839 |
2840 | ("clang_codeCompleteGetNumDiagnostics",
2841 | [CodeCompletionResults],
2842 | c_int),
2843 |
2844 | ("clang_createIndex",
2845 | [c_int, c_int],
2846 | c_object_p),
2847 |
2848 | ("clang_createTranslationUnit",
2849 | [Index, c_char_p],
2850 | c_object_p),
2851 |
2852 | ("clang_CXXMethod_isPureVirtual",
2853 | [Cursor],
2854 | bool),
2855 |
2856 | ("clang_CXXMethod_isStatic",
2857 | [Cursor],
2858 | bool),
2859 |
2860 | ("clang_CXXMethod_isVirtual",
2861 | [Cursor],
2862 | bool),
2863 |
2864 | ("clang_defaultSaveOptions",
2865 | [TranslationUnit],
2866 | c_uint),
2867 |
2868 | ("clang_disposeCodeCompleteResults",
2869 | [CodeCompletionResults]),
2870 |
2871 | # ("clang_disposeCXTUResourceUsage",
2872 | # [CXTUResourceUsage]),
2873 |
2874 | ("clang_disposeDiagnostic",
2875 | [Diagnostic]),
2876 |
2877 | ("clang_disposeIndex",
2878 | [Index]),
2879 |
2880 | ("clang_disposeString",
2881 | [_CXString]),
2882 |
2883 | ("clang_disposeTokens",
2884 | [TranslationUnit, POINTER(Token), c_uint]),
2885 |
2886 | ("clang_disposeTranslationUnit",
2887 | [TranslationUnit]),
2888 |
2889 | ("clang_equalCursors",
2890 | [Cursor, Cursor],
2891 | bool),
2892 |
2893 | ("clang_equalLocations",
2894 | [SourceLocation, SourceLocation],
2895 | bool),
2896 |
2897 | ("clang_equalRanges",
2898 | [SourceRange, SourceRange],
2899 | bool),
2900 |
2901 | ("clang_equalTypes",
2902 | [Type, Type],
2903 | bool),
2904 |
2905 | ("clang_getArgType",
2906 | [Type, c_uint],
2907 | Type,
2908 | Type.from_result),
2909 |
2910 | ("clang_getArrayElementType",
2911 | [Type],
2912 | Type,
2913 | Type.from_result),
2914 |
2915 | ("clang_getArraySize",
2916 | [Type],
2917 | c_longlong),
2918 |
2919 | ("clang_getFieldDeclBitWidth",
2920 | [Cursor],
2921 | c_int),
2922 |
2923 | ("clang_getCanonicalCursor",
2924 | [Cursor],
2925 | Cursor,
2926 | Cursor.from_cursor_result),
2927 |
2928 | ("clang_getCanonicalType",
2929 | [Type],
2930 | Type,
2931 | Type.from_result),
2932 |
2933 | ("clang_getCompletionAvailability",
2934 | [c_void_p],
2935 | c_int),
2936 |
2937 | ("clang_getCompletionBriefComment",
2938 | [c_void_p],
2939 | _CXString),
2940 |
2941 | ("clang_getCompletionChunkCompletionString",
2942 | [c_void_p, c_int],
2943 | c_object_p),
2944 |
2945 | ("clang_getCompletionChunkKind",
2946 | [c_void_p, c_int],
2947 | c_int),
2948 |
2949 | ("clang_getCompletionChunkText",
2950 | [c_void_p, c_int],
2951 | _CXString),
2952 |
2953 | ("clang_getCompletionPriority",
2954 | [c_void_p],
2955 | c_int),
2956 |
2957 | ("clang_getCString",
2958 | [_CXString],
2959 | c_char_p),
2960 |
2961 | ("clang_getCursor",
2962 | [TranslationUnit, SourceLocation],
2963 | Cursor),
2964 |
2965 | ("clang_getCursorDefinition",
2966 | [Cursor],
2967 | Cursor,
2968 | Cursor.from_result),
2969 |
2970 | ("clang_getCursorDisplayName",
2971 | [Cursor],
2972 | _CXString,
2973 | _CXString.from_result),
2974 |
2975 | ("clang_getCursorExtent",
2976 | [Cursor],
2977 | SourceRange),
2978 |
2979 | ("clang_getCursorLexicalParent",
2980 | [Cursor],
2981 | Cursor,
2982 | Cursor.from_cursor_result),
2983 |
2984 | ("clang_getCursorLocation",
2985 | [Cursor],
2986 | SourceLocation),
2987 |
2988 | ("clang_getCursorReferenced",
2989 | [Cursor],
2990 | Cursor,
2991 | Cursor.from_result),
2992 |
2993 | ("clang_getCursorReferenceNameRange",
2994 | [Cursor, c_uint, c_uint],
2995 | SourceRange),
2996 |
2997 | ("clang_getCursorSemanticParent",
2998 | [Cursor],
2999 | Cursor,
3000 | Cursor.from_cursor_result),
3001 |
3002 | ("clang_getCursorSpelling",
3003 | [Cursor],
3004 | _CXString,
3005 | _CXString.from_result),
3006 |
3007 | ("clang_getCursorType",
3008 | [Cursor],
3009 | Type,
3010 | Type.from_result),
3011 |
3012 | ("clang_getCursorUSR",
3013 | [Cursor],
3014 | _CXString,
3015 | _CXString.from_result),
3016 |
3017 | ("clang_Cursor_getMangling",
3018 | [Cursor],
3019 | _CXString,
3020 | _CXString.from_result),
3021 |
3022 | # ("clang_getCXTUResourceUsage",
3023 | # [TranslationUnit],
3024 | # CXTUResourceUsage),
3025 |
3026 | ("clang_getCXXAccessSpecifier",
3027 | [Cursor],
3028 | c_uint),
3029 |
3030 | ("clang_getDeclObjCTypeEncoding",
3031 | [Cursor],
3032 | _CXString,
3033 | _CXString.from_result),
3034 |
3035 | ("clang_getDiagnostic",
3036 | [c_object_p, c_uint],
3037 | c_object_p),
3038 |
3039 | ("clang_getDiagnosticCategory",
3040 | [Diagnostic],
3041 | c_uint),
3042 |
3043 | ("clang_getDiagnosticCategoryText",
3044 | [Diagnostic],
3045 | _CXString,
3046 | _CXString.from_result),
3047 |
3048 | ("clang_getDiagnosticFixIt",
3049 | [Diagnostic, c_uint, POINTER(SourceRange)],
3050 | _CXString,
3051 | _CXString.from_result),
3052 |
3053 | ("clang_getDiagnosticLocation",
3054 | [Diagnostic],
3055 | SourceLocation),
3056 |
3057 | ("clang_getDiagnosticNumFixIts",
3058 | [Diagnostic],
3059 | c_uint),
3060 |
3061 | ("clang_getDiagnosticNumRanges",
3062 | [Diagnostic],
3063 | c_uint),
3064 |
3065 | ("clang_getDiagnosticOption",
3066 | [Diagnostic, POINTER(_CXString)],
3067 | _CXString,
3068 | _CXString.from_result),
3069 |
3070 | ("clang_getDiagnosticRange",
3071 | [Diagnostic, c_uint],
3072 | SourceRange),
3073 |
3074 | ("clang_getDiagnosticSeverity",
3075 | [Diagnostic],
3076 | c_int),
3077 |
3078 | ("clang_getDiagnosticSpelling",
3079 | [Diagnostic],
3080 | _CXString,
3081 | _CXString.from_result),
3082 |
3083 | ("clang_getElementType",
3084 | [Type],
3085 | Type,
3086 | Type.from_result),
3087 |
3088 | ("clang_getEnumConstantDeclUnsignedValue",
3089 | [Cursor],
3090 | c_ulonglong),
3091 |
3092 | ("clang_getEnumConstantDeclValue",
3093 | [Cursor],
3094 | c_longlong),
3095 |
3096 | ("clang_getEnumDeclIntegerType",
3097 | [Cursor],
3098 | Type,
3099 | Type.from_result),
3100 |
3101 | ("clang_getFile",
3102 | [TranslationUnit, c_char_p],
3103 | c_object_p),
3104 |
3105 | ("clang_getFileName",
3106 | [File],
3107 | _CXString), # TODO go through _CXString.from_result?
3108 |
3109 | ("clang_getFileTime",
3110 | [File],
3111 | c_uint),
3112 |
3113 | ("clang_getIBOutletCollectionType",
3114 | [Cursor],
3115 | Type,
3116 | Type.from_result),
3117 |
3118 | ("clang_getIncludedFile",
3119 | [Cursor],
3120 | File,
3121 | File.from_cursor_result),
3122 |
3123 | ("clang_getInclusions",
3124 | [TranslationUnit, callbacks['translation_unit_includes'], py_object]),
3125 |
3126 | ("clang_getInstantiationLocation",
3127 | [SourceLocation, POINTER(c_object_p), POINTER(c_uint), POINTER(c_uint),
3128 | POINTER(c_uint)]),
3129 |
3130 | ("clang_getLocation",
3131 | [TranslationUnit, File, c_uint, c_uint],
3132 | SourceLocation),
3133 |
3134 | ("clang_getLocationForOffset",
3135 | [TranslationUnit, File, c_uint],
3136 | SourceLocation),
3137 |
3138 | ("clang_getNullCursor",
3139 | None,
3140 | Cursor),
3141 |
3142 | ("clang_getNumArgTypes",
3143 | [Type],
3144 | c_uint),
3145 |
3146 | ("clang_getNumCompletionChunks",
3147 | [c_void_p],
3148 | c_int),
3149 |
3150 | ("clang_getNumDiagnostics",
3151 | [c_object_p],
3152 | c_uint),
3153 |
3154 | ("clang_getNumElements",
3155 | [Type],
3156 | c_longlong),
3157 |
3158 | ("clang_getNumOverloadedDecls",
3159 | [Cursor],
3160 | c_uint),
3161 |
3162 | ("clang_getOverloadedDecl",
3163 | [Cursor, c_uint],
3164 | Cursor,
3165 | Cursor.from_cursor_result),
3166 |
3167 | ("clang_getPointeeType",
3168 | [Type],
3169 | Type,
3170 | Type.from_result),
3171 |
3172 | ("clang_getRange",
3173 | [SourceLocation, SourceLocation],
3174 | SourceRange),
3175 |
3176 | ("clang_getRangeEnd",
3177 | [SourceRange],
3178 | SourceLocation),
3179 |
3180 | ("clang_getRangeStart",
3181 | [SourceRange],
3182 | SourceLocation),
3183 |
3184 | ("clang_getResultType",
3185 | [Type],
3186 | Type,
3187 | Type.from_result),
3188 |
3189 | ("clang_getSpecializedCursorTemplate",
3190 | [Cursor],
3191 | Cursor,
3192 | Cursor.from_cursor_result),
3193 |
3194 | ("clang_getTemplateCursorKind",
3195 | [Cursor],
3196 | c_uint),
3197 |
3198 | ("clang_getTokenExtent",
3199 | [TranslationUnit, Token],
3200 | SourceRange),
3201 |
3202 | ("clang_getTokenKind",
3203 | [Token],
3204 | c_uint),
3205 |
3206 | ("clang_getTokenLocation",
3207 | [TranslationUnit, Token],
3208 | SourceLocation),
3209 |
3210 | ("clang_getTokenSpelling",
3211 | [TranslationUnit, Token],
3212 | _CXString,
3213 | _CXString.from_result),
3214 |
3215 | ("clang_getTranslationUnitCursor",
3216 | [TranslationUnit],
3217 | Cursor,
3218 | Cursor.from_result),
3219 |
3220 | ("clang_getTranslationUnitSpelling",
3221 | [TranslationUnit],
3222 | _CXString,
3223 | _CXString.from_result),
3224 |
3225 | ("clang_getTUResourceUsageName",
3226 | [c_uint],
3227 | c_char_p),
3228 |
3229 | ("clang_getTypeDeclaration",
3230 | [Type],
3231 | Cursor,
3232 | Cursor.from_result),
3233 |
3234 | ("clang_getTypedefDeclUnderlyingType",
3235 | [Cursor],
3236 | Type,
3237 | Type.from_result),
3238 |
3239 | ("clang_getTypeKindSpelling",
3240 | [c_uint],
3241 | _CXString,
3242 | _CXString.from_result),
3243 |
3244 | ("clang_getTypeSpelling",
3245 | [Type],
3246 | _CXString,
3247 | _CXString.from_result),
3248 |
3249 | ("clang_hashCursor",
3250 | [Cursor],
3251 | c_uint),
3252 |
3253 | ("clang_isAttribute",
3254 | [CursorKind],
3255 | bool),
3256 |
3257 | ("clang_isConstQualifiedType",
3258 | [Type],
3259 | bool),
3260 |
3261 | ("clang_isCursorDefinition",
3262 | [Cursor],
3263 | bool),
3264 |
3265 | ("clang_isDeclaration",
3266 | [CursorKind],
3267 | bool),
3268 |
3269 | ("clang_isExpression",
3270 | [CursorKind],
3271 | bool),
3272 |
3273 | ("clang_isFileMultipleIncludeGuarded",
3274 | [TranslationUnit, File],
3275 | bool),
3276 |
3277 | ("clang_isFunctionTypeVariadic",
3278 | [Type],
3279 | bool),
3280 |
3281 | ("clang_isInvalid",
3282 | [CursorKind],
3283 | bool),
3284 |
3285 | ("clang_isPODType",
3286 | [Type],
3287 | bool),
3288 |
3289 | ("clang_isPreprocessing",
3290 | [CursorKind],
3291 | bool),
3292 |
3293 | ("clang_isReference",
3294 | [CursorKind],
3295 | bool),
3296 |
3297 | ("clang_isRestrictQualifiedType",
3298 | [Type],
3299 | bool),
3300 |
3301 | ("clang_isStatement",
3302 | [CursorKind],
3303 | bool),
3304 |
3305 | ("clang_isTranslationUnit",
3306 | [CursorKind],
3307 | bool),
3308 |
3309 | ("clang_isUnexposed",
3310 | [CursorKind],
3311 | bool),
3312 |
3313 | ("clang_isVirtualBase",
3314 | [Cursor],
3315 | bool),
3316 |
3317 | ("clang_isVolatileQualifiedType",
3318 | [Type],
3319 | bool),
3320 |
3321 | ("clang_parseTranslationUnit",
3322 | [Index, c_char_p, c_void_p, c_int, c_void_p, c_int, c_int],
3323 | c_object_p),
3324 |
3325 | ("clang_reparseTranslationUnit",
3326 | [TranslationUnit, c_int, c_void_p, c_int],
3327 | c_int),
3328 |
3329 | ("clang_saveTranslationUnit",
3330 | [TranslationUnit, c_char_p, c_uint],
3331 | c_int),
3332 |
3333 | ("clang_tokenize",
3334 | [TranslationUnit, SourceRange, POINTER(POINTER(Token)), POINTER(c_uint)]),
3335 |
3336 | ("clang_visitChildren",
3337 | [Cursor, callbacks['cursor_visit'], py_object],
3338 | c_uint),
3339 |
3340 | ("clang_Cursor_getNumArguments",
3341 | [Cursor],
3342 | c_int),
3343 |
3344 | ("clang_Cursor_getArgument",
3345 | [Cursor, c_uint],
3346 | Cursor,
3347 | Cursor.from_result),
3348 |
3349 | ("clang_Cursor_getNumTemplateArguments",
3350 | [Cursor],
3351 | c_int),
3352 |
3353 | ("clang_Cursor_getTemplateArgumentKind",
3354 | [Cursor, c_uint],
3355 | TemplateArgumentKind.from_id),
3356 |
3357 | ("clang_Cursor_getTemplateArgumentType",
3358 | [Cursor, c_uint],
3359 | Type,
3360 | Type.from_result),
3361 |
3362 | ("clang_Cursor_getTemplateArgumentValue",
3363 | [Cursor, c_uint],
3364 | c_longlong),
3365 |
3366 | ("clang_Cursor_getTemplateArgumentUnsignedValue",
3367 | [Cursor, c_uint],
3368 | c_ulonglong),
3369 |
3370 | ("clang_Cursor_isBitField",
3371 | [Cursor],
3372 | bool),
3373 |
3374 | ("clang_Cursor_getBriefCommentText",
3375 | [Cursor],
3376 | _CXString,
3377 | _CXString.from_result),
3378 |
3379 | ("clang_Cursor_getRawCommentText",
3380 | [Cursor],
3381 | _CXString,
3382 | _CXString.from_result),
3383 |
3384 | ("clang_Type_getAlignOf",
3385 | [Type],
3386 | c_longlong),
3387 |
3388 | ("clang_Type_getClassType",
3389 | [Type],
3390 | Type,
3391 | Type.from_result),
3392 |
3393 | ("clang_Type_getOffsetOf",
3394 | [Type, c_char_p],
3395 | c_longlong),
3396 |
3397 | ("clang_Type_getSizeOf",
3398 | [Type],
3399 | c_longlong),
3400 |
3401 | ("clang_Type_getCXXRefQualifier",
3402 | [Type],
3403 | c_uint),
3404 | ]
3405 |
3406 | class LibclangError(Exception):
3407 | def __init__(self, message):
3408 | self.m = message
3409 |
3410 | def __str__(self):
3411 | return self.m
3412 |
3413 | def register_function(lib, item, ignore_errors):
3414 | # A function may not exist, if these bindings are used with an older or
3415 | # incompatible version of libclang.so.
3416 | try:
3417 | func = getattr(lib, item[0])
3418 | except AttributeError as e:
3419 | msg = str(e) + ". Please ensure that your python bindings are "\
3420 | "compatible with your libclang.so version."
3421 | if ignore_errors:
3422 | return
3423 | raise LibclangError(msg)
3424 |
3425 | if len(item) >= 2:
3426 | func.argtypes = item[1]
3427 |
3428 | if len(item) >= 3:
3429 | func.restype = item[2]
3430 |
3431 | if len(item) == 4:
3432 | func.errcheck = item[3]
3433 |
3434 | def register_functions(lib, ignore_errors):
3435 | """Register function prototypes with a libclang library instance.
3436 |
3437 | This must be called as part of library instantiation so Python knows how
3438 | to call out to the shared library.
3439 | """
3440 |
3441 | def register(item):
3442 | return register_function(lib, item, ignore_errors)
3443 |
3444 | map(register, functionList)
3445 |
3446 | class Config:
3447 | library_path = None
3448 | library_file = None
3449 | compatibility_check = True
3450 | loaded = False
3451 |
3452 | @staticmethod
3453 | def set_library_path(path):
3454 | """Set the path in which to search for libclang"""
3455 | if Config.loaded:
3456 | raise Exception("library path must be set before before using " \
3457 | "any other functionalities in libclang.")
3458 |
3459 | Config.library_path = path
3460 |
3461 | @staticmethod
3462 | def set_library_file(filename):
3463 | """Set the exact location of libclang"""
3464 | if Config.loaded:
3465 | raise Exception("library file must be set before before using " \
3466 | "any other functionalities in libclang.")
3467 |
3468 | Config.library_file = filename
3469 |
3470 | @staticmethod
3471 | def set_compatibility_check(check_status):
3472 | """ Perform compatibility check when loading libclang
3473 |
3474 | The python bindings are only tested and evaluated with the version of
3475 | libclang they are provided with. To ensure correct behavior a (limited)
3476 | compatibility check is performed when loading the bindings. This check
3477 | will throw an exception, as soon as it fails.
3478 |
3479 | In case these bindings are used with an older version of libclang, parts
3480 | that have been stable between releases may still work. Users of the
3481 | python bindings can disable the compatibility check. This will cause
3482 | the python bindings to load, even though they are written for a newer
3483 | version of libclang. Failures now arise if unsupported or incompatible
3484 | features are accessed. The user is required to test themselves if the
3485 | features they are using are available and compatible between different
3486 | libclang versions.
3487 | """
3488 | if Config.loaded:
3489 | raise Exception("compatibility_check must be set before before " \
3490 | "using any other functionalities in libclang.")
3491 |
3492 | Config.compatibility_check = check_status
3493 |
3494 | @CachedProperty
3495 | def lib(self):
3496 | lib = self.get_cindex_library()
3497 | register_functions(lib, not Config.compatibility_check)
3498 | Config.loaded = True
3499 | return lib
3500 |
3501 | def get_filename(self):
3502 | if Config.library_file:
3503 | return Config.library_file
3504 |
3505 | import platform
3506 | name = platform.system()
3507 |
3508 | if name == 'Darwin':
3509 | file = 'libclang.dylib'
3510 | elif name == 'Windows':
3511 | file = 'libclang.dll'
3512 | else:
3513 | file = 'libclang-3.6.so'
3514 |
3515 | if Config.library_path:
3516 | file = Config.library_path + '/' + file
3517 |
3518 | return file
3519 |
3520 | def get_cindex_library(self):
3521 | try:
3522 | library = cdll.LoadLibrary(self.get_filename())
3523 | except OSError as e:
3524 | msg = str(e) + ". To provide a path to libclang use " \
3525 | "Config.set_library_path() or " \
3526 | "Config.set_library_file()."
3527 | raise LibclangError(msg)
3528 |
3529 | return library
3530 |
3531 | def function_exists(self, name):
3532 | try:
3533 | getattr(self.lib, name)
3534 | except AttributeError:
3535 | return False
3536 |
3537 | return True
3538 |
3539 | def register_enumerations():
3540 | for name, value in clang.enumerations.TokenKinds:
3541 | TokenKind.register(value, name)
3542 |
3543 | conf = Config()
3544 | register_enumerations()
3545 |
3546 | __all__ = [
3547 | 'Config',
3548 | 'CodeCompletionResults',
3549 | 'CompilationDatabase',
3550 | 'CompileCommands',
3551 | 'CompileCommand',
3552 | 'CursorKind',
3553 | 'Cursor',
3554 | 'Diagnostic',
3555 | 'File',
3556 | 'FixIt',
3557 | 'Index',
3558 | 'SourceLocation',
3559 | 'SourceRange',
3560 | 'TokenKind',
3561 | 'Token',
3562 | 'TranslationUnitLoadError',
3563 | 'TranslationUnit',
3564 | 'TypeKind',
3565 | 'Type',
3566 | ]
3567 |
--------------------------------------------------------------------------------
/python/clang/enumerations.py:
--------------------------------------------------------------------------------
1 | #===- enumerations.py - Python Enumerations ------------------*- python -*--===#
2 | #
3 | # The LLVM Compiler Infrastructure
4 | #
5 | # This file is distributed under the University of Illinois Open Source
6 | # License. See LICENSE.TXT for details.
7 | #
8 | #===------------------------------------------------------------------------===#
9 |
10 | """
11 | Clang Enumerations
12 | ==================
13 |
14 | This module provides static definitions of enumerations that exist in libclang.
15 |
16 | Enumerations are typically defined as a list of tuples. The exported values are
17 | typically munged into other types or classes at module load time.
18 |
19 | All enumerations are centrally defined in this file so they are all grouped
20 | together and easier to audit. And, maybe even one day this file will be
21 | automatically generated by scanning the libclang headers!
22 | """
23 |
24 | # Maps to CXTokenKind. Note that libclang maintains a separate set of token
25 | # enumerations from the C++ API.
26 | TokenKinds = [
27 | ('PUNCTUATION', 0),
28 | ('KEYWORD', 1),
29 | ('IDENTIFIER', 2),
30 | ('LITERAL', 3),
31 | ('COMMENT', 4),
32 | ]
33 |
34 | __all__ = ['TokenKinds']
35 |
--------------------------------------------------------------------------------
/python/compilation_database.py:
--------------------------------------------------------------------------------
1 | import os
2 | import json
3 |
4 | USEFUL_OPTS = ['-D', '-I', '-isystem', '-include', '-x']
5 | USEFUL_FLAGS = ['-std']
6 |
7 |
8 | def check_prefix(str, prefix_list):
9 | for prefix in prefix_list:
10 | if str.startswith(prefix):
11 | return True
12 |
13 | return False
14 |
15 |
16 | class CompilationDatabase(object):
17 |
18 | def __init__(self, file_path, jdata, heuristic):
19 | self.__heuristic = heuristic
20 | self.__file_path = file_path
21 | self.__jdata = jdata
22 | self.__cdb_cache = {}
23 |
24 | @staticmethod
25 | def from_dir(dir, heuristic):
26 | file_path = dir + '/compile_commands.json'
27 | try:
28 | json_file = open(file_path)
29 | except:
30 | return None
31 |
32 | jdata = json.load(json_file)
33 | json_file.close()
34 |
35 | if not isinstance(jdata, list):
36 | return None
37 |
38 | cdb = CompilationDatabase(file_path, jdata, heuristic)
39 | return cdb
40 |
41 | def get_useful_args(self, abs_path):
42 | if not self.__cdb_cache:
43 | self.build_cdb_cache()
44 |
45 | if not self.__cdb_cache.get(abs_path):
46 | self.__cdb_cache[abs_path] = {'abs_path': abs_path}
47 |
48 | if self.__cdb_cache[abs_path].get('arg_list'):
49 | return self.__cdb_cache[abs_path]['arg_list']
50 |
51 | command = self.get_commands(abs_path)
52 | if not command:
53 | return []
54 |
55 | args = command.replace('\"', '').replace('\'', '').split()
56 |
57 | useful_opts = []
58 | useful_flags = []
59 |
60 | while (args):
61 | arg = args.pop(0)
62 |
63 | if check_prefix(arg, USEFUL_FLAGS):
64 | useful_flags.append(arg)
65 | continue
66 |
67 | if arg in USEFUL_OPTS:
68 | if args and args[0] and not args[0].startswith('-'):
69 | useful_opts.append(arg)
70 | useful_opts.append(args.pop(0))
71 |
72 | continue
73 |
74 | if check_prefix(arg, USEFUL_OPTS):
75 | useful_opts.append(arg)
76 | continue
77 |
78 | self.__cdb_cache[abs_path]['arg_list'] = useful_flags + useful_opts
79 | return self.__cdb_cache[abs_path]['arg_list']
80 |
81 | def get_commands(self, abs_path):
82 | if not self.__cdb_cache:
83 | self.build_cdb_cache()
84 |
85 | context = self.__cdb_cache.get(abs_path)
86 |
87 | if not context:
88 | return None
89 |
90 | if context.get('command'):
91 | return context['command']
92 |
93 | if not self.__heuristic:
94 | return None
95 |
96 | command = ""
97 | for key, value in self.__cdb_cache.iteritems():
98 | if os.path.splitext(
99 | os.path.basename(abs_path))[0] == os.path.splitext(
100 | os.path.basename(key))[0] and value.get('command'):
101 | if value.get('command'):
102 | command += value['command']
103 |
104 | return command
105 |
106 | def clean_cdb_cache(self):
107 | self.__cdb_cache.clear()
108 |
109 | def build_cdb_cache(self):
110 | for entry in self.__jdata:
111 | if not entry.get('directory') or not entry.get(
112 | 'command') or not entry.get('file'):
113 | continue
114 |
115 | abs_path = os.path.join(
116 | entry['directory'].encode('utf-8'),
117 | entry['file'].encode('utf-8'))
118 |
119 | self.__cdb_cache[abs_path] = {
120 | 'abs_path': abs_path,
121 | 'command': entry['command'].encode('utf-8')}
122 |
123 | @property
124 | def file_path(self):
125 | return self.__file_path
126 |
--------------------------------------------------------------------------------
/python/engine.py:
--------------------------------------------------------------------------------
1 | from neovim import attach
2 | from clang import cindex
3 | import compilation_database
4 | import clamp_helper
5 | import sys
6 | import threading
7 | import functools
8 |
9 |
10 | CUSTOM_SYNTAX_GROUP = {
11 | cindex.CursorKind.INCLUSION_DIRECTIVE: 'clampInclusionDirective',
12 | cindex.CursorKind.MACRO_INSTANTIATION: 'clampMacroInstantiation',
13 | cindex.CursorKind.VAR_DECL: 'clampVarDecl',
14 | cindex.CursorKind.STRUCT_DECL: 'clampStructDecl',
15 | cindex.CursorKind.UNION_DECL: 'clampUnionDecl',
16 | cindex.CursorKind.CLASS_DECL: 'clampClassDecl',
17 | cindex.CursorKind.ENUM_DECL: 'clampEnumDecl',
18 | cindex.CursorKind.PARM_DECL: 'clampParmDecl',
19 | cindex.CursorKind.FUNCTION_DECL: 'clampFunctionDecl',
20 | cindex.CursorKind.FUNCTION_TEMPLATE: 'clampFunctionDecl',
21 | cindex.CursorKind.CXX_METHOD: 'clampFunctionDecl',
22 | cindex.CursorKind.CONSTRUCTOR: 'clampFunctionDecl',
23 | cindex.CursorKind.DESTRUCTOR: 'clampFunctionDecl',
24 | cindex.CursorKind.FIELD_DECL: 'clampFieldDecl',
25 | cindex.CursorKind.ENUM_CONSTANT_DECL: 'clampEnumConstantDecl',
26 | cindex.CursorKind.NAMESPACE: 'clampNamespace',
27 | cindex.CursorKind.CLASS_TEMPLATE: 'clampClassDecl',
28 | cindex.CursorKind.TEMPLATE_TYPE_PARAMETER: 'clampTemplateTypeParameter',
29 | cindex.CursorKind.TEMPLATE_NON_TYPE_PARAMETER: 'clampTemplateNoneTypeParameter',
30 | cindex.CursorKind.TYPE_REF: 'clampTypeRef', # class ref
31 | cindex.CursorKind.NAMESPACE_REF: 'clampNamespaceRef', # namespace ref
32 | cindex.CursorKind.TEMPLATE_REF: 'clampTemplateRef', # template class ref
33 | cindex.CursorKind.DECL_REF_EXPR:
34 | {
35 | cindex.TypeKind.FUNCTIONPROTO: 'clampDeclRefExprCall', # function call
36 | cindex.TypeKind.ENUM: 'clampDeclRefExprEnum', # enum ref
37 | cindex.TypeKind.TYPEDEF: 'clampTypeRef', # ex: cout
38 | },
39 | cindex.CursorKind.MEMBER_REF: 'clampDeclRefExprCall', # ex: designated initializer
40 | cindex.CursorKind.MEMBER_REF_EXPR:
41 | {
42 | cindex.TypeKind.UNEXPOSED: 'clampMemberRefExprCall', # member function call
43 | },
44 | }
45 |
46 |
47 | def _get_default_syn(cursor_kind):
48 | if cursor_kind.is_preprocessing():
49 | return 'clampPrepro'
50 | elif cursor_kind.is_declaration():
51 | return 'clampDecl'
52 | elif cursor_kind.is_reference():
53 | return 'clampRef'
54 | else:
55 | return None
56 |
57 |
58 | def _get_syntax_group(cursor, blacklist):
59 | group = _get_default_syn(cursor.kind)
60 |
61 | custom = CUSTOM_SYNTAX_GROUP.get(cursor.kind)
62 | if custom:
63 | if cursor.kind == cindex.CursorKind.DECL_REF_EXPR:
64 | custom = custom.get(cursor.type.kind)
65 | if custom:
66 | group = custom
67 | elif cursor.kind == cursor.kind == cindex.CursorKind.MEMBER_REF_EXPR:
68 | custom = custom.get(cursor.type.kind)
69 | if custom:
70 | group = custom
71 | else:
72 | group = 'clampMemberRefExprVar'
73 | else:
74 | group = custom
75 |
76 | if group in blacklist:
77 | return None
78 |
79 | return group
80 |
81 | parse_set = set()
82 | condition = threading.Condition()
83 |
84 | def ParseWorker():
85 | while True:
86 | with condition:
87 | print("try parse")
88 | while not parse_set:
89 | condition.wait()
90 |
91 | for parse_item in parse_set:
92 | parse_item();
93 |
94 | parse_set.clear()
95 |
96 |
97 | def engine_start():
98 | _is_running = True
99 |
100 | context = {} # {'bufname' : [tu, tick]}
101 |
102 | parse_thread = threading.Thread(target=ParseWorker)
103 | parse_thread.daemon = True
104 | parse_thread.start()
105 |
106 | nvim = attach('stdio')
107 |
108 | # nvim = attach('socket', path=sys.argv[1])
109 | # nvim.command('let g:clamp_channel=%d' % nvim.channel_id)
110 |
111 | sys.stderr.write('channel=%d\n' % nvim.channel_id)
112 |
113 | cindex.Config.set_library_file(nvim.vars['clamp_libclang_path'])
114 | sys.stderr.write('libclang=%s\n' % cindex.Config.library_file)
115 |
116 | occurrences_pri = nvim.vars['clamp_occurrence_priority']
117 | syntax_pri = nvim.vars['clamp_syntax_priority']
118 |
119 | _parse.idx = cindex.Index.create()
120 | _parse.cdb = compilation_database.CompilationDatabase.from_dir(
121 | nvim.call('getcwd'), nvim.vars['clamp_heuristic_compile_args'])
122 | _parse.global_args = nvim.vars['clamp_compile_args']
123 |
124 | _highlight.blacklist = nvim.vars['clamp_highlight_blacklist']
125 |
126 | unsaved = []
127 | while (_is_running):
128 | event = nvim.next_message()
129 | if not event:
130 | continue
131 |
132 | sys.stderr.write('event %s\n' % event[1])
133 | if event[1] == 'highlight':
134 | bufname = event[2][0]
135 | begin_line = event[2][1]
136 | end_line = event[2][2]
137 | row = event[2][3]
138 | col = event[2][4]
139 |
140 | if bufname not in context:
141 | event[3].send(0)
142 | continue
143 |
144 | tu, tick = context[bufname]
145 |
146 | symbol = clamp_helper.get_semantic_symbol_from_location(
147 | tu, bufname, row, col)
148 | syntax, occurrence = _highlight(
149 | tu, bufname, begin_line, end_line, symbol)
150 |
151 | nvim.call('ClampHighlight', bufname, [
152 | [syntax_pri, syntax], [occurrences_pri, occurrence]])
153 |
154 | event[3].send(1)
155 |
156 |
157 | elif event[1] == 'parse':
158 | bufname = event[2][0]
159 | changedtick = event[2][1]
160 | content = event[2][2]
161 |
162 | _update_unsaved(bufname, unsaved, changedtick, content)
163 | #thread.start_new_thread(_parse_or_reparse_if_need, (bufname, unsaved, context, changedtick))
164 |
165 | with condition:
166 | func = functools.partial(_parse_or_reparse_if_need, bufname, unsaved, context, changedtick)
167 | parse_set.add(func)
168 | condition.notify()
169 |
170 | event[3].send(0)
171 |
172 | elif event[1] == 'rename':
173 | bufname = event[2][0]
174 | row = event[2][1]
175 | col = event[2][2]
176 |
177 | _update_unsaved_and_parse_all(nvim, unsaved, context)
178 |
179 | symbol = clamp_helper.get_semantic_symbol_from_location(
180 | context[bufname][0], bufname, row, col)
181 | if not symbol:
182 | print 'fffff'
183 | event[3].send({})
184 | continue
185 |
186 | result = {'old': symbol.spelling, 'renames': {}}
187 | usr = symbol.get_usr()
188 |
189 | if usr:
190 | for bufname, [tu, tick] in context.iteritems():
191 | locations = []
192 | clamp_helper.search_referenced_tokens_by_usr(
193 | tu, usr, locations, symbol.spelling)
194 |
195 | if locations:
196 | result['renames'][bufname] = locations
197 |
198 | event[3].send(result)
199 | elif event[1] == 'cursor_info':
200 | bufname = event[2][0]
201 | row = event[2][1]
202 | col = event[2][2]
203 |
204 | tu = context[bufname][0]
205 | cursor = clamp_helper.get_cursor(tu, bufname, row, col)
206 |
207 | if not cursor:
208 | event[3].send('None')
209 |
210 | result = {'cursor':str(cursor), 'cursor.kind': str(cursor.kind), 'cursor.type.kind': str(cursor.type.kind), 'cursor.spelling' : cursor.spelling}
211 | event[3].send(result)
212 |
213 | elif event[1] == 'update_unsaved_all':
214 | _update_unsaved_all(nvim, unsaved)
215 | event[3].send('ok')
216 |
217 | elif event[1] == 'shutdown':
218 | nvim.session.stop()
219 | _is_running = False
220 | event[3].send('ok')
221 |
222 | # elif event[1] == 'parse':
223 | # bufnr = event[2][0]
224 |
225 | # changedtick = nvim.eval('b:changedtick')
226 | # buffer = nvim.buffers[bufnr - 1]
227 | # _update_unsaved(buffer, unsaved)
228 | # _parse_or_reparse_if_need(
229 | # buffer.name,
230 | # unsaved,
231 | # context,
232 | # changedtick)
233 |
234 | # elif event[1] == 'highlight':
235 | # bufnr = event[2][0]
236 | # begin_line = event[2][1]
237 | # end_line = event[2][2]
238 | # row = event[2][3]
239 | # col = event[2][4]
240 |
241 | # buffer = nvim.buffers[bufnr - 1]
242 | # tu, tick = context[buffer.name]
243 |
244 | # symbol = clamp_helper.get_semantic_symbol_from_location(
245 | # tu, buffer.name, row, col)
246 |
247 | # syntax, occurrence = _highlight(
248 | # tu, buffer.name, begin_line, end_line, symbol)
249 |
250 | # nvim.call('ClampHighlight', buffer.name, [
251 | # (syntax_pri, syntax), (occurrences_pri, occurrence)])
252 |
253 |
254 | def _update_unsaved_all(nvim, unsaved):
255 | del unsaved[:]
256 |
257 | for buffer in nvim.buffers:
258 | if not buffer.name.split(".")[-1] in ['c', 'cpp', 'h', 'hpp']:
259 | continue
260 |
261 | unsaved.append((buffer.name, '\n'.join(buffer)))
262 |
263 |
264 | def _parse(unsaved, bufname):
265 | args = None
266 | if _parse.cdb:
267 | args = _parse.cdb.get_useful_args(bufname) + _parse.global_args
268 |
269 | return _parse.idx.parse(
270 | bufname,
271 | args,
272 | unsaved,
273 | options=cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD)
274 |
275 |
276 | def _update_unsaved(bufname, unsaved, changedtick, content):
277 | for item in unsaved:
278 | if item[0] == bufname:
279 | unsaved.remove(item)
280 |
281 | unsaved.append((bufname, content))
282 |
283 |
284 | def _update_unsaved_and_parse_all(nvim, unsaved, context):
285 | _update_unsaved_all(nvim, unsaved)
286 |
287 | for buffer in nvim.buffers:
288 | if not buffer.name.split(".")[-1] in ['c', 'cpp', 'h', 'hpp']:
289 | continue
290 |
291 | _parse_or_reparse_if_need(
292 | buffer.name,
293 | unsaved,
294 | context,
295 | nvim.call('getbufvar',
296 | buffer.name,
297 | 'changedtick'))
298 |
299 |
300 | def _parse_or_reparse_if_need(bufname, unsaved, context, changedtick):
301 | context[bufname] = [_parse(unsaved, bufname), changedtick]
302 | return True
303 | # if bufname not in context
304 |
305 | # if bufname not in context:
306 | # context[bufname] = [_parse(unsaved, bufname), changedtick]
307 | # return True
308 | # elif context[bufname][1] != changedtick:
309 | # context[bufname][0].reparse(
310 | # unsaved,
311 | # options=cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD)
312 | # context[bufname][1] = changedtick
313 | # return True
314 | # else:
315 | # return False
316 |
317 |
318 | def _highlight(tu, bufname, begin_line, end_line, symbol):
319 | file = tu.get_file(bufname)
320 |
321 | if not file:
322 | return None, None
323 |
324 | begin = cindex.SourceLocation.from_position(
325 | tu, file, line=begin_line, column=1)
326 | end = cindex.SourceLocation.from_position(
327 | tu, file, line=end_line + 1, column=1)
328 | tokens = tu.get_tokens(
329 | extent=cindex.SourceRange.from_locations(begin, end))
330 |
331 | syntax = {}
332 | occurrence = {'clampOccurrences': []}
333 |
334 | for token in tokens:
335 | if token.kind.value != 2: # no keyword, comment
336 | continue
337 |
338 | cursor = token.cursor
339 | cursor._tu = tu
340 |
341 | pos = [token.location.line, token.location.column, len(token.spelling)]
342 | group = _get_syntax_group(
343 | cursor,
344 | _highlight.blacklist)
345 |
346 | if group:
347 | if group not in syntax:
348 | syntax[group] = []
349 |
350 | syntax[group].append(pos)
351 |
352 | t_symbol = None
353 | t_symbol = clamp_helper.get_semantic_symbol(cursor)
354 |
355 | if symbol and t_symbol and symbol == t_symbol and t_symbol.spelling == token.spelling:
356 | occurrence['clampOccurrences'].append(pos)
357 |
358 | return syntax, occurrence
359 |
360 |
361 | def main(argv=None):
362 | engine_start()
363 |
364 | if __name__ == "__main__":
365 | main()
366 |
--------------------------------------------------------------------------------
/syntax/clamp.vim:
--------------------------------------------------------------------------------
1 | hi default link clampPrepro PreProc
2 | hi default link clampDecl Identifier
3 | hi default link clampRef Type
4 |
5 | hi default link clampInclusionDirective cIncluded
6 | hi default link clampMacroInstantiation Constant
7 | hi default link clampVarDecl Identifier
8 | hi default link clampStructDecl Identifier
9 | hi default link clampUnionDecl Identifier
10 | hi default link clampClassDecl Identifier
11 | hi default link clampEnumDecl Identifier
12 | hi default link clampParmDecl Identifier
13 | hi default link clampFunctionDecl Identifier
14 | hi default link clampFieldDecl Identifier
15 | hi default link clampEnumConstantDecl Constant
16 | hi default link clampDeclRefExprEnum Constant
17 | hi default link clampDeclRefExprCall Type
18 | hi default link clampMemberRefExprCall Type
19 | hi default link clampMemberRefExprVar Type
20 | hi default link clampTypeRef Type
21 | hi default link clampNamespace Identifier
22 | hi default link clampNamespaceRef Type
23 | hi default link clampTemplateTypeParameter Identifier
24 | hi default link clampTemplateNoneTypeParameter Identifier
25 | hi default link clampTemplateRef Type
26 |
27 | hi default link clampOccurrences IncSearch
28 |
--------------------------------------------------------------------------------