├── 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 | --------------------------------------------------------------------------------