# HG changeset patch # User Steve Losh # Date 1320939121 18000 # Node ID b503af8e2bbeca163e9943089f00259ed7bcfb02 # Parent 27ec8da23760ddb09f2c6fd3b3913b71c77b5f49 Remove rope files from this repo in preparation for making them subreos. diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/.hgignore --- a/vim/sadness/ropevim/src/rope/.hgignore Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -syntax: glob - -*.pyc -rope.egg-info diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/.hgtags --- a/vim/sadness/ropevim/src/rope/.hgtags Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -2b74d75e4f0a15e9a728e9642fd1a5dc50343544 0.7 -21d026b272052bf6e5798294409a6fc58dfe95fe 0.7.1 -dea8b62c2141d7459e67086efacb20cf422b5977 0.7.2 -edabbceda687af4ad93687e8d08c1e2d45a6181d 0.7.3 -c229ca17b51c169c11207ded55c05bae96b12a3e 0.7.4 -d05b87226c5410cd5427deaaa38f3e6d93bce272 0.7.5 -72c14e80687543b55aa38fc00538888212f6f11a 0.7.6 -ffcd014a92164f5df2206949fecce09ccb9bde9e 0.7.7 -ef7c349beeed1d763e545bce89754cb0154b837c 0.7.8 -b5ee6eb7f245e9713a5a1e45892ce9e5021680f8 0.7.9 -19960b1c3511de606ede66125edb487d299b4eac 0.8 -4b4db07361c5f09f5f3efd419bdb9cdfdac17b97 0.8.1 -31646f5ab763f85df9b01ba025f1475ca4db324a 0.8.2 -b77bd0f68d3eca884ea5001ec4f95c247eab40d2 0.8.3 -02b9af86ce327745783a21c140a609bc860a31bb 0.8.4 -5938069e8ca2ea309c0b23784806b2dc1d9b90cf 0.9 -62727f11b9666ccef926b5e4e6b849fff36e30e0 0.9.1 -a4a74d4469eb3f7f027bdd0cae64cf8143f52d94 0.9.2 -f8e015405cf4dfd0e4c8486f5e88505060bc458c 0.9.3 diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/CONTRIBUTORS --- a/vim/sadness/ropevim/src/rope/CONTRIBUTORS Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -=================== - Rope Contributors -=================== - -See Mercurial logs and the mailing list for details. - -* Alexander Solovyov -* Sebastjan Trepca -* MATSUI Tetsushi -* Kevin Turner -* Darren Syzling -* Orestis Markou -* Ronny Pfannschmidt -* Anton Gritsay diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/COPYING --- a/vim/sadness/ropevim/src/rope/COPYING Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/MANIFEST.in --- a/vim/sadness/ropevim/src/rope/MANIFEST.in Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -include README.txt COPYING setup.py MANIFEST.in -recursive-include rope *.py -recursive-include docs *.txt -recursive-include ropetest *.py diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/README.txt --- a/vim/sadness/ropevim/src/rope/README.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -======================================== - rope, a python refactoring library ... -======================================== - - -Overview -======== - -`Rope`_ is a python refactoring library. - -.. _`rope`: http://rope.sf.net/ - - -New Features -============ - -* codeassist: better handling of unicode in docstrings -* codeassist: handling builtin unknowns, such as sys.stdout -* codeassist: proposals scopes and types revised -* fscommands: handle hg crew ui changes -* patchedast: handle ExtSlice node - -Getting Started -=============== - -* List of features: `docs/rope.txt`_ -* Overview of some of rope's features: `docs/overview.txt`_ -* Using as a library: `docs/library.txt`_ -* Contributing: `docs/contributing.txt`_ - -To change your project preferences edit -``$PROJECT_ROOT/.ropeproject/config.py`` where ``$PROJECT_ROOT`` is -the root folder of your project (this file is created the first time -you open a project). - - -Bug Reports -=========== - -Send your bug reports and feature requests to `rope-dev (at) -googlegroups.com`_. - -.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev - - -License -======= - -This program is under the terms of GPL (GNU General Public License). -Have a look at ``COPYING`` file for more information. - - -.. _`docs/rope.txt`: docs/rope.html -.. _`docs/overview.txt`: docs/overview.html -.. _`docs/contributing.txt`: docs/contributing.html -.. _`docs/library.txt`: docs/library.html diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/docs/contributing.txt --- a/vim/sadness/ropevim/src/rope/docs/contributing.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -====================== - Contributing to Rope -====================== - - -Get Involved! -============= - -Rope's main goal is being a good refactoring tool for python. It also -provides some IDE helpers. If you like to contribute, you're welcome! - - -How to Help Rope? -================= - -Rope mailing list is `rope-dev (at) googlegroups.com`_. You can send -a mail to ``rope-dev-subscribe (at) googlegroups [dot] com`` to -subscribe. - -* Use rope -* Send bug reports and request features -* Submit patches for bugs or new features -* Discuss your ideas - -.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev - - -Wish List -========= - -You are welcome to send your patches to `rope-dev (at) -googlegroups.com`_ mailing list. Here is only a list of suggestions. - -Issues ------- - -The `dev/issues.txt`_ file is actually the main rope todo file. There -is a section called "unresolved issues"; it contains almost every kind -of task. Most of them need some thought or discussion. Pickup -whichever you are most interested in. If you have ideas or questions -about them, don't hesitate to discuss it in the mailing list. - -.. _`dev/issues.txt`: dev/issues.html - -Getting Ready For Python 3.0 ----------------------------- - -Checkout http://bitbucket.org/agr/rope_py3k Mercurial_ repository. -Contributions are welcome. - -Write Plugins For Other IDEs ----------------------------- - -See ropemacs_, ropevim_, eric4_ and ropeide_. - - -.. _ropemacs: http://rope.sf.net/ropemacs.html -.. _ropevim: http://rope.sf.net/ropevim.html -.. _ropeide: http://rope.sf.net/ropeide.html -.. _eric4: http://www.die-offenbachs.de/eric/index.html - - -Rope Structure -============== - -Rope package structure: - -* `rope.base`: the base part of rope -* `rope.refactor`: refactorings and tools used in them -* `rope.contrib`: IDE helpers - -Have a look at ``__init__.py`` of these packages or `library.txt`_ for -more information. - -.. _`library.txt`: library.html - - -Source Repository -================= - -Rope uses Mercurial_ CMS: - -* Rope main branch: http://bitbucket.org/agr/rope -* Rope py3k branch: http://bitbucket.org/agr/rope_py3k - -.. _Mercurial: http://selenic.com/mercurial - - -Submitting patches -================== - -Patches are welcome. - -Patch style ------------ - -* Follow :PEP:`8`. -* Use four spaces for indentation. -* Include good unit-tests if possible. -* Rope test suite should pass after patching -* Use ``hg export`` format to preserve your identity diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/docs/dev/issues.txt --- a/vim/sadness/ropevim/src/rope/docs/dev/issues.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -============= - Rope Issues -============= - - -Unresolved Issues -================= - -* purging out less accurate callinfos when better ones appear? -* using properties without calling its get? -* global variable inlines -* transform and extension modules -* merging extract and usefunction -* caching instances of PyObject -* moving a group of elements together -* temps might be read after body in usefunction or extract -* usefunction and function returns -* usefunction on methods -* extracted functions should be inserted before using class bodies -* adding "referenced later" wildcard argument to restructurings? -* adding "change references" wildcard argument to restructurings? -* ideas for more custom wildcards -* adapting future python 2.6 ast changes -* custom wildcards and recursive patterns -* custom restructuring wildcard patterns and replacements -* not reimporting back imports after moving -* importing compressed objectdb/history data? -* not applying all commenting mechanisms always in codeassist -* fixing try blocks before current line in code_assist -* better tests for patchedast -* import actions with more that one phase and filtering problems -* handle long imports should work on filtered imports unconditionally? -* extracting subexpressions; look at `extracttest` for more info -* switching to gplv3? -* unignored files that are not under version control -* inline fails when there is an arg mismatch -* evaluate function parameter defaults in staticoi? -* saving diffs instead of old contents in ChangeContents? -* handling tuple parameters -* extract class -* analyzing function decorators -* generate ... and implicit interfaces -* generate method and class hierarchies -* lambdas as functions; consider their parameters -* renaming similarly named variables -* handling the return type of ``yield`` keyword -* not writing unchanged objectdb and history? - - -To Be Reviewed -============== - -* review patchedast; make it faster -* lots of estimations in codeanalyze in WordRangeFinder -* review objectdb modules -* how concluded data are held for star imports - - -Insert Before In Restructurings -=============================== - -Consider a restructuring like this:: - - pattern: ${a} if ${b} else ${c} - goal: replacement - before: if ${b}:\n replacement = ${a}\nelse:\n replacement = ${c} - - -Memory Management -================= - -These are the places in which rope spends most of the memory it -consumes: - -* PyCore: for storing PyModules -* ObjectInfo: for storing object information -* History: for storing changes - -We should measure the amount of memory each of them use to make -decisions. - - -Custom Restructuring Wildcards -============================== - -There is a need to add more custom wildcards in restructuring -patterns. But adding all such needs to `similarfinder` module makes -it really complex. So I think adding the ability to extend them is -useful. - -Sometimes wildcards can be customized. For instance one might want to -match the function calls only if ``p1`` is passed in the arguments. -They can be specified in wildcard arguments. - -Since matched wildcards can appear in the goal pattern, each wildcard -should have a corresponding replacement wildcard. Each replacement -might be customized in each place it appears; for instance -``${mycall:-p1}`` might mean to remove ``p1`` argument. - - -Wildcard Format ---------------- - -All wildcards should appear as ``${name}``. The type of wildcards and -their parameters can be specified using the ``args`` argument of -``Restructuring()``. - -Ideas: - -* Maybe we can put checks inside args, too:: - - pattern: ${project:type=rope.base.project.Project}.pycore - - But what should be done when a variable appears twice:: - - pattern: ${a:type=__builtin__.int} + ${a} - - -Examples --------- - -.. ... - - -Possible Module Renamings -========================= - -*First level*: - -These module names are somehow inconsistent. - -* change -> changes -* method_object -> methodobject -* default_config -> defaultconfig - -*Second level* - -Many modules use long names. They can be shortened without loss of -readability. - -* methodobject -> methobj or funcobj -* usefunction -> usefunc -* multiproject -> mulprj -* functionutils -> funcutils -* importutils -> imputils -* introduce_factory -> factory -* change_signature -> signature -* encapsulate_field -> encapsulate -* sourceutils -> srcutils -* resourceobserver -> observer - - -Getting Ready For Python 3.0 -============================ - -This has been moved to a separate branch. diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/docs/dev/todo.txt --- a/vim/sadness/ropevim/src/rope/docs/dev/todo.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -====== - TODO -====== - -See the `unresolved issues` section of ``issues.txt`` file for more. - - -> Public Release 1.0 diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/docs/done.txt --- a/vim/sadness/ropevim/src/rope/docs/done.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1105 +0,0 @@ -=========== - Done List -=========== - - -> Public Release 0.9.3 : February 4, 2010 - - -- codeassist: proposals scopes and types revised : January 26, 2010 - - -- codeassist: handling "builtin unknowns" : January 06, 2010 - - -- refactor: fixed arguments in extracted method : December 26, 2009 - - -- pycore: fixed project's property `source_folders` : October 26, 2009 - - -- codeassist: better handling of unicode docstrings : August 20, 2009 - - -- setup.py: don't include docs as package data : July 18, 2009 - - -- fscommands: handle hg crew ui changes : May 04, 2009 - - -- patchedast: handle ExtSlice node : April 29, 2009 - - -> Public Release 0.9.2 : February 19, 2009 - - -- caching all sub-modules in `autoimport` : February 18 : 2009 - - -- extract method handles conditional variable updates : February 10, 2009 - - -- added basic support for setuptools : January 15, 2009 - - -- added `CompletionProposal.parameters` : November 4, 2008 - - -- fix recursion when creating modules : October 31, 2008 - - -> Public Release 0.9.1 : October 29, 2008 - - -- added import_dynload_stdmods project variable : October 28, 2008 - - -- finding dynload standard modules on windows : October 15, 2008 - - -> Public Release 0.9 : October 3, 2008 - - -- supporting Darcs VCS : August 20, 2008 - - -- handling files with mac line-ending : July 25, 2008 - - -- not searching all files when inlining a local variable : July 24, 2008 - - -> Public Release 0.8.4 : June 24, 2008 - - -- handling only_current for inline in other modules : July 21, 2008 - - -- inlining variable in other modules : July 19, 2008 - - -- added `rope.contrib.finderrors` : July 17, 2008 - - -- added `rope.contrib.fixmodnames` : July 16, 2008 - - -- added `rope.contrib.changestack` : July 15, 2008 - - -- better extension module handling : June 29, 2008 - - -- added `findit.Location.region` field : June 26, 2008 - - -- added `rope.contrib.findit.find_definition()` : June 26, 2008 - - -- added ``remove_self`` argument to `get_calltip()` : June 20, 2008 - - -> Public Release 0.8.3 : June 20, 2008 - - -- handling builtin modules in autoimport : June 12, 2008 - - -- creating parent folders of ``.ropeproject`` if don't exist : June 6, 2008 - - -- fixed inlining functions with line-breaks in arguments : May 22, 2008 - - -- added lineno to `rope.contrib.findit.Location` : May 19, 2008 - - -- deprecated some of `ChangeSignature` methods : May 19, 2008 - - -- added `ChangeSignature.get_args()` : May 19, 2008 - - -> Public Release 0.8.2 : May 10, 2008 - - -- inlining parameters : May 10, 2008 - - -- automatic default insertion in change signature : May 10, 2008 - - -- adding underlined parameter to `AutoImport` : May 7, 2008 - - -- added `rope.contrib.findit.find_implementations()` : April 28, 2008 - - -- moved `find_occurrences()` to `rope.contrib.findit` : April 25, 2008 - - -> Public Release 0.8.1 : April 20, 2008 - - -- added GIT support in fscommands : April 19, 2008 - - -- back importing underlined names in move : April 19, 2008 - - -- added `codeassist.get_calltip()` : April 12, 2008 - - -- added `libutils.analyze_modules()` : April 12, 2008 - - -- added ``soa_followed_calls`` project config : April 11, 2008 - - -- `libutils.report_change()` reads `automatic_soa` : April 10, 2008 - - -- SOA can follow functions : April 10, 2008 - - -- better handling of for, with and except variables : April 7, 2008 - - -- not reparsing unchanged modules for code assists : April 6, 2008 - - -- handling property as decorator : April 5, 2008 - - -> Public Release 0.8 : April 5, 2008 - - -- ignore_bad_imports project config : March 28, 2008 - - -- added AutoImport.get_name_locations() : March 17, 2008 - - -> Public Release 0.7.9 : March 14, 2008 - - -- Deprecated codeassist templates : March 14, 2008 - - -- Added in_hierarchy option to find occurrences : March 10, 2008 - - -- Faster class hierarchy analysis for refactorings : March 10, 2008 - - -- Added maxfixes to get doc and get definition location : March 6, 2008 - - -- Added extension_modules project config : March 6, 2008 - - -- Supporting builtin and c-extension modules : March 6, 2008 - - -> Public Release 0.7.8 : March 1, 2008 - - -- Extracting functions with only one return statement : February 29, 2008 - - -- Reporting errors for exceptional conditions in usefunction : February 29, 2008 - - -- More intelligent import handling for factory and move : February 25, 2008 - - -- Handling future imports in organize imports : February 20, 2008 - - -- Codeanalyze ignores comments when finding primaries : February 17, 2008 - - -- Organize import and dynload builtin modules on unix : February 16, 2008 - - -- Moved ImportOrganizer to rope.refactor.importutils : February 14, 2008 - - -- Moved ModuleToPackage to rope.refactor.topackage : February 14, 2008 - - -> Public Release 0.7.7 : February 13, 2008 - - -- Added python_files project config : February 10, 2008 - - -- Added codeassist.starting_expression() : February 10, 2008 - - -- Added AutoImport.clear_cache() : February 7, 2008 - - -- Improved extract function : February 1, 2008 - - -- Handling except variables : January 29, 2008 - - -> Public Release 0.7.6 : January 28, 2008 - - -- Handling unsure matches in restructurings : January 27, 2008 - - -- Added rope.contrib.autoimport : January 26, 2008 - - -- Added use function refactoring : January 25, 2008 - - -- Completing names after from-imports : January 23, 2008 - - -- Adding resources parameter to some refactorings : January 22, 2008 - - -- Deprecated in_file argument of `Rename.get_changes()` : January 22, 2008 - - -> Public Release 0.7.5 : January 17, 2008 - - -- Checking isinstance in restructurings : January 11, 2008 - - -- Better handling of one-liners : January 10, 2008 - - -- Choosing which files to apply a restructuring on : January 9, 2008 - - -- Allowing customizable restructuring wildcards : January 7, 2008 - - -> Public Release 0.7.4 : January 3, 2008 - - -- Deprecated objectdb_type project config : December 23, 2007 - - -- Added save_objectdb config : December 23, 2007 - - -- Added compress_history and compress_objectdb configs : December 22, 2007 - - -> Public Release 0.7.3 : December 19, 2007 - - -- Inlining a single occurrence : December 13, 2007 - - -- Global extract method/variable : December 13, 2007 - - -> Public Release 0.7.2 : December 13, 2007 - - -- Specifying the number of fixes in code_assist : December 10, 2007 - - -- Deprecated `Pycore.create_(module|package)` : November 29, 2007 - - -- Performing refactorings across multiple projects : November 29, 2007 - - -> Public Release 0.7.1 : November 28, 2007 - - -- Better handling of symlinks in project path : November 27, 2007 - - -- Asking the user about unsure occurrences : November 10, 2007 - - -> Public Release 0.7 : November 1, 2007 - - -- ropemacs: moving elements, methods and modules : October 30, 2007 - - -- ropemacs: undoing refactorings : October 29, 2007 - - -- ropemacs: inline refactoring : October 29, 2007 - - -- ropemacs: extract method and local variable : October 29, 2007 - - -- ropemacs: goto definition : October 29, 2007 - - -- ropemacs: rename refactoring : October 29, 2007 - - -- A new open project dialog : October 10, 2007 - - -- Added `Core.add_extension()` : September 19, 2007 - - -> Public Release 0.6.2 : September 9, 2007 - - -- Setting statusbar, menu and bufferlist fonts in ``~/.rope`` : September 8, 2007 - - -- Better kill line : September 8, 2007 - - -- Using ``/``\s to match parent folders in find file : September 5, 2007 - - -- Fixed matching method implicit argument when extracting : September 5, 2007 - - -- An option for not removing the definition after inlining : September 1, 2007 - - -- Performing import actions on individual imports : September 1, 2007 - - -- ``C-u`` action prefix : September 1, 2007 - - -- Changing inline and move to use froms for back imports : August 27, 2007 - - -> Public Release 0.6.1 : August 19, 2007 - - -- Cleaning up `rope.ide.codeassist` : August 19, 2007 - - -- Showing unsure occurrences in show occurrences : August 17, 2007 - - -- Sorting scopes : August 9, 2007 - - -> Public Release 0.6 : August 5, 2007 - - -- Finding the scope in an overwritten scope : August 4, 2007 - - -- Added ``ignore_syntax_errors`` project config : August 2, 2007 - - -> Public Release 0.6m6 : July 29, 2007 - - -- Better diff highlighting : July 20, 2007 - - -- Handling imports when inlining : July 20, 2007 - - -- Handling recursive restructurings : July 18, 2007 - - -> Public Release 0.6m5 : July 15, 2007 - - -- Next/prev scope; ``M-C-e/M-C-a`` : July 9, 2007 - - -- Next/prev statement; ``M-e/M-a`` : July 8, 2007 - - -- Importing modules in restructurings : July 7, 2007 - - -- Auto-indentation in restructurings : July 6, 2007 - - -> Public Release 0.6m4 : July 1, 2007 - - -- Adding tools for making using rope library easier : June 23, 2007 - - -- Separating rope library from rope IDE : June 20, 2007 - - -- Restructuring checks for builtin objects using `__builtin__` : June 20, 2007 - - -> Public Release 0.6m3 : June 17, 2007 - - -- Self assignment warning : June 17, 2007 - - -- Adding support for Mercurial VCS : June 17, 2007 - - -- Inferring the object, list comprehensions hold : June 6, 2007 - - -> Public Release 0.6m2 : June 3, 2007 - - -- Enhancing extract method on staticmethods/classmethods : June 2, 2007 - - -- Extracting similar expressions/statements : May 30, 2007 - - -- Adding checks in restructuring dialog : May 23, 2007 - - -- Using `_ast` instead of `compiler` : May 23, 2007 - - -> Public Release 0.6m1 : May 20, 2007 - - -- Adding custom source folders in ``config.py`` : May 15, 2007 - - -- A simple UI for performing restructurings : May 15, 2007 - - -- Restructurings : May 14, 2007 - - -- Finding similar code : May 13, 2007 - - -- Patching ASTs to include formatting information : May 9, 2007 - - -> Public Release 0.5 : May 6, 2007 - - -- Better dialogs : May 2, 2007 - - -> Public Release 0.5rc1 : April 29, 2007 - - -- Showing current file history; ``C-x p 1 h`` : April 28, 2007 - - -- Open Type; ``C-x C-t`` : April 23, 2007 - - -- Adding persisted_memory objectdb : April 20, 2007 - - -- Adding sqlite objectdb : April 20, 2007 - - -> Public Release 0.5m5 : April 15, 2007 - - -- Encapsulating field in the defining class : April 13, 2007 - - -- Renaming occurrences in strings and comments : April 13, 2007 - - -- Stoppable refactorings : April 11, 2007 - - -- Faster automatic SOI analysis : April 9, 2007 - - -- Basic implicit interfaces : April 9, 2007 - - -- Automatic SOI analysis : April 6, 2007 - - -- Using a better object textual form : April 4, 2007 - - -- Spell-Checker : April 3, 2007 - - -> Public Release 0.5m4 : April 1, 2007 - - -- Incremental ObjectDB validation : March 31, 2007 - - -- Saving history across sessions : March 29, 2007 - - -- Saving object data to disk : March 28, 2007 - - -- Adding `.ropeproject` folder : Mark 26, 2007 - - -- Inlining `staticmethod`\s : March 23, 2007 - - -- Saving locations and texts : March 23, 2007 - - -- Generating python elements : March 21, 2007 - - -> Public Release 0.5m3 : March 18, 2007 - - -- Holding per name information for builtin containers : March 17, 2007 - - -- Filling paragraphs in text modes; ``M-q`` : March 15, 2007 - - -- Yanking; ``M-y`` : March 13, 2007 - - -- Repeating last command; ``C-x z`` : March 13, 2007 - - -- Adding 'rename when unsure' option : March 13, 2007 - - -- Change signature for constructors : March 11, 2007 - - -- Supporting generator functions : March 9, 2007 - - -- Enhancing show pydoc to include docs from superclasses : March 8, 2007 - - -- Enhanced returned object static object inference : March 8, 2007 - - -- Enhanced static object inference : March 8, 2007 - - -- Handling ``*args`` and ``**kwds`` arguments : March 7, 2007 - - -- Showing pydoc for some of builtin types and functions : March 7, 2007 - - -> Public Release 0.5m2 : March 4, 2007 - - -- Showing codetag/error/warning list : March 3, 2007 - - -- Registering templates in ``~/.rope`` : February 26, 2007 - - -- Auto-completing function keyword arguments when calling : February 26, 2007 - - -- Better status bar : February 23, 2007 - - -- Change occurrences : February 23, 2007 - - -- Moving methods : February 21, 2007 - - -> Public Release 0.5m1 : February 18, 2007 - - -- Handling ``with`` statements : February 15, 2007 - - -- Performing change signature in class hierarchies : February 14, 2007 - - -- Supporting builtin `zip` and `enumerate` : February 14, 2007 - - -- Replace method with method object : February 12, 2007 - - -- Enhancing searching : February 10, 2007 - - -- Execute command; ``M-x`` : February 10, 2007 - - -- Changing editor font and keybinding in ``~/.rope`` : February 9, 2007 - - -- Having two keybindings emacs/normal : February 9, 2007 - - -- Handling multi-key keyboard shortcuts : February 8, 2007 - - -- Fixing removing imports that eat the blank lines : February 8, 2007 - - -- Removing extra spaces and lines; ``C-c C-f`` : February 7, 2007 - - -> Public Release 0.4 : February 4, 2007 - - -- Reporting some of the refactoring problems in the UI : February 1, 2007 - - -> Public Release 0.4rc1 : January 28, 2007 - - -- Project History; Undoing refactorings in any order : January 25, 2007 - - -- Handling ``global`` keywords : January 22, 2007 - - -- Undoing everything; Project history : January 21, 2007 - - -- Removing `PythonRefactoring` facade : January 19, 2007 - - -- Basic lambdas handling : January 16, 2007 - - -- Handling builtin `property` : January 14, 2007 - - -> Public Release 0.4m5 : January 14, 2007 - - -- Handling long imports : January 11, 2007 - - -- Builtin functions : super, sorted, reversed, range : January 7, 2007 - - -- Support for file/open builtin type : January 7, 2007 - - -- Sorting imports; standard, third party, project : January 7, 2007 - - -- Enhanced dynamic object inference : January 5, 2007 - - -> Public Release 0.4m4 : December 31, 2006 - - -- Basic support for builtin types : December 29, 2006 - - -- Find occurrences; ``C-G`` : December 26, 2006 - - -- Ignoring ``*.pyc``, ``*~`` and ``.svn`` : December 26, 2006 - - -- Moving/renaming current module/package : December 25, 2006 - - -- Removing imports from the same module : December 22, 2006 - - -- Goto last edit location; ``C-q`` : December 20, 2006 - - -- Trying ``utf-8`` if defaults don't work : December 19, 2006 - - -- Comment line and region; ``C-c c``, ``C-c C-c`` : December 18, 2006 - - -> Public Release 0.4m3 : December 17, 2006 - - -- Introduce parameter : December 14, 2006 - - -- 8 spaces per tabs in `rope.base` and `rope.refactor` : December 8, 2006 - - -- Better support for other version control systems : December 8, 2006 - - -- Updating files that have been changed : December 8, 2006 - - -- Fixing module running on Windows : December 6, 2006 - - -> Public Release 0.4m2 : December 3, 2006 - - -- Change method signature : December 1, 2006 - - -- Change method signature dialog : November 30, 2006 - - -- Reordering parameters : November 28, 2006 - - -- Removing parameters : November 26, 2006 - - -- Inline parameter default value : November 26, 2006 - - -- Adding parameters : November 26, 2006 - - -- Normalizing function calls : November 26, 2006 - - -> Public Release 0.4m1 : November 19, 2006 - - -- Better help menu : November 15, 2006 - - -- Inline method refactoring : November 10, 2006 - - -> Public Release 0.3 : November 5, 2006 - - -- Better code assist proposal sorting and dialog : November 3, 2006 - - -- Extract method works with normal selection : October 31, 2006 - - -- Basic python file encoding support : October 31, 2006 - - -> Public Release 0.3rc1 : October 29, 2006 - - -- Unit-test running view : October 28, 2006 - - -- Previewing refactoring changes : October 25, 2006 - - -- Encapsulate field : October 19, 2006 - - -- Convert local variable to field refactoring : October 18, 2006 - - -> Public Release 0.3m5 : October 15, 2006 - - -- Code completions inside uncompleted ``try`` blocks : October 7, 2006 - - -- Single line extract method and variable : October 7, 2006 - - -- Hiding unappropriate menu items in different contexts : October 6, 2006 - - -- Inline local variable : October 5, 2006 - - -- Rename function parameters : October 5, 2006 - - -- Move a module or package to another package : October 4, 2006 - - -> Public Release 0.3m4 : October 1, 2006 - - -- Showing function signature in show doc : September 29, 2006 - - -- Goto line : September 29, 2006 - - -- Move refactoring for global class/function : September 29, 2006 - - -- Change relative imports to absolute : September 28, 2006 - - -- Changing from imports to normal imports : September 28, 2006 - - -- Removing duplicate imports : September 27, 2006 - - -- Expanding from-star-imports : September 27, 2006 - - -- Removing unused imports : September 27, 2006 - - -- Introduce factory method refactoring : September 25, 2006 - - -- Basic import tools : September 21, 2006 - - -- Separating concluded and structural data in `PyModule`\s : September 19, 2006 - - -> Public Release 0.3m3 : September 17, 2006 - - -- Basic subversion support using pysvn : September 14, 2006 - - -- Renaming methods in class hierarchy : September 12, 2006 - - -- Transform module to package refactoring : September 11, 2006 - - -> Public Release 0.3m2 : September 3, 2006 - - -- Better New ... Dialogs : September 2, 2006 - - -- Function argument dynamic object inference : September 2, 2006 - - -- Basic dynamic type inference : September 2, 2006 - - -- Better menus : August 27, 2006 - - -- Relative imports : August 23, 2006 - - -- Read ``__init__.py`` of packages : August 23, 2006 - - -- Extract function : August 22, 2006 - - -> Public Release 0.3m1 : August 20, 2006 - - -- Undoing refactorings : August 19, 2006 - - -- Making module dependancy graph : August 19, 2006 - - -- Rename modules/packages : August 18, 2006 - - -- Reloading changed editors after refactorings : August 17, 2006 - - -- Rename class/function : August 17, 2006 - - -- Function return object static type inference : August 15, 2006 - - -- Show PyDoc : August 15, 2006 - - -- Object inference for chained assignments : August 14, 2006 - - -> Public Release 0.2 : August 6, 2006 - - -- Resource tree view : August 5, 2006 - - -- Handle ``HTTPClient`` style names in go to next/prev word : August 2, 2006 - - -> Public Release 0.2RC : July 30, 2006 - - -- Asking whether to save modified buffers when exiting : July 29, 2006 - - -- Extending menus : July 25, 2006 - - -- ReST highlighting : July 24, 2006 - - -- Showing editor modified status : July 23, 2006 - - -- Sorting code assist proposals : July 22, 2006 - - -- Not renaming names in strings and comments in refactorings : July 22, 2006 - - -- Separating entering and correcting indentation : July 22, 2006 - - -> Public Release 0.2pre5 : July 16, 2006 - - -- Out of project modules : July 15, 2006 - - -- Handle circular from-imports : July 14, 2006 - - -- Completeing ``AClass(param).a_`` : July 11, 2006 - - -- We know the type of ``var = AClass()`` : July 4, 2006 - - -- Rename function parameter in the function : July 3, 2006 - - -> Public Release 0.2pre4 : July 2, 2006 - - -- Rename local variable : July 2, 2006 - - -- Complete as you type : July 2, 2006 - - -- Show quick outline; C-o : June 23, 2006 - - -- Go to definition; F3 : June 22, 2006 - - -> Public release 0.2pre3 : June 18, 2006 - - -- Auto-completing "self."s : June 13, 2006 - - -- Proposing base class attributes : June 12, 2006 - - -- Auto completion after "."s : June 8, 2006 - - -> Public Release 0.2pre2 : June 4, 2006 - - -- Next/prev word stops at underlines and capitals : May 29, 2006 - - -- Ignoring string and comment contents while indenting : May 29, 2006 - - -- Proposing templates in code-assist proposals : May 26, 2006 - - -- Auto-complete from-import imported objects : May 25, 2006 - - -- Not proposing variables which are not defined yet : May 23, 2006 - - -- Auto-completion should ignore current statement : May 23, 2006 - - -- Proposing function parameters in functions : May 22, 2006 - - -- Auto-complete local variable names : May 22, 2006 - - -> Public Release 0.2pre1 : May 20, 2006 - - -- Auto completing keywords and builtins : May 19, 2006 - - -- Auto-complete imported objects : May 19, 2006 - - -- Show searching status in the status bar : May 18, 2006 - - -- Auto-complete class and function names : May 16, 2006 - - -- Auto-complete global variables : May 14, 2006 - - -> Public Release 0.1 : May 8, 2006 - - -- Separating indenting and correcting indentation : May 7, 2006 - - -- Enhancing editor and indentation : May 4, 2006 - - - Pressing backspace should deindent - - Clearing undo list when opening a file; undoSeparator when saving - - -- Showing current line in status bar : April 28, 2006 - - -- Switch editor dialog; C-x b and C-F6 : April 27, 2006 - - -- Make new package dialog : April 25, 2006 - - -- Make new module dialog : April 25, 2006 - - -> Public Release 0.1pre : April 22, 2006 - - -- Extending syntax highlighted elements : April 22, 2006 - - -- Auto indentation; C-i : April 20, 2006 - - -- Basic searching; C-s : April 12, 2006 - - -> SF registration : April 10, 2006 - - -- Multiple buffers : April 8, 2006 - The editor should have a notebook view. - - -- Enhancing dialogs : April 7, 2006 - Using tkMessageBox, tkFileDialog, tkSimpleDialog, ScrolledText - - -- Running modules : April 6, 2006 - You should add the required directories to the python path. - - -- Guessing source folders in the project : April 5, 2006 - - -- Finding a file in a project : April 4, 2006 - - -- Highlighting keywords : March 21, 2006 - Only python files(``*.py``) should be highlighted. diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/docs/library.txt --- a/vim/sadness/ropevim/src/rope/docs/library.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,732 +0,0 @@ -========================= - Using Rope As A Library -========================= - -If you need other features, send a feature request. Have a look at -`contributing.txt`_. - - -.. contents:: Table of Contents - - -Quick Start -=========== - -This section will help you get started as soon as possible. - - -Making A Project ----------------- - -The first thing you should do is to make a project:: - - import rope.base.project - - - myproject = rope.base.project.Project('/path/to/myproject') - -It's good to know that: - -* A project is a folder in the file-system. -* It can contain anything. -* Rope searches for python modules and packages inside a project when - needed. -* Refactorings only change files and folders inside the project that - has been passed to them. -* Out of project modules that are imported from a module inside a - project are handled but never changed by refactorings. -* Rope makes a rope folder inside projects. By default the name of - this folder is ``.ropeproject`` but that can be changed using the - constructor's `ropefolder` parameter (passing `None` will prevent - rope from making this folder). -* Rope uses ``.ropeproject`` folder for things like saving object - information and loading project configurations. -* Project preferences can be configured by passing options to the - constructor or in ``.ropeproject/config.py``. See the default - ``config.py``, `rope.base.default_config` module, for more - information. -* All configurations that are available in the ``config.py`` file can - be specified as keyword parameters to `Project` constructor. These - parameters override the ones in the ``config.py`` file. -* Each project has a set of ignored resource patterns; You can use it - to tell rope to ignore files and folders matching certain patterns. -* The ``.ropeproject`` folder can be safely copied in other clones of - a project if you don't want to lose your objectdb and history. - - -Library Utilities ------------------ - -The `rope.base.libutils` module provides tools for making using rope -as a library easier. We'll talk more about this module later. - - -What Are These `Resource`\s? ----------------------------- - -In rope, files and folders in a project are accessed through -`rope.base.resources.Resource` objects. It has two subclasses `File` -and `Folder`. What we care about is that refactorings and `Change`\s -(we'll talk about them later) use resources. - -In order to create a `Resource` for a path in a project we have two -options. The first approach uses the `Project` object (use -`Project.get_resource()`_ method). I prefer to describe the second -approach since it needs less to know. - -We can use `libutils` module. It has a function named -`path_to_resource()`. It takes a project and a path:: - - from rope.base import libutils - - myresource = libutils.path_to_resource(myproject, '/path/to/resource') - - -But this is only half of the answer. Consider we have a resource. -How can we know anything about it? The answer is to use its ``path`` -and ``real_path`` fields. `Resource.real_path` is the absolute path -of the resource in the file-system. `Resource.path` field contains -the address of a resource relative to project root (the same format as -needed by `Project.get_resource()`_). - - -Performing Refactorings ------------------------ - -There are examples at the end of this document. But as another -example we'll extract a variable in a file. First we need the -`Resource` object that points to a file in a project:: - - resource = libutils.path_to_resource(myproject, '/path/to/my/module.py') - -So we can make our Refactoring class:: - - from rope.refactor.extract import ExtractVariable - - - extractor = ExtractVariable(myproject, resource, start, end) - -Where `start` and `end` are the offsets of the region to extract in -resource. Be careful when calculating the offsets. Dos line-endings -and multi-byte characters are considered to be only one character. -This is actually easier for IDEs, since most GUI libraries do that -when calculating offsets. - -Next, IDE's usually pop up a dialog for letting the user configure -refactoring options like the name of the extracted variable. - -After that, we can calculate the changes:: - - changes = extractor.get_changes('extracted_variable') - -`changes` holds the changes this refactoring makes. Calculating it -might be time consuming; See `rope.base.taskhandle.TaskHandle`_ -section for measuring its progress or interrupting it. - - -Previewing And Performing Changes ---------------------------------- - -As mentioned in the last section each refactoring returns a -`rope.base.change.Change` object. Now how can we know what it -contains and how to perform it? - -*Previewing*: - -``str(changes)`` returns a short description of the changes. You can -use ``changes.get_description()`` to get a preview; it is useful when -you don't care much about the format. Otherwise you can use the -``changes`` object directly. See the documentation in -`rope.base.change` module. - -*Performing*: - -The easiest way for performing the refactoring is to use -`Project.do()`_ method:: - - myproject.do(changes) - -If you want to perform the changes yourself, you have two options. -Note that the main reason for performing the changes manually is -handling version control systems that are not supported by rope. - -The first approach is to use `rope.base.fscommands`_. See `Writing A -FileSystemCommands`_ section. The changes can be performed as before -using `Project.do()`. - -The other is to perform the changes manually based on the returned -`changes` object (again see the documentation in `rope.base.change` -module). If this approach is used you cannot undo the refactoring -using ``project.history.undo()``. - -*Updating Open Buffers In IDEs*: - -Usually editors need to reload the files changed by rope. You can use -``Change.get_changed_resources()`` to get the list of resources that -need to be reloaded. - - -Validating The Project ----------------------- - -When using rope as a library, you probably change the files in it in -parallel (for example in IDEs). To force rope to invalidate cached -information about resources that have been removed or changed outside -rope you should call `Project.validate()`_ method. You can pass a -resource to this method. For example:: - - myproject.validate() - -validates all files and directories in the project. So call this -function every time you want use rope (before performing refactorings, -for instance). - - -Activating Static Object Analysis ---------------------------------- - -One of the greatest strengths of rope is its static object analysis, -SOA. You can perform SOA on a module using `PyCore.analyze_module()` -method but performing SOA on a module is not cheap. So I decided that -the best time for performing SOA is when saving files and only -performing it on changed scopes. - -But since rope is not notified about the changes the IDE performs, you -should tell rope about the change. You can do so by using -`rope.base.libutils.report_change()`. That is, whenever you want to -change a module you can do something like:: - - # Do the actual writing - old_contents = read(path) - write(path, new_content) - - # Inform rope about the change - libutils.report_change(myproject, path, old_contents) - -Where `read` and `write` stand for methods used for reading and -writing files. - - -Closing The Project -------------------- - -`Project.close()`_ closes project open resources. Always call this -function when you don't need a project anymore:: - - myproject.close() - - -`rope.base.project.Project` -=========================== - -You can create a project by:: - - project = Project(root_address) - -Where the `root_address` is the root folder of your project. - -A project has some useful fields. `Project.address` is the address of -the root folder of a project. `Project.root` is a `Folder` object -that points to that folder. - - -`Project.get_resource()` ------------------------- - -You can use this method for getting a resource (that is file or -folder) inside a project. Uses ``'/'``s for separating directories. -For instance ``project.get_resource('my_folder/my_file.txt')`` returns -a `rope.base.resources.File` object that points to -``${projectroot}/my_folder/my_file.txt`` file. - -Note that this method assumes the resource exists. If it does not -exist you can use `Project.get_file()` and `Project.get_folder()` -methods. - - -`Project.do()` --------------- - -For committing changes returned by refactorings. - - -`Project.history` ------------------ - -A `rope.base.history.History` object. You can use its `undo` and -`redo` methods for undoing or redoing changes. Note that you can use -it only if you have committed your changes using rope. - - -`Project.validate()` --------------------- - -When using rope as a library you probably change the files in that -project in parallel (for example in IDEs). To force rope to -invalidate cached information about resources that have been -removed or changed outside rope you should call `Project.validate`. -You should pass a resource to this method. For example:: - - project.validate(project.root) - -validates all files and directories in the project. - - -`Project.close()` ------------------ - -Closes project open resources. Always call this function when you -don't need a project anymore. Currently it closes the files used for -storing object information and project history. Since some parts of -these files are in memory for efficiency not closing a project might -put them in an inconsistent state. - - -`rope.base.fscommands` ----------------------- - -The `rope.base.fscommands` module implements the basic file system -operations that rope needs to perform. The main reason for the -existence of this module is supporting version control systems. Have -a look at `FileSystemCommands` and `SubversionCommands` in the same -module. If you need other version control systems you can write a new -class that provides this interface. `rope.base.project.Project` -accepts a ``fscommands`` argument. You can use this argument to force -rope to use your new class. - - -``.ropeproject`` Folder ------------------------ - -From version ``0.5``, rope makes a ``.ropeproject`` folder in the -project by default for saving project configurations and data. The -name of this folder is passed to the constructor if you want to change -that. Also you can force rope not to make such a folder by passing -`None`. - -If such a folder exists rope loads the ``config.py`` file in that -folder. It might also use it for storing object information and -history. - - -`rope.base.pycore.PyCore` -========================= - -Provides useful methods for managing python modules and packages. -Each project has a `PyCore` that can be accessed using -`Project.pycore` attribute. - -`PyCore.run_module()` runs a resource. When running, it collects type -information to do dynamic object inference. For this reason modules -run much slower. - -Also `Pycore.analyze_module()` collects object information for a -module. The collected information can be used to enhance rope's -static object inference. - - -`rope.base.taskhandle.TaskHandle` -================================= - -Can be used for stopping and monitoring the progress of time consuming -tasks like some of refactorings. `Project.do()` and -`Refactoring.get_changes()` of most refactorings take a keyword -parameter called ``task_handle``. You can pass a `TaskHandle` object -to them. A `TaskHandle` can be used for interrupting or observing a -task. - -Always pass ``task_handle`` as keyword argument; it will always be the -last argument and new arguments of the refactoring are added before -it. - -A task might consist of a few `JobSet`\s. Each `JobSet` does a few -jobs. For instance calculating the changes for renaming a method in a -class hierarchy has two job sets; We need to find the classes for -constructing the class hierarchy and then we need to change the -occurrences. - -The `TaskHandle.current_jobset()` returns the most recent `JobSet` or -`None` if none has been started. You can use the methods of `JobSet` -for obtaining information about the current job. So you might want to -do something like:: - - import rope.base.taskhandle - - - handle = rope.base.taskhandle.TaskHandle("Test Task") - - def update_progress(): - jobset = handle.current_jobsets() - if jobset: - text = '' - # getting current job set name - if jobset.get_name() is not None: - text += jobset.get_name() - # getting active job name - if jobset.get_active_job_name() is not None: - text += ' : ' + jobset.get_active_job_name() - # adding done percent - percent = jobset.get_percent_done() - if percent is not None: - text += ' ... %s percent done' % percent - print text - - handle.add_observer(update_progress) - - changes = renamer.get_changes('new_name', task_handle=handle) - -Also you can use something like this for stopping the task:: - - def stop(): - handle.stop() - -After calling ``stop()``, the thread that is executing the task will -be interrupted by a `rope.base.exceptions.InterruptedTaskError` -exception. - - -Refactorings -============ - -Have a look at `rope.refactor` package and its sub-modules. For -example for performing a move refactoring you can create a -`Move` object like this:: - - mover = Move(project, resource, offset) - -Where `resource` and `offset` is the location to perform the -refactoring. - -Then you can commit the changes by it using `get_changes()` method:: - - project.do(mover.get_changes(destination)) - -Where `destination` module/package is the destination resource for -move refactoring. Other refactorings classes have a similar -interface. - - -List Of Refactorings --------------------- - -Here is the list of refactorings rope provides. Note that this list -might be out of date. For more information about these refactoring -see pydocs in their modules and the unit-tests in the -``ropetest/refactor/`` folder. - -* `rope.refactor.rename`: - Rename something in the project. See the example below. - -* `rope.refactor.move`: - Move a python element in the project. - -* `rope.refactor.restructure`: - Restructure code. See the example below. - -* `rope.refactor.extract`: - Extract methods/variables. - -* `rope.refactor.inline`: - Inline occurrences of a method/variable/parameter. - -* `rope.refactor.usefunction`: - Try to use a function wherever possible. - -* `rope.refactor.method_object`: - Transform a function or a method to a method object. - -* `rope.refactor.change_signature`: - Change the signature of a function/method. - -* `rope.refactor.introduce_factory`: - Introduce a factory for a class and changes all constructors to use - it. - -* `rope.refactor.introduce_parameter`: - Introduce a parameter in a function. - -* `rope.refactor.encapsulate_field`: - Generate a getter/setter for a field and changes its occurrences to - use them. - -* `rope.refactor.localtofield`: - Change a local variable to field - -* `rope.refactor.topackage`: - Transform a module to a package with the same name. - -* `rope.refactor.importutils`: - Perform actions like organize imports. - - -Refactoring Resources Parameter -------------------------------- - -Some refactorings, restructure and find occurrences accept an argument -called ``resources``. If it is a list of `File`\s, all other -resources in the project are ignored and the refactoring only analyzes -them; if it is `None` all python modules in the project will be -analyzed. Using this parameter, IDEs can let the user limit the files -on which a refactoring should be applied. - - -Examples -======== - -Rename ------- - -Using rename refactoring:: - - # Creating a project - >>> from rope.base.project import Project - >>> project = Project('.') - - # Working with files to create a module - >>> mod1 = project.root.create_file('mod1.py') - >>> mod1.write('a_var = 10\n') - - # Alternatively you can use `generate` module. - # Creating modules and packages using `generate` module - >>> from rope.contrib import generate - >>> pycore = project.pycore - >>> pkg = generate.create_package(project, 'pkg') - >>> mod2 = generate.create_module(project, 'mod2', pkg) - >>> mod2.write('import mod1\nprint mod1.a_var\n') - - # We can use `PyCore.find_module` for finding modules, too - >>> assert mod2 == pycore.find_module('pkg.mod2') - - # Performing rename refactoring on `mod1.a_var` - >>> from rope.refactor.rename import Rename - >>> changes = Rename(project, mod1, 1).get_changes('new_var') - >>> project.do(changes) - >>> mod1.read() - u'new_var = 10\n' - >>> mod2.read() - u'import mod1\nprint mod1.new_var\n' - - # Undoing rename refactoring - >>> project.history.undo() - ... - >>> mod1.read() - u'a_var = 10\n' - >>> mod2.read() - u'import mod1\nprint mod1.a_var\n' - - # Cleaning up - >>> pkg.remove() - >>> mod1.remove() - >>> project.close() - - -Restructuring -------------- - -The example for replacing occurrences of our `pow` function to ``**`` -operator (see the restructuring section of `overview.txt`_):: - - # Setting up the project - >>> from rope.base.project import Project - >>> project = Project('.') - - >>> mod1 = project.root.create_file('mod1.py') - >>> mod1.write('def pow(x, y):\n result = 1\n' - ... ' for i in range(y):\n result *= x\n' - ... ' return result\n') - >>> mod2 = project.root.create_file('mod2.py') - >>> mod2.write('import mod1\nprint(mod1.pow(2, 3))\n') - - >>> from rope.refactor import restructure - - >>> pattern = '${pow_func}(${param1}, ${param2})' - >>> goal = '${param1} ** ${param2}' - >>> args = {'pow_func': 'name=mod1.pow'} - - >>> restructuring = restructure.Restructure(project, pattern, goal, args) - - >>> project.do(restructuring.get_changes()) - >>> mod2.read() - u'import mod1\nprint(2 ** 3)\n' - - # Cleaning up - >>> mod1.remove() - >>> mod2.remove() - >>> project.close() - - -See code documentation and test suites for more information. - -.. _overview.txt: overview.html -.. _contributing.txt: contributing.html - - -Other Topics -============ - - -Writing A `FileSystemCommands` ------------------------------- - -The `get_changes()` method of refactoring classes return a -`rope.base.change.Change` object. You perform these changes by -calling `Project.do()`. But as explained above some IDEs need to -perform the changes themselves. - -Every change to file-system in rope is commited using an object that -provides `rope.base.fscommands.FileSystemCommands` interface. As -explained above in `rope.base.fscommands`_ section, rope uses this -interface to handle different VCSs. - -You can implement your own fscommands object:: - - class MyFileSystemCommands(object): - - def create_file(self, path): - """Create a new file""" - # ... - - def create_folder(self, path): - """Create a new folder""" - # ... - - def move(self, path, new_location): - """Move resource at `path` to `new_location`""" - # ... - - def remove(self, path): - """Remove resource""" - # ... - - def write(self, path, data): - """Write `data` to file at `path`""" - # ... - -And you can create a project like this:: - - my_fscommands = MyFileSystemCommands() - project = rope.base.project.Project('~/myproject', - fscommands=my_fscommands) - - -`rope.contrib.codeassist` -------------------------- - -The `rope.contrib` package contains modules that use rope base parts -and provide useful features. `rope.contrib.codeassist` module can -be used in IDEs:: - - from rope.ide import codeassist - - - # Get the proposals; you might want to pass a Resource - proposals = codeassist.code_assist(project, source_code, offset) - # Sorting proposals; for changing the order see pydoc - proposals = codeassist.sorted_proposals(proposals) - - # Where to insert the completions - starting_offset = codeassist.starting_offset(source_code, offset) - - # Applying a proposal - proposal = proposals[x] - replacement = proposal.name - - new_source_code = (source_code[:starting_offset] + - replacement + source_code[offset:]) - -`maxfixes` parameter of `code_assist` decides how many syntax errors -to fix. The default value is one. For instance:: - - def f(): - g(my^ - - myvariable = None - - def g(p): - invalid syntax ... - -will report `myvariable`, only if `maxfixes` is bigger than 1. - -`later_locals`, if `True`, forces rope to propose names that are -defined later in current scope. It is `True` by default. For -instance:: - - def f(): - my^ - myvariable = None - -will not report `myvariable`, if `later_locals` is False. - -See pydocs and source code for more information (other functions in -this module might be interesting, too; like `get_doc`, -`get_definition_location`). - - -`rope.contrib.findit` ---------------------- - -`findit` module provides `find_occurrences()` for finding occurrences -of a name. Also `find_implementations()` function finds the places in -which a method is overridden. - - -`rope.contrib.autoimport` -------------------------- - -This module can be used to find the modules that provide a name. IDEs -can use this module to auto-import names. `AutoImport.get_modules()` -returns the list of modules with the given global name. -`AutoImport.import_assist()` tries to find the modules that have a -global name that starts with the given prefix. - - -Cross-Project Refactorings --------------------------- - -`rope.refactor.multiproject` can be used to perform a refactoring -across multiple projects. - -Usually refactorings have a main project. That is the project that -contains the definition of the changing python name. Other projects -depend on the main one and uses of the changed name in them should be -updated. - -Each refactoring changes only one project (the project passed to its -constructor). But we can use `MultiProjectRefactoring` proxy to -perform a refactoring on other projects, too. - -First we need to create a multi-project refactoring constructor. As -an example consider we want to perform a rename refactoring:: - - from rope.refactor import multiproject, rename - - - CrossRename = multiproject.MultiProjectRefactoring(rename.Rename, - projects) - - -Here `projects` is the list of dependant projects; it does not include -the main project. The first argument is the refactoring class (such -as `Rename`) or factory function (like `create_move`). - -Next we can construct the refactoring:: - - renamer = CrossRename(project, resource, offset) - -We create the rename refactoring as we do for normal refactorings. -Note that `project` is the main project. - -As mentioned above, other projects use the main project; rope -automatically adds the main project to the python path of other -projects. - -Finally we can calculate the changes. But instead of calling -`get_changes()` (which returns main project changes, only), we can -call `get_all_changes()` with the same arguments. It returns a list -of ``(project, changes)`` tuples. You can perform them manually by -calling ``project.do(changes)`` for each tuple or use -`multiproject.perform()`:: - - project_and_changes = renamer.get_all_changes('newname') - - multiproject.perform(project_and_changes) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/docs/overview.txt --- a/vim/sadness/ropevim/src/rope/docs/overview.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1116 +0,0 @@ -=============== - Rope Overview -=============== - - -The purpose of this file is to give an overview of some of rope's -features. It is incomplete. And some of the features shown here are -old and do not show what rope can do in extremes. So if you really -want to feel the power of rope try its features and see its unit -tests. - -This file is more suitable for the users. Developers who plan to use -rope as a library might find library.txt_ more useful. - -.. contents:: Table of Contents -.. _library.txt: library.html - - -``.ropeproject`` Folder -======================= - -Rope uses a folder inside projects for holding project configuration -and data. Its default name is ``.ropeproject``, but it can be -changed (you can even tell rope not to create this folder). - -Currently it is used for things such as: - -* There is a ``config.py`` file in this folder in which you can change - project configurations. Have look at the default ``config.py`` file - (is created when it does not exist) for more information. -* It can be used for saving project history, so that the next time you - open the project you can undo past changes. -* It can be used for saving object information to help rope object - inference. -* It can be used for saving global names cache which is used in - auto-import. - -You can change what to save and what not to in the ``config.py`` file. - - -Refactorings -============ - -This section shows some random refactorings that you can perform using -rope. - - -Renaming Attributes -------------------- - -Consider we have:: - - class AClass(object): - - def __init__(self): - self.an_attr = 1 - - def a_method(self, arg): - print self.an_attr, arg - - a_var = AClass() - a_var.a_method(a_var.an_attr) - -After renaming ``an_attr`` to ``new_attr`` and ``a_method`` to -``new_method`` we'll have:: - - class AClass(object): - - def __init__(self): - self.new_attr = 1 - - def new_method(self, arg): - print self.new_attr, arg - - a_var = AClass() - a_var.new_method(a_var.new_attr) - - -Renaming Function Keyword Parameters ------------------------------------- - -On:: - - def a_func(a_param): - print a_param - - a_func(a_param=10) - a_func(10) - -performing rename refactoring on any occurrence of ``a_param`` will -result in:: - - def a_func(new_param): - print new_param - - a_func(new_param=10) - a_func(10) - - -Renaming modules ----------------- - -Consider the project tree is something like:: - - root/ - mod1.py - mod2.py - -``mod1.py`` contains:: - - import mod2 - from mod2 import AClass - - mod2.a_func() - a_var = AClass() - -After performing rename refactoring one of the ``mod2`` occurrences in -`mod1` we'll get:: - - import newmod - from newmod import AClass - - newmod.a_func() - a_var = AClass() - -and the new project tree would be:: - - root/ - mod1.py - newmod.py - - -Renaming Occurrences In Strings And Comments --------------------------------------------- - -You can tell rope to rename all occurrences of a name in comments and -strings. This can be done by passing ``docs=True`` to -`Rename.get_changes()` method. Rope renames names in comments and -strings only where the name is visible. For example in:: - - def f(): - a_var = 1 - # INFO: I'm printing `a_var` - print 'a_var = %s' % a_var - - # f prints a_var - -after we rename the `a_var` local variable in `f()` to `new_var` we -would get:: - - def f(): - new_var = 1 - # INFO: I'm printing `new_var` - print 'new_var = %s' % new_var - - # f prints a_var - -This makes it safe to assume that this option does not perform wrong -renames most of the time. - -This also changes occurrences inside evaluated strings:: - - def func(): - print 'func() called' - - eval('func()') - -After renaming `func` to `newfunc` we should have:: - - def newfunc(): - print 'newfunc() called' - - eval('newfunc()') - - -Rename When Unsure ------------------- - -This option tells rope to rename when it doesn't know whether it is an -exact match or not. For example after renaming `C.a_func` when the -'rename when unsure' option is set in:: - - class C(object): - - def a_func(self): - pass - - def a_func(arg): - arg.a_func() - - C().a_func() - -we would have:: - - class C(object): - - def new_func(self): - pass - - def a_func(arg): - arg.new_func() - - C().new_func() - -Note that the global `a_func` was not renamed because we are sure that -it is not a match. But when using this option there might be some -unexpected renames. So only use this option when the name is almost -unique and is not defined in other places. - -Move Method Refactoring ------------------------ - -It happens when you perform move refactoring on a method of a class. -In this refactoring, a method of a class is moved to the class of one -of its attributes. The old method will call the new method. If you -want to change all of the occurrences of the old method to use the new -method you can inline it afterwards. - -For instance if you perform move method on `a_method` in:: - - class A(object): - pass - - class B(object): - - def __init__(self): - self.attr = A() - - def a_method(self): - pass - - b = B() - b.a_method() - -You will be asked for the destination field and the name of the new -method. If you use ``attr`` and ``new_method`` in these fields -and press enter, you'll have:: - - class A(object): - - def new_method(self): - pass - - class B(object): - - def __init__(self): - self.attr = A() - - def a_method(self): - return self.attr.new_method() - - - b = B() - b.a_method() - -Now if you want to change the occurrences of `B.a_method()` to use -`A.new_method()`, you can inline `B.a_method()`:: - - class A(object): - - def new_method(self): - pass - - class B(object): - - def __init__(self): - self.attr = A() - - b = B() - b.attr.new_method() - - -Moving Fields -------------- - -Rope does not have a separate refactoring for moving fields. Rope's -refactorings are very flexible, though. You can use the rename -refactoring to move fields. For instance:: - - class A(object): - pass - - class B(object): - - def __init__(self): - self.a = A() - self.attr = 1 - - b = B() - print(b.attr) - -consider we want to move `attr` to `A`. We can do that by renaming `attr` -to `a.attr`:: - - class A(object): - pass - - class B(object): - - def __init__(self): - self.a = A() - self.a.attr = 1 - - b = B() - print(b.a.attr) - -You can move the definition of `attr` manually. - - -Extract Method --------------- - -In these examples ``${region_start}`` and ``${region_end}`` show the -selected region for extraction:: - - def a_func(): - a = 1 - b = 2 * a - c = ${region_start}a * 2 + b * 3${region_end} - -After performing extract method we'll have:: - - def a_func(): - a = 1 - b = 2 * a - c = new_func(a, b) - - def new_func(a, b): - return a * 2 + b * 3 - -For multi-line extractions if we have:: - - def a_func(): - a = 1 - ${region_start}b = 2 * a - c = a * 2 + b * 3${region_end} - print b, c - -After performing extract method we'll have:: - - def a_func(): - a = 1 - b, c = new_func(a) - print b, c - - def new_func(a): - b = 2 * a - c = a * 2 + b * 3 - return b, c - - -Extracting Similar Expressions/Statements ------------------------------------------ - -When performing extract method or local variable refactorings you can -tell rope to extract similar expressions/statements. For instance -in:: - - if True: - x = 2 * 3 - else: - x = 2 * 3 + 1 - -Extracting ``2 * 3`` will result in:: - - six = 2 * 3 - if True: - x = six - else: - x = six + 1 - - -Extract Method In staticmethods/classmethods --------------------------------------------- - -The extract method refactoring has been enhanced to handle static and -class methods better. For instance in:: - - class A(object): - - @staticmethod - def f(a): - b = a * 2 - -if you extract ``a * 2`` as a method you'll get:: - - class A(object): - - @staticmethod - def f(a): - b = A.twice(a) - - @staticmethod - def twice(a): - return a * 2 - - -Inline Method Refactoring -------------------------- - -Inline method refactoring can add imports when necessary. For -instance consider ``mod1.py`` is:: - - import sys - - - class C(object): - pass - - def do_something(): - print sys.version - return C() - -and ``mod2.py`` is:: - - import mod1 - - - c = mod1.do_something() - -After inlining `do_something`, ``mod2.py`` would be:: - - import mod1 - import sys - - - print sys.version - c = mod1.C() - -Rope can inline methods, too:: - - class C(object): - - var = 1 - - def f(self, p): - result = self.var + pn - return result - - - c = C() - x = c.f(1) - -After inlining `C.f()`, we'll have:: - - class C(object): - - var = 1 - - c = C() - result = c.var + pn - x = result - -As another example we will inline a `classmethod`:: - - class C(object): - @classmethod - def say_hello(cls, name): - return 'Saying hello to %s from %s' % (name, cls.__name__) - hello = C.say_hello('Rope') - -Inlining `say_hello` will result in:: - - class C(object): - pass - hello = 'Saying hello to %s from %s' % ('Rope', C.__name__) - - -Inlining Parameters -------------------- - -`rope.refactor.inline.create_inline()` creates an `InlineParameter` -object when performed on a parameter. It passes the default value of -the parameter wherever its function is called without passing it. For -instance in:: - - def f(p1=1, p2=1): - pass - - f(3) - f() - f(3, 4) - -after inlining p2 parameter will have:: - - def f(p1=1, p2=1): - pass - - f(3, 2) - f(p2=2) - f(3, 4) - - -Use Function Refactoring ------------------------- - -It tries to find the places in which a function can be used and -changes the code to call it instead. For instance if mod1 is:: - - def square(p): - return p ** 2 - - my_var = 3 ** 2 - - -and mod2 is:: - - another_var = 4 ** 2 - -if we perform "use function" on square function, mod1 will be:: - - def square(p): - return p ** 2 - - my_var = square(3) - -and mod2 will be:: - - import mod1 - another_var = mod1.square(4) - - -Automatic Default Insertion In Change Signature ------------------------------------------------ - -The `rope.refactor.change_signature.ArgumentReorderer` signature -changer takes a parameter called ``autodef``. If not `None`, its -value is used whenever rope needs to insert a default for a parameter -(that happens when an argument without default is moved after another -that has a default value). For instance in:: - - def f(p1, p2=2): - pass - -if we reorder using:: - - changers = [ArgumentReorderer([1, 0], autodef='1')] - -will result in:: - - def f(p2=2, p1=1): - pass - - -Sorting Imports ---------------- - -Organize imports sorts imports, too. It does that according to -:PEP:`8`:: - - [__future__ imports] - - [standard imports] - - [third-party imports] - - [project imports] - - - [the rest of module] - - -Handling Long Imports ---------------------- - -``Handle long imports`` command trys to make long imports look better by -transforming ``import pkg1.pkg2.pkg3.pkg4.mod1`` to ``from -pkg1.pkg2.pkg3.pkg4 import mod1``. Long imports can be identified -either by having lots of dots or being very long. The default -configuration considers imported modules with more than 2 dots or with -more than 27 characters to be long. - - -Stoppable Refactorings ----------------------- - -Some refactorings might take a long time to finish (based on the size -of your project). The `get_changes()` method of these refactorings -take a parameter called `task_handle`. If you want to monitor or stop -these refactoring you can pass a `rope.refactor. -taskhandle.TaskHandle` to this method. See `rope.refactor.taskhandle` -module for more information. - - -Basic Implicit Interfaces -------------------------- - -Implicit interfaces are the interfaces that you don't explicitly -define; But you expect a group of classes to have some common -attributes. These interfaces are very common in dynamic languages; -Since we only have implementation inheritance and not interface -inheritance. For instance:: - - class A(object): - - def count(self): - pass - - class B(object): - - def count(self): - pass - - def count_for(arg): - return arg.count() - - count_for(A()) - count_for(B()) - -Here we know that there is an implicit interface defined by the -function `count_for` that provides `count()`. Here when we rename -`A.count()` we expect `B.count()` to be renamed, too. Currently rope -supports a basic form of implicit interfaces. When you try to rename -an attribute of a parameter, rope renames that attribute for all -objects that have been passed to that function in different call -sites. That is renaming the occurrence of `count` in `count_for` -function to `newcount` will result in:: - - class A(object): - - def newcount(self): - pass - - class B(object): - - def newcount(self): - pass - - def count_for(arg): - return arg.newcount() - - count_for(A()) - count_for(B()) - -This also works for change method signature. Note that this feature -relies on rope's object analysis mechanisms to find out the parameters -that are passed to a function. - - -Restructurings --------------- - -`rope.refactor.restructure` can be used for performing restructurings. -A restructuring is a program transformation; not as well defined as -other refactorings like rename. In this section, we'll see some -examples. After this example you might like to have a look at: - -* `rope.refactor.restructure` for more examples and features not - described here like adding imports to changed modules. -* `rope.refactor.wildcards` for an overview of the arguments the - default wildcard supports. - -Finally, restructurings can be improved in many ways (for instance -adding new wildcards). You might like to discuss your ideas in the -mailing list. - - -Example 1 -''''''''' - -In its basic form we have a pattern and a goal. Consider we were not -aware of the ``**`` operator and wrote our own :: - - def pow(x, y): - result = 1 - for i in range(y): - result *= x - return result - - print pow(2, 3) - -Now that we know ``**`` exists we want to use it wherever `pow` is -used (there might be hundreds of them!). We can use a pattern like:: - - pattern: pow(${param1}, ${param2}) - -Goal can be something like:: - - goal: ${param1} ** ${param2} - -Note that ``${...}`` can be used to match expressions. By default -every expression at that point will match. - -You can use the matched names in goal and they will be replaced with -the string that was matched in each occurrence. So the outcome of our -restructuring will be:: - - def pow(x, y): - result = 1 - for i in range(y): - result *= x - return result - - print 2 ** 3 - -It seems to be working but what if `pow` is imported in some module or -we have some other function defined in some other module that uses the -same name and we don't want to change it. Wildcard arguments come to -rescue. Wildcard arguments is a mapping; Its keys are wildcard names -that appear in the pattern (the names inside ``${...}``). - -The values are the parameters that are passed to wildcard matchers. -The arguments a wildcard takes is based on its type. - -For checking the type of a wildcard, we can pass ``type=value`` as an -argument; ``value`` should be resolved to a python variable (or -reference). For instance for specifying `pow` in this example we can -use `mod.pow`. As you see, this string should start from module name. -For referencing python builtin types and functions you can use -`__builtin__` module (for instance `__builtin__.int`). - -For solving the mentioned problem, we change our `pattern`. But -`goal` remains the same:: - - pattern: ${pow_func}(${param1}, ${param2}) - goal: ${param1} ** ${param2} - -Consider the name of the module containing our `pow` function is -`mod`. ``args`` can be:: - - pow_func: name=mod.pow - -If we need to pass more arguments to a wildcard matcher we can use -``,`` to separate them. Such as ``name: type=mod.MyClass,exact``. - -This restructuring handles aliases; like in:: - - mypow = pow - result = mypow(2, 3) - -Transforms into:: - - mypow = pow - result = 2 ** 3 - -If we want to ignore aliases we can pass ``exact`` as another wildcard -argument:: - - pattern: ${pow}(${param1}, ${param2}) - goal: ${param1} ** ${param2} - args: pow: name=mod.pow, exact - -``${name}``, by default, matches every expression at that point; if -``exact`` argument is passed to a wildcard only the specified name -will match (for instance, if ``exact`` is specified , ``${name}`` -matches ``name`` and ``x.name`` but not ``var`` nor ``(1 + 2)`` while -a normal ``${name}`` can match all of them). - -For performing this refactoring using rope library see `library.txt`_. - - -Example 2 -''''''''' - -As another example consider:: - - class A(object): - - def f(self, p1, p2): - print p1 - print p2 - - - a = A() - a.f(1, 2) - -Later we decide that `A.f()` is doing too much and we want to divide -it to `A.f1()` and `A.f2()`:: - - class A(object): - - def f(self, p1, p2): - print p1 - print p2 - - def f1(self, p): - print p - - def f2(self, p): - print p - - - a = A() - a.f(1, 2) - -But who's going to fix all those nasty occurrences (actually this -situation can be handled using inline method refactoring but this is -just an example; consider inline refactoring is not implemented yet!). -Restructurings come to rescue:: - - pattern: ${inst}.f(${p1}, ${p2}) - goal: - ${inst}.f1(${p1}) - ${inst}.f2(${p2}) - - args: - inst: type=mod.A - -After performing we will have:: - - class A(object): - - def f(self, p1, p2): - print p1 - print p2 - - def f1(self, p): - print p - - def f2(self, p): - print p - - - a = A() - a.f1(1) - a.f2(2) - - -Example 3 -''''''''' - -If you like to replace every occurrences of ``x.set(y)`` with ``x = -y`` when x is an instance of `mod.A` in:: - - from mod import A - - a = A() - b = A() - a.set(b) - -We can perform a restructuring with these information:: - - pattern: ${x}.set(${y}) - goal: ${x} = ${y} - - args: x: type=mod.A - -After performing the above restructuring we'll have:: - - from mod import A - - a = A() - b = A() - a = b - -Note that ``mod.py`` contains something like:: - - class A(object): - - def set(self, arg): - pass - -Issues -'''''' - -Pattern names can appear only at the start of an expression. For -instance ``var.${name}`` is invalid. These situations can usually be -fixed by specifying good checks, for example on the type of `var` and -using a ``${var}.name``. - - -Object Inference -================ - -This section is a bit out of date. Static object inference can do -more than described here (see unittests). Hope to update this -someday! - - -Static Object Inference ------------------------ - -:: - - class AClass(object): - - def __init__(self): - self.an_attr = 1 - - def call_a_func(self): - return a_func() - - def a_func(): - return AClass() - - a_var = a_func() - #a_var.${codeassist} - - another_var = a_var - #another_var.${codeassist} - #another_var.call_a_func().${codeassist} - - -Basic support for builtin types:: - - a_list = [AClass(), AClass()] - for x in a_list: - pass - #x.${codeassist} - #a_list.pop().${codeassist} - - a_dict = ['text': AClass()] - for key, value in a_dict.items(): - pass - #key.${codeassist} - #value.${codeassist} - -Enhanced static returned object inference:: - - class C(object): - - def c_func(self): - return [''] - - def a_func(arg): - return arg.c_func() - - a_var = a_func(C()) - -Here rope knows that the type of a_var is a `list` that holds `str`\s. - -Supporting generator functions:: - - class C(object): - pass - - def a_generator(): - yield C() - - - for c in a_generator(): - a_var = c - -Here the objects `a_var` and `c` hold are known. - -Rope collects different types of data during SOA, like per name data -for builtin container types:: - - l1 = [C()] - var1 = l1.pop() - - l2 = [] - l2.append(C()) - var2 = l2.pop() - -Here rope can easily infer the type of `var1`. But for knowing the -type of `var2`, it needs to analyze the items inserted into `l2` which -might happen in other modules. Rope can do that by running SOA on -that module. - -You might be wondering is there any reason for using DOA instead of -SOA. The answer is that DOA might be more accurate and handles -complex and dynamic situations. For example in:: - - def f(arg): - return eval(arg) - - a_var = f('C') - -SOA can no way conclude the object `a_var` holds but it is really -trivial for DOA. What's more SOA only analyzes calls in one module -while DOA analyzes any call that happens when running a module. That -is, for achieving the same result as DOA you might need to run SOA on -more than one module and more than once (not considering dynamic -situations.) One advantage of SOA is that it is much faster than DOA. - - -Dynamic Object Analysis ------------------------ - -`PyCore.run_module()` runs a module and collects object information if -``perform_doa`` project config is set. Since as the program runs rope -gathers type information, the program runs much slower. After the -program is run, you can get better code assists and some of the -refactorings perform much better. - -``mod1.py``:: - - def f1(param): - pass - #param.${codeassist} - #f2(param).${codeassist} - - def f2(param): - #param.${codeassist} - return param - -Using code assist in specified places does not give any information -and there is actually no information about the return type of `f2` or -`param` parameter of `f1`. - -``mod2.py``:: - - import mod1 - - class A(object): - - def a_method(self): - pass - - a_var = A() - mod1.f1(a_var) - -Retry those code assists after performing DOA on `mod2` module. - - -Builtin Container Types -''''''''''''''''''''''' - -Builtin types can be handled in a limited way, too:: - - class A(object): - - def a_method(self): - pass - - def f1(): - result = [] - result.append(A()) - return result - - returned = f() - #returned[0].${codeassist} - -Test the the proposed completions after running this module. - - -Guessing Function Returned Value Based On Parameters ----------------------------------------------------- - -``mod1.py``:: - - class C1(object): - - def c1_func(self): - pass - - class C2(object): - - def c2_func(self): - pass - - - def func(arg): - if isinstance(arg, C1): - return C2() - else: - return C1() - - func(C1()) - func(C2()) - -After running `mod1` either SOA or DOA on this module you can test: - -``mod2.py``:: - - import mod1 - - arg = mod1.C1() - a_var = mod1.func(arg) - a_var.${codeassist} - mod1.func(mod1.C2()).${codeassist} - - -Automatic SOA -------------- - -When turned on, it analyzes the changed scopes of a file when saving -for obtaining object information; So this might make saving files a -bit more time consuming. By default, this feature is turned on, but -you can turn it off by editing your project ``config.py`` file, though -that is not recommended. - - -Validating Object DB --------------------- - -Since files on disk change over time project objectdb might hold -invalid information. Currently there is a basic incremental objectdb -validation that can be used to remove or fix out of date information. -Rope uses this feature by default but you can disable it by editing -``config.py``. - - -Custom Source Folders -===================== - -By default rope searches the project for finding source folders -(folders that should be searched for finding modules). You can add -paths to that list using ``source_folders`` project config. Note that -rope guesses project source folders correctly most of the time. You -can also extend python path using ``python_path`` config. - - -Version Control Systems Support -=============================== - -When performing refactorings some files might need to be moved (when -renaming a module) or new files might be created. When using a VCS, -rope detects and uses it to perform file system actions. - -Currently Mercurial_, GIT_, Darcs_ and SVN (using pysvn_ library) are -supported. They are selected based on dot files in project root -directory. For instance, Mercurial will be used if `mercurial` module -is available and there is a ``.hg`` folder in project root. Rope -assumes either all files are under version control in a project or -there is no version control at all. Also don't forget to commit your -changes yourself, rope doesn't do that. - -Adding support for other VCSs is easy; have a look at -`library.txt`_. - -.. _pysvn: http://pysvn.tigris.org -.. _Mercurial: http://selenic.com/mercurial -.. _GIT: http://git.or.cz -.. _darcs: http://darcs.net diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/docs/rope.txt --- a/vim/sadness/ropevim/src/rope/docs/rope.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -Features -======== - -Features implemented so far: - -* Refactorings - - * Rename everything! - * Extract method/local variable - * Move class/function/module/package/method - * Inline method/local variable/parameter - * Restructuring (like converting ``${a}.f(${b})`` to - ``${b}.g(${a})`` where ``a: type=mymod.A``) - * Introduce factory - * Change method signature - * Transform module to package - * Encapsulate field - * Replace method with method object - * And a few others - -* Refactoring Features - - * Extracting similar statements in extract refactorings - * Fixing imports when needed - * Previewing refactorings - * Undo/redo refactorings - * Stopping refactorings - * Cross-project refactorings - * Basic implicit interfaces handling in rename and change signature - * Mercurial_, GIT_, Darcs_ and SVN (pysvn_ library) support in - refactorings - -* IDE helpers - - * Auto-completion - * Definition location - * Get pydoc - * Find occurrences - * Organize imports (remove unused and duplicate imports and sort them) - * Generating python elements - -* Object Inference - - * Static and dynamic object analysis - * Handling built-in container types - * Saving object information on disk and validating them - -For more information see `overview.txt`_. - - -.. _overview.txt: overview.html -.. _pysvn: http://pysvn.tigris.org -.. _Mercurial: http://selenic.com/mercurial -.. _GIT: http://git.or.cz -.. _darcs: http://darcs.net diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/__init__.py --- a/vim/sadness/ropevim/src/rope/rope/__init__.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -"""rope, a python refactoring library""" - -INFO = __doc__ -VERSION = '0.9.3' -COPYRIGHT = """\ -Copyright (C) 2006-2010 Ali Gholami Rudi -Copyright (C) 2009-2010 Anton Gritsay - -This program is free software; you can redistribute it and/or modify it -under the terms of GNU General Public License as published by the -Free Software Foundation; either version 2 of the license, or (at your -opinion) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details.""" diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/__init__.py --- a/vim/sadness/ropevim/src/rope/rope/base/__init__.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -"""Base rope package - -This package contains rope core modules that are used by other modules -and packages. - -""" - -__all__ = ['project', 'libutils', 'exceptions'] diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/arguments.py --- a/vim/sadness/ropevim/src/rope/rope/base/arguments.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -import rope.base.evaluate -from rope.base import ast - - -class Arguments(object): - """A class for evaluating parameters passed to a function - - You can use the `create_arguments` factory. It handles implicit - first arguments. - - """ - - def __init__(self, args, scope): - self.args = args - self.scope = scope - self.instance = None - - def get_arguments(self, parameters): - result = [] - for pyname in self.get_pynames(parameters): - if pyname is None: - result.append(None) - else: - result.append(pyname.get_object()) - return result - - def get_pynames(self, parameters): - result = [None] * max(len(parameters), len(self.args)) - for index, arg in enumerate(self.args): - if isinstance(arg, ast.keyword) and arg.arg in parameters: - result[parameters.index(arg.arg)] = self._evaluate(arg.value) - else: - result[index] = self._evaluate(arg) - return result - - def get_instance_pyname(self): - if self.args: - return self._evaluate(self.args[0]) - - def _evaluate(self, ast_node): - return rope.base.evaluate.eval_node(self.scope, ast_node) - - -def create_arguments(primary, pyfunction, call_node, scope): - """A factory for creating `Arguments`""" - args = list(call_node.args) - args.extend(call_node.keywords) - called = call_node.func - # XXX: Handle constructors - if _is_method_call(primary, pyfunction) and \ - isinstance(called, ast.Attribute): - args.insert(0, called.value) - return Arguments(args, scope) - - -class ObjectArguments(object): - - def __init__(self, pynames): - self.pynames = pynames - - def get_arguments(self, parameters): - result = [] - for pyname in self.pynames: - if pyname is None: - result.append(None) - else: - result.append(pyname.get_object()) - return result - - def get_pynames(self, parameters): - return self.pynames - - def get_instance_pyname(self): - return self.pynames[0] -class MixedArguments(object): - - def __init__(self, pyname, arguments, scope): - """`argumens` is an instance of `Arguments`""" - self.pyname = pyname - self.args = arguments - - def get_pynames(self, parameters): - return [self.pyname] + self.args.get_pynames(parameters[1:]) - - def get_arguments(self, parameters): - result = [] - for pyname in self.get_pynames(parameters): - if pyname is None: - result.append(None) - else: - result.append(pyname.get_object()) - return result - - def get_instance_pyname(self): - return self.pyname - - -def _is_method_call(primary, pyfunction): - if primary is None: - return False - pyobject = primary.get_object() - if isinstance(pyobject.get_type(), rope.base.pyobjects.PyClass) and \ - isinstance(pyfunction, rope.base.pyobjects.PyFunction) and \ - isinstance(pyfunction.parent, rope.base.pyobjects.PyClass): - return True - if isinstance(pyobject.get_type(), rope.base.pyobjects.AbstractClass) and \ - isinstance(pyfunction, rope.base.builtins.BuiltinFunction): - return True - return False diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/ast.py --- a/vim/sadness/ropevim/src/rope/rope/base/ast.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -import _ast -from _ast import * - -from rope.base import fscommands - - -def parse(source, filename=''): - # NOTE: the raw string should be given to `compile` function - if isinstance(source, unicode): - source = fscommands.unicode_to_file_data(source) - if '\r' in source: - source = source.replace('\r\n', '\n').replace('\r', '\n') - if not source.endswith('\n'): - source += '\n' - try: - return compile(source, filename, 'exec', _ast.PyCF_ONLY_AST) - except (TypeError, ValueError), e: - error = SyntaxError() - error.lineno = 1 - error.filename = filename - error.msg = str(e) - raise error - - -def walk(node, walker): - """Walk the syntax tree""" - method_name = '_' + node.__class__.__name__ - method = getattr(walker, method_name, None) - if method is not None: - return method(node) - for child in get_child_nodes(node): - walk(child, walker) - - -def get_child_nodes(node): - if isinstance(node, _ast.Module): - return node.body - result = [] - if node._fields is not None: - for name in node._fields: - child = getattr(node, name) - if isinstance(child, list): - for entry in child: - if isinstance(entry, _ast.AST): - result.append(entry) - if isinstance(child, _ast.AST): - result.append(child) - return result - - -def call_for_nodes(node, callback, recursive=False): - """If callback returns `True` the child nodes are skipped""" - result = callback(node) - if recursive and not result: - for child in get_child_nodes(node): - call_for_nodes(child, callback, recursive) - - -def get_children(node): - result = [] - if node._fields is not None: - for name in node._fields: - if name in ['lineno', 'col_offset']: - continue - child = getattr(node, name) - result.append(child) - return result diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/astutils.py --- a/vim/sadness/ropevim/src/rope/rope/base/astutils.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -from rope.base import ast - - -def get_name_levels(node): - """Return a list of ``(name, level)`` tuples for assigned names - - The `level` is `None` for simple assignments and is a list of - numbers for tuple assignments for example in:: - - a, (b, c) = x - - The levels for for `a` is ``[0]``, for `b` is ``[1, 0]`` and for - `c` is ``[1, 1]``. - - """ - visitor = _NodeNameCollector() - ast.walk(node, visitor) - return visitor.names - - -class _NodeNameCollector(object): - - def __init__(self, levels=None): - self.names = [] - self.levels = levels - self.index = 0 - - def _add_node(self, node): - new_levels = [] - if self.levels is not None: - new_levels = list(self.levels) - new_levels.append(self.index) - self.index += 1 - self._added(node, new_levels) - - def _added(self, node, levels): - if hasattr(node, 'id'): - self.names.append((node.id, levels)) - - def _Name(self, node): - self._add_node(node) - - def _Tuple(self, node): - new_levels = [] - if self.levels is not None: - new_levels = list(self.levels) - new_levels.append(self.index) - self.index += 1 - visitor = _NodeNameCollector(new_levels) - for child in ast.get_child_nodes(node): - ast.walk(child, visitor) - self.names.extend(visitor.names) - - def _Subscript(self, node): - self._add_node(node) - - def _Attribute(self, node): - self._add_node(node) - - def _Slice(self, node): - self._add_node(node) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/builtins.py --- a/vim/sadness/ropevim/src/rope/rope/base/builtins.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,762 +0,0 @@ -"""This module trys to support builtin types and functions.""" -import inspect - -import rope.base.evaluate -from rope.base import pynames, pyobjects, arguments, utils, ast - - -class BuiltinModule(pyobjects.AbstractModule): - - def __init__(self, name, pycore=None, initial={}): - super(BuiltinModule, self).__init__() - self.name = name - self.pycore = pycore - self.initial = initial - - parent = None - - def get_attributes(self): - return self.attributes - - def get_doc(self): - if self.module: - return self.module.__doc__ - - def get_name(self): - return self.name.split('.')[-1] - - @property - @utils.saveit - def attributes(self): - result = _object_attributes(self.module, self) - result.update(self.initial) - if self.pycore is not None: - submodules = self.pycore._builtin_submodules(self.name) - for name, module in submodules.iteritems(): - result[name] = rope.base.builtins.BuiltinName(module) - return result - - @property - @utils.saveit - def module(self): - try: - result = __import__(self.name) - for token in self.name.split('.')[1:]: - result = getattr(result, token, None) - return result - except ImportError: - return - - -class _BuiltinElement(object): - - def __init__(self, builtin, parent=None): - self.builtin = builtin - self._parent = parent - - def get_doc(self): - if self.builtin: - return getattr(self.builtin, '__doc__', None) - - def get_name(self): - if self.builtin: - return getattr(self.builtin, '__name__', None) - - @property - def parent(self): - if self._parent is None: - return builtins - return self._parent - - -class BuiltinClass(_BuiltinElement, pyobjects.AbstractClass): - - def __init__(self, builtin, attributes, parent=None): - _BuiltinElement.__init__(self, builtin, parent) - pyobjects.AbstractClass.__init__(self) - self.initial = attributes - - @utils.saveit - def get_attributes(self): - result = _object_attributes(self.builtin, self) - result.update(self.initial) - return result - - -class BuiltinFunction(_BuiltinElement, pyobjects.AbstractFunction): - - def __init__(self, returned=None, function=None, builtin=None, - argnames=[], parent=None): - _BuiltinElement.__init__(self, builtin, parent) - pyobjects.AbstractFunction.__init__(self) - self.argnames = argnames - self.returned = returned - self.function = function - - def get_returned_object(self, args): - if self.function is not None: - return self.function(_CallContext(self.argnames, args)) - else: - return self.returned - - def get_param_names(self, special_args=True): - return self.argnames - - -class BuiltinUnknown(_BuiltinElement, pyobjects.PyObject): - - def __init__(self, builtin): - super(BuiltinUnknown, self).__init__(pyobjects.get_unknown()) - self.builtin = builtin - self.type = pyobjects.get_unknown() - - def get_name(self): - return getattr(type(self.builtin), '__name__', None) - - @utils.saveit - def get_attributes(self): - return _object_attributes(self.builtin, self) - - -def _object_attributes(obj, parent): - attributes = {} - for name in dir(obj): - if name == 'None': - continue - child = getattr(obj, name) - pyobject = None - if inspect.isclass(child): - pyobject = BuiltinClass(child, {}, parent=parent) - elif inspect.isroutine(child): - pyobject = BuiltinFunction(builtin=child, parent=parent) - else: - pyobject = BuiltinUnknown(builtin=child) - attributes[name] = BuiltinName(pyobject) - return attributes - - -def _create_builtin_type_getter(cls): - def _get_builtin(*args): - if not hasattr(cls, '_generated'): - cls._generated = {} - if args not in cls._generated: - cls._generated[args] = cls(*args) - return cls._generated[args] - return _get_builtin - -def _create_builtin_getter(cls): - type_getter = _create_builtin_type_getter(cls) - def _get_builtin(*args): - return pyobjects.PyObject(type_getter(*args)) - return _get_builtin - - -class _CallContext(object): - - def __init__(self, argnames, args): - self.argnames = argnames - self.args = args - - def _get_scope_and_pyname(self, pyname): - if pyname is not None and isinstance(pyname, pynames.AssignedName): - pymodule, lineno = pyname.get_definition_location() - if pymodule is None: - return None, None - if lineno is None: - lineno = 1 - scope = pymodule.get_scope().get_inner_scope_for_line(lineno) - name = None - while name is None and scope is not None: - for current in scope.get_names(): - if scope[current] is pyname: - name = current - break - else: - scope = scope.parent - return scope, name - return None, None - - def get_argument(self, name): - if self.args: - args = self.args.get_arguments(self.argnames) - return args[self.argnames.index(name)] - - def get_pyname(self, name): - if self.args: - args = self.args.get_pynames(self.argnames) - if name in self.argnames: - return args[self.argnames.index(name)] - - def get_arguments(self, argnames): - if self.args: - return self.args.get_arguments(argnames) - - def get_pynames(self, argnames): - if self.args: - return self.args.get_pynames(argnames) - - def get_per_name(self): - if self.args is None: - return None - pyname = self.args.get_instance_pyname() - scope, name = self._get_scope_and_pyname(pyname) - if name is not None: - pymodule = pyname.get_definition_location()[0] - return pymodule.pycore.object_info.get_per_name(scope, name) - return None - - def save_per_name(self, value): - if self.args is None: - return None - pyname = self.args.get_instance_pyname() - scope, name = self._get_scope_and_pyname(pyname) - if name is not None: - pymodule = pyname.get_definition_location()[0] - pymodule.pycore.object_info.save_per_name(scope, name, value) - - -class _AttributeCollector(object): - - def __init__(self, type): - self.attributes = {} - self.type = type - - def __call__(self, name, returned=None, function=None, - argnames=['self'], check_existence=True): - try: - builtin = getattr(self.type, name) - except AttributeError: - if check_existence: - raise - builtin=None - self.attributes[name] = BuiltinName( - BuiltinFunction(returned=returned, function=function, - argnames=argnames, builtin=builtin)) - - def __setitem__(self, name, value): - self.attributes[name] = value - - -class List(BuiltinClass): - - def __init__(self, holding=None): - self.holding = holding - collector = _AttributeCollector(list) - - collector('__iter__', function=self._iterator_get) - collector('__new__', function=self._new_list) - - # Adding methods - collector('append', function=self._list_add, argnames=['self', 'value']) - collector('__setitem__', function=self._list_add, - argnames=['self', 'index', 'value']) - collector('insert', function=self._list_add, - argnames=['self', 'index', 'value']) - collector('extend', function=self._self_set, - argnames=['self', 'iterable']) - - # Getting methods - collector('__getitem__', function=self._list_get) - collector('pop', function=self._list_get) - collector('__getslice__', function=self._self_get) - - super(List, self).__init__(list, collector.attributes) - - def _new_list(self, args): - return _create_builtin(args, get_list) - - def _list_add(self, context): - if self.holding is not None: - return - holding = context.get_argument('value') - if holding is not None and holding != pyobjects.get_unknown(): - context.save_per_name(holding) - - def _self_set(self, context): - if self.holding is not None: - return - iterable = context.get_pyname('iterable') - holding = _infer_sequence_for_pyname(iterable) - if holding is not None and holding != pyobjects.get_unknown(): - context.save_per_name(holding) - - def _list_get(self, context): - if self.holding is not None: - return self.holding - return context.get_per_name() - - def _iterator_get(self, context): - return get_iterator(self._list_get(context)) - - def _self_get(self, context): - return get_list(self._list_get(context)) - - -get_list = _create_builtin_getter(List) -get_list_type = _create_builtin_type_getter(List) - - -class Dict(BuiltinClass): - - def __init__(self, keys=None, values=None): - self.keys = keys - self.values = values - item = get_tuple(self.keys, self.values) - collector = _AttributeCollector(dict) - collector('__new__', function=self._new_dict) - collector('__setitem__', function=self._dict_add) - collector('popitem', function=self._item_get) - collector('pop', function=self._value_get) - collector('get', function=self._key_get) - collector('keys', function=self._key_list) - collector('values', function=self._value_list) - collector('items', function=self._item_list) - collector('copy', function=self._self_get) - collector('__getitem__', function=self._value_get) - collector('__iter__', function=self._key_iter) - collector('update', function=self._self_set) - super(Dict, self).__init__(dict, collector.attributes) - - def _new_dict(self, args): - def do_create(holding=None): - if holding is None: - return get_dict() - type = holding.get_type() - if isinstance(type, Tuple) and len(type.get_holding_objects()) == 2: - return get_dict(*type.get_holding_objects()) - return _create_builtin(args, do_create) - - def _dict_add(self, context): - if self.keys is not None: - return - key, value = context.get_arguments(['self', 'key', 'value'])[1:] - if key is not None and key != pyobjects.get_unknown(): - context.save_per_name(get_tuple(key, value)) - - def _item_get(self, context): - if self.keys is not None: - return get_tuple(self.keys, self.values) - item = context.get_per_name() - if item is None or not isinstance(item.get_type(), Tuple): - return get_tuple(self.keys, self.values) - return item - - def _value_get(self, context): - item = self._item_get(context).get_type() - return item.get_holding_objects()[1] - - def _key_get(self, context): - item = self._item_get(context).get_type() - return item.get_holding_objects()[0] - - def _value_list(self, context): - return get_list(self._value_get(context)) - - def _key_list(self, context): - return get_list(self._key_get(context)) - - def _item_list(self, context): - return get_list(self._item_get(context)) - - def _value_iter(self, context): - return get_iterator(self._value_get(context)) - - def _key_iter(self, context): - return get_iterator(self._key_get(context)) - - def _item_iter(self, context): - return get_iterator(self._item_get(context)) - - def _self_get(self, context): - item = self._item_get(context).get_type() - key, value = item.get_holding_objects()[:2] - return get_dict(key, value) - - def _self_set(self, context): - if self.keys is not None: - return - new_dict = context.get_pynames(['self', 'd'])[1] - if new_dict and isinstance(new_dict.get_object().get_type(), Dict): - args = arguments.ObjectArguments([new_dict]) - items = new_dict.get_object()['popitem'].\ - get_object().get_returned_object(args) - context.save_per_name(items) - else: - holding = _infer_sequence_for_pyname(new_dict) - if holding is not None and isinstance(holding.get_type(), Tuple): - context.save_per_name(holding) - - -get_dict = _create_builtin_getter(Dict) -get_dict_type = _create_builtin_type_getter(Dict) - - -class Tuple(BuiltinClass): - - def __init__(self, *objects): - self.objects = objects - first = None - if objects: - first = objects[0] - attributes = { - '__getitem__': BuiltinName(BuiltinFunction(first)), - '__getslice__': BuiltinName(BuiltinFunction(pyobjects.PyObject(self))), - '__new__': BuiltinName(BuiltinFunction(function=self._new_tuple)), - '__iter__': BuiltinName(BuiltinFunction(get_iterator(first)))} - super(Tuple, self).__init__(tuple, attributes) - - def get_holding_objects(self): - return self.objects - - def _new_tuple(self, args): - return _create_builtin(args, get_tuple) - - -get_tuple = _create_builtin_getter(Tuple) -get_tuple_type = _create_builtin_type_getter(Tuple) - - -class Set(BuiltinClass): - - def __init__(self, holding=None): - self.holding = holding - collector = _AttributeCollector(set) - collector('__new__', function=self._new_set) - - self_methods = ['copy', 'difference', 'intersection', - 'symmetric_difference', 'union'] - for method in self_methods: - collector(method, function=self._self_get) - collector('add', function=self._set_add) - collector('update', function=self._self_set) - collector('update', function=self._self_set) - collector('symmetric_difference_update', function=self._self_set) - collector('difference_update', function=self._self_set) - - collector('pop', function=self._set_get) - collector('__iter__', function=self._iterator_get) - super(Set, self).__init__(set, collector.attributes) - - def _new_set(self, args): - return _create_builtin(args, get_set) - - def _set_add(self, context): - if self.holding is not None: - return - holding = context.get_arguments(['self', 'value'])[1] - if holding is not None and holding != pyobjects.get_unknown(): - context.save_per_name(holding) - - def _self_set(self, context): - if self.holding is not None: - return - iterable = context.get_pyname('iterable') - holding = _infer_sequence_for_pyname(iterable) - if holding is not None and holding != pyobjects.get_unknown(): - context.save_per_name(holding) - - def _set_get(self, context): - if self.holding is not None: - return self.holding - return context.get_per_name() - - def _iterator_get(self, context): - return get_iterator(self._set_get(context)) - - def _self_get(self, context): - return get_list(self._set_get(context)) - - -get_set = _create_builtin_getter(Set) -get_set_type = _create_builtin_type_getter(Set) - - -class Str(BuiltinClass): - - def __init__(self): - self_object = pyobjects.PyObject(self) - collector = _AttributeCollector(str) - collector('__iter__', get_iterator(self_object), check_existence=False) - - self_methods = ['__getitem__', '__getslice__', 'capitalize', 'center', - 'decode', 'encode', 'expandtabs', 'join', 'ljust', - 'lower', 'lstrip', 'replace', 'rjust', 'rstrip', 'strip', - 'swapcase', 'title', 'translate', 'upper', 'zfill'] - for method in self_methods: - collector(method, self_object) - - for method in ['rsplit', 'split', 'splitlines']: - collector(method, get_list(self_object)) - - super(Str, self).__init__(str, collector.attributes) - - def get_doc(self): - return str.__doc__ - - -get_str = _create_builtin_getter(Str) -get_str_type = _create_builtin_type_getter(Str) - - -class BuiltinName(pynames.PyName): - - def __init__(self, pyobject): - self.pyobject = pyobject - - def get_object(self): - return self.pyobject - - def get_definition_location(self): - return (None, None) - -class Iterator(pyobjects.AbstractClass): - - def __init__(self, holding=None): - super(Iterator, self).__init__() - self.holding = holding - self.attributes = { - 'next': BuiltinName(BuiltinFunction(self.holding)), - '__iter__': BuiltinName(BuiltinFunction(self))} - - def get_attributes(self): - return self.attributes - - def get_returned_object(self, args): - return self.holding - -get_iterator = _create_builtin_getter(Iterator) - - -class Generator(pyobjects.AbstractClass): - - def __init__(self, holding=None): - super(Generator, self).__init__() - self.holding = holding - self.attributes = { - 'next': BuiltinName(BuiltinFunction(self.holding)), - '__iter__': BuiltinName(BuiltinFunction(get_iterator(self.holding))), - 'close': BuiltinName(BuiltinFunction()), - 'send': BuiltinName(BuiltinFunction()), - 'throw': BuiltinName(BuiltinFunction())} - - def get_attributes(self): - return self.attributes - - def get_returned_object(self, args): - return self.holding - -get_generator = _create_builtin_getter(Generator) - - -class File(BuiltinClass): - - def __init__(self): - self_object = pyobjects.PyObject(self) - str_object = get_str() - str_list = get_list(get_str()) - attributes = {} - def add(name, returned=None, function=None): - builtin = getattr(file, name, None) - attributes[name] = BuiltinName( - BuiltinFunction(returned=returned, function=function, - builtin=builtin)) - add('__iter__', get_iterator(str_object)) - for method in ['next', 'read', 'readline', 'readlines']: - add(method, str_list) - for method in ['close', 'flush', 'lineno', 'isatty', 'seek', 'tell', - 'truncate', 'write', 'writelines']: - add(method) - super(File, self).__init__(file, attributes) - - -get_file = _create_builtin_getter(File) -get_file_type = _create_builtin_type_getter(File) - - -class Property(BuiltinClass): - - def __init__(self, fget=None, fset=None, fdel=None, fdoc=None): - self._fget = fget - self._fdoc = fdoc - attributes = { - 'fget': BuiltinName(BuiltinFunction()), - 'fset': BuiltinName(pynames.UnboundName()), - 'fdel': BuiltinName(pynames.UnboundName()), - '__new__': BuiltinName(BuiltinFunction(function=_property_function))} - super(Property, self).__init__(property, attributes) - - def get_property_object(self, args): - if isinstance(self._fget, pyobjects.AbstractFunction): - return self._fget.get_returned_object(args) - - -def _property_function(args): - parameters = args.get_arguments(['fget', 'fset', 'fdel', 'fdoc']) - return pyobjects.PyObject(Property(parameters[0])) - - -class Lambda(pyobjects.AbstractFunction): - - def __init__(self, node, scope): - super(Lambda, self).__init__() - self.node = node - self.arguments = node.args - self.scope = scope - - def get_returned_object(self, args): - result = rope.base.evaluate.eval_node(self.scope, self.node.body) - if result is not None: - return result.get_object() - else: - return pyobjects.get_unknown() - - def get_module(self): - return self.parent.get_module() - - def get_scope(self): - return self.scope - - def get_kind(self): - return 'lambda' - - def get_ast(self): - return self.node - - def get_attributes(self): - return {} - - def get_name(self): - return 'lambda' - - def get_param_names(self, special_args=True): - result = [node.id for node in self.arguments.args - if isinstance(node, ast.Name)] - if self.arguments.vararg: - result.append('*' + self.arguments.vararg) - if self.arguments.kwarg: - result.append('**' + self.arguments.kwarg) - return result - - @property - def parent(self): - return self.scope.pyobject - - -class BuiltinObject(BuiltinClass): - - def __init__(self): - super(BuiltinObject, self).__init__(object, {}) - - -class BuiltinType(BuiltinClass): - - def __init__(self): - super(BuiltinType, self).__init__(type, {}) - - -def _infer_sequence_for_pyname(pyname): - if pyname is None: - return None - seq = pyname.get_object() - args = arguments.ObjectArguments([pyname]) - if '__iter__' in seq: - obj = seq['__iter__'].get_object() - if not isinstance(obj, pyobjects.AbstractFunction): - return None - iter = obj.get_returned_object(args) - if iter is not None and 'next' in iter: - holding = iter['next'].get_object().\ - get_returned_object(args) - return holding - - -def _create_builtin(args, creator): - passed = args.get_pynames(['sequence'])[0] - if passed is None: - holding = None - else: - holding = _infer_sequence_for_pyname(passed) - if holding is not None: - return creator(holding) - else: - return creator() - - -def _range_function(args): - return get_list() - -def _reversed_function(args): - return _create_builtin(args, get_iterator) - -def _sorted_function(args): - return _create_builtin(args, get_list) - -def _super_function(args): - passed_class, passed_self = args.get_arguments(['type', 'self']) - if passed_self is None: - return passed_class - else: - #pyclass = passed_self.get_type() - pyclass = passed_class - if isinstance(pyclass, pyobjects.AbstractClass): - supers = pyclass.get_superclasses() - if supers: - return pyobjects.PyObject(supers[0]) - return passed_self - -def _zip_function(args): - args = args.get_pynames(['sequence']) - objects = [] - for seq in args: - if seq is None: - holding = None - else: - holding = _infer_sequence_for_pyname(seq) - objects.append(holding) - tuple = get_tuple(*objects) - return get_list(tuple) - -def _enumerate_function(args): - passed = args.get_pynames(['sequence'])[0] - if passed is None: - holding = None - else: - holding = _infer_sequence_for_pyname(passed) - tuple = get_tuple(None, holding) - return get_iterator(tuple) - -def _iter_function(args): - passed = args.get_pynames(['sequence'])[0] - if passed is None: - holding = None - else: - holding = _infer_sequence_for_pyname(passed) - return get_iterator(holding) - -def _input_function(args): - return get_str() - - -_initial_builtins = { - 'list': BuiltinName(get_list_type()), - 'dict': BuiltinName(get_dict_type()), - 'tuple': BuiltinName(get_tuple_type()), - 'set': BuiltinName(get_set_type()), - 'str': BuiltinName(get_str_type()), - 'file': BuiltinName(get_file_type()), - 'open': BuiltinName(get_file_type()), - 'unicode': BuiltinName(get_str_type()), - 'range': BuiltinName(BuiltinFunction(function=_range_function, builtin=range)), - 'reversed': BuiltinName(BuiltinFunction(function=_reversed_function, builtin=reversed)), - 'sorted': BuiltinName(BuiltinFunction(function=_sorted_function, builtin=sorted)), - 'super': BuiltinName(BuiltinFunction(function=_super_function, builtin=super)), - 'property': BuiltinName(BuiltinFunction(function=_property_function, builtin=property)), - 'zip': BuiltinName(BuiltinFunction(function=_zip_function, builtin=zip)), - 'enumerate': BuiltinName(BuiltinFunction(function=_enumerate_function, builtin=enumerate)), - 'object': BuiltinName(BuiltinObject()), - 'type': BuiltinName(BuiltinType()), - 'iter': BuiltinName(BuiltinFunction(function=_iter_function, builtin=iter)), - 'raw_input': BuiltinName(BuiltinFunction(function=_input_function, builtin=raw_input)), - } - -builtins = BuiltinModule('__builtin__', initial=_initial_builtins) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/change.py --- a/vim/sadness/ropevim/src/rope/rope/base/change.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,448 +0,0 @@ -import datetime -import difflib -import os -import time -import warnings - -import rope.base.fscommands -from rope.base import taskhandle, exceptions, utils - - -class Change(object): - """The base class for changes - - Rope refactorings return `Change` objects. They can be previewed, - committed or undone. - """ - - def do(self, job_set=None): - """Perform the change - - .. note:: Do use this directly. Use `Project.do()` instead. - """ - - def undo(self, job_set=None): - """Perform the change - - .. note:: Do use this directly. Use `History.undo()` instead. - """ - - def get_description(self): - """Return the description of this change - - This can be used for previewing the changes. - """ - return str(self) - - def get_changed_resources(self): - """Return the list of resources that will be changed""" - return [] - - @property - @utils.saveit - def _operations(self): - return _ResourceOperations(self.resource.project) - - -class ChangeSet(Change): - """A collection of `Change` objects - - This class holds a collection of changes. This class provides - these fields: - - * `changes`: the list of changes - * `description`: the goal of these changes - """ - - def __init__(self, description, timestamp=None): - self.changes = [] - self.description = description - self.time = timestamp - - def do(self, job_set=taskhandle.NullJobSet()): - try: - done = [] - for change in self.changes: - change.do(job_set) - done.append(change) - self.time = time.time() - except Exception: - for change in done: - change.undo() - raise - - def undo(self, job_set=taskhandle.NullJobSet()): - try: - done = [] - for change in reversed(self.changes): - change.undo(job_set) - done.append(change) - except Exception: - for change in done: - change.do() - raise - - def add_change(self, change): - self.changes.append(change) - - def get_description(self): - result = [str(self) + ':\n\n\n'] - for change in self.changes: - result.append(change.get_description()) - result.append('\n') - return ''.join(result) - - def __str__(self): - if self.time is not None: - date = datetime.datetime.fromtimestamp(self.time) - if date.date() == datetime.date.today(): - string_date = 'today' - elif date.date() == (datetime.date.today() - datetime.timedelta(1)): - string_date = 'yesterday' - elif date.year == datetime.date.today().year: - string_date = date.strftime('%b %d') - else: - string_date = date.strftime('%d %b, %Y') - string_time = date.strftime('%H:%M:%S') - string_time = '%s %s ' % (string_date, string_time) - return self.description + ' - ' + string_time - return self.description - - def get_changed_resources(self): - result = set() - for change in self.changes: - result.update(change.get_changed_resources()) - return result - - -def _handle_job_set(function): - """A decorator for handling `taskhandle.JobSet`\s - - A decorator for handling `taskhandle.JobSet`\s for `do` and `undo` - methods of `Change`\s. - """ - def call(self, job_set=taskhandle.NullJobSet()): - job_set.started_job(str(self)) - function(self) - job_set.finished_job() - return call - - -class ChangeContents(Change): - """A class to change the contents of a file - - Fields: - - * `resource`: The `rope.base.resources.File` to change - * `new_contents`: What to write in the file - """ - - def __init__(self, resource, new_contents, old_contents=None): - self.resource = resource - # IDEA: Only saving diffs; possible problems when undo/redoing - self.new_contents = new_contents - self.old_contents = old_contents - - @_handle_job_set - def do(self): - if self.old_contents is None: - self.old_contents = self.resource.read() - self._operations.write_file(self.resource, self.new_contents) - - @_handle_job_set - def undo(self): - if self.old_contents is None: - raise exceptions.HistoryError( - 'Undoing a change that is not performed yet!') - self._operations.write_file(self.resource, self.old_contents) - - def __str__(self): - return 'Change <%s>' % self.resource.path - - def get_description(self): - new = self.new_contents - old = self.old_contents - if old is None: - if self.resource.exists(): - old = self.resource.read() - else: - old = '' - result = difflib.unified_diff( - old.splitlines(True), new.splitlines(True), - 'a/' + self.resource.path, 'b/' + self.resource.path) - return ''.join(list(result)) - - def get_changed_resources(self): - return [self.resource] - - -class MoveResource(Change): - """Move a resource to a new location - - Fields: - - * `resource`: The `rope.base.resources.Resource` to move - * `new_resource`: The destination for move; It is the moved - resource not the folder containing that resource. - """ - - def __init__(self, resource, new_location, exact=False): - self.project = resource.project - self.resource = resource - if not exact: - new_location = _get_destination_for_move(resource, new_location) - if resource.is_folder(): - self.new_resource = self.project.get_folder(new_location) - else: - self.new_resource = self.project.get_file(new_location) - - @_handle_job_set - def do(self): - self._operations.move(self.resource, self.new_resource) - - @_handle_job_set - def undo(self): - self._operations.move(self.new_resource, self.resource) - - def __str__(self): - return 'Move <%s>' % self.resource.path - - def get_description(self): - return 'rename from %s\nrename to %s' % (self.resource.path, - self.new_resource.path) - - def get_changed_resources(self): - return [self.resource, self.new_resource] - - -class CreateResource(Change): - """A class to create a resource - - Fields: - - * `resource`: The resource to create - """ - - def __init__(self, resource): - self.resource = resource - - @_handle_job_set - def do(self): - self._operations.create(self.resource) - - @_handle_job_set - def undo(self): - self._operations.remove(self.resource) - - def __str__(self): - return 'Create Resource <%s>' % (self.resource.path) - - def get_description(self): - return 'new file %s' % (self.resource.path) - - def get_changed_resources(self): - return [self.resource] - - def _get_child_path(self, parent, name): - if parent.path == '': - return name - else: - return parent.path + '/' + name - - -class CreateFolder(CreateResource): - """A class to create a folder - - See docs for `CreateResource`. - """ - - def __init__(self, parent, name): - resource = parent.project.get_folder(self._get_child_path(parent, name)) - super(CreateFolder, self).__init__(resource) - - -class CreateFile(CreateResource): - """A class to create a file - - See docs for `CreateResource`. - """ - - def __init__(self, parent, name): - resource = parent.project.get_file(self._get_child_path(parent, name)) - super(CreateFile, self).__init__(resource) - - -class RemoveResource(Change): - """A class to remove a resource - - Fields: - - * `resource`: The resource to be removed - """ - - def __init__(self, resource): - self.resource = resource - - @_handle_job_set - def do(self): - self._operations.remove(self.resource) - - # TODO: Undoing remove operations - @_handle_job_set - def undo(self): - raise NotImplementedError( - 'Undoing `RemoveResource` is not implemented yet.') - - def __str__(self): - return 'Remove <%s>' % (self.resource.path) - - def get_changed_resources(self): - return [self.resource] - - -def count_changes(change): - """Counts the number of basic changes a `Change` will make""" - if isinstance(change, ChangeSet): - result = 0 - for child in change.changes: - result += count_changes(child) - return result - return 1 - -def create_job_set(task_handle, change): - return task_handle.create_jobset(str(change), count_changes(change)) - - -class _ResourceOperations(object): - - def __init__(self, project): - self.project = project - self.fscommands = project.fscommands - self.direct_commands = rope.base.fscommands.FileSystemCommands() - - def _get_fscommands(self, resource): - if self.project.is_ignored(resource): - return self.direct_commands - return self.fscommands - - def write_file(self, resource, contents): - data = rope.base.fscommands.unicode_to_file_data(contents) - fscommands = self._get_fscommands(resource) - fscommands.write(resource.real_path, data) - for observer in list(self.project.observers): - observer.resource_changed(resource) - - def move(self, resource, new_resource): - fscommands = self._get_fscommands(resource) - fscommands.move(resource.real_path, new_resource.real_path) - for observer in list(self.project.observers): - observer.resource_moved(resource, new_resource) - - def create(self, resource): - if resource.is_folder(): - self._create_resource(resource.path, kind='folder') - else: - self._create_resource(resource.path) - for observer in list(self.project.observers): - observer.resource_created(resource) - - def remove(self, resource): - fscommands = self._get_fscommands(resource) - fscommands.remove(resource.real_path) - for observer in list(self.project.observers): - observer.resource_removed(resource) - - def _create_resource(self, file_name, kind='file'): - resource_path = self.project._get_resource_path(file_name) - if os.path.exists(resource_path): - raise exceptions.RopeError('Resource <%s> already exists' - % resource_path) - resource = self.project.get_file(file_name) - if not resource.parent.exists(): - raise exceptions.ResourceNotFoundError( - 'Parent folder of <%s> does not exist' % resource.path) - fscommands = self._get_fscommands(resource) - try: - if kind == 'file': - fscommands.create_file(resource_path) - else: - fscommands.create_folder(resource_path) - except IOError, e: - raise exceptions.RopeError(e) - - -def _get_destination_for_move(resource, destination): - dest_path = resource.project._get_resource_path(destination) - if os.path.isdir(dest_path): - if destination != '': - return destination + '/' + resource.name - else: - return resource.name - return destination - - -class ChangeToData(object): - - def convertChangeSet(self, change): - description = change.description - changes = [] - for child in change.changes: - changes.append(self(child)) - return (description, changes, change.time) - - def convertChangeContents(self, change): - return (change.resource.path, change.new_contents, change.old_contents) - - def convertMoveResource(self, change): - return (change.resource.path, change.new_resource.path) - - def convertCreateResource(self, change): - return (change.resource.path, change.resource.is_folder()) - - def convertRemoveResource(self, change): - return (change.resource.path, change.resource.is_folder()) - - def __call__(self, change): - change_type = type(change) - if change_type in (CreateFolder, CreateFile): - change_type = CreateResource - method = getattr(self, 'convert' + change_type.__name__) - return (change_type.__name__, method(change)) - - -class DataToChange(object): - - def __init__(self, project): - self.project = project - - def makeChangeSet(self, description, changes, time=None): - result = ChangeSet(description, time) - for child in changes: - result.add_change(self(child)) - return result - - def makeChangeContents(self, path, new_contents, old_contents): - resource = self.project.get_file(path) - return ChangeContents(resource, new_contents, old_contents) - - def makeMoveResource(self, old_path, new_path): - resource = self.project.get_file(old_path) - return MoveResource(resource, new_path, exact=True) - - def makeCreateResource(self, path, is_folder): - if is_folder: - resource = self.project.get_folder(path) - else: - resource = self.project.get_file(path) - return CreateResource(resource) - - def makeRemoveResource(self, path, is_folder): - if is_folder: - resource = self.project.get_folder(path) - else: - resource = self.project.get_file(path) - return RemoveResource(resource) - - def __call__(self, data): - method = getattr(self, 'make' + data[0]) - return method(*data[1]) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/codeanalyze.py --- a/vim/sadness/ropevim/src/rope/rope/base/codeanalyze.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,358 +0,0 @@ -import bisect -import re -import token -import tokenize - - -class ChangeCollector(object): - - def __init__(self, text): - self.text = text - self.changes = [] - - def add_change(self, start, end, new_text=None): - if new_text is None: - new_text = self.text[start:end] - self.changes.append((start, end, new_text)) - - def get_changed(self): - if not self.changes: - return None - def compare_changes(change1, change2): - return cmp(change1[:2], change2[:2]) - self.changes.sort(compare_changes) - pieces = [] - last_changed = 0 - for change in self.changes: - start, end, text = change - pieces.append(self.text[last_changed:start] + text) - last_changed = end - if last_changed < len(self.text): - pieces.append(self.text[last_changed:]) - result = ''.join(pieces) - if result != self.text: - return result - - -class SourceLinesAdapter(object): - """Adapts source to Lines interface - - Note: The creation of this class is expensive. - """ - - def __init__(self, source_code): - self.code = source_code - self.starts = None - self._initialize_line_starts() - - def _initialize_line_starts(self): - self.starts = [] - self.starts.append(0) - try: - i = 0 - while True: - i = self.code.index('\n', i) + 1 - self.starts.append(i) - except ValueError: - pass - self.starts.append(len(self.code) + 1) - - def get_line(self, lineno): - return self.code[self.starts[lineno - 1]: - self.starts[lineno] - 1] - - def length(self): - return len(self.starts) - 1 - - def get_line_number(self, offset): - return bisect.bisect(self.starts, offset) - - def get_line_start(self, lineno): - return self.starts[lineno - 1] - - def get_line_end(self, lineno): - return self.starts[lineno] - 1 - - -class ArrayLinesAdapter(object): - - def __init__(self, lines): - self.lines = lines - - def get_line(self, line_number): - return self.lines[line_number - 1] - - def length(self): - return len(self.lines) - - -class LinesToReadline(object): - - def __init__(self, lines, start): - self.lines = lines - self.current = start - - def readline(self): - if self.current <= self.lines.length(): - self.current += 1 - return self.lines.get_line(self.current - 1) + '\n' - return '' - - def __call__(self): - return self.readline() - - -class _CustomGenerator(object): - - def __init__(self, lines): - self.lines = lines - self.in_string = '' - self.open_count = 0 - self.continuation = False - - def __call__(self): - size = self.lines.length() - result = [] - i = 1 - while i <= size: - while i <= size and not self.lines.get_line(i).strip(): - i += 1 - if i <= size: - start = i - while True: - line = self.lines.get_line(i) - self._analyze_line(line) - if not (self.continuation or self.open_count or - self.in_string) or i == size: - break - i += 1 - result.append((start, i)) - i += 1 - return result - - _main_chars = re.compile(r'[\'|"|#|\\|\[|\]|\{|\}|\(|\)]') - def _analyze_line(self, line): - char = None - for match in self._main_chars.finditer(line): - char = match.group() - i = match.start() - if char in '\'"': - if not self.in_string: - self.in_string = char - if char * 3 == line[i:i + 3]: - self.in_string = char * 3 - elif self.in_string == line[i:i + len(self.in_string)] and \ - not (i > 0 and line[i - 1] == '\\' and - not (i > 1 and line[i - 2] == '\\')): - self.in_string = '' - if self.in_string: - continue - if char == '#': - break - if char in '([{': - self.open_count += 1 - elif char in ')]}': - self.open_count -= 1 - if line and char != '#' and line.endswith('\\'): - self.continuation = True - else: - self.continuation = False - -def custom_generator(lines): - return _CustomGenerator(lines)() - - -class LogicalLineFinder(object): - - def __init__(self, lines): - self.lines = lines - - def logical_line_in(self, line_number): - indents = count_line_indents(self.lines.get_line(line_number)) - tries = 0 - while True: - block_start = get_block_start(self.lines, line_number, indents) - try: - return self._block_logical_line(block_start, line_number) - except IndentationError, e: - tries += 1 - if tries == 5: - raise e - lineno = e.lineno + block_start - 1 - indents = count_line_indents(self.lines.get_line(lineno)) - - def generate_starts(self, start_line=1, end_line=None): - for start, end in self.generate_regions(start_line, end_line): - yield start - - def generate_regions(self, start_line=1, end_line=None): - # XXX: `block_start` should be at a better position! - block_start = 1 - readline = LinesToReadline(self.lines, block_start) - shifted = start_line - block_start + 1 - try: - for start, end in self._logical_lines(readline): - real_start = start + block_start - 1 - real_start = self._first_non_blank(real_start) - if end_line is not None and real_start >= end_line: - break - real_end = end + block_start - 1 - if real_start >= start_line: - yield (real_start, real_end) - except tokenize.TokenError, e: - pass - - def _block_logical_line(self, block_start, line_number): - readline = LinesToReadline(self.lines, block_start) - shifted = line_number - block_start + 1 - region = self._calculate_logical(readline, shifted) - start = self._first_non_blank(region[0] + block_start - 1) - if region[1] is None: - end = self.lines.length() - else: - end = region[1] + block_start - 1 - return start, end - - def _calculate_logical(self, readline, line_number): - last_end = 1 - try: - for start, end in self._logical_lines(readline): - if line_number <= end: - return (start, end) - last_end = end + 1 - except tokenize.TokenError, e: - current = e.args[1][0] - return (last_end, max(last_end, current - 1)) - return (last_end, None) - - def _logical_lines(self, readline): - last_end = 1 - for current_token in tokenize.generate_tokens(readline): - current = current_token[2][0] - if current_token[0] == token.NEWLINE: - yield (last_end, current) - last_end = current + 1 - - def _first_non_blank(self, line_number): - current = line_number - while current < self.lines.length(): - line = self.lines.get_line(current).strip() - if line and not line.startswith('#'): - return current - current += 1 - return current - - -def tokenizer_generator(lines): - return LogicalLineFinder(lines).generate_regions() - - -class CachingLogicalLineFinder(object): - - def __init__(self, lines, generate=custom_generator): - self.lines = lines - self._generate = generate - - _starts = None - @property - def starts(self): - if self._starts is None: - self._init_logicals() - return self._starts - - _ends = None - @property - def ends(self): - if self._ends is None: - self._init_logicals() - return self._ends - - def _init_logicals(self): - """Should initialize _starts and _ends attributes""" - size = self.lines.length() + 1 - self._starts = [None] * size - self._ends = [None] * size - for start, end in self._generate(self.lines): - self._starts[start] = True - self._ends[end] = True - - def logical_line_in(self, line_number): - start = line_number - while start > 0 and not self.starts[start]: - start -= 1 - if start == 0: - try: - start = self.starts.index(True, line_number) - except ValueError: - return (line_number, line_number) - return (start, self.ends.index(True, start)) - - def generate_starts(self, start_line=1, end_line=None): - if end_line is None: - end_line = self.lines.length() - for index in range(start_line, end_line): - if self.starts[index]: - yield index - - -def get_block_start(lines, lineno, maximum_indents=80): - """Approximate block start""" - pattern = get_block_start_patterns() - for i in range(lineno, 0, -1): - match = pattern.search(lines.get_line(i)) - if match is not None and \ - count_line_indents(lines.get_line(i)) <= maximum_indents: - striped = match.string.lstrip() - # Maybe we're in a list comprehension or generator expression - if i > 1 and striped.startswith('if') or striped.startswith('for'): - bracs = 0 - for j in range(i, min(i + 5, lines.length() + 1)): - for c in lines.get_line(j): - if c == '#': - break - if c in '[(': - bracs += 1 - if c in ')]': - bracs -= 1 - if bracs < 0: - break - if bracs < 0: - break - if bracs < 0: - continue - return i - return 1 - - -_block_start_pattern = None - -def get_block_start_patterns(): - global _block_start_pattern - if not _block_start_pattern: - pattern = '^\\s*(((def|class|if|elif|except|for|while|with)\\s)|'\ - '((try|else|finally|except)\\s*:))' - _block_start_pattern = re.compile(pattern, re.M) - return _block_start_pattern - - -def count_line_indents(line): - indents = 0 - for char in line: - if char == ' ': - indents += 1 - elif char == '\t': - indents += 8 - else: - return indents - return 0 - - -def get_string_pattern(): - start = r'(\b[uU]?[rR]?)?' - longstr = r'%s"""(\\.|"(?!"")|\\\n|[^"\\])*"""' % start - shortstr = r'%s"(\\.|[^"\\\n])*"' % start - return '|'.join([longstr, longstr.replace('"', "'"), - shortstr, shortstr.replace('"', "'")]) - -def get_comment_pattern(): - return r'#[^\n]*' diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/default_config.py --- a/vim/sadness/ropevim/src/rope/rope/base/default_config.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -# The default ``config.py`` - - -def set_prefs(prefs): - """This function is called before opening the project""" - - # Specify which files and folders to ignore in the project. - # Changes to ignored resources are not added to the history and - # VCSs. Also they are not returned in `Project.get_files()`. - # Note that ``?`` and ``*`` match all characters but slashes. - # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' - # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' - # '.svn': matches 'pkg/.svn' and all of its children - # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' - # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' - prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', - '.hg', '.svn', '_svn', '.git'] - - # Specifies which files should be considered python files. It is - # useful when you have scripts inside your project. Only files - # ending with ``.py`` are considered to be python files by - # default. - #prefs['python_files'] = ['*.py'] - - # Custom source folders: By default rope searches the project - # for finding source folders (folders that should be searched - # for finding modules). You can add paths to that list. Note - # that rope guesses project source folders correctly most of the - # time; use this if you have any problems. - # The folders should be relative to project root and use '/' for - # separating folders regardless of the platform rope is running on. - # 'src/my_source_folder' for instance. - #prefs.add('source_folders', 'src') - - # You can extend python path for looking up modules - #prefs.add('python_path', '~/python/') - - # Should rope save object information or not. - prefs['save_objectdb'] = True - prefs['compress_objectdb'] = False - - # If `True`, rope analyzes each module when it is being saved. - prefs['automatic_soa'] = True - # The depth of calls to follow in static object analysis - prefs['soa_followed_calls'] = 0 - - # If `False` when running modules or unit tests "dynamic object - # analysis" is turned off. This makes them much faster. - prefs['perform_doa'] = True - - # Rope can check the validity of its object DB when running. - prefs['validate_objectdb'] = True - - # How many undos to hold? - prefs['max_history_items'] = 32 - - # Shows whether to save history across sessions. - prefs['save_history'] = True - prefs['compress_history'] = False - - # Set the number spaces used for indenting. According to - # :PEP:`8`, it is best to use 4 spaces. Since most of rope's - # unit-tests use 4 spaces it is more reliable, too. - prefs['indent_size'] = 4 - - # Builtin and c-extension modules that are allowed to be imported - # and inspected by rope. - prefs['extension_modules'] = [] - - # Add all standard c-extensions to extension_modules list. - prefs['import_dynload_stdmods'] = True - - # If `True` modules with syntax errors are considered to be empty. - # The default value is `False`; When `False` syntax errors raise - # `rope.base.exceptions.ModuleSyntaxError` exception. - prefs['ignore_syntax_errors'] = False - - # If `True`, rope ignores unresolvable imports. Otherwise, they - # appear in the importing namespace. - prefs['ignore_bad_imports'] = False - - -def project_opened(project): - """This function is called after opening the project""" - # Do whatever you like here! diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/evaluate.py --- a/vim/sadness/ropevim/src/rope/rope/base/evaluate.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,321 +0,0 @@ -import rope.base.builtins -import rope.base.pynames -import rope.base.pyobjects -from rope.base import ast, astutils, exceptions, pyobjects, arguments, worder - - -BadIdentifierError = exceptions.BadIdentifierError - -def eval_location(pymodule, offset): - """Find the pyname at the offset""" - return eval_location2(pymodule, offset)[1] - - -def eval_location2(pymodule, offset): - """Find the primary and pyname at offset""" - pyname_finder = ScopeNameFinder(pymodule) - return pyname_finder.get_primary_and_pyname_at(offset) - - -def eval_node(scope, node): - """Evaluate a `ast.AST` node and return a PyName - - Return `None` if the expression cannot be evaluated. - """ - return eval_node2(scope, node)[1] - - -def eval_node2(scope, node): - evaluator = StatementEvaluator(scope) - ast.walk(node, evaluator) - return evaluator.old_result, evaluator.result - - -def eval_str(holding_scope, name): - return eval_str2(holding_scope, name)[1] - - -def eval_str2(holding_scope, name): - try: - # parenthesizing for handling cases like 'a_var.\nattr' - node = ast.parse('(%s)' % name) - except SyntaxError: - raise BadIdentifierError('Not a resolvable python identifier selected.') - return eval_node2(holding_scope, node) - - -class ScopeNameFinder(object): - - def __init__(self, pymodule): - self.module_scope = pymodule.get_scope() - self.lines = pymodule.lines - self.worder = worder.Worder(pymodule.source_code, True) - - def _is_defined_in_class_body(self, holding_scope, offset, lineno): - if lineno == holding_scope.get_start() and \ - holding_scope.parent is not None and \ - holding_scope.parent.get_kind() == 'Class' and \ - self.worder.is_a_class_or_function_name_in_header(offset): - return True - if lineno != holding_scope.get_start() and \ - holding_scope.get_kind() == 'Class' and \ - self.worder.is_name_assigned_in_class_body(offset): - return True - return False - - def _is_function_name_in_function_header(self, scope, offset, lineno): - if scope.get_start() <= lineno <= scope.get_body_start() and \ - scope.get_kind() == 'Function' and \ - self.worder.is_a_class_or_function_name_in_header(offset): - return True - return False - - def get_pyname_at(self, offset): - return self.get_primary_and_pyname_at(offset)[1] - - def get_primary_and_pyname_at(self, offset): - lineno = self.lines.get_line_number(offset) - holding_scope = self.module_scope.get_inner_scope_for_line(lineno) - # function keyword parameter - if self.worder.is_function_keyword_parameter(offset): - keyword_name = self.worder.get_word_at(offset) - pyobject = self.get_enclosing_function(offset) - if isinstance(pyobject, pyobjects.PyFunction): - return (None, pyobject.get_parameters().get(keyword_name, None)) - # class body - if self._is_defined_in_class_body(holding_scope, offset, lineno): - class_scope = holding_scope - if lineno == holding_scope.get_start(): - class_scope = holding_scope.parent - name = self.worder.get_primary_at(offset).strip() - try: - return (None, class_scope.pyobject[name]) - except rope.base.exceptions.AttributeNotFoundError: - return (None, None) - # function header - if self._is_function_name_in_function_header(holding_scope, offset, lineno): - name = self.worder.get_primary_at(offset).strip() - return (None, holding_scope.parent[name]) - # from statement module - if self.worder.is_from_statement_module(offset): - module = self.worder.get_primary_at(offset) - module_pyname = self._find_module(module) - return (None, module_pyname) - if self.worder.is_from_aliased(offset): - name = self.worder.get_from_aliased(offset) - else: - name = self.worder.get_primary_at(offset) - return eval_str2(holding_scope, name) - - def get_enclosing_function(self, offset): - function_parens = self.worder.find_parens_start_from_inside(offset) - try: - function_pyname = self.get_pyname_at(function_parens - 1) - except BadIdentifierError: - function_pyname = None - if function_pyname is not None: - pyobject = function_pyname.get_object() - if isinstance(pyobject, pyobjects.AbstractFunction): - return pyobject - elif isinstance(pyobject, pyobjects.AbstractClass) and \ - '__init__' in pyobject: - return pyobject['__init__'].get_object() - elif '__call__' in pyobject: - return pyobject['__call__'].get_object() - return None - - def _find_module(self, module_name): - dots = 0 - while module_name[dots] == '.': - dots += 1 - return rope.base.pynames.ImportedModule( - self.module_scope.pyobject, module_name[dots:], dots) - - -class StatementEvaluator(object): - - def __init__(self, scope): - self.scope = scope - self.result = None - self.old_result = None - - def _Name(self, node): - self.result = self.scope.lookup(node.id) - - def _Attribute(self, node): - pyname = eval_node(self.scope, node.value) - if pyname is None: - pyname = rope.base.pynames.UnboundName() - self.old_result = pyname - if pyname.get_object() != rope.base.pyobjects.get_unknown(): - try: - self.result = pyname.get_object()[node.attr] - except exceptions.AttributeNotFoundError: - self.result = None - - def _Call(self, node): - primary, pyobject = self._get_primary_and_object_for_node(node.func) - if pyobject is None: - return - def _get_returned(pyobject): - args = arguments.create_arguments(primary, pyobject, - node, self.scope) - return pyobject.get_returned_object(args) - if isinstance(pyobject, rope.base.pyobjects.AbstractClass): - result = None - if '__new__' in pyobject: - new_function = pyobject['__new__'].get_object() - result = _get_returned(new_function) - if result is None or \ - result == rope.base.pyobjects.get_unknown(): - result = rope.base.pyobjects.PyObject(pyobject) - self.result = rope.base.pynames.UnboundName(pyobject=result) - return - - pyfunction = None - if isinstance(pyobject, rope.base.pyobjects.AbstractFunction): - pyfunction = pyobject - elif '__call__' in pyobject: - pyfunction = pyobject['__call__'].get_object() - if pyfunction is not None: - self.result = rope.base.pynames.UnboundName( - pyobject=_get_returned(pyfunction)) - - def _Str(self, node): - self.result = rope.base.pynames.UnboundName( - pyobject=rope.base.builtins.get_str()) - - def _Num(self, node): - type_name = type(node.n).__name__ - self.result = self._get_builtin_name(type_name) - - def _get_builtin_name(self, type_name): - pytype = rope.base.builtins.builtins[type_name].get_object() - return rope.base.pynames.UnboundName( - rope.base.pyobjects.PyObject(pytype)) - - def _BinOp(self, node): - self.result = rope.base.pynames.UnboundName( - self._get_object_for_node(node.left)) - - def _BoolOp(self, node): - pyobject = self._get_object_for_node(node.values[0]) - if pyobject is None: - pyobject = self._get_object_for_node(node.values[1]) - self.result = rope.base.pynames.UnboundName(pyobject) - - def _Repr(self, node): - self.result = self._get_builtin_name('str') - - def _UnaryOp(self, node): - self.result = rope.base.pynames.UnboundName( - self._get_object_for_node(node.operand)) - - def _Compare(self, node): - self.result = self._get_builtin_name('bool') - - def _Dict(self, node): - keys = None - values = None - if node.keys: - keys = self._get_object_for_node(node.keys[0]) - values = self._get_object_for_node(node.values[0]) - self.result = rope.base.pynames.UnboundName( - pyobject=rope.base.builtins.get_dict(keys, values)) - - def _List(self, node): - holding = None - if node.elts: - holding = self._get_object_for_node(node.elts[0]) - self.result = rope.base.pynames.UnboundName( - pyobject=rope.base.builtins.get_list(holding)) - - def _ListComp(self, node): - pyobject = self._what_does_comprehension_hold(node) - self.result = rope.base.pynames.UnboundName( - pyobject=rope.base.builtins.get_list(pyobject)) - - def _GeneratorExp(self, node): - pyobject = self._what_does_comprehension_hold(node) - self.result = rope.base.pynames.UnboundName( - pyobject=rope.base.builtins.get_iterator(pyobject)) - - def _what_does_comprehension_hold(self, node): - scope = self._make_comprehension_scope(node) - pyname = eval_node(scope, node.elt) - return pyname.get_object() if pyname is not None else None - - def _make_comprehension_scope(self, node): - scope = self.scope - module = scope.pyobject.get_module() - names = {} - for comp in node.generators: - new_names = _get_evaluated_names(comp.target, comp.iter, module, - '.__iter__().next()', node.lineno) - names.update(new_names) - return rope.base.pyscopes.TemporaryScope(scope.pycore, scope, names) - - def _Tuple(self, node): - objects = [] - if len(node.elts) < 4: - for stmt in node.elts: - pyobject = self._get_object_for_node(stmt) - objects.append(pyobject) - else: - objects.append(self._get_object_for_node(node.elts[0])) - self.result = rope.base.pynames.UnboundName( - pyobject=rope.base.builtins.get_tuple(*objects)) - - def _get_object_for_node(self, stmt): - pyname = eval_node(self.scope, stmt) - pyobject = None - if pyname is not None: - pyobject = pyname.get_object() - return pyobject - - def _get_primary_and_object_for_node(self, stmt): - primary, pyname = eval_node2(self.scope, stmt) - pyobject = None - if pyname is not None: - pyobject = pyname.get_object() - return primary, pyobject - - def _Subscript(self, node): - if isinstance(node.slice, ast.Index): - self._call_function(node.value, '__getitem__', - [node.slice.value]) - elif isinstance(node.slice, ast.Slice): - self._call_function(node.value, '__getslice__') - - def _call_function(self, node, function_name, other_args=None): - pyname = eval_node(self.scope, node) - if pyname is not None: - pyobject = pyname.get_object() - else: - return - if function_name in pyobject: - called = pyobject[function_name].get_object() - if not called or not isinstance(called, pyobjects.AbstractFunction): - return - args = [node] - if other_args: - args += other_args - arguments_ = arguments.Arguments(args, self.scope) - self.result = rope.base.pynames.UnboundName( - pyobject=called.get_returned_object(arguments_)) - - def _Lambda(self, node): - self.result = rope.base.pynames.UnboundName( - pyobject=rope.base.builtins.Lambda(node, self.scope)) - - -def _get_evaluated_names(targets, assigned, module, evaluation, lineno): - result = {} - for name, levels in astutils.get_name_levels(targets): - assignment = rope.base.pynames.AssignmentValue(assigned, levels, - evaluation) - # XXX: this module should not access `rope.base.pynamesdef`! - pyname = rope.base.pynamesdef.AssignedName(lineno, module) - pyname.assignments.append(assignment) - result[name] = pyname - return result diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/exceptions.py --- a/vim/sadness/ropevim/src/rope/rope/base/exceptions.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -class RopeError(Exception): - """Base exception for rope""" - - -class ResourceNotFoundError(RopeError): - """Resource not found exception""" - - -class RefactoringError(RopeError): - """Errors for performing a refactoring""" - - -class InterruptedTaskError(RopeError): - """The task has been interrupted""" - - -class HistoryError(RopeError): - """Errors for history undo/redo operations""" - - -class ModuleNotFoundError(RopeError): - """Module not found exception""" - - -class AttributeNotFoundError(RopeError): - """Attribute not found exception""" - - -class NameNotFoundError(RopeError): - """Name not found exception""" - - -class BadIdentifierError(RopeError): - """The name cannot be resolved""" - - -class ModuleSyntaxError(RopeError): - """Module has syntax errors - - The `filename` and `lineno` fields indicate where the error has - occurred. - - """ - - def __init__(self, filename, lineno, message): - self.filename = filename - self.lineno = lineno - self.message_ = message - super(ModuleSyntaxError, self).__init__( - 'Syntax error in file <%s> line <%s>: %s' % - (filename, lineno, message)) - - -class ModuleDecodeError(RopeError): - """Cannot decode module""" - - def __init__(self, filename, message): - self.filename = filename - self.message_ = message - super(ModuleDecodeError, self).__init__( - 'Cannot decode file <%s>: %s' % (filename, message)) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/fscommands.py --- a/vim/sadness/ropevim/src/rope/rope/base/fscommands.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,268 +0,0 @@ -"""Project file system commands. - -This modules implements file system operations used by rope. Different -version control systems can be supported by implementing the interface -provided by `FileSystemCommands` class. See `SubversionCommands` and -`MercurialCommands` for example. - -""" -import os -import shutil -import subprocess - - -def create_fscommands(root): - dirlist = os.listdir(root) - commands = {'.hg': MercurialCommands, - '.svn': SubversionCommands, - '.git': GITCommands, - '_svn': SubversionCommands, - '_darcs': DarcsCommands} - for key in commands: - if key in dirlist: - try: - return commands[key](root) - except (ImportError, OSError): - pass - return FileSystemCommands() - - -class FileSystemCommands(object): - - def create_file(self, path): - open(path, 'w').close() - - def create_folder(self, path): - os.mkdir(path) - - def move(self, path, new_location): - shutil.move(path, new_location) - - def remove(self, path): - if os.path.isfile(path): - os.remove(path) - else: - shutil.rmtree(path) - - def write(self, path, data): - file_ = open(path, 'wb') - try: - file_.write(data) - finally: - file_.close() - - -class SubversionCommands(object): - - def __init__(self, *args): - self.normal_actions = FileSystemCommands() - import pysvn - self.client = pysvn.Client() - - def create_file(self, path): - self.normal_actions.create_file(path) - self.client.add(path, force=True) - - def create_folder(self, path): - self.normal_actions.create_folder(path) - self.client.add(path, force=True) - - def move(self, path, new_location): - self.client.move(path, new_location, force=True) - - def remove(self, path): - self.client.remove(path, force=True) - - def write(self, path, data): - self.normal_actions.write(path, data) - - -class MercurialCommands(object): - - def __init__(self, root): - self.hg = self._import_mercurial() - self.normal_actions = FileSystemCommands() - try: - self.ui = self.hg.ui.ui( - verbose=False, debug=False, quiet=True, - interactive=False, traceback=False, report_untrusted=False) - except: - self.ui = self.hg.ui.ui() - self.ui.setconfig('ui', 'interactive', 'no') - self.ui.setconfig('ui', 'debug', 'no') - self.ui.setconfig('ui', 'traceback', 'no') - self.ui.setconfig('ui', 'verbose', 'no') - self.ui.setconfig('ui', 'report_untrusted', 'no') - self.ui.setconfig('ui', 'quiet', 'yes') - self.ui.setconfig('extensions', 'progress', '!') - - self.repo = self.hg.hg.repository(self.ui, root) - - def _import_mercurial(self): - import mercurial.commands - import mercurial.hg - import mercurial.ui - return mercurial - - def create_file(self, path): - self.normal_actions.create_file(path) - self.hg.commands.add(self.ui, self.repo, path) - - def create_folder(self, path): - self.normal_actions.create_folder(path) - - def move(self, path, new_location): - self.hg.commands.rename(self.ui, self.repo, path, - new_location, after=False) - - def remove(self, path): - self.hg.commands.remove(self.ui, self.repo, path) - - def write(self, path, data): - self.normal_actions.write(path, data) - - -class GITCommands(object): - - def __init__(self, root): - self.root = root - self._do(['version']) - self.normal_actions = FileSystemCommands() - - def create_file(self, path): - self.normal_actions.create_file(path) - self._do(['add', self._in_dir(path)]) - - def create_folder(self, path): - self.normal_actions.create_folder(path) - - def move(self, path, new_location): - self._do(['mv', self._in_dir(path), self._in_dir(new_location)]) - - def remove(self, path): - self._do(['rm', self._in_dir(path)]) - - def write(self, path, data): - # XXX: should we use ``git add``? - self.normal_actions.write(path, data) - - def _do(self, args): - _execute(['git'] + args, cwd=self.root) - - def _in_dir(self, path): - if path.startswith(self.root): - return path[len(self.root) + 1:] - return self.root - - -class DarcsCommands(object): - - def __init__(self, root): - self.root = root - self.normal_actions = FileSystemCommands() - - def create_file(self, path): - self.normal_actions.create_file(path) - self._do(['add', path]) - - def create_folder(self, path): - self.normal_actions.create_folder(path) - self._do(['add', path]) - - def move(self, path, new_location): - self._do(['mv', path, new_location]) - - def remove(self, path): - self.normal_actions.remove(path) - - def write(self, path, data): - self.normal_actions.write(path, data) - - def _do(self, args): - _execute(['darcs'] + args, cwd=self.root) - - -def _execute(args, cwd=None): - process = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE) - process.wait() - return process.returncode - - -def unicode_to_file_data(contents, encoding=None): - if not isinstance(contents, unicode): - return contents - if encoding is None: - encoding = read_str_coding(contents) - if encoding is not None: - return contents.encode(encoding) - try: - return contents.encode() - except UnicodeEncodeError: - return contents.encode('utf-8') - -def file_data_to_unicode(data, encoding=None): - result = _decode_data(data, encoding) - if '\r' in result: - result = result.replace('\r\n', '\n').replace('\r', '\n') - return result - -def _decode_data(data, encoding): - if isinstance(data, unicode): - return data - if encoding is None: - encoding = read_str_coding(data) - if encoding is None: - # there is no encoding tip, we need to guess. - # PEP263 says that "encoding not explicitly defined" means it is ascii, - # but we will use utf8 instead since utf8 fully covers ascii and btw is - # the only non-latin sane encoding. - encoding = 'utf-8' - try: - return data.decode(encoding) - except (UnicodeError, LookupError): - # fallback to latin1: it should never fail - return data.decode('latin1') - - -def read_file_coding(path): - file = open(path, 'b') - count = 0 - result = [] - buffsize = 10 - while True: - current = file.read(10) - if not current: - break - count += current.count('\n') - result.append(current) - file.close() - return _find_coding(''.join(result)) - - -def read_str_coding(source): - try: - first = source.index('\n') + 1 - second = source.index('\n', first) + 1 - except ValueError: - second = len(source) - return _find_coding(source[:second]) - - -def _find_coding(text): - coding = 'coding' - try: - start = text.index(coding) + len(coding) - if text[start] not in '=:': - return - start += 1 - while start < len(text) and text[start].isspace(): - start += 1 - end = start - while end < len(text): - c = text[end] - if not c.isalnum() and c not in '-_': - break - end += 1 - return text[start:end] - except ValueError: - pass diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/history.py --- a/vim/sadness/ropevim/src/rope/rope/base/history.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -from rope.base import exceptions, change, taskhandle - - -class History(object): - """A class that holds project history""" - - def __init__(self, project, maxundos=None): - self.project = project - self._undo_list = [] - self._redo_list = [] - self._maxundos = maxundos - self._load_history() - self.project.data_files.add_write_hook(self.write) - self.current_change = None - - def _load_history(self): - if self.save: - result = self.project.data_files.read_data( - 'history', compress=self.compress, import_=True) - if result is not None: - to_change = change.DataToChange(self.project) - for data in result[0]: - self._undo_list.append(to_change(data)) - for data in result[1]: - self._redo_list.append(to_change(data)) - - def do(self, changes, task_handle=taskhandle.NullTaskHandle()): - """Perform the change and add it to the `self.undo_list` - - Note that uninteresting changes (changes to ignored files) - will not be appended to `self.undo_list`. - - """ - try: - self.current_change = changes - changes.do(change.create_job_set(task_handle, changes)) - finally: - self.current_change = None - if self._is_change_interesting(changes): - self.undo_list.append(changes) - self._remove_extra_items() - del self.redo_list[:] - - def _remove_extra_items(self): - if len(self.undo_list) > self.max_undos: - del self.undo_list[0:len(self.undo_list) - self.max_undos] - - def _is_change_interesting(self, changes): - for resource in changes.get_changed_resources(): - if not self.project.is_ignored(resource): - return True - return False - - def undo(self, change=None, drop=False, - task_handle=taskhandle.NullTaskHandle()): - """Redo done changes from the history - - When `change` is `None`, the last done change will be undone. - If change is not `None` it should be an item from - `self.undo_list`; this change and all changes that depend on - it will be undone. In both cases the list of undone changes - will be returned. - - If `drop` is `True`, the undone change will not be appended to - the redo list. - - """ - if not self._undo_list: - raise exceptions.HistoryError('Undo list is empty') - if change is None: - change = self.undo_list[-1] - dependencies = self._find_dependencies(self.undo_list, change) - self._move_front(self.undo_list, dependencies) - self._perform_undos(len(dependencies), task_handle) - result = self.redo_list[-len(dependencies):] - if drop: - del self.redo_list[-len(dependencies):] - return result - - def redo(self, change=None, task_handle=taskhandle.NullTaskHandle()): - """Redo undone changes from the history - - When `change` is `None`, the last undone change will be - redone. If change is not `None` it should be an item from - `self.redo_list`; this change and all changes that depend on - it will be redone. In both cases the list of redone changes - will be returned. - - """ - if not self.redo_list: - raise exceptions.HistoryError('Redo list is empty') - if change is None: - change = self.redo_list[-1] - dependencies = self._find_dependencies(self.redo_list, change) - self._move_front(self.redo_list, dependencies) - self._perform_redos(len(dependencies), task_handle) - return self.undo_list[-len(dependencies):] - - def _move_front(self, change_list, changes): - for change in changes: - change_list.remove(change) - change_list.append(change) - - def _find_dependencies(self, change_list, change): - index = change_list.index(change) - return _FindChangeDependencies(change_list[index:])() - - def _perform_undos(self, count, task_handle): - for i in range(count): - self.current_change = self.undo_list[-1] - try: - job_set = change.create_job_set(task_handle, - self.current_change) - self.current_change.undo(job_set) - finally: - self.current_change = None - self.redo_list.append(self.undo_list.pop()) - - def _perform_redos(self, count, task_handle): - for i in range(count): - self.current_change = self.redo_list[-1] - try: - job_set = change.create_job_set(task_handle, - self.current_change) - self.current_change.do(job_set) - finally: - self.current_change = None - self.undo_list.append(self.redo_list.pop()) - - def contents_before_current_change(self, file): - if self.current_change is None: - return None - result = self._search_for_change_contents([self.current_change], file) - if result is not None: - return result - if file.exists() and not file.is_folder(): - return file.read() - else: - return None - - def _search_for_change_contents(self, change_list, file): - for change_ in reversed(change_list): - if isinstance(change_, change.ChangeSet): - result = self._search_for_change_contents(change_.changes, - file) - if result is not None: - return result - if isinstance(change_, change.ChangeContents) and \ - change_.resource == file: - return change_.old_contents - - def write(self): - if self.save: - data = [] - to_data = change.ChangeToData() - self._remove_extra_items() - data.append([to_data(change_) for change_ in self.undo_list]) - data.append([to_data(change_) for change_ in self.redo_list]) - self.project.data_files.write_data('history', data, - compress=self.compress) - - def get_file_undo_list(self, resource): - result = [] - for change in self.undo_list: - if resource in change.get_changed_resources(): - result.append(change) - return result - - def __str__(self): - return 'History holds %s changes in memory' % \ - (len(self.undo_list) + len(self.redo_list)) - - undo_list = property(lambda self: self._undo_list) - redo_list = property(lambda self: self._redo_list) - - @property - def tobe_undone(self): - """The last done change if available, `None` otherwise""" - if self.undo_list: - return self.undo_list[-1] - - @property - def tobe_redone(self): - """The last undone change if available, `None` otherwise""" - if self.redo_list: - return self.redo_list[-1] - - @property - def max_undos(self): - if self._maxundos is None: - return self.project.prefs.get('max_history_items', 100) - else: - return self._maxundos - - @property - def save(self): - return self.project.prefs.get('save_history', False) - - @property - def compress(self): - return self.project.prefs.get('compress_history', False) - - def clear(self): - """Forget all undo and redo information""" - del self.undo_list[:] - del self.redo_list[:] - - -class _FindChangeDependencies(object): - - def __init__(self, change_list): - self.change = change_list[0] - self.change_list = change_list - self.changed_resources = set(self.change.get_changed_resources()) - - def __call__(self): - result = [self.change] - for change in self.change_list[1:]: - if self._depends_on(change, result): - result.append(change) - self.changed_resources.update(change.get_changed_resources()) - return result - - def _depends_on(self, changes, result): - for resource in changes.get_changed_resources(): - if resource is None: - continue - if resource in self.changed_resources: - return True - for changed in self.changed_resources: - if resource.is_folder() and resource.contains(changed): - return True - if changed.is_folder() and changed.contains(resource): - return True - return False diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/libutils.py --- a/vim/sadness/ropevim/src/rope/rope/base/libutils.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -"""A few useful functions for using rope as a library""" -import os.path - -import rope.base.project -import rope.base.pycore -from rope.base import taskhandle - - -def path_to_resource(project, path, type=None): - """Get the resource at path - - You only need to specify `type` if `path` does not exist. It can - be either 'file' or 'folder'. If the type is `None` it is assumed - that the resource already exists. - - Note that this function uses `Project.get_resource()`, - `Project.get_file()`, and `Project.get_folder()` methods. - - """ - project_path = relative(project.address, path) - if project_path is None: - project_path = rope.base.project._realpath(path) - project = rope.base.project.get_no_project() - if type is None: - return project.get_resource(project_path) - if type == 'file': - return project.get_file(project_path) - if type == 'folder': - return project.get_folder(project_path) - return None - -def relative(root, path): - root = rope.base.project._realpath(root).replace(os.path.sep, '/') - path = rope.base.project._realpath(path).replace(os.path.sep, '/') - if path == root: - return '' - if path.startswith(root + '/'): - return path[len(root) + 1:] - -def report_change(project, path, old_content): - """Report that the contents of file at `path` was changed - - The new contents of file is retrieved by reading the file. - - """ - resource = path_to_resource(project, path) - if resource is None: - return - for observer in list(project.observers): - observer.resource_changed(resource) - if project.pycore.automatic_soa: - rope.base.pycore.perform_soa_on_changed_scopes(project, resource, - old_content) - -def analyze_modules(project, task_handle=taskhandle.NullTaskHandle()): - """Perform static object analysis on all python files in the project - - Note that this might be really time consuming. - """ - resources = project.pycore.get_python_files() - job_set = task_handle.create_jobset('Analyzing Modules', len(resources)) - for resource in resources: - job_set.started_job(resource.path) - project.pycore.analyze_module(resource) - job_set.finished_job() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/oi/__init__.py --- a/vim/sadness/ropevim/src/rope/rope/base/oi/__init__.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -"""Rope object analysis and inference package - -Rope makes some simplifying assumptions about a python program. It -assumes that a program only performs assignments and function calls. -Tracking assignments is simple and `PyName` objects handle that. The -main problem is function calls. Rope uses these two approaches for -obtaining call information: - -* Static object analysis: `rope.base.pycore.PyCore.analyze_module()` - - It can analyze modules to obtain information about functions. This - is done by analyzing function calls in a module or scope. Currently - SOA analyzes the scopes that are changed while saving or when the - user asks to analyze a module. That is mainly because static - analysis is time-consuming. - -* Dynamic object analysis: `rope.base.pycore.PyCore.run_module()` - - When you run a module or your testsuite, when DOA is enabled, it - collects information about parameters passed to and objects returned - from functions. The main problem with this approach is that it is - quite slow; Not when looking up the information but when collecting - them. - -An instance of `rope.base.oi.objectinfo.ObjectInfoManager` can be used -for accessing these information. It saves the data in a -`rope.base.oi.objectdb.ObjectDB` internally. - -Now if our objectdb does not know anything about a function and we -need the value returned by it, static object inference, SOI, comes -into play. It analyzes function body and tries to infer the object -that is returned from it (we usually need the returned value for the -given parameter objects). - -Rope might collect and store information for other `PyName`\s, too. -For instance rope stores the object builtin containers hold. - -""" diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/oi/doa.py --- a/vim/sadness/ropevim/src/rope/rope/base/oi/doa.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -import cPickle as pickle -import marshal -import os -import socket -import subprocess -import sys -import tempfile -import threading - - -class PythonFileRunner(object): - """A class for running python project files""" - - def __init__(self, pycore, file_, args=None, stdin=None, - stdout=None, analyze_data=None): - self.pycore = pycore - self.file = file_ - self.analyze_data = analyze_data - self.observers = [] - self.args = args - self.stdin = stdin - self.stdout = stdout - - def run(self): - """Execute the process""" - env = dict(os.environ) - file_path = self.file.real_path - path_folders = self.pycore.get_source_folders() + \ - self.pycore.get_python_path_folders() - env['PYTHONPATH'] = os.pathsep.join(folder.real_path - for folder in path_folders) - runmod_path = self.pycore.find_module('rope.base.oi.runmod').real_path - self.receiver = None - self._init_data_receiving() - send_info = '-' - if self.receiver: - send_info = self.receiver.get_send_info() - args = [sys.executable, runmod_path, send_info, - self.pycore.project.address, self.file.real_path] - if self.analyze_data is None: - del args[1:4] - if self.args is not None: - args.extend(self.args) - self.process = subprocess.Popen( - executable=sys.executable, args=args, env=env, - cwd=os.path.split(file_path)[0], stdin=self.stdin, - stdout=self.stdout, stderr=self.stdout, close_fds=os.name != 'nt') - - def _init_data_receiving(self): - if self.analyze_data is None: - return - # Disabling FIFO data transfer due to blocking when running - # unittests in the GUI. - # XXX: Handle FIFO data transfer for `rope.ui.testview` - if True or os.name == 'nt': - self.receiver = _SocketReceiver() - else: - self.receiver = _FIFOReceiver() - self.receiving_thread = threading.Thread(target=self._receive_information) - self.receiving_thread.setDaemon(True) - self.receiving_thread.start() - - def _receive_information(self): - #temp = open('/dev/shm/info', 'w') - for data in self.receiver.receive_data(): - self.analyze_data(data) - #temp.write(str(data) + '\n') - #temp.close() - for observer in self.observers: - observer() - - def wait_process(self): - """Wait for the process to finish""" - self.process.wait() - if self.analyze_data: - self.receiving_thread.join() - - def kill_process(self): - """Stop the process""" - if self.process.poll() is not None: - return - try: - if hasattr(self.process, 'terminate'): - self.process.terminate() - elif os.name != 'nt': - os.kill(self.process.pid, 9) - else: - import ctypes - handle = int(self.process._handle) - ctypes.windll.kernel32.TerminateProcess(handle, -1) - except OSError: - pass - - def add_finishing_observer(self, observer): - """Notify this observer when execution finishes""" - self.observers.append(observer) - - -class _MessageReceiver(object): - - def receive_data(self): - pass - - def get_send_info(self): - pass - - -class _SocketReceiver(_MessageReceiver): - - def __init__(self): - self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.data_port = 3037 - while self.data_port < 4000: - try: - self.server_socket.bind(('', self.data_port)) - break - except socket.error, e: - self.data_port += 1 - self.server_socket.listen(1) - - def get_send_info(self): - return str(self.data_port) - - def receive_data(self): - conn, addr = self.server_socket.accept() - self.server_socket.close() - my_file = conn.makefile('r') - while True: - try: - yield pickle.load(my_file) - except EOFError: - break - my_file.close() - conn.close() - - -class _FIFOReceiver(_MessageReceiver): - - def __init__(self): - # XXX: this is insecure and might cause race conditions - self.file_name = self._get_file_name() - os.mkfifo(self.file_name) - - def _get_file_name(self): - prefix = tempfile.gettempdir() + '/__rope_' - i = 0 - while os.path.exists(prefix + str(i).rjust(4, '0')): - i += 1 - return prefix + str(i).rjust(4, '0') - - def get_send_info(self): - return self.file_name - - def receive_data(self): - my_file = open(self.file_name, 'rb') - while True: - try: - yield marshal.load(my_file) - except EOFError: - break - my_file.close() - os.remove(self.file_name) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/oi/memorydb.py --- a/vim/sadness/ropevim/src/rope/rope/base/oi/memorydb.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -from rope.base.oi import objectdb - - -class MemoryDB(objectdb.FileDict): - - def __init__(self, project, persist=None): - self.project = project - self._persist = persist - self.files = self - self._load_files() - self.project.data_files.add_write_hook(self.write) - - def _load_files(self): - self._files = {} - if self.persist: - result = self.project.data_files.read_data( - 'objectdb', compress=self.compress, import_=True) - if result is not None: - self._files = result - - def keys(self): - return self._files.keys() - - def __contains__(self, key): - return key in self._files - - def __getitem__(self, key): - return FileInfo(self._files[key]) - - def create(self, path): - self._files[path] = {} - - def rename(self, file, newfile): - if file not in self._files: - return - self._files[newfile] = self._files[file] - del self[file] - - def __delitem__(self, file): - del self._files[file] - - def write(self): - if self.persist: - self.project.data_files.write_data('objectdb', self._files, - self.compress) - - @property - def compress(self): - return self.project.prefs.get('compress_objectdb', False) - - @property - def persist(self): - if self._persist is not None: - return self._persist - else: - return self.project.prefs.get('save_objectdb', False) - - -class FileInfo(objectdb.FileInfo): - - def __init__(self, scopes): - self.scopes = scopes - - def create_scope(self, key): - self.scopes[key] = ScopeInfo() - - def keys(self): - return self.scopes.keys() - - def __contains__(self, key): - return key in self.scopes - - def __getitem__(self, key): - return self.scopes[key] - - def __delitem__(self, key): - del self.scopes[key] - - -class ScopeInfo(objectdb.ScopeInfo): - - def __init__(self): - self.call_info = {} - self.per_name = {} - - def get_per_name(self, name): - return self.per_name.get(name, None) - - def save_per_name(self, name, value): - self.per_name[name] = value - - def get_returned(self, parameters): - return self.call_info.get(parameters, None) - - def get_call_infos(self): - for args, returned in self.call_info.items(): - yield objectdb.CallInfo(args, returned) - - def add_call(self, parameters, returned): - self.call_info[parameters] = returned - - def __getstate__(self): - return (self.call_info, self.per_name) - - def __setstate__(self, data): - self.call_info, self.per_name = data diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/oi/objectdb.py --- a/vim/sadness/ropevim/src/rope/rope/base/oi/objectdb.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,175 +0,0 @@ -import UserDict - - -class ObjectDB(object): - - def __init__(self, db, validation): - self.db = db - self.validation = validation - self.observers = [] - self.files = db.files - - def validate_files(self): - for file in list(self.files): - if not self.validation.is_file_valid(file): - del self.files[file] - self._file_removed(file) - - def validate_file(self, file): - if file not in self.files: - return - for key in list(self.files[file]): - if not self.validation.is_scope_valid(file, key): - del self.files[file][key] - - def file_moved(self, file, newfile): - if file not in self.files: - return - self.files.rename(file, newfile) - self._file_removed(file) - self._file_added(newfile) - - def get_files(self): - return self.files.keys() - - def get_returned(self, path, key, args): - scope_info = self._get_scope_info(path, key, readonly=True) - result = scope_info.get_returned(args) - if self.validation.is_value_valid(result): - return result - - def get_pername(self, path, key, name): - scope_info = self._get_scope_info(path, key, readonly=True) - result = scope_info.get_per_name(name) - if self.validation.is_value_valid(result): - return result - - def get_callinfos(self, path, key): - scope_info = self._get_scope_info(path, key, readonly=True) - return scope_info.get_call_infos() - - def add_callinfo(self, path, key, args, returned): - scope_info = self._get_scope_info(path, key, readonly=False) - old_returned = scope_info.get_returned(args) - if self.validation.is_more_valid(returned, old_returned): - scope_info.add_call(args, returned) - - def add_pername(self, path, key, name, value): - scope_info = self._get_scope_info(path, key, readonly=False) - old_value = scope_info.get_per_name(name) - if self.validation.is_more_valid(value, old_value): - scope_info.save_per_name(name, value) - - def add_file_list_observer(self, observer): - self.observers.append(observer) - - def write(self): - self.db.write() - - def _get_scope_info(self, path, key, readonly=True): - if path not in self.files: - if readonly: - return _NullScopeInfo() - self.files.create(path) - self._file_added(path) - if key not in self.files[path]: - if readonly: - return _NullScopeInfo() - self.files[path].create_scope(key) - result = self.files[path][key] - if isinstance(result, dict): - print self.files, self.files[path], self.files[path][key] - return result - - def _file_removed(self, path): - for observer in self.observers: - observer.removed(path) - - def _file_added(self, path): - for observer in self.observers: - observer.added(path) - - def __str__(self): - scope_count = 0 - for file_dict in self.files.values(): - scope_count += len(file_dict) - return 'ObjectDB holds %s file and %s scope infos' % \ - (len(self.files), scope_count) - - -class _NullScopeInfo(object): - - def __init__(self, error_on_write=True): - self.error_on_write = error_on_write - - def get_per_name(self, name): - pass - - def save_per_name(self, name, value): - if self.error_on_write: - raise NotImplementedError() - - def get_returned(self, parameters): - pass - - def get_call_infos(self): - return [] - - def add_call(self, parameters, returned): - if self.error_on_write: - raise NotImplementedError() - - -class FileInfo(UserDict.DictMixin): - - def create_scope(self, key): - pass - - -class FileDict(UserDict.DictMixin): - - def create(self, key): - pass - - def rename(self, key, new_key): - pass - - -class ScopeInfo(object): - - def get_per_name(self, name): - pass - - def save_per_name(self, name, value): - pass - - def get_returned(self, parameters): - pass - - def get_call_infos(self): - pass - - def add_call(self, parameters, returned): - pass - - -class CallInfo(object): - - def __init__(self, args, returned): - self.args = args - self.returned = returned - - def get_parameters(self): - return self.args - - def get_returned(self): - return self.returned - - -class FileListObserver(object): - - def added(self, path): - pass - - def removed(self, path): - pass diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/oi/objectinfo.py --- a/vim/sadness/ropevim/src/rope/rope/base/oi/objectinfo.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,232 +0,0 @@ -import warnings - -from rope.base import exceptions, resourceobserver -from rope.base.oi import objectdb, memorydb, transform - - -class ObjectInfoManager(object): - """Stores object information - - It uses an instance of `objectdb.ObjectDB` for storing - information. - - """ - - def __init__(self, project): - self.project = project - self.to_textual = transform.PyObjectToTextual(project) - self.to_pyobject = transform.TextualToPyObject(project) - self.doi_to_pyobject = transform.DOITextualToPyObject(project) - self._init_objectdb() - if project.prefs.get('validate_objectdb', False): - self._init_validation() - - def _init_objectdb(self): - dbtype = self.project.get_prefs().get('objectdb_type', None) - persist = None - if dbtype is not None: - warnings.warn( - '"objectdb_type" project config is deprecated;\n' - 'Use "save_objectdb" instead in your project ' - 'config file.\n(".ropeproject/config.py" by default)\n', - DeprecationWarning) - if dbtype != 'memory' and self.project.ropefolder is not None: - persist = True - self.validation = TextualValidation(self.to_pyobject) - db = memorydb.MemoryDB(self.project, persist=persist) - self.objectdb = objectdb.ObjectDB(db, self.validation) - - def _init_validation(self): - self.objectdb.validate_files() - observer = resourceobserver.ResourceObserver( - changed=self._resource_changed, moved=self._resource_moved, - removed=self._resource_moved) - files = [] - for path in self.objectdb.get_files(): - resource = self.to_pyobject.path_to_resource(path) - if resource is not None and resource.project == self.project: - files.append(resource) - self.observer = resourceobserver.FilteredResourceObserver(observer, - files) - self.objectdb.add_file_list_observer(_FileListObserver(self)) - self.project.add_observer(self.observer) - - def _resource_changed(self, resource): - try: - self.objectdb.validate_file( - self.to_textual.resource_to_path(resource)) - except exceptions.ModuleSyntaxError: - pass - - def _resource_moved(self, resource, new_resource=None): - self.observer.remove_resource(resource) - if new_resource is not None: - old = self.to_textual.resource_to_path(resource) - new = self.to_textual.resource_to_path(new_resource) - self.objectdb.file_moved(old, new) - self.observer.add_resource(new_resource) - - def get_returned(self, pyobject, args): - result = self.get_exact_returned(pyobject, args) - if result is not None: - return result - path, key = self._get_scope(pyobject) - if path is None: - return None - for call_info in self.objectdb.get_callinfos(path, key): - returned = call_info.get_returned() - if returned and returned[0] not in ('unknown', 'none'): - result = returned - break - if result is None: - result = returned - if result is not None: - return self.to_pyobject(result) - - def get_exact_returned(self, pyobject, args): - path, key = self._get_scope(pyobject) - if path is not None: - returned = self.objectdb.get_returned( - path, key, self._args_to_textual(pyobject, args)) - if returned is not None: - return self.to_pyobject(returned) - - def _args_to_textual(self, pyfunction, args): - parameters = list(pyfunction.get_param_names(special_args=False)) - arguments = args.get_arguments(parameters)[:len(parameters)] - textual_args = tuple([self.to_textual(arg) - for arg in arguments]) - return textual_args - - def get_parameter_objects(self, pyobject): - path, key = self._get_scope(pyobject) - if path is None: - return None - arg_count = len(pyobject.get_param_names(special_args=False)) - unknowns = arg_count - parameters = [None] * arg_count - for call_info in self.objectdb.get_callinfos(path, key): - args = call_info.get_parameters() - for index, arg in enumerate(args[:arg_count]): - old = parameters[index] - if self.validation.is_more_valid(arg, old): - parameters[index] = arg - if self.validation.is_value_valid(arg): - unknowns -= 1 - if unknowns == 0: - break - if unknowns < arg_count: - return [self.to_pyobject(parameter) - for parameter in parameters] - - def get_passed_objects(self, pyfunction, parameter_index): - path, key = self._get_scope(pyfunction) - if path is None: - return [] - result = [] - for call_info in self.objectdb.get_callinfos(path, key): - args = call_info.get_parameters() - if len(args) > parameter_index: - parameter = self.to_pyobject(args[parameter_index]) - if parameter is not None: - result.append(parameter) - return result - - def doa_data_received(self, data): - def doi_to_normal(textual): - pyobject = self.doi_to_pyobject(textual) - return self.to_textual(pyobject) - function = doi_to_normal(data[0]) - args = tuple([doi_to_normal(textual) for textual in data[1]]) - returned = doi_to_normal(data[2]) - if function[0] == 'defined' and len(function) == 3: - self._save_data(function, args, returned) - - def function_called(self, pyfunction, params, returned=None): - function_text = self.to_textual(pyfunction) - params_text = tuple([self.to_textual(param) - for param in params]) - returned_text = ('unknown',) - if returned is not None: - returned_text = self.to_textual(returned) - self._save_data(function_text, params_text, returned_text) - - def save_per_name(self, scope, name, data): - path, key = self._get_scope(scope.pyobject) - if path is not None: - self.objectdb.add_pername(path, key, name, self.to_textual(data)) - - def get_per_name(self, scope, name): - path, key = self._get_scope(scope.pyobject) - if path is not None: - result = self.objectdb.get_pername(path, key, name) - if result is not None: - return self.to_pyobject(result) - - def _save_data(self, function, args, returned=('unknown',)): - self.objectdb.add_callinfo(function[1], function[2], args, returned) - - def _get_scope(self, pyobject): - resource = pyobject.get_module().get_resource() - if resource is None: - return None, None - textual = self.to_textual(pyobject) - if textual[0] == 'defined': - path = textual[1] - if len(textual) == 3: - key = textual[2] - else: - key = '' - return path, key - return None, None - - def sync(self): - self.objectdb.sync() - - def __str__(self): - return str(self.objectdb) - - -class TextualValidation(object): - - def __init__(self, to_pyobject): - self.to_pyobject = to_pyobject - - def is_value_valid(self, value): - # ???: Should none and unknown be considered valid? - if value is None or value[0] in ('none', 'unknown'): - return False - return self.to_pyobject(value) is not None - - def is_more_valid(self, new, old): - if old is None: - return True - return new[0] not in ('unknown', 'none') - - def is_file_valid(self, path): - return self.to_pyobject.path_to_resource(path) is not None - - def is_scope_valid(self, path, key): - if key == '': - textual = ('defined', path) - else: - textual = ('defined', path, key) - return self.to_pyobject(textual) is not None - - -class _FileListObserver(object): - - def __init__(self, object_info): - self.object_info = object_info - self.observer = self.object_info.observer - self.to_pyobject = self.object_info.to_pyobject - - def removed(self, path): - resource = self.to_pyobject.path_to_resource(path) - if resource is not None: - self.observer.remove_resource(resource) - - def added(self, path): - resource = self.to_pyobject.path_to_resource(path) - if resource is not None: - self.observer.add_resource(resource) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/oi/runmod.py --- a/vim/sadness/ropevim/src/rope/rope/base/oi/runmod.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +0,0 @@ - -def __rope_start_everything(): - import os - import sys - import socket - import cPickle as pickle - import marshal - import inspect - import types - import threading - - class _MessageSender(object): - - def send_data(self, data): - pass - - class _SocketSender(_MessageSender): - - def __init__(self, port): - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect(('127.0.0.1', port)) - self.my_file = s.makefile('w') - - def send_data(self, data): - if not self.my_file.closed: - pickle.dump(data, self.my_file) - - def close(self): - self.my_file.close() - - class _FileSender(_MessageSender): - - def __init__(self, file_name): - self.my_file = open(file_name, 'wb') - - def send_data(self, data): - if not self.my_file.closed: - marshal.dump(data, self.my_file) - - def close(self): - self.my_file.close() - - - def _cached(func): - cache = {} - def newfunc(self, arg): - if arg in cache: - return cache[arg] - result = func(self, arg) - cache[arg] = result - return result - return newfunc - - class _FunctionCallDataSender(object): - - def __init__(self, send_info, project_root): - self.project_root = project_root - if send_info.isdigit(): - self.sender = _SocketSender(int(send_info)) - else: - self.sender = _FileSender(send_info) - - def global_trace(frame, event, arg): - # HACK: Ignoring out->in calls - # This might lose some information - if self._is_an_interesting_call(frame): - return self.on_function_call - sys.settrace(global_trace) - threading.settrace(global_trace) - - def on_function_call(self, frame, event, arg): - if event != 'return': - return - args = [] - returned = ('unknown',) - code = frame.f_code - for argname in code.co_varnames[:code.co_argcount]: - try: - args.append(self._object_to_persisted_form(frame.f_locals[argname])) - except (TypeError, AttributeError): - args.append(('unknown',)) - try: - returned = self._object_to_persisted_form(arg) - except (TypeError, AttributeError): - pass - try: - data = (self._object_to_persisted_form(frame.f_code), - tuple(args), returned) - self.sender.send_data(data) - except (TypeError): - pass - return self.on_function_call - - def _is_an_interesting_call(self, frame): - #if frame.f_code.co_name in ['?', '']: - # return False - #return not frame.f_back or not self._is_code_inside_project(frame.f_back.f_code) - - if not self._is_code_inside_project(frame.f_code) and \ - (not frame.f_back or not self._is_code_inside_project(frame.f_back.f_code)): - return False - return True - - def _is_code_inside_project(self, code): - source = self._path(code.co_filename) - return source is not None and os.path.exists(source) and \ - _realpath(source).startswith(self.project_root) - - @_cached - def _get_persisted_code(self, object_): - source = self._path(object_.co_filename) - if not os.path.exists(source): - raise TypeError('no source') - return ('defined', _realpath(source), str(object_.co_firstlineno)) - - @_cached - def _get_persisted_class(self, object_): - try: - return ('defined', _realpath(inspect.getsourcefile(object_)), - object_.__name__) - except (TypeError, AttributeError): - return ('unknown',) - - def _get_persisted_builtin(self, object_): - if isinstance(object_, (str, unicode)): - return ('builtin', 'str') - if isinstance(object_, list): - holding = None - if len(object_) > 0: - holding = object_[0] - return ('builtin', 'list', self._object_to_persisted_form(holding)) - if isinstance(object_, dict): - keys = None - values = None - if len(object_) > 0: - keys = object_.keys()[0] - values = object_[keys] - return ('builtin', 'dict', - self._object_to_persisted_form(keys), - self._object_to_persisted_form(values)) - if isinstance(object_, tuple): - objects = [] - if len(object_) < 3: - for holding in object_: - objects.append(self._object_to_persisted_form(holding)) - else: - objects.append(self._object_to_persisted_form(object_[0])) - return tuple(['builtin', 'tuple'] + objects) - if isinstance(object_, set): - holding = None - if len(object_) > 0: - for o in object_: - holding = o - break - return ('builtin', 'set', self._object_to_persisted_form(holding)) - return ('unknown',) - - def _object_to_persisted_form(self, object_): - if object_ is None: - return ('none',) - if isinstance(object_, types.CodeType): - return self._get_persisted_code(object_) - if isinstance(object_, types.FunctionType): - return self._get_persisted_code(object_.func_code) - if isinstance(object_, types.MethodType): - return self._get_persisted_code(object_.im_func.func_code) - if isinstance(object_, types.ModuleType): - return self._get_persisted_module(object_) - if isinstance(object_, (str, unicode, list, dict, tuple, set)): - return self._get_persisted_builtin(object_) - if isinstance(object_, (types.TypeType, types.ClassType)): - return self._get_persisted_class(object_) - return ('instance', self._get_persisted_class(type(object_))) - - @_cached - def _get_persisted_module(self, object_): - path = self._path(object_.__file__) - if path and os.path.exists(path): - return ('defined', _realpath(path)) - return ('unknown',) - - def _path(self, path): - if path.endswith('.pyc'): - path = path[:-1] - if path.endswith('.py'): - return path - - def close(self): - self.sender.close() - - def _realpath(path): - return os.path.realpath(os.path.abspath(os.path.expanduser(path))) - - send_info = sys.argv[1] - project_root = sys.argv[2] - file_to_run = sys.argv[3] - run_globals = globals() - run_globals.update({'__name__': '__main__', - '__builtins__': __builtins__, - '__file__': file_to_run}) - if send_info != '-': - data_sender = _FunctionCallDataSender(send_info, project_root) - del sys.argv[1:4] - execfile(file_to_run, run_globals) - if send_info != '-': - data_sender.close() - - -if __name__ == '__main__': - __rope_start_everything() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/oi/soa.py --- a/vim/sadness/ropevim/src/rope/rope/base/oi/soa.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -import rope.base.ast -import rope.base.oi.soi -import rope.base.pynames -from rope.base import pyobjects, evaluate, astutils, arguments - - -def analyze_module(pycore, pymodule, should_analyze, - search_subscopes, followed_calls): - """Analyze `pymodule` for static object inference - - Analyzes scopes for collecting object information. The analysis - starts from inner scopes. - - """ - _analyze_node(pycore, pymodule, should_analyze, - search_subscopes, followed_calls) - - -def _analyze_node(pycore, pydefined, should_analyze, - search_subscopes, followed_calls): - if search_subscopes(pydefined): - for scope in pydefined.get_scope().get_scopes(): - _analyze_node(pycore, scope.pyobject, should_analyze, - search_subscopes, followed_calls) - if should_analyze(pydefined): - new_followed_calls = max(0, followed_calls - 1) - return_true = lambda pydefined: True - return_false = lambda pydefined: False - def _follow(pyfunction): - _analyze_node(pycore, pyfunction, return_true, - return_false, new_followed_calls) - if not followed_calls: - _follow = None - visitor = SOAVisitor(pycore, pydefined, _follow) - for child in rope.base.ast.get_child_nodes(pydefined.get_ast()): - rope.base.ast.walk(child, visitor) - - -class SOAVisitor(object): - - def __init__(self, pycore, pydefined, follow_callback=None): - self.pycore = pycore - self.pymodule = pydefined.get_module() - self.scope = pydefined.get_scope() - self.follow = follow_callback - - def _FunctionDef(self, node): - pass - - def _ClassDef(self, node): - pass - - def _Call(self, node): - for child in rope.base.ast.get_child_nodes(node): - rope.base.ast.walk(child, self) - primary, pyname = evaluate.eval_node2(self.scope, node.func) - if pyname is None: - return - pyfunction = pyname.get_object() - if isinstance(pyfunction, pyobjects.AbstractFunction): - args = arguments.create_arguments(primary, pyfunction, - node, self.scope) - elif isinstance(pyfunction, pyobjects.PyClass): - pyclass = pyfunction - if '__init__' in pyfunction: - pyfunction = pyfunction['__init__'].get_object() - pyname = rope.base.pynames.UnboundName(pyobjects.PyObject(pyclass)) - args = self._args_with_self(primary, pyname, pyfunction, node) - elif '__call__' in pyfunction: - pyfunction = pyfunction['__call__'].get_object() - args = self._args_with_self(primary, pyname, pyfunction, node) - else: - return - self._call(pyfunction, args) - - def _args_with_self(self, primary, self_pyname, pyfunction, node): - base_args = arguments.create_arguments(primary, pyfunction, - node, self.scope) - return arguments.MixedArguments(self_pyname, base_args, self.scope) - - def _call(self, pyfunction, args): - if isinstance(pyfunction, pyobjects.PyFunction): - if self.follow is not None: - before = self._parameter_objects(pyfunction) - self.pycore.object_info.function_called( - pyfunction, args.get_arguments(pyfunction.get_param_names())) - pyfunction._set_parameter_pyobjects(None) - if self.follow is not None: - after = self._parameter_objects(pyfunction) - if after != before: - self.follow(pyfunction) - # XXX: Maybe we should not call every builtin function - if isinstance(pyfunction, rope.base.builtins.BuiltinFunction): - pyfunction.get_returned_object(args) - - def _parameter_objects(self, pyfunction): - result = [] - for i in range(len(pyfunction.get_param_names(False))): - result.append(pyfunction.get_parameter(i)) - return result - - def _Assign(self, node): - for child in rope.base.ast.get_child_nodes(node): - rope.base.ast.walk(child, self) - visitor = _SOAAssignVisitor() - nodes = [] - for child in node.targets: - rope.base.ast.walk(child, visitor) - nodes.extend(visitor.nodes) - for subscript, levels in nodes: - instance = evaluate.eval_node(self.scope, subscript.value) - args_pynames = [] - args_pynames.append(evaluate.eval_node(self.scope, - subscript.slice.value)) - value = rope.base.oi.soi._infer_assignment( - rope.base.pynames.AssignmentValue(node.value, levels), self.pymodule) - args_pynames.append(rope.base.pynames.UnboundName(value)) - if instance is not None and value is not None: - pyobject = instance.get_object() - if '__setitem__' in pyobject: - pyfunction = pyobject['__setitem__'].get_object() - args = arguments.ObjectArguments([instance] + args_pynames) - self._call(pyfunction, args) - # IDEA: handle `__setslice__`, too - - -class _SOAAssignVisitor(astutils._NodeNameCollector): - - def __init__(self): - super(_SOAAssignVisitor, self).__init__() - self.nodes = [] - - def _added(self, node, levels): - if isinstance(node, rope.base.ast.Subscript) and \ - isinstance(node.slice, rope.base.ast.Index): - self.nodes.append((node, levels)) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/oi/soi.py --- a/vim/sadness/ropevim/src/rope/rope/base/oi/soi.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -"""A module for inferring objects - -For more information see the documentation in `rope.base.oi` -package. - -""" -import rope.base.builtins -import rope.base.pynames -import rope.base.pyobjects -from rope.base import evaluate, utils, arguments - - -_ignore_inferred = utils.ignore_exception( - rope.base.pyobjects.IsBeingInferredError) - - -@_ignore_inferred -def infer_returned_object(pyfunction, args): - """Infer the `PyObject` this `PyFunction` returns after calling""" - object_info = pyfunction.pycore.object_info - result = object_info.get_exact_returned(pyfunction, args) - if result is not None: - return result - result = _infer_returned(pyfunction, args) - if result is not None: - if args and pyfunction.get_module().get_resource() is not None: - params = args.get_arguments( - pyfunction.get_param_names(special_args=False)) - object_info.function_called(pyfunction, params, result) - return result - return object_info.get_returned(pyfunction, args) - -@_ignore_inferred -def infer_parameter_objects(pyfunction): - """Infer the `PyObject`\s of parameters of this `PyFunction`""" - object_info = pyfunction.pycore.object_info - result = object_info.get_parameter_objects(pyfunction) - if result is None: - result = _parameter_objects(pyfunction) - _handle_first_parameter(pyfunction, result) - return result - -def _handle_first_parameter(pyobject, parameters): - kind = pyobject.get_kind() - if parameters is None or kind not in ['method', 'classmethod']: - pass - if not parameters: - if not pyobject.get_param_names(special_args=False): - return - parameters.append(rope.base.pyobjects.get_unknown()) - if kind == 'method': - parameters[0] = rope.base.pyobjects.PyObject(pyobject.parent) - if kind == 'classmethod': - parameters[0] = pyobject.parent - -@_ignore_inferred -def infer_assigned_object(pyname): - if not pyname.assignments: - return - for assignment in reversed(pyname.assignments): - result = _infer_assignment(assignment, pyname.module) - if result is not None: - return result - -def get_passed_objects(pyfunction, parameter_index): - object_info = pyfunction.pycore.object_info - result = object_info.get_passed_objects(pyfunction, - parameter_index) - if not result: - statically_inferred = _parameter_objects(pyfunction) - if len(statically_inferred) > parameter_index: - result.append(statically_inferred[parameter_index]) - return result - -def _infer_returned(pyobject, args): - if args: - # HACK: Setting parameter objects manually - # This is not thread safe and might cause problems if `args` - # does not come from a good call site - pyobject.get_scope().invalidate_data() - pyobject._set_parameter_pyobjects( - args.get_arguments(pyobject.get_param_names(special_args=False))) - scope = pyobject.get_scope() - if not scope._get_returned_asts(): - return - maxtries = 3 - for returned_node in reversed(scope._get_returned_asts()[-maxtries:]): - try: - resulting_pyname = evaluate.eval_node(scope, returned_node) - if resulting_pyname is None: - continue - pyobject = resulting_pyname.get_object() - if pyobject == rope.base.pyobjects.get_unknown(): - continue - if not scope._is_generator(): - return pyobject - else: - return rope.base.builtins.get_generator(pyobject) - except rope.base.pyobjects.IsBeingInferredError: - pass - -def _parameter_objects(pyobject): - params = pyobject.get_param_names(special_args=False) - return [rope.base.pyobjects.get_unknown()] * len(params) - -# handling `rope.base.pynames.AssignmentValue` - -@_ignore_inferred -def _infer_assignment(assignment, pymodule): - result = _follow_pyname(assignment, pymodule) - if result is None: - return None - pyname, pyobject = result - pyobject = _follow_evaluations(assignment, pyname, pyobject) - if pyobject is None: - return None - return _follow_levels(assignment, pyobject) - -def _follow_levels(assignment, pyobject): - for index in assignment.levels: - if isinstance(pyobject.get_type(), rope.base.builtins.Tuple): - holdings = pyobject.get_type().get_holding_objects() - if holdings: - pyobject = holdings[min(len(holdings) - 1, index)] - else: - pyobject = None - elif isinstance(pyobject.get_type(), rope.base.builtins.List): - pyobject = pyobject.get_type().holding - else: - pyobject = None - if pyobject is None: - break - return pyobject - -@_ignore_inferred -def _follow_pyname(assignment, pymodule, lineno=None): - assign_node = assignment.ast_node - if lineno is None: - lineno = _get_lineno_for_node(assign_node) - holding_scope = pymodule.get_scope().get_inner_scope_for_line(lineno) - pyname = evaluate.eval_node(holding_scope, assign_node) - if pyname is not None: - result = pyname.get_object() - if isinstance(result.get_type(), rope.base.builtins.Property) and \ - holding_scope.get_kind() == 'Class': - arg = rope.base.pynames.UnboundName( - rope.base.pyobjects.PyObject(holding_scope.pyobject)) - return pyname, result.get_type().get_property_object( - arguments.ObjectArguments([arg])) - return pyname, result - -@_ignore_inferred -def _follow_evaluations(assignment, pyname, pyobject): - new_pyname = pyname - tokens = assignment.evaluation.split('.') - for token in tokens: - call = token.endswith('()') - if call: - token = token[:-2] - if token: - pyname = new_pyname - new_pyname = _get_attribute(pyobject, token) - if new_pyname is not None: - pyobject = new_pyname.get_object() - if pyobject is not None and call: - if isinstance(pyobject, rope.base.pyobjects.AbstractFunction): - args = arguments.ObjectArguments([pyname]) - pyobject = pyobject.get_returned_object(args) - else: - pyobject = None - if pyobject is None: - break - if pyobject is not None and assignment.assign_type: - return rope.base.pyobjects.PyObject(pyobject) - return pyobject - - -def _get_lineno_for_node(assign_node): - if hasattr(assign_node, 'lineno') and \ - assign_node.lineno is not None: - return assign_node.lineno - return 1 - -def _get_attribute(pyobject, name): - if pyobject is not None and name in pyobject: - return pyobject[name] diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/oi/transform.py --- a/vim/sadness/ropevim/src/rope/rope/base/oi/transform.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,285 +0,0 @@ -"""Provides classes for persisting `PyObject`\s""" -import os -import re - -import rope.base.builtins -from rope.base import exceptions - - -class PyObjectToTextual(object): - """For transforming `PyObject` to textual form - - This can be used for storing `PyObjects` in files. Use - `TextualToPyObject` for converting back. - - """ - - def __init__(self, project): - self.project = project - - def transform(self, pyobject): - """Transform a `PyObject` to textual form""" - if pyobject is None: - return ('none',) - object_type = type(pyobject) - try: - method = getattr(self, object_type.__name__ + '_to_textual') - return method(pyobject) - except AttributeError: - return ('unknown',) - - def __call__(self, pyobject): - return self.transform(pyobject) - - def PyObject_to_textual(self, pyobject): - if isinstance(pyobject.get_type(), rope.base.pyobjects.AbstractClass): - result = self.transform(pyobject.get_type()) - if result[0] == 'defined': - return ('instance', result) - return result - return ('unknown',) - - def PyFunction_to_textual(self, pyobject): - return self._defined_to_textual(pyobject) - - def PyClass_to_textual(self, pyobject): - return self._defined_to_textual(pyobject) - - def _defined_to_textual(self, pyobject): - address = [] - while pyobject.parent is not None: - address.insert(0, pyobject.get_name()) - pyobject = pyobject.parent - return ('defined', self._get_pymodule_path(pyobject.get_module()), - '.'.join(address)) - - def PyModule_to_textual(self, pyobject): - return ('defined', self._get_pymodule_path(pyobject)) - - def PyPackage_to_textual(self, pyobject): - return ('defined', self._get_pymodule_path(pyobject)) - - def List_to_textual(self, pyobject): - return ('builtin', 'list', self.transform(pyobject.holding)) - - def Dict_to_textual(self, pyobject): - return ('builtin', 'dict', self.transform(pyobject.keys), - self.transform(pyobject.values)) - - def Tuple_to_textual(self, pyobject): - objects = [self.transform(holding) - for holding in pyobject.get_holding_objects()] - return tuple(['builtin', 'tuple'] + objects) - - def Set_to_textual(self, pyobject): - return ('builtin', 'set', self.transform(pyobject.holding)) - - def Iterator_to_textual(self, pyobject): - return ('builtin', 'iter', self.transform(pyobject.holding)) - - def Generator_to_textual(self, pyobject): - return ('builtin', 'generator', self.transform(pyobject.holding)) - - def Str_to_textual(self, pyobject): - return ('builtin', 'str') - - def File_to_textual(self, pyobject): - return ('builtin', 'file') - - def BuiltinFunction_to_textual(self, pyobject): - return ('builtin', 'function', pyobject.get_name()) - - def _get_pymodule_path(self, pymodule): - return self.resource_to_path(pymodule.get_resource()) - - def resource_to_path(self, resource): - if resource.project == self.project: - return resource.path - else: - return resource.real_path - - -class TextualToPyObject(object): - """For transforming textual form to `PyObject`""" - - def __init__(self, project, allow_in_project_absolutes=False): - self.project = project - - def __call__(self, textual): - return self.transform(textual) - - def transform(self, textual): - """Transform an object from textual form to `PyObject`""" - if textual is None: - return None - type = textual[0] - try: - method = getattr(self, type + '_to_pyobject') - return method(textual) - except AttributeError: - return None - - def builtin_to_pyobject(self, textual): - name = textual[1] - method = getattr(self, 'builtin_%s_to_pyobject' % textual[1], None) - if method is not None: - return method(textual) - - def builtin_str_to_pyobject(self, textual): - return rope.base.builtins.get_str() - - def builtin_list_to_pyobject(self, textual): - holding = self.transform(textual[2]) - return rope.base.builtins.get_list(holding) - - def builtin_dict_to_pyobject(self, textual): - keys = self.transform(textual[2]) - values = self.transform(textual[3]) - return rope.base.builtins.get_dict(keys, values) - - def builtin_tuple_to_pyobject(self, textual): - objects = [] - for holding in textual[2:]: - objects.append(self.transform(holding)) - return rope.base.builtins.get_tuple(*objects) - - def builtin_set_to_pyobject(self, textual): - holding = self.transform(textual[2]) - return rope.base.builtins.get_set(holding) - - def builtin_iter_to_pyobject(self, textual): - holding = self.transform(textual[2]) - return rope.base.builtins.get_iterator(holding) - - def builtin_generator_to_pyobject(self, textual): - holding = self.transform(textual[2]) - return rope.base.builtins.get_generator(holding) - - def builtin_file_to_pyobject(self, textual): - return rope.base.builtins.get_file() - - def builtin_function_to_pyobject(self, textual): - if textual[2] in rope.base.builtins.builtins: - return rope.base.builtins.builtins[textual[2]].get_object() - - def unknown_to_pyobject(self, textual): - return None - - def none_to_pyobject(self, textual): - return None - - def _module_to_pyobject(self, textual): - path = textual[1] - return self._get_pymodule(path) - - def _hierarchical_defined_to_pyobject(self, textual): - path = textual[1] - names = textual[2].split('.') - pymodule = self._get_pymodule(path) - pyobject = pymodule - for name in names: - if pyobject is None: - return None - if isinstance(pyobject, rope.base.pyobjects.PyDefinedObject): - try: - pyobject = pyobject.get_scope()[name].get_object() - except exceptions.NameNotFoundError: - return None - else: - return None - return pyobject - - def defined_to_pyobject(self, textual): - if len(textual) == 2 or textual[2] == '': - return self._module_to_pyobject(textual) - else: - return self._hierarchical_defined_to_pyobject(textual) - - def instance_to_pyobject(self, textual): - type = self.transform(textual[1]) - if type is not None: - return rope.base.pyobjects.PyObject(type) - - def _get_pymodule(self, path): - resource = self.path_to_resource(path) - if resource is not None: - return self.project.pycore.resource_to_pyobject(resource) - - def path_to_resource(self, path): - try: - root = self.project.address - if not os.path.isabs(path): - return self.project.get_resource(path) - if path == root or path.startswith(root + os.sep): - # INFO: This is a project file; should not be absolute - return None - import rope.base.project - return rope.base.project.get_no_project().get_resource(path) - except exceptions.ResourceNotFoundError: - return None - - -class DOITextualToPyObject(TextualToPyObject): - """For transforming textual form to `PyObject` - - The textual form DOI uses is different from rope's standard - textual form. The reason is that we cannot find the needed - information by analyzing live objects. This class can be - used to transform DOI textual form to `PyObject` and later - we can convert it to standard textual form using - `TextualToPyObject` class. - - """ - - def _function_to_pyobject(self, textual): - path = textual[1] - lineno = int(textual[2]) - pymodule = self._get_pymodule(path) - if pymodule is not None: - scope = pymodule.get_scope() - inner_scope = scope.get_inner_scope_for_line(lineno) - return inner_scope.pyobject - - def _class_to_pyobject(self, textual): - path, name = textual[1:] - pymodule = self._get_pymodule(path) - if pymodule is None: - return None - module_scope = pymodule.get_scope() - suspected = None - if name in module_scope.get_names(): - suspected = module_scope[name].get_object() - if suspected is not None and \ - isinstance(suspected, rope.base.pyobjects.PyClass): - return suspected - else: - lineno = self._find_occurrence(name, pymodule.get_resource().read()) - if lineno is not None: - inner_scope = module_scope.get_inner_scope_for_line(lineno) - return inner_scope.pyobject - - def defined_to_pyobject(self, textual): - if len(textual) == 2: - return self._module_to_pyobject(textual) - else: - if textual[2].isdigit(): - result = self._function_to_pyobject(textual) - else: - result = self._class_to_pyobject(textual) - if not isinstance(result, rope.base.pyobjects.PyModule): - return result - - def _find_occurrence(self, name, source): - pattern = re.compile(r'^\s*class\s*' + name + r'\b') - lines = source.split('\n') - for i in range(len(lines)): - if pattern.match(lines[i]): - return i + 1 - - def path_to_resource(self, path): - import rope.base.libutils - root = self.project.address - relpath = rope.base.libutils.relative(root, path) - if relpath is not None: - path = relpath - return super(DOITextualToPyObject, self).path_to_resource(path) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/prefs.py --- a/vim/sadness/ropevim/src/rope/rope/base/prefs.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -class Prefs(object): - - def __init__(self): - self.prefs = {} - self.callbacks = {} - - def set(self, key, value): - """Set the value of `key` preference to `value`.""" - if key in self.callbacks: - self.callbacks[key](value) - else: - self.prefs[key] = value - - def add(self, key, value): - """Add an entry to a list preference - - Add `value` to the list of entries for the `key` preference. - - """ - if not key in self.prefs: - self.prefs[key] = [] - self.prefs[key].append(value) - - def get(self, key, default=None): - """Get the value of the key preference""" - return self.prefs.get(key, default) - - def add_callback(self, key, callback): - """Add `key` preference with `callback` function - - Whenever `key` is set the callback is called with the - given `value` as parameter. - - """ - self.callbacks[key] = callback - - def __setitem__(self, key, value): - self.set(key, value) - - def __getitem__(self, key): - return self.get(key) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/project.py --- a/vim/sadness/ropevim/src/rope/rope/base/project.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,375 +0,0 @@ -import cPickle as pickle -import os -import shutil -import sys -import warnings - -import rope.base.fscommands -from rope.base import exceptions, taskhandle, prefs, history, pycore, utils -from rope.base.resourceobserver import * -from rope.base.resources import File, Folder, _ResourceMatcher - - -class _Project(object): - - def __init__(self, fscommands): - self.observers = [] - self.fscommands = fscommands - self.prefs = prefs.Prefs() - self.data_files = _DataFiles(self) - - def get_resource(self, resource_name): - """Get a resource in a project. - - `resource_name` is the path of a resource in a project. It is - the path of a resource relative to project root. Project root - folder address is an empty string. If the resource does not - exist a `exceptions.ResourceNotFound` exception would be - raised. Use `get_file()` and `get_folder()` when you need to - get nonexistent `Resource`\s. - - """ - path = self._get_resource_path(resource_name) - if not os.path.exists(path): - raise exceptions.ResourceNotFoundError( - 'Resource <%s> does not exist' % resource_name) - elif os.path.isfile(path): - return File(self, resource_name) - elif os.path.isdir(path): - return Folder(self, resource_name) - else: - raise exceptions.ResourceNotFoundError('Unknown resource ' - + resource_name) - - def validate(self, folder): - """Validate files and folders contained in this folder - - It validates all of the files and folders contained in this - folder if some observers are interested in them. - - """ - for observer in list(self.observers): - observer.validate(folder) - - def add_observer(self, observer): - """Register a `ResourceObserver` - - See `FilteredResourceObserver`. - """ - self.observers.append(observer) - - def remove_observer(self, observer): - """Remove a registered `ResourceObserver`""" - if observer in self.observers: - self.observers.remove(observer) - - def do(self, changes, task_handle=taskhandle.NullTaskHandle()): - """Apply the changes in a `ChangeSet` - - Most of the time you call this function for committing the - changes for a refactoring. - """ - self.history.do(changes, task_handle=task_handle) - - def get_pycore(self): - return self.pycore - - def get_file(self, path): - """Get the file with `path` (it may not exist)""" - return File(self, path) - - def get_folder(self, path): - """Get the folder with `path` (it may not exist)""" - return Folder(self, path) - - def is_ignored(self, resource): - return False - - def get_prefs(self): - return self.prefs - - def _get_resource_path(self, name): - pass - - @property - @utils.saveit - def history(self): - return history.History(self) - - @property - @utils.saveit - def pycore(self): - return pycore.PyCore(self) - - def close(self): - warnings.warn('Cannot close a NoProject', - DeprecationWarning, stacklevel=2) - - ropefolder = None - - -class Project(_Project): - """A Project containing files and folders""" - - def __init__(self, projectroot, fscommands=None, - ropefolder='.ropeproject', **prefs): - """A rope project - - :parameters: - - `projectroot`: The address of the root folder of the project - - `fscommands`: Implements the file system operations used - by rope; have a look at `rope.base.fscommands` - - `ropefolder`: The name of the folder in which rope stores - project configurations and data. Pass `None` for not using - such a folder at all. - - `prefs`: Specify project preferences. These values - overwrite config file preferences. - - """ - if projectroot != '/': - projectroot = _realpath(projectroot).rstrip('/\\') - self._address = projectroot - self._ropefolder_name = ropefolder - if not os.path.exists(self._address): - os.mkdir(self._address) - elif not os.path.isdir(self._address): - raise exceptions.RopeError('Project root exists and' - ' is not a directory') - if fscommands is None: - fscommands = rope.base.fscommands.create_fscommands(self._address) - super(Project, self).__init__(fscommands) - self.ignored = _ResourceMatcher() - self.file_list = _FileListCacher(self) - self.prefs.add_callback('ignored_resources', self.ignored.set_patterns) - if ropefolder is not None: - self.prefs['ignored_resources'] = [ropefolder] - self._init_prefs(prefs) - - def get_files(self): - return self.file_list.get_files() - - def _get_resource_path(self, name): - return os.path.join(self._address, *name.split('/')) - - def _init_ropefolder(self): - if self.ropefolder is not None: - if not self.ropefolder.exists(): - self._create_recursively(self.ropefolder) - if not self.ropefolder.has_child('config.py'): - config = self.ropefolder.create_file('config.py') - config.write(self._default_config()) - - def _create_recursively(self, folder): - if folder.parent != self.root and not folder.parent.exists(): - self._create_recursively(folder.parent) - folder.create() - - def _init_prefs(self, prefs): - run_globals = {} - if self.ropefolder is not None: - config = self.get_file(self.ropefolder.path + '/config.py') - run_globals.update({'__name__': '__main__', - '__builtins__': __builtins__, - '__file__': config.real_path}) - if config.exists(): - config = self.ropefolder.get_child('config.py') - execfile(config.real_path, run_globals) - else: - exec(self._default_config(), run_globals) - if 'set_prefs' in run_globals: - run_globals['set_prefs'](self.prefs) - for key, value in prefs.items(): - self.prefs[key] = value - self._init_other_parts() - self._init_ropefolder() - if 'project_opened' in run_globals: - run_globals['project_opened'](self) - - def _default_config(self): - import rope.base.default_config - import inspect - return inspect.getsource(rope.base.default_config) - - def _init_other_parts(self): - # Forcing the creation of `self.pycore` to register observers - self.pycore - - def is_ignored(self, resource): - return self.ignored.does_match(resource) - - def sync(self): - """Closes project open resources""" - self.close() - - def close(self): - """Closes project open resources""" - self.data_files.write() - - def set(self, key, value): - """Set the `key` preference to `value`""" - self.prefs.set(key, value) - - @property - def ropefolder(self): - if self._ropefolder_name is not None: - return self.get_folder(self._ropefolder_name) - - def validate(self, folder=None): - if folder is None: - folder = self.root - super(Project, self).validate(folder) - - root = property(lambda self: self.get_resource('')) - address = property(lambda self: self._address) - - -class NoProject(_Project): - """A null object for holding out of project files. - - This class is singleton use `get_no_project` global function - """ - - def __init__(self): - fscommands = rope.base.fscommands.FileSystemCommands() - super(NoProject, self).__init__(fscommands) - - def _get_resource_path(self, name): - real_name = name.replace('/', os.path.sep) - return _realpath(real_name) - - def get_resource(self, name): - universal_name = _realpath(name).replace(os.path.sep, '/') - return super(NoProject, self).get_resource(universal_name) - - def get_files(self): - return [] - - _no_project = None - - -def get_no_project(): - if NoProject._no_project is None: - NoProject._no_project = NoProject() - return NoProject._no_project - - -class _FileListCacher(object): - - def __init__(self, project): - self.project = project - self.files = None - rawobserver = ResourceObserver( - self._changed, self._invalid, self._invalid, - self._invalid, self._invalid) - self.project.add_observer(rawobserver) - - def get_files(self): - if self.files is None: - self.files = set() - self._add_files(self.project.root) - return self.files - - def _add_files(self, folder): - for child in folder.get_children(): - if child.is_folder(): - self._add_files(child) - elif not self.project.is_ignored(child): - self.files.add(child) - - def _changed(self, resource): - if resource.is_folder(): - self.files = None - - def _invalid(self, resource, new_resource=None): - self.files = None - - -class _DataFiles(object): - - def __init__(self, project): - self.project = project - self.hooks = [] - - def read_data(self, name, compress=False, import_=False): - if self.project.ropefolder is None: - return None - compress = compress and self._can_compress() - opener = self._get_opener(compress) - file = self._get_file(name, compress) - if not compress and import_: - self._import_old_files(name) - if file.exists(): - input = opener(file.real_path, 'rb') - try: - result = [] - try: - while True: - result.append(pickle.load(input)) - except EOFError: - pass - if len(result) == 1: - return result[0] - if len(result) > 1: - return result - finally: - input.close() - - def write_data(self, name, data, compress=False): - if self.project.ropefolder is not None: - compress = compress and self._can_compress() - file = self._get_file(name, compress) - opener = self._get_opener(compress) - output = opener(file.real_path, 'wb') - try: - pickle.dump(data, output, 2) - finally: - output.close() - - def add_write_hook(self, hook): - self.hooks.append(hook) - - def write(self): - for hook in self.hooks: - hook() - - def _can_compress(self): - try: - import gzip - return True - except ImportError: - return False - - def _import_old_files(self, name): - old = self._get_file(name + '.pickle', False) - new = self._get_file(name, False) - if old.exists() and not new.exists(): - shutil.move(old.real_path, new.real_path) - - def _get_opener(self, compress): - if compress: - try: - import gzip - return gzip.open - except ImportError: - pass - return open - - def _get_file(self, name, compress): - path = self.project.ropefolder.path + '/' + name - if compress: - path += '.gz' - return self.project.get_file(path) - - -def _realpath(path): - """Return the real path of `path` - - Is equivalent to ``realpath(abspath(expanduser(path)))``. - - """ - # there is a bug in cygwin for os.path.abspath() for abs paths - if sys.platform == 'cygwin': - if path[1:3] == ':\\': - return path - return os.path.abspath(os.path.expanduser(path)) - return os.path.realpath(os.path.abspath(os.path.expanduser(path))) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/pycore.py --- a/vim/sadness/ropevim/src/rope/rope/base/pycore.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,409 +0,0 @@ -import bisect -import difflib -import sys -import warnings - -import rope.base.oi.doa -import rope.base.oi.objectinfo -import rope.base.oi.soa -from rope.base import ast, exceptions, taskhandle, utils, stdmods -from rope.base.exceptions import ModuleNotFoundError -from rope.base.pyobjectsdef import PyModule, PyPackage, PyClass -import rope.base.resources -import rope.base.resourceobserver -from rope.base import builtins - - -class PyCore(object): - - def __init__(self, project): - self.project = project - self._init_resource_observer() - self.cache_observers = [] - self.module_cache = _ModuleCache(self) - self.extension_cache = _ExtensionCache(self) - self.object_info = rope.base.oi.objectinfo.ObjectInfoManager(project) - self._init_python_files() - self._init_automatic_soa() - self._init_source_folders() - - def _init_python_files(self): - self.python_matcher = None - patterns = self.project.prefs.get('python_files', None) - if patterns is not None: - self.python_matcher = rope.base.resources._ResourceMatcher() - self.python_matcher.set_patterns(patterns) - - def _init_resource_observer(self): - callback = self._invalidate_resource_cache - observer = rope.base.resourceobserver.ResourceObserver( - changed=callback, moved=callback, removed=callback) - self.observer = rope.base.resourceobserver.FilteredResourceObserver(observer) - self.project.add_observer(self.observer) - - def _init_source_folders(self): - self._custom_source_folders = [] - for path in self.project.prefs.get('source_folders', []): - folder = self.project.get_resource(path) - self._custom_source_folders.append(folder) - - def _init_automatic_soa(self): - if not self.automatic_soa: - return - callback = self._file_changed_for_soa - observer = rope.base.resourceobserver.ResourceObserver( - changed=callback, moved=callback, removed=callback) - self.project.add_observer(observer) - - @property - def automatic_soa(self): - auto_soa = self.project.prefs.get('automatic_soi', None) - return self.project.prefs.get('automatic_soa', auto_soa) - - def _file_changed_for_soa(self, resource, new_resource=None): - old_contents = self.project.history.\ - contents_before_current_change(resource) - if old_contents is not None: - perform_soa_on_changed_scopes(self.project, resource, old_contents) - - def is_python_file(self, resource): - if resource.is_folder(): - return False - if self.python_matcher is None: - return resource.name.endswith('.py') - return self.python_matcher.does_match(resource) - - def get_module(self, name, folder=None): - """Returns a `PyObject` if the module was found.""" - module = self.find_module(name, folder) - if module is None: - module = self._builtin_module(name) - if module is None: - raise ModuleNotFoundError('Module %s not found' % name) - return module - return self.resource_to_pyobject(module) - - def _builtin_submodules(self, modname): - result = {} - for extension in self.extension_modules: - if extension.startswith(modname + '.'): - name = extension[len(modname) + 1:] - if '.' not in name: - result[name] = self._builtin_module(extension) - return result - - def _builtin_module(self, name): - return self.extension_cache.get_pymodule(name) - - def get_relative_module(self, name, folder, level): - module = self.find_relative_module(name, folder, level) - if module is None: - raise ModuleNotFoundError('Module %s not found' % name) - return self.resource_to_pyobject(module) - - def get_string_module(self, code, resource=None, force_errors=False): - """Returns a `PyObject` object for the given code - - If `force_errors` is `True`, `exceptions.ModuleSyntaxError` is - raised if module has syntax errors. This overrides - ``ignore_syntax_errors`` project config. - - """ - return PyModule(self, code, resource, force_errors=force_errors) - - def get_string_scope(self, code, resource=None): - """Returns a `Scope` object for the given code""" - return self.get_string_module(code, resource).get_scope() - - def _invalidate_resource_cache(self, resource, new_resource=None): - for observer in self.cache_observers: - observer(resource) - - def _find_module_in_folder(self, folder, modname): - module = folder - packages = modname.split('.') - for pkg in packages[:-1]: - if module.is_folder() and module.has_child(pkg): - module = module.get_child(pkg) - else: - return None - if module.is_folder(): - if module.has_child(packages[-1]) and \ - module.get_child(packages[-1]).is_folder(): - return module.get_child(packages[-1]) - elif module.has_child(packages[-1] + '.py') and \ - not module.get_child(packages[-1] + '.py').is_folder(): - return module.get_child(packages[-1] + '.py') - - def get_python_path_folders(self): - import rope.base.project - result = [] - for src in self.project.prefs.get('python_path', []) + sys.path: - try: - src_folder = rope.base.project.get_no_project().get_resource(src) - result.append(src_folder) - except rope.base.exceptions.ResourceNotFoundError: - pass - return result - - def find_module(self, modname, folder=None): - """Returns a resource corresponding to the given module - - returns None if it can not be found - """ - return self._find_module(modname, folder) - - def find_relative_module(self, modname, folder, level): - for i in range(level - 1): - folder = folder.parent - if modname == '': - return folder - else: - return self._find_module_in_folder(folder, modname) - - def _find_module(self, modname, folder=None): - """Return `modname` module resource""" - for src in self.get_source_folders(): - module = self._find_module_in_folder(src, modname) - if module is not None: - return module - for src in self.get_python_path_folders(): - module = self._find_module_in_folder(src, modname) - if module is not None: - return module - if folder is not None: - module = self._find_module_in_folder(folder, modname) - if module is not None: - return module - return None - - # INFO: It was decided not to cache source folders, since: - # - Does not take much time when the root folder contains - # packages, that is most of the time - # - We need a separate resource observer; `self.observer` - # does not get notified about module and folder creations - def get_source_folders(self): - """Returns project source folders""" - if self.project.root is None: - return [] - result = list(self._custom_source_folders) - result.extend(self._find_source_folders(self.project.root)) - return result - - def resource_to_pyobject(self, resource, force_errors=False): - return self.module_cache.get_pymodule(resource, force_errors) - - def get_python_files(self): - """Returns all python files available in the project""" - return [resource for resource in self.project.get_files() - if self.is_python_file(resource)] - - def _is_package(self, folder): - if folder.has_child('__init__.py') and \ - not folder.get_child('__init__.py').is_folder(): - return True - else: - return False - - def _find_source_folders(self, folder): - for resource in folder.get_folders(): - if self._is_package(resource): - return [folder] - result = [] - for resource in folder.get_files(): - if resource.name.endswith('.py'): - result.append(folder) - break - for resource in folder.get_folders(): - result.extend(self._find_source_folders(resource)) - return result - - def run_module(self, resource, args=None, stdin=None, stdout=None): - """Run `resource` module - - Returns a `rope.base.oi.doa.PythonFileRunner` object for - controlling the process. - - """ - perform_doa = self.project.prefs.get('perform_doi', True) - perform_doa = self.project.prefs.get('perform_doa', perform_doa) - receiver = self.object_info.doa_data_received - if not perform_doa: - receiver = None - runner = rope.base.oi.doa.PythonFileRunner( - self, resource, args, stdin, stdout, receiver) - runner.add_finishing_observer(self.module_cache.forget_all_data) - runner.run() - return runner - - def analyze_module(self, resource, should_analyze=lambda py: True, - search_subscopes=lambda py: True, followed_calls=None): - """Analyze `resource` module for static object inference - - This function forces rope to analyze this module to collect - information about function calls. `should_analyze` is a - function that is called with a `PyDefinedObject` argument. If - it returns `True` the element is analyzed. If it is `None` or - returns `False` the element is not analyzed. - - `search_subscopes` is like `should_analyze`; The difference is - that if it returns `False` the sub-scopes are all ignored. - That is it is assumed that `should_analyze` returns `False` - for all of its subscopes. - - `followed_calls` override the value of ``soa_followed_calls`` - project config. - """ - if followed_calls is None: - followed_calls = self.project.prefs.get('soa_followed_calls', 0) - pymodule = self.resource_to_pyobject(resource) - self.module_cache.forget_all_data() - rope.base.oi.soa.analyze_module( - self, pymodule, should_analyze, search_subscopes, followed_calls) - - def get_classes(self, task_handle=taskhandle.NullTaskHandle()): - warnings.warn('`PyCore.get_classes()` is deprecated', - DeprecationWarning, stacklevel=2) - return [] - - def __str__(self): - return str(self.module_cache) + str(self.object_info) - - def modname(self, resource): - if resource.is_folder(): - module_name = resource.name - source_folder = resource.parent - elif resource.name == '__init__.py': - module_name = resource.parent.name - source_folder = resource.parent.parent - else: - module_name = resource.name[:-3] - source_folder = resource.parent - - while source_folder != source_folder.parent and \ - source_folder.has_child('__init__.py'): - module_name = source_folder.name + '.' + module_name - source_folder = source_folder.parent - return module_name - - @property - @utils.cacheit - def extension_modules(self): - result = set(self.project.prefs.get('extension_modules', [])) - if self.project.prefs.get('import_dynload_stdmods', False): - result.update(stdmods.dynload_modules()) - return result - - -class _ModuleCache(object): - - def __init__(self, pycore): - self.pycore = pycore - self.module_map = {} - self.pycore.cache_observers.append(self._invalidate_resource) - self.observer = self.pycore.observer - - def _invalidate_resource(self, resource): - if resource in self.module_map: - self.forget_all_data() - self.observer.remove_resource(resource) - del self.module_map[resource] - - def get_pymodule(self, resource, force_errors=False): - if resource in self.module_map: - return self.module_map[resource] - if resource.is_folder(): - result = PyPackage(self.pycore, resource, - force_errors=force_errors) - else: - result = PyModule(self.pycore, resource=resource, - force_errors=force_errors) - if result.has_errors: - return result - self.module_map[resource] = result - self.observer.add_resource(resource) - return result - - def forget_all_data(self): - for pymodule in self.module_map.values(): - pymodule._forget_concluded_data() - - def __str__(self): - return 'PyCore caches %d PyModules\n' % len(self.module_map) - - -class _ExtensionCache(object): - - def __init__(self, pycore): - self.pycore = pycore - self.extensions = {} - - def get_pymodule(self, name): - if name == '__builtin__': - return builtins.builtins - allowed = self.pycore.extension_modules - if name not in self.extensions and name in allowed: - self.extensions[name] = builtins.BuiltinModule(name, self.pycore) - return self.extensions.get(name) - - -def perform_soa_on_changed_scopes(project, resource, old_contents): - pycore = project.pycore - if resource.exists() and pycore.is_python_file(resource): - try: - new_contents = resource.read() - # detecting changes in new_contents relative to old_contents - detector = _TextChangeDetector(new_contents, old_contents) - def search_subscopes(pydefined): - scope = pydefined.get_scope() - return detector.is_changed(scope.get_start(), scope.get_end()) - def should_analyze(pydefined): - scope = pydefined.get_scope() - start = scope.get_start() - end = scope.get_end() - return detector.consume_changes(start, end) - pycore.analyze_module(resource, should_analyze, search_subscopes) - except exceptions.ModuleSyntaxError: - pass - - -class _TextChangeDetector(object): - - def __init__(self, old, new): - self.old = old - self.new = new - self._set_diffs() - - def _set_diffs(self): - differ = difflib.Differ() - self.lines = [] - lineno = 0 - for line in differ.compare(self.old.splitlines(True), - self.new.splitlines(True)): - if line.startswith(' '): - lineno += 1 - elif line.startswith('-'): - lineno += 1 - self.lines.append(lineno) - - def is_changed(self, start, end): - """Tell whether any of start till end lines have changed - - The end points are inclusive and indices start from 1. - """ - left, right = self._get_changed(start, end) - if left < right: - return True - return False - - def consume_changes(self, start, end): - """Clear the changed status of lines from start till end""" - left, right = self._get_changed(start, end) - if left < right: - del self.lines[left:right] - return left < right - - def _get_changed(self, start, end): - left = bisect.bisect_left(self.lines, start) - right = bisect.bisect_right(self.lines, end) - return left, right diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/pynames.py --- a/vim/sadness/ropevim/src/rope/rope/base/pynames.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,199 +0,0 @@ -import rope.base.pyobjects -from rope.base import exceptions, utils - - -class PyName(object): - """References to `PyObject`\s inside python programs""" - - def get_object(self): - """Return the `PyObject` object referenced by this `PyName`""" - - def get_definition_location(self): - """Return a (module, lineno) tuple""" - - -class DefinedName(PyName): - - def __init__(self, pyobject): - self.pyobject = pyobject - - def get_object(self): - return self.pyobject - - def get_definition_location(self): - return (self.pyobject.get_module(), self.pyobject.get_ast().lineno) - - -class AssignedName(PyName): - """Only a placeholder""" - - -class UnboundName(PyName): - - def __init__(self, pyobject=None): - self.pyobject = pyobject - if self.pyobject is None: - self.pyobject = rope.base.pyobjects.get_unknown() - - def get_object(self): - return self.pyobject - - def get_definition_location(self): - return (None, None) - - -class AssignmentValue(object): - """An assigned expression""" - - def __init__(self, ast_node, levels=None, evaluation='', - assign_type=False): - """The `level` is `None` for simple assignments and is - a list of numbers for tuple assignments for example in:: - - a, (b, c) = x - - The levels for for `a` is ``[0]``, for `b` is ``[1, 0]`` and for - `c` is ``[1, 1]``. - - """ - self.ast_node = ast_node - if levels == None: - self.levels = [] - else: - self.levels = levels - self.evaluation = evaluation - self.assign_type = assign_type - - def get_lineno(self): - return self.ast_node.lineno - - -class EvaluatedName(PyName): - """A name whose object will be evaluated later""" - - def __init__(self, callback, module=None, lineno=None): - self.module = module - self.lineno = lineno - self.callback = callback - self.pyobject = _Inferred(callback, _get_concluded_data(module)) - - def get_object(self): - return self.pyobject.get() - - def get_definition_location(self): - return (self.module, self.lineno) - - def invalidate(self): - """Forget the `PyObject` this `PyName` holds""" - self.pyobject.set(None) - - -class ParameterName(PyName): - """Only a placeholder""" - - -class ImportedModule(PyName): - - def __init__(self, importing_module, module_name=None, - level=0, resource=None): - self.importing_module = importing_module - self.module_name = module_name - self.level = level - self.resource = resource - self.pymodule = _get_concluded_data(self.importing_module) - - def _current_folder(self): - resource = self.importing_module.get_module().get_resource() - if resource is None: - return None - return resource.parent - - def _get_pymodule(self): - if self.pymodule.get() is None: - pycore = self.importing_module.pycore - if self.resource is not None: - self.pymodule.set(pycore.resource_to_pyobject(self.resource)) - elif self.module_name is not None: - try: - if self.level == 0: - pymodule = pycore.get_module(self.module_name, - self._current_folder()) - else: - pymodule = pycore.get_relative_module( - self.module_name, self._current_folder(), self.level) - self.pymodule.set(pymodule) - except exceptions.ModuleNotFoundError: - pass - return self.pymodule.get() - - def get_object(self): - if self._get_pymodule() is None: - return rope.base.pyobjects.get_unknown() - return self._get_pymodule() - - def get_definition_location(self): - pymodule = self._get_pymodule() - if not isinstance(pymodule, rope.base.pyobjects.PyDefinedObject): - return (None, None) - return (pymodule.get_module(), 1) - - -class ImportedName(PyName): - - def __init__(self, imported_module, imported_name): - self.imported_module = imported_module - self.imported_name = imported_name - - def _get_imported_pyname(self): - try: - result = self.imported_module.get_object()[self.imported_name] - if result != self: - return result - except exceptions.AttributeNotFoundError: - pass - return UnboundName() - - @utils.prevent_recursion(rope.base.pyobjects.get_unknown) - def get_object(self): - return self._get_imported_pyname().get_object() - - @utils.prevent_recursion(lambda: (None, None)) - def get_definition_location(self): - return self._get_imported_pyname().get_definition_location() - - -def _get_concluded_data(module): - if module is None: - return rope.base.pyobjects._ConcludedData() - return module._get_concluded_data() - - -def _circular_inference(): - raise rope.base.pyobjects.IsBeingInferredError( - 'Circular Object Inference') - -class _Inferred(object): - - def __init__(self, get_inferred, concluded=None): - self.get_inferred = get_inferred - self.concluded = concluded - if self.concluded is None: - self.temp = None - - @utils.prevent_recursion(_circular_inference) - def get(self, *args, **kwds): - if self.concluded is None or self.concluded.get() is None: - self.set(self.get_inferred(*args, **kwds)) - if self._get() is None: - self.set(rope.base.pyobjects.get_unknown()) - return self._get() - - def set(self, pyobject): - if self.concluded is not None: - self.concluded.set(pyobject) - self.temp = pyobject - - def _get(self): - if self.concluded is not None: - return self.concluded.get() - return self.temp diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/pynamesdef.py --- a/vim/sadness/ropevim/src/rope/rope/base/pynamesdef.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -import rope.base.oi.soi -from rope.base import pynames -from rope.base.pynames import * - - -class AssignedName(pynames.AssignedName): - - def __init__(self, lineno=None, module=None, pyobject=None): - self.lineno = lineno - self.module = module - self.assignments = [] - self.pyobject = _Inferred(self._get_inferred, - pynames._get_concluded_data(module)) - self.pyobject.set(pyobject) - - @utils.prevent_recursion(lambda: None) - def _get_inferred(self): - if self.module is not None: - return rope.base.oi.soi.infer_assigned_object(self) - - def get_object(self): - return self.pyobject.get() - - def get_definition_location(self): - """Returns a (module, lineno) tuple""" - if self.lineno is None and self.assignments: - self.lineno = self.assignments[0].get_lineno() - return (self.module, self.lineno) - - def invalidate(self): - """Forget the `PyObject` this `PyName` holds""" - self.pyobject.set(None) - - -class ParameterName(pynames.ParameterName): - - def __init__(self, pyfunction, index): - self.pyfunction = pyfunction - self.index = index - - def get_object(self): - result = self.pyfunction.get_parameter(self.index) - if result is None: - result = rope.base.pyobjects.get_unknown() - return result - - def get_objects(self): - """Returns the list of objects passed as this parameter""" - return rope.base.oi.soi.get_passed_objects( - self.pyfunction, self.index) - - def get_definition_location(self): - return (self.pyfunction.get_module(), self.pyfunction.get_ast().lineno) - -_Inferred = pynames._Inferred diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/pyobjects.py --- a/vim/sadness/ropevim/src/rope/rope/base/pyobjects.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,311 +0,0 @@ -from rope.base.fscommands import _decode_data -from rope.base import ast, exceptions, utils - - -class PyObject(object): - - def __init__(self, type_): - if type_ is None: - type_ = self - self.type = type_ - - def get_attributes(self): - if self.type is self: - return {} - return self.type.get_attributes() - - def get_attribute(self, name): - if name not in self.get_attributes(): - raise exceptions.AttributeNotFoundError( - 'Attribute %s not found' % name) - return self.get_attributes()[name] - - def get_type(self): - return self.type - - def __getitem__(self, key): - """The same as ``get_attribute(key)``""" - return self.get_attribute(key) - - def __contains__(self, key): - """The same as ``key in self.get_attributes()``""" - return key in self.get_attributes() - - def __eq__(self, obj): - """Check the equality of two `PyObject`\s - - Currently it is assumed that instances (the direct instances - of `PyObject`, not the instances of its subclasses) are equal - if their types are equal. For every other object like - defineds or builtins rope assumes objects are reference - objects and their identities should match. - - """ - if self.__class__ != obj.__class__: - return False - if type(self) == PyObject: - if self is not self.type: - return self.type == obj.type - else: - return self.type is obj.type - return self is obj - - def __ne__(self, obj): - return not self.__eq__(obj) - - def __hash__(self): - """See docs for `__eq__()` method""" - if type(self) == PyObject and self != self.type: - return hash(self.type) + 1 - else: - return super(PyObject, self).__hash__() - - def __iter__(self): - """The same as ``iter(self.get_attributes())``""" - return iter(self.get_attributes()) - - _types = None - _unknown = None - - @staticmethod - def _get_base_type(name): - if PyObject._types is None: - PyObject._types = {} - base_type = PyObject(None) - PyObject._types['Type'] = base_type - PyObject._types['Module'] = PyObject(base_type) - PyObject._types['Function'] = PyObject(base_type) - PyObject._types['Unknown'] = PyObject(base_type) - return PyObject._types[name] - - -def get_base_type(name): - """Return the base type with name `name`. - - The base types are 'Type', 'Function', 'Module' and 'Unknown'. It - was used to check the type of a `PyObject` but currently its use - is discouraged. Use classes defined in this module instead. - For example instead of - ``pyobject.get_type() == get_base_type('Function')`` use - ``isinstance(pyobject, AbstractFunction)``. - - You can use `AbstractClass` for classes, `AbstractFunction` for - functions, and `AbstractModule` for modules. You can also use - `PyFunction` and `PyClass` for testing if an object is - defined somewhere and rope can access its source. These classes - provide more methods. - - """ - return PyObject._get_base_type(name) - - -def get_unknown(): - """Return a pyobject whose type is unknown - - Note that two unknown objects are equal. So for example you can - write:: - - if pyname.get_object() == get_unknown(): - print 'cannot determine what this pyname holds' - - Rope could have used `None` for indicating unknown objects but - we had to check that in many places. So actually this method - returns a null object. - - """ - if PyObject._unknown is None: - PyObject._unknown = PyObject(get_base_type('Unknown')) - return PyObject._unknown - - -class AbstractClass(PyObject): - - def __init__(self): - super(AbstractClass, self).__init__(get_base_type('Type')) - - def get_name(self): - pass - - def get_doc(self): - pass - - def get_superclasses(self): - return [] - - -class AbstractFunction(PyObject): - - def __init__(self): - super(AbstractFunction, self).__init__(get_base_type('Function')) - - def get_name(self): - pass - - def get_doc(self): - pass - - def get_param_names(self, special_args=True): - return [] - - def get_returned_object(self, args): - return get_unknown() - - -class AbstractModule(PyObject): - - def __init__(self, doc=None): - super(AbstractModule, self).__init__(get_base_type('Module')) - - def get_doc(self): - pass - - def get_resource(self): - pass - - -class PyDefinedObject(object): - """Python defined names that rope can access their sources""" - - def __init__(self, pycore, ast_node, parent): - self.pycore = pycore - self.ast_node = ast_node - self.scope = None - self.parent = parent - self.structural_attributes = None - self.concluded_attributes = self.get_module()._get_concluded_data() - self.attributes = self.get_module()._get_concluded_data() - self.defineds = None - - visitor_class = None - - @utils.prevent_recursion(lambda: {}) - def _get_structural_attributes(self): - if self.structural_attributes is None: - self.structural_attributes = self._create_structural_attributes() - return self.structural_attributes - - @utils.prevent_recursion(lambda: {}) - def _get_concluded_attributes(self): - if self.concluded_attributes.get() is None: - self._get_structural_attributes() - self.concluded_attributes.set(self._create_concluded_attributes()) - return self.concluded_attributes.get() - - def get_attributes(self): - if self.attributes.get() is None: - result = dict(self._get_concluded_attributes()) - result.update(self._get_structural_attributes()) - self.attributes.set(result) - return self.attributes.get() - - def get_attribute(self, name): - if name in self._get_structural_attributes(): - return self._get_structural_attributes()[name] - if name in self._get_concluded_attributes(): - return self._get_concluded_attributes()[name] - raise exceptions.AttributeNotFoundError('Attribute %s not found' % - name) - - def get_scope(self): - if self.scope is None: - self.scope = self._create_scope() - return self.scope - - def get_module(self): - current_object = self - while current_object.parent is not None: - current_object = current_object.parent - return current_object - - def get_doc(self): - if len(self.get_ast().body) > 0: - expr = self.get_ast().body[0] - if isinstance(expr, ast.Expr) and \ - isinstance(expr.value, ast.Str): - docstring = expr.value.s - coding = self.get_module().coding - return _decode_data(docstring, coding) - - def _get_defined_objects(self): - if self.defineds is None: - self._get_structural_attributes() - return self.defineds - - def _create_structural_attributes(self): - if self.visitor_class is None: - return {} - new_visitor = self.visitor_class(self.pycore, self) - for child in ast.get_child_nodes(self.ast_node): - ast.walk(child, new_visitor) - self.defineds = new_visitor.defineds - return new_visitor.names - - def _create_concluded_attributes(self): - return {} - - def get_ast(self): - return self.ast_node - - def _create_scope(self): - pass - - -class PyFunction(PyDefinedObject, AbstractFunction): - """Only a placeholder""" - - -class PyClass(PyDefinedObject, AbstractClass): - """Only a placeholder""" - - -class _ConcludedData(object): - - def __init__(self): - self.data_ = None - - def set(self, data): - self.data_ = data - - def get(self): - return self.data_ - - data = property(get, set) - - def _invalidate(self): - self.data = None - - def __str__(self): - return '<' + str(self.data) + '>' - - -class _PyModule(PyDefinedObject, AbstractModule): - - def __init__(self, pycore, ast_node, resource): - self.resource = resource - self.concluded_data = [] - AbstractModule.__init__(self) - PyDefinedObject.__init__(self, pycore, ast_node, None) - - def _get_concluded_data(self): - new_data = _ConcludedData() - self.concluded_data.append(new_data) - return new_data - - def _forget_concluded_data(self): - for data in self.concluded_data: - data._invalidate() - - def get_resource(self): - return self.resource - - -class PyModule(_PyModule): - """Only a placeholder""" - - -class PyPackage(_PyModule): - """Only a placeholder""" - - -class IsBeingInferredError(exceptions.RopeError): - pass diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/pyobjectsdef.py --- a/vim/sadness/ropevim/src/rope/rope/base/pyobjectsdef.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,537 +0,0 @@ -import rope.base.codeanalyze -import rope.base.evaluate -import rope.base.builtins -import rope.base.oi.soi -import rope.base.pyscopes -from rope.base import (pynamesdef as pynames, exceptions, ast, - astutils, pyobjects, fscommands, arguments, utils) -from rope.base.pyobjects import * - - -class PyFunction(pyobjects.PyFunction): - - def __init__(self, pycore, ast_node, parent): - AbstractFunction.__init__(self) - PyDefinedObject.__init__(self, pycore, ast_node, parent) - self.arguments = self.ast_node.args - self.parameter_pyobjects = pynames._Inferred( - self._infer_parameters, self.get_module()._get_concluded_data()) - self.returned = pynames._Inferred(self._infer_returned) - self.parameter_pynames = None - - def _create_structural_attributes(self): - return {} - - def _create_concluded_attributes(self): - return {} - - def _create_scope(self): - return rope.base.pyscopes.FunctionScope(self.pycore, self, - _FunctionVisitor) - - def _infer_parameters(self): - pyobjects = rope.base.oi.soi.infer_parameter_objects(self) - self._handle_special_args(pyobjects) - return pyobjects - - def _infer_returned(self, args=None): - return rope.base.oi.soi.infer_returned_object(self, args) - - def _handle_special_args(self, pyobjects): - if len(pyobjects) == len(self.arguments.args): - if self.arguments.vararg: - pyobjects.append(rope.base.builtins.get_list()) - if self.arguments.kwarg: - pyobjects.append(rope.base.builtins.get_dict()) - - def _set_parameter_pyobjects(self, pyobjects): - if pyobjects is not None: - self._handle_special_args(pyobjects) - self.parameter_pyobjects.set(pyobjects) - - def get_parameters(self): - if self.parameter_pynames is None: - result = {} - for index, name in enumerate(self.get_param_names()): - # TODO: handle tuple parameters - result[name] = pynames.ParameterName(self, index) - self.parameter_pynames = result - return self.parameter_pynames - - def get_parameter(self, index): - if index < len(self.parameter_pyobjects.get()): - return self.parameter_pyobjects.get()[index] - - def get_returned_object(self, args): - return self.returned.get(args) - - def get_name(self): - return self.get_ast().name - - def get_param_names(self, special_args=True): - # TODO: handle tuple parameters - result = [node.id for node in self.arguments.args - if isinstance(node, ast.Name)] - if special_args: - if self.arguments.vararg: - result.append(self.arguments.vararg) - if self.arguments.kwarg: - result.append(self.arguments.kwarg) - return result - - def get_kind(self): - """Get function type - - It returns one of 'function', 'method', 'staticmethod' or - 'classmethod' strs. - - """ - scope = self.parent.get_scope() - if isinstance(self.parent, PyClass): - for decorator in self.decorators: - pyname = rope.base.evaluate.eval_node(scope, decorator) - if pyname == rope.base.builtins.builtins['staticmethod']: - return 'staticmethod' - if pyname == rope.base.builtins.builtins['classmethod']: - return 'classmethod' - return 'method' - return 'function' - - @property - def decorators(self): - try: - return getattr(self.ast_node, 'decorator_list') - except AttributeError: - return getattr(self.ast_node, 'decorators', None) - - -class PyClass(pyobjects.PyClass): - - def __init__(self, pycore, ast_node, parent): - self.visitor_class = _ClassVisitor - AbstractClass.__init__(self) - PyDefinedObject.__init__(self, pycore, ast_node, parent) - self.parent = parent - self._superclasses = self.get_module()._get_concluded_data() - - def get_superclasses(self): - if self._superclasses.get() is None: - self._superclasses.set(self._get_bases()) - return self._superclasses.get() - - def get_name(self): - return self.get_ast().name - - def _create_concluded_attributes(self): - result = {} - for base in reversed(self.get_superclasses()): - result.update(base.get_attributes()) - return result - - def _get_bases(self): - result = [] - for base_name in self.ast_node.bases: - base = rope.base.evaluate.eval_node(self.parent.get_scope(), - base_name) - if base is not None and \ - base.get_object().get_type() == get_base_type('Type'): - result.append(base.get_object()) - return result - - def _create_scope(self): - return rope.base.pyscopes.ClassScope(self.pycore, self) - - -class PyModule(pyobjects.PyModule): - - def __init__(self, pycore, source=None, - resource=None, force_errors=False): - ignore = pycore.project.prefs.get('ignore_syntax_errors', False) - syntax_errors = force_errors or not ignore - self.has_errors = False - try: - source, node = self._init_source(pycore, source, resource) - except exceptions.ModuleSyntaxError: - self.has_errors = True - if syntax_errors: - raise - else: - source = '\n' - node = ast.parse('\n') - self.source_code = source - self.star_imports = [] - self.visitor_class = _GlobalVisitor - self.coding = fscommands.read_str_coding(self.source_code) - super(PyModule, self).__init__(pycore, node, resource) - - def _init_source(self, pycore, source_code, resource): - filename = 'string' - if resource: - filename = resource.path - try: - if source_code is None: - source_bytes = resource.read_bytes() - source_code = fscommands.file_data_to_unicode(source_bytes) - else: - if isinstance(source_code, unicode): - source_bytes = fscommands.unicode_to_file_data(source_code) - else: - source_bytes = source_code - ast_node = ast.parse(source_bytes, filename=filename) - except SyntaxError, e: - raise exceptions.ModuleSyntaxError(filename, e.lineno, e.msg) - except UnicodeDecodeError, e: - raise exceptions.ModuleSyntaxError(filename, 1, '%s' % (e.reason)) - return source_code, ast_node - - @utils.prevent_recursion(lambda: {}) - def _create_concluded_attributes(self): - result = {} - for star_import in self.star_imports: - result.update(star_import.get_names()) - return result - - def _create_scope(self): - return rope.base.pyscopes.GlobalScope(self.pycore, self) - - @property - @utils.saveit - def lines(self): - """A `SourceLinesAdapter`""" - return rope.base.codeanalyze.SourceLinesAdapter(self.source_code) - - @property - @utils.saveit - def logical_lines(self): - """A `LogicalLinesFinder`""" - return rope.base.codeanalyze.CachingLogicalLineFinder(self.lines) - - -class PyPackage(pyobjects.PyPackage): - - def __init__(self, pycore, resource=None, force_errors=False): - self.resource = resource - init_dot_py = self._get_init_dot_py() - if init_dot_py is not None: - ast_node = pycore.resource_to_pyobject( - init_dot_py, force_errors=force_errors).get_ast() - else: - ast_node = ast.parse('\n') - super(PyPackage, self).__init__(pycore, ast_node, resource) - - def _create_structural_attributes(self): - result = {} - modname = self.pycore.modname(self.resource) - extension_submodules = self.pycore._builtin_submodules(modname) - for name, module in extension_submodules.iteritems(): - result[name] = rope.base.builtins.BuiltinName(module) - if self.resource is None: - return result - for name, resource in self._get_child_resources().items(): - result[name] = pynames.ImportedModule(self, resource=resource) - return result - - def _create_concluded_attributes(self): - result = {} - init_dot_py = self._get_init_dot_py() - if init_dot_py: - init_object = self.pycore.resource_to_pyobject(init_dot_py) - result.update(init_object.get_attributes()) - return result - - def _get_child_resources(self): - result = {} - for child in self.resource.get_children(): - if child.is_folder(): - result[child.name] = child - elif child.name.endswith('.py') and \ - child.name != '__init__.py': - name = child.name[:-3] - result[name] = child - return result - - def _get_init_dot_py(self): - if self.resource is not None and self.resource.has_child('__init__.py'): - return self.resource.get_child('__init__.py') - else: - return None - - def _create_scope(self): - return self.get_module().get_scope() - - def get_module(self): - init_dot_py = self._get_init_dot_py() - if init_dot_py: - return self.pycore.resource_to_pyobject(init_dot_py) - return self - - -class _AssignVisitor(object): - - def __init__(self, scope_visitor): - self.scope_visitor = scope_visitor - self.assigned_ast = None - - def _Assign(self, node): - self.assigned_ast = node.value - for child_node in node.targets: - ast.walk(child_node, self) - - def _assigned(self, name, assignment=None): - self.scope_visitor._assigned(name, assignment) - - def _Name(self, node): - assignment = None - if self.assigned_ast is not None: - assignment = pynames.AssignmentValue(self.assigned_ast) - self._assigned(node.id, assignment) - - def _Tuple(self, node): - names = astutils.get_name_levels(node) - for name, levels in names: - assignment = None - if self.assigned_ast is not None: - assignment = pynames.AssignmentValue(self.assigned_ast, levels) - self._assigned(name, assignment) - - def _Attribute(self, node): - pass - - def _Subscript(self, node): - pass - - def _Slice(self, node): - pass - - -class _ScopeVisitor(object): - - def __init__(self, pycore, owner_object): - self.pycore = pycore - self.owner_object = owner_object - self.names = {} - self.defineds = [] - - def get_module(self): - if self.owner_object is not None: - return self.owner_object.get_module() - else: - return None - - def _ClassDef(self, node): - pyclass = PyClass(self.pycore, node, self.owner_object) - self.names[node.name] = pynames.DefinedName(pyclass) - self.defineds.append(pyclass) - - def _FunctionDef(self, node): - pyfunction = PyFunction(self.pycore, node, self.owner_object) - for decorator in pyfunction.decorators: - if isinstance(decorator, ast.Name) and decorator.id == 'property': - if isinstance(self, _ClassVisitor): - type_ = rope.base.builtins.Property(pyfunction) - arg = pynames.UnboundName(PyObject(self.owner_object)) - def _eval(type_=type_, arg=arg): - return type_.get_property_object( - arguments.ObjectArguments([arg])) - self.names[node.name] = pynames.EvaluatedName( - _eval, module=self.get_module(), lineno=node.lineno) - break - else: - self.names[node.name] = pynames.DefinedName(pyfunction) - self.defineds.append(pyfunction) - - def _Assign(self, node): - ast.walk(node, _AssignVisitor(self)) - - def _AugAssign(self, node): - pass - - def _For(self, node): - names = self._update_evaluated(node.target, node.iter, - '.__iter__().next()') - for child in node.body + node.orelse: - ast.walk(child, self) - - def _assigned(self, name, assignment): - pyname = self.names.get(name, None) - if pyname is None: - pyname = pynames.AssignedName(module=self.get_module()) - if isinstance(pyname, pynames.AssignedName): - if assignment is not None: - pyname.assignments.append(assignment) - self.names[name] = pyname - - def _update_evaluated(self, targets, assigned, - evaluation= '', eval_type=False): - result = {} - names = astutils.get_name_levels(targets) - for name, levels in names: - assignment = pynames.AssignmentValue(assigned, levels, - evaluation, eval_type) - self._assigned(name, assignment) - return result - - def _With(self, node): - if node.optional_vars: - self._update_evaluated(node.optional_vars, - node.context_expr, '.__enter__()') - for child in node.body: - ast.walk(child, self) - - def _excepthandler(self, node): - if node.name is not None and isinstance(node.name, ast.Name): - type_node = node.type - if isinstance(node.type, ast.Tuple) and type_node.elts: - type_node = type_node.elts[0] - self._update_evaluated(node.name, type_node, eval_type=True) - for child in node.body: - ast.walk(child, self) - - def _ExceptHandler(self, node): - self._excepthandler(node) - - def _Import(self, node): - for import_pair in node.names: - module_name = import_pair.name - alias = import_pair.asname - first_package = module_name.split('.')[0] - if alias is not None: - imported = pynames.ImportedModule(self.get_module(), - module_name) - if not self._is_ignored_import(imported): - self.names[alias] = imported - else: - imported = pynames.ImportedModule(self.get_module(), - first_package) - if not self._is_ignored_import(imported): - self.names[first_package] = imported - - def _ImportFrom(self, node): - level = 0 - if node.level: - level = node.level - imported_module = pynames.ImportedModule(self.get_module(), - node.module, level) - if self._is_ignored_import(imported_module): - return - if len(node.names) == 1 and node.names[0].name == '*': - if isinstance(self.owner_object, PyModule): - self.owner_object.star_imports.append( - StarImport(imported_module)) - else: - for imported_name in node.names: - imported = imported_name.name - alias = imported_name.asname - if alias is not None: - imported = alias - self.names[imported] = pynames.ImportedName(imported_module, - imported_name.name) - - def _is_ignored_import(self, imported_module): - if not self.pycore.project.prefs.get('ignore_bad_imports', False): - return False - return not isinstance(imported_module.get_object(), AbstractModule) - - def _Global(self, node): - module = self.get_module() - for name in node.names: - if module is not None: - try: - pyname = module[name] - except exceptions.AttributeNotFoundError: - pyname = pynames.AssignedName(node.lineno) - self.names[name] = pyname - - -class _GlobalVisitor(_ScopeVisitor): - - def __init__(self, pycore, owner_object): - super(_GlobalVisitor, self).__init__(pycore, owner_object) - - -class _ClassVisitor(_ScopeVisitor): - - def __init__(self, pycore, owner_object): - super(_ClassVisitor, self).__init__(pycore, owner_object) - - def _FunctionDef(self, node): - _ScopeVisitor._FunctionDef(self, node) - if len(node.args.args) > 0: - first = node.args.args[0] - if isinstance(first, ast.Name): - new_visitor = _ClassInitVisitor(self, first.id) - for child in ast.get_child_nodes(node): - ast.walk(child, new_visitor) - - -class _FunctionVisitor(_ScopeVisitor): - - def __init__(self, pycore, owner_object): - super(_FunctionVisitor, self).__init__(pycore, owner_object) - self.returned_asts = [] - self.generator = False - - def _Return(self, node): - if node.value is not None: - self.returned_asts.append(node.value) - - def _Yield(self, node): - if node.value is not None: - self.returned_asts.append(node.value) - self.generator = True - - -class _ClassInitVisitor(_AssignVisitor): - - def __init__(self, scope_visitor, self_name): - super(_ClassInitVisitor, self).__init__(scope_visitor) - self.self_name = self_name - - def _Attribute(self, node): - if not isinstance(node.ctx, ast.Store): - return - if isinstance(node.value, ast.Name) and \ - node.value.id == self.self_name: - if node.attr not in self.scope_visitor.names: - self.scope_visitor.names[node.attr] = pynames.AssignedName( - lineno=node.lineno, module=self.scope_visitor.get_module()) - if self.assigned_ast is not None: - pyname = self.scope_visitor.names[node.attr] - if isinstance(pyname, pynames.AssignedName): - pyname.assignments.append( - pynames.AssignmentValue(self.assigned_ast)) - - def _Tuple(self, node): - if not isinstance(node.ctx, ast.Store): - return - for child in ast.get_child_nodes(node): - ast.walk(child, self) - - def _Name(self, node): - pass - - def _FunctionDef(self, node): - pass - - def _ClassDef(self, node): - pass - - def _For(self, node): - pass - - def _With(self, node): - pass - - -class StarImport(object): - - def __init__(self, imported_module): - self.imported_module = imported_module - - def get_names(self): - result = {} - imported = self.imported_module.get_object() - for name in imported: - if not name.startswith('_'): - result[name] = pynames.ImportedName(self.imported_module, name) - return result diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/pyscopes.py --- a/vim/sadness/ropevim/src/rope/rope/base/pyscopes.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,313 +0,0 @@ -import rope.base.builtins -import rope.base.codeanalyze -import rope.base.pynames -from rope.base import ast, exceptions, utils - - -class Scope(object): - - def __init__(self, pycore, pyobject, parent_scope): - self.pycore = pycore - self.pyobject = pyobject - self.parent = parent_scope - - def get_names(self): - """Return the names defined or imported in this scope""" - return self.pyobject.get_attributes() - - def get_defined_names(self): - """Return the names defined in this scope""" - return self.pyobject._get_structural_attributes() - - def get_name(self, name): - """Return name `PyName` defined in this scope""" - if name not in self.get_names(): - raise exceptions.NameNotFoundError('name %s not found' % name) - return self.get_names()[name] - - def __getitem__(self, key): - """The same as ``get_name(key)``""" - return self.get_name(key) - - def __contains__(self, key): - """The same as ``key in self.get_names()``""" - return key in self.get_names() - - @utils.saveit - def get_scopes(self): - """Return the subscopes of this scope - - The returned scopes should be sorted by the order they appear. - """ - return self._create_scopes() - - def lookup(self, name): - if name in self.get_names(): - return self.get_names()[name] - if self.parent is not None: - return self.parent._propagated_lookup(name) - return None - - def get_propagated_names(self): - """Return the visible names of this scope - - Return the names defined in this scope that are visible from - scopes containing this scope. This method returns the same - dictionary returned by `get_names()` except for `ClassScope` - which returns an empty dict. - """ - return self.get_names() - - def _propagated_lookup(self, name): - if name in self.get_propagated_names(): - return self.get_propagated_names()[name] - if self.parent is not None: - return self.parent._propagated_lookup(name) - return None - - def _create_scopes(self): - return [pydefined.get_scope() - for pydefined in self.pyobject._get_defined_objects()] - - def _get_global_scope(self): - current = self - while current.parent is not None: - current = current.parent - return current - - def get_start(self): - return self.pyobject.get_ast().lineno - - def get_body_start(self): - body = self.pyobject.get_ast().body - if body: - return body[0].lineno - return self.get_start() - - def get_end(self): - pymodule = self._get_global_scope().pyobject - return pymodule.logical_lines.logical_line_in(self.logical_end)[1] - - @utils.saveit - def get_logical_end(self): - global_scope = self._get_global_scope() - return global_scope._scope_finder.find_scope_end(self) - - start = property(get_start) - end = property(get_end) - logical_end = property(get_logical_end) - - def get_kind(self): - pass - - -class GlobalScope(Scope): - - def __init__(self, pycore, module): - super(GlobalScope, self).__init__(pycore, module, None) - self.names = module._get_concluded_data() - - def get_start(self): - return 1 - - def get_kind(self): - return 'Module' - - def get_name(self, name): - try: - return self.pyobject[name] - except exceptions.AttributeNotFoundError: - if name in self.builtin_names: - return self.builtin_names[name] - raise exceptions.NameNotFoundError('name %s not found' % name) - - def get_names(self): - if self.names.get() is None: - result = dict(self.builtin_names) - result.update(super(GlobalScope, self).get_names()) - self.names.set(result) - return self.names.get() - - def get_inner_scope_for_line(self, lineno, indents=None): - return self._scope_finder.get_holding_scope(self, lineno, indents) - - def get_inner_scope_for_offset(self, offset): - return self._scope_finder.get_holding_scope_for_offset(self, offset) - - @property - @utils.saveit - def _scope_finder(self): - return _HoldingScopeFinder(self.pyobject) - - @property - def builtin_names(self): - return rope.base.builtins.builtins.get_attributes() - - -class FunctionScope(Scope): - - def __init__(self, pycore, pyobject, visitor): - super(FunctionScope, self).__init__(pycore, pyobject, - pyobject.parent.get_scope()) - self.names = None - self.returned_asts = None - self.is_generator = None - self.defineds = None - self.visitor = visitor - - def _get_names(self): - if self.names is None: - self._visit_function() - return self.names - - def _visit_function(self): - if self.names is None: - new_visitor = self.visitor(self.pycore, self.pyobject) - for n in ast.get_child_nodes(self.pyobject.get_ast()): - ast.walk(n, new_visitor) - self.names = new_visitor.names - self.names.update(self.pyobject.get_parameters()) - self.returned_asts = new_visitor.returned_asts - self.is_generator = new_visitor.generator - self.defineds = new_visitor.defineds - - def _get_returned_asts(self): - if self.names is None: - self._visit_function() - return self.returned_asts - - def _is_generator(self): - if self.is_generator is None: - self._get_returned_asts() - return self.is_generator - - def get_names(self): - return self._get_names() - - def _create_scopes(self): - if self.defineds is None: - self._visit_function() - return [pydefined.get_scope() for pydefined in self.defineds] - - def get_kind(self): - return 'Function' - - def invalidate_data(self): - for pyname in self.get_names().values(): - if isinstance(pyname, (rope.base.pynames.AssignedName, - rope.base.pynames.EvaluatedName)): - pyname.invalidate() - - -class ClassScope(Scope): - - def __init__(self, pycore, pyobject): - super(ClassScope, self).__init__(pycore, pyobject, - pyobject.parent.get_scope()) - - def get_kind(self): - return 'Class' - - def get_propagated_names(self): - return {} - - -class _HoldingScopeFinder(object): - - def __init__(self, pymodule): - self.pymodule = pymodule - - def get_indents(self, lineno): - return rope.base.codeanalyze.count_line_indents( - self.lines.get_line(lineno)) - - def _get_scope_indents(self, scope): - return self.get_indents(scope.get_start()) - - def get_holding_scope(self, module_scope, lineno, line_indents=None): - if line_indents is None: - line_indents = self.get_indents(lineno) - current_scope = module_scope - new_scope = current_scope - while new_scope is not None and \ - (new_scope.get_kind() == 'Module' or - self._get_scope_indents(new_scope) <= line_indents): - current_scope = new_scope - if current_scope.get_start() == lineno and \ - current_scope.get_kind() != 'Module': - return current_scope - new_scope = None - for scope in current_scope.get_scopes(): - if scope.get_start() <= lineno: - if lineno <= scope.get_end(): - new_scope = scope - break - else: - break - return current_scope - - def _is_empty_line(self, lineno): - line = self.lines.get_line(lineno) - return line.strip() == '' or line.lstrip().startswith('#') - - def _get_body_indents(self, scope): - return self.get_indents(scope.get_body_start()) - - def get_holding_scope_for_offset(self, scope, offset): - return self.get_holding_scope( - scope, self.lines.get_line_number(offset)) - - def find_scope_end(self, scope): - if not scope.parent: - return self.lines.length() - end = scope.pyobject.get_ast().body[-1].lineno - scope_start = self.pymodule.logical_lines.logical_line_in(scope.start) - if scope_start[1] >= end: - # handling one-liners - body_indents = self._get_scope_indents(scope) + 4 - else: - body_indents = self._get_body_indents(scope) - for l in self.logical_lines.generate_starts( - min(end + 1, self.lines.length()), self.lines.length() + 1): - if not self._is_empty_line(l): - if self.get_indents(l) < body_indents: - return end - else: - end = l - return end - - @property - def lines(self): - return self.pymodule.lines - - @property - def code(self): - return self.pymodule.source_code - - @property - def logical_lines(self): - return self.pymodule.logical_lines - -class TemporaryScope(Scope): - """Currently used for list comprehensions and generator expressions - - These scopes do not appear in the `get_scopes()` method of their - parent scopes. - """ - - def __init__(self, pycore, parent_scope, names): - super(TemporaryScope, self).__init__( - pycore, parent_scope.pyobject, parent_scope) - self.names = names - - def get_names(self): - return self.names - - def get_defined_names(self): - return self.names - - def _create_scopes(self): - return [] - - def get_kind(self): - return 'Temporary' diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/resourceobserver.py --- a/vim/sadness/ropevim/src/rope/rope/base/resourceobserver.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,271 +0,0 @@ -import os - - -class ResourceObserver(object): - """Provides the interface for observing resources - - `ResourceObserver`\s can be registered using `Project. - add_observer()`. But most of the time `FilteredResourceObserver` - should be used. `ResourceObserver`\s report all changes passed - to them and they don't report changes to all resources. For - example if a folder is removed, it only calls `removed()` for that - folder and not its contents. You can use - `FilteredResourceObserver` if you are interested in changes only - to a list of resources. And you want changes to be reported on - individual resources. - - """ - - def __init__(self, changed=None, moved=None, created=None, - removed=None, validate=None): - self.changed = changed - self.moved = moved - self.created = created - self.removed = removed - self._validate = validate - - def resource_changed(self, resource): - """It is called when the resource changes""" - if self.changed is not None: - self.changed(resource) - - def resource_moved(self, resource, new_resource): - """It is called when a resource is moved""" - if self.moved is not None: - self.moved(resource, new_resource) - - def resource_created(self, resource): - """Is called when a new resource is created""" - if self.created is not None: - self.created(resource) - - def resource_removed(self, resource): - """Is called when a new resource is removed""" - if self.removed is not None: - self.removed(resource) - - def validate(self, resource): - """Validate the existence of this resource and its children. - - This function is called when rope need to update its resource - cache about the files that might have been changed or removed - by other processes. - - """ - if self._validate is not None: - self._validate(resource) - - -class FilteredResourceObserver(object): - """A useful decorator for `ResourceObserver` - - Most resource observers have a list of resources and are - interested only in changes to those files. This class satisfies - this need. It dispatches resource changed and removed messages. - It performs these tasks: - - * Changes to files and folders are analyzed to check whether any - of the interesting resources are changed or not. If they are, - it reports these changes to `resource_observer` passed to the - constructor. - * When a resource is removed it checks whether any of the - interesting resources are contained in that folder and reports - them to `resource_observer`. - * When validating a folder it validates all of the interesting - files in that folder. - - Since most resource observers are interested in a list of - resources that change over time, `add_resource` and - `remove_resource` might be useful. - - """ - - def __init__(self, resource_observer, initial_resources=None, - timekeeper=None): - self.observer = resource_observer - self.resources = {} - if timekeeper is not None: - self.timekeeper = timekeeper - else: - self.timekeeper = ChangeIndicator() - if initial_resources is not None: - for resource in initial_resources: - self.add_resource(resource) - - def add_resource(self, resource): - """Add a resource to the list of interesting resources""" - if resource.exists(): - self.resources[resource] = self.timekeeper.get_indicator(resource) - else: - self.resources[resource] = None - - def remove_resource(self, resource): - """Add a resource to the list of interesting resources""" - if resource in self.resources: - del self.resources[resource] - - def clear_resources(self): - """Removes all registered resources""" - self.resources.clear() - - def resource_changed(self, resource): - changes = _Changes() - self._update_changes_caused_by_changed(changes, resource) - self._perform_changes(changes) - - def _update_changes_caused_by_changed(self, changes, changed): - if changed in self.resources: - changes.add_changed(changed) - if self._is_parent_changed(changed): - changes.add_changed(changed.parent) - - def _update_changes_caused_by_moved(self, changes, resource, - new_resource=None): - if resource in self.resources: - changes.add_removed(resource, new_resource) - if new_resource in self.resources: - changes.add_created(new_resource) - if resource.is_folder(): - for file in list(self.resources): - if resource.contains(file): - new_file = self._calculate_new_resource( - resource, new_resource, file) - changes.add_removed(file, new_file) - if self._is_parent_changed(resource): - changes.add_changed(resource.parent) - if new_resource is not None: - if self._is_parent_changed(new_resource): - changes.add_changed(new_resource.parent) - - def _is_parent_changed(self, child): - return child.parent in self.resources - - def resource_moved(self, resource, new_resource): - changes = _Changes() - self._update_changes_caused_by_moved(changes, resource, new_resource) - self._perform_changes(changes) - - def resource_created(self, resource): - changes = _Changes() - self._update_changes_caused_by_created(changes, resource) - self._perform_changes(changes) - - def _update_changes_caused_by_created(self, changes, resource): - if resource in self.resources: - changes.add_created(resource) - if self._is_parent_changed(resource): - changes.add_changed(resource.parent) - - def resource_removed(self, resource): - changes = _Changes() - self._update_changes_caused_by_moved(changes, resource) - self._perform_changes(changes) - - def _perform_changes(self, changes): - for resource in changes.changes: - self.observer.resource_changed(resource) - self.resources[resource] = self.timekeeper.get_indicator(resource) - for resource, new_resource in changes.moves.items(): - self.resources[resource] = None - if new_resource is not None: - self.observer.resource_moved(resource, new_resource) - else: - self.observer.resource_removed(resource) - for resource in changes.creations: - self.observer.resource_created(resource) - self.resources[resource] = self.timekeeper.get_indicator(resource) - - def validate(self, resource): - changes = _Changes() - for file in self._search_resource_moves(resource): - if file in self.resources: - self._update_changes_caused_by_moved(changes, file) - for file in self._search_resource_changes(resource): - if file in self.resources: - self._update_changes_caused_by_changed(changes, file) - for file in self._search_resource_creations(resource): - if file in self.resources: - changes.add_created(file) - self._perform_changes(changes) - - def _search_resource_creations(self, resource): - creations = set() - if resource in self.resources and resource.exists() and \ - self.resources[resource] is None: - creations.add(resource) - if resource.is_folder(): - for file in self.resources: - if file.exists() and resource.contains(file) and \ - self.resources[file] is None: - creations.add(file) - return creations - - def _search_resource_moves(self, resource): - all_moved = set() - if resource in self.resources and not resource.exists(): - all_moved.add(resource) - if resource.is_folder(): - for file in self.resources: - if resource.contains(file): - if not file.exists(): - all_moved.add(file) - moved = set(all_moved) - for folder in [file for file in all_moved if file.is_folder()]: - if folder in moved: - for file in list(moved): - if folder.contains(file): - moved.remove(file) - return moved - - def _search_resource_changes(self, resource): - changed = set() - if resource in self.resources and self._is_changed(resource): - changed.add(resource) - if resource.is_folder(): - for file in self.resources: - if file.exists() and resource.contains(file): - if self._is_changed(file): - changed.add(file) - return changed - - def _is_changed(self, resource): - if self.resources[resource] is None: - return False - return self.resources[resource] != self.timekeeper.get_indicator(resource) - - def _calculate_new_resource(self, main, new_main, resource): - if new_main is None: - return None - diff = resource.path[len(main.path):] - return resource.project.get_resource(new_main.path + diff) - - -class ChangeIndicator(object): - - def get_indicator(self, resource): - """Return the modification time and size of a `Resource`.""" - path = resource.real_path - # on dos, mtime does not change for a folder when files are added - if os.name != 'posix' and os.path.isdir(path): - return (os.path.getmtime(path), - len(os.listdir(path)), - os.path.getsize(path)) - return (os.path.getmtime(path), - os.path.getsize(path)) - - -class _Changes(object): - - def __init__(self): - self.changes = set() - self.creations = set() - self.moves = {} - - def add_changed(self, resource): - self.changes.add(resource) - - def add_removed(self, resource, new_resource=None): - self.moves[resource] = new_resource - - def add_created(self, resource): - self.creations.add(resource) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/resources.py --- a/vim/sadness/ropevim/src/rope/rope/base/resources.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,211 +0,0 @@ -import os -import re - -import rope.base.change -import rope.base.fscommands -from rope.base import exceptions - - -class Resource(object): - """Represents files and folders in a project""" - - def __init__(self, project, path): - self.project = project - self._path = path - - def move(self, new_location): - """Move resource to `new_location`""" - self._perform_change(rope.base.change.MoveResource(self, new_location), - 'Moving <%s> to <%s>' % (self.path, new_location)) - - def remove(self): - """Remove resource from the project""" - self._perform_change(rope.base.change.RemoveResource(self), - 'Removing <%s>' % self.path) - - def is_folder(self): - """Return true if the resource is a folder""" - - def create(self): - """Create this resource""" - - def exists(self): - return os.path.exists(self.real_path) - - @property - def parent(self): - parent = '/'.join(self.path.split('/')[0:-1]) - return self.project.get_folder(parent) - - @property - def path(self): - """Return the path of this resource relative to the project root - - The path is the list of parent directories separated by '/' followed - by the resource name. - """ - return self._path - - @property - def name(self): - """Return the name of this resource""" - return self.path.split('/')[-1] - - @property - def real_path(self): - """Return the file system path of this resource""" - return self.project._get_resource_path(self.path) - - def __eq__(self, obj): - return self.__class__ == obj.__class__ and self.path == obj.path - - def __ne__(self, obj): - return not self.__eq__(obj) - - def __hash__(self): - return hash(self.path) - - def _perform_change(self, change_, description): - changes = rope.base.change.ChangeSet(description) - changes.add_change(change_) - self.project.do(changes) - - -class File(Resource): - """Represents a file""" - - def __init__(self, project, name): - super(File, self).__init__(project, name) - - def read(self): - data = self.read_bytes() - try: - return rope.base.fscommands.file_data_to_unicode(data) - except UnicodeDecodeError, e: - raise exceptions.ModuleDecodeError(self.path, e.reason) - - def read_bytes(self): - return open(self.real_path, 'rb').read() - - def write(self, contents): - try: - if contents == self.read(): - return - except IOError: - pass - self._perform_change(rope.base.change.ChangeContents(self, contents), - 'Writing file <%s>' % self.path) - - def is_folder(self): - return False - - def create(self): - self.parent.create_file(self.name) - - -class Folder(Resource): - """Represents a folder""" - - def __init__(self, project, name): - super(Folder, self).__init__(project, name) - - def is_folder(self): - return True - - def get_children(self): - """Return the children of this folder""" - result = [] - for name in os.listdir(self.real_path): - try: - child = self.get_child(name) - except exceptions.ResourceNotFoundError: - continue - if not self.project.is_ignored(child): - result.append(self.get_child(name)) - return result - - def create_file(self, file_name): - self._perform_change( - rope.base.change.CreateFile(self, file_name), - 'Creating file <%s>' % self._get_child_path(file_name)) - return self.get_child(file_name) - - def create_folder(self, folder_name): - self._perform_change( - rope.base.change.CreateFolder(self, folder_name), - 'Creating folder <%s>' % self._get_child_path(folder_name)) - return self.get_child(folder_name) - - def _get_child_path(self, name): - if self.path: - return self.path + '/' + name - else: - return name - - def get_child(self, name): - return self.project.get_resource(self._get_child_path(name)) - - def has_child(self, name): - try: - self.get_child(name) - return True - except exceptions.ResourceNotFoundError: - return False - - def get_files(self): - return [resource for resource in self.get_children() - if not resource.is_folder()] - - def get_folders(self): - return [resource for resource in self.get_children() - if resource.is_folder()] - - def contains(self, resource): - if self == resource: - return False - return self.path == '' or resource.path.startswith(self.path + '/') - - def create(self): - self.parent.create_folder(self.name) - - -class _ResourceMatcher(object): - - def __init__(self): - self.patterns = [] - self._compiled_patterns = [] - - def set_patterns(self, patterns): - """Specify which resources to match - - `patterns` is a `list` of `str`\s that can contain ``*`` and - ``?`` signs for matching resource names. - - """ - self._compiled_patterns = None - self.patterns = patterns - - def _add_pattern(self, pattern): - re_pattern = pattern.replace('.', '\\.').\ - replace('*', '[^/]*').replace('?', '[^/]').\ - replace('//', '/(.*/)?') - re_pattern = '^(.*/)?' + re_pattern + '(/.*)?$' - self.compiled_patterns.append(re.compile(re_pattern)) - - def does_match(self, resource): - for pattern in self.compiled_patterns: - if pattern.match(resource.path): - return True - path = os.path.join(resource.project.address, - *resource.path.split('/')) - if os.path.islink(path): - return True - return False - - @property - def compiled_patterns(self): - if self._compiled_patterns is None: - self._compiled_patterns = [] - for pattern in self.patterns: - self._add_pattern(pattern) - return self._compiled_patterns diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/simplify.py --- a/vim/sadness/ropevim/src/rope/rope/base/simplify.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -"""A module to ease code analysis - -This module is here to help source code analysis. -""" -import re - -from rope.base import codeanalyze, utils - - -@utils.cached(7) -def real_code(source): - """Simplify `source` for analysis - - It replaces: - - * comments with spaces - * strs with a new str filled with spaces - * implicit and explicit continuations with spaces - * tabs and semicolons with spaces - - The resulting code is a lot easier to analyze if we are interested - only in offsets. - """ - collector = codeanalyze.ChangeCollector(source) - for start, end in ignored_regions(source): - if source[start] == '#': - replacement = ' ' * (end - start) - else: - replacement = '"%s"' % (' ' * (end - start - 2)) - collector.add_change(start, end, replacement) - source = collector.get_changed() or source - collector = codeanalyze.ChangeCollector(source) - parens = 0 - for match in _parens.finditer(source): - i = match.start() - c = match.group() - if c in '({[': - parens += 1 - if c in ')}]': - parens -= 1 - if c == '\n' and parens > 0: - collector.add_change(i, i + 1, ' ') - source = collector.get_changed() or source - return source.replace('\\\n', ' ').replace('\t', ' ').replace(';', '\n') - - -@utils.cached(7) -def ignored_regions(source): - """Return ignored regions like strings and comments in `source` """ - return [(match.start(), match.end()) for match in _str.finditer(source)] - - -_str = re.compile('%s|%s' % (codeanalyze.get_comment_pattern(), - codeanalyze.get_string_pattern())) -_parens = re.compile(r'[\({\[\]}\)\n]') diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/stdmods.py --- a/vim/sadness/ropevim/src/rope/rope/base/stdmods.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -import os -import sys - -from rope.base import utils - - -def _stdlib_path(): - import inspect - return os.path.dirname(inspect.getsourcefile(inspect)) - -@utils.cached(1) -def standard_modules(): - return python_modules() | dynload_modules() - -@utils.cached(1) -def python_modules(): - result = set() - lib_path = _stdlib_path() - if os.path.exists(lib_path): - for name in os.listdir(lib_path): - path = os.path.join(lib_path, name) - if os.path.isdir(path): - if '-' not in name: - result.add(name) - else: - if name.endswith('.py'): - result.add(name[:-3]) - return result - -@utils.cached(1) -def dynload_modules(): - result = set(sys.builtin_module_names) - dynload_path = os.path.join(_stdlib_path(), 'lib-dynload') - if os.path.exists(dynload_path): - for name in os.listdir(dynload_path): - path = os.path.join(dynload_path, name) - if os.path.isfile(path): - if name.endswith('.so') or name.endswith('.dll'): - result.add(os.path.splitext(name)[0]) - return result diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/taskhandle.py --- a/vim/sadness/ropevim/src/rope/rope/base/taskhandle.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -import warnings - -from rope.base import exceptions - - -class TaskHandle(object): - - def __init__(self, name='Task', interrupts=True): - """Construct a TaskHandle - - If `interrupts` is `False` the task won't be interrupted by - calling `TaskHandle.stop()`. - - """ - self.name = name - self.interrupts = interrupts - self.stopped = False - self.job_sets = [] - self.observers = [] - - def stop(self): - """Interrupts the refactoring""" - if self.interrupts: - self.stopped = True - self._inform_observers() - - def current_jobset(self): - """Return the current `JobSet`""" - if self.job_sets: - return self.job_sets[-1] - - def add_observer(self, observer): - """Register an observer for this task handle - - The observer is notified whenever the task is stopped or - a job gets finished. - - """ - self.observers.append(observer) - - def is_stopped(self): - return self.stopped - - def get_jobsets(self): - return self.job_sets - - def create_jobset(self, name='JobSet', count=None): - result = JobSet(self, name=name, count=count) - self.job_sets.append(result) - self._inform_observers() - return result - - def _inform_observers(self): - for observer in list(self.observers): - observer() - - -class JobSet(object): - - def __init__(self, handle, name, count): - self.handle = handle - self.name = name - self.count = count - self.done = 0 - self.job_name = None - - def started_job(self, name): - self.check_status() - self.job_name = name - self.handle._inform_observers() - - def finished_job(self): - self.check_status() - self.done += 1 - self.handle._inform_observers() - self.job_name = None - - def check_status(self): - if self.handle.is_stopped(): - raise exceptions.InterruptedTaskError() - - def get_active_job_name(self): - return self.job_name - - def get_percent_done(self): - if self.count is not None and self.count > 0: - percent = self.done * 100 // self.count - return min(percent, 100) - - def get_name(self): - return self.name - - -class NullTaskHandle(object): - - def __init__(self): - pass - - def is_stopped(self): - return False - - def stop(self): - pass - - def create_jobset(self, *args, **kwds): - return NullJobSet() - - def get_jobsets(self): - return [] - - def add_observer(self, observer): - pass - - -class NullJobSet(object): - - def started_job(self, name): - pass - - def finished_job(self): - pass - - def check_status(self): - pass - - def get_active_job_name(self): - pass - - def get_percent_done(self): - pass - - def get_name(self): - pass diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/utils.py --- a/vim/sadness/ropevim/src/rope/rope/base/utils.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -import warnings - - -def saveit(func): - """A decorator that caches the return value of a function""" - - name = '_' + func.__name__ - def _wrapper(self, *args, **kwds): - if not hasattr(self, name): - setattr(self, name, func(self, *args, **kwds)) - return getattr(self, name) - return _wrapper - -cacheit = saveit - -def prevent_recursion(default): - """A decorator that returns the return value of `default` in recursions""" - def decorator(func): - name = '_calling_%s_' % func.__name__ - def newfunc(self, *args, **kwds): - if getattr(self, name, False): - return default() - setattr(self, name, True) - try: - return func(self, *args, **kwds) - finally: - setattr(self, name, False) - return newfunc - return decorator - - -def ignore_exception(exception_class): - """A decorator that ignores `exception_class` exceptions""" - def _decorator(func): - def newfunc(*args, **kwds): - try: - return func(*args, **kwds) - except exception_class: - pass - return newfunc - return _decorator - - -def deprecated(message=None): - """A decorator for deprecated functions""" - def _decorator(func, message=message): - if message is None: - message = '%s is deprecated' % func.__name__ - def newfunc(*args, **kwds): - warnings.warn(message, DeprecationWarning, stacklevel=2) - return func(*args, **kwds) - return newfunc - return _decorator - - -def cached(count): - """A caching decorator based on parameter objects""" - def decorator(func): - return _Cached(func, count) - return decorator - -class _Cached(object): - - def __init__(self, func, count): - self.func = func - self.cache = [] - self.count = count - - def __call__(self, *args, **kwds): - key = (args, kwds) - for cached_key, cached_result in self.cache: - if cached_key == key: - return cached_result - result = self.func(*args, **kwds) - self.cache.append((key, result)) - if len(self.cache) > self.count: - del self.cache[0] - return result diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/base/worder.py --- a/vim/sadness/ropevim/src/rope/rope/base/worder.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,521 +0,0 @@ -import bisect -import keyword - -import rope.base.simplify - - -def get_name_at(resource, offset): - source_code = resource.read() - word_finder = Worder(source_code) - return word_finder.get_word_at(offset) - - -class Worder(object): - """A class for finding boundaries of words and expressions - - Note that in these methods, offset should be the index of the - character not the index of the character after it. - """ - - def __init__(self, code, handle_ignores=False): - simplified = rope.base.simplify.real_code(code) - self.code_finder = _RealFinder(simplified, code) - self.handle_ignores = handle_ignores - self.code = code - - def _init_ignores(self): - ignores = rope.base.simplify.ignored_regions(self.code) - self.dumb_finder = _RealFinder(self.code, self.code) - self.starts = [ignored[0] for ignored in ignores] - self.ends = [ignored[1] for ignored in ignores] - - def _context_call(self, name, offset): - if self.handle_ignores: - if not hasattr(self, 'starts'): - self._init_ignores() - start = bisect.bisect(self.starts, offset) - if start > 0 and offset < self.ends[start - 1]: - return getattr(self.dumb_finder, name)(offset) - return getattr(self.code_finder, name)(offset) - - def get_primary_at(self, offset): - return self._context_call('get_primary_at', offset) - - def get_word_at(self, offset): - return self._context_call('get_word_at', offset) - - def get_primary_range(self, offset): - return self._context_call('get_primary_range', offset) - - def get_splitted_primary_before(self, offset): - return self._context_call('get_splitted_primary_before', offset) - - def get_word_range(self, offset): - return self._context_call('get_word_range', offset) - - def is_function_keyword_parameter(self, offset): - return self.code_finder.is_function_keyword_parameter(offset) - - def is_a_class_or_function_name_in_header(self, offset): - return self.code_finder.is_a_class_or_function_name_in_header(offset) - - def is_from_statement_module(self, offset): - return self.code_finder.is_from_statement_module(offset) - - def is_from_aliased(self, offset): - return self.code_finder.is_from_aliased(offset) - - def find_parens_start_from_inside(self, offset): - return self.code_finder.find_parens_start_from_inside(offset) - - def is_a_name_after_from_import(self, offset): - return self.code_finder.is_a_name_after_from_import(offset) - - def is_from_statement(self, offset): - return self.code_finder.is_from_statement(offset) - - def get_from_aliased(self, offset): - return self.code_finder.get_from_aliased(offset) - - def is_import_statement(self, offset): - return self.code_finder.is_import_statement(offset) - - def is_assigned_here(self, offset): - return self.code_finder.is_assigned_here(offset) - - def is_a_function_being_called(self, offset): - return self.code_finder.is_a_function_being_called(offset) - - def get_word_parens_range(self, offset): - return self.code_finder.get_word_parens_range(offset) - - def is_name_assigned_in_class_body(self, offset): - return self.code_finder.is_name_assigned_in_class_body(offset) - - def is_on_function_call_keyword(self, offset): - return self.code_finder.is_on_function_call_keyword(offset) - - def _find_parens_start(self, offset): - return self.code_finder._find_parens_start(offset) - - def get_parameters(self, first, last): - return self.code_finder.get_parameters(first, last) - - def get_from_module(self, offset): - return self.code_finder.get_from_module(offset) - - def is_assigned_in_a_tuple_assignment(self, offset): - return self.code_finder.is_assigned_in_a_tuple_assignment(offset) - - def get_assignment_type(self, offset): - return self.code_finder.get_assignment_type(offset) - - def get_function_and_args_in_header(self, offset): - return self.code_finder.get_function_and_args_in_header(offset) - - def get_lambda_and_args(self, offset): - return self.code_finder.get_lambda_and_args(offset) - - def find_function_offset(self, offset): - return self.code_finder.find_function_offset(offset) - - -class _RealFinder(object): - - def __init__(self, code, raw): - self.code = code - self.raw = raw - - def _find_word_start(self, offset): - current_offset = offset - while current_offset >= 0 and self._is_id_char(current_offset): - current_offset -= 1 - return current_offset + 1 - - def _find_word_end(self, offset): - while offset + 1 < len(self.code) and self._is_id_char(offset + 1): - offset += 1 - return offset - - def _find_last_non_space_char(self, offset): - while offset >= 0 and self.code[offset].isspace(): - if self.code[offset] == '\n': - return offset - offset -= 1 - return max(-1, offset) - - def get_word_at(self, offset): - offset = self._get_fixed_offset(offset) - return self.raw[self._find_word_start(offset): - self._find_word_end(offset) + 1] - - def _get_fixed_offset(self, offset): - if offset >= len(self.code): - return offset - 1 - if not self._is_id_char(offset): - if offset > 0 and self._is_id_char(offset - 1): - return offset - 1 - if offset < len(self.code) - 1 and self._is_id_char(offset + 1): - return offset + 1 - return offset - - def _is_id_char(self, offset): - return self.code[offset].isalnum() or self.code[offset] == '_' - - def _find_string_start(self, offset): - kind = self.code[offset] - try: - return self.code.rindex(kind, 0, offset) - except ValueError: - return 0 - - def _find_parens_start(self, offset): - offset = self._find_last_non_space_char(offset - 1) - while offset >= 0 and self.code[offset] not in '[({': - if self.code[offset] not in ':,': - offset = self._find_primary_start(offset) - offset = self._find_last_non_space_char(offset - 1) - return offset - - def _find_atom_start(self, offset): - old_offset = offset - if self.code[offset] == '\n': - return offset + 1 - if self.code[offset].isspace(): - offset = self._find_last_non_space_char(offset) - if self.code[offset] in '\'"': - return self._find_string_start(offset) - if self.code[offset] in ')]}': - return self._find_parens_start(offset) - if self._is_id_char(offset): - return self._find_word_start(offset) - return old_offset - - def _find_primary_without_dot_start(self, offset): - """It tries to find the undotted primary start - - It is different from `self._get_atom_start()` in that it - follows function calls, too; such as in ``f(x)``. - - """ - last_atom = offset - offset = self._find_last_non_space_char(last_atom) - while offset > 0 and self.code[offset] in ')]': - last_atom = self._find_parens_start(offset) - offset = self._find_last_non_space_char(last_atom - 1) - if offset >= 0 and (self.code[offset] in '"\'})]' or - self._is_id_char(offset)): - atom_start = self._find_atom_start(offset) - if not keyword.iskeyword(self.code[atom_start:offset + 1]): - return atom_start - return last_atom - - def _find_primary_start(self, offset): - if offset >= len(self.code): - offset = len(self.code) - 1 - if self.code[offset] != '.': - offset = self._find_primary_without_dot_start(offset) - else: - offset = offset + 1 - while offset > 0: - prev = self._find_last_non_space_char(offset - 1) - if offset <= 0 or self.code[prev] != '.': - break - offset = self._find_primary_without_dot_start(prev - 1) - if not self._is_id_char(offset): - break - - return offset - - def get_primary_at(self, offset): - offset = self._get_fixed_offset(offset) - start, end = self.get_primary_range(offset) - return self.raw[start:end].strip() - - def get_splitted_primary_before(self, offset): - """returns expression, starting, starting_offset - - This function is used in `rope.codeassist.assist` function. - """ - if offset == 0: - return ('', '', 0) - end = offset - 1 - word_start = self._find_atom_start(end) - real_start = self._find_primary_start(end) - if self.code[word_start:offset].strip() == '': - word_start = end - if self.code[end].isspace(): - word_start = end - if self.code[real_start:word_start].strip() == '': - real_start = word_start - if real_start == word_start == end and not self._is_id_char(end): - return ('', '', offset) - if real_start == word_start: - return ('', self.raw[word_start:offset], word_start) - else: - if self.code[end] == '.': - return (self.raw[real_start:end], '', offset) - last_dot_position = word_start - if self.code[word_start] != '.': - last_dot_position = self._find_last_non_space_char(word_start - 1) - last_char_position = self._find_last_non_space_char(last_dot_position - 1) - if self.code[word_start].isspace(): - word_start = offset - return (self.raw[real_start:last_char_position + 1], - self.raw[word_start:offset], word_start) - - def _get_line_start(self, offset): - try: - return self.code.rindex('\n', 0, offset + 1) - except ValueError: - return 0 - - def _get_line_end(self, offset): - try: - return self.code.index('\n', offset) - except ValueError: - return len(self.code) - - def is_name_assigned_in_class_body(self, offset): - word_start = self._find_word_start(offset - 1) - word_end = self._find_word_end(offset) + 1 - if '.' in self.code[word_start:word_end]: - return False - line_start = self._get_line_start(word_start) - line = self.code[line_start:word_start].strip() - return not line and self.get_assignment_type(offset) == '=' - - def is_a_class_or_function_name_in_header(self, offset): - word_start = self._find_word_start(offset - 1) - line_start = self._get_line_start(word_start) - prev_word = self.code[line_start:word_start].strip() - return prev_word in ['def', 'class'] - - def _find_first_non_space_char(self, offset): - if offset >= len(self.code): - return len(self.code) - while offset < len(self.code) and self.code[offset].isspace(): - if self.code[offset] == '\n': - return offset - offset += 1 - return offset - - def is_a_function_being_called(self, offset): - word_end = self._find_word_end(offset) + 1 - next_char = self._find_first_non_space_char(word_end) - return next_char < len(self.code) and \ - self.code[next_char] == '(' and \ - not self.is_a_class_or_function_name_in_header(offset) - - def _find_import_end(self, start): - return self._get_line_end(start) - - def is_import_statement(self, offset): - try: - last_import = self.code.rindex('import ', 0, offset) - except ValueError: - return False - return self._find_import_end(last_import + 7) >= offset - - def is_from_statement(self, offset): - try: - last_from = self.code.rindex('from ', 0, offset) - from_import = self.code.index(' import ', last_from) - from_names = from_import + 8 - except ValueError: - return False - from_names = self._find_first_non_space_char(from_names) - return self._find_import_end(from_names) >= offset - - def is_from_statement_module(self, offset): - if offset >= len(self.code) - 1: - return False - stmt_start = self._find_primary_start(offset) - line_start = self._get_line_start(stmt_start) - prev_word = self.code[line_start:stmt_start].strip() - return prev_word == 'from' - - def is_a_name_after_from_import(self, offset): - try: - line_start = self._get_line_start(offset) - last_from = self.code.rindex('from ', line_start, offset) - from_import = self.code.index(' import ', last_from) - from_names = from_import + 8 - except ValueError: - return False - if from_names - 1 > offset: - return False - return self._find_import_end(from_names) >= offset - - def get_from_module(self, offset): - try: - last_from = self.code.rindex('from ', 0, offset) - import_offset = self.code.index(' import ', last_from) - end = self._find_last_non_space_char(import_offset) - return self.get_primary_at(end) - except ValueError: - pass - - def is_from_aliased(self, offset): - if not self.is_a_name_after_from_import(offset): - return False - try: - end = self._find_word_end(offset) - as_end = min(self._find_word_end(end + 1), len(self.code)) - as_start = self._find_word_start(as_end) - if self.code[as_start:as_end + 1] == 'as': - return True - except ValueError: - return False - - def get_from_aliased(self, offset): - try: - end = self._find_word_end(offset) - as_ = self._find_word_end(end + 1) - alias = self._find_word_end(as_ + 1) - start = self._find_word_start(alias) - return self.raw[start:alias + 1] - except ValueError: - pass - - def is_function_keyword_parameter(self, offset): - word_end = self._find_word_end(offset) - if word_end + 1 == len(self.code): - return False - next_char = self._find_first_non_space_char(word_end + 1) - equals = self.code[next_char:next_char + 2] - if equals == '==' or not equals.startswith('='): - return False - word_start = self._find_word_start(offset) - prev_char = self._find_last_non_space_char(word_start - 1) - return prev_char - 1 >= 0 and self.code[prev_char] in ',(' - - def is_on_function_call_keyword(self, offset): - stop = self._get_line_start(offset) - if self._is_id_char(offset): - offset = self._find_word_start(offset) - 1 - offset = self._find_last_non_space_char(offset) - if offset <= stop or self.code[offset] not in '(,': - return False - parens_start = self.find_parens_start_from_inside(offset) - return stop < parens_start - - def find_parens_start_from_inside(self, offset): - stop = self._get_line_start(offset) - opens = 1 - while offset > stop: - if self.code[offset] == '(': - break - if self.code[offset] != ',': - offset = self._find_primary_start(offset) - offset -= 1 - return max(stop, offset) - - def is_assigned_here(self, offset): - return self.get_assignment_type(offset) is not None - - def get_assignment_type(self, offset): - # XXX: does not handle tuple assignments - word_end = self._find_word_end(offset) - next_char = self._find_first_non_space_char(word_end + 1) - single = self.code[next_char:next_char + 1] - double = self.code[next_char:next_char + 2] - triple = self.code[next_char:next_char + 3] - if double not in ('==', '<=', '>=', '!='): - for op in [single, double, triple]: - if op.endswith('='): - return op - - def get_primary_range(self, offset): - start = self._find_primary_start(offset) - end = self._find_word_end(offset) + 1 - return (start, end) - - def get_word_range(self, offset): - offset = max(0, offset) - start = self._find_word_start(offset) - end = self._find_word_end(offset) + 1 - return (start, end) - - def get_word_parens_range(self, offset, opening='(', closing=')'): - end = self._find_word_end(offset) - start_parens = self.code.index(opening, end) - index = start_parens - open_count = 0 - while index < len(self.code): - if self.code[index] == opening: - open_count += 1 - if self.code[index] == closing: - open_count -= 1 - if open_count == 0: - return (start_parens, index + 1) - index += 1 - return (start_parens, index) - - def get_parameters(self, first, last): - keywords = [] - args = [] - current = self._find_last_non_space_char(last - 1) - while current > first: - primary_start = current - current = self._find_primary_start(current) - while current != first and self.code[current] not in '=,': - current = self._find_last_non_space_char(current - 1) - primary = self.raw[current + 1:primary_start + 1].strip() - if self.code[current] == '=': - primary_start = current - 1 - current -= 1 - while current != first and self.code[current] not in ',': - current = self._find_last_non_space_char(current - 1) - param_name = self.raw[current + 1:primary_start + 1].strip() - keywords.append((param_name, primary)) - else: - args.append(primary) - current = self._find_last_non_space_char(current - 1) - args.reverse() - keywords.reverse() - return args, keywords - - def is_assigned_in_a_tuple_assignment(self, offset): - start = self._get_line_start(offset) - end = self._get_line_end(offset) - primary_start = self._find_primary_start(offset) - primary_end = self._find_word_end(offset) - - prev_char_offset = self._find_last_non_space_char(primary_start - 1) - next_char_offset = self._find_first_non_space_char(primary_end + 1) - next_char = prev_char = '' - if prev_char_offset >= start: - prev_char = self.code[prev_char_offset] - if next_char_offset < end: - next_char = self.code[next_char_offset] - try: - equals_offset = self.code.index('=', start, end) - except ValueError: - return False - if prev_char not in '(,' and next_char not in ',)': - return False - parens_start = self.find_parens_start_from_inside(offset) - # XXX: only handling (x, y) = value - return offset < equals_offset and \ - self.code[start:parens_start].strip() == '' - - def get_function_and_args_in_header(self, offset): - offset = self.find_function_offset(offset) - lparens, rparens = self.get_word_parens_range(offset) - return self.raw[offset:rparens + 1] - - def find_function_offset(self, offset, definition='def '): - while True: - offset = self.code.index(definition, offset) - if offset == 0 or not self._is_id_char(offset - 1): - break - offset += 1 - def_ = offset + 4 - return self._find_first_non_space_char(def_) - - def get_lambda_and_args(self, offset): - offset = self.find_function_offset(offset, definition = 'lambda ') - lparens, rparens = self.get_word_parens_range(offset, opening=' ', closing=':') - return self.raw[offset:rparens + 1] - diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/contrib/__init__.py --- a/vim/sadness/ropevim/src/rope/rope/contrib/__init__.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -"""rope IDE tools package - -This package contains modules that can be used in IDEs -but do not depend on the UI. So these modules will be used -by `rope.ui` modules. - -""" diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/contrib/autoimport.py --- a/vim/sadness/ropevim/src/rope/rope/contrib/autoimport.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,217 +0,0 @@ -import re - -from rope.base import (exceptions, pynames, resourceobserver, - taskhandle, pyobjects, builtins, resources) -from rope.refactor import importutils - - -class AutoImport(object): - """A class for finding the module that provides a name - - This class maintains a cache of global names in python modules. - Note that this cache is not accurate and might be out of date. - - """ - - def __init__(self, project, observe=True, underlined=False): - """Construct an AutoImport object - - If `observe` is `True`, listen for project changes and update - the cache. - - If `underlined` is `True`, underlined names are cached, too. - """ - self.project = project - self.underlined = underlined - self.names = project.data_files.read_data('globalnames') - if self.names is None: - self.names = {} - project.data_files.add_write_hook(self._write) - # XXX: using a filtered observer - observer = resourceobserver.ResourceObserver( - changed=self._changed, moved=self._moved, removed=self._removed) - if observe: - project.add_observer(observer) - - def import_assist(self, starting): - """Return a list of ``(name, module)`` tuples - - This function tries to find modules that have a global name - that starts with `starting`. - """ - # XXX: breaking if gave up! use generators - result = [] - for module in self.names: - for global_name in self.names[module]: - if global_name.startswith(starting): - result.append((global_name, module)) - return result - - def get_modules(self, name): - """Return the list of modules that have global `name`""" - result = [] - for module in self.names: - if name in self.names[module]: - result.append(module) - return result - - def get_all_names(self): - """Return the list of all cached global names""" - result = set() - for module in self.names: - result.update(set(self.names[module])) - return result - - def get_name_locations(self, name): - """Return a list of ``(resource, lineno)`` tuples""" - result = [] - pycore = self.project.pycore - for module in self.names: - if name in self.names[module]: - try: - pymodule = pycore.get_module(module) - if name in pymodule: - pyname = pymodule[name] - module, lineno = pyname.get_definition_location() - if module is not None: - resource = module.get_module().get_resource() - if resource is not None and lineno is not None: - result.append((resource, lineno)) - except exceptions.ModuleNotFoundError: - pass - return result - - def generate_cache(self, resources=None, underlined=None, - task_handle=taskhandle.NullTaskHandle()): - """Generate global name cache for project files - - If `resources` is a list of `rope.base.resource.File`\s, only - those files are searched; otherwise all python modules in the - project are cached. - - """ - if resources is None: - resources = self.project.pycore.get_python_files() - job_set = task_handle.create_jobset( - 'Generatig autoimport cache', len(resources)) - for file in resources: - job_set.started_job('Working on <%s>' % file.path) - self.update_resource(file, underlined) - job_set.finished_job() - - def generate_modules_cache(self, modules, underlined=None, - task_handle=taskhandle.NullTaskHandle()): - """Generate global name cache for modules listed in `modules`""" - job_set = task_handle.create_jobset( - 'Generatig autoimport cache for modules', len(modules)) - for modname in modules: - job_set.started_job('Working on <%s>' % modname) - if modname.endswith('.*'): - mod = self.project.pycore.find_module(modname[:-2]) - if mod: - for sub in submodules(mod): - self.update_resource(sub, underlined) - else: - self.update_module(modname, underlined) - job_set.finished_job() - - def clear_cache(self): - """Clear all entries in global-name cache - - It might be a good idea to use this function before - regenerating global names. - - """ - self.names.clear() - - def find_insertion_line(self, code): - """Guess at what line the new import should be inserted""" - match = re.search(r'^(def|class)\s+', code) - if match is not None: - code = code[:match.start()] - try: - pymodule = self.project.pycore.get_string_module(code) - except exceptions.ModuleSyntaxError: - return 1 - testmodname = '__rope_testmodule_rope' - importinfo = importutils.NormalImport(((testmodname, None),)) - module_imports = importutils.get_module_imports( - self.project.pycore, pymodule) - module_imports.add_import(importinfo) - code = module_imports.get_changed_source() - offset = code.index(testmodname) - lineno = code.count('\n', 0, offset) + 1 - return lineno - - def update_resource(self, resource, underlined=None): - """Update the cache for global names in `resource`""" - try: - pymodule = self.project.pycore.resource_to_pyobject(resource) - modname = self._module_name(resource) - self._add_names(pymodule, modname, underlined) - except exceptions.ModuleSyntaxError: - pass - - def update_module(self, modname, underlined=None): - """Update the cache for global names in `modname` module - - `modname` is the name of a module. - """ - try: - pymodule = self.project.pycore.get_module(modname) - self._add_names(pymodule, modname, underlined) - except exceptions.ModuleNotFoundError: - pass - - def _module_name(self, resource): - return self.project.pycore.modname(resource) - - def _add_names(self, pymodule, modname, underlined): - if underlined is None: - underlined = self.underlined - globals = [] - if isinstance(pymodule, pyobjects.PyDefinedObject): - attributes = pymodule._get_structural_attributes() - else: - attributes = pymodule.get_attributes() - for name, pyname in attributes.items(): - if not underlined and name.startswith('_'): - continue - if isinstance(pyname, (pynames.AssignedName, pynames.DefinedName)): - globals.append(name) - if isinstance(pymodule, builtins.BuiltinModule): - globals.append(name) - self.names[modname] = globals - - def _write(self): - self.project.data_files.write_data('globalnames', self.names) - - def _changed(self, resource): - if not resource.is_folder(): - self.update_resource(resource) - - def _moved(self, resource, newresource): - if not resource.is_folder(): - modname = self._module_name(resource) - if modname in self.names: - del self.names[modname] - self.update_resource(newresource) - - def _removed(self, resource): - if not resource.is_folder(): - modname = self._module_name(resource) - if modname in self.names: - del self.names[modname] - - -def submodules(mod): - if isinstance(mod, resources.File): - if mod.name.endswith('.py') and mod.name != '__init__.py': - return set([mod]) - return set() - if not mod.has_child('__init__.py'): - return set() - result = set([mod]) - for child in mod.get_children(): - result |= submodules(child) - return result diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/contrib/changestack.py --- a/vim/sadness/ropevim/src/rope/rope/contrib/changestack.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -"""For performing many refactorings as a single command - -`changestack` module can be used to perform many refactorings on top -of each other as one bigger command. It can be used like:: - - stack = ChangeStack(project, 'my big command') - - #.. - stack.push(refactoring1.get_changes()) - #.. - stack.push(refactoring2.get_changes()) - #.. - stack.push(refactoringX.get_changes()) - - stack.pop_all() - changes = stack.merged() - -Now `changes` can be previewed or performed as before. -""" - -from rope.base import change - - -class ChangeStack(object): - - def __init__(self, project, description='merged changes'): - self.project = project - self.description = description - self.stack = [] - - def push(self, changes): - self.stack.append(changes) - self.project.do(changes) - - def pop_all(self): - for i in range(len(self.stack)): - self.project.history.undo(drop=True) - - def merged(self): - result = change.ChangeSet(self.description) - for changes in self.stack: - for c in self._basic_changes(changes): - result.add_change(c) - return result - - def _basic_changes(self, changes): - if isinstance(changes, change.ChangeSet): - for child in changes.changes: - for atom in self._basic_changes(child): - yield atom - else: - yield changes diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/contrib/codeassist.py --- a/vim/sadness/ropevim/src/rope/rope/contrib/codeassist.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,647 +0,0 @@ -import keyword -import sys -import warnings - -import rope.base.codeanalyze -import rope.base.evaluate -from rope.base import pyobjects, pyobjectsdef, pynames, builtins, exceptions, worder -from rope.base.codeanalyze import SourceLinesAdapter -from rope.contrib import fixsyntax -from rope.refactor import functionutils - - -def code_assist(project, source_code, offset, resource=None, - templates=None, maxfixes=1, later_locals=True): - """Return python code completions as a list of `CodeAssistProposal`\s - - `resource` is a `rope.base.resources.Resource` object. If - provided, relative imports are handled. - - `maxfixes` is the maximum number of errors to fix if the code has - errors in it. - - If `later_locals` is `False` names defined in this scope and after - this line is ignored. - - """ - if templates is not None: - warnings.warn('Codeassist no longer supports templates', - DeprecationWarning, stacklevel=2) - assist = _PythonCodeAssist( - project, source_code, offset, resource=resource, - maxfixes=maxfixes, later_locals=later_locals) - return assist() - - -def starting_offset(source_code, offset): - """Return the offset in which the completion should be inserted - - Usually code assist proposals should be inserted like:: - - completion = proposal.name - result = (source_code[:starting_offset] + - completion + source_code[offset:]) - - Where starting_offset is the offset returned by this function. - - """ - word_finder = worder.Worder(source_code, True) - expression, starting, starting_offset = \ - word_finder.get_splitted_primary_before(offset) - return starting_offset - - -def get_doc(project, source_code, offset, resource=None, maxfixes=1): - """Get the pydoc""" - fixer = fixsyntax.FixSyntax(project.pycore, source_code, - resource, maxfixes) - pymodule = fixer.get_pymodule() - pyname = fixer.pyname_at(offset) - if pyname is None: - return None - pyobject = pyname.get_object() - return PyDocExtractor().get_doc(pyobject) - - -def get_calltip(project, source_code, offset, resource=None, - maxfixes=1, ignore_unknown=False, remove_self=False): - """Get the calltip of a function - - The format of the returned string is - ``module_name.holding_scope_names.function_name(arguments)``. For - classes `__init__()` and for normal objects `__call__()` function - is used. - - Note that the offset is on the function itself *not* after the its - open parenthesis. (Actually it used to be the other way but it - was easily confused when string literals were involved. So I - decided it is better for it not to try to be too clever when it - cannot be clever enough). You can use a simple search like:: - - offset = source_code.rindex('(', 0, offset) - 1 - - to handle simple situations. - - If `ignore_unknown` is `True`, `None` is returned for functions - without source-code like builtins and extensions. - - If `remove_self` is `True`, the first parameter whose name is self - will be removed for methods. - """ - fixer = fixsyntax.FixSyntax(project.pycore, source_code, - resource, maxfixes) - pymodule = fixer.get_pymodule() - pyname = fixer.pyname_at(offset) - if pyname is None: - return None - pyobject = pyname.get_object() - return PyDocExtractor().get_calltip(pyobject, ignore_unknown, remove_self) - - -def get_definition_location(project, source_code, offset, - resource=None, maxfixes=1): - """Return the definition location of the python name at `offset` - - Return a (`rope.base.resources.Resource`, lineno) tuple. If no - `resource` is given and the definition is inside the same module, - the first element of the returned tuple would be `None`. If the - location cannot be determined ``(None, None)`` is returned. - - """ - fixer = fixsyntax.FixSyntax(project.pycore, source_code, - resource, maxfixes) - pymodule = fixer.get_pymodule() - pyname = fixer.pyname_at(offset) - if pyname is not None: - module, lineno = pyname.get_definition_location() - if module is not None: - return module.get_module().get_resource(), lineno - return (None, None) - - -def find_occurrences(*args, **kwds): - import rope.contrib.findit - warnings.warn('Use `rope.contrib.findit.find_occurrences()` instead', - DeprecationWarning, stacklevel=2) - return rope.contrib.findit.find_occurrences(*args, **kwds) - - -class CompletionProposal(object): - """A completion proposal - - The `scope` instance variable shows where proposed name came from - and can be 'global', 'local', 'builtin', 'attribute', 'keyword', - 'imported', 'parameter_keyword'. - - The `type` instance variable shows the approximate type of the - proposed object and can be 'instance', 'class', 'function', 'module', - and `None`. - - All possible relations between proposal's `scope` and `type` are shown - in the table below (different scopes in rows and types in columns): - - | instance | class | function | module | None - local | + | + | + | + | - global | + | + | + | + | - builtin | + | + | + | | - attribute | + | + | + | + | - imported | + | + | + | + | - keyword | | | | | + - parameter_keyword | | | | | + - - """ - - def __init__(self, name, scope, pyname=None): - self.name = name - self.pyname = pyname - self.scope = self._get_scope(scope) - - def __str__(self): - return '%s (%s, %s)' % (self.name, self.scope, self.type) - - def __repr__(self): - return str(self) - - @property - def parameters(self): - """The names of the parameters the function takes. - - Returns None if this completion is not a function. - """ - pyname = self.pyname - if isinstance(pyname, pynames.ImportedName): - pyname = pyname._get_imported_pyname() - if isinstance(pyname, pynames.DefinedName): - pyobject = pyname.get_object() - if isinstance(pyobject, pyobjects.AbstractFunction): - return pyobject.get_param_names() - - @property - def type(self): - pyname = self.pyname - if isinstance(pyname, builtins.BuiltinName): - pyobject = pyname.get_object() - if isinstance(pyobject, builtins.BuiltinFunction): - return 'function' - elif isinstance(pyobject, builtins.BuiltinClass): - clsobj = pyobject.builtin - return 'class' - elif isinstance(pyobject, builtins.BuiltinObject) or \ - isinstance(pyobject, builtins.BuiltinName): - return 'instance' - elif isinstance(pyname, pynames.ImportedModule): - return 'module' - elif isinstance(pyname, pynames.ImportedName) or \ - isinstance(pyname, pynames.DefinedName): - pyobject = pyname.get_object() - if isinstance(pyobject, pyobjects.AbstractFunction): - return 'function' - if isinstance(pyobject, pyobjects.AbstractClass): - return 'class' - return 'instance' - - def _get_scope(self, scope): - if isinstance(self.pyname, builtins.BuiltinName): - return 'builtin' - if isinstance(self.pyname, pynames.ImportedModule) or \ - isinstance(self.pyname, pynames.ImportedName): - return 'imported' - return scope - - def get_doc(self): - """Get the proposed object's docstring. - - Returns None if it can not be get. - """ - if not self.pyname: - return None - pyobject = self.pyname.get_object() - if not hasattr(pyobject, 'get_doc'): - return None - return self.pyname.get_object().get_doc() - - @property - def kind(self): - warnings.warn("the proposal's `kind` property is deprecated, " \ - "use `scope` instead") - return self.scope - - -# leaved for backward compatibility -CodeAssistProposal = CompletionProposal - - -class NamedParamProposal(CompletionProposal): - """A parameter keyword completion proposal - - Holds reference to ``_function`` -- the function which - parameter ``name`` belongs to. This allows to determine - default value for this parameter. - """ - def __init__(self, name, function): - self.argname = name - name = '%s=' % name - super(NamedParamProposal, self).__init__(name, 'parameter_keyword') - self._function = function - - def get_default(self): - """Get a string representation of a param's default value. - - Returns None if there is no default value for this param. - """ - definfo = functionutils.DefinitionInfo.read(self._function) - for arg, default in definfo.args_with_defaults: - if self.argname == arg: - return default - return None - - -def sorted_proposals(proposals, scopepref=None, typepref=None): - """Sort a list of proposals - - Return a sorted list of the given `CodeAssistProposal`\s. - - `scopepref` can be a list of proposal scopes. Defaults to - ``['parameter_keyword', 'local', 'global', 'imported', - 'attribute', 'builtin', 'keyword']``. - - `typepref` can be a list of proposal types. Defaults to - ``['class', 'function', 'instance', 'module', None]``. - (`None` stands for completions with no type like keywords.) - """ - sorter = _ProposalSorter(proposals, scopepref, typepref) - return sorter.get_sorted_proposal_list() - - -def starting_expression(source_code, offset): - """Return the expression to complete""" - word_finder = worder.Worder(source_code, True) - expression, starting, starting_offset = \ - word_finder.get_splitted_primary_before(offset) - if expression: - return expression + '.' + starting - return starting - - -def default_templates(): - warnings.warn('default_templates() is deprecated.', - DeprecationWarning, stacklevel=2) - return {} - - -class _PythonCodeAssist(object): - - def __init__(self, project, source_code, offset, resource=None, - maxfixes=1, later_locals=True): - self.project = project - self.pycore = self.project.pycore - self.code = source_code - self.resource = resource - self.maxfixes = maxfixes - self.later_locals = later_locals - self.word_finder = worder.Worder(source_code, True) - self.expression, self.starting, self.offset = \ - self.word_finder.get_splitted_primary_before(offset) - - keywords = keyword.kwlist - - def _find_starting_offset(self, source_code, offset): - current_offset = offset - 1 - while current_offset >= 0 and (source_code[current_offset].isalnum() or - source_code[current_offset] in '_'): - current_offset -= 1; - return current_offset + 1 - - def _matching_keywords(self, starting): - result = [] - for kw in self.keywords: - if kw.startswith(starting): - result.append(CompletionProposal(kw, 'keyword')) - return result - - def __call__(self): - if self.offset > len(self.code): - return [] - completions = list(self._code_completions().values()) - if self.expression.strip() == '' and self.starting.strip() != '': - completions.extend(self._matching_keywords(self.starting)) - return completions - - def _dotted_completions(self, module_scope, holding_scope): - result = {} - found_pyname = rope.base.evaluate.eval_str(holding_scope, - self.expression) - if found_pyname is not None: - element = found_pyname.get_object() - compl_scope = 'attribute' - if isinstance(element, (pyobjectsdef.PyModule, - pyobjectsdef.PyPackage)): - compl_scope = 'imported' - for name, pyname in element.get_attributes().items(): - if name.startswith(self.starting): - result[name] = CompletionProposal(name, compl_scope, pyname) - return result - - def _undotted_completions(self, scope, result, lineno=None): - if scope.parent != None: - self._undotted_completions(scope.parent, result) - if lineno is None: - names = scope.get_propagated_names() - else: - names = scope.get_names() - for name, pyname in names.items(): - if name.startswith(self.starting): - compl_scope = 'local' - if scope.get_kind() == 'Module': - compl_scope = 'global' - if lineno is None or self.later_locals or \ - not self._is_defined_after(scope, pyname, lineno): - result[name] = CompletionProposal(name, compl_scope, - pyname) - - def _from_import_completions(self, pymodule): - module_name = self.word_finder.get_from_module(self.offset) - if module_name is None: - return {} - pymodule = self._find_module(pymodule, module_name) - result = {} - for name in pymodule: - if name.startswith(self.starting): - result[name] = CompletionProposal(name, scope='global', - pyname=pymodule[name]) - return result - - def _find_module(self, pymodule, module_name): - dots = 0 - while module_name[dots] == '.': - dots += 1 - pyname = pynames.ImportedModule(pymodule, - module_name[dots:], dots) - return pyname.get_object() - - def _is_defined_after(self, scope, pyname, lineno): - location = pyname.get_definition_location() - if location is not None and location[1] is not None: - if location[0] == scope.pyobject.get_module() and \ - lineno <= location[1] <= scope.get_end(): - return True - - def _code_completions(self): - lineno = self.code.count('\n', 0, self.offset) + 1 - fixer = fixsyntax.FixSyntax(self.pycore, self.code, - self.resource, self.maxfixes) - pymodule = fixer.get_pymodule() - module_scope = pymodule.get_scope() - code = pymodule.source_code - lines = code.split('\n') - result = {} - start = fixsyntax._logical_start(lines, lineno) - indents = fixsyntax._get_line_indents(lines[start - 1]) - inner_scope = module_scope.get_inner_scope_for_line(start, indents) - if self.word_finder.is_a_name_after_from_import(self.offset): - return self._from_import_completions(pymodule) - if self.expression.strip() != '': - result.update(self._dotted_completions(module_scope, inner_scope)) - else: - result.update(self._keyword_parameters(module_scope.pyobject, - inner_scope)) - self._undotted_completions(inner_scope, result, lineno=lineno) - return result - - def _keyword_parameters(self, pymodule, scope): - offset = self.offset - if offset == 0: - return {} - word_finder = worder.Worder(self.code, True) - lines = SourceLinesAdapter(self.code) - lineno = lines.get_line_number(offset) - if word_finder.is_on_function_call_keyword(offset - 1): - name_finder = rope.base.evaluate.ScopeNameFinder(pymodule) - function_parens = word_finder.\ - find_parens_start_from_inside(offset - 1) - primary = word_finder.get_primary_at(function_parens - 1) - try: - function_pyname = rope.base.evaluate.\ - eval_str(scope, primary) - except exceptions.BadIdentifierError, e: - return {} - if function_pyname is not None: - pyobject = function_pyname.get_object() - if isinstance(pyobject, pyobjects.AbstractFunction): - pass - elif isinstance(pyobject, pyobjects.AbstractClass) and \ - '__init__' in pyobject: - pyobject = pyobject['__init__'].get_object() - elif '__call__' in pyobject: - pyobject = pyobject['__call__'].get_object() - if isinstance(pyobject, pyobjects.AbstractFunction): - param_names = [] - param_names.extend( - pyobject.get_param_names(special_args=False)) - result = {} - for name in param_names: - if name.startswith(self.starting): - result[name + '='] = NamedParamProposal( - name, pyobject - ) - return result - return {} - - -class _ProposalSorter(object): - """Sort a list of code assist proposals""" - - def __init__(self, code_assist_proposals, scopepref=None, typepref=None): - self.proposals = code_assist_proposals - if scopepref is None: - scopepref = ['parameter_keyword', 'local', 'global', 'imported', - 'attribute', 'builtin', 'keyword'] - self.scopepref = scopepref - if typepref is None: - typepref = ['class', 'function', 'instance', 'module', None] - self.typerank = dict((type, index) - for index, type in enumerate(typepref)) - - def get_sorted_proposal_list(self): - """Return a list of `CodeAssistProposal`""" - proposals = {} - for proposal in self.proposals: - proposals.setdefault(proposal.scope, []).append(proposal) - result = [] - for scope in self.scopepref: - scope_proposals = proposals.get(scope, []) - scope_proposals = [proposal for proposal in scope_proposals - if proposal.type in self.typerank] - scope_proposals.sort(self._proposal_cmp) - result.extend(scope_proposals) - return result - - def _proposal_cmp(self, proposal1, proposal2): - if proposal1.type != proposal2.type: - return cmp(self.typerank.get(proposal1.type, 100), - self.typerank.get(proposal2.type, 100)) - return self._compare_underlined_names(proposal1.name, - proposal2.name) - - def _compare_underlined_names(self, name1, name2): - def underline_count(name): - result = 0 - while result < len(name) and name[result] == '_': - result += 1 - return result - underline_count1 = underline_count(name1) - underline_count2 = underline_count(name2) - if underline_count1 != underline_count2: - return cmp(underline_count1, underline_count2) - return cmp(name1, name2) - - -class PyDocExtractor(object): - - def get_doc(self, pyobject): - if isinstance(pyobject, pyobjects.AbstractFunction): - return self._get_function_docstring(pyobject) - elif isinstance(pyobject, pyobjects.AbstractClass): - return self._get_class_docstring(pyobject) - elif isinstance(pyobject, pyobjects.AbstractModule): - return self._trim_docstring(pyobject.get_doc()) - return None - - def get_calltip(self, pyobject, ignore_unknown=False, remove_self=False): - try: - if isinstance(pyobject, pyobjects.AbstractClass): - pyobject = pyobject['__init__'].get_object() - if not isinstance(pyobject, pyobjects.AbstractFunction): - pyobject = pyobject['__call__'].get_object() - except exceptions.AttributeNotFoundError: - return None - if ignore_unknown and not isinstance(pyobject, pyobjects.PyFunction): - return - if isinstance(pyobject, pyobjects.AbstractFunction): - result = self._get_function_signature(pyobject, add_module=True) - if remove_self and self._is_method(pyobject): - return result.replace('(self)', '()').replace('(self, ', '(') - return result - - def _get_class_docstring(self, pyclass): - contents = self._trim_docstring(pyclass.get_doc(), 2) - supers = [super.get_name() for super in pyclass.get_superclasses()] - doc = 'class %s(%s):\n\n' % (pyclass.get_name(), ', '.join(supers)) + contents - - if '__init__' in pyclass: - init = pyclass['__init__'].get_object() - if isinstance(init, pyobjects.AbstractFunction): - doc += '\n\n' + self._get_single_function_docstring(init) - return doc - - def _get_function_docstring(self, pyfunction): - functions = [pyfunction] - if self._is_method(pyfunction): - functions.extend(self._get_super_methods(pyfunction.parent, - pyfunction.get_name())) - return '\n\n'.join([self._get_single_function_docstring(function) - for function in functions]) - - def _is_method(self, pyfunction): - return isinstance(pyfunction, pyobjects.PyFunction) and \ - isinstance(pyfunction.parent, pyobjects.PyClass) - - def _get_single_function_docstring(self, pyfunction): - signature = self._get_function_signature(pyfunction) - docs = self._trim_docstring(pyfunction.get_doc(), indents=2) - return signature + ':\n\n' + docs - - def _get_super_methods(self, pyclass, name): - result = [] - for super_class in pyclass.get_superclasses(): - if name in super_class: - function = super_class[name].get_object() - if isinstance(function, pyobjects.AbstractFunction): - result.append(function) - result.extend(self._get_super_methods(super_class, name)) - return result - - def _get_function_signature(self, pyfunction, add_module=False): - location = self._location(pyfunction, add_module) - if isinstance(pyfunction, pyobjects.PyFunction): - info = functionutils.DefinitionInfo.read(pyfunction) - return location + info.to_string() - else: - return '%s(%s)' % (location + pyfunction.get_name(), - ', '.join(pyfunction.get_param_names())) - - def _location(self, pyobject, add_module=False): - location = [] - parent = pyobject.parent - while parent and not isinstance(parent, pyobjects.AbstractModule): - location.append(parent.get_name()) - location.append('.') - parent = parent.parent - if add_module: - if isinstance(pyobject, pyobjects.PyFunction): - module = pyobject.get_module() - location.insert(0, self._get_module(pyobject)) - if isinstance(parent, builtins.BuiltinModule): - location.insert(0, parent.get_name() + '.') - return ''.join(location) - - def _get_module(self, pyfunction): - module = pyfunction.get_module() - if module is not None: - resource = module.get_resource() - if resource is not None: - return pyfunction.pycore.modname(resource) + '.' - return '' - - def _trim_docstring(self, docstring, indents=0): - """The sample code from :PEP:`257`""" - if not docstring: - return '' - # Convert tabs to spaces (following normal Python rules) - # and split into a list of lines: - lines = docstring.expandtabs().splitlines() - # Determine minimum indentation (first line doesn't count): - indent = sys.maxint - for line in lines[1:]: - stripped = line.lstrip() - if stripped: - indent = min(indent, len(line) - len(stripped)) - # Remove indentation (first line is special): - trimmed = [lines[0].strip()] - if indent < sys.maxint: - for line in lines[1:]: - trimmed.append(line[indent:].rstrip()) - # Strip off trailing and leading blank lines: - while trimmed and not trimmed[-1]: - trimmed.pop() - while trimmed and not trimmed[0]: - trimmed.pop(0) - # Return a single string: - return '\n'.join((' ' * indents + line for line in trimmed)) - - -# Deprecated classes - -class TemplateProposal(CodeAssistProposal): - def __init__(self, name, template): - warnings.warn('TemplateProposal is deprecated.', - DeprecationWarning, stacklevel=2) - super(TemplateProposal, self).__init__(name, 'template') - self.template = template - - -class Template(object): - - def __init__(self, template): - self.template = template - warnings.warn('Template is deprecated.', - DeprecationWarning, stacklevel=2) - - def variables(self): - return [] - - def substitute(self, mapping): - return self.template - - def get_cursor_location(self, mapping): - return len(self.template) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/contrib/finderrors.py --- a/vim/sadness/ropevim/src/rope/rope/contrib/finderrors.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -"""Finding bad name and attribute accesses - -`find_errors` function can be used to find possible bad name and -attribute accesses. As an example:: - - errors = find_errors(project, project.get_resource('mod.py')) - for error in errors: - print '%s: %s' % (error.lineno, error.error) - -prints possible errors for ``mod.py`` file. - -TODO: - -* use task handles -* reporting names at most once -* attributes of extension modules that don't appear in - extension_modules project config can be ignored -* not calling `PyScope.get_inner_scope_for_line()` if it is a - bottleneck; needs profiling -* not reporting occurrences where rope cannot infer the object -* rope saves multiple objects for some of the names in its objectdb - use all of them not to give false positives -* ... ;-) - -""" -from rope.base import ast, evaluate, pyobjects - - -def find_errors(project, resource): - """Find possible bad name and attribute accesses - - It returns a list of `Error`\s. - """ - pymodule = project.pycore.resource_to_pyobject(resource) - finder = _BadAccessFinder(pymodule) - ast.walk(pymodule.get_ast(), finder) - return finder.errors - - -class _BadAccessFinder(object): - - def __init__(self, pymodule): - self.pymodule = pymodule - self.scope = pymodule.get_scope() - self.errors = [] - - def _Name(self, node): - if isinstance(node.ctx, (ast.Store, ast.Param)): - return - scope = self.scope.get_inner_scope_for_line(node.lineno) - pyname = scope.lookup(node.id) - if pyname is None: - self._add_error(node, 'Unresolved variable') - elif self._is_defined_after(scope, pyname, node.lineno): - self._add_error(node, 'Defined later') - - def _Attribute(self, node): - if not isinstance(node.ctx, ast.Store): - scope = self.scope.get_inner_scope_for_line(node.lineno) - pyname = evaluate.eval_node(scope, node.value) - if pyname is not None and \ - pyname.get_object() != pyobjects.get_unknown(): - if node.attr not in pyname.get_object(): - self._add_error(node, 'Unresolved attribute') - ast.walk(node.value, self) - - def _add_error(self, node, msg): - if isinstance(node, ast.Attribute): - name = node.attr - else: - name = node.id - if name != 'None': - error = Error(node.lineno, msg + ' ' + name) - self.errors.append(error) - - def _is_defined_after(self, scope, pyname, lineno): - location = pyname.get_definition_location() - if location is not None and location[1] is not None: - if location[0] == self.pymodule and \ - lineno <= location[1] <= scope.get_end(): - return True - - -class Error(object): - - def __init__(self, lineno, error): - self.lineno = lineno - self.error = error - - def __str__(self): - return '%s: %s' % (self.lineno, self.error) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/contrib/findit.py --- a/vim/sadness/ropevim/src/rope/rope/contrib/findit.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -import rope.base.codeanalyze -import rope.base.evaluate -import rope.base.pyobjects -from rope.base import taskhandle, exceptions, worder -from rope.contrib import fixsyntax -from rope.refactor import occurrences - - -def find_occurrences(project, resource, offset, unsure=False, resources=None, - in_hierarchy=False, task_handle=taskhandle.NullTaskHandle()): - """Return a list of `Location`\s - - If `unsure` is `True`, possible matches are returned, too. You - can use `Location.unsure` to see which are unsure occurrences. - `resources` can be a list of `rope.base.resource.File`\s that - should be searched for occurrences; if `None` all python files - in the project are searched. - - """ - name = worder.get_name_at(resource, offset) - this_pymodule = project.pycore.resource_to_pyobject(resource) - primary, pyname = rope.base.evaluate.eval_location2( - this_pymodule, offset) - def is_match(occurrence): - return unsure - finder = occurrences.create_finder( - project.pycore, name, pyname, unsure=is_match, - in_hierarchy=in_hierarchy, instance=primary) - if resources is None: - resources = project.pycore.get_python_files() - job_set = task_handle.create_jobset('Finding Occurrences', - count=len(resources)) - return _find_locations(finder, resources, job_set) - - -def find_implementations(project, resource, offset, resources=None, - task_handle=taskhandle.NullTaskHandle()): - """Find the places a given method is overridden. - - Finds the places a method is implemented. Returns a list of - `Location`\s. - """ - name = worder.get_name_at(resource, offset) - this_pymodule = project.pycore.resource_to_pyobject(resource) - pyname = rope.base.evaluate.eval_location(this_pymodule, offset) - if pyname is not None: - pyobject = pyname.get_object() - if not isinstance(pyobject, rope.base.pyobjects.PyFunction) or \ - pyobject.get_kind() != 'method': - raise exceptions.BadIdentifierError('Not a method!') - else: - raise exceptions.BadIdentifierError('Cannot resolve the identifier!') - def is_defined(occurrence): - if not occurrence.is_defined(): - return False - def not_self(occurrence): - if occurrence.get_pyname().get_object() == pyname.get_object(): - return False - filters = [is_defined, not_self, - occurrences.InHierarchyFilter(pyname, True)] - finder = occurrences.Finder(project.pycore, name, filters=filters) - if resources is None: - resources = project.pycore.get_python_files() - job_set = task_handle.create_jobset('Finding Implementations', - count=len(resources)) - return _find_locations(finder, resources, job_set) - - -def find_definition(project, code, offset, resource=None, maxfixes=1): - """Return the definition location of the python name at `offset` - - A `Location` object is returned if the definition location can be - determined, otherwise ``None`` is returned. - """ - fixer = fixsyntax.FixSyntax(project.pycore, code, resource, maxfixes) - main_module = fixer.get_pymodule() - pyname = fixer.pyname_at(offset) - if pyname is not None: - module, lineno = pyname.get_definition_location() - name = rope.base.worder.Worder(code).get_word_at(offset) - if lineno is not None: - start = module.lines.get_line_start(lineno) - def check_offset(occurrence): - if occurrence.offset < start: - return False - pyname_filter = occurrences.PyNameFilter(pyname) - finder = occurrences.Finder(project.pycore, name, - [check_offset, pyname_filter]) - for occurrence in finder.find_occurrences(pymodule=module): - return Location(occurrence) - - -class Location(object): - - def __init__(self, occurrence): - self.resource = occurrence.resource - self.region = occurrence.get_word_range() - self.offset = self.region[0] - self.unsure = occurrence.is_unsure() - self.lineno = occurrence.lineno - - -def _find_locations(finder, resources, job_set): - result = [] - for resource in resources: - job_set.started_job(resource.path) - for occurrence in finder.find_occurrences(resource): - result.append(Location(occurrence)) - job_set.finished_job() - return result diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/contrib/fixmodnames.py --- a/vim/sadness/ropevim/src/rope/rope/contrib/fixmodnames.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -"""Fix the name of modules - -This module is useful when you want to rename many of the modules in -your project. That can happen specially when you want to change their -naming style. - -For instance:: - - fixer = FixModuleNames(project) - changes = fixer.get_changes(fixer=str.lower) - project.do(changes) - -Here it renames all modules and packages to use lower-cased chars. -You can tell it to use any other style by using the ``fixer`` -argument. - -""" -from rope.base import change, taskhandle -from rope.contrib import changestack -from rope.refactor import rename - - -class FixModuleNames(object): - - def __init__(self, project): - self.project = project - - def get_changes(self, fixer=str.lower, - task_handle=taskhandle.NullTaskHandle()): - """Fix module names - - `fixer` is a function that takes and returns a `str`. Given - the name of a module, it should return the fixed name. - - """ - stack = changestack.ChangeStack(self.project, 'Fixing module names') - jobset = task_handle.create_jobset('Fixing module names', - self._count_fixes(fixer) + 1) - try: - while True: - for resource in self._tobe_fixed(fixer): - jobset.started_job(resource.path) - renamer = rename.Rename(self.project, resource) - changes = renamer.get_changes(fixer(self._name(resource))) - stack.push(changes) - jobset.finished_job() - break - else: - break - finally: - jobset.started_job('Reverting to original state') - stack.pop_all() - jobset.finished_job() - return stack.merged() - - def _count_fixes(self, fixer): - return len(list(self._tobe_fixed(fixer))) - - def _tobe_fixed(self, fixer): - for resource in self.project.pycore.get_python_files(): - modname = self._name(resource) - if modname != fixer(modname): - yield resource - - def _name(self, resource): - modname = resource.name.rsplit('.', 1)[0] - if modname == '__init__': - modname = resource.parent.name - return modname diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/contrib/fixsyntax.py --- a/vim/sadness/ropevim/src/rope/rope/contrib/fixsyntax.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -import rope.base.codeanalyze -import rope.base.evaluate -from rope.base import worder, exceptions, utils -from rope.base.codeanalyze import ArrayLinesAdapter, LogicalLineFinder - - -class FixSyntax(object): - - def __init__(self, pycore, code, resource, maxfixes=1): - self.pycore = pycore - self.code = code - self.resource = resource - self.maxfixes = maxfixes - - @utils.saveit - def get_pymodule(self): - """Get a `PyModule`""" - errors = [] - code = self.code - tries = 0 - while True: - try: - if tries == 0 and self.resource is not None and \ - self.resource.read() == code: - return self.pycore.resource_to_pyobject(self.resource, - force_errors=True) - return self.pycore.get_string_module( - code, resource=self.resource, force_errors=True) - except exceptions.ModuleSyntaxError, e: - if tries < self.maxfixes: - tries += 1 - self.commenter.comment(e.lineno) - code = '\n'.join(self.commenter.lines) - errors.append(' * line %s: %s ... fixed' % (e.lineno, - e.message_)) - else: - errors.append(' * line %s: %s ... raised!' % (e.lineno, - e.message_)) - new_message = ('\nSyntax errors in file %s:\n' % e.filename) \ - + '\n'.join(errors) - raise exceptions.ModuleSyntaxError(e.filename, e.lineno, - new_message) - - @property - @utils.saveit - def commenter(self): - return _Commenter(self.code) - - def pyname_at(self, offset): - pymodule = self.get_pymodule() - def old_pyname(): - word_finder = worder.Worder(self.code, True) - expression = word_finder.get_primary_at(offset) - expression = expression.replace('\\\n', ' ').replace('\n', ' ') - lineno = self.code.count('\n', 0, offset) - scope = pymodule.get_scope().get_inner_scope_for_line(lineno) - return rope.base.evaluate.eval_str(scope, expression) - new_code = pymodule.source_code - def new_pyname(): - newoffset = self.commenter.transfered_offset(offset) - return rope.base.evaluate.eval_location(pymodule, newoffset) - if new_code.startswith(self.code[:offset + 1]): - return new_pyname() - result = old_pyname() - if result is None: - return new_pyname() - return result - - -class _Commenter(object): - - def __init__(self, code): - self.code = code - self.lines = self.code.split('\n') - self.lines.append('\n') - self.origs = range(len(self.lines) + 1) - self.diffs = [0] * (len(self.lines) + 1) - - def comment(self, lineno): - start = _logical_start(self.lines, lineno, check_prev=True) - 1 - # using self._get_stmt_end() instead of self._get_block_end() - # to lower commented lines - end = self._get_stmt_end(start) - indents = _get_line_indents(self.lines[start]) - if 0 < start: - last_lineno = self._last_non_blank(start - 1) - last_line = self.lines[last_lineno] - if last_line.rstrip().endswith(':'): - indents = _get_line_indents(last_line) + 4 - self._set(start, ' ' * indents + 'pass') - for line in range(start + 1, end + 1): - self._set(line, self.lines[start]) - self._fix_incomplete_try_blocks(lineno, indents) - - def transfered_offset(self, offset): - lineno = self.code.count('\n', 0, offset) - diff = sum(self.diffs[:lineno]) - return offset + diff - - def _last_non_blank(self, start): - while start > 0 and self.lines[start].strip() == '': - start -= 1 - return start - - def _get_block_end(self, lineno): - end_line = lineno - base_indents = _get_line_indents(self.lines[lineno]) - for i in range(lineno + 1, len(self.lines)): - if _get_line_indents(self.lines[i]) >= base_indents: - end_line = i - else: - break - return end_line - - def _get_stmt_end(self, lineno): - end_line = lineno - base_indents = _get_line_indents(self.lines[lineno]) - for i in range(lineno + 1, len(self.lines)): - if _get_line_indents(self.lines[i]) <= base_indents: - return i - 1 - return lineno - - def _fix_incomplete_try_blocks(self, lineno, indents): - block_start = lineno - last_indents = current_indents = indents - while block_start > 0: - block_start = rope.base.codeanalyze.get_block_start( - ArrayLinesAdapter(self.lines), block_start) - 1 - if self.lines[block_start].strip().startswith('try:'): - indents = _get_line_indents(self.lines[block_start]) - if indents > last_indents: - continue - last_indents = indents - block_end = self._find_matching_deindent(block_start) - line = self.lines[block_end].strip() - if not (line.startswith('finally:') or - line.startswith('except ') or - line.startswith('except:')): - self._insert(block_end, ' ' * indents + 'finally:') - self._insert(block_end + 1, ' ' * indents + ' pass') - - def _find_matching_deindent(self, line_number): - indents = _get_line_indents(self.lines[line_number]) - current_line = line_number + 1 - while current_line < len(self.lines): - line = self.lines[current_line] - if not line.strip().startswith('#') and not line.strip() == '': - # HACK: We should have used logical lines here - if _get_line_indents(self.lines[current_line]) <= indents: - return current_line - current_line += 1 - return len(self.lines) - 1 - - def _set(self, lineno, line): - self.diffs[self.origs[lineno]] += len(line) - len(self.lines[lineno]) - self.lines[lineno] = line - - def _insert(self, lineno, line): - self.diffs[self.origs[lineno]] += len(line) + 1 - self.origs.insert(lineno, self.origs[lineno]) - self.lines.insert(lineno, line) - -def _logical_start(lines, lineno, check_prev=False): - logical_finder = LogicalLineFinder(ArrayLinesAdapter(lines)) - if check_prev: - prev = lineno - 1 - while prev > 0: - start, end = logical_finder.logical_line_in(prev) - if end is None or start <= lineno < end: - return start - if start <= prev: - break - prev -= 1 - return logical_finder.logical_line_in(lineno)[0] - - -def _get_line_indents(line): - return rope.base.codeanalyze.count_line_indents(line) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/contrib/generate.py --- a/vim/sadness/ropevim/src/rope/rope/contrib/generate.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,355 +0,0 @@ -import rope.base.evaluate -from rope.base import change, pyobjects, exceptions, pynames, worder, codeanalyze -from rope.refactor import sourceutils, importutils, functionutils, suites - - -def create_generate(kind, project, resource, offset): - """A factory for creating `Generate` objects - - `kind` can be 'variable', 'function', 'class', 'module' or - 'package'. - - """ - generate = eval('Generate' + kind.title()) - return generate(project, resource, offset) - - -def create_module(project, name, sourcefolder=None): - """Creates a module and returns a `rope.base.resources.File`""" - if sourcefolder is None: - sourcefolder = project.root - packages = name.split('.') - parent = sourcefolder - for package in packages[:-1]: - parent = parent.get_child(package) - return parent.create_file(packages[-1] + '.py') - -def create_package(project, name, sourcefolder=None): - """Creates a package and returns a `rope.base.resources.Folder`""" - if sourcefolder is None: - sourcefolder = project.root - packages = name.split('.') - parent = sourcefolder - for package in packages[:-1]: - parent = parent.get_child(package) - made_packages = parent.create_folder(packages[-1]) - made_packages.create_file('__init__.py') - return made_packages - - -class _Generate(object): - - def __init__(self, project, resource, offset): - self.project = project - self.resource = resource - self.info = self._generate_info(project, resource, offset) - self.name = self.info.get_name() - self._check_exceptional_conditions() - - def _generate_info(self, project, resource, offset): - return _GenerationInfo(project.pycore, resource, offset) - - def _check_exceptional_conditions(self): - if self.info.element_already_exists(): - raise exceptions.RefactoringError( - 'Element <%s> already exists.' % self.name) - if not self.info.primary_is_found(): - raise exceptions.RefactoringError( - 'Cannot determine the scope <%s> should be defined in.' % self.name) - - def get_changes(self): - changes = change.ChangeSet('Generate %s <%s>' % - (self._get_element_kind(), self.name)) - indents = self.info.get_scope_indents() - blanks = self.info.get_blank_lines() - base_definition = sourceutils.fix_indentation(self._get_element(), indents) - definition = '\n' * blanks[0] + base_definition + '\n' * blanks[1] - - resource = self.info.get_insertion_resource() - start, end = self.info.get_insertion_offsets() - - collector = codeanalyze.ChangeCollector(resource.read()) - collector.add_change(start, end, definition) - changes.add_change(change.ChangeContents( - resource, collector.get_changed())) - return changes - - def get_location(self): - return (self.info.get_insertion_resource(), - self.info.get_insertion_lineno()) - - def _get_element_kind(self): - raise NotImplementedError() - - def _get_element(self): - raise NotImplementedError() - - -class GenerateFunction(_Generate): - - def _generate_info(self, project, resource, offset): - return _FunctionGenerationInfo(project.pycore, resource, offset) - - def _get_element(self): - decorator = '' - args = [] - if self.info.is_static_method(): - decorator = '@staticmethod\n' - if self.info.is_method() or self.info.is_constructor() or \ - self.info.is_instance(): - args.append('self') - args.extend(self.info.get_passed_args()) - definition = '%sdef %s(%s):\n pass\n' % (decorator, self.name, - ', '.join(args)) - return definition - - def _get_element_kind(self): - return 'Function' - - -class GenerateVariable(_Generate): - - def _get_element(self): - return '%s = None\n' % self.name - - def _get_element_kind(self): - return 'Variable' - - -class GenerateClass(_Generate): - - def _get_element(self): - return 'class %s(object):\n pass\n' % self.name - - def _get_element_kind(self): - return 'Class' - - -class GenerateModule(_Generate): - - def get_changes(self): - package = self.info.get_package() - changes = change.ChangeSet('Generate Module <%s>' % self.name) - new_resource = self.project.get_file('%s/%s.py' % (package.path, self.name)) - if new_resource.exists(): - raise exceptions.RefactoringError( - 'Module <%s> already exists' % new_resource.path) - changes.add_change(change.CreateResource(new_resource)) - changes.add_change(_add_import_to_module( - self.project.pycore, self.resource, new_resource)) - return changes - - def get_location(self): - package = self.info.get_package() - return (package.get_child('%s.py' % self.name) , 1) - - -class GeneratePackage(_Generate): - - def get_changes(self): - package = self.info.get_package() - changes = change.ChangeSet('Generate Package <%s>' % self.name) - new_resource = self.project.get_folder('%s/%s' % (package.path, self.name)) - if new_resource.exists(): - raise exceptions.RefactoringError( - 'Package <%s> already exists' % new_resource.path) - changes.add_change(change.CreateResource(new_resource)) - changes.add_change(_add_import_to_module( - self.project.pycore, self.resource, new_resource)) - child = self.project.get_folder(package.path + '/' + self.name) - changes.add_change(change.CreateFile(child, '__init__.py')) - return changes - - def get_location(self): - package = self.info.get_package() - child = package.get_child(self.name) - return (child.get_child('__init__.py') , 1) - - -def _add_import_to_module(pycore, resource, imported): - pymodule = pycore.resource_to_pyobject(resource) - import_tools = importutils.ImportTools(pycore) - module_imports = import_tools.module_imports(pymodule) - module_name = pycore.modname(imported) - new_import = importutils.NormalImport(((module_name, None), )) - module_imports.add_import(new_import) - return change.ChangeContents(resource, module_imports.get_changed_source()) - - -class _GenerationInfo(object): - - def __init__(self, pycore, resource, offset): - self.pycore = pycore - self.resource = resource - self.offset = offset - self.source_pymodule = self.pycore.resource_to_pyobject(resource) - finder = rope.base.evaluate.ScopeNameFinder(self.source_pymodule) - self.primary, self.pyname = finder.get_primary_and_pyname_at(offset) - self._init_fields() - - def _init_fields(self): - self.source_scope = self._get_source_scope() - self.goal_scope = self._get_goal_scope() - self.goal_pymodule = self._get_goal_module(self.goal_scope) - - def _get_goal_scope(self): - if self.primary is None: - return self._get_source_scope() - pyobject = self.primary.get_object() - if isinstance(pyobject, pyobjects.PyDefinedObject): - return pyobject.get_scope() - elif isinstance(pyobject.get_type(), pyobjects.PyClass): - return pyobject.get_type().get_scope() - - def _get_goal_module(self, scope): - if scope is None: - return - while scope.parent is not None: - scope = scope.parent - return scope.pyobject - - def _get_source_scope(self): - module_scope = self.source_pymodule.get_scope() - lineno = self.source_pymodule.lines.get_line_number(self.offset) - return module_scope.get_inner_scope_for_line(lineno) - - def get_insertion_lineno(self): - lines = self.goal_pymodule.lines - if self.goal_scope == self.source_scope: - line_finder = self.goal_pymodule.logical_lines - lineno = lines.get_line_number(self.offset) - lineno = line_finder.logical_line_in(lineno)[0] - root = suites.ast_suite_tree(self.goal_scope.pyobject.get_ast()) - suite = root.find_suite(lineno) - indents = sourceutils.get_indents(lines, lineno) - while self.get_scope_indents() < indents: - lineno = suite.get_start() - indents = sourceutils.get_indents(lines, lineno) - suite = suite.parent - return lineno - else: - return min(self.goal_scope.get_end() + 1, lines.length()) - - def get_insertion_resource(self): - return self.goal_pymodule.get_resource() - - def get_insertion_offsets(self): - if self.goal_scope.get_kind() == 'Class': - start, end = sourceutils.get_body_region(self.goal_scope.pyobject) - if self.goal_pymodule.source_code[start:end].strip() == 'pass': - return start, end - lines = self.goal_pymodule.lines - start = lines.get_line_start(self.get_insertion_lineno()) - return (start, start) - - def get_scope_indents(self): - if self.goal_scope.get_kind() == 'Module': - return 0 - return sourceutils.get_indents(self.goal_pymodule.lines, - self.goal_scope.get_start()) + 4 - - def get_blank_lines(self): - if self.goal_scope.get_kind() == 'Module': - base_blanks = 2 - if self.goal_pymodule.source_code.strip() == '': - base_blanks = 0 - if self.goal_scope.get_kind() == 'Class': - base_blanks = 1 - if self.goal_scope.get_kind() == 'Function': - base_blanks = 0 - if self.goal_scope == self.source_scope: - return (0, base_blanks) - return (base_blanks, 0) - - def get_package(self): - primary = self.primary - if self.primary is None: - return self.pycore.get_source_folders()[0] - if isinstance(primary.get_object(), pyobjects.PyPackage): - return primary.get_object().get_resource() - raise exceptions.RefactoringError( - 'A module/package can be only created in a package.') - - def primary_is_found(self): - return self.goal_scope is not None - - def element_already_exists(self): - if self.pyname is None or isinstance(self.pyname, pynames.UnboundName): - return False - return self.get_name() in self.goal_scope.get_defined_names() - - def get_name(self): - return worder.get_name_at(self.resource, self.offset) - - -class _FunctionGenerationInfo(_GenerationInfo): - - def _get_goal_scope(self): - if self.is_constructor(): - return self.pyname.get_object().get_scope() - if self.is_instance(): - return self.pyname.get_object().get_type().get_scope() - if self.primary is None: - return self._get_source_scope() - pyobject = self.primary.get_object() - if isinstance(pyobject, pyobjects.PyDefinedObject): - return pyobject.get_scope() - elif isinstance(pyobject.get_type(), pyobjects.PyClass): - return pyobject.get_type().get_scope() - - def element_already_exists(self): - if self.pyname is None or isinstance(self.pyname, pynames.UnboundName): - return False - return self.get_name() in self.goal_scope.get_defined_names() - - def is_static_method(self): - return self.primary is not None and \ - isinstance(self.primary.get_object(), pyobjects.PyClass) - - def is_method(self): - return self.primary is not None and \ - isinstance(self.primary.get_object().get_type(), pyobjects.PyClass) - - def is_constructor(self): - return self.pyname is not None and \ - isinstance(self.pyname.get_object(), pyobjects.PyClass) - - def is_instance(self): - if self.pyname is None: - return False - pyobject = self.pyname.get_object() - return isinstance(pyobject.get_type(), pyobjects.PyClass) - - def get_name(self): - if self.is_constructor(): - return '__init__' - if self.is_instance(): - return '__call__' - return worder.get_name_at(self.resource, self.offset) - - def get_passed_args(self): - result = [] - source = self.source_pymodule.source_code - finder = worder.Worder(source) - if finder.is_a_function_being_called(self.offset): - start, end = finder.get_primary_range(self.offset) - parens_start, parens_end = finder.get_word_parens_range(end - 1) - call = source[start:parens_end] - parser = functionutils._FunctionParser(call, False) - args, keywords = parser.get_parameters() - for arg in args: - if self._is_id(arg): - result.append(arg) - else: - result.append('arg%d' % len(result)) - for name, value in keywords: - result.append(name) - return result - - def _is_id(self, arg): - def id_or_underline(c): - return c.isalpha() or c == '_' - for c in arg: - if not id_or_underline(c) and not c.isdigit(): - return False - return id_or_underline(arg[0]) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/__init__.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/__init__.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -"""rope refactor package - -This package contains modules that perform python refactorings. -Refactoring classes perform refactorings in 4 steps: - -1. Collect some data for performing the refactoring and use them - to construct a refactoring class. Like:: - - renamer = Rename(project, resource, offset) - -2. Some refactorings give you useful information about the - refactoring after their construction. Like:: - - print(renamer.get_old_name()) - -3. Give the refactoring class more information about how to - perform the refactoring and get the changes this refactoring is - going to make. This is done by calling `get_changes` method of the - refactoring class. Like:: - - changes = renamer.get_changes(new_name) - -4. You can commit the changes. Like:: - - project.do(changes) - -These steps are like the steps IDEs usually do for performing a -refactoring. These are the things an IDE does in each step: - -1. Construct a refactoring object by giving it information like - resource, offset and ... . Some of the refactoring problems (like - performing rename refactoring on language keywords) can be reported - here. -2. Print some information about the refactoring and ask the user - about the information that are necessary for completing the - refactoring (like new name). -3. Call the `get_changes` by passing it information asked from - the user (if necessary) and get and preview the changes returned by - it. -4. perform the refactoring. - -From ``0.5m5`` release the `get_changes()` method of some time- -consuming refactorings take an optional `rope.base.taskhandle. -TaskHandle` parameter. You can use this object for stopping or -monitoring the progress of refactorings. - -""" -from rope.refactor.importutils import ImportOrganizer -from rope.refactor.topackage import ModuleToPackage - - -__all__ = ['rename', 'move', 'inline', 'extract', 'restructure', 'topackage', - 'importutils', 'usefunction', 'change_signature', - 'encapsulate_field', 'introduce_factory', 'introduce_parameter', - 'localtofield', 'method_object', 'multiproject'] diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/change_signature.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/change_signature.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,342 +0,0 @@ -import copy - -import rope.base.exceptions -from rope.base import pyobjects, taskhandle, evaluate, worder, codeanalyze, utils -from rope.base.change import ChangeContents, ChangeSet -from rope.refactor import occurrences, functionutils - - -class ChangeSignature(object): - - def __init__(self, project, resource, offset): - self.pycore = project.pycore - self.resource = resource - self.offset = offset - self._set_name_and_pyname() - if self.pyname is None or self.pyname.get_object() is None or \ - not isinstance(self.pyname.get_object(), pyobjects.PyFunction): - raise rope.base.exceptions.RefactoringError( - 'Change method signature should be performed on functions') - - def _set_name_and_pyname(self): - self.name = worder.get_name_at(self.resource, self.offset) - this_pymodule = self.pycore.resource_to_pyobject(self.resource) - self.primary, self.pyname = evaluate.eval_location2( - this_pymodule, self.offset) - if self.pyname is None: - return - pyobject = self.pyname.get_object() - if isinstance(pyobject, pyobjects.PyClass) and \ - '__init__' in pyobject: - self.pyname = pyobject['__init__'] - self.name = '__init__' - pyobject = self.pyname.get_object() - self.others = None - if self.name == '__init__' and \ - isinstance(pyobject, pyobjects.PyFunction) and \ - isinstance(pyobject.parent, pyobjects.PyClass): - pyclass = pyobject.parent - self.others = (pyclass.get_name(), - pyclass.parent[pyclass.get_name()]) - - def _change_calls(self, call_changer, in_hierarchy=None, resources=None, - handle=taskhandle.NullTaskHandle()): - if resources is None: - resources = self.pycore.get_python_files() - changes = ChangeSet('Changing signature of <%s>' % self.name) - job_set = handle.create_jobset('Collecting Changes', len(resources)) - finder = occurrences.create_finder( - self.pycore, self.name, self.pyname, instance=self.primary, - in_hierarchy=in_hierarchy and self.is_method()) - if self.others: - name, pyname = self.others - constructor_finder = occurrences.create_finder( - self.pycore, name, pyname, only_calls=True) - finder = _MultipleFinders([finder, constructor_finder]) - for file in resources: - job_set.started_job(file.path) - change_calls = _ChangeCallsInModule( - self.pycore, finder, file, call_changer) - changed_file = change_calls.get_changed_module() - if changed_file is not None: - changes.add_change(ChangeContents(file, changed_file)) - job_set.finished_job() - return changes - - def get_args(self): - """Get function arguments. - - Return a list of ``(name, default)`` tuples for all but star - and double star arguments. For arguments that don't have a - default, `None` will be used. - """ - return self._definfo().args_with_defaults - - def is_method(self): - pyfunction = self.pyname.get_object() - return isinstance(pyfunction.parent, pyobjects.PyClass) - - @utils.deprecated('Use `ChangeSignature.get_args()` instead') - def get_definition_info(self): - return self._definfo() - - def _definfo(self): - return functionutils.DefinitionInfo.read(self.pyname.get_object()) - - @utils.deprecated() - def normalize(self): - changer = _FunctionChangers( - self.pyname.get_object(), self.get_definition_info(), - [ArgumentNormalizer()]) - return self._change_calls(changer) - - @utils.deprecated() - def remove(self, index): - changer = _FunctionChangers( - self.pyname.get_object(), self.get_definition_info(), - [ArgumentRemover(index)]) - return self._change_calls(changer) - - @utils.deprecated() - def add(self, index, name, default=None, value=None): - changer = _FunctionChangers( - self.pyname.get_object(), self.get_definition_info(), - [ArgumentAdder(index, name, default, value)]) - return self._change_calls(changer) - - @utils.deprecated() - def inline_default(self, index): - changer = _FunctionChangers( - self.pyname.get_object(), self.get_definition_info(), - [ArgumentDefaultInliner(index)]) - return self._change_calls(changer) - - @utils.deprecated() - def reorder(self, new_ordering): - changer = _FunctionChangers( - self.pyname.get_object(), self.get_definition_info(), - [ArgumentReorderer(new_ordering)]) - return self._change_calls(changer) - - def get_changes(self, changers, in_hierarchy=False, resources=None, - task_handle=taskhandle.NullTaskHandle()): - """Get changes caused by this refactoring - - `changers` is a list of `_ArgumentChanger`\s. If `in_hierarchy` - is `True` the changers are applyed to all matching methods in - the class hierarchy. - `resources` can be a list of `rope.base.resource.File`\s that - should be searched for occurrences; if `None` all python files - in the project are searched. - - """ - function_changer = _FunctionChangers(self.pyname.get_object(), - self._definfo(), changers) - return self._change_calls(function_changer, in_hierarchy, - resources, task_handle) - - -class _FunctionChangers(object): - - def __init__(self, pyfunction, definition_info, changers=None): - self.pyfunction = pyfunction - self.definition_info = definition_info - self.changers = changers - self.changed_definition_infos = self._get_changed_definition_infos() - - def _get_changed_definition_infos(self): - result = [] - definition_info = self.definition_info - result.append(definition_info) - for changer in self.changers: - definition_info = copy.deepcopy(definition_info) - changer.change_definition_info(definition_info) - result.append(definition_info) - return result - - def change_definition(self, call): - return self.changed_definition_infos[-1].to_string() - - def change_call(self, primary, pyname, call): - call_info = functionutils.CallInfo.read( - primary, pyname, self.definition_info, call) - mapping = functionutils.ArgumentMapping(self.definition_info, call_info) - - for definition_info, changer in zip(self.changed_definition_infos, self.changers): - changer.change_argument_mapping(definition_info, mapping) - - return mapping.to_call_info(self.changed_definition_infos[-1]).to_string() - - -class _ArgumentChanger(object): - - def change_definition_info(self, definition_info): - pass - - def change_argument_mapping(self, definition_info, argument_mapping): - pass - - -class ArgumentNormalizer(_ArgumentChanger): - pass - - -class ArgumentRemover(_ArgumentChanger): - - def __init__(self, index): - self.index = index - - def change_definition_info(self, call_info): - if self.index < len(call_info.args_with_defaults): - del call_info.args_with_defaults[self.index] - elif self.index == len(call_info.args_with_defaults) and \ - call_info.args_arg is not None: - call_info.args_arg = None - elif (self.index == len(call_info.args_with_defaults) and - call_info.args_arg is None and call_info.keywords_arg is not None) or \ - (self.index == len(call_info.args_with_defaults) + 1 and - call_info.args_arg is not None and call_info.keywords_arg is not None): - call_info.keywords_arg = None - - def change_argument_mapping(self, definition_info, mapping): - if self.index < len(definition_info.args_with_defaults): - name = definition_info.args_with_defaults[0] - if name in mapping.param_dict: - del mapping.param_dict[name] - - -class ArgumentAdder(_ArgumentChanger): - - def __init__(self, index, name, default=None, value=None): - self.index = index - self.name = name - self.default = default - self.value = value - - def change_definition_info(self, definition_info): - for pair in definition_info.args_with_defaults: - if pair[0] == self.name: - raise rope.base.exceptions.RefactoringError( - 'Adding duplicate parameter: <%s>.' % self.name) - definition_info.args_with_defaults.insert(self.index, - (self.name, self.default)) - - def change_argument_mapping(self, definition_info, mapping): - if self.value is not None: - mapping.param_dict[self.name] = self.value - - -class ArgumentDefaultInliner(_ArgumentChanger): - - def __init__(self, index): - self.index = index - self.remove = False - - def change_definition_info(self, definition_info): - if self.remove: - definition_info.args_with_defaults[self.index] = \ - (definition_info.args_with_defaults[self.index][0], None) - - def change_argument_mapping(self, definition_info, mapping): - default = definition_info.args_with_defaults[self.index][1] - name = definition_info.args_with_defaults[self.index][0] - if default is not None and name not in mapping.param_dict: - mapping.param_dict[name] = default - - -class ArgumentReorderer(_ArgumentChanger): - - def __init__(self, new_order, autodef=None): - """Construct an `ArgumentReorderer` - - Note that the `new_order` is a list containing the new - position of parameters; not the position each parameter - is going to be moved to. (changed in ``0.5m4``) - - For example changing ``f(a, b, c)`` to ``f(c, a, b)`` - requires passing ``[2, 0, 1]`` and *not* ``[1, 2, 0]``. - - The `autodef` (automatic default) argument, forces rope to use - it as a default if a default is needed after the change. That - happens when an argument without default is moved after - another that has a default value. Note that `autodef` should - be a string or `None`; the latter disables adding automatic - default. - - """ - self.new_order = new_order - self.autodef = autodef - - def change_definition_info(self, definition_info): - new_args = list(definition_info.args_with_defaults) - for new_index, index in enumerate(self.new_order): - new_args[new_index] = definition_info.args_with_defaults[index] - seen_default = False - for index, (arg, default) in enumerate(list(new_args)): - if default is not None: - seen_default = True - if seen_default and default is None and self.autodef is not None: - new_args[index] = (arg, self.autodef) - definition_info.args_with_defaults = new_args - - -class _ChangeCallsInModule(object): - - def __init__(self, pycore, occurrence_finder, resource, call_changer): - self.pycore = pycore - self.occurrence_finder = occurrence_finder - self.resource = resource - self.call_changer = call_changer - - def get_changed_module(self): - word_finder = worder.Worder(self.source) - change_collector = codeanalyze.ChangeCollector(self.source) - for occurrence in self.occurrence_finder.find_occurrences(self.resource): - if not occurrence.is_called() and not occurrence.is_defined(): - continue - start, end = occurrence.get_primary_range() - begin_parens, end_parens = word_finder.get_word_parens_range(end - 1) - if occurrence.is_called(): - primary, pyname = occurrence.get_primary_and_pyname() - changed_call = self.call_changer.change_call( - primary, pyname, self.source[start:end_parens]) - else: - changed_call = self.call_changer.change_definition( - self.source[start:end_parens]) - if changed_call is not None: - change_collector.add_change(start, end_parens, changed_call) - return change_collector.get_changed() - - @property - @utils.saveit - def pymodule(self): - return self.pycore.resource_to_pyobject(self.resource) - - @property - @utils.saveit - def source(self): - if self.resource is not None: - return self.resource.read() - else: - return self.pymodule.source_code - - @property - @utils.saveit - def lines(self): - return self.pymodule.lines - - -class _MultipleFinders(object): - - def __init__(self, finders): - self.finders = finders - - def find_occurrences(self, resource=None, pymodule=None): - all_occurrences = [] - for finder in self.finders: - all_occurrences.extend(finder.find_occurrences(resource, pymodule)) - all_occurrences.sort(self._cmp_occurrences) - return all_occurrences - - def _cmp_occurrences(self, o1, o2): - return cmp(o1.get_primary_range(), o2.get_primary_range()) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/encapsulate_field.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/encapsulate_field.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,202 +0,0 @@ -from rope.base import pynames, taskhandle, evaluate, exceptions, worder, utils -from rope.base.change import ChangeSet, ChangeContents -from rope.refactor import sourceutils, occurrences - - -class EncapsulateField(object): - - def __init__(self, project, resource, offset): - self.pycore = project.pycore - self.name = worder.get_name_at(resource, offset) - this_pymodule = self.pycore.resource_to_pyobject(resource) - self.pyname = evaluate.eval_location(this_pymodule, offset) - if not self._is_an_attribute(self.pyname): - raise exceptions.RefactoringError( - 'Encapsulate field should be performed on class attributes.') - self.resource = self.pyname.get_definition_location()[0].get_resource() - - def get_changes(self, getter=None, setter=None, resources=None, - task_handle=taskhandle.NullTaskHandle()): - """Get the changes this refactoring makes - - If `getter` is not `None`, that will be the name of the - getter, otherwise ``get_${field_name}`` will be used. The - same is true for `setter` and if it is None set_${field_name} is - used. - - `resources` can be a list of `rope.base.resource.File`\s that - the refactoring should be applied on; if `None` all python - files in the project are searched. - - """ - if resources is None: - resources = self.pycore.get_python_files() - changes = ChangeSet('Encapsulate field <%s>' % self.name) - job_set = task_handle.create_jobset('Collecting Changes', - len(resources)) - if getter is None: - getter = 'get_' + self.name - if setter is None: - setter = 'set_' + self.name - renamer = GetterSetterRenameInModule( - self.pycore, self.name, self.pyname, getter, setter) - for file in resources: - job_set.started_job(file.path) - if file == self.resource: - result = self._change_holding_module(changes, renamer, - getter, setter) - changes.add_change(ChangeContents(self.resource, result)) - else: - result = renamer.get_changed_module(file) - if result is not None: - changes.add_change(ChangeContents(file, result)) - job_set.finished_job() - return changes - - def get_field_name(self): - """Get the name of the field to be encapsulated""" - return self.name - - def _is_an_attribute(self, pyname): - if pyname is not None and isinstance(pyname, pynames.AssignedName): - pymodule, lineno = self.pyname.get_definition_location() - scope = pymodule.get_scope().\ - get_inner_scope_for_line(lineno) - if scope.get_kind() == 'Class': - return pyname in scope.get_names().values() - parent = scope.parent - if parent is not None and parent.get_kind() == 'Class': - return pyname in parent.get_names().values() - return False - - def _get_defining_class_scope(self): - defining_scope = self._get_defining_scope() - if defining_scope.get_kind() == 'Function': - defining_scope = defining_scope.parent - return defining_scope - - def _get_defining_scope(self): - pymodule, line = self.pyname.get_definition_location() - return pymodule.get_scope().get_inner_scope_for_line(line) - - def _change_holding_module(self, changes, renamer, getter, setter): - pymodule = self.pycore.resource_to_pyobject(self.resource) - class_scope = self._get_defining_class_scope() - defining_object = self._get_defining_scope().pyobject - start, end = sourceutils.get_body_region(defining_object) - - new_source = renamer.get_changed_module(pymodule=pymodule, - skip_start=start, skip_end=end) - if new_source is not None: - pymodule = self.pycore.get_string_module(new_source, self.resource) - class_scope = pymodule.get_scope().\ - get_inner_scope_for_line(class_scope.get_start()) - indents = sourceutils.get_indent(self.pycore) * ' ' - getter = 'def %s(self):\n%sreturn self.%s' % \ - (getter, indents, self.name) - setter = 'def %s(self, value):\n%sself.%s = value' % \ - (setter, indents, self.name) - new_source = sourceutils.add_methods(pymodule, class_scope, - [getter, setter]) - return new_source - - -class GetterSetterRenameInModule(object): - - def __init__(self, pycore, name, pyname, getter, setter): - self.pycore = pycore - self.name = name - self.finder = occurrences.create_finder(pycore, name, pyname) - self.getter = getter - self.setter = setter - - def get_changed_module(self, resource=None, pymodule=None, - skip_start=0, skip_end=0): - change_finder = _FindChangesForModule(self, resource, pymodule, - skip_start, skip_end) - return change_finder.get_changed_module() - - -class _FindChangesForModule(object): - - def __init__(self, finder, resource, pymodule, skip_start, skip_end): - self.pycore = finder.pycore - self.finder = finder.finder - self.getter = finder.getter - self.setter = finder.setter - self.resource = resource - self.pymodule = pymodule - self.last_modified = 0 - self.last_set = None - self.set_index = None - self.skip_start = skip_start - self.skip_end = skip_end - - def get_changed_module(self): - result = [] - for occurrence in self.finder.find_occurrences(self.resource, - self.pymodule): - start, end = occurrence.get_word_range() - if self.skip_start <= start < self.skip_end: - continue - self._manage_writes(start, result) - result.append(self.source[self.last_modified:start]) - if self._is_assigned_in_a_tuple_assignment(occurrence): - raise exceptions.RefactoringError( - 'Cannot handle tuple assignments in encapsulate field.') - if occurrence.is_written(): - assignment_type = self.worder.get_assignment_type(start) - if assignment_type == '=': - result.append(self.setter + '(') - else: - var_name = self.source[occurrence.get_primary_range()[0]: - start] + self.getter + '()' - result.append(self.setter + '(' + var_name - + ' %s ' % assignment_type[:-1]) - current_line = self.lines.get_line_number(start) - start_line, end_line = self.pymodule.logical_lines.\ - logical_line_in(current_line) - self.last_set = self.lines.get_line_end(end_line) - end = self.source.index('=', end) + 1 - self.set_index = len(result) - else: - result.append(self.getter + '()') - self.last_modified = end - if self.last_modified != 0: - self._manage_writes(len(self.source), result) - result.append(self.source[self.last_modified:]) - return ''.join(result) - return None - - def _manage_writes(self, offset, result): - if self.last_set is not None and self.last_set <= offset: - result.append(self.source[self.last_modified:self.last_set]) - set_value = ''.join(result[self.set_index:]).strip() - del result[self.set_index:] - result.append(set_value + ')') - self.last_modified = self.last_set - self.last_set = None - - def _is_assigned_in_a_tuple_assignment(self, occurance): - offset = occurance.get_word_range()[0] - return self.worder.is_assigned_in_a_tuple_assignment(offset) - - @property - @utils.saveit - def source(self): - if self.resource is not None: - return self.resource.read() - else: - return self.pymodule.source_code - - @property - @utils.saveit - def lines(self): - if self.pymodule is None: - self.pymodule = self.pycore.resource_to_pyobject(self.resource) - return self.pymodule.lines - - @property - @utils.saveit - def worder(self): - return worder.Worder(self.source) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/extract.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/extract.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,789 +0,0 @@ -import re - -from rope.base import ast, codeanalyze -from rope.base.change import ChangeSet, ChangeContents -from rope.base.exceptions import RefactoringError -from rope.refactor import (sourceutils, similarfinder, - patchedast, suites, usefunction) - - -# Extract refactoring has lots of special cases. I tried to split it -# to smaller parts to make it more manageable: -# -# _ExtractInfo: holds information about the refactoring; it is passed -# to the parts that need to have information about the refactoring -# -# _ExtractCollector: merely saves all of the information necessary for -# performing the refactoring. -# -# _DefinitionLocationFinder: finds where to insert the definition. -# -# _ExceptionalConditionChecker: checks for exceptional conditions in -# which the refactoring cannot be applied. -# -# _ExtractMethodParts: generates the pieces of code (like definition) -# needed for performing extract method. -# -# _ExtractVariableParts: like _ExtractMethodParts for variables. -# -# _ExtractPerformer: Uses above classes to collect refactoring -# changes. -# -# There are a few more helper functions and classes used by above -# classes. -class _ExtractRefactoring(object): - - def __init__(self, project, resource, start_offset, end_offset, - variable=False): - self.project = project - self.pycore = project.pycore - self.resource = resource - self.start_offset = self._fix_start(resource.read(), start_offset) - self.end_offset = self._fix_end(resource.read(), end_offset) - - def _fix_start(self, source, offset): - while offset < len(source) and source[offset].isspace(): - offset += 1 - return offset - - def _fix_end(self, source, offset): - while offset > 0 and source[offset - 1].isspace(): - offset -= 1 - return offset - - def get_changes(self, extracted_name, similar=False, global_=False): - """Get the changes this refactoring makes - - :parameters: - - `similar`: if `True`, similar expressions/statements are also - replaced. - - `global_`: if `True`, the extracted method/variable will - be global. - - """ - info = _ExtractInfo( - self.project, self.resource, self.start_offset, self.end_offset, - extracted_name, variable=self.kind == 'variable', - similar=similar, make_global=global_) - new_contents = _ExtractPerformer(info).extract() - changes = ChangeSet('Extract %s <%s>' % (self.kind, - extracted_name)) - changes.add_change(ChangeContents(self.resource, new_contents)) - return changes - - -class ExtractMethod(_ExtractRefactoring): - - def __init__(self, *args, **kwds): - super(ExtractMethod, self).__init__(*args, **kwds) - - kind = 'method' - - -class ExtractVariable(_ExtractRefactoring): - - def __init__(self, *args, **kwds): - kwds = dict(kwds) - kwds['variable'] = True - super(ExtractVariable, self).__init__(*args, **kwds) - - kind = 'variable' - - -class _ExtractInfo(object): - """Holds information about the extract to be performed""" - - def __init__(self, project, resource, start, end, new_name, - variable, similar, make_global): - self.pycore = project.pycore - self.resource = resource - self.pymodule = self.pycore.resource_to_pyobject(resource) - self.global_scope = self.pymodule.get_scope() - self.source = self.pymodule.source_code - self.lines = self.pymodule.lines - self.new_name = new_name - self.variable = variable - self.similar = similar - self._init_parts(start, end) - self._init_scope() - self.make_global = make_global - - def _init_parts(self, start, end): - self.region = (self._choose_closest_line_end(start), - self._choose_closest_line_end(end, end=True)) - - start = self.logical_lines.logical_line_in( - self.lines.get_line_number(self.region[0]))[0] - end = self.logical_lines.logical_line_in( - self.lines.get_line_number(self.region[1]))[1] - self.region_lines = (start, end) - - self.lines_region = (self.lines.get_line_start(self.region_lines[0]), - self.lines.get_line_end(self.region_lines[1])) - - @property - def logical_lines(self): - return self.pymodule.logical_lines - - def _init_scope(self): - start_line = self.region_lines[0] - scope = self.global_scope.get_inner_scope_for_line(start_line) - if scope.get_kind() != 'Module' and scope.get_start() == start_line: - scope = scope.parent - self.scope = scope - self.scope_region = self._get_scope_region(self.scope) - - def _get_scope_region(self, scope): - return (self.lines.get_line_start(scope.get_start()), - self.lines.get_line_end(scope.get_end()) + 1) - - def _choose_closest_line_end(self, offset, end=False): - lineno = self.lines.get_line_number(offset) - line_start = self.lines.get_line_start(lineno) - line_end = self.lines.get_line_end(lineno) - if self.source[line_start:offset].strip() == '': - if end: - return line_start - 1 - else: - return line_start - elif self.source[offset:line_end].strip() == '': - return min(line_end, len(self.source)) - return offset - - @property - def one_line(self): - return self.region != self.lines_region and \ - (self.logical_lines.logical_line_in(self.region_lines[0]) == - self.logical_lines.logical_line_in(self.region_lines[1])) - - @property - def global_(self): - return self.scope.parent is None - - @property - def method(self): - return self.scope.parent is not None and \ - self.scope.parent.get_kind() == 'Class' - - @property - def indents(self): - return sourceutils.get_indents(self.pymodule.lines, - self.region_lines[0]) - - @property - def scope_indents(self): - if self.global_: - return 0 - return sourceutils.get_indents(self.pymodule.lines, - self.scope.get_start()) - - @property - def extracted(self): - return self.source[self.region[0]:self.region[1]] - - _returned = None - @property - def returned(self): - """Does the extracted piece contain return statement""" - if self._returned is None: - node = _parse_text(self.extracted) - self._returned = usefunction._returns_last(node) - return self._returned - - -class _ExtractCollector(object): - """Collects information needed for performing the extract""" - - def __init__(self, info): - self.definition = None - self.body_pattern = None - self.checks = {} - self.replacement_pattern = None - self.matches = None - self.replacements = None - self.definition_location = None - - -class _ExtractPerformer(object): - - def __init__(self, info): - self.info = info - _ExceptionalConditionChecker()(self.info) - - def extract(self): - extract_info = self._collect_info() - content = codeanalyze.ChangeCollector(self.info.source) - definition = extract_info.definition - lineno, indents = extract_info.definition_location - offset = self.info.lines.get_line_start(lineno) - indented = sourceutils.fix_indentation(definition, indents) - content.add_change(offset, offset, indented) - self._replace_occurrences(content, extract_info) - return content.get_changed() - - def _replace_occurrences(self, content, extract_info): - for match in extract_info.matches: - replacement = similarfinder.CodeTemplate( - extract_info.replacement_pattern) - mapping = {} - for name in replacement.get_names(): - node = match.get_ast(name) - if node: - start, end = patchedast.node_region(match.get_ast(name)) - mapping[name] = self.info.source[start:end] - else: - mapping[name] = name - region = match.get_region() - content.add_change(region[0], region[1], - replacement.substitute(mapping)) - - def _collect_info(self): - extract_collector = _ExtractCollector(self.info) - self._find_definition(extract_collector) - self._find_matches(extract_collector) - self._find_definition_location(extract_collector) - return extract_collector - - def _find_matches(self, collector): - regions = self._where_to_search() - finder = similarfinder.SimilarFinder(self.info.pymodule) - matches = [] - for start, end in regions: - matches.extend((finder.get_matches(collector.body_pattern, - collector.checks, start, end))) - collector.matches = matches - - def _where_to_search(self): - if self.info.similar: - if self.info.make_global or self.info.global_: - return [(0, len(self.info.pymodule.source_code))] - if self.info.method and not self.info.variable: - class_scope = self.info.scope.parent - regions = [] - method_kind = _get_function_kind(self.info.scope) - for scope in class_scope.get_scopes(): - if method_kind == 'method' and \ - _get_function_kind(scope) != 'method': - continue - start = self.info.lines.get_line_start(scope.get_start()) - end = self.info.lines.get_line_end(scope.get_end()) - regions.append((start, end)) - return regions - else: - if self.info.variable: - return [self.info.scope_region] - else: - return [self.info._get_scope_region(self.info.scope.parent)] - else: - return [self.info.region] - - def _find_definition_location(self, collector): - matched_lines = [] - for match in collector.matches: - start = self.info.lines.get_line_number(match.get_region()[0]) - start_line = self.info.logical_lines.logical_line_in(start)[0] - matched_lines.append(start_line) - location_finder = _DefinitionLocationFinder(self.info, matched_lines) - collector.definition_location = (location_finder.find_lineno(), - location_finder.find_indents()) - - def _find_definition(self, collector): - if self.info.variable: - parts = _ExtractVariableParts(self.info) - else: - parts = _ExtractMethodParts(self.info) - collector.definition = parts.get_definition() - collector.body_pattern = parts.get_body_pattern() - collector.replacement_pattern = parts.get_replacement_pattern() - collector.checks = parts.get_checks() - - -class _DefinitionLocationFinder(object): - - def __init__(self, info, matched_lines): - self.info = info - self.matched_lines = matched_lines - # This only happens when subexpressions cannot be matched - if not matched_lines: - self.matched_lines.append(self.info.region_lines[0]) - - def find_lineno(self): - if self.info.variable and not self.info.make_global: - return self._get_before_line() - if self.info.make_global or self.info.global_: - toplevel = self._find_toplevel(self.info.scope) - ast = self.info.pymodule.get_ast() - newlines = sorted(self.matched_lines + [toplevel.get_end() + 1]) - return suites.find_visible(ast, newlines) - return self._get_after_scope() - - def _find_toplevel(self, scope): - toplevel = scope - if toplevel.parent is not None: - while toplevel.parent.parent is not None: - toplevel = toplevel.parent - return toplevel - - def find_indents(self): - if self.info.variable and not self.info.make_global: - return sourceutils.get_indents(self.info.lines, - self._get_before_line()) - else: - if self.info.global_ or self.info.make_global: - return 0 - return self.info.scope_indents - - def _get_before_line(self): - ast = self.info.scope.pyobject.get_ast() - return suites.find_visible(ast, self.matched_lines) - - def _get_after_scope(self): - return self.info.scope.get_end() + 1 - - -class _ExceptionalConditionChecker(object): - - def __call__(self, info): - self.base_conditions(info) - if info.one_line: - self.one_line_conditions(info) - else: - self.multi_line_conditions(info) - - def base_conditions(self, info): - if info.region[1] > info.scope_region[1]: - raise RefactoringError('Bad region selected for extract method') - end_line = info.region_lines[1] - end_scope = info.global_scope.get_inner_scope_for_line(end_line) - if end_scope != info.scope and end_scope.get_end() != end_line: - raise RefactoringError('Bad region selected for extract method') - try: - extracted = info.source[info.region[0]:info.region[1]] - if info.one_line: - extracted = '(%s)' % extracted - if _UnmatchedBreakOrContinueFinder.has_errors(extracted): - raise RefactoringError('A break/continue without having a ' - 'matching for/while loop.') - except SyntaxError: - raise RefactoringError('Extracted piece should ' - 'contain complete statements.') - - def one_line_conditions(self, info): - if self._is_region_on_a_word(info): - raise RefactoringError('Should extract complete statements.') - if info.variable and not info.one_line: - raise RefactoringError('Extract variable should not ' - 'span multiple lines.') - - def multi_line_conditions(self, info): - node = _parse_text(info.source[info.region[0]:info.region[1]]) - count = usefunction._return_count(node) - if count > 1: - raise RefactoringError('Extracted piece can have only one ' - 'return statement.') - if usefunction._yield_count(node): - raise RefactoringError('Extracted piece cannot ' - 'have yield statements.') - if count == 1 and not usefunction._returns_last(node): - raise RefactoringError('Return should be the last statement.') - if info.region != info.lines_region: - raise RefactoringError('Extracted piece should ' - 'contain complete statements.') - - def _is_region_on_a_word(self, info): - if info.region[0] > 0 and self._is_on_a_word(info, info.region[0] - 1) or \ - self._is_on_a_word(info, info.region[1] - 1): - return True - - def _is_on_a_word(self, info, offset): - prev = info.source[offset] - if not (prev.isalnum() or prev == '_') or \ - offset + 1 == len(info.source): - return False - next = info.source[offset + 1] - return next.isalnum() or next == '_' - - -class _ExtractMethodParts(object): - - def __init__(self, info): - self.info = info - self.info_collector = self._create_info_collector() - - def get_definition(self): - if self.info.global_: - return '\n%s\n' % self._get_function_definition() - else: - return '\n%s' % self._get_function_definition() - - def get_replacement_pattern(self): - variables = [] - variables.extend(self._find_function_arguments()) - variables.extend(self._find_function_returns()) - return similarfinder.make_pattern(self._get_call(), variables) - - def get_body_pattern(self): - variables = [] - variables.extend(self._find_function_arguments()) - variables.extend(self._find_function_returns()) - variables.extend(self._find_temps()) - return similarfinder.make_pattern(self._get_body(), variables) - - def _get_body(self): - result = sourceutils.fix_indentation(self.info.extracted, 0) - if self.info.one_line: - result = '(%s)' % result - return result - - def _find_temps(self): - return usefunction.find_temps(self.info.pycore.project, - self._get_body()) - - def get_checks(self): - if self.info.method and not self.info.make_global: - if _get_function_kind(self.info.scope) == 'method': - class_name = similarfinder._pydefined_to_str( - self.info.scope.parent.pyobject) - return {self._get_self_name(): 'type=' + class_name} - return {} - - def _create_info_collector(self): - zero = self.info.scope.get_start() - 1 - start_line = self.info.region_lines[0] - zero - end_line = self.info.region_lines[1] - zero - info_collector = _FunctionInformationCollector(start_line, end_line, - self.info.global_) - body = self.info.source[self.info.scope_region[0]: - self.info.scope_region[1]] - node = _parse_text(body) - ast.walk(node, info_collector) - return info_collector - - def _get_function_definition(self): - args = self._find_function_arguments() - returns = self._find_function_returns() - result = [] - if self.info.method and not self.info.make_global and \ - _get_function_kind(self.info.scope) != 'method': - result.append('@staticmethod\n') - result.append('def %s:\n' % self._get_function_signature(args)) - unindented_body = self._get_unindented_function_body(returns) - indents = sourceutils.get_indent(self.info.pycore) - function_body = sourceutils.indent_lines(unindented_body, indents) - result.append(function_body) - definition = ''.join(result) - - return definition + '\n' - - def _get_function_signature(self, args): - args = list(args) - prefix = '' - if self._extracting_method(): - self_name = self._get_self_name() - if self_name is None: - raise RefactoringError('Extracting a method from a function ' - 'with no self argument.') - if self_name in args: - args.remove(self_name) - args.insert(0, self_name) - return prefix + self.info.new_name + \ - '(%s)' % self._get_comma_form(args) - - def _extracting_method(self): - return self.info.method and not self.info.make_global and \ - _get_function_kind(self.info.scope) == 'method' - - def _get_self_name(self): - param_names = self.info.scope.pyobject.get_param_names() - if param_names: - return param_names[0] - - def _get_function_call(self, args): - prefix = '' - if self.info.method and not self.info.make_global: - if _get_function_kind(self.info.scope) == 'method': - self_name = self._get_self_name() - if self_name in args: - args.remove(self_name) - prefix = self_name + '.' - else: - prefix = self.info.scope.parent.pyobject.get_name() + '.' - return prefix + '%s(%s)' % (self.info.new_name, - self._get_comma_form(args)) - - def _get_comma_form(self, names): - result = '' - if names: - result += names[0] - for name in names[1:]: - result += ', ' + name - return result - - def _get_call(self): - if self.info.one_line: - args = self._find_function_arguments() - return self._get_function_call(args) - args = self._find_function_arguments() - returns = self._find_function_returns() - call_prefix = '' - if returns: - call_prefix = self._get_comma_form(returns) + ' = ' - if self.info.returned: - call_prefix = 'return ' - return call_prefix + self._get_function_call(args) - - def _find_function_arguments(self): - # if not make_global, do not pass any global names; they are - # all visible. - if self.info.global_ and not self.info.make_global: - return () - if not self.info.one_line: - result = (self.info_collector.prewritten & - self.info_collector.read) - result |= (self.info_collector.prewritten & - self.info_collector.postread & - (self.info_collector.maybe_written - - self.info_collector.written)) - return list(result) - start = self.info.region[0] - if start == self.info.lines_region[0]: - start = start + re.search('\S', self.info.extracted).start() - function_definition = self.info.source[start:self.info.region[1]] - read = _VariableReadsAndWritesFinder.find_reads_for_one_liners( - function_definition) - return list(self.info_collector.prewritten.intersection(read)) - - def _find_function_returns(self): - if self.info.one_line or self.info.returned: - return [] - written = self.info_collector.written | \ - self.info_collector.maybe_written - return list(written & self.info_collector.postread) - - def _get_unindented_function_body(self, returns): - if self.info.one_line: - return 'return ' + _join_lines(self.info.extracted) - extracted_body = self.info.extracted - unindented_body = sourceutils.fix_indentation(extracted_body, 0) - if returns: - unindented_body += '\nreturn %s' % self._get_comma_form(returns) - return unindented_body - - -class _ExtractVariableParts(object): - - def __init__(self, info): - self.info = info - - def get_definition(self): - result = self.info.new_name + ' = ' + \ - _join_lines(self.info.extracted) + '\n' - return result - - def get_body_pattern(self): - return '(%s)' % self.info.extracted.strip() - - def get_replacement_pattern(self): - return self.info.new_name - - def get_checks(self): - return {} - - -class _FunctionInformationCollector(object): - - def __init__(self, start, end, is_global): - self.start = start - self.end = end - self.is_global = is_global - self.prewritten = set() - self.maybe_written = set() - self.written = set() - self.read = set() - self.postread = set() - self.postwritten = set() - self.host_function = True - self.conditional = False - - def _read_variable(self, name, lineno): - if self.start <= lineno <= self.end: - if name not in self.written: - self.read.add(name) - if self.end < lineno: - if name not in self.postwritten: - self.postread.add(name) - - def _written_variable(self, name, lineno): - if self.start <= lineno <= self.end: - if self.conditional: - self.maybe_written.add(name) - else: - self.written.add(name) - if self.start > lineno: - self.prewritten.add(name) - if self.end < lineno: - self.postwritten.add(name) - - def _FunctionDef(self, node): - if not self.is_global and self.host_function: - self.host_function = False - for name in _get_argnames(node.args): - self._written_variable(name, node.lineno) - for child in node.body: - ast.walk(child, self) - else: - self._written_variable(node.name, node.lineno) - visitor = _VariableReadsAndWritesFinder() - for child in node.body: - ast.walk(child, visitor) - for name in visitor.read - visitor.written: - self._read_variable(name, node.lineno) - - def _Name(self, node): - if isinstance(node.ctx, (ast.Store, ast.AugStore)): - self._written_variable(node.id, node.lineno) - if not isinstance(node.ctx, ast.Store): - self._read_variable(node.id, node.lineno) - - def _Assign(self, node): - ast.walk(node.value, self) - for child in node.targets: - ast.walk(child, self) - - def _ClassDef(self, node): - self._written_variable(node.name, node.lineno) - - def _handle_conditional_node(self, node): - self.conditional = True - try: - for child in ast.get_child_nodes(node): - ast.walk(child, self) - finally: - self.conditional = False - - def _If(self, node): - self._handle_conditional_node(node) - - def _While(self, node): - self._handle_conditional_node(node) - - def _For(self, node): - self._handle_conditional_node(node) - - - -def _get_argnames(arguments): - result = [node.id for node in arguments.args - if isinstance(node, ast.Name)] - if arguments.vararg: - result.append(arguments.vararg) - if arguments.kwarg: - result.append(arguments.kwarg) - return result - - -class _VariableReadsAndWritesFinder(object): - - def __init__(self): - self.written = set() - self.read = set() - - def _Name(self, node): - if isinstance(node.ctx, (ast.Store, ast.AugStore)): - self.written.add(node.id) - if not isinstance(node, ast.Store): - self.read.add(node.id) - - def _FunctionDef(self, node): - self.written.add(node.name) - visitor = _VariableReadsAndWritesFinder() - for child in ast.get_child_nodes(node): - ast.walk(child, visitor) - self.read.update(visitor.read - visitor.written) - - def _Class(self, node): - self.written.add(node.name) - - @staticmethod - def find_reads_and_writes(code): - if code.strip() == '': - return set(), set() - if isinstance(code, unicode): - code = code.encode('utf-8') - node = _parse_text(code) - visitor = _VariableReadsAndWritesFinder() - ast.walk(node, visitor) - return visitor.read, visitor.written - - @staticmethod - def find_reads_for_one_liners(code): - if code.strip() == '': - return set(), set() - node = _parse_text(code) - visitor = _VariableReadsAndWritesFinder() - ast.walk(node, visitor) - return visitor.read - - -class _UnmatchedBreakOrContinueFinder(object): - - def __init__(self): - self.error = False - self.loop_count = 0 - - def _For(self, node): - self.loop_encountered(node) - - def _While(self, node): - self.loop_encountered(node) - - def loop_encountered(self, node): - self.loop_count += 1 - for child in node.body: - ast.walk(child, self) - self.loop_count -= 1 - if node.orelse: - ast.walk(node.orelse, self) - - def _Break(self, node): - self.check_loop() - - def _Continue(self, node): - self.check_loop() - - def check_loop(self): - if self.loop_count < 1: - self.error = True - - def _FunctionDef(self, node): - pass - - def _ClassDef(self, node): - pass - - @staticmethod - def has_errors(code): - if code.strip() == '': - return False - node = _parse_text(code) - visitor = _UnmatchedBreakOrContinueFinder() - ast.walk(node, visitor) - return visitor.error - -def _get_function_kind(scope): - return scope.pyobject.get_kind() - - -def _parse_text(body): - body = sourceutils.fix_indentation(body, 0) - node = ast.parse(body) - return node - -def _join_lines(code): - lines = [] - for line in code.splitlines(): - if line.endswith('\\'): - lines.append(line[:-1].strip()) - else: - lines.append(line.strip()) - return ' '.join(lines) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/functionutils.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/functionutils.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,222 +0,0 @@ -import rope.base.exceptions -import rope.base.pyobjects -from rope.base.builtins import Lambda -from rope.base import worder - - -class DefinitionInfo(object): - - def __init__(self, function_name, is_method, args_with_defaults, - args_arg, keywords_arg): - self.function_name = function_name - self.is_method = is_method - self.args_with_defaults = args_with_defaults - self.args_arg = args_arg - self.keywords_arg = keywords_arg - - def to_string(self): - return '%s(%s)' % (self.function_name, self.arguments_to_string()) - - def arguments_to_string(self, from_index=0): - params = [] - for arg, default in self.args_with_defaults: - if default is not None: - params.append('%s=%s' % (arg, default)) - else: - params.append(arg) - if self.args_arg is not None: - params.append('*' + self.args_arg) - if self.keywords_arg: - params.append('**' + self.keywords_arg) - return ', '.join(params[from_index:]) - - @staticmethod - def _read(pyfunction, code): - scope = pyfunction.get_scope() - parent = scope.parent - parameter_names = pyfunction.get_param_names() - kind = pyfunction.get_kind() - is_method = kind == 'method' - is_lambda = kind == 'lambda' - info = _FunctionParser(code, is_method, is_lambda) - args, keywords = info.get_parameters() - args_arg = None - keywords_arg = None - if args and args[-1].startswith('**'): - keywords_arg = args[-1][2:] - del args[-1] - if args and args[-1].startswith('*'): - args_arg = args[-1][1:] - del args[-1] - args_with_defaults = [(name, None) for name in args] - args_with_defaults.extend(keywords) - return DefinitionInfo(info.get_function_name(), is_method, - args_with_defaults, args_arg, keywords_arg) - - @staticmethod - def read(pyfunction): - pymodule = pyfunction.get_module() - word_finder = worder.Worder(pymodule.source_code) - lineno = pyfunction.get_ast().lineno - start = pymodule.lines.get_line_start(lineno) - if isinstance(pyfunction, Lambda): - call = word_finder.get_lambda_and_args(start) - else: - call = word_finder.get_function_and_args_in_header(start) - return DefinitionInfo._read(pyfunction, call) - - -class CallInfo(object): - - def __init__(self, function_name, args, keywords, args_arg, - keywords_arg, implicit_arg, constructor): - self.function_name = function_name - self.args = args - self.keywords = keywords - self.args_arg = args_arg - self.keywords_arg = keywords_arg - self.implicit_arg = implicit_arg - self.constructor = constructor - - def to_string(self): - function = self.function_name - if self.implicit_arg: - function = self.args[0] + '.' + self.function_name - params = [] - start = 0 - if self.implicit_arg or self.constructor: - start = 1 - if self.args[start:]: - params.extend(self.args[start:]) - if self.keywords: - params.extend(['%s=%s' % (name, value) for name, value in self.keywords]) - if self.args_arg is not None: - params.append('*' + self.args_arg) - if self.keywords_arg: - params.append('**' + self.keywords_arg) - return '%s(%s)' % (function, ', '.join(params)) - - @staticmethod - def read(primary, pyname, definition_info, code): - is_method_call = CallInfo._is_method_call(primary, pyname) - is_constructor = CallInfo._is_class(pyname) - is_classmethod = CallInfo._is_classmethod(pyname) - info = _FunctionParser(code, is_method_call or is_classmethod) - args, keywords = info.get_parameters() - args_arg = None - keywords_arg = None - if args and args[-1].startswith('**'): - keywords_arg = args[-1][2:] - del args[-1] - if args and args[-1].startswith('*'): - args_arg = args[-1][1:] - del args[-1] - if is_constructor: - args.insert(0, definition_info.args_with_defaults[0][0]) - return CallInfo(info.get_function_name(), args, keywords, args_arg, - keywords_arg, is_method_call or is_classmethod, - is_constructor) - - @staticmethod - def _is_method_call(primary, pyname): - return primary is not None and \ - isinstance(primary.get_object().get_type(), - rope.base.pyobjects.PyClass) and \ - CallInfo._is_method(pyname) - - @staticmethod - def _is_class(pyname): - return pyname is not None and \ - isinstance(pyname.get_object(), - rope.base.pyobjects.PyClass) - - @staticmethod - def _is_method(pyname): - if pyname is not None and \ - isinstance(pyname.get_object(), rope.base.pyobjects.PyFunction): - return pyname.get_object().get_kind() == 'method' - return False - - @staticmethod - def _is_classmethod(pyname): - if pyname is not None and \ - isinstance(pyname.get_object(), rope.base.pyobjects.PyFunction): - return pyname.get_object().get_kind() == 'classmethod' - return False - - -class ArgumentMapping(object): - - def __init__(self, definition_info, call_info): - self.call_info = call_info - self.param_dict = {} - self.keyword_args = [] - self.args_arg = [] - for index, value in enumerate(call_info.args): - if index < len(definition_info.args_with_defaults): - name = definition_info.args_with_defaults[index][0] - self.param_dict[name] = value - else: - self.args_arg.append(value) - for name, value in call_info.keywords: - index = -1 - for pair in definition_info.args_with_defaults: - if pair[0] == name: - self.param_dict[name] = value - break - else: - self.keyword_args.append((name, value)) - - def to_call_info(self, definition_info): - args = [] - keywords = [] - for index in range(len(definition_info.args_with_defaults)): - name = definition_info.args_with_defaults[index][0] - if name in self.param_dict: - args.append(self.param_dict[name]) - else: - for i in range(index, len(definition_info.args_with_defaults)): - name = definition_info.args_with_defaults[i][0] - if name in self.param_dict: - keywords.append((name, self.param_dict[name])) - break - args.extend(self.args_arg) - keywords.extend(self.keyword_args) - return CallInfo(self.call_info.function_name, args, keywords, - self.call_info.args_arg, self.call_info.keywords_arg, - self.call_info.implicit_arg, self.call_info.constructor) - - -class _FunctionParser(object): - - def __init__(self, call, implicit_arg, is_lambda=False): - self.call = call - self.implicit_arg = implicit_arg - self.word_finder = worder.Worder(self.call) - if is_lambda: - self.last_parens = self.call.rindex(':') - else: - self.last_parens = self.call.rindex(')') - self.first_parens = self.word_finder._find_parens_start(self.last_parens) - - def get_parameters(self): - args, keywords = self.word_finder.get_parameters(self.first_parens, - self.last_parens) - if self.is_called_as_a_method(): - instance = self.call[:self.call.rindex('.', 0, self.first_parens)] - args.insert(0, instance.strip()) - return args, keywords - - def get_instance(self): - if self.is_called_as_a_method(): - return self.word_finder.get_primary_at( - self.call.rindex('.', 0, self.first_parens) - 1) - - def get_function_name(self): - if self.is_called_as_a_method(): - return self.word_finder.get_word_at(self.first_parens - 1) - else: - return self.word_finder.get_primary_at(self.first_parens - 1) - - def is_called_as_a_method(self): - return self.implicit_arg and '.' in self.call[:self.first_parens] diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/importutils/__init__.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/importutils/__init__.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,299 +0,0 @@ -"""A package for handling imports - -This package provides tools for modifying module imports after -refactorings or as a separate task. - -""" -import rope.base.evaluate -from rope.base.change import ChangeSet, ChangeContents -from rope.refactor import occurrences, rename -from rope.refactor.importutils import module_imports, actions -from rope.refactor.importutils.importinfo import NormalImport, FromImport -import rope.base.codeanalyze - - -class ImportOrganizer(object): - """Perform some import-related commands - - Each method returns a `rope.base.change.Change` object. - - """ - - def __init__(self, project): - self.project = project - self.pycore = project.pycore - self.import_tools = ImportTools(self.pycore) - - def organize_imports(self, resource, offset=None): - return self._perform_command_on_import_tools( - self.import_tools.organize_imports, resource, offset) - - def expand_star_imports(self, resource, offset=None): - return self._perform_command_on_import_tools( - self.import_tools.expand_stars, resource, offset) - - def froms_to_imports(self, resource, offset=None): - return self._perform_command_on_import_tools( - self.import_tools.froms_to_imports, resource, offset) - - def relatives_to_absolutes(self, resource, offset=None): - return self._perform_command_on_import_tools( - self.import_tools.relatives_to_absolutes, resource, offset) - - def handle_long_imports(self, resource, offset=None): - return self._perform_command_on_import_tools( - self.import_tools.handle_long_imports, resource, offset) - - def _perform_command_on_import_tools(self, method, resource, offset): - pymodule = self.pycore.resource_to_pyobject(resource) - before_performing = pymodule.source_code - import_filter = None - if offset is not None: - import_filter = self._line_filter( - pymodule.lines.get_line_number(offset)) - result = method(pymodule, import_filter=import_filter) - if result is not None and result != before_performing: - changes = ChangeSet(method.__name__.replace('_', ' ') + - ' in <%s>' % resource.path) - changes.add_change(ChangeContents(resource, result)) - return changes - - def _line_filter(self, lineno): - def import_filter(import_stmt): - return import_stmt.start_line <= lineno < import_stmt.end_line - return import_filter - - -class ImportTools(object): - - def __init__(self, pycore): - self.pycore = pycore - - def get_import(self, resource): - """The import statement for `resource`""" - module_name = self.pycore.modname(resource) - return NormalImport(((module_name, None), )) - - def get_from_import(self, resource, name): - """The from import statement for `name` in `resource`""" - module_name = self.pycore.modname(resource) - names = [] - if isinstance(name, list): - names = [(imported, None) for imported in name] - else: - names = [(name, None),] - return FromImport(module_name, 0, tuple(names)) - - def module_imports(self, module, imports_filter=None): - return module_imports.ModuleImports(self.pycore, module, - imports_filter) - - def froms_to_imports(self, pymodule, import_filter=None): - pymodule = self._clean_up_imports(pymodule, import_filter) - module_imports = self.module_imports(pymodule, import_filter) - for import_stmt in module_imports.imports: - if import_stmt.readonly or \ - not self._is_transformable_to_normal(import_stmt.import_info): - continue - pymodule = self._from_to_normal(pymodule, import_stmt) - - # Adding normal imports in place of froms - module_imports = self.module_imports(pymodule, import_filter) - for import_stmt in module_imports.imports: - if not import_stmt.readonly and \ - self._is_transformable_to_normal(import_stmt.import_info): - import_stmt.import_info = \ - NormalImport(((import_stmt.import_info.module_name, None),)) - module_imports.remove_duplicates() - return module_imports.get_changed_source() - - def expand_stars(self, pymodule, import_filter=None): - module_imports = self.module_imports(pymodule, import_filter) - module_imports.expand_stars() - return module_imports.get_changed_source() - - def _from_to_normal(self, pymodule, import_stmt): - resource = pymodule.get_resource() - from_import = import_stmt.import_info - module_name = from_import.module_name - for name, alias in from_import.names_and_aliases: - imported = name - if alias is not None: - imported = alias - occurrence_finder = occurrences.create_finder( - self.pycore, imported, pymodule[imported], imports=False) - source = rename.rename_in_module( - occurrence_finder, module_name + '.' + name, - pymodule=pymodule, replace_primary=True) - if source is not None: - pymodule = self.pycore.get_string_module(source, resource) - return pymodule - - def _clean_up_imports(self, pymodule, import_filter): - resource = pymodule.get_resource() - module_with_imports = self.module_imports(pymodule, import_filter) - module_with_imports.expand_stars() - source = module_with_imports.get_changed_source() - if source is not None: - pymodule = self.pycore.get_string_module(source, resource) - source = self.relatives_to_absolutes(pymodule) - if source is not None: - pymodule = self.pycore.get_string_module(source, resource) - - module_with_imports = self.module_imports(pymodule, import_filter) - module_with_imports.remove_duplicates() - module_with_imports.remove_unused_imports() - source = module_with_imports.get_changed_source() - if source is not None: - pymodule = self.pycore.get_string_module(source, resource) - return pymodule - - def relatives_to_absolutes(self, pymodule, import_filter=None): - module_imports = self.module_imports(pymodule, import_filter) - to_be_absolute_list = module_imports.get_relative_to_absolute_list() - for name, absolute_name in to_be_absolute_list: - pymodule = self._rename_in_module(pymodule, name, absolute_name) - module_imports = self.module_imports(pymodule, import_filter) - module_imports.get_relative_to_absolute_list() - source = module_imports.get_changed_source() - if source is None: - source = pymodule.source_code - return source - - def _is_transformable_to_normal(self, import_info): - if not isinstance(import_info, FromImport): - return False - return True - - def organize_imports(self, pymodule, - unused=True, duplicates=True, - selfs=True, sort=True, import_filter=None): - if unused or duplicates: - module_imports = self.module_imports(pymodule, import_filter) - if unused: - module_imports.remove_unused_imports() - if duplicates: - module_imports.remove_duplicates() - source = module_imports.get_changed_source() - if source is not None: - pymodule = self.pycore.get_string_module( - source, pymodule.get_resource()) - if selfs: - pymodule = self._remove_self_imports(pymodule, import_filter) - if sort: - return self.sort_imports(pymodule, import_filter) - else: - return pymodule.source_code - - def _remove_self_imports(self, pymodule, import_filter=None): - module_imports = self.module_imports(pymodule, import_filter) - to_be_fixed, to_be_renamed = module_imports.get_self_import_fix_and_rename_list() - for name in to_be_fixed: - try: - pymodule = self._rename_in_module(pymodule, name, '', till_dot=True) - except ValueError: - # There is a self import with direct access to it - return pymodule - for name, new_name in to_be_renamed: - pymodule = self._rename_in_module(pymodule, name, new_name) - module_imports = self.module_imports(pymodule, import_filter) - module_imports.get_self_import_fix_and_rename_list() - source = module_imports.get_changed_source() - if source is not None: - pymodule = self.pycore.get_string_module(source, pymodule.get_resource()) - return pymodule - - def _rename_in_module(self, pymodule, name, new_name, till_dot=False): - old_name = name.split('.')[-1] - old_pyname = rope.base.evaluate.eval_str(pymodule.get_scope(), name) - occurrence_finder = occurrences.create_finder( - self.pycore, old_name, old_pyname, imports=False) - changes = rope.base.codeanalyze.ChangeCollector(pymodule.source_code) - for occurrence in occurrence_finder.find_occurrences(pymodule=pymodule): - start, end = occurrence.get_primary_range() - if till_dot: - new_end = pymodule.source_code.index('.', end) + 1 - space = pymodule.source_code[end:new_end - 1].strip() - if not space == '': - for c in space: - if not c.isspace() and c not in '\\': - raise ValueError() - end = new_end - changes.add_change(start, end, new_name) - source = changes.get_changed() - if source is not None: - pymodule = self.pycore.get_string_module(source, pymodule.get_resource()) - return pymodule - - def sort_imports(self, pymodule, import_filter=None): - module_imports = self.module_imports(pymodule, import_filter) - module_imports.sort_imports() - return module_imports.get_changed_source() - - def handle_long_imports(self, pymodule, maxdots=2, maxlength=27, - import_filter=None): - # IDEA: `maxdots` and `maxlength` can be specified in project config - # adding new from imports - module_imports = self.module_imports(pymodule, import_filter) - to_be_fixed = module_imports.handle_long_imports(maxdots, maxlength) - # performing the renaming - pymodule = self.pycore.get_string_module( - module_imports.get_changed_source(), - resource=pymodule.get_resource()) - for name in to_be_fixed: - pymodule = self._rename_in_module(pymodule, name, - name.split('.')[-1]) - # organizing imports - return self.organize_imports(pymodule, selfs=False, sort=False, - import_filter=import_filter) - - -def get_imports(pycore, pydefined): - """A shortcut for getting the `ImportInfo`\s used in a scope""" - pymodule = pydefined.get_module() - module = module_imports.ModuleImports(pycore, pymodule) - if pymodule == pydefined: - return [stmt.import_info for stmt in module.imports] - return module.get_used_imports(pydefined) - - -def get_module_imports(pycore, pymodule): - """A shortcut for creating a `module_imports.ModuleImports` object""" - return module_imports.ModuleImports(pycore, pymodule) - - -def add_import(pycore, pymodule, module_name, name=None): - imports = get_module_imports(pycore, pymodule) - candidates = [] - names = [] - # from mod import name - if name is not None: - from_import = FromImport(module_name, 0, [(name, None)]) - names.append(name) - candidates.append(from_import) - # from pkg import mod - if '.' in module_name: - pkg, mod = module_name.rsplit('.', 1) - candidates.append(FromImport(pkg, 0, [(mod, None)])) - if name: - names.append(mod + '.' + name) - else: - names.append(mod) - # import mod - normal_import = NormalImport([(module_name, None)]) - if name: - names.append(module_name + '.' + name) - else: - names.append(module_name) - - candidates.append(normal_import) - - visitor = actions.AddingVisitor(pycore, candidates) - selected_import = normal_import - for import_statement in imports.imports: - if import_statement.accept(visitor): - selected_import = visitor.import_info - break - imports.add_import(selected_import) - imported_name = names[candidates.index(selected_import)] - return imports.get_changed_source(), imported_name diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/importutils/actions.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/importutils/actions.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,359 +0,0 @@ -import os -import sys - -from rope.base import pyobjects, exceptions, stdmods -from rope.refactor import occurrences -from rope.refactor.importutils import importinfo - - -class ImportInfoVisitor(object): - - def dispatch(self, import_): - try: - method_name = 'visit' + import_.import_info.__class__.__name__ - method = getattr(self, method_name) - return method(import_, import_.import_info) - except exceptions.ModuleNotFoundError: - pass - - def visitEmptyImport(self, import_stmt, import_info): - pass - - def visitNormalImport(self, import_stmt, import_info): - pass - - def visitFromImport(self, import_stmt, import_info): - pass - - -class RelativeToAbsoluteVisitor(ImportInfoVisitor): - - def __init__(self, pycore, current_folder): - self.to_be_absolute = [] - self.pycore = pycore - self.folder = current_folder - self.context = importinfo.ImportContext(pycore, current_folder) - - def visitNormalImport(self, import_stmt, import_info): - self.to_be_absolute.extend(self._get_relative_to_absolute_list(import_info)) - new_pairs = [] - for name, alias in import_info.names_and_aliases: - resource = self.pycore.find_module(name, folder=self.folder) - if resource is None: - new_pairs.append((name, alias)) - continue - absolute_name = self.pycore.modname(resource) - new_pairs.append((absolute_name, alias)) - if not import_info._are_name_and_alias_lists_equal( - new_pairs, import_info.names_and_aliases): - import_stmt.import_info = importinfo.NormalImport(new_pairs) - - def _get_relative_to_absolute_list(self, import_info): - result = [] - for name, alias in import_info.names_and_aliases: - if alias is not None: - continue - resource = self.pycore.find_module(name, folder=self.folder) - if resource is None: - continue - absolute_name = self.pycore.modname(resource) - if absolute_name != name: - result.append((name, absolute_name)) - return result - - def visitFromImport(self, import_stmt, import_info): - resource = import_info.get_imported_resource(self.context) - if resource is None: - return None - absolute_name = self.pycore.modname(resource) - if import_info.module_name != absolute_name: - import_stmt.import_info = importinfo.FromImport( - absolute_name, 0, import_info.names_and_aliases) - - -class FilteringVisitor(ImportInfoVisitor): - - def __init__(self, pycore, folder, can_select): - self.to_be_absolute = [] - self.pycore = pycore - self.can_select = self._transform_can_select(can_select) - self.context = importinfo.ImportContext(pycore, folder) - - def _transform_can_select(self, can_select): - def can_select_name_and_alias(name, alias): - imported = name - if alias is not None: - imported = alias - return can_select(imported) - return can_select_name_and_alias - - def visitNormalImport(self, import_stmt, import_info): - new_pairs = [] - for name, alias in import_info.names_and_aliases: - if self.can_select(name, alias): - new_pairs.append((name, alias)) - return importinfo.NormalImport(new_pairs) - - def visitFromImport(self, import_stmt, import_info): - if _is_future(import_info): - return import_info - new_pairs = [] - if import_info.is_star_import(): - for name in import_info.get_imported_names(self.context): - if self.can_select(name, None): - new_pairs.append(import_info.names_and_aliases[0]) - break - else: - for name, alias in import_info.names_and_aliases: - if self.can_select(name, alias): - new_pairs.append((name, alias)) - return importinfo.FromImport( - import_info.module_name, import_info.level, new_pairs) - - -class RemovingVisitor(ImportInfoVisitor): - - def __init__(self, pycore, folder, can_select): - self.to_be_absolute = [] - self.pycore = pycore - self.filtering = FilteringVisitor(pycore, folder, can_select) - - def dispatch(self, import_): - result = self.filtering.dispatch(import_) - if result is not None: - import_.import_info = result - - -class AddingVisitor(ImportInfoVisitor): - """A class for adding imports - - Given a list of `ImportInfo`\s, it tries to add each import to the - module and returns `True` and gives up when an import can be added - to older ones. - - """ - - def __init__(self, pycore, import_list): - self.pycore = pycore - self.import_list = import_list - self.import_info = None - - def dispatch(self, import_): - for import_info in self.import_list: - self.import_info = import_info - if ImportInfoVisitor.dispatch(self, import_): - return True - - # TODO: Handle adding relative and absolute imports - def visitNormalImport(self, import_stmt, import_info): - if not isinstance(self.import_info, import_info.__class__): - return False - # Adding ``import x`` and ``import x.y`` that results ``import x.y`` - if len(import_info.names_and_aliases) == \ - len(self.import_info.names_and_aliases) == 1: - imported1 = import_info.names_and_aliases[0] - imported2 = self.import_info.names_and_aliases[0] - if imported1[1] == imported2[1] is None: - if imported1[0].startswith(imported2[0] + '.'): - return True - if imported2[0].startswith(imported1[0] + '.'): - import_stmt.import_info = self.import_info - return True - # Multiple imports using a single import statement is discouraged - # so we won't bother adding them. - if self.import_info._are_name_and_alias_lists_equal( - import_info.names_and_aliases, self.import_info.names_and_aliases): - return True - - def visitFromImport(self, import_stmt, import_info): - if isinstance(self.import_info, import_info.__class__) and \ - import_info.module_name == self.import_info.module_name and \ - import_info.level == self.import_info.level: - if import_info.is_star_import(): - return True - if self.import_info.is_star_import(): - import_stmt.import_info = self.import_info - return True - new_pairs = list(import_info.names_and_aliases) - for pair in self.import_info.names_and_aliases: - if pair not in new_pairs: - new_pairs.append(pair) - import_stmt.import_info = importinfo.FromImport( - import_info.module_name, import_info.level, new_pairs) - return True - - -class ExpandStarsVisitor(ImportInfoVisitor): - - def __init__(self, pycore, folder, can_select): - self.pycore = pycore - self.filtering = FilteringVisitor(pycore, folder, can_select) - self.context = importinfo.ImportContext(pycore, folder) - - def visitNormalImport(self, import_stmt, import_info): - self.filtering.dispatch(import_stmt) - - def visitFromImport(self, import_stmt, import_info): - if import_info.is_star_import(): - new_pairs = [] - for name in import_info.get_imported_names(self.context): - new_pairs.append((name, None)) - new_import = importinfo.FromImport( - import_info.module_name, import_info.level, new_pairs) - import_stmt.import_info = \ - self.filtering.visitFromImport(None, new_import) - else: - self.filtering.dispatch(import_stmt) - - -class SelfImportVisitor(ImportInfoVisitor): - - def __init__(self, pycore, current_folder, resource): - self.pycore = pycore - self.folder = current_folder - self.resource = resource - self.to_be_fixed = set() - self.to_be_renamed = set() - self.context = importinfo.ImportContext(pycore, current_folder) - - def visitNormalImport(self, import_stmt, import_info): - new_pairs = [] - for name, alias in import_info.names_and_aliases: - resource = self.pycore.find_module(name, folder=self.folder) - if resource is not None and resource == self.resource: - imported = name - if alias is not None: - imported = alias - self.to_be_fixed.add(imported) - else: - new_pairs.append((name, alias)) - if not import_info._are_name_and_alias_lists_equal( - new_pairs, import_info.names_and_aliases): - import_stmt.import_info = importinfo.NormalImport(new_pairs) - - def visitFromImport(self, import_stmt, import_info): - resource = import_info.get_imported_resource(self.context) - if resource is None: - return - if resource == self.resource: - self._importing_names_from_self(import_info, import_stmt) - return - pymodule = self.pycore.resource_to_pyobject(resource) - new_pairs = [] - for name, alias in import_info.names_and_aliases: - try: - result = pymodule[name].get_object() - if isinstance(result, pyobjects.PyModule) and \ - result.get_resource() == self.resource: - imported = name - if alias is not None: - imported = alias - self.to_be_fixed.add(imported) - else: - new_pairs.append((name, alias)) - except exceptions.AttributeNotFoundError: - new_pairs.append((name, alias)) - if not import_info._are_name_and_alias_lists_equal( - new_pairs, import_info.names_and_aliases): - import_stmt.import_info = importinfo.FromImport( - import_info.module_name, import_info.level, new_pairs) - - def _importing_names_from_self(self, import_info, import_stmt): - if not import_info.is_star_import(): - for name, alias in import_info.names_and_aliases: - if alias is not None: - self.to_be_renamed.add((alias, name)) - import_stmt.empty_import() - - -class SortingVisitor(ImportInfoVisitor): - - def __init__(self, pycore, current_folder): - self.pycore = pycore - self.folder = current_folder - self.standard = set() - self.third_party = set() - self.in_project = set() - self.future = set() - self.context = importinfo.ImportContext(pycore, current_folder) - - def visitNormalImport(self, import_stmt, import_info): - if import_info.names_and_aliases: - name, alias = import_info.names_and_aliases[0] - resource = self.pycore.find_module( - name, folder=self.folder) - self._check_imported_resource(import_stmt, resource, name) - - def visitFromImport(self, import_stmt, import_info): - resource = import_info.get_imported_resource(self.context) - self._check_imported_resource(import_stmt, resource, - import_info.module_name) - - def _check_imported_resource(self, import_stmt, resource, imported_name): - info = import_stmt.import_info - if resource is not None and resource.project == self.pycore.project: - self.in_project.add(import_stmt) - elif _is_future(info): - self.future.add(import_stmt) - elif imported_name.split('.')[0] in stdmods.standard_modules(): - self.standard.add(import_stmt) - else: - self.third_party.add(import_stmt) - - -class LongImportVisitor(ImportInfoVisitor): - - def __init__(self, current_folder, pycore, maxdots, maxlength): - self.maxdots = maxdots - self.maxlength = maxlength - self.to_be_renamed = set() - self.current_folder = current_folder - self.pycore = pycore - self.new_imports = [] - - def visitNormalImport(self, import_stmt, import_info): - new_pairs = [] - for name, alias in import_info.names_and_aliases: - if alias is None and self._is_long(name): - self.to_be_renamed.add(name) - last_dot = name.rindex('.') - from_ = name[:last_dot] - imported = name[last_dot + 1:] - self.new_imports.append( - importinfo.FromImport(from_, 0, ((imported, None), ))) - - def _is_long(self, name): - return name.count('.') > self.maxdots or \ - ('.' in name and len(name) > self.maxlength) - - -class RemovePyNameVisitor(ImportInfoVisitor): - - def __init__(self, pycore, pymodule, pyname, folder): - self.pymodule = pymodule - self.pyname = pyname - self.context = importinfo.ImportContext(pycore, folder) - - def visitFromImport(self, import_stmt, import_info): - new_pairs = [] - if not import_info.is_star_import(): - for name, alias in import_info.names_and_aliases: - try: - pyname = self.pymodule[alias or name] - if occurrences.same_pyname(self.pyname, pyname): - continue - except exceptions.AttributeNotFoundError: - pass - new_pairs.append((name, alias)) - return importinfo.FromImport( - import_info.module_name, import_info.level, new_pairs) - - def dispatch(self, import_): - result = ImportInfoVisitor.dispatch(self, import_) - if result is not None: - import_.import_info = result - - -def _is_future(info): - return isinstance(info, importinfo.FromImport) and \ - info.module_name == '__future__' diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/importutils/importinfo.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/importutils/importinfo.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -class ImportStatement(object): - """Represent an import in a module - - `readonly` attribute controls whether this import can be changed - by import actions or not. - - """ - - def __init__(self, import_info, start_line, end_line, - main_statement=None, blank_lines=0): - self.start_line = start_line - self.end_line = end_line - self.readonly = False - self.main_statement = main_statement - self._import_info = None - self.import_info = import_info - self._is_changed = False - self.new_start = None - self.blank_lines = blank_lines - - def _get_import_info(self): - return self._import_info - - def _set_import_info(self, new_import): - if not self.readonly and \ - new_import is not None and not new_import == self._import_info: - self._is_changed = True - self._import_info = new_import - - import_info = property(_get_import_info, _set_import_info) - - def get_import_statement(self): - if self._is_changed or self.main_statement is None: - return self.import_info.get_import_statement() - else: - return self.main_statement - - def empty_import(self): - self.import_info = ImportInfo.get_empty_import() - - def move(self, lineno, blank_lines=0): - self.new_start = lineno - self.blank_lines = blank_lines - - def get_old_location(self): - return self.start_line, self.end_line - - def get_new_start(self): - return self.new_start - - def is_changed(self): - return self._is_changed or (self.new_start is not None or - self.new_start != self.start_line) - - def accept(self, visitor): - return visitor.dispatch(self) - - -class ImportInfo(object): - - def get_imported_primaries(self, context): - pass - - def get_imported_names(self, context): - return [primary.split('.')[0] - for primary in self.get_imported_primaries(context)] - - def get_import_statement(self): - pass - - def is_empty(self): - pass - - def __hash__(self): - return hash(self.get_import_statement()) - - def _are_name_and_alias_lists_equal(self, list1, list2): - if len(list1) != len(list2): - return False - for pair1, pair2 in zip(list1, list2): - if pair1 != pair2: - return False - return True - - def __eq__(self, obj): - return isinstance(obj, self.__class__) and \ - self.get_import_statement() == obj.get_import_statement() - - def __ne__(self, obj): - return not self.__eq__(obj) - - @staticmethod - def get_empty_import(): - return EmptyImport() - - -class NormalImport(ImportInfo): - - def __init__(self, names_and_aliases): - self.names_and_aliases = names_and_aliases - - def get_imported_primaries(self, context): - result = [] - for name, alias in self.names_and_aliases: - if alias: - result.append(alias) - else: - result.append(name) - return result - - def get_import_statement(self): - result = 'import ' - for name, alias in self.names_and_aliases: - result += name - if alias: - result += ' as ' + alias - result += ', ' - return result[:-2] - - def is_empty(self): - return len(self.names_and_aliases) == 0 - - -class FromImport(ImportInfo): - - def __init__(self, module_name, level, names_and_aliases): - self.module_name = module_name - self.level = level - self.names_and_aliases = names_and_aliases - - def get_imported_primaries(self, context): - if self.names_and_aliases[0][0] == '*': - module = self.get_imported_module(context) - return [name for name in module - if not name.startswith('_')] - result = [] - for name, alias in self.names_and_aliases: - if alias: - result.append(alias) - else: - result.append(name) - return result - - def get_imported_resource(self, context): - """Get the imported resource - - Returns `None` if module was not found. - """ - if self.level == 0: - return context.pycore.find_module( - self.module_name, folder=context.folder) - else: - return context.pycore.find_relative_module( - self.module_name, context.folder, self.level) - - def get_imported_module(self, context): - """Get the imported `PyModule` - - Raises `rope.base.exceptions.ModuleNotFoundError` if module - could not be found. - """ - if self.level == 0: - return context.pycore.get_module( - self.module_name, context.folder) - else: - return context.pycore.get_relative_module( - self.module_name, context.folder, self.level) - - def get_import_statement(self): - result = 'from ' + '.' * self.level + self.module_name + ' import ' - for name, alias in self.names_and_aliases: - result += name - if alias: - result += ' as ' + alias - result += ', ' - return result[:-2] - - def is_empty(self): - return len(self.names_and_aliases) == 0 - - def is_star_import(self): - return len(self.names_and_aliases) > 0 and \ - self.names_and_aliases[0][0] == '*' - - -class EmptyImport(ImportInfo): - - names_and_aliases = [] - - def is_empty(self): - return True - - def get_imported_primaries(self, context): - return [] - - -class ImportContext(object): - - def __init__(self, pycore, folder): - self.pycore = pycore - self.folder = folder diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/importutils/module_imports.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/importutils/module_imports.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,454 +0,0 @@ -import rope.base.pynames -from rope.base import ast, utils -from rope.refactor.importutils import importinfo -from rope.refactor.importutils import actions - - -class ModuleImports(object): - - def __init__(self, pycore, pymodule, import_filter=None): - self.pycore = pycore - self.pymodule = pymodule - self.separating_lines = 0 - self.filter = import_filter - - @property - @utils.saveit - def imports(self): - finder = _GlobalImportFinder(self.pymodule, self.pycore) - result = finder.find_import_statements() - self.separating_lines = finder.get_separating_line_count() - if self.filter is not None: - for import_stmt in result: - if not self.filter(import_stmt): - import_stmt.readonly = True - return result - - def _get_unbound_names(self, defined_pyobject): - visitor = _GlobalUnboundNameFinder(self.pymodule, defined_pyobject) - ast.walk(self.pymodule.get_ast(), visitor) - return visitor.unbound - - def remove_unused_imports(self): - can_select = _OneTimeSelector(self._get_unbound_names(self.pymodule)) - visitor = actions.RemovingVisitor( - self.pycore, self._current_folder(), can_select) - for import_statement in self.imports: - import_statement.accept(visitor) - - def get_used_imports(self, defined_pyobject): - result = [] - can_select = _OneTimeSelector(self._get_unbound_names(defined_pyobject)) - visitor = actions.FilteringVisitor( - self.pycore, self._current_folder(), can_select) - for import_statement in self.imports: - new_import = import_statement.accept(visitor) - if new_import is not None and not new_import.is_empty(): - result.append(new_import) - return result - - def get_changed_source(self): - imports = self.imports - after_removing = self._remove_imports(imports) - imports = [stmt for stmt in imports - if not stmt.import_info.is_empty()] - - first_non_blank = self._first_non_blank_line(after_removing, 0) - first_import = self._first_import_line() - 1 - result = [] - # Writing module docs - result.extend(after_removing[first_non_blank:first_import]) - # Writing imports - sorted_imports = sorted(imports, self._compare_import_locations) - for stmt in sorted_imports: - start = self._get_import_location(stmt) - if stmt != sorted_imports[0]: - result.append('\n' * stmt.blank_lines) - result.append(stmt.get_import_statement() + '\n') - if sorted_imports and first_non_blank < len(after_removing): - result.append('\n' * self.separating_lines) - - # Writing the body - first_after_imports = self._first_non_blank_line(after_removing, - first_import) - result.extend(after_removing[first_after_imports:]) - return ''.join(result) - - def _get_import_location(self, stmt): - start = stmt.get_new_start() - if start is None: - start = stmt.get_old_location()[0] - return start - - def _compare_import_locations(self, stmt1, stmt2): - def get_location(stmt): - if stmt.get_new_start() is not None: - return stmt.get_new_start() - else: - return stmt.get_old_location()[0] - return cmp(get_location(stmt1), get_location(stmt2)) - - def _remove_imports(self, imports): - lines = self.pymodule.source_code.splitlines(True) - after_removing = [] - last_index = 0 - for stmt in imports: - start, end = stmt.get_old_location() - after_removing.extend(lines[last_index:start - 1]) - last_index = end - 1 - for i in range(start, end): - after_removing.append('') - after_removing.extend(lines[last_index:]) - return after_removing - - def _first_non_blank_line(self, lines, lineno): - result = lineno - for line in lines[lineno:]: - if line.strip() == '': - result += 1 - else: - break - return result - - def add_import(self, import_info): - visitor = actions.AddingVisitor(self.pycore, [import_info]) - for import_statement in self.imports: - if import_statement.accept(visitor): - break - else: - lineno = self._get_new_import_lineno() - blanks = self._get_new_import_blanks() - self.imports.append(importinfo.ImportStatement( - import_info, lineno, lineno, - blank_lines=blanks)) - - def _get_new_import_blanks(self): - return 0 - - def _get_new_import_lineno(self): - if self.imports: - return self.imports[-1].end_line - return 1 - - def filter_names(self, can_select): - visitor = actions.RemovingVisitor( - self.pycore, self._current_folder(), can_select) - for import_statement in self.imports: - import_statement.accept(visitor) - - def expand_stars(self): - can_select = _OneTimeSelector(self._get_unbound_names(self.pymodule)) - visitor = actions.ExpandStarsVisitor( - self.pycore, self._current_folder(), can_select) - for import_statement in self.imports: - import_statement.accept(visitor) - - def remove_duplicates(self): - added_imports = [] - for import_stmt in self.imports: - visitor = actions.AddingVisitor(self.pycore, - [import_stmt.import_info]) - for added_import in added_imports: - if added_import.accept(visitor): - import_stmt.empty_import() - else: - added_imports.append(import_stmt) - - def get_relative_to_absolute_list(self): - visitor = rope.refactor.importutils.actions.RelativeToAbsoluteVisitor( - self.pycore, self._current_folder()) - for import_stmt in self.imports: - if not import_stmt.readonly: - import_stmt.accept(visitor) - return visitor.to_be_absolute - - def get_self_import_fix_and_rename_list(self): - visitor = rope.refactor.importutils.actions.SelfImportVisitor( - self.pycore, self._current_folder(), self.pymodule.get_resource()) - for import_stmt in self.imports: - if not import_stmt.readonly: - import_stmt.accept(visitor) - return visitor.to_be_fixed, visitor.to_be_renamed - - def _current_folder(self): - return self.pymodule.get_resource().parent - - def sort_imports(self): - # IDEA: Sort from import list - visitor = actions.SortingVisitor(self.pycore, self._current_folder()) - for import_statement in self.imports: - import_statement.accept(visitor) - in_projects = sorted(visitor.in_project, self._compare_imports) - third_party = sorted(visitor.third_party, self._compare_imports) - standards = sorted(visitor.standard, self._compare_imports) - future = sorted(visitor.future, self._compare_imports) - blank_lines = 0 - last_index = self._first_import_line() - last_index = self._move_imports(future, last_index, 0) - last_index = self._move_imports(standards, last_index, 1) - last_index = self._move_imports(third_party, last_index, 1) - last_index = self._move_imports(in_projects, last_index, 1) - self.separating_lines = 2 - - def _first_import_line(self): - nodes = self.pymodule.get_ast().body - lineno = 0 - if self.pymodule.get_doc() is not None: - lineno = 1 - if len(nodes) > lineno: - lineno = self.pymodule.logical_lines.logical_line_in( - nodes[lineno].lineno)[0] - else: - lineno = self.pymodule.lines.length() - while lineno > 1: - line = self.pymodule.lines.get_line(lineno - 1) - if line.strip() == '': - lineno -= 1 - else: - break - return lineno - - def _compare_imports(self, stmt1, stmt2): - str1 = stmt1.get_import_statement() - str2 = stmt2.get_import_statement() - if str1.startswith('from ') and not str2.startswith('from '): - return 1 - if not str1.startswith('from ') and str2.startswith('from '): - return -1 - return cmp(str1, str2) - - def _move_imports(self, imports, index, blank_lines): - if imports: - imports[0].move(index, blank_lines) - index += 1 - if len(imports) > 1: - for stmt in imports[1:]: - stmt.move(index) - index += 1 - return index - - def handle_long_imports(self, maxdots, maxlength): - visitor = actions.LongImportVisitor( - self._current_folder(), self.pycore, maxdots, maxlength) - for import_statement in self.imports: - if not import_statement.readonly: - import_statement.accept(visitor) - for import_info in visitor.new_imports: - self.add_import(import_info) - return visitor.to_be_renamed - - def remove_pyname(self, pyname): - """Removes pyname when imported in ``from mod import x``""" - visitor = actions.RemovePyNameVisitor(self.pycore, self.pymodule, - pyname, self._current_folder()) - for import_stmt in self.imports: - import_stmt.accept(visitor) - - -class _OneTimeSelector(object): - - def __init__(self, names): - self.names = names - self.selected_names = set() - - def __call__(self, imported_primary): - if self._can_name_be_added(imported_primary): - for name in self._get_dotted_tokens(imported_primary): - self.selected_names.add(name) - return True - return False - - def _get_dotted_tokens(self, imported_primary): - tokens = imported_primary.split('.') - for i in range(len(tokens)): - yield '.'.join(tokens[:i + 1]) - - def _can_name_be_added(self, imported_primary): - for name in self._get_dotted_tokens(imported_primary): - if name in self.names and name not in self.selected_names: - return True - return False - - -class _UnboundNameFinder(object): - - def __init__(self, pyobject): - self.pyobject = pyobject - - def _visit_child_scope(self, node): - pyobject = self.pyobject.get_module().get_scope().\ - get_inner_scope_for_line(node.lineno).pyobject - visitor = _LocalUnboundNameFinder(pyobject, self) - for child in ast.get_child_nodes(node): - ast.walk(child, visitor) - - def _FunctionDef(self, node): - self._visit_child_scope(node) - - def _ClassDef(self, node): - self._visit_child_scope(node) - - def _Name(self, node): - if self._get_root()._is_node_interesting(node) and \ - not self.is_bound(node.id): - self.add_unbound(node.id) - - def _Attribute(self, node): - result = [] - while isinstance(node, ast.Attribute): - result.append(node.attr) - node = node.value - if isinstance(node, ast.Name): - result.append(node.id) - primary = '.'.join(reversed(result)) - if self._get_root()._is_node_interesting(node) and \ - not self.is_bound(primary): - self.add_unbound(primary) - else: - ast.walk(node, self) - - def _get_root(self): - pass - - def is_bound(self, name, propagated=False): - pass - - def add_unbound(self, name): - pass - - -class _GlobalUnboundNameFinder(_UnboundNameFinder): - - def __init__(self, pymodule, wanted_pyobject): - super(_GlobalUnboundNameFinder, self).__init__(pymodule) - self.unbound = set() - self.names = set() - for name, pyname in pymodule._get_structural_attributes().items(): - if not isinstance(pyname, (rope.base.pynames.ImportedName, - rope.base.pynames.ImportedModule)): - self.names.add(name) - wanted_scope = wanted_pyobject.get_scope() - self.start = wanted_scope.get_start() - self.end = wanted_scope.get_end() + 1 - - def _get_root(self): - return self - - def is_bound(self, primary, propagated=False): - name = primary.split('.')[0] - if name in self.names: - return True - return False - - def add_unbound(self, name): - names = name.split('.') - for i in range(len(names)): - self.unbound.add('.'.join(names[:i + 1])) - - def _is_node_interesting(self, node): - return self.start <= node.lineno < self.end - - -class _LocalUnboundNameFinder(_UnboundNameFinder): - - def __init__(self, pyobject, parent): - super(_LocalUnboundNameFinder, self).__init__(pyobject) - self.parent = parent - - def _get_root(self): - return self.parent._get_root() - - def is_bound(self, primary, propagated=False): - name = primary.split('.')[0] - if propagated: - names = self.pyobject.get_scope().get_propagated_names() - else: - names = self.pyobject.get_scope().get_names() - if name in names or self.parent.is_bound(name, propagated=True): - return True - return False - - def add_unbound(self, name): - self.parent.add_unbound(name) - - -class _GlobalImportFinder(object): - - def __init__(self, pymodule, pycore): - self.current_folder = None - if pymodule.get_resource(): - self.current_folder = pymodule.get_resource().parent - self.pymodule = pymodule - self.pycore = pycore - self.imports = [] - self.pymodule = pymodule - self.lines = self.pymodule.lines - - def visit_import(self, node, end_line): - start_line = node.lineno - import_statement = importinfo.ImportStatement( - importinfo.NormalImport(self._get_names(node.names)), - start_line, end_line, self._get_text(start_line, end_line), - blank_lines=self._count_empty_lines_before(start_line)) - self.imports.append(import_statement) - - def _count_empty_lines_before(self, lineno): - result = 0 - for current in range(lineno - 1, 0, -1): - line = self.lines.get_line(current) - if line.strip() == '': - result += 1 - else: - break - return result - - def _count_empty_lines_after(self, lineno): - result = 0 - for current in range(lineno + 1, self.lines.length()): - line = self.lines.get_line(current) - if line.strip() == '': - result += 1 - else: - break - return result - - def get_separating_line_count(self): - if not self.imports: - return 0 - return self._count_empty_lines_after(self.imports[-1].end_line - 1) - - def _get_text(self, start_line, end_line): - result = [] - for index in range(start_line, end_line): - result.append(self.lines.get_line(index)) - return '\n'.join(result) - - def visit_from(self, node, end_line): - level = 0 - if node.level: - level = node.level - import_info = importinfo.FromImport( - node.module, level, self._get_names(node.names)) - start_line = node.lineno - self.imports.append(importinfo.ImportStatement( - import_info, node.lineno, end_line, - self._get_text(start_line, end_line), - blank_lines=self._count_empty_lines_before(start_line))) - - def _get_names(self, alias_names): - result = [] - for alias in alias_names: - result.append((alias.name, alias.asname)) - return result - - def find_import_statements(self): - nodes = self.pymodule.get_ast().body - for index, node in enumerate(nodes): - if isinstance(node, (ast.Import, ast.ImportFrom)): - lines = self.pymodule.logical_lines - end_line = lines.logical_line_in(node.lineno)[1] + 1 - if isinstance(node, ast.Import): - self.visit_import(node, end_line) - if isinstance(node, ast.ImportFrom): - self.visit_from(node, end_line) - return self.imports diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/inline.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/inline.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,615 +0,0 @@ -# Known Bugs when inlining a function/method -# The values passed to function are inlined using _inlined_variable. -# This may cause two problems, illustrated in the examples below -# -# def foo(var1): -# var1 = var1*10 -# return var1 -# -# If a call to foo(20) is inlined, the result of inlined function is 20, -# but it should be 200. -# -# def foo(var1): -# var2 = var1*10 -# return var2 -# -# 2- If a call to foo(10+10) is inlined the result of inlined function is 110 -# but it should be 200. - -import re - -import rope.base.exceptions -import rope.refactor.functionutils -from rope.base import (pynames, pyobjects, codeanalyze, - taskhandle, evaluate, worder, utils) -from rope.base.change import ChangeSet, ChangeContents -from rope.refactor import (occurrences, rename, sourceutils, - importutils, move, change_signature) - -def unique_prefix(): - n = 0 - while True: - yield "__" + str(n) + "__" - n += 1 - -def create_inline(project, resource, offset): - """Create a refactoring object for inlining - - Based on `resource` and `offset` it returns an instance of - `InlineMethod`, `InlineVariable` or `InlineParameter`. - - """ - pycore = project.pycore - pyname = _get_pyname(pycore, resource, offset) - message = 'Inline refactoring should be performed on ' \ - 'a method, local variable or parameter.' - if pyname is None: - raise rope.base.exceptions.RefactoringError(message) - if isinstance(pyname, pynames.ImportedName): - pyname = pyname._get_imported_pyname() - if isinstance(pyname, pynames.AssignedName): - return InlineVariable(project, resource, offset) - if isinstance(pyname, pynames.ParameterName): - return InlineParameter(project, resource, offset) - if isinstance(pyname.get_object(), pyobjects.PyFunction): - return InlineMethod(project, resource, offset) - else: - raise rope.base.exceptions.RefactoringError(message) - - -class _Inliner(object): - - def __init__(self, project, resource, offset): - self.project = project - self.pycore = project.pycore - self.pyname = _get_pyname(self.pycore, resource, offset) - range_finder = worder.Worder(resource.read()) - self.region = range_finder.get_primary_range(offset) - self.name = range_finder.get_word_at(offset) - self.offset = offset - self.original = resource - - def get_changes(self, *args, **kwds): - pass - - def get_kind(self): - """Return either 'variable', 'method' or 'parameter'""" - - -class InlineMethod(_Inliner): - - def __init__(self, *args, **kwds): - super(InlineMethod, self).__init__(*args, **kwds) - self.pyfunction = self.pyname.get_object() - self.pymodule = self.pyfunction.get_module() - self.resource = self.pyfunction.get_module().get_resource() - self.occurrence_finder = occurrences.create_finder( - self.pycore, self.name, self.pyname) - self.normal_generator = _DefinitionGenerator(self.project, - self.pyfunction) - self._init_imports() - - def _init_imports(self): - body = sourceutils.get_body(self.pyfunction) - body, imports = move.moving_code_with_imports( - self.pycore, self.resource, body) - self.imports = imports - self.others_generator = _DefinitionGenerator( - self.project, self.pyfunction, body=body) - - def _get_scope_range(self): - scope = self.pyfunction.get_scope() - lines = self.pymodule.lines - logicals = self.pymodule.logical_lines - start_line = scope.get_start() - if self.pyfunction.decorators: - decorators = self.pyfunction.decorators - if hasattr(decorators[0], 'lineno'): - start_line = decorators[0].lineno - start_offset = lines.get_line_start(start_line) - end_offset = min(lines.get_line_end(scope.end) + 1, - len(self.pymodule.source_code)) - return (start_offset, end_offset) - - def get_changes(self, remove=True, only_current=False, resources=None, - task_handle=taskhandle.NullTaskHandle()): - """Get the changes this refactoring makes - - If `remove` is `False` the definition will not be removed. If - `only_current` is `True`, the the current occurrence will be - inlined, only. - """ - changes = ChangeSet('Inline method <%s>' % self.name) - if resources is None: - resources = self.pycore.get_python_files() - if only_current: - resources = [self.original] - if remove: - resources.append(self.resource) - job_set = task_handle.create_jobset('Collecting Changes', - len(resources)) - for file in resources: - job_set.started_job(file.path) - if file == self.resource: - changes.add_change(self._defining_file_changes( - changes, remove=remove, only_current=only_current)) - else: - aim = None - if only_current and self.original == file: - aim = self.offset - handle = _InlineFunctionCallsForModuleHandle( - self.pycore, file, self.others_generator, aim) - result = move.ModuleSkipRenamer( - self.occurrence_finder, file, handle).get_changed_module() - if result is not None: - result = _add_imports(self.pycore, result, - file, self.imports) - if remove: - result = _remove_from(self.pycore, self.pyname, - result, file) - changes.add_change(ChangeContents(file, result)) - job_set.finished_job() - return changes - - def _get_removed_range(self): - scope = self.pyfunction.get_scope() - lines = self.pymodule.lines - logical = self.pymodule.logical_lines - start_line = scope.get_start() - start, end = self._get_scope_range() - end_line = scope.get_end() - for i in range(end_line + 1, lines.length()): - if lines.get_line(i).strip() == '': - end_line = i - else: - break - end = min(lines.get_line_end(end_line) + 1, - len(self.pymodule.source_code)) - return (start, end) - - def _defining_file_changes(self, changes, remove, only_current): - start_offset, end_offset = self._get_removed_range() - aim = None - if only_current: - if self.resource == self.original: - aim = self.offset - else: - # we don't want to change any of them - aim = len(self.resource.read()) + 100 - handle = _InlineFunctionCallsForModuleHandle( - self.pycore, self.resource, - self.normal_generator, aim_offset=aim) - replacement = None - if remove: - replacement = self._get_method_replacement() - result = move.ModuleSkipRenamer( - self.occurrence_finder, self.resource, handle, start_offset, - end_offset, replacement).get_changed_module() - return ChangeContents(self.resource, result) - - def _get_method_replacement(self): - if self._is_the_last_method_of_a_class(): - indents = sourceutils.get_indents( - self.pymodule.lines, self.pyfunction.get_scope().get_start()) - return ' ' * indents + 'pass\n' - return '' - - def _is_the_last_method_of_a_class(self): - pyclass = self.pyfunction.parent - if not isinstance(pyclass, pyobjects.PyClass): - return False - class_start, class_end = sourceutils.get_body_region(pyclass) - source = self.pymodule.source_code - lines = self.pymodule.lines - func_start, func_end = self._get_scope_range() - if source[class_start:func_start].strip() == '' and \ - source[func_end:class_end].strip() == '': - return True - return False - - def get_kind(self): - return 'method' - - -class InlineVariable(_Inliner): - - def __init__(self, *args, **kwds): - super(InlineVariable, self).__init__(*args, **kwds) - self.pymodule = self.pyname.get_definition_location()[0] - self.resource = self.pymodule.get_resource() - self._check_exceptional_conditions() - self._init_imports() - - def _check_exceptional_conditions(self): - if len(self.pyname.assignments) != 1: - raise rope.base.exceptions.RefactoringError( - 'Local variable should be assigned once for inlining.') - - def get_changes(self, remove=True, only_current=False, resources=None, - task_handle=taskhandle.NullTaskHandle()): - if resources is None: - if rename._is_local(self.pyname): - resources = [self.resource] - else: - resources = self.pycore.get_python_files() - if only_current: - resources = [self.original] - if remove and self.original != self.resource: - resources.append(self.resource) - changes = ChangeSet('Inline variable <%s>' % self.name) - jobset = task_handle.create_jobset('Calculating changes', - len(resources)) - - for resource in resources: - jobset.started_job(resource.path) - if resource == self.resource: - source = self._change_main_module(remove, only_current) - changes.add_change(ChangeContents(self.resource, source)) - else: - result = self._change_module(resource, remove, only_current) - if result is not None: - result = _add_imports(self.pycore, result, - resource, self.imports) - changes.add_change(ChangeContents(resource, result)) - jobset.finished_job() - return changes - - def _change_main_module(self, remove, only_current): - region = None - if only_current and self.original == self.resource: - region = self.region - return _inline_variable(self.pycore, self.pymodule, self.pyname, - self.name, remove=remove, region=region) - - def _init_imports(self): - vardef = _getvardef(self.pymodule, self.pyname) - self.imported, self.imports = move.moving_code_with_imports( - self.pycore, self.resource, vardef) - - def _change_module(self, resource, remove, only_current): - filters = [occurrences.NoImportsFilter(), - occurrences.PyNameFilter(self.pyname)] - if only_current and resource == self.original: - def check_aim(occurrence): - start, end = occurrence.get_primary_range() - if self.offset < start or end < self.offset: - return False - filters.insert(0, check_aim) - finder = occurrences.Finder(self.pycore, self.name, filters=filters) - changed = rename.rename_in_module( - finder, self.imported, resource=resource, replace_primary=True) - if changed and remove: - changed = _remove_from(self.pycore, self.pyname, changed, resource) - return changed - - def get_kind(self): - return 'variable' - - -class InlineParameter(_Inliner): - - def __init__(self, *args, **kwds): - super(InlineParameter, self).__init__(*args, **kwds) - resource, offset = self._function_location() - index = self.pyname.index - self.changers = [change_signature.ArgumentDefaultInliner(index)] - self.signature = change_signature.ChangeSignature(self.project, - resource, offset) - - def _function_location(self): - pymodule, lineno = self.pyname.get_definition_location() - resource = pymodule.get_resource() - start = pymodule.lines.get_line_start(lineno) - word_finder = worder.Worder(pymodule.source_code) - offset = word_finder.find_function_offset(start) - return resource, offset - - def get_changes(self, **kwds): - """Get the changes needed by this refactoring - - See `rope.refactor.change_signature.ChangeSignature.get_changes()` - for arguments. - """ - return self.signature.get_changes(self.changers, **kwds) - - def get_kind(self): - return 'parameter' - - -def _join_lines(lines): - definition_lines = [] - for unchanged_line in lines: - line = unchanged_line.strip() - if line.endswith('\\'): - line = line[:-1].strip() - definition_lines.append(line) - joined = ' '.join(definition_lines) - return joined - - -class _DefinitionGenerator(object): - unique_prefix = unique_prefix() - def __init__(self, project, pyfunction, body=None): - self.pycore = project.pycore - self.pyfunction = pyfunction - self.pymodule = pyfunction.get_module() - self.resource = self.pymodule.get_resource() - self.definition_info = self._get_definition_info() - self.definition_params = self._get_definition_params() - self._calculated_definitions = {} - if body is not None: - self.body = body - else: - self.body = sourceutils.get_body(self.pyfunction) - - def _get_definition_info(self): - return rope.refactor.functionutils.DefinitionInfo.read(self.pyfunction) - - def _get_definition_params(self): - definition_info = self.definition_info - paramdict = dict([pair for pair in definition_info.args_with_defaults]) - if definition_info.args_arg is not None or \ - definition_info.keywords_arg is not None: - raise rope.base.exceptions.RefactoringError( - 'Cannot inline functions with list and keyword arguements.') - if self.pyfunction.get_kind() == 'classmethod': - paramdict[definition_info.args_with_defaults[0][0]] = \ - self.pyfunction.parent.get_name() - return paramdict - - def get_function_name(self): - return self.pyfunction.get_name() - - def get_definition(self, primary, pyname, call, host_vars=[],returns=False): - # caching already calculated definitions - return self._calculate_definition(primary, pyname, call, - host_vars, returns) - - def _calculate_header(self, primary, pyname, call): - # A header is created which initializes parameters - # to the values passed to the function. - call_info = rope.refactor.functionutils.CallInfo.read( - primary, pyname, self.definition_info, call) - paramdict = self.definition_params - mapping = rope.refactor.functionutils.ArgumentMapping( - self.definition_info, call_info) - for param_name, value in mapping.param_dict.items(): - paramdict[param_name] = value - header = '' - to_be_inlined = [] - mod = self.pycore.get_string_module(self.body) - all_names = mod.get_scope().get_names() - assigned_names = [name for name in all_names if - isinstance(all_names[name], rope.base.pynamesdef.AssignedName)] - for name, value in paramdict.items(): - if name != value and value is not None: - header += name + ' = ' + value.replace('\n', ' ') + '\n' - to_be_inlined.append(name) - return header, to_be_inlined - - def _calculate_definition(self, primary, pyname, call, host_vars, returns): - - header, to_be_inlined = self._calculate_header(primary, pyname, call) - - source = header + self.body - mod = self.pycore.get_string_module(source) - name_dict = mod.get_scope().get_names() - all_names = [x for x in name_dict if - not isinstance(name_dict[x], rope.base.builtins.BuiltinName)] - - # If there is a name conflict, all variable names - # inside the inlined function are renamed - if len(set(all_names).intersection(set(host_vars))) > 0: - - prefix = _DefinitionGenerator.unique_prefix.next() - guest = self.pycore.get_string_module(source, self.resource) - - to_be_inlined = [prefix+item for item in to_be_inlined] - for item in all_names: - pyname = guest[item] - occurrence_finder = occurrences.create_finder( - self.pycore, item, pyname) - source = rename.rename_in_module(occurrence_finder, - prefix+item, pymodule=guest) - guest = self.pycore.get_string_module(source, self.resource) - - #parameters not reassigned inside the functions are now inlined. - for name in to_be_inlined: - pymodule = self.pycore.get_string_module(source, self.resource) - pyname = pymodule[name] - source = _inline_variable(self.pycore, pymodule, pyname, name) - - return self._replace_returns_with(source, returns) - - def _replace_returns_with(self, source, returns): - result = [] - returned = None - last_changed = 0 - for match in _DefinitionGenerator._get_return_pattern().finditer(source): - for key, value in match.groupdict().items(): - if value and key == 'return': - result.append(source[last_changed:match.start('return')]) - if returns: - self._check_nothing_after_return(source, - match.end('return')) - returned = _join_lines( - source[match.end('return'): len(source)].splitlines()) - last_changed = len(source) - else: - current = match.end('return') - while current < len(source) and source[current] in ' \t': - current += 1 - last_changed = current - if current == len(source) or source[current] == '\n': - result.append('pass') - result.append(source[last_changed:]) - return ''.join(result), returned - - def _check_nothing_after_return(self, source, offset): - lines = codeanalyze.SourceLinesAdapter(source) - lineno = lines.get_line_number(offset) - logical_lines = codeanalyze.LogicalLineFinder(lines) - lineno = logical_lines.logical_line_in(lineno)[1] - if source[lines.get_line_end(lineno):len(source)].strip() != '': - raise rope.base.exceptions.RefactoringError( - 'Cannot inline functions with statements after return statement.') - - @classmethod - def _get_return_pattern(cls): - if not hasattr(cls, '_return_pattern'): - def named_pattern(name, list_): - return "(?P<%s>" % name + "|".join(list_) + ")" - comment_pattern = named_pattern('comment', [r'#[^\n]*']) - string_pattern = named_pattern('string', - [codeanalyze.get_string_pattern()]) - return_pattern = r'\b(?Preturn)\b' - cls._return_pattern = re.compile(comment_pattern + "|" + - string_pattern + "|" + - return_pattern) - return cls._return_pattern - - -class _InlineFunctionCallsForModuleHandle(object): - - def __init__(self, pycore, resource, - definition_generator, aim_offset=None): - """Inlines occurrences - - If `aim` is not `None` only the occurrences that intersect - `aim` offset will be inlined. - - """ - self.pycore = pycore - self.generator = definition_generator - self.resource = resource - self.aim = aim_offset - - def occurred_inside_skip(self, change_collector, occurrence): - if not occurrence.is_defined(): - raise rope.base.exceptions.RefactoringError( - 'Cannot inline functions that reference themselves') - - def occurred_outside_skip(self, change_collector, occurrence): - start, end = occurrence.get_primary_range() - # we remove out of date imports later - if occurrence.is_in_import_statement(): - return - # the function is referenced outside an import statement - if not occurrence.is_called(): - raise rope.base.exceptions.RefactoringError( - 'Reference to inlining function other than function call' - ' in ' % (self.resource.path, start)) - if self.aim is not None and (self.aim < start or self.aim > end): - return - end_parens = self._find_end_parens(self.source, end - 1) - lineno = self.lines.get_line_number(start) - start_line, end_line = self.pymodule.logical_lines.\ - logical_line_in(lineno) - line_start = self.lines.get_line_start(start_line) - line_end = self.lines.get_line_end(end_line) - - - returns = self.source[line_start:start].strip() != '' or \ - self.source[end_parens:line_end].strip() != '' - indents = sourceutils.get_indents(self.lines, start_line) - primary, pyname = occurrence.get_primary_and_pyname() - - host = self.pycore.resource_to_pyobject(self.resource) - scope = host.scope.get_inner_scope_for_line(lineno) - definition, returned = self.generator.get_definition( - primary, pyname, self.source[start:end_parens], scope.get_names(), returns=returns) - - end = min(line_end + 1, len(self.source)) - change_collector.add_change(line_start, end, - sourceutils.fix_indentation(definition, indents)) - if returns: - name = returned - if name is None: - name = 'None' - change_collector.add_change( - line_end, end, self.source[line_start:start] + name + - self.source[end_parens:end]) - - def _find_end_parens(self, source, offset): - finder = worder.Worder(source) - return finder.get_word_parens_range(offset)[1] - - @property - @utils.saveit - def pymodule(self): - return self.pycore.resource_to_pyobject(self.resource) - - @property - @utils.saveit - def source(self): - if self.resource is not None: - return self.resource.read() - else: - return self.pymodule.source_code - - @property - @utils.saveit - def lines(self): - return self.pymodule.lines - - -def _inline_variable(pycore, pymodule, pyname, name, - remove=True, region=None): - definition = _getvardef(pymodule, pyname) - start, end = _assigned_lineno(pymodule, pyname) - - occurrence_finder = occurrences.create_finder(pycore, name, pyname) - changed_source = rename.rename_in_module( - occurrence_finder, definition, pymodule=pymodule, - replace_primary=True, writes=False, region=region) - if changed_source is None: - changed_source = pymodule.source_code - if remove: - lines = codeanalyze.SourceLinesAdapter(changed_source) - source = changed_source[:lines.get_line_start(start)] + \ - changed_source[lines.get_line_end(end) + 1:] - else: - source = changed_source - return source - -def _getvardef(pymodule, pyname): - assignment = pyname.assignments[0] - lines = pymodule.lines - start, end = _assigned_lineno(pymodule, pyname) - definition_with_assignment = _join_lines( - [lines.get_line(n) for n in range(start, end + 1)]) - if assignment.levels: - raise rope.base.exceptions.RefactoringError( - 'Cannot inline tuple assignments.') - definition = definition_with_assignment[definition_with_assignment.\ - index('=') + 1:].strip() - return definition - -def _assigned_lineno(pymodule, pyname): - definition_line = pyname.assignments[0].ast_node.lineno - return pymodule.logical_lines.logical_line_in(definition_line) - -def _add_imports(pycore, source, resource, imports): - if not imports: - return source - pymodule = pycore.get_string_module(source, resource) - module_import = importutils.get_module_imports(pycore, pymodule) - for import_info in imports: - module_import.add_import(import_info) - source = module_import.get_changed_source() - pymodule = pycore.get_string_module(source, resource) - import_tools = importutils.ImportTools(pycore) - return import_tools.organize_imports(pymodule, unused=False, sort=False) - -def _get_pyname(pycore, resource, offset): - pymodule = pycore.resource_to_pyobject(resource) - pyname = evaluate.eval_location(pymodule, offset) - if isinstance(pyname, pynames.ImportedName): - pyname = pyname._get_imported_pyname() - return pyname - -def _remove_from(pycore, pyname, source, resource): - pymodule = pycore.get_string_module(source, resource) - module_import = importutils.get_module_imports(pycore, pymodule) - module_import.remove_pyname(pyname) - return module_import.get_changed_source() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/introduce_factory.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/introduce_factory.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -import rope.base.exceptions -import rope.base.pyobjects -from rope.base import taskhandle, evaluate -from rope.base.change import (ChangeSet, ChangeContents) -from rope.refactor import rename, occurrences, sourceutils, importutils - - -class IntroduceFactory(object): - - def __init__(self, project, resource, offset): - self.pycore = project.pycore - self.offset = offset - - this_pymodule = self.pycore.resource_to_pyobject(resource) - self.old_pyname = evaluate.eval_location(this_pymodule, offset) - if self.old_pyname is None or not isinstance(self.old_pyname.get_object(), - rope.base.pyobjects.PyClass): - raise rope.base.exceptions.RefactoringError( - 'Introduce factory should be performed on a class.') - self.old_name = self.old_pyname.get_object().get_name() - self.pymodule = self.old_pyname.get_object().get_module() - self.resource = self.pymodule.get_resource() - - def get_changes(self, factory_name, global_factory=False, resources=None, - task_handle=taskhandle.NullTaskHandle()): - """Get the changes this refactoring makes - - `factory_name` indicates the name of the factory function to - be added. If `global_factory` is `True` the factory will be - global otherwise a static method is added to the class. - - `resources` can be a list of `rope.base.resource.File`\s that - this refactoring should be applied on; if `None` all python - files in the project are searched. - - """ - if resources is None: - resources = self.pycore.get_python_files() - changes = ChangeSet('Introduce factory method <%s>' % factory_name) - job_set = task_handle.create_jobset('Collecting Changes', - len(resources)) - self._change_module(resources, changes, factory_name, - global_factory, job_set) - return changes - - def get_name(self): - """Return the name of the class""" - return self.old_name - - def _change_module(self, resources, changes, - factory_name, global_, job_set): - if global_: - replacement = '__rope_factory_%s_' % factory_name - else: - replacement = self._new_function_name(factory_name, global_) - - for file_ in resources: - job_set.started_job(file_.path) - if file_ == self.resource: - self._change_resource(changes, factory_name, global_) - job_set.finished_job() - continue - changed_code = self._rename_occurrences(file_, replacement, - global_) - if changed_code is not None: - if global_: - new_pymodule = self.pycore.get_string_module(changed_code, - self.resource) - modname = self.pycore.modname(self.resource) - changed_code, imported = importutils.add_import( - self.pycore, new_pymodule, modname, factory_name) - changed_code = changed_code.replace(replacement, imported) - changes.add_change(ChangeContents(file_, changed_code)) - job_set.finished_job() - - def _change_resource(self, changes, factory_name, global_): - class_scope = self.old_pyname.get_object().get_scope() - source_code = self._rename_occurrences( - self.resource, self._new_function_name(factory_name, - global_), global_) - if source_code is None: - source_code = self.pymodule.source_code - else: - self.pymodule = self.pycore.get_string_module( - source_code, resource=self.resource) - lines = self.pymodule.lines - start = self._get_insertion_offset(class_scope, lines) - result = source_code[:start] - result += self._get_factory_method(lines, class_scope, - factory_name, global_) - result += source_code[start:] - changes.add_change(ChangeContents(self.resource, result)) - - def _get_insertion_offset(self, class_scope, lines): - start_line = class_scope.get_end() - if class_scope.get_scopes(): - start_line = class_scope.get_scopes()[-1].get_end() - start = lines.get_line_end(start_line) + 1 - return start - - def _get_factory_method(self, lines, class_scope, - factory_name, global_): - unit_indents = ' ' * sourceutils.get_indent(self.pycore) - if global_: - if self._get_scope_indents(lines, class_scope) > 0: - raise rope.base.exceptions.RefactoringError( - 'Cannot make global factory method for nested classes.') - return ('\ndef %s(*args, **kwds):\n%sreturn %s(*args, **kwds)\n' % - (factory_name, unit_indents, self.old_name)) - unindented_factory = \ - ('@staticmethod\ndef %s(*args, **kwds):\n' % factory_name + - '%sreturn %s(*args, **kwds)\n' % (unit_indents, self.old_name)) - indents = self._get_scope_indents(lines, class_scope) + \ - sourceutils.get_indent(self.pycore) - return '\n' + sourceutils.indent_lines(unindented_factory, indents) - - def _get_scope_indents(self, lines, scope): - return sourceutils.get_indents(lines, scope.get_start()) - - def _new_function_name(self, factory_name, global_): - if global_: - return factory_name - else: - return self.old_name + '.' + factory_name - - def _rename_occurrences(self, file_, changed_name, global_factory): - finder = occurrences.create_finder(self.pycore, self.old_name, - self.old_pyname, only_calls=True) - result = rename.rename_in_module(finder, changed_name, resource=file_, - replace_primary=global_factory) - return result - -IntroduceFactoryRefactoring = IntroduceFactory diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/introduce_parameter.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/introduce_parameter.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -import rope.base.change -from rope.base import exceptions, evaluate, worder, codeanalyze -from rope.refactor import functionutils, sourceutils, occurrences - - -class IntroduceParameter(object): - """Introduce parameter refactoring - - This refactoring adds a new parameter to a function and replaces - references to an expression in it with the new parameter. - - The parameter finding part is different from finding similar - pieces in extract refactorings. In this refactoring parameters - are found based on the object they reference to. For instance - in:: - - class A(object): - var = None - - class B(object): - a = A() - - b = B() - a = b.a - - def f(a): - x = b.a.var + a.var - - using this refactoring on ``a.var`` with ``p`` as the new - parameter name, will result in:: - - def f(p=a.var): - x = p + p - - """ - - def __init__(self, project, resource, offset): - self.pycore = project.pycore - self.resource = resource - self.offset = offset - self.pymodule = self.pycore.resource_to_pyobject(self.resource) - scope = self.pymodule.get_scope().get_inner_scope_for_offset(offset) - if scope.get_kind() != 'Function': - raise exceptions.RefactoringError( - 'Introduce parameter should be performed inside functions') - self.pyfunction = scope.pyobject - self.name, self.pyname = self._get_name_and_pyname() - if self.pyname is None: - raise exceptions.RefactoringError( - 'Cannot find the definition of <%s>' % self.name) - - def _get_primary(self): - word_finder = worder.Worder(self.resource.read()) - return word_finder.get_primary_at(self.offset) - - def _get_name_and_pyname(self): - return (worder.get_name_at(self.resource, self.offset), - evaluate.eval_location(self.pymodule, self.offset)) - - def get_changes(self, new_parameter): - definition_info = functionutils.DefinitionInfo.read(self.pyfunction) - definition_info.args_with_defaults.append((new_parameter, - self._get_primary())) - collector = codeanalyze.ChangeCollector(self.resource.read()) - header_start, header_end = self._get_header_offsets() - body_start, body_end = sourceutils.get_body_region(self.pyfunction) - collector.add_change(header_start, header_end, - definition_info.to_string()) - self._change_function_occurances(collector, body_start, - body_end, new_parameter) - changes = rope.base.change.ChangeSet('Introduce parameter <%s>' % - new_parameter) - change = rope.base.change.ChangeContents(self.resource, - collector.get_changed()) - changes.add_change(change) - return changes - - def _get_header_offsets(self): - lines = self.pymodule.lines - start_line = self.pyfunction.get_scope().get_start() - end_line = self.pymodule.logical_lines.\ - logical_line_in(start_line)[1] - start = lines.get_line_start(start_line) - end = lines.get_line_end(end_line) - start = self.pymodule.source_code.find('def', start) + 4 - end = self.pymodule.source_code.rfind(':', start, end) - return start, end - - def _change_function_occurances(self, collector, function_start, - function_end, new_name): - finder = occurrences.create_finder(self.pycore, self.name, self.pyname) - for occurrence in finder.find_occurrences(resource=self.resource): - start, end = occurrence.get_primary_range() - if function_start <= start < function_end: - collector.add_change(start, end, new_name) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/localtofield.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/localtofield.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -from rope.base import pynames, evaluate, exceptions, worder -from rope.refactor.rename import Rename - - -class LocalToField(object): - - def __init__(self, project, resource, offset): - self.project = project - self.pycore = project.pycore - self.resource = resource - self.offset = offset - - def get_changes(self): - name = worder.get_name_at(self.resource, self.offset) - this_pymodule = self.pycore.resource_to_pyobject(self.resource) - pyname = evaluate.eval_location(this_pymodule, self.offset) - if not self._is_a_method_local(pyname): - raise exceptions.RefactoringError( - 'Convert local variable to field should be performed on \n' - 'a local variable of a method.') - - pymodule, lineno = pyname.get_definition_location() - function_scope = pymodule.get_scope().get_inner_scope_for_line(lineno) - # Not checking redefinition - #self._check_redefinition(name, function_scope) - - new_name = self._get_field_name(function_scope.pyobject, name) - changes = Rename(self.project, self.resource, self.offset).\ - get_changes(new_name, resources=[self.resource]) - return changes - - def _check_redefinition(self, name, function_scope): - class_scope = function_scope.parent - if name in class_scope.pyobject: - raise exceptions.RefactoringError( - 'The field %s already exists' % name) - - def _get_field_name(self, pyfunction, name): - self_name = pyfunction.get_param_names()[0] - new_name = self_name + '.' + name - return new_name - - def _is_a_method_local(self, pyname): - pymodule, lineno = pyname.get_definition_location() - holding_scope = pymodule.get_scope().get_inner_scope_for_line(lineno) - parent = holding_scope.parent - return isinstance(pyname, pynames.AssignedName) and \ - pyname in holding_scope.get_names().values() and \ - holding_scope.get_kind() == 'Function' and \ - parent is not None and parent.get_kind() == 'Class' diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/method_object.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/method_object.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -import warnings - -from rope.base import pyobjects, exceptions, change, evaluate, codeanalyze -from rope.refactor import sourceutils, occurrences, rename - - -class MethodObject(object): - - def __init__(self, project, resource, offset): - self.pycore = project.pycore - this_pymodule = self.pycore.resource_to_pyobject(resource) - pyname = evaluate.eval_location(this_pymodule, offset) - if pyname is None or not isinstance(pyname.get_object(), - pyobjects.PyFunction): - raise exceptions.RefactoringError( - 'Replace method with method object refactoring should be ' - 'performed on a function.') - self.pyfunction = pyname.get_object() - self.pymodule = self.pyfunction.get_module() - self.resource = self.pymodule.get_resource() - - def get_new_class(self, name): - body = sourceutils.fix_indentation( - self._get_body(), sourceutils.get_indent(self.pycore) * 2) - return 'class %s(object):\n\n%s%sdef __call__(self):\n%s' % \ - (name, self._get_init(), - ' ' * sourceutils.get_indent(self.pycore), body) - - def get_changes(self, classname=None, new_class_name=None): - if new_class_name is not None: - warnings.warn( - 'new_class_name parameter is deprecated; use classname', - DeprecationWarning, stacklevel=2) - classname = new_class_name - collector = codeanalyze.ChangeCollector(self.pymodule.source_code) - start, end = sourceutils.get_body_region(self.pyfunction) - indents = sourceutils.get_indents( - self.pymodule.lines, self.pyfunction.get_scope().get_start()) + \ - sourceutils.get_indent(self.pycore) - new_contents = ' ' * indents + 'return %s(%s)()\n' % \ - (classname, ', '.join(self._get_parameter_names())) - collector.add_change(start, end, new_contents) - insertion = self._get_class_insertion_point() - collector.add_change(insertion, insertion, - '\n\n' + self.get_new_class(classname)) - changes = change.ChangeSet('Replace method with method object refactoring') - changes.add_change(change.ChangeContents(self.resource, - collector.get_changed())) - return changes - - def _get_class_insertion_point(self): - current = self.pyfunction - while current.parent != self.pymodule: - current = current.parent - end = self.pymodule.lines.get_line_end(current.get_scope().get_end()) - return min(end + 1, len(self.pymodule.source_code)) - - def _get_body(self): - body = sourceutils.get_body(self.pyfunction) - for param in self._get_parameter_names(): - body = param + ' = None\n' + body - pymod = self.pycore.get_string_module(body, self.resource) - pyname = pymod[param] - finder = occurrences.create_finder(self.pycore, param, pyname) - result = rename.rename_in_module(finder, 'self.' + param, - pymodule=pymod) - body = result[result.index('\n') + 1:] - return body - - def _get_init(self): - params = self._get_parameter_names() - indents = ' ' * sourceutils.get_indent(self.pycore) - if not params: - return '' - header = indents + 'def __init__(self' - body = '' - for arg in params: - new_name = arg - if arg == 'self': - new_name = 'host' - header += ', %s' % new_name - body += indents * 2 + 'self.%s = %s\n' % (arg, new_name) - header += '):' - return '%s\n%s\n' % (header, body) - - def _get_parameter_names(self): - return self.pyfunction.get_param_names() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/move.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/move.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,625 +0,0 @@ -"""A module containing classes for move refactoring - -`create_move()` is a factory for creating move refactoring objects -based on inputs. - -""" -from rope.base import pyobjects, codeanalyze, exceptions, pynames, taskhandle, evaluate, worder -from rope.base.change import ChangeSet, ChangeContents, MoveResource -from rope.refactor import importutils, rename, occurrences, sourceutils, functionutils - - -def create_move(project, resource, offset=None): - """A factory for creating Move objects - - Based on `resource` and `offset`, return one of `MoveModule`, - `MoveGlobal` or `MoveMethod` for performing move refactoring. - - """ - if offset is None: - return MoveModule(project, resource) - this_pymodule = project.pycore.resource_to_pyobject(resource) - pyname = evaluate.eval_location(this_pymodule, offset) - if pyname is None: - raise exceptions.RefactoringError( - 'Move only works on classes, functions, modules and methods.') - pyobject = pyname.get_object() - if isinstance(pyobject, pyobjects.PyModule) or \ - isinstance(pyobject, pyobjects.PyPackage): - return MoveModule(project, pyobject.get_resource()) - if isinstance(pyobject, pyobjects.PyFunction) and \ - isinstance(pyobject.parent, pyobjects.PyClass): - return MoveMethod(project, resource, offset) - if isinstance(pyobject, pyobjects.PyDefinedObject) and \ - isinstance(pyobject.parent, pyobjects.PyModule): - return MoveGlobal(project, resource, offset) - raise exceptions.RefactoringError( - 'Move only works on global classes/functions, modules and methods.') - - -class MoveMethod(object): - """For moving methods - - It makes a new method in the destination class and changes - the body of the old method to call the new method. You can - inline the old method to change all of its occurrences. - - """ - - def __init__(self, project, resource, offset): - self.project = project - self.pycore = project.pycore - this_pymodule = self.pycore.resource_to_pyobject(resource) - pyname = evaluate.eval_location(this_pymodule, offset) - self.method_name = worder.get_name_at(resource, offset) - self.pyfunction = pyname.get_object() - if self.pyfunction.get_kind() != 'method': - raise exceptions.RefactoringError('Only normal methods' - ' can be moved.') - - def get_changes(self, dest_attr, new_name=None, resources=None, - task_handle=taskhandle.NullTaskHandle()): - """Return the changes needed for this refactoring - - Parameters: - - - `dest_attr`: the name of the destination attribute - - `new_name`: the name of the new method; if `None` uses - the old name - - `resources` can be a list of `rope.base.resources.File`\s to - apply this refactoring on. If `None`, the restructuring - will be applied to all python files. - - """ - changes = ChangeSet('Moving method <%s>' % self.method_name) - if resources is None: - resources = self.pycore.get_python_files() - if new_name is None: - new_name = self.get_method_name() - resource1, start1, end1, new_content1 = \ - self._get_changes_made_by_old_class(dest_attr, new_name) - collector1 = codeanalyze.ChangeCollector(resource1.read()) - collector1.add_change(start1, end1, new_content1) - - resource2, start2, end2, new_content2 = \ - self._get_changes_made_by_new_class(dest_attr, new_name) - if resource1 == resource2: - collector1.add_change(start2, end2, new_content2) - else: - collector2 = codeanalyze.ChangeCollector(resource2.read()) - collector2.add_change(start2, end2, new_content2) - result = collector2.get_changed() - import_tools = importutils.ImportTools(self.pycore) - new_imports = self._get_used_imports(import_tools) - if new_imports: - goal_pymodule = self.pycore.get_string_module(result, - resource2) - result = _add_imports_to_module( - import_tools, goal_pymodule, new_imports) - if resource2 in resources: - changes.add_change(ChangeContents(resource2, result)) - - if resource1 in resources: - changes.add_change(ChangeContents(resource1, - collector1.get_changed())) - return changes - - def get_method_name(self): - return self.method_name - - def _get_used_imports(self, import_tools): - return importutils.get_imports(self.pycore, self.pyfunction) - - def _get_changes_made_by_old_class(self, dest_attr, new_name): - pymodule = self.pyfunction.get_module() - indents = self._get_scope_indents(self.pyfunction) - body = 'return self.%s.%s(%s)\n' % (dest_attr, new_name, - self._get_passed_arguments_string()) - region = sourceutils.get_body_region(self.pyfunction) - return (pymodule.get_resource(), region[0], region[1], - sourceutils.fix_indentation(body, indents)) - - def _get_scope_indents(self, pyobject): - pymodule = pyobject.get_module() - return sourceutils.get_indents( - pymodule.lines, pyobject.get_scope().get_start()) + \ - sourceutils.get_indent(self.pycore) - - def _get_changes_made_by_new_class(self, dest_attr, new_name): - old_pyclass = self.pyfunction.parent - if dest_attr not in old_pyclass: - raise exceptions.RefactoringError( - 'Destination attribute <%s> not found' % dest_attr) - pyclass = old_pyclass[dest_attr].get_object().get_type() - if not isinstance(pyclass, pyobjects.PyClass): - raise exceptions.RefactoringError( - 'Unknown class type for attribute <%s>' % dest_attr) - pymodule = pyclass.get_module() - resource = pyclass.get_module().get_resource() - start, end = sourceutils.get_body_region(pyclass) - pre_blanks = '\n' - if pymodule.source_code[start:end].strip() != 'pass': - pre_blanks = '\n\n' - start = end - indents = self._get_scope_indents(pyclass) - body = pre_blanks + sourceutils.fix_indentation( - self.get_new_method(new_name), indents) - return resource, start, end, body - - def get_new_method(self, name): - return '%s\n%s' % ( - self._get_new_header(name), - sourceutils.fix_indentation(self._get_body(), - sourceutils.get_indent(self.pycore))) - - def _get_unchanged_body(self): - return sourceutils.get_body(self.pyfunction) - - def _get_body(self, host='host'): - self_name = self._get_self_name() - body = self_name + ' = None\n' + self._get_unchanged_body() - pymodule = self.pycore.get_string_module(body) - finder = occurrences.create_finder( - self.pycore, self_name, pymodule[self_name]) - result = rename.rename_in_module(finder, host, pymodule=pymodule) - if result is None: - result = body - return result[result.index('\n') + 1:] - - def _get_self_name(self): - return self.pyfunction.get_param_names()[0] - - def _get_new_header(self, name): - header = 'def %s(self' % name - if self._is_host_used(): - header += ', host' - definition_info = functionutils.DefinitionInfo.read(self.pyfunction) - others = definition_info.arguments_to_string(1) - if others: - header += ', ' + others - return header + '):' - - def _get_passed_arguments_string(self): - result = '' - if self._is_host_used(): - result = 'self' - definition_info = functionutils.DefinitionInfo.read(self.pyfunction) - others = definition_info.arguments_to_string(1) - if others: - if result: - result += ', ' - result += others - return result - - def _is_host_used(self): - return self._get_body('__old_self') != self._get_unchanged_body() - - -class MoveGlobal(object): - """For moving global function and classes""" - - def __init__(self, project, resource, offset): - self.pycore = project.pycore - this_pymodule = self.pycore.resource_to_pyobject(resource) - self.old_pyname = evaluate.eval_location(this_pymodule, offset) - self.old_name = self.old_pyname.get_object().get_name() - pymodule = self.old_pyname.get_object().get_module() - self.source = pymodule.get_resource() - self.tools = _MoveTools(self.pycore, self.source, - self.old_pyname, self.old_name) - self.import_tools = self.tools.import_tools - self._check_exceptional_conditions() - - def _check_exceptional_conditions(self): - if self.old_pyname is None or \ - not isinstance(self.old_pyname.get_object(), pyobjects.PyDefinedObject): - raise exceptions.RefactoringError( - 'Move refactoring should be performed on a class/function.') - moving_pyobject = self.old_pyname.get_object() - if not self._is_global(moving_pyobject): - raise exceptions.RefactoringError( - 'Move refactoring should be performed on a global class/function.') - - def _is_global(self, pyobject): - return pyobject.get_scope().parent == pyobject.get_module().get_scope() - - def get_changes(self, dest, resources=None, - task_handle=taskhandle.NullTaskHandle()): - if resources is None: - resources = self.pycore.get_python_files() - if dest is None or not dest.exists(): - raise exceptions.RefactoringError( - 'Move destination does not exist.') - if dest.is_folder() and dest.has_child('__init__.py'): - dest = dest.get_child('__init__.py') - if dest.is_folder(): - raise exceptions.RefactoringError( - 'Move destination for non-modules should not be folders.') - if self.source == dest: - raise exceptions.RefactoringError( - 'Moving global elements to the same module.') - return self._calculate_changes(dest, resources, task_handle) - - def _calculate_changes(self, dest, resources, task_handle): - changes = ChangeSet('Moving global <%s>' % self.old_name) - job_set = task_handle.create_jobset('Collecting Changes', - len(resources)) - for file_ in resources: - job_set.started_job(file_.path) - if file_ == self.source: - changes.add_change(self._source_module_changes(dest)) - elif file_ == dest: - changes.add_change(self._dest_module_changes(dest)) - elif self.tools.occurs_in_module(resource=file_): - pymodule = self.pycore.resource_to_pyobject(file_) - # Changing occurrences - placeholder = '__rope_renaming_%s_' % self.old_name - source = self.tools.rename_in_module(placeholder, - resource=file_) - should_import = source is not None - # Removing out of date imports - pymodule = self.tools.new_pymodule(pymodule, source) - source = self.tools.remove_old_imports(pymodule) - # Adding new import - if should_import: - pymodule = self.tools.new_pymodule(pymodule, source) - source, imported = importutils.add_import( - self.pycore, pymodule, self._new_modname(dest), self.old_name) - source = source.replace(placeholder, imported) - source = self.tools.new_source(pymodule, source) - if source != file_.read(): - changes.add_change(ChangeContents(file_, source)) - job_set.finished_job() - return changes - - def _source_module_changes(self, dest): - placeholder = '__rope_moving_%s_' % self.old_name - handle = _ChangeMoveOccurrencesHandle(placeholder) - occurrence_finder = occurrences.create_finder( - self.pycore, self.old_name, self.old_pyname) - start, end = self._get_moving_region() - renamer = ModuleSkipRenamer(occurrence_finder, self.source, - handle, start, end) - source = renamer.get_changed_module() - if handle.occurred: - pymodule = self.pycore.get_string_module(source, self.source) - # Adding new import - source, imported = importutils.add_import( - self.pycore, pymodule, self._new_modname(dest), self.old_name) - source = source.replace(placeholder, imported) - return ChangeContents(self.source, source) - - def _new_modname(self, dest): - return self.pycore.modname(dest) - - def _dest_module_changes(self, dest): - # Changing occurrences - pymodule = self.pycore.resource_to_pyobject(dest) - source = self.tools.rename_in_module(self.old_name, pymodule) - pymodule = self.tools.new_pymodule(pymodule, source) - - moving, imports = self._get_moving_element_with_imports() - source = self.tools.remove_old_imports(pymodule) - pymodule = self.tools.new_pymodule(pymodule, source) - pymodule, has_changed = self._add_imports2(pymodule, imports) - - module_with_imports = self.import_tools.module_imports(pymodule) - source = pymodule.source_code - if module_with_imports.imports: - start = pymodule.lines.get_line_end( - module_with_imports.imports[-1].end_line - 1) - result = source[:start + 1] + '\n\n' - else: - result = '' - start = -1 - result += moving + source[start + 1:] - - # Organizing imports - source = result - pymodule = self.pycore.get_string_module(source, dest) - source = self.import_tools.organize_imports(pymodule, sort=False, - unused=False) - return ChangeContents(dest, source) - - def _get_moving_element_with_imports(self): - return moving_code_with_imports( - self.pycore, self.source, self._get_moving_element()) - - def _get_module_with_imports(self, source_code, resource): - pymodule = self.pycore.get_string_module(source_code, resource) - return self.import_tools.module_imports(pymodule) - - def _get_moving_element(self): - start, end = self._get_moving_region() - moving = self.source.read()[start:end] - return moving.rstrip() + '\n' - - def _get_moving_region(self): - pymodule = self.pycore.resource_to_pyobject(self.source) - lines = pymodule.lines - scope = self.old_pyname.get_object().get_scope() - start = lines.get_line_start(scope.get_start()) - end_line = scope.get_end() - while end_line < lines.length() and \ - lines.get_line(end_line + 1).strip() == '': - end_line += 1 - end = min(lines.get_line_end(end_line) + 1, len(pymodule.source_code)) - return start, end - - def _add_imports2(self, pymodule, new_imports): - source = self.tools.add_imports(pymodule, new_imports) - if source is None: - return pymodule, False - else: - resource = pymodule.get_resource() - pymodule = self.pycore.get_string_module(source, resource) - return pymodule, True - - -class MoveModule(object): - """For moving modules and packages""" - - def __init__(self, project, resource): - self.project = project - self.pycore = project.pycore - if not resource.is_folder() and resource.name == '__init__.py': - resource = resource.parent - if resource.is_folder() and not resource.has_child('__init__.py'): - raise exceptions.RefactoringError( - 'Cannot move non-package folder.') - dummy_pymodule = self.pycore.get_string_module('') - self.old_pyname = pynames.ImportedModule(dummy_pymodule, - resource=resource) - self.source = self.old_pyname.get_object().get_resource() - if self.source.is_folder(): - self.old_name = self.source.name - else: - self.old_name = self.source.name[:-3] - self.tools = _MoveTools(self.pycore, self.source, - self.old_pyname, self.old_name) - self.import_tools = self.tools.import_tools - - def get_changes(self, dest, resources=None, - task_handle=taskhandle.NullTaskHandle()): - moving_pyobject = self.old_pyname.get_object() - if resources is None: - resources = self.pycore.get_python_files() - if dest is None or not dest.is_folder(): - raise exceptions.RefactoringError( - 'Move destination for modules should be packages.') - return self._calculate_changes(dest, resources, task_handle) - - def _calculate_changes(self, dest, resources, task_handle): - changes = ChangeSet('Moving module <%s>' % self.old_name) - job_set = task_handle.create_jobset('Collecting changes', - len(resources)) - for module in resources: - job_set.started_job(module.path) - if module == self.source: - self._change_moving_module(changes, dest) - else: - source = self._change_occurrences_in_module(dest, - resource=module) - if source is not None: - changes.add_change(ChangeContents(module, source)) - job_set.finished_job() - if self.project == self.source.project: - changes.add_change(MoveResource(self.source, dest.path)) - return changes - - def _new_modname(self, dest): - destname = self.pycore.modname(dest) - if destname: - return destname + '.' + self.old_name - return self.old_name - - def _new_import(self, dest): - return importutils.NormalImport([(self._new_modname(dest), None)]) - - def _change_moving_module(self, changes, dest): - if not self.source.is_folder(): - pymodule = self.pycore.resource_to_pyobject(self.source) - source = self.import_tools.relatives_to_absolutes(pymodule) - pymodule = self.tools.new_pymodule(pymodule, source) - source = self._change_occurrences_in_module(dest, pymodule) - source = self.tools.new_source(pymodule, source) - if source != self.source.read(): - changes.add_change(ChangeContents(self.source, source)) - - def _change_occurrences_in_module(self, dest, pymodule=None, - resource=None): - if not self.tools.occurs_in_module(pymodule=pymodule, - resource=resource): - return - if pymodule is None: - pymodule = self.pycore.resource_to_pyobject(resource) - new_name = self._new_modname(dest) - new_import = self._new_import(dest) - source = self.tools.rename_in_module( - new_name, imports=True, pymodule=pymodule, resource=resource) - should_import = self.tools.occurs_in_module( - pymodule=pymodule, resource=resource, imports=False) - pymodule = self.tools.new_pymodule(pymodule, source) - source = self.tools.remove_old_imports(pymodule) - if should_import: - pymodule = self.tools.new_pymodule(pymodule, source) - source = self.tools.add_imports(pymodule, [new_import]) - source = self.tools.new_source(pymodule, source) - if source != pymodule.resource.read(): - return source - - -class _ChangeMoveOccurrencesHandle(object): - - def __init__(self, new_name): - self.new_name = new_name - self.occurred = False - - def occurred_inside_skip(self, change_collector, occurrence): - pass - - def occurred_outside_skip(self, change_collector, occurrence): - start, end = occurrence.get_primary_range() - change_collector.add_change(start, end, self.new_name) - self.occurred = True - - -class _MoveTools(object): - - def __init__(self, pycore, source, pyname, old_name): - self.pycore = pycore - self.source = source - self.old_pyname = pyname - self.old_name = old_name - self.import_tools = importutils.ImportTools(self.pycore) - - def remove_old_imports(self, pymodule): - old_source = pymodule.source_code - module_with_imports = self.import_tools.module_imports(pymodule) - class CanSelect(object): - changed = False - old_name = self.old_name - old_pyname = self.old_pyname - def __call__(self, name): - try: - if name == self.old_name and \ - pymodule[name].get_object() == \ - self.old_pyname.get_object(): - self.changed = True - return False - except exceptions.AttributeNotFoundError: - pass - return True - can_select = CanSelect() - module_with_imports.filter_names(can_select) - new_source = module_with_imports.get_changed_source() - if old_source != new_source: - return new_source - - def rename_in_module(self, new_name, pymodule=None, - imports=False, resource=None): - occurrence_finder = self._create_finder(imports) - source = rename.rename_in_module( - occurrence_finder, new_name, replace_primary=True, - pymodule=pymodule, resource=resource) - return source - - def occurs_in_module(self, pymodule=None, resource=None, imports=True): - finder = self._create_finder(imports) - for occurrence in finder.find_occurrences(pymodule=pymodule, - resource=resource): - return True - return False - - def _create_finder(self, imports): - return occurrences.create_finder(self.pycore, self.old_name, - self.old_pyname, imports=imports) - - def new_pymodule(self, pymodule, source): - if source is not None: - return self.pycore.get_string_module( - source, pymodule.get_resource()) - return pymodule - - def new_source(self, pymodule, source): - if source is None: - return pymodule.source_code - return source - - def add_imports(self, pymodule, new_imports): - return _add_imports_to_module(self.import_tools, pymodule, new_imports) - - -def _add_imports_to_module(import_tools, pymodule, new_imports): - module_with_imports = import_tools.module_imports(pymodule) - for new_import in new_imports: - module_with_imports.add_import(new_import) - return module_with_imports.get_changed_source() - - -def moving_code_with_imports(pycore, resource, source): - import_tools = importutils.ImportTools(pycore) - pymodule = pycore.get_string_module(source, resource) - origin = pycore.resource_to_pyobject(resource) - - imports = [] - for stmt in import_tools.module_imports(origin).imports: - imports.append(stmt.import_info) - - back_names = [] - for name in origin: - if name not in pymodule: - back_names.append(name) - imports.append(import_tools.get_from_import(resource, back_names)) - - source = _add_imports_to_module(import_tools, pymodule, imports) - pymodule = pycore.get_string_module(source, resource) - - source = import_tools.relatives_to_absolutes(pymodule) - pymodule = pycore.get_string_module(source, resource) - source = import_tools.organize_imports(pymodule, selfs=False) - pymodule = pycore.get_string_module(source, resource) - - # extracting imports after changes - module_imports = import_tools.module_imports(pymodule) - imports = [import_stmt.import_info - for import_stmt in module_imports.imports] - start = 1 - if module_imports.imports: - start = module_imports.imports[-1].end_line - lines = codeanalyze.SourceLinesAdapter(source) - while start < lines.length() and not lines.get_line(start).strip(): - start += 1 - moving = source[lines.get_line_start(start):] - return moving, imports - - -class ModuleSkipRenamerHandle(object): - - def occurred_outside_skip(self, change_collector, occurrence): - pass - - def occurred_inside_skip(self, change_collector, occurrence): - pass - - -class ModuleSkipRenamer(object): - """Rename occurrences in a module - - This class can be used when you want to treat a region in a file - separately from other parts when renaming. - - """ - - def __init__(self, occurrence_finder, resource, handle=None, - skip_start=0, skip_end=0, replacement=''): - """Constructor - - if replacement is `None` the region is not changed. Otherwise - it is replaced with `replacement`. - - """ - self.occurrence_finder = occurrence_finder - self.resource = resource - self.skip_start = skip_start - self.skip_end = skip_end - self.replacement = replacement - self.handle = handle - if self.handle is None: - self.handle = ModuleSkipHandle() - - def get_changed_module(self): - source = self.resource.read() - change_collector = codeanalyze.ChangeCollector(source) - if self.replacement is not None: - change_collector.add_change(self.skip_start, self.skip_end, - self.replacement) - for occurrence in self.occurrence_finder.find_occurrences(self.resource): - start, end = occurrence.get_primary_range() - if self.skip_start <= start < self.skip_end: - self.handle.occurred_inside_skip(change_collector, occurrence) - else: - self.handle.occurred_outside_skip(change_collector, occurrence) - result = change_collector.get_changed() - if result is not None and result != source: - return result diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/multiproject.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/multiproject.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -"""This module can be used for performing cross-project refactorings - -See the "cross-project refactorings" section of ``docs/library.txt`` -file. - -""" - -from rope.base import resources, project, libutils - - -class MultiProjectRefactoring(object): - - def __init__(self, refactoring, projects, addpath=True): - """Create a multiproject proxy for the main refactoring - - `projects` are other project. - - """ - self.refactoring = refactoring - self.projects = projects - self.addpath = addpath - - def __call__(self, project, *args, **kwds): - """Create the refactoring""" - return _MultiRefactoring(self.refactoring, self.projects, - self.addpath, project, *args, **kwds) - - -class _MultiRefactoring(object): - - def __init__(self, refactoring, other_projects, addpath, - project, *args, **kwds): - self.refactoring = refactoring - self.projects = [project] + other_projects - for other_project in other_projects: - for folder in self.project.pycore.get_source_folders(): - other_project.get_prefs().add('python_path', folder.real_path) - self.refactorings = [] - for other in self.projects: - args, kwds = self._resources_for_args(other, args, kwds) - self.refactorings.append( - self.refactoring(other, *args, **kwds)) - - def get_all_changes(self, *args, **kwds): - """Get a project to changes dict""" - result = [] - for project, refactoring in zip(self.projects, self.refactorings): - args, kwds = self._resources_for_args(project, args, kwds) - result.append((project, refactoring.get_changes(*args, **kwds))) - return result - - def __getattr__(self, name): - return getattr(self.main_refactoring, name) - - def _resources_for_args(self, project, args, kwds): - newargs = [self._change_project_resource(project, arg) for arg in args] - newkwds = dict((name, self._change_project_resource(project, value)) - for name, value in kwds.items()) - return newargs, newkwds - - def _change_project_resource(self, project, obj): - if isinstance(obj, resources.Resource) and \ - obj.project != project: - return libutils.path_to_resource(project, obj.real_path) - return obj - - @property - def project(self): - return self.projects[0] - - @property - def main_refactoring(self): - return self.refactorings[0] - - -def perform(project_changes): - for project, changes in project_changes: - project.do(changes) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/occurrences.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/occurrences.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,334 +0,0 @@ -import re - -import rope.base.pynames -from rope.base import pynames, pyobjects, codeanalyze, evaluate, exceptions, utils, worder - - -class Finder(object): - """For finding occurrences of a name - - The constructor takes a `filters` argument. It should be a list - of functions that take a single argument. For each possible - occurrence, these functions are called in order with the an - instance of `Occurrence`: - - * If it returns `None` other filters are tried. - * If it returns `True`, the occurrence will be a match. - * If it returns `False`, the occurrence will be skipped. - * If all of the filters return `None`, it is skipped also. - - """ - - def __init__(self, pycore, name, filters=[lambda o: True], docs=False): - self.pycore = pycore - self.name = name - self.docs = docs - self.filters = filters - self._textual_finder = _TextualFinder(name, docs=docs) - - def find_occurrences(self, resource=None, pymodule=None): - """Generate `Occurrence` instances""" - tools = _OccurrenceToolsCreator(self.pycore, resource=resource, - pymodule=pymodule, docs=self.docs) - for offset in self._textual_finder.find_offsets(tools.source_code): - occurrence = Occurrence(tools, offset) - for filter in self.filters: - result = filter(occurrence) - if result is None: - continue - if result: - yield occurrence - break - - -def create_finder(pycore, name, pyname, only_calls=False, imports=True, - unsure=None, docs=False, instance=None, in_hierarchy=False): - """A factory for `Finder` - - Based on the arguments it creates a list of filters. `instance` - argument is needed only when you want implicit interfaces to be - considered. - - """ - pynames = set([pyname]) - filters = [] - if only_calls: - filters.append(CallsFilter()) - if not imports: - filters.append(NoImportsFilter()) - if isinstance(instance, rope.base.pynames.ParameterName): - for pyobject in instance.get_objects(): - try: - pynames.add(pyobject[name]) - except exceptions.AttributeNotFoundError: - pass - for pyname in pynames: - filters.append(PyNameFilter(pyname)) - if in_hierarchy: - filters.append(InHierarchyFilter(pyname)) - if unsure: - filters.append(UnsureFilter(unsure)) - return Finder(pycore, name, filters=filters, docs=docs) - - -class Occurrence(object): - - def __init__(self, tools, offset): - self.tools = tools - self.offset = offset - self.resource = tools.resource - - @utils.saveit - def get_word_range(self): - return self.tools.word_finder.get_word_range(self.offset) - - @utils.saveit - def get_primary_range(self): - return self.tools.word_finder.get_primary_range(self.offset) - - @utils.saveit - def get_pyname(self): - try: - return self.tools.name_finder.get_pyname_at(self.offset) - except exceptions.BadIdentifierError: - pass - - @utils.saveit - def get_primary_and_pyname(self): - try: - return self.tools.name_finder.get_primary_and_pyname_at(self.offset) - except exceptions.BadIdentifierError: - pass - - @utils.saveit - def is_in_import_statement(self): - return (self.tools.word_finder.is_from_statement(self.offset) or - self.tools.word_finder.is_import_statement(self.offset)) - - def is_called(self): - return self.tools.word_finder.is_a_function_being_called(self.offset) - - def is_defined(self): - return self.tools.word_finder.is_a_class_or_function_name_in_header(self.offset) - - def is_a_fixed_primary(self): - return self.tools.word_finder.is_a_class_or_function_name_in_header(self.offset) or \ - self.tools.word_finder.is_a_name_after_from_import(self.offset) - - def is_written(self): - return self.tools.word_finder.is_assigned_here(self.offset) - - def is_unsure(self): - return unsure_pyname(self.get_pyname()) - - @property - @utils.saveit - def lineno(self): - offset = self.get_word_range()[0] - return self.tools.pymodule.lines.get_line_number(offset) - - -def same_pyname(expected, pyname): - """Check whether `expected` and `pyname` are the same""" - if expected is None or pyname is None: - return False - if expected == pyname: - return True - if type(expected) not in (pynames.ImportedModule, pynames.ImportedName) and \ - type(pyname) not in (pynames.ImportedModule, pynames.ImportedName): - return False - return expected.get_definition_location() == pyname.get_definition_location() and \ - expected.get_object() == pyname.get_object() - -def unsure_pyname(pyname, unbound=True): - """Return `True` if we don't know what this name references""" - if pyname is None: - return True - if unbound and not isinstance(pyname, pynames.UnboundName): - return False - if pyname.get_object() == pyobjects.get_unknown(): - return True - - -class PyNameFilter(object): - """For finding occurrences of a name""" - - def __init__(self, pyname): - self.pyname = pyname - - def __call__(self, occurrence): - if same_pyname(self.pyname, occurrence.get_pyname()): - return True - - -class InHierarchyFilter(object): - """For finding occurrences of a name""" - - def __init__(self, pyname, implementations_only=False): - self.pyname = pyname - self.impl_only = implementations_only - self.pyclass = self._get_containing_class(pyname) - if self.pyclass is not None: - self.name = pyname.get_object().get_name() - self.roots = self._get_root_classes(self.pyclass, self.name) - else: - self.roots = None - - def __call__(self, occurrence): - if self.roots is None: - return - pyclass = self._get_containing_class(occurrence.get_pyname()) - if pyclass is not None: - roots = self._get_root_classes(pyclass, self.name) - if self.roots.intersection(roots): - return True - - def _get_containing_class(self, pyname): - if isinstance(pyname, pynames.DefinedName): - scope = pyname.get_object().get_scope() - parent = scope.parent - if parent is not None and parent.get_kind() == 'Class': - return parent.pyobject - - def _get_root_classes(self, pyclass, name): - if self.impl_only and pyclass == self.pyclass: - return set([pyclass]) - result = set() - for superclass in pyclass.get_superclasses(): - if name in superclass: - result.update(self._get_root_classes(superclass, name)) - if not result: - return set([pyclass]) - return result - - -class UnsureFilter(object): - - def __init__(self, unsure): - self.unsure = unsure - - def __call__(self, occurrence): - if occurrence.is_unsure() and self.unsure(occurrence): - return True - - -class NoImportsFilter(object): - - def __call__(self, occurrence): - if occurrence.is_in_import_statement(): - return False - - -class CallsFilter(object): - - def __call__(self, occurrence): - if not occurrence.is_called(): - return False - - -class _TextualFinder(object): - - def __init__(self, name, docs=False): - self.name = name - self.docs = docs - self.comment_pattern = _TextualFinder.any('comment', [r'#[^\n]*']) - self.string_pattern = _TextualFinder.any( - 'string', [codeanalyze.get_string_pattern()]) - self.pattern = self._get_occurrence_pattern(self.name) - - def find_offsets(self, source): - if not self._fast_file_query(source): - return - if self.docs: - searcher = self._normal_search - else: - searcher = self._re_search - for matched in searcher(source): - yield matched - - def _re_search(self, source): - for match in self.pattern.finditer(source): - for key, value in match.groupdict().items(): - if value and key == 'occurrence': - yield match.start(key) - - def _normal_search(self, source): - current = 0 - while True: - try: - found = source.index(self.name, current) - current = found + len(self.name) - if (found == 0 or not self._is_id_char(source[found - 1])) and \ - (current == len(source) or not self._is_id_char(source[current])): - yield found - except ValueError: - break - - def _is_id_char(self, c): - return c.isalnum() or c == '_' - - def _fast_file_query(self, source): - try: - source.index(self.name) - return True - except ValueError: - return False - - def _get_source(self, resource, pymodule): - if resource is not None: - return resource.read() - else: - return pymodule.source_code - - def _get_occurrence_pattern(self, name): - occurrence_pattern = _TextualFinder.any('occurrence', - ['\\b' + name + '\\b']) - pattern = re.compile(occurrence_pattern + '|' + self.comment_pattern + - '|' + self.string_pattern) - return pattern - - @staticmethod - def any(name, list_): - return '(?P<%s>' % name + '|'.join(list_) + ')' - - -class _OccurrenceToolsCreator(object): - - def __init__(self, pycore, resource=None, pymodule=None, docs=False): - self.pycore = pycore - self.__resource = resource - self.__pymodule = pymodule - self.docs = docs - - @property - @utils.saveit - def name_finder(self): - return evaluate.ScopeNameFinder(self.pymodule) - - @property - @utils.saveit - def source_code(self): - if self.__resource is not None: - return self.resource.read() - else: - return self.pymodule.source_code - - @property - @utils.saveit - def word_finder(self): - return worder.Worder(self.source_code, self.docs) - - @property - @utils.saveit - def resource(self): - if self.__resource is not None: - return self.__resource - if self.__pymodule is not None: - return self.__pymodule.resource - - @property - @utils.saveit - def pymodule(self): - if self.__pymodule is not None: - return self.__pymodule - return self.pycore.resource_to_pyobject(self.resource) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/patchedast.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/patchedast.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,732 +0,0 @@ -import collections -import re -import warnings - -from rope.base import ast, codeanalyze, exceptions - - -def get_patched_ast(source, sorted_children=False): - """Adds ``region`` and ``sorted_children`` fields to nodes - - Adds ``sorted_children`` field only if `sorted_children` is True. - - """ - return patch_ast(ast.parse(source), source, sorted_children) - - -def patch_ast(node, source, sorted_children=False): - """Patches the given node - - After calling, each node in `node` will have a new field named - `region` that is a tuple containing the start and end offsets - of the code that generated it. - - If `sorted_children` is true, a `sorted_children` field will - be created for each node, too. It is a list containing child - nodes as well as whitespaces and comments that occur between - them. - - """ - if hasattr(node, 'region'): - return node - walker = _PatchingASTWalker(source, children=sorted_children) - ast.call_for_nodes(node, walker) - return node - - -def node_region(patched_ast_node): - """Get the region of a patched ast node""" - return patched_ast_node.region - - -def write_ast(patched_ast_node): - """Extract source form a patched AST node with `sorted_children` field - - If the node is patched with sorted_children turned off you can use - `node_region` function for obtaining code using module source code. - """ - result = [] - for child in patched_ast_node.sorted_children: - if isinstance(child, ast.AST): - result.append(write_ast(child)) - else: - result.append(child) - return ''.join(result) - - -class MismatchedTokenError(exceptions.RopeError): - pass - - -class _PatchingASTWalker(object): - - def __init__(self, source, children=False): - self.source = _Source(source) - self.children = children - self.lines = codeanalyze.SourceLinesAdapter(source) - self.children_stack = [] - - Number = object() - String = object() - - def __call__(self, node): - method = getattr(self, '_' + node.__class__.__name__, None) - if method is not None: - return method(node) - # ???: Unknown node; what should we do here? - warnings.warn('Unknown node type <%s>; please report!' - % node.__class__.__name__, RuntimeWarning) - node.region = (self.source.offset, self.source.offset) - if self.children: - node.sorted_children = ast.get_children(node) - - def _handle(self, node, base_children, eat_parens=False, eat_spaces=False): - if hasattr(node, 'region'): - # ???: The same node was seen twice; what should we do? - warnings.warn( - 'Node <%s> has been already patched; please report!' % - node.__class__.__name__, RuntimeWarning) - return - base_children = collections.deque(base_children) - self.children_stack.append(base_children) - children = collections.deque() - formats = [] - suspected_start = self.source.offset - start = suspected_start - first_token = True - while base_children: - child = base_children.popleft() - if child is None: - continue - offset = self.source.offset - if isinstance(child, ast.AST): - ast.call_for_nodes(child, self) - token_start = child.region[0] - else: - if child is self.String: - region = self.source.consume_string( - end=self._find_next_statement_start()) - elif child is self.Number: - region = self.source.consume_number() - elif child == '!=': - # INFO: This has been added to handle deprecated ``<>`` - region = self.source.consume_not_equal() - else: - region = self.source.consume(child) - child = self.source[region[0]:region[1]] - token_start = region[0] - if not first_token: - formats.append(self.source[offset:token_start]) - if self.children: - children.append(self.source[offset:token_start]) - else: - first_token = False - start = token_start - if self.children: - children.append(child) - start = self._handle_parens(children, start, formats) - if eat_parens: - start = self._eat_surrounding_parens( - children, suspected_start, start) - if eat_spaces: - if self.children: - children.appendleft(self.source[0:start]) - end_spaces = self.source[self.source.offset:] - self.source.consume(end_spaces) - if self.children: - children.append(end_spaces) - start = 0 - if self.children: - node.sorted_children = children - node.region = (start, self.source.offset) - self.children_stack.pop() - - def _handle_parens(self, children, start, formats): - """Changes `children` and returns new start""" - opens, closes = self._count_needed_parens(formats) - old_end = self.source.offset - new_end = None - for i in range(closes): - new_end = self.source.consume(')')[1] - if new_end is not None: - if self.children: - children.append(self.source[old_end:new_end]) - new_start = start - for i in range(opens): - new_start = self.source.rfind_token('(', 0, new_start) - if new_start != start: - if self.children: - children.appendleft(self.source[new_start:start]) - start = new_start - return start - - def _eat_surrounding_parens(self, children, suspected_start, start): - index = self.source.rfind_token('(', suspected_start, start) - if index is not None: - old_start = start - old_offset = self.source.offset - start = index - if self.children: - children.appendleft(self.source[start + 1:old_start]) - children.appendleft('(') - token_start, token_end = self.source.consume(')') - if self.children: - children.append(self.source[old_offset:token_start]) - children.append(')') - return start - - def _count_needed_parens(self, children): - start = 0 - opens = 0 - for child in children: - if not isinstance(child, basestring): - continue - if child == '' or child[0] in '\'"': - continue - index = 0 - while index < len(child): - if child[index] == ')': - if opens > 0: - opens -= 1 - else: - start += 1 - if child[index] == '(': - opens += 1 - if child[index] == '#': - try: - index = child.index('\n', index) - except ValueError: - break - index += 1 - return start, opens - - def _find_next_statement_start(self): - for children in reversed(self.children_stack): - for child in children: - if isinstance(child, ast.stmt): - return self.lines.get_line_start(child.lineno) - return len(self.source.source) - - _operators = {'And': 'and', 'Or': 'or', 'Add': '+', 'Sub': '-', 'Mult': '*', - 'Div': '/', 'Mod': '%', 'Pow': '**', 'LShift': '<<', - 'RShift': '>>', 'BitOr': '|', 'BitAnd': '&', 'BitXor': '^', - 'FloorDiv': '//', 'Invert': '~', 'Not': 'not', 'UAdd': '+', - 'USub': '-', 'Eq': '==', 'NotEq': '!=', 'Lt': '<', - 'LtE': '<=', 'Gt': '>', 'GtE': '>=', 'Is': 'is', - 'IsNot': 'is not', 'In': 'in', 'NotIn': 'not in'} - - def _get_op(self, node): - return self._operators[node.__class__.__name__].split(' ') - - def _Attribute(self, node): - self._handle(node, [node.value, '.', node.attr]) - - def _Assert(self, node): - children = ['assert', node.test] - if node.msg: - children.append(',') - children.append(node.msg) - self._handle(node, children) - - def _Assign(self, node): - children = self._child_nodes(node.targets, '=') - children.append('=') - children.append(node.value) - self._handle(node, children) - - def _AugAssign(self, node): - children = [node.target] - children.extend(self._get_op(node.op)) - children.extend(['=', node.value]) - self._handle(node, children) - - def _Repr(self, node): - self._handle(node, ['`', node.value, '`']) - - def _BinOp(self, node): - children = [node.left] + self._get_op(node.op) + [node.right] - self._handle(node, children) - - def _BoolOp(self, node): - self._handle(node, self._child_nodes(node.values, - self._get_op(node.op)[0])) - - def _Break(self, node): - self._handle(node, ['break']) - - def _Call(self, node): - children = [node.func, '('] - args = list(node.args) + node.keywords - children.extend(self._child_nodes(args, ',')) - if node.starargs is not None: - if args: - children.append(',') - children.extend(['*', node.starargs]) - if node.kwargs is not None: - if args or node.starargs is not None: - children.append(',') - children.extend(['**', node.kwargs]) - children.append(')') - self._handle(node, children) - - def _ClassDef(self, node): - children = [] - if getattr(node, 'decorator_list', None): - for decorator in node.decorator_list: - children.append('@') - children.append(decorator) - children.extend(['class', node.name]) - if node.bases: - children.append('(') - children.extend(self._child_nodes(node.bases, ',')) - children.append(')') - children.append(':') - children.extend(node.body) - self._handle(node, children) - - def _Compare(self, node): - children = [] - children.append(node.left) - for op, expr in zip(node.ops, node.comparators): - children.extend(self._get_op(op)) - children.append(expr) - self._handle(node, children) - - def _Delete(self, node): - self._handle(node, ['del'] + self._child_nodes(node.targets, ',')) - - def _Num(self, node): - self._handle(node, [self.Number]) - - def _Str(self, node): - self._handle(node, [self.String]) - - def _Continue(self, node): - self._handle(node, ['continue']) - - def _Dict(self, node): - children = [] - children.append('{') - if node.keys: - for index, (key, value) in enumerate(zip(node.keys, node.values)): - children.extend([key, ':', value]) - if index < len(node.keys) - 1: - children.append(',') - children.append('}') - self._handle(node, children) - - def _Ellipsis(self, node): - self._handle(node, ['...']) - - def _Expr(self, node): - self._handle(node, [node.value]) - - def _Exec(self, node): - children = [] - children.extend(['exec', node.body]) - if node.globals: - children.extend(['in', node.globals]) - if node.locals: - children.extend([',', node.locals]) - self._handle(node, children) - - def _ExtSlice(self, node): - children = [] - for index, dim in enumerate(node.dims): - if index > 0: - children.append(',') - children.append(dim) - self._handle(node, children) - - def _For(self, node): - children = ['for', node.target, 'in', node.iter, ':'] - children.extend(node.body) - if node.orelse: - children.extend(['else', ':']) - children.extend(node.orelse) - self._handle(node, children) - - def _ImportFrom(self, node): - children = ['from'] - if node.level: - children.append('.' * node.level) - children.extend([node.module, 'import']) - children.extend(self._child_nodes(node.names, ',')) - self._handle(node, children) - - def _alias(self, node): - children = [node.name] - if node.asname: - children.extend(['as', node.asname]) - self._handle(node, children) - - def _FunctionDef(self, node): - children = [] - try: - decorators = getattr(node, 'decorator_list') - except AttributeError: - decorators = getattr(node, 'decorators', None) - if decorators: - for decorator in decorators: - children.append('@') - children.append(decorator) - children.extend(['def', node.name, '(', node.args]) - children.extend([')', ':']) - children.extend(node.body) - self._handle(node, children) - - def _arguments(self, node): - children = [] - args = list(node.args) - defaults = [None] * (len(args) - len(node.defaults)) + list(node.defaults) - for index, (arg, default) in enumerate(zip(args, defaults)): - if index > 0: - children.append(',') - self._add_args_to_children(children, arg, default) - if node.vararg is not None: - if args: - children.append(',') - children.extend(['*', node.vararg]) - if node.kwarg is not None: - if args or node.vararg is not None: - children.append(',') - children.extend(['**', node.kwarg]) - self._handle(node, children) - - def _add_args_to_children(self, children, arg, default): - if isinstance(arg, (list, tuple)): - self._add_tuple_parameter(children, arg) - else: - children.append(arg) - if default is not None: - children.append('=') - children.append(default) - - def _add_tuple_parameter(self, children, arg): - children.append('(') - for index, token in enumerate(arg): - if index > 0: - children.append(',') - if isinstance(token, (list, tuple)): - self._add_tuple_parameter(children, token) - else: - children.append(token) - children.append(')') - - def _GeneratorExp(self, node): - children = [node.elt] - children.extend(node.generators) - self._handle(node, children, eat_parens=True) - - def _comprehension(self, node): - children = ['for', node.target, 'in', node.iter] - if node.ifs: - for if_ in node.ifs: - children.append('if') - children.append(if_) - self._handle(node, children) - - def _Global(self, node): - children = self._child_nodes(node.names, ',') - children.insert(0, 'global') - self._handle(node, children) - - def _If(self, node): - if self._is_elif(node): - children = ['elif'] - else: - children = ['if'] - children.extend([node.test, ':']) - children.extend(node.body) - if node.orelse: - if len(node.orelse) == 1 and self._is_elif(node.orelse[0]): - pass - else: - children.extend(['else', ':']) - children.extend(node.orelse) - self._handle(node, children) - - def _is_elif(self, node): - if not isinstance(node, ast.If): - return False - offset = self.lines.get_line_start(node.lineno) + node.col_offset - word = self.source[offset:offset + 4] - # XXX: This is a bug; the offset does not point to the first - alt_word = self.source[offset - 5:offset - 1] - return 'elif' in (word, alt_word) - - def _IfExp(self, node): - return self._handle(node, [node.body, 'if', node.test, - 'else', node.orelse]) - - def _Import(self, node): - children = ['import'] - children.extend(self._child_nodes(node.names, ',')) - self._handle(node, children) - - def _keyword(self, node): - self._handle(node, [node.arg, '=', node.value]) - - def _Lambda(self, node): - self._handle(node, ['lambda', node.args, ':', node.body]) - - def _List(self, node): - self._handle(node, ['['] + self._child_nodes(node.elts, ',') + [']']) - - def _ListComp(self, node): - children = ['[', node.elt] - children.extend(node.generators) - children.append(']') - self._handle(node, children) - - def _Module(self, node): - self._handle(node, list(node.body), eat_spaces=True) - - def _Name(self, node): - self._handle(node, [node.id]) - - def _Pass(self, node): - self._handle(node, ['pass']) - - def _Print(self, node): - children = ['print'] - if node.dest: - children.extend(['>>', node.dest]) - if node.values: - children.append(',') - children.extend(self._child_nodes(node.values, ',')) - if not node.nl: - children.append(',') - self._handle(node, children) - - def _Raise(self, node): - children = ['raise'] - if node.type: - children.append(node.type) - if node.inst: - children.append(',') - children.append(node.inst) - if node.tback: - children.append(',') - children.append(node.tback) - self._handle(node, children) - - def _Return(self, node): - children = ['return'] - if node.value: - children.append(node.value) - self._handle(node, children) - - def _Sliceobj(self, node): - children = [] - for index, slice in enumerate(node.nodes): - if index > 0: - children.append(':') - if slice: - children.append(slice) - self._handle(node, children) - - def _Index(self, node): - self._handle(node, [node.value]) - - def _Subscript(self, node): - self._handle(node, [node.value, '[', node.slice, ']']) - - def _Slice(self, node): - children = [] - if node.lower: - children.append(node.lower) - children.append(':') - if node.upper: - children.append(node.upper) - if node.step: - children.append(':') - children.append(node.step) - self._handle(node, children) - - def _TryFinally(self, node): - children = [] - if len(node.body) != 1 or not isinstance(node.body[0], ast.TryExcept): - children.extend(['try', ':']) - children.extend(node.body) - children.extend(['finally', ':']) - children.extend(node.finalbody) - self._handle(node, children) - - def _TryExcept(self, node): - children = ['try', ':'] - children.extend(node.body) - children.extend(node.handlers) - if node.orelse: - children.extend(['else', ':']) - children.extend(node.orelse) - self._handle(node, children) - - def _ExceptHandler(self, node): - self._excepthandler(node) - - def _excepthandler(self, node): - children = ['except'] - if node.type: - children.append(node.type) - if node.name: - children.extend([',', node.name]) - children.append(':') - children.extend(node.body) - self._handle(node, children) - - def _Tuple(self, node): - if node.elts: - self._handle(node, self._child_nodes(node.elts, ','), - eat_parens=True) - else: - self._handle(node, ['(', ')']) - - def _UnaryOp(self, node): - children = self._get_op(node.op) - children.append(node.operand) - self._handle(node, children) - - def _Yield(self, node): - children = ['yield'] - if node.value: - children.append(node.value) - self._handle(node, children) - - def _While(self, node): - children = ['while', node.test, ':'] - children.extend(node.body) - if node.orelse: - children.extend(['else', ':']) - children.extend(node.orelse) - self._handle(node, children) - - def _With(self, node): - children = ['with', node.context_expr] - if node.optional_vars: - children.extend(['as', node.optional_vars]) - children.append(':') - children.extend(node.body) - self._handle(node, children) - - def _child_nodes(self, nodes, separator): - children = [] - for index, child in enumerate(nodes): - children.append(child) - if index < len(nodes) - 1: - children.append(separator) - return children - - -class _Source(object): - - def __init__(self, source): - self.source = source - self.offset = 0 - - def consume(self, token): - try: - while True: - new_offset = self.source.index(token, self.offset) - if self._good_token(token, new_offset): - break - else: - self._skip_comment() - except (ValueError, TypeError): - raise MismatchedTokenError( - 'Token <%s> at %s cannot be matched' % - (token, self._get_location())) - self.offset = new_offset + len(token) - return (new_offset, self.offset) - - def consume_string(self, end=None): - if _Source._string_pattern is None: - original = codeanalyze.get_string_pattern() - pattern = r'(%s)((\s|\\\n|#[^\n]*\n)*(%s))*' % \ - (original, original) - _Source._string_pattern = re.compile(pattern) - repattern = _Source._string_pattern - return self._consume_pattern(repattern, end) - - def consume_number(self): - if _Source._number_pattern is None: - _Source._number_pattern = re.compile( - self._get_number_pattern()) - repattern = _Source._number_pattern - return self._consume_pattern(repattern) - - def consume_not_equal(self): - if _Source._not_equals_pattern is None: - _Source._not_equals_pattern = re.compile(r'<>|!=') - repattern = _Source._not_equals_pattern - return self._consume_pattern(repattern) - - def _good_token(self, token, offset, start=None): - """Checks whether consumed token is in comments""" - if start is None: - start = self.offset - try: - comment_index = self.source.rindex('#', start, offset) - except ValueError: - return True - try: - new_line_index = self.source.rindex('\n', start, offset) - except ValueError: - return False - return comment_index < new_line_index - - def _skip_comment(self): - self.offset = self.source.index('\n', self.offset + 1) - - def _get_location(self): - lines = self.source[:self.offset].split('\n') - return (len(lines), len(lines[-1])) - - def _consume_pattern(self, repattern, end=None): - while True: - if end is None: - end = len(self.source) - match = repattern.search(self.source, self.offset, end) - if self._good_token(match.group(), match.start()): - break - else: - self._skip_comment() - self.offset = match.end() - return match.start(), match.end() - - def till_token(self, token): - new_offset = self.source.index(token, self.offset) - return self[self.offset:new_offset] - - def rfind_token(self, token, start, end): - index = start - while True: - try: - index = self.source.rindex(token, start, end) - if self._good_token(token, index, start=start): - return index - else: - end = index - except ValueError: - return None - - def from_offset(self, offset): - return self[offset:self.offset] - - def find_backwards(self, pattern, offset): - return self.source.rindex(pattern, 0, offset) - - def __getitem__(self, index): - return self.source[index] - - def __getslice__(self, i, j): - return self.source[i:j] - - def _get_number_pattern(self): - # HACK: It is merely an approaximation and does the job - integer = r'(0|0x)?[\da-fA-F]+[lL]?' - return r'(%s(\.\d*)?|(\.\d+))([eE][-+]?\d*)?[jJ]?' % integer - - _string_pattern = None - _number_pattern = None - _not_equals_pattern = None diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/rename.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/rename.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,216 +0,0 @@ -import warnings - -from rope.base import exceptions, pyobjects, pynames, taskhandle, evaluate, worder, codeanalyze -from rope.base.change import ChangeSet, ChangeContents, MoveResource -from rope.refactor import occurrences, sourceutils - - -class Rename(object): - """A class for performing rename refactoring - - It can rename everything: classes, functions, modules, packages, - methods, variables and keyword arguments. - - """ - - def __init__(self, project, resource, offset=None): - """If `offset` is None, the `resource` itself will be renamed""" - self.project = project - self.pycore = project.pycore - self.resource = resource - if offset is not None: - self.old_name = worder.get_name_at(self.resource, offset) - this_pymodule = self.pycore.resource_to_pyobject(self.resource) - self.old_instance, self.old_pyname = \ - evaluate.eval_location2(this_pymodule, offset) - if self.old_pyname is None: - raise exceptions.RefactoringError( - 'Rename refactoring should be performed' - ' on resolvable python identifiers.') - else: - if not resource.is_folder() and resource.name == '__init__.py': - resource = resource.parent - dummy_pymodule = self.pycore.get_string_module('') - self.old_instance = None - self.old_pyname = pynames.ImportedModule(dummy_pymodule, - resource=resource) - if resource.is_folder(): - self.old_name = resource.name - else: - self.old_name = resource.name[:-3] - - def get_old_name(self): - return self.old_name - - def get_changes(self, new_name, in_file=None, in_hierarchy=False, - unsure=None, docs=False, resources=None, - task_handle=taskhandle.NullTaskHandle()): - """Get the changes needed for this refactoring - - Parameters: - - - `in_hierarchy`: when renaming a method this keyword forces - to rename all matching methods in the hierarchy - - `docs`: when `True` rename refactoring will rename - occurrences in comments and strings where the name is - visible. Setting it will make renames faster, too. - - `unsure`: decides what to do about unsure occurrences. - If `None`, they are ignored. Otherwise `unsure` is - called with an instance of `occurrence.Occurrence` as - parameter. If it returns `True`, the occurrence is - considered to be a match. - - `resources` can be a list of `rope.base.resources.File`\s to - apply this refactoring on. If `None`, the restructuring - will be applied to all python files. - - `in_file`: this argument has been deprecated; use - `resources` instead. - - """ - if unsure in (True, False): - warnings.warn( - 'unsure parameter should be a function that returns ' - 'True or False', DeprecationWarning, stacklevel=2) - def unsure_func(value=unsure): - return value - unsure = unsure_func - if in_file is not None: - warnings.warn( - '`in_file` argument has been deprecated; use `resources` ' - 'instead. ', DeprecationWarning, stacklevel=2) - if in_file: - resources = [self.resource] - if _is_local(self.old_pyname): - resources = [self.resource] - if resources is None: - resources = self.pycore.get_python_files() - changes = ChangeSet('Renaming <%s> to <%s>' % - (self.old_name, new_name)) - finder = occurrences.create_finder( - self.pycore, self.old_name, self.old_pyname, unsure=unsure, - docs=docs, instance=self.old_instance, - in_hierarchy=in_hierarchy and self.is_method()) - job_set = task_handle.create_jobset('Collecting Changes', len(resources)) - for file_ in resources: - job_set.started_job(file_.path) - new_content = rename_in_module(finder, new_name, resource=file_) - if new_content is not None: - changes.add_change(ChangeContents(file_, new_content)) - job_set.finished_job() - if self._is_renaming_a_module(): - resource = self.old_pyname.get_object().get_resource() - if self._is_allowed_to_move(resources, resource): - self._rename_module(resource, new_name, changes) - return changes - - def _is_allowed_to_move(self, resources, resource): - if resource.is_folder(): - try: - return resource.get_child('__init__.py') in resources - except exceptions.ResourceNotFoundError: - return False - else: - return resource in resources - - def _is_renaming_a_module(self): - if isinstance(self.old_pyname.get_object(), pyobjects.AbstractModule): - return True - return False - - def is_method(self): - pyname = self.old_pyname - return isinstance(pyname, pynames.DefinedName) and \ - isinstance(pyname.get_object(), pyobjects.PyFunction) and \ - isinstance(pyname.get_object().parent, pyobjects.PyClass) - - def _rename_module(self, resource, new_name, changes): - if not resource.is_folder(): - new_name = new_name + '.py' - parent_path = resource.parent.path - if parent_path == '': - new_location = new_name - else: - new_location = parent_path + '/' + new_name - changes.add_change(MoveResource(resource, new_location)) - - -class ChangeOccurrences(object): - """A class for changing the occurrences of a name in a scope - - This class replaces the occurrences of a name. Note that it only - changes the scope containing the offset passed to the constructor. - What's more it does not have any side-effects. That is for - example changing occurrences of a module does not rename the - module; it merely replaces the occurrences of that module in a - scope with the given expression. This class is useful for - performing many custom refactorings. - - """ - - def __init__(self, project, resource, offset): - self.pycore = project.pycore - self.resource = resource - self.offset = offset - self.old_name = worder.get_name_at(resource, offset) - self.pymodule = self.pycore.resource_to_pyobject(self.resource) - self.old_pyname = evaluate.eval_location(self.pymodule, offset) - - def get_old_name(self): - word_finder = worder.Worder(self.resource.read()) - return word_finder.get_primary_at(self.offset) - - def _get_scope_offset(self): - lines = self.pymodule.lines - scope = self.pymodule.get_scope().\ - get_inner_scope_for_line(lines.get_line_number(self.offset)) - start = lines.get_line_start(scope.get_start()) - end = lines.get_line_end(scope.get_end()) - return start, end - - def get_changes(self, new_name, only_calls=False, reads=True, writes=True): - changes = ChangeSet('Changing <%s> occurrences to <%s>' % - (self.old_name, new_name)) - scope_start, scope_end = self._get_scope_offset() - finder = occurrences.create_finder( - self.pycore, self.old_name, self.old_pyname, - imports=False, only_calls=only_calls) - new_contents = rename_in_module( - finder, new_name, pymodule=self.pymodule, replace_primary=True, - region=(scope_start, scope_end), reads=reads, writes=writes) - if new_contents is not None: - changes.add_change(ChangeContents(self.resource, new_contents)) - return changes - - -def rename_in_module(occurrences_finder, new_name, resource=None, pymodule=None, - replace_primary=False, region=None, reads=True, writes=True): - """Returns the changed source or `None` if there is no changes""" - if resource is not None: - source_code = resource.read() - else: - source_code = pymodule.source_code - change_collector = codeanalyze.ChangeCollector(source_code) - for occurrence in occurrences_finder.find_occurrences(resource, pymodule): - if replace_primary and occurrence.is_a_fixed_primary(): - continue - if replace_primary: - start, end = occurrence.get_primary_range() - else: - start, end = occurrence.get_word_range() - if (not reads and not occurrence.is_written()) or \ - (not writes and occurrence.is_written()): - continue - if region is None or region[0] <= start < region[1]: - change_collector.add_change(start, end, new_name) - return change_collector.get_changed() - -def _is_local(pyname): - module, lineno = pyname.get_definition_location() - if lineno is None: - return False - scope = module.get_scope().get_inner_scope_for_line(lineno) - if isinstance(pyname, pynames.DefinedName) and \ - scope.get_kind() in ('Function', 'Class'): - scope = scope.parent - return scope.get_kind() == 'Function' and \ - pyname in scope.get_names().values() and \ - isinstance(pyname, pynames.AssignedName) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/restructure.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/restructure.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,307 +0,0 @@ -import warnings - -from rope.base import change, taskhandle, builtins, ast, codeanalyze -from rope.refactor import patchedast, similarfinder, sourceutils -from rope.refactor.importutils import module_imports - - -class Restructure(object): - """A class to perform python restructurings - - A restructuring transforms pieces of code matching `pattern` to - `goal`. In the `pattern` wildcards can appear. Wildcards match - some piece of code based on their kind and arguments that are - passed to them through `args`. - - `args` is a dictionary of wildcard names to wildcard arguments. - If the argument is a tuple, the first item of the tuple is - considered to be the name of the wildcard to use; otherwise the - "default" wildcard is used. For getting the list arguments a - wildcard supports, see the pydoc of the wildcard. (see - `rope.refactor.wildcard.DefaultWildcard` for the default - wildcard.) - - `wildcards` is the list of wildcard types that can appear in - `pattern`. See `rope.refactor.wildcards`. If a wildcard does not - specify its kind (by using a tuple in args), the wildcard named - "default" is used. So there should be a wildcard with "default" - name in `wildcards`. - - `imports` is the list of imports that changed modules should - import. Note that rope handles duplicate imports and does not add - the import if it already appears. - - Example #1:: - - pattern ${pyobject}.get_attribute(${name}) - goal ${pyobject}[${name}] - args pyobject: instance=rope.base.pyobjects.PyObject - - Example #2:: - - pattern ${name} in ${pyobject}.get_attributes() - goal ${name} in {pyobject} - args pyobject: instance=rope.base.pyobjects.PyObject - - Example #3:: - - pattern ${pycore}.create_module(${project}.root, ${name}) - goal generate.create_module(${project}, ${name}) - - imports - from rope.contrib import generate - - args - pycore: type=rope.base.pycore.PyCore - project: type=rope.base.project.Project - - Example #4:: - - pattern ${pow}(${param1}, ${param2}) - goal ${param1} ** ${param2} - args pow: name=mod.pow, exact - - Example #5:: - - pattern ${inst}.longtask(${p1}, ${p2}) - goal - ${inst}.subtask1(${p1}) - ${inst}.subtask2(${p2}) - args - inst: type=mod.A,unsure - - """ - - def __init__(self, project, pattern, goal, args=None, - imports=None, wildcards=None): - """Construct a restructuring - - See class pydoc for more info about the arguments. - - """ - self.pycore = project.pycore - self.pattern = pattern - self.goal = goal - self.args = args - if self.args is None: - self.args = {} - self.imports = imports - if self.imports is None: - self.imports = [] - self.wildcards = wildcards - self.template = similarfinder.CodeTemplate(self.goal) - - def get_changes(self, checks=None, imports=None, resources=None, - task_handle=taskhandle.NullTaskHandle()): - """Get the changes needed by this restructuring - - `resources` can be a list of `rope.base.resources.File`\s to - apply the restructuring on. If `None`, the restructuring will - be applied to all python files. - - `checks` argument has been deprecated. Use the `args` argument - of the constructor. The usage of:: - - strchecks = {'obj1.type': 'mod.A', 'obj2': 'mod.B', - 'obj3.object': 'mod.C'} - checks = restructuring.make_checks(strchecks) - - can be replaced with:: - - args = {'obj1': 'type=mod.A', 'obj2': 'name=mod.B', - 'obj3': 'object=mod.C'} - - where obj1, obj2 and obj3 are wildcard names that appear - in restructuring pattern. - - """ - if checks is not None: - warnings.warn( - 'The use of checks parameter is deprecated; ' - 'use the args parameter of the constructor instead.', - DeprecationWarning, stacklevel=2) - for name, value in checks.items(): - self.args[name] = similarfinder._pydefined_to_str(value) - if imports is not None: - warnings.warn( - 'The use of imports parameter is deprecated; ' - 'use imports parameter of the constructor, instead.', - DeprecationWarning, stacklevel=2) - self.imports = imports - changes = change.ChangeSet('Restructuring <%s> to <%s>' % - (self.pattern, self.goal)) - if resources is not None: - files = [resource for resource in resources - if self.pycore.is_python_file(resource)] - else: - files = self.pycore.get_python_files() - job_set = task_handle.create_jobset('Collecting Changes', len(files)) - for resource in files: - job_set.started_job(resource.path) - pymodule = self.pycore.resource_to_pyobject(resource) - finder = similarfinder.SimilarFinder(pymodule, - wildcards=self.wildcards) - matches = list(finder.get_matches(self.pattern, self.args)) - computer = self._compute_changes(matches, pymodule) - result = computer.get_changed() - if result is not None: - imported_source = self._add_imports(resource, result, - self.imports) - changes.add_change(change.ChangeContents(resource, - imported_source)) - job_set.finished_job() - return changes - - def _compute_changes(self, matches, pymodule): - return _ChangeComputer( - pymodule.source_code, pymodule.get_ast(), - pymodule.lines, self.template, matches) - - def _add_imports(self, resource, source, imports): - if not imports: - return source - import_infos = self._get_import_infos(resource, imports) - pymodule = self.pycore.get_string_module(source, resource) - imports = module_imports.ModuleImports(self.pycore, pymodule) - for import_info in import_infos: - imports.add_import(import_info) - return imports.get_changed_source() - - def _get_import_infos(self, resource, imports): - pymodule = self.pycore.get_string_module('\n'.join(imports), - resource) - imports = module_imports.ModuleImports(self.pycore, pymodule) - return [imports.import_info - for imports in imports.imports] - - def make_checks(self, string_checks): - """Convert str to str dicts to str to PyObject dicts - - This function is here to ease writing a UI. - - """ - checks = {} - for key, value in string_checks.items(): - is_pyname = not key.endswith('.object') and \ - not key.endswith('.type') - evaluated = self._evaluate(value, is_pyname=is_pyname) - if evaluated is not None: - checks[key] = evaluated - return checks - - def _evaluate(self, code, is_pyname=True): - attributes = code.split('.') - pyname = None - if attributes[0] in ('__builtin__', '__builtins__'): - class _BuiltinsStub(object): - def get_attribute(self, name): - return builtins.builtins[name] - pyobject = _BuiltinsStub() - else: - pyobject = self.pycore.get_module(attributes[0]) - for attribute in attributes[1:]: - pyname = pyobject[attribute] - if pyname is None: - return None - pyobject = pyname.get_object() - return pyname if is_pyname else pyobject - - -def replace(code, pattern, goal): - """used by other refactorings""" - finder = similarfinder.RawSimilarFinder(code) - matches = list(finder.get_matches(pattern)) - ast = patchedast.get_patched_ast(code) - lines = codeanalyze.SourceLinesAdapter(code) - template = similarfinder.CodeTemplate(goal) - computer = _ChangeComputer(code, ast, lines, template, matches) - result = computer.get_changed() - if result is None: - return code - return result - - -class _ChangeComputer(object): - - def __init__(self, code, ast, lines, goal, matches): - self.source = code - self.goal = goal - self.matches = matches - self.ast = ast - self.lines = lines - self.matched_asts = {} - self._nearest_roots = {} - if self._is_expression(): - for match in self.matches: - self.matched_asts[match.ast] = match - - def get_changed(self): - if self._is_expression(): - result = self._get_node_text(self.ast) - if result == self.source: - return None - return result - else: - collector = codeanalyze.ChangeCollector(self.source) - last_end = -1 - for match in self.matches: - start, end = match.get_region() - if start < last_end: - if not self._is_expression(): - continue - last_end = end - replacement = self._get_matched_text(match) - collector.add_change(start, end, replacement) - return collector.get_changed() - - def _is_expression(self): - return self.matches and isinstance(self.matches[0], - similarfinder.ExpressionMatch) - - def _get_matched_text(self, match): - mapping = {} - for name in self.goal.get_names(): - node = match.get_ast(name) - if node is None: - raise similarfinder.BadNameInCheckError( - 'Unknown name <%s>' % name) - force = self._is_expression() and match.ast == node - mapping[name] = self._get_node_text(node, force) - unindented = self.goal.substitute(mapping) - return self._auto_indent(match.get_region()[0], unindented) - - def _get_node_text(self, node, force=False): - if not force and node in self.matched_asts: - return self._get_matched_text(self.matched_asts[node]) - start, end = patchedast.node_region(node) - main_text = self.source[start:end] - collector = codeanalyze.ChangeCollector(main_text) - for node in self._get_nearest_roots(node): - sub_start, sub_end = patchedast.node_region(node) - collector.add_change(sub_start - start, sub_end - start, - self._get_node_text(node)) - result = collector.get_changed() - if result is None: - return main_text - return result - - def _auto_indent(self, offset, text): - lineno = self.lines.get_line_number(offset) - indents = sourceutils.get_indents(self.lines, lineno) - result = [] - for index, line in enumerate(text.splitlines(True)): - if index != 0 and line.strip(): - result.append(' ' * indents) - result.append(line) - return ''.join(result) - - def _get_nearest_roots(self, node): - if node not in self._nearest_roots: - result = [] - for child in ast.get_child_nodes(node): - if child in self.matched_asts: - result.append(child) - else: - result.extend(self._get_nearest_roots(child)) - self._nearest_roots[node] = result - return self._nearest_roots[node] diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/similarfinder.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/similarfinder.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,362 +0,0 @@ -"""This module can be used for finding similar code""" -import re - -import rope.refactor.wildcards -from rope.base import codeanalyze, evaluate, exceptions, ast, builtins -from rope.refactor import (patchedast, sourceutils, occurrences, - wildcards, importutils) - - -class BadNameInCheckError(exceptions.RefactoringError): - pass - - -class SimilarFinder(object): - """`SimilarFinder` can be used to find similar pieces of code - - See the notes in the `rope.refactor.restructure` module for more - info. - - """ - - def __init__(self, pymodule, wildcards=None): - """Construct a SimilarFinder""" - self.source = pymodule.source_code - self.raw_finder = RawSimilarFinder( - pymodule.source_code, pymodule.get_ast(), self._does_match) - self.pymodule = pymodule - if wildcards is None: - self.wildcards = {} - for wildcard in [rope.refactor.wildcards. - DefaultWildcard(pymodule.pycore.project)]: - self.wildcards[wildcard.get_name()] = wildcard - else: - self.wildcards = wildcards - - def get_matches(self, code, args={}, start=0, end=None): - self.args = args - if end is None: - end = len(self.source) - skip_region = None - if 'skip' in args.get('', {}): - resource, region = args['']['skip'] - if resource == self.pymodule.get_resource(): - skip_region = region - return self.raw_finder.get_matches(code, start=start, end=end, - skip=skip_region) - - def get_match_regions(self, *args, **kwds): - for match in self.get_matches(*args, **kwds): - yield match.get_region() - - def _does_match(self, node, name): - arg = self.args.get(name, '') - kind = 'default' - if isinstance(arg, (tuple, list)): - kind = arg[0] - arg = arg[1] - suspect = wildcards.Suspect(self.pymodule, node, name) - return self.wildcards[kind].matches(suspect, arg) - - -class RawSimilarFinder(object): - """A class for finding similar expressions and statements""" - - def __init__(self, source, node=None, does_match=None): - if node is None: - node = ast.parse(source) - if does_match is None: - self.does_match = self._simple_does_match - else: - self.does_match = does_match - self._init_using_ast(node, source) - - def _simple_does_match(self, node, name): - return isinstance(node, (ast.expr, ast.Name)) - - def _init_using_ast(self, node, source): - self.source = source - self._matched_asts = {} - if not hasattr(node, 'region'): - patchedast.patch_ast(node, source) - self.ast = node - - def get_matches(self, code, start=0, end=None, skip=None): - """Search for `code` in source and return a list of `Match`\es - - `code` can contain wildcards. ``${name}`` matches normal - names and ``${?name} can match any expression. You can use - `Match.get_ast()` for getting the node that has matched a - given pattern. - - """ - if end is None: - end = len(self.source) - for match in self._get_matched_asts(code): - match_start, match_end = match.get_region() - if start <= match_start and match_end <= end: - if skip is not None and (skip[0] < match_end and - skip[1] > match_start): - continue - yield match - - def _get_matched_asts(self, code): - if code not in self._matched_asts: - wanted = self._create_pattern(code) - matches = _ASTMatcher(self.ast, wanted, - self.does_match).find_matches() - self._matched_asts[code] = matches - return self._matched_asts[code] - - def _create_pattern(self, expression): - expression = self._replace_wildcards(expression) - node = ast.parse(expression) - # Getting Module.Stmt.nodes - nodes = node.body - if len(nodes) == 1 and isinstance(nodes[0], ast.Expr): - # Getting Discard.expr - wanted = nodes[0].value - else: - wanted = nodes - return wanted - - def _replace_wildcards(self, expression): - ropevar = _RopeVariable() - template = CodeTemplate(expression) - mapping = {} - for name in template.get_names(): - mapping[name] = ropevar.get_var(name) - return template.substitute(mapping) - - -class _ASTMatcher(object): - - def __init__(self, body, pattern, does_match): - """Searches the given pattern in the body AST. - - body is an AST node and pattern can be either an AST node or - a list of ASTs nodes - """ - self.body = body - self.pattern = pattern - self.matches = None - self.ropevar = _RopeVariable() - self.matches_callback = does_match - - def find_matches(self): - if self.matches is None: - self.matches = [] - ast.call_for_nodes(self.body, self._check_node, recursive=True) - return self.matches - - def _check_node(self, node): - if isinstance(self.pattern, list): - self._check_statements(node) - else: - self._check_expression(node) - - def _check_expression(self, node): - mapping = {} - if self._match_nodes(self.pattern, node, mapping): - self.matches.append(ExpressionMatch(node, mapping)) - - def _check_statements(self, node): - for child in ast.get_children(node): - if isinstance(child, (list, tuple)): - self.__check_stmt_list(child) - - def __check_stmt_list(self, nodes): - for index in range(len(nodes)): - if len(nodes) - index >= len(self.pattern): - current_stmts = nodes[index:index + len(self.pattern)] - mapping = {} - if self._match_stmts(current_stmts, mapping): - self.matches.append(StatementMatch(current_stmts, mapping)) - - def _match_nodes(self, expected, node, mapping): - if isinstance(expected, ast.Name): - if self.ropevar.is_var(expected.id): - return self._match_wildcard(expected, node, mapping) - if not isinstance(expected, ast.AST): - return expected == node - if expected.__class__ != node.__class__: - return False - - children1 = self._get_children(expected) - children2 = self._get_children(node) - if len(children1) != len(children2): - return False - for child1, child2 in zip(children1, children2): - if isinstance(child1, ast.AST): - if not self._match_nodes(child1, child2, mapping): - return False - elif isinstance(child1, (list, tuple)): - if not isinstance(child2, (list, tuple)) or \ - len(child1) != len(child2): - return False - for c1, c2 in zip(child1, child2): - if not self._match_nodes(c1, c2, mapping): - return False - else: - if child1 != child2: - return False - return True - - def _get_children(self, node): - """Return not `ast.expr_context` children of `node`""" - children = ast.get_children(node) - return [child for child in children - if not isinstance(child, ast.expr_context)] - - def _match_stmts(self, current_stmts, mapping): - if len(current_stmts) != len(self.pattern): - return False - for stmt, expected in zip(current_stmts, self.pattern): - if not self._match_nodes(expected, stmt, mapping): - return False - return True - - def _match_wildcard(self, node1, node2, mapping): - name = self.ropevar.get_base(node1.id) - if name not in mapping: - if self.matches_callback(node2, name): - mapping[name] = node2 - return True - return False - else: - return self._match_nodes(mapping[name], node2, {}) - - -class Match(object): - - def __init__(self, mapping): - self.mapping = mapping - - def get_region(self): - """Returns match region""" - - def get_ast(self, name): - """Return the ast node that has matched rope variables""" - return self.mapping.get(name, None) - - -class ExpressionMatch(Match): - - def __init__(self, ast, mapping): - super(ExpressionMatch, self).__init__(mapping) - self.ast = ast - - def get_region(self): - return self.ast.region - - -class StatementMatch(Match): - - def __init__(self, ast_list, mapping): - super(StatementMatch, self).__init__(mapping) - self.ast_list = ast_list - - def get_region(self): - return self.ast_list[0].region[0], self.ast_list[-1].region[1] - - -class CodeTemplate(object): - - def __init__(self, template): - self.template = template - self._find_names() - - def _find_names(self): - self.names = {} - for match in CodeTemplate._get_pattern().finditer(self.template): - if 'name' in match.groupdict() and \ - match.group('name') is not None: - start, end = match.span('name') - name = self.template[start + 2:end - 1] - if name not in self.names: - self.names[name] = [] - self.names[name].append((start, end)) - - def get_names(self): - return self.names.keys() - - def substitute(self, mapping): - collector = codeanalyze.ChangeCollector(self.template) - for name, occurrences in self.names.items(): - for region in occurrences: - collector.add_change(region[0], region[1], mapping[name]) - result = collector.get_changed() - if result is None: - return self.template - return result - - _match_pattern = None - - @classmethod - def _get_pattern(cls): - if cls._match_pattern is None: - pattern = codeanalyze.get_comment_pattern() + '|' + \ - codeanalyze.get_string_pattern() + '|' + \ - r'(?P\$\{[^\s\$\}]*\})' - cls._match_pattern = re.compile(pattern) - return cls._match_pattern - - -class _RopeVariable(object): - """Transform and identify rope inserted wildcards""" - - _normal_prefix = '__rope__variable_normal_' - _any_prefix = '__rope__variable_any_' - - def get_var(self, name): - if name.startswith('?'): - return self._get_any(name) - else: - return self._get_normal(name) - - def is_var(self, name): - return self._is_normal(name) or self._is_var(name) - - def get_base(self, name): - if self._is_normal(name): - return name[len(self._normal_prefix):] - if self._is_var(name): - return '?' + name[len(self._any_prefix):] - - def _get_normal(self, name): - return self._normal_prefix + name - - def _get_any(self, name): - return self._any_prefix + name[1:] - - def _is_normal(self, name): - return name.startswith(self._normal_prefix) - - def _is_var(self, name): - return name.startswith(self._any_prefix) - - -def make_pattern(code, variables): - variables = set(variables) - collector = codeanalyze.ChangeCollector(code) - def does_match(node, name): - return isinstance(node, ast.Name) and node.id == name - finder = RawSimilarFinder(code, does_match=does_match) - for variable in variables: - for match in finder.get_matches('${%s}' % variable): - start, end = match.get_region() - collector.add_change(start, end, '${%s}' % variable) - result = collector.get_changed() - return result if result is not None else code - - -def _pydefined_to_str(pydefined): - address = [] - if isinstance(pydefined, (builtins.BuiltinClass, builtins.BuiltinFunction)): - return '__builtins__.' + pydefined.get_name() - else: - while pydefined.parent is not None: - address.insert(0, pydefined.get_name()) - pydefined = pydefined.parent - module_name = pydefined.pycore.modname(pydefined.resource) - return '.'.join(module_name.split('.') + address) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/sourceutils.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/sourceutils.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -from rope.base import ast, codeanalyze - - -def get_indents(lines, lineno): - return codeanalyze.count_line_indents(lines.get_line(lineno)) - - -def find_minimum_indents(source_code): - result = 80 - lines = source_code.split('\n') - for line in lines: - if line.strip() == '': - continue - result = min(result, codeanalyze.count_line_indents(line)) - return result - - -def indent_lines(source_code, amount): - if amount == 0: - return source_code - lines = source_code.splitlines(True) - result = [] - for l in lines: - if l.strip() == '': - result.append('\n') - continue - if amount < 0: - indents = codeanalyze.count_line_indents(l) - result.append(max(0, indents + amount) * ' ' + l.lstrip()) - else: - result.append(' ' * amount + l) - return ''.join(result) - - -def fix_indentation(code, new_indents): - """Change the indentation of `code` to `new_indents`""" - min_indents = find_minimum_indents(code) - return indent_lines(code, new_indents - min_indents) - - -def add_methods(pymodule, class_scope, methods_sources): - source_code = pymodule.source_code - lines = pymodule.lines - insertion_line = class_scope.get_end() - if class_scope.get_scopes(): - insertion_line = class_scope.get_scopes()[-1].get_end() - insertion_offset = lines.get_line_end(insertion_line) - methods = '\n\n' + '\n\n'.join(methods_sources) - indented_methods = fix_indentation( - methods, get_indents(lines, class_scope.get_start()) + - get_indent(pymodule.pycore)) - result = [] - result.append(source_code[:insertion_offset]) - result.append(indented_methods) - result.append(source_code[insertion_offset:]) - return ''.join(result) - - -def get_body(pyfunction): - """Return unindented function body""" - scope = pyfunction.get_scope() - pymodule = pyfunction.get_module() - start, end = get_body_region(pyfunction) - return fix_indentation(pymodule.source_code[start:end], 0) - - -def get_body_region(defined): - """Return the start and end offsets of function body""" - scope = defined.get_scope() - pymodule = defined.get_module() - lines = pymodule.lines - node = defined.get_ast() - start_line = node.lineno - if defined.get_doc() is None: - start_line = node.body[0].lineno - elif len(node.body) > 1: - start_line = node.body[1].lineno - start = lines.get_line_start(start_line) - scope_start = pymodule.logical_lines.logical_line_in(scope.start) - if scope_start[1] >= start_line: - # a one-liner! - # XXX: what if colon appears in a string - start = pymodule.source_code.index(':', start) + 1 - while pymodule.source_code[start].isspace(): - start += 1 - end = min(lines.get_line_end(scope.end) + 1, len(pymodule.source_code)) - return start, end - - -def get_indent(pycore): - project = pycore.project - return project.prefs.get('indent_size', 4) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/suites.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/suites.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -from rope.base import ast - - -def find_visible(node, lines): - """Return the line which is visible from all `lines`""" - root = ast_suite_tree(node) - return find_visible_for_suite(root, lines) - - -def find_visible_for_suite(root, lines): - if len(lines) == 1: - return lines[0] - line1 = lines[0] - line2 = find_visible_for_suite(root, lines[1:]) - suite1 = root.find_suite(line1) - suite2 = root.find_suite(line2) - def valid(suite): - return suite is not None and not suite.ignored - if valid(suite1) and not valid(suite2): - return line1 - if not valid(suite1) and valid(suite2): - return line2 - if not valid(suite1) and not valid(suite2): - return None - while suite1 != suite2 and suite1.parent != suite2.parent: - if suite1._get_level() < suite2._get_level(): - line2 = suite2.get_start() - suite2 = suite2.parent - elif suite1._get_level() > suite2._get_level(): - line1 = suite1.get_start() - suite1 = suite1.parent - else: - line1 = suite1.get_start() - line2 = suite2.get_start() - suite1 = suite1.parent - suite2 = suite2.parent - if suite1 == suite2: - return min(line1, line2) - return min(suite1.get_start(), suite2.get_start()) - - -def ast_suite_tree(node): - if hasattr(node, 'lineno'): - lineno = node.lineno - else: - lineno = 1 - return Suite(node.body, lineno) - - -class Suite(object): - - def __init__(self, child_nodes, lineno, parent=None, ignored=False): - self.parent = parent - self.lineno = lineno - self.child_nodes = child_nodes - self._children = None - self.ignored = ignored - - def get_start(self): - if self.parent is None: - if self.child_nodes: - return self.local_start() - else: - return 1 - return self.lineno - - def get_children(self): - if self._children is None: - walker = _SuiteWalker(self) - for child in self.child_nodes: - ast.walk(child, walker) - self._children = walker.suites - return self._children - - def local_start(self): - return self.child_nodes[0].lineno - - def local_end(self): - end = self.child_nodes[-1].lineno - if self.get_children(): - end = max(end, self.get_children()[-1].local_end()) - return end - - def find_suite(self, line): - if line is None: - return None - for child in self.get_children(): - if child.local_start() <= line <= child.local_end(): - return child.find_suite(line) - return self - - def _get_level(self): - if self.parent is None: - return 0 - return self.parent._get_level() + 1 - - -class _SuiteWalker(object): - - def __init__(self, suite): - self.suite = suite - self.suites = [] - - def _If(self, node): - self._add_if_like_node(node) - - def _For(self, node): - self._add_if_like_node(node) - - def _While(self, node): - self._add_if_like_node(node) - - def _With(self, node): - self.suites.append(Suite(node.body, node.lineno, self.suite)) - - def _TryFinally(self, node): - if len(node.finalbody) == 1 and \ - isinstance(node.body[0], ast.TryExcept): - self._TryExcept(node.body[0]) - else: - self.suites.append(Suite(node.body, node.lineno, self.suite)) - self.suites.append(Suite(node.finalbody, node.lineno, self.suite)) - - def _TryExcept(self, node): - self.suites.append(Suite(node.body, node.lineno, self.suite)) - for handler in node.handlers: - self.suites.append(Suite(handler.body, node.lineno, self.suite)) - if node.orelse: - self.suites.append(Suite(node.orelse, node.lineno, self.suite)) - - def _add_if_like_node(self, node): - self.suites.append(Suite(node.body, node.lineno, self.suite)) - if node.orelse: - self.suites.append(Suite(node.orelse, node.lineno, self.suite)) - - def _FunctionDef(self, node): - self.suites.append(Suite(node.body, node.lineno, - self.suite, ignored=True)) - - def _ClassDef(self, node): - self.suites.append(Suite(node.body, node.lineno, - self.suite, ignored=True)) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/topackage.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/topackage.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -import rope.refactor.importutils -from rope.base.change import ChangeSet, ChangeContents, MoveResource, CreateFolder - - -class ModuleToPackage(object): - - def __init__(self, project, resource): - self.project = project - self.pycore = project.pycore - self.resource = resource - - def get_changes(self): - changes = ChangeSet('Transform <%s> module to package' % - self.resource.path) - new_content = self._transform_relatives_to_absolute(self.resource) - if new_content is not None: - changes.add_change(ChangeContents(self.resource, new_content)) - parent = self.resource.parent - name = self.resource.name[:-3] - changes.add_change(CreateFolder(parent, name)) - parent_path = parent.path + '/' - if not parent.path: - parent_path = '' - new_path = parent_path + '%s/__init__.py' % name - if self.resource.project == self.project: - changes.add_change(MoveResource(self.resource, new_path)) - return changes - - def _transform_relatives_to_absolute(self, resource): - pymodule = self.pycore.resource_to_pyobject(resource) - import_tools = rope.refactor.importutils.ImportTools(self.pycore) - return import_tools.relatives_to_absolutes(pymodule) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/usefunction.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/usefunction.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,171 +0,0 @@ -from rope.base import (change, taskhandle, evaluate, - exceptions, pyobjects, pynames, ast) -from rope.refactor import restructure, sourceutils, similarfinder, importutils - - -class UseFunction(object): - """Try to use a function wherever possible""" - - def __init__(self, project, resource, offset): - self.project = project - self.offset = offset - this_pymodule = project.pycore.resource_to_pyobject(resource) - pyname = evaluate.eval_location(this_pymodule, offset) - if pyname is None: - raise exceptions.RefactoringError('Unresolvable name selected') - self.pyfunction = pyname.get_object() - if not isinstance(self.pyfunction, pyobjects.PyFunction) or \ - not isinstance(self.pyfunction.parent, pyobjects.PyModule): - raise exceptions.RefactoringError( - 'Use function works for global functions, only.') - self.resource = self.pyfunction.get_module().get_resource() - self._check_returns() - - def _check_returns(self): - node = self.pyfunction.get_ast() - if _yield_count(node): - raise exceptions.RefactoringError('Use function should not ' - 'be used on generators.') - returns = _return_count(node) - if returns > 1: - raise exceptions.RefactoringError('usefunction: Function has more ' - 'than one return statement.') - if returns == 1 and not _returns_last(node): - raise exceptions.RefactoringError('usefunction: return should ' - 'be the last statement.') - - def get_changes(self, resources=None, - task_handle=taskhandle.NullTaskHandle()): - if resources is None: - resources = self.project.pycore.get_python_files() - changes = change.ChangeSet('Using function <%s>' % - self.pyfunction.get_name()) - if self.resource in resources: - newresources = list(resources) - newresources.remove(self.resource) - for c in self._restructure(newresources, task_handle).changes: - changes.add_change(c) - if self.resource in resources: - for c in self._restructure([self.resource], task_handle, - others=False).changes: - changes.add_change(c) - return changes - - def get_function_name(self): - return self.pyfunction.get_name() - - def _restructure(self, resources, task_handle, others=True): - body = self._get_body() - pattern = self._make_pattern() - goal = self._make_goal(import_=others) - imports = None - if others: - imports = ['import %s' % self._module_name()] - - body_region = sourceutils.get_body_region(self.pyfunction) - args_value = {'skip': (self.resource, body_region)} - args = {'': args_value} - - restructuring = restructure.Restructure( - self.project, pattern, goal, args=args, imports=imports) - return restructuring.get_changes(resources=resources, - task_handle=task_handle) - - def _find_temps(self): - return find_temps(self.project, self._get_body()) - - def _module_name(self): - return self.project.pycore.modname(self.resource) - - def _make_pattern(self): - params = self.pyfunction.get_param_names() - body = self._get_body() - body = restructure.replace(body, 'return', 'pass') - wildcards = list(params) - wildcards.extend(self._find_temps()) - if self._does_return(): - if self._is_expression(): - replacement = '${%s}' % self._rope_returned - else: - replacement = '%s = ${%s}' % (self._rope_result, - self._rope_returned) - body = restructure.replace( - body, 'return ${%s}' % self._rope_returned, - replacement) - wildcards.append(self._rope_result) - return similarfinder.make_pattern(body, wildcards) - - def _get_body(self): - return sourceutils.get_body(self.pyfunction) - - def _make_goal(self, import_=False): - params = self.pyfunction.get_param_names() - function_name = self.pyfunction.get_name() - if import_: - function_name = self._module_name() + '.' + function_name - goal = '%s(%s)' % (function_name, - ', ' .join(('${%s}' % p) for p in params)) - if self._does_return() and not self._is_expression(): - goal = '${%s} = %s' % (self._rope_result, goal) - return goal - - def _does_return(self): - body = self._get_body() - removed_return = restructure.replace(body, 'return ${result}', '') - return removed_return != body - - def _is_expression(self): - return len(self.pyfunction.get_ast().body) == 1 - - _rope_result = '_rope__result' - _rope_returned = '_rope__returned' - - -def find_temps(project, code): - code = 'def f():\n' + sourceutils.indent_lines(code, 4) - pymodule = project.pycore.get_string_module(code) - result = [] - function_scope = pymodule.get_scope().get_scopes()[0] - for name, pyname in function_scope.get_names().items(): - if isinstance(pyname, pynames.AssignedName): - result.append(name) - return result - - -def _returns_last(node): - return node.body and isinstance(node.body[-1], ast.Return) - -def _yield_count(node): - visitor = _ReturnOrYieldFinder() - visitor.start_walking(node) - return visitor.yields - -def _return_count(node): - visitor = _ReturnOrYieldFinder() - visitor.start_walking(node) - return visitor.returns - -class _ReturnOrYieldFinder(object): - - def __init__(self): - self.returns = 0 - self.yields = 0 - - def _Return(self, node): - self.returns += 1 - - def _Yield(self, node): - self.yields += 1 - - def _FunctionDef(self, node): - pass - - def _ClassDef(self, node): - pass - - def start_walking(self, node): - nodes = [node] - if isinstance(node, ast.FunctionDef): - nodes = ast.get_child_nodes(node) - for child in nodes: - ast.walk(child, self) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/rope/refactor/wildcards.py --- a/vim/sadness/ropevim/src/rope/rope/refactor/wildcards.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -from rope.base import ast, evaluate, builtins, pyobjects -from rope.refactor import patchedast, occurrences - - -class Wildcard(object): - - def get_name(self): - """Return the name of this wildcard""" - - def matches(self, suspect, arg): - """Return `True` if `suspect` matches this wildcard""" - - -class Suspect(object): - - def __init__(self, pymodule, node, name): - self.name = name - self.pymodule = pymodule - self.node = node - - -class DefaultWildcard(object): - """The default restructuring wildcard - - The argument passed to this wildcard is in the - ``key1=value1,key2=value2,...`` format. Possible keys are: - - * name - for checking the reference - * type - for checking the type - * object - for checking the object - * instance - for checking types but similar to builtin isinstance - * exact - matching only occurrences with the same name as the wildcard - * unsure - matching unsure occurrences - - """ - - def __init__(self, project): - self.project = project - - def get_name(self): - return 'default' - - def matches(self, suspect, arg=''): - args = parse_arg(arg) - - if not self._check_exact(args, suspect): - return False - if not self._check_object(args, suspect): - return False - return True - - def _check_object(self, args, suspect): - kind = None - expected = None - unsure = args.get('unsure', False) - for check in ['name', 'object', 'type', 'instance']: - if check in args: - kind = check - expected = args[check] - if expected is not None: - checker = _CheckObject(self.project, expected, - kind, unsure=unsure) - return checker(suspect.pymodule, suspect.node) - return True - - def _check_exact(self, args, suspect): - node = suspect.node - if args.get('exact'): - if not isinstance(node, ast.Name) or not node.id == suspect.name: - return False - else: - if not isinstance(node, ast.expr): - return False - return True - - -def parse_arg(arg): - if isinstance(arg, dict): - return arg - result = {} - tokens = arg.split(',') - for token in tokens: - if '=' in token: - parts = token.split('=', 1) - result[parts[0].strip()] = parts[1].strip() - else: - result[token.strip()] = True - return result - - -class _CheckObject(object): - - def __init__(self, project, expected, kind='object', unsure=False): - self.project = project - self.kind = kind - self.unsure = unsure - self.expected = self._evaluate(expected) - - def __call__(self, pymodule, node): - pyname = self._evaluate_node(pymodule, node) - if pyname is None or self.expected is None: - return self.unsure - if self._unsure_pyname(pyname, unbound=self.kind=='name'): - return True - if self.kind == 'name': - return self._same_pyname(self.expected, pyname) - else: - pyobject = pyname.get_object() - if self.kind == 'object': - objects = [pyobject] - if self.kind == 'type': - objects = [pyobject.get_type()] - if self.kind == 'instance': - objects = [pyobject] - objects.extend(self._get_super_classes(pyobject)) - objects.extend(self._get_super_classes(pyobject.get_type())) - for pyobject in objects: - if self._same_pyobject(self.expected.get_object(), pyobject): - return True - return False - - def _get_super_classes(self, pyobject): - result = [] - if isinstance(pyobject, pyobjects.AbstractClass): - for superclass in pyobject.get_superclasses(): - result.append(superclass) - result.extend(self._get_super_classes(superclass)) - return result - - def _same_pyobject(self, expected, pyobject): - return expected == pyobject - - def _same_pyname(self, expected, pyname): - return occurrences.same_pyname(expected, pyname) - - def _unsure_pyname(self, pyname, unbound=True): - return self.unsure and occurrences.unsure_pyname(pyname, unbound) - - def _split_name(self, name): - parts = name.split('.') - expression, kind = parts[0], parts[-1] - if len(parts) == 1: - kind = 'name' - return expression, kind - - def _evaluate_node(self, pymodule, node): - scope = pymodule.get_scope().get_inner_scope_for_line(node.lineno) - expression = node - if isinstance(expression, ast.Name) and \ - isinstance(expression.ctx, ast.Store): - start, end = patchedast.node_region(expression) - text = pymodule.source_code[start:end] - return evaluate.eval_str(scope, text) - else: - return evaluate.eval_node(scope, expression) - - def _evaluate(self, code): - attributes = code.split('.') - pyname = None - if attributes[0] in ('__builtin__', '__builtins__'): - class _BuiltinsStub(object): - def get_attribute(self, name): - return builtins.builtins[name] - def __getitem__(self, name): - return builtins.builtins[name] - def __contains__(self, name): - return name in builtins.builtins - pyobject = _BuiltinsStub() - else: - pyobject = self.project.pycore.get_module(attributes[0]) - for attribute in attributes[1:]: - pyname = pyobject[attribute] - if pyname is None: - return None - pyobject = pyname.get_object() - return pyname diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/__init__.py --- a/vim/sadness/ropevim/src/rope/ropetest/__init__.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -import sys -import unittest - -import ropetest.projecttest -import ropetest.codeanalyzetest -import ropetest.pycoretest -import ropetest.pyscopestest -import ropetest.objectinfertest -import ropetest.objectdbtest -import ropetest.advanced_oi_test -import ropetest.runmodtest -import ropetest.builtinstest -import ropetest.historytest -import ropetest.simplifytest - - -def suite(): - result = unittest.TestSuite() - result.addTests(ropetest.projecttest.suite()) - result.addTests(ropetest.codeanalyzetest.suite()) - result.addTests(ropetest.pycoretest.suite()) - result.addTests(ropetest.pyscopestest.suite()) - result.addTests(ropetest.objectinfertest.suite()) - result.addTests(ropetest.objectdbtest.suite()) - result.addTests(ropetest.advanced_oi_test.suite()) - result.addTests(ropetest.runmodtest.suite()) - result.addTests(ropetest.builtinstest.suite()) - result.addTests(ropetest.historytest.suite()) - result.addTests(ropetest.simplifytest.suite()) - return result - - -if __name__ == '__main__': - runner = unittest.TextTestRunner() - result = runner.run(suite()) - sys.exit(not result.wasSuccessful()) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/advanced_oi_test.py --- a/vim/sadness/ropevim/src/rope/ropetest/advanced_oi_test.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,740 +0,0 @@ -import unittest - -import rope.base.oi -import rope.base.libutils -from ropetest import testutils - - -class DynamicOITest(unittest.TestCase): - - def setUp(self): - super(DynamicOITest, self).setUp() - self.project = testutils.sample_project(validate_objectdb=True) - self.pycore = self.project.pycore - - def tearDown(self): - testutils.remove_project(self.project) - super(DynamicOITest, self).tearDown() - - def test_simple_dti(self): - mod = testutils.create_module(self.project, 'mod') - code = 'def a_func(arg):\n return eval("arg")\n' \ - 'a_var = a_func(a_func)\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - self.assertEquals(pymod['a_func'].get_object(), - pymod['a_var'].get_object()) - - def test_module_dti(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - code = 'import mod1\ndef a_func(arg):\n return eval("arg")\n' \ - 'a_var = a_func(mod1)\n' - mod2.write(code) - self.pycore.run_module(mod2).wait_process() - pymod2 = self.pycore.resource_to_pyobject(mod2) - self.assertEquals(self.pycore.resource_to_pyobject(mod1), - pymod2['a_var'].get_object()) - - def test_class_from_another_module_dti(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - code1 = 'class AClass(object):\n pass\n' - code2 = 'from mod1 import AClass\n' \ - '\ndef a_func(arg):\n return eval("arg")\n' \ - 'a_var = a_func(AClass)\n' - mod1.write(code1) - mod2.write(code2) - self.pycore.run_module(mod2).wait_process() - pymod1 = self.pycore.resource_to_pyobject(mod1) - pymod2 = self.pycore.resource_to_pyobject(mod2) - self.assertEquals(pymod2['AClass'].get_object(), - pymod2['a_var'].get_object()) - - - def test_class_dti(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class AClass(object):\n pass\n' \ - '\ndef a_func(arg):\n return eval("arg")\n' \ - 'a_var = a_func(AClass)\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - self.assertEquals(pymod['AClass'].get_object(), - pymod['a_var'].get_object()) - - def test_instance_dti(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class AClass(object):\n pass\n' \ - '\ndef a_func(arg):\n return eval("arg()")\n' \ - 'a_var = a_func(AClass)\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - self.assertEquals(pymod['AClass'].get_object(), - pymod['a_var'].get_object().get_type()) - - def test_method_dti(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class AClass(object):\n def a_method(self, arg):\n' \ - ' return eval("arg()")\n' \ - 'an_instance = AClass()\n' \ - 'a_var = an_instance.a_method(AClass)\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - self.assertEquals(pymod['AClass'].get_object(), - pymod['a_var'].get_object().get_type()) - - def test_function_argument_dti(self): - mod = testutils.create_module(self.project, 'mod') - code = 'def a_func(arg):\n pass\n' \ - 'a_func(a_func)\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pyscope = self.pycore.resource_to_pyobject(mod).get_scope() - self.assertEquals(pyscope['a_func'].get_object(), - pyscope.get_scopes()[0]['arg'].get_object()) - - def test_classes_with_the_same_name(self): - mod = testutils.create_module(self.project, 'mod') - code = 'def a_func(arg):\n class AClass(object):\n' \ - ' pass\n return eval("arg")\n' \ - 'class AClass(object):\n pass\n' \ - 'a_var = a_func(AClass)\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - self.assertEquals(pymod['AClass'].get_object(), - pymod['a_var'].get_object()) - - def test_nested_classes(self): - mod = testutils.create_module(self.project, 'mod') - code = 'def a_func():\n class AClass(object):\n' \ - ' pass\n return AClass\n' \ - 'def another_func(arg):\n return eval("arg")\n' \ - 'a_var = another_func(a_func())\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pyscope = self.pycore.resource_to_pyobject(mod).get_scope() - self.assertEquals(pyscope.get_scopes()[0]['AClass'].get_object(), - pyscope['a_var'].get_object()) - - def test_function_argument_dti2(self): - mod = testutils.create_module(self.project, 'mod') - code = 'def a_func(arg, a_builtin_type):\n pass\n' \ - 'a_func(a_func, [])\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pyscope = self.pycore.resource_to_pyobject(mod).get_scope() - self.assertEquals(pyscope['a_func'].get_object(), - pyscope.get_scopes()[0]['arg'].get_object()) - - def test_dti_and_concluded_data_invalidation(self): - mod = testutils.create_module(self.project, 'mod') - code = 'def a_func(arg):\n return eval("arg")\n' \ - 'a_var = a_func(a_func)\n' - mod.write(code) - pymod = self.pycore.resource_to_pyobject(mod) - pymod['a_var'].get_object() - self.pycore.run_module(mod).wait_process() - self.assertEquals(pymod['a_func'].get_object(), - pymod['a_var'].get_object()) - - def test_list_objects_and_dynamicoi(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C(object):\n pass\n' \ - 'def a_func(arg):\n return eval("arg")\n' \ - 'a_var = a_func([C()])[0]\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_for_loops_and_dynamicoi(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C(object):\n pass\n' \ - 'def a_func(arg):\n return eval("arg")\n' \ - 'for c in a_func([C()]):\n a_var = c\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_dict_objects_and_dynamicoi(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C(object):\n pass\n' \ - 'def a_func(arg):\n return eval("arg")\n' \ - 'a_var = a_func({1: C()})[1]\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_dict_keys_and_dynamicoi(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C(object):\n pass\n' \ - 'def a_func(arg):\n return eval("arg")\n' \ - 'a_var = a_func({C(): 1}).keys()[0]\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_dict_keys_and_dynamicoi2(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'def a_func(arg):\n return eval("arg")\n' \ - 'a, b = a_func((C1(), C2()))\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_strs_and_dynamicoi(self): - mod = testutils.create_module(self.project, 'mod') - code = 'def a_func(arg):\n return eval("arg")\n' \ - 'a_var = a_func("hey")\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - a_var = pymod['a_var'].get_object() - self.assertTrue(isinstance(a_var.get_type(), rope.base.builtins.Str)) - - def test_textual_transformations(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C(object):\n pass\ndef f():\n pass\na_var = C()\n' \ - 'a_list = [C()]\na_str = "hey"\na_file = open("file.txt")\n' - mod.write(code) - to_pyobject = rope.base.oi.transform.TextualToPyObject(self.project) - to_textual = rope.base.oi.transform.PyObjectToTextual(self.project) - pymod = self.pycore.resource_to_pyobject(mod) - def complex_to_textual(pyobject): - return to_textual.transform( - to_pyobject.transform(to_textual.transform(pyobject))) - for name in ('C', 'f', 'a_var', 'a_list', 'a_str', 'a_file'): - var = pymod[name].get_object() - self.assertEquals(to_textual.transform(var), complex_to_textual(var)) - self.assertEquals(to_textual.transform(pymod), complex_to_textual(pymod)) - enumerate_func = rope.base.builtins.builtins['enumerate'].get_object() - self.assertEquals(to_textual.transform(enumerate_func), - complex_to_textual(enumerate_func)) - - def test_arguments_with_keywords(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'def a_func(arg):\n return eval("arg")\n' \ - 'a = a_func(arg=C1())\nb = a_func(arg=C2())\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_a_function_with_different_returns(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'def a_func(arg):\n return eval("arg")\n' \ - 'a = a_func(C1())\nb = a_func(C2())\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_a_function_with_different_returns2(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'def a_func(p):\n if p == C1:\n return C1()\n' \ - ' else:\n return C2()\n' \ - 'a = a_func(C1)\nb = a_func(C2)\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_ignoring_star_args(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'def a_func(p, *args):\n if p == C1:\n return C1()\n' \ - ' else:\n return C2()\n' \ - 'a = a_func(C1, 1)\nb = a_func(C2, 2)\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_ignoring_double_star_args(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'def a_func(p, *kwds, **args):\n if p == C1:\n return C1()\n' \ - ' else:\n return C2()\n' \ - 'a = a_func(C1, kwd=1)\nb = a_func(C2, kwd=2)\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - pymod = self.pycore.resource_to_pyobject(mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_invalidating_data_after_changing(self): - mod = testutils.create_module(self.project, 'mod') - code = 'def a_func(arg):\n return eval("arg")\n' \ - 'a_var = a_func(a_func)\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - mod.write(code.replace('a_func', 'newfunc')) - mod.write(code) - pymod = self.pycore.resource_to_pyobject(mod) - self.assertNotEquals(pymod['a_func'].get_object(), - pymod['a_var'].get_object()) - - def test_invalidating_data_after_moving(self): - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('class C(object):\n pass\n') - mod = testutils.create_module(self.project, 'mod') - code = 'import mod2\ndef a_func(arg):\n return eval(arg)\n' \ - 'a_var = a_func("mod2.C")\n' - mod.write(code) - self.pycore.run_module(mod).wait_process() - mod.move('newmod.py') - pymod = self.pycore.get_module('newmod') - pymod2 = self.pycore.resource_to_pyobject(mod2) - self.assertEquals(pymod2['C'].get_object(), - pymod['a_var'].get_object()) - - -class NewStaticOITest(unittest.TestCase): - - def setUp(self): - super(NewStaticOITest, self).setUp() - self.project = testutils.sample_project(validate_objectdb=True) - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod') - - def tearDown(self): - testutils.remove_project(self.project) - super(NewStaticOITest, self).tearDown() - - def test_static_oi_for_simple_function_calls(self): - code = 'class C(object):\n pass\ndef f(p):\n pass\nf(C())\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - f_scope = pymod['f'].get_object().get_scope() - p_type = f_scope['p'].get_object().get_type() - self.assertEquals(c_class, p_type) - - def test_static_oi_not_failing_when_callin_callables(self): - code = 'class C(object):\n pass\nC()\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - - def test_static_oi_for_nested_calls(self): - code = 'class C(object):\n pass\ndef f(p):\n pass\n' \ - 'def g(p):\n return p\nf(g(C()))\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - f_scope = pymod['f'].get_object().get_scope() - p_type = f_scope['p'].get_object().get_type() - self.assertEquals(c_class, p_type) - - def test_static_oi_class_methods(self): - code = 'class C(object):\n def f(self, p):\n pass\n' \ - 'C().f(C())' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - f_scope = c_class['f'].get_object().get_scope() - p_type = f_scope['p'].get_object().get_type() - self.assertEquals(c_class, p_type) - - def test_static_oi_preventing_soi_maximum_recursion_exceptions(self): - code = 'item = {}\nfor item in item.keys():\n pass\n' - self.mod.write(code) - try: - self.pycore.analyze_module(self.mod) - except RuntimeError, e: - self.fail(str(e)) - - def test_static_oi_for_infering_returned_types_from_functions_based_on_parameters(self): - code = 'class C(object):\n pass\ndef func(p):\n return p\n' \ - 'a_var = func(C())\n' - self.mod.write(code) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_a_function_with_different_returns(self): - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'def a_func(arg):\n return arg\n' \ - 'a = a_func(C1())\nb = a_func(C2())\n' - self.mod.write(code) - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_not_reporting_out_of_date_information(self): - code = 'class C1(object):\n pass\n' \ - 'def f(arg):\n return C1()\na_var = f('')\n' - self.mod.write(code) - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - - self.mod.write(code.replace('C1', 'C2')) - pymod = self.pycore.resource_to_pyobject(self.mod) - c2_class = pymod['C2'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c2_class, a_var.get_type()) - - def test_invalidating_concluded_data_in_a_function(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('def func(arg):\n temp = arg\n return temp\n') - mod2.write('import mod1\n' - 'class C1(object):\n pass\n' - 'class C2(object):\n pass\n' - 'a_var = mod1.func(C1())\n') - pymod2 = self.pycore.resource_to_pyobject(mod2) - c1_class = pymod2['C1'].get_object() - a_var = pymod2['a_var'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - - mod2.write(mod2.read()[:mod2.read().rfind('C1()')] + 'C2())\n') - pymod2 = self.pycore.resource_to_pyobject(mod2) - c2_class = pymod2['C2'].get_object() - a_var = pymod2['a_var'].get_object() - self.assertEquals(c2_class, a_var.get_type()) - - def test_handling_generator_functions_for_strs(self): - self.mod.write('class C(object):\n pass\ndef f(p):\n yield p()\n' - 'for c in f(C):\n a_var = c\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - # TODO: Returning a generator for functions that yield unknowns - def xxx_test_handling_generator_functions_when_unknown_type_is_yielded(self): - self.mod.write('class C(object):\n pass\ndef f():\n yield eval("C()")\n' - 'a_var = f()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - a_var = pymod['a_var'].get_object() - self.assertTrue(isinstance(a_var.get_type(), - rope.base.builtins.Generator)) - - def test_static_oi_for_lists_depending_on_append_function(self): - code = 'class C(object):\n pass\nl = list()\n' \ - 'l.append(C())\na_var = l.pop()\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_static_oi_for_lists_per_object_for_get_item(self): - code = 'class C(object):\n pass\nl = list()\n' \ - 'l.append(C())\na_var = l[0]\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_static_oi_for_lists_per_object_for_fields(self): - code = 'class C(object):\n pass\n' \ - 'class A(object):\n def __init__(self):\n self.l = []\n' \ - ' def set(self):\n self.l.append(C())\n' \ - 'a = A()\na.set()\na_var = a.l[0]\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_static_oi_for_lists_per_object_for_set_item(self): - code = 'class C(object):\n pass\nl = [None]\n' \ - 'l[0] = C()\na_var = l[0]\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_static_oi_for_lists_per_object_for_extending_lists(self): - code = 'class C(object):\n pass\nl = []\n' \ - 'l.append(C())\nl2 = []\nl2.extend(l)\na_var = l2[0]\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_static_oi_for_lists_per_object_for_iters(self): - code = 'class C(object):\n pass\n' \ - 'l = []\nl.append(C())\n' \ - 'for c in l:\n a_var = c\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_static_oi_for_dicts_depending_on_append_function(self): - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'd = {}\nd[C1()] = C2()\na, b = d.popitem()\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_static_oi_for_dicts_depending_on_for_loops(self): - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'd = {}\nd[C1()] = C2()\nfor k, v in d.items():\n a = k\n b = v\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_static_oi_for_dicts_depending_on_update(self): - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'd = {}\nd[C1()] = C2()\nd2 = {}\nd2.update(d)\na, b = d2.popitem()\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_static_oi_for_dicts_depending_on_update_on_seqs(self): - code = 'class C1(object):\n pass\nclass C2(object):\n pass\n' \ - 'd = {}\nd.update([(C1(), C2())])\na, b = d.popitem()\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_static_oi_for_sets_per_object_for_set_item(self): - code = 'class C(object):\n pass\ns = set()\n' \ - 's.add(C())\na_var = s.pop() \n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_properties_and_calling_get_property(self): - code = 'class C1(object):\n pass\n' \ - 'class C2(object):\n c1 = C1()\n' \ - ' def get_c1(self):\n return self.c1\n' \ - ' p = property(get_c1)\nc2 = C2()\na_var = c2.p\n' - self.mod.write(code) - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - - def test_soi_on_constructors(self): - code = 'class C1(object):\n pass\n' \ - 'class C2(object):\n' \ - ' def __init__(self, arg):\n self.attr = arg\n' \ - 'c2 = C2(C1())\na_var = c2.attr' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - - def test_not_saving_unknown_function_returns(self): - mod2 = testutils.create_module(self.project, 'mod2') - self.mod.write('class C(object):\n pass\nl = []\nl.append(C())\n') - mod2.write('import mod\ndef f():\n return mod.l.pop()\na_var = f()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - pymod2 = self.pycore.resource_to_pyobject(mod2) - c_class = pymod['C'].get_object() - a_var = pymod2['a_var'] - - self.pycore.analyze_module(mod2) - self.assertNotEquals(c_class, a_var.get_object().get_type()) - - self.pycore.analyze_module(self.mod) - self.assertEquals(c_class, a_var.get_object().get_type()) - - def test_using_the_best_callinfo(self): - code = 'class C1(object):\n pass\n' \ - 'def f(arg1, arg2, arg3):\n pass\n' \ - 'f("", None, C1())\nf("", C1(), None)\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - f_scope = pymod['f'].get_object().get_scope() - arg2 = f_scope['arg2'].get_object() - self.assertEquals(c1_class, arg2.get_type()) - - def test_call_function_and_parameters(self): - code = 'class A(object):\n def __call__(self, p):\n pass\n' \ - 'A()("")\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - scope = self.pycore.resource_to_pyobject(self.mod).get_scope() - p_object = scope.get_scopes()[0].get_scopes()[0]['p'].get_object() - self.assertTrue(isinstance(p_object.get_type(), - rope.base.builtins.Str)) - - def test_report_change_in_libutils(self): - self.project.prefs['automatic_soa'] = True - code = 'class C(object):\n pass\ndef f(p):\n pass\nf(C())\n' - mod_file = open(self.mod.real_path, 'w') - mod_file.write(code) - mod_file.close() - rope.base.libutils.report_change(self.project, self.mod.real_path, '') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - f_scope = pymod['f'].get_object().get_scope() - p_type = f_scope['p'].get_object().get_type() - self.assertEquals(c_class, p_type) - - def test_report_libutils_and_analyze_all_modules(self): - code = 'class C(object):\n pass\ndef f(p):\n pass\nf(C())\n' - self.mod.write(code) - rope.base.libutils.analyze_modules(self.project) - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - f_scope = pymod['f'].get_object().get_scope() - p_type = f_scope['p'].get_object().get_type() - self.assertEquals(c_class, p_type) - - def test_validation_problems_for_objectdb_retrievals(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('l = []\nvar = l.pop()\n') - mod2.write('import mod1\n\nclass C(object):\n pass\n' - 'mod1.l.append(C())\n') - self.pycore.analyze_module(mod2) - - pymod2 = self.pycore.resource_to_pyobject(mod2) - c_class = pymod2['C'].get_object() - pymod1 = self.pycore.resource_to_pyobject(mod1) - var_pyname = pymod1['var'] - self.assertEquals(c_class, var_pyname.get_object().get_type()) - mod2.write('import mod1\n\nmod1.l.append("")\n') - self.assertNotEquals(c_class, var_pyname.get_object().get_type(), - 'Class `C` no more exists') - - def test_validation_problems_for_changing_builtin_types(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('l = []\nl.append("")\n') - self.pycore.analyze_module(mod1) - - mod1.write('l = {}\nv = l["key"]\n') - pymod1 = self.pycore.resource_to_pyobject(mod1) - var = pymod1['v'].get_object() - - def test_always_returning_containing_class_for_selfs(self): - code = 'class A(object):\n def f(p):\n return p\n' \ - 'class B(object):\n pass\nb = B()\nb.f()\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod) - pymod = self.pycore.resource_to_pyobject(self.mod) - a_class = pymod['A'].get_object() - f_scope = a_class.get_scope().get_scopes()[0] - p_type = f_scope['p'].get_object().get_type() - self.assertEquals(a_class, p_type) - - def test_following_function_calls_when_asked_to(self): - code = 'class A(object):\n pass\n' \ - 'class C(object):\n' \ - ' def __init__(self, arg):\n' \ - ' self.attr = arg\n' \ - 'def f(p):\n return C(p)\n' \ - 'c = f(A())\nx = c.attr\n' - self.mod.write(code) - self.pycore.analyze_module(self.mod, followed_calls=1) - pymod = self.pycore.resource_to_pyobject(self.mod) - a_class = pymod['A'].get_object() - x_var = pymod['x'].get_object().get_type() - self.assertEquals(a_class, x_var) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(DynamicOITest)) - result.addTests(unittest.makeSuite(NewStaticOITest)) - return result - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/builtinstest.py --- a/vim/sadness/ropevim/src/rope/ropetest/builtinstest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,482 +0,0 @@ -import unittest - -from rope.base import pyobjects, builtins -from ropetest import testutils - - -class BuiltinTypesTest(unittest.TestCase): - - def setUp(self): - super(BuiltinTypesTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod') - - def tearDown(self): - testutils.remove_project(self.project) - super(BuiltinTypesTest, self).tearDown() - - def test_simple_case(self): - self.mod.write('l = []\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertTrue('append' in pymod['l'].get_object()) - - def test_holding_type_information(self): - self.mod.write('class C(object):\n pass\nl = [C()]\na_var = l.pop()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_get_items(self): - self.mod.write('class C(object):\n def __getitem__(self, i):\n return C()\n' - 'c = C()\na_var = c[0]') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_get_items_for_lists(self): - self.mod.write('class C(object):\n pass\nl = [C()]\na_var = l[0]\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_get_items_from_slices(self): - self.mod.write('class C(object):\n pass\nl = [C()]\na_var = l[:].pop()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_simple_for_loops(self): - self.mod.write('class C(object):\n pass\nl = [C()]\n' - 'for c in l:\n a_var = c\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_definition_location_for_loop_variables(self): - self.mod.write('class C(object):\n pass\nl = [C()]\n' - 'for c in l:\n pass\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_var = pymod['c'] - self.assertEquals((pymod, 4), c_var.get_definition_location()) - - def test_simple_case_for_dicts(self): - self.mod.write('d = {}\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertTrue('get' in pymod['d'].get_object()) - - def test_get_item_for_dicts(self): - self.mod.write('class C(object):\n pass\nd = {1: C()}\na_var = d[1]\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_popping_dicts(self): - self.mod.write('class C(object):\n pass\nd = {1: C()}\na_var = d.pop(1)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_getting_keys_from_dicts(self): - self.mod.write('class C1(object):\n pass\nclass C2(object):\n pass\n' - 'd = {C1(): C2()}\nfor c in d.keys():\n a_var = c\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C1'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_getting_values_from_dicts(self): - self.mod.write('class C1(object):\n pass\nclass C2(object):\n pass\n' - 'd = {C1(): C2()}\nfor c in d.values():\n a_var = c\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C2'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_getting_iterkeys_from_dicts(self): - self.mod.write('class C1(object):\n pass\nclass C2(object):\n pass\n' - 'd = {C1(): C2()}\nfor c in d.keys():\n a_var = c\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C1'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_getting_itervalues_from_dicts(self): - self.mod.write('class C1(object):\n pass\nclass C2(object):\n pass\n' - 'd = {C1(): C2()}\nfor c in d.values():\n a_var = c\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C2'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_using_copy_for_dicts(self): - self.mod.write('class C1(object):\n pass\nclass C2(object):\n pass\n' - 'd = {C1(): C2()}\nfor c in d.copy():\n a_var = c\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C1'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_tuple_assignments_for_items(self): - self.mod.write('class C1(object):\n pass\nclass C2(object):\n pass\n' - 'd = {C1(): C2()}\nkey, value = d.items()[0]\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - key = pymod['key'].get_object() - value = pymod['value'].get_object() - self.assertEquals(c1_class, key.get_type()) - self.assertEquals(c2_class, value.get_type()) - - def test_tuple_assignment_for_lists(self): - self.mod.write('class C(object):\n pass\nl = [C(), C()]\na, b = l\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c_class, a_var.get_type()) - self.assertEquals(c_class, b_var.get_type()) - - def test_tuple_assignments_for_iteritems_in_fors(self): - self.mod.write('class C1(object):\n pass\nclass C2(object):\n pass\n' - 'd = {C1(): C2()}\nfor x, y in d.items():\n a = x;\n b = y\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_simple_tuple_assignments(self): - self.mod.write('class C1(object):\n pass\nclass C2(object):\n pass\n' - 'a, b = C1(), C2()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_overriding_builtin_names(self): - self.mod.write('class C(object):\n pass\nlist = C\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - list_var = pymod['list'].get_object() - self.assertEquals(c_class, list_var) - - def test_simple_builtin_scope_test(self): - self.mod.write('l = list()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertTrue('append' in pymod['l'].get_object()) - - def test_simple_sets(self): - self.mod.write('s = set()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertTrue('add' in pymod['s'].get_object()) - - def test_making_lists_using_the_passed_argument_to_init(self): - self.mod.write('class C(object):\n pass\nl1 = [C()]\n' - 'l2 = list(l1)\na_var = l2.pop()') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_making_tuples_using_the_passed_argument_to_init(self): - self.mod.write('class C(object):\n pass\nl1 = [C()]\n' - 'l2 = tuple(l1)\na_var = l2[0]') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_making_sets_using_the_passed_argument_to_init(self): - self.mod.write('class C(object):\n pass\nl1 = [C()]\n' - 'l2 = set(l1)\na_var = l2.pop()') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_making_dicts_using_the_passed_argument_to_init(self): - self.mod.write('class C1(object):\n pass\nclass C2(object):\n pass\n' - 'l1 = [(C1(), C2())]\n' - 'l2 = dict(l1)\na, b = l2.items()[0]') - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_range_builtin_function(self): - self.mod.write('l = range(1)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - l = pymod['l'].get_object() - self.assertTrue('append' in l) - - def test_reversed_builtin_function(self): - self.mod.write('class C(object):\n pass\nl = [C()]\n' - 'for x in reversed(l):\n a_var = x\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_sorted_builtin_function(self): - self.mod.write('class C(object):\n pass\nl = [C()]\n' - 'a_var = sorted(l).pop()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_super_builtin_function(self): - self.mod.write( - 'class C(object):\n pass\n' - 'class A(object):\n def a_f(self):\n return C()\n' - 'class B(A):\n def b_f(self):\n return super(B, self).a_f()\n' - 'a_var = B.b_f()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_file_builtin_type(self): - self.mod.write('for line in open("file.txt"):\n a_var = line\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - a_var = pymod['a_var'].get_object() - self.assertTrue(isinstance(a_var.get_type(), builtins.Str)) - - def test_property_builtin_type(self): - self.mod.write('p = property()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - p_var = pymod['p'].get_object() - self.assertTrue('fget' in p_var) - - def test_lambda_functions(self): - self.mod.write('l = lambda: 1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - l_var = pymod['l'].get_object() - self.assertEquals(pyobjects.get_base_type('Function'), - l_var.get_type()) - - def test_lambda_function_definition(self): - self.mod.write('l = lambda x, y = 2, *a, **b: x + y\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - l_var = pymod['l'].get_object() - self.assertTrue(l_var.get_name() is not None) - self.assertEquals(len(l_var.get_param_names()), 4) - self.assertEquals((pymod, 1), - pymod['l'].get_definition_location()) - - def test_lambdas_that_return_unknown(self): - self.mod.write('a_var = (lambda: None)()\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - a_var = pymod['a_var'].get_object() - self.assertTrue(a_var is not None) - - def test_builtin_zip_function(self): - self.mod.write( - 'class C1(object):\n pass\nclass C2(object):\n pass\n' - 'c1_list = [C1()]\nc2_list = [C2()]\n' - 'a, b = zip(c1_list, c2_list)[0]') - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_builtin_zip_function_with_more_than_two_args(self): - self.mod.write( - 'class C1(object):\n pass\nclass C2(object):\n pass\n' - 'c1_list = [C1()]\nc2_list = [C2()]\n' - 'a, b, c = zip(c1_list, c2_list, c1_list)[0]') - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - c2_class = pymod['C2'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - c_var = pymod['c'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - self.assertEquals(c1_class, c_var.get_type()) - - def test_wrong_arguments_to_zip_function(self): - self.mod.write( - 'class C1(object):\n pass\nc1_list = [C1()]\n' - 'a, b = zip(c1_list, 1)[0]') - pymod = self.pycore.resource_to_pyobject(self.mod) - c1_class = pymod['C1'].get_object() - a_var = pymod['a'].get_object() - b_var = pymod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - - def test_enumerate_builtin_function(self): - self.mod.write('class C(object):\n pass\nl = [C()]\n' - 'for i, x in enumerate(l):\n a_var = x\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_builtin_class_get_name(self): - self.assertEquals('object', - builtins.builtins['object'].get_object().get_name()) - self.assertEquals('property', - builtins.builtins['property'].get_object().get_name()) - - def test_star_args_and_double_star_args(self): - self.mod.write('def func(p, *args, **kwds):\n pass\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - func_scope = pymod['func'].get_object().get_scope() - args = func_scope['args'].get_object() - kwds = func_scope['kwds'].get_object() - self.assertTrue(isinstance(args.get_type(), builtins.List)) - self.assertTrue(isinstance(kwds.get_type(), builtins.Dict)) - - def test_simple_list_comprehension_test(self): - self.mod.write('a_var = [i for i in range(10)]\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - a_var = pymod['a_var'].get_object() - self.assertTrue(isinstance(a_var.get_type(), builtins.List)) - - def test_simple_list_generator_expression(self): - self.mod.write('a_var = (i for i in range(10))\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - a_var = pymod['a_var'].get_object() - self.assertTrue(isinstance(a_var.get_type(), builtins.Iterator)) - - def test_iter_builtin_function(self): - self.mod.write('class C(object):\n pass\nl = [C()]\n' - 'for c in iter(l):\n a_var = c\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - c_class = pymod['C'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_simple_int_type(self): - self.mod.write('l = 1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals(builtins.builtins['int'].get_object(), - pymod['l'].get_object().get_type()) - - def test_simple_float_type(self): - self.mod.write('l = 1.0\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals(builtins.builtins['float'].get_object(), - pymod['l'].get_object().get_type()) - - def test_simple_float_type2(self): - self.mod.write('l = 1e1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals(builtins.builtins['float'].get_object(), - pymod['l'].get_object().get_type()) - - def test_simple_complex_type(self): - self.mod.write('l = 1.0j\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals(builtins.builtins['complex'].get_object(), - pymod['l'].get_object().get_type()) - - def test_handling_unaryop_on_ints(self): - self.mod.write('l = -(1)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals(builtins.builtins['int'].get_object(), - pymod['l'].get_object().get_type()) - - def test_handling_binop_on_ints(self): - self.mod.write('l = 1 + 1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals(builtins.builtins['int'].get_object(), - pymod['l'].get_object().get_type()) - - def test_handling_compares(self): - self.mod.write('l = 1 == 1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals(builtins.builtins['bool'].get_object(), - pymod['l'].get_object().get_type()) - - def test_handling_boolops(self): - self.mod.write('l = 1 and 2\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals(builtins.builtins['int'].get_object(), - pymod['l'].get_object().get_type()) - - def test_binary_or_left_value_unknown(self): - code = 'var = (asdsd or 3)\n' - pymod = self.pycore.get_string_module(code) - self.assertEquals(builtins.builtins['int'].get_object(), - pymod['var'].get_object().get_type()) - - def test_unknown_return_object(self): - src = 'import sys\n' \ - 'def foo():\n' \ - ' res = set(sys.builtin_module_names)\n' \ - ' if foo: res.add(bar)\n' - self.project.prefs['import_dynload_stdmods'] = True - self.mod.write(src) - self.project.pycore.analyze_module(self.mod) - - -class BuiltinModulesTest(unittest.TestCase): - - def setUp(self): - super(BuiltinModulesTest, self).setUp() - self.project = testutils.sample_project( - extension_modules=['time', 'invalid', 'invalid.sub']) - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod') - - def tearDown(self): - testutils.remove_project(self.project) - super(BuiltinModulesTest, self).tearDown() - - def test_simple_case(self): - self.mod.write('import time') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertTrue('time' in pymod['time'].get_object()) - - def test_ignored_extensions(self): - self.mod.write('import os') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertTrue('rename' not in pymod['os'].get_object()) - - def test_ignored_extensions(self): - self.mod.write('import os') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertTrue('rename' not in pymod['os'].get_object()) - - def test_nonexistent_modules(self): - self.mod.write('import invalid') - pymod = self.pycore.resource_to_pyobject(self.mod) - pymod['invalid'].get_object() - - def test_nonexistent_modules(self): - self.mod.write('import invalid\nimport invalid.sub') - pymod = self.pycore.resource_to_pyobject(self.mod) - invalid = pymod['invalid'].get_object() - self.assertTrue('sub' in invalid) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(BuiltinTypesTest)) - result.addTests(unittest.makeSuite(BuiltinModulesTest)) - return result - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/codeanalyzetest.py --- a/vim/sadness/ropevim/src/rope/ropetest/codeanalyzetest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,616 +0,0 @@ -import unittest - -import rope.base.evaluate -from rope.base import exceptions, ast, worder, codeanalyze -from rope.base.codeanalyze import SourceLinesAdapter, LogicalLineFinder, get_block_start -from ropetest import testutils - - -class SourceLinesAdapterTest(unittest.TestCase): - - def setUp(self): - super(SourceLinesAdapterTest, self).setUp() - - def tearDown(self): - super(SourceLinesAdapterTest, self).tearDown() - - def test_source_lines_simple(self): - to_lines = SourceLinesAdapter('line1\nline2\n') - self.assertEquals('line1', to_lines.get_line(1)) - self.assertEquals('line2', to_lines.get_line(2)) - self.assertEquals('', to_lines.get_line(3)) - self.assertEquals(3, to_lines.length()) - - def test_source_lines_get_line_number(self): - to_lines = SourceLinesAdapter('line1\nline2\n') - self.assertEquals(1, to_lines.get_line_number(0)) - self.assertEquals(1, to_lines.get_line_number(5)) - self.assertEquals(2, to_lines.get_line_number(7)) - self.assertEquals(3, to_lines.get_line_number(12)) - - def test_source_lines_get_line_start(self): - to_lines = SourceLinesAdapter('line1\nline2\n') - self.assertEquals(0, to_lines.get_line_start(1)) - self.assertEquals(6, to_lines.get_line_start(2)) - self.assertEquals(12, to_lines.get_line_start(3)) - - def test_source_lines_get_line_end(self): - to_lines = SourceLinesAdapter('line1\nline2\n') - self.assertEquals(5, to_lines.get_line_end(1)) - self.assertEquals(11, to_lines.get_line_end(2)) - self.assertEquals(12, to_lines.get_line_end(3)) - - def test_source_lines_last_line_with_no_new_line(self): - to_lines = SourceLinesAdapter('line1') - self.assertEquals(1, to_lines.get_line_number(5)) - - -class WordRangeFinderTest(unittest.TestCase): - - def setUp(self): - super(WordRangeFinderTest, self).setUp() - - def tearDown(self): - super(WordRangeFinderTest, self).tearDown() - - def _find_primary(self, code, offset): - word_finder = worder.Worder(code) - result = word_finder.get_primary_at(offset) - return result - - def test_keyword_before_parens(self): - code = 'if (a_var).an_attr:\n pass\n' - self.assertEquals('(a_var).an_attr', - self._find_primary(code, code.index(':'))) - - def test_inside_parans(self): - code = 'a_func(a_var)' - self.assertEquals('a_var', self._find_primary(code, 10)) - - def test_simple_names(self): - code = 'a_var = 10' - self.assertEquals('a_var', self._find_primary(code, 3)) - - def test_function_calls(self): - code = 'sample_function()' - self.assertEquals('sample_function', self._find_primary(code, 10)) - - def test_attribute_accesses(self): - code = 'a_var.an_attr' - self.assertEquals('a_var.an_attr', self._find_primary(code, 10)) - - def test_word_finder_on_word_beginning(self): - code = 'print a_var\n' - word_finder = worder.Worder(code) - result = word_finder.get_word_at(code.index('a_var')) - self.assertEquals('a_var', result) - - def test_word_finder_on_primary_beginning(self): - code = 'print a_var\n' - result = self._find_primary(code, code.index('a_var')) - self.assertEquals('a_var', result) - - def test_word_finder_on_word_ending(self): - code = 'print a_var\n' - word_finder = worder.Worder(code) - result = word_finder.get_word_at(code.index('a_var') + 5) - self.assertEquals('a_var', result) - - def test_word_finder_on_primary_ending(self): - code = 'print a_var\n' - result = self._find_primary(code, code.index('a_var') + 5) - self.assertEquals('a_var', result) - - def test_word_finder_on_primaries_with_dots_inside_parens(self): - code = '(a_var.\nattr)' - result = self._find_primary(code, code.index('attr') + 1) - self.assertEquals('a_var.\nattr', result) - - def test_strings(self): - code = '"a string".split()' - self.assertEquals('"a string".split', self._find_primary(code, 14)) - - def test_function_calls2(self): - code = 'file("afile.txt").read()' - self.assertEquals('file("afile.txt").read', self._find_primary(code, 18)) - - def test_parens(self): - code = '("afile.txt").split()' - self.assertEquals('("afile.txt").split', self._find_primary(code, 18)) - - def test_function_with_no_param(self): - code = 'AClass().a_func()' - self.assertEquals('AClass().a_func', self._find_primary(code, 12)) - - def test_function_with_multiple_param(self): - code = 'AClass(a_param, another_param, "a string").a_func()' - self.assertEquals('AClass(a_param, another_param, "a string").a_func', - self._find_primary(code, 44)) - - def test_param_expressions(self): - code = 'AClass(an_object.an_attr).a_func()' - self.assertEquals('an_object.an_attr', self._find_primary(code, 20)) - - def test_string_parens(self): - code = 'a_func("(").an_attr' - self.assertEquals('a_func("(").an_attr', self._find_primary(code, 16)) - - def test_extra_spaces(self): - code = 'a_func ( "(" ) . an_attr' - self.assertEquals('a_func ( "(" ) . an_attr', - self._find_primary(code, 26)) - - def test_functions_on_ending_parens(self): - code = 'A()' - self.assertEquals('A()', self._find_primary(code, 2)) - - def test_splitted_statement(self): - word_finder = worder.Worder('an_object.an_attr') - self.assertEquals(('an_object', 'an_at', 10), - word_finder.get_splitted_primary_before(15)) - - def test_empty_splitted_statement(self): - word_finder = worder.Worder('an_attr') - self.assertEquals(('', 'an_at', 0), - word_finder.get_splitted_primary_before(5)) - - def test_empty_splitted_statement2(self): - word_finder = worder.Worder('an_object.') - self.assertEquals(('an_object', '', 10), - word_finder.get_splitted_primary_before(10)) - - def test_empty_splitted_statement3(self): - word_finder = worder.Worder('') - self.assertEquals(('', '', 0), - word_finder.get_splitted_primary_before(0)) - - def test_empty_splitted_statement4(self): - word_finder = worder.Worder('a_var = ') - self.assertEquals(('', '', 8), - word_finder.get_splitted_primary_before(8)) - - def test_empty_splitted_statement5(self): - word_finder = worder.Worder('a.') - self.assertEquals(('a', '', 2), - word_finder.get_splitted_primary_before(2)) - - def test_operators_inside_parens(self): - code = '(a_var + another_var).reverse()' - self.assertEquals('(a_var + another_var).reverse', - self._find_primary(code, 25)) - - def test_dictionaries(self): - code = 'print {1: "one", 2: "two"}.keys()' - self.assertEquals('{1: "one", 2: "two"}.keys', - self._find_primary(code, 29)) - - def test_following_parens(self): - code = 'a_var = a_func()()' - result = self._find_primary(code, code.index(')(') + 3) - self.assertEquals('a_func()()', result) - - def test_comments_for_finding_statements(self): - code = '# var2 . \n var3' - self.assertEquals('var3', self._find_primary(code, code.index('3'))) - - def test_str_in_comments_for_finding_statements(self): - code = '# "var2" . \n var3' - self.assertEquals('var3', self._find_primary(code, code.index('3'))) - - def test_comments_for_finding_statements2(self): - code = 'var1 + "# var2".\n var3' - self.assertEquals('var3', self._find_primary(code, 21)) - - def test_comments_for_finding_statements3(self): - code = '"" + # var2.\n var3' - self.assertEquals('var3', self._find_primary(code, 21)) - - def test_import_statement_finding(self): - code = 'import mod\na_var = 10\n' - word_finder = worder.Worder(code) - self.assertTrue(word_finder.is_import_statement(code.index('mod') + 1)) - self.assertFalse(word_finder.is_import_statement(code.index('a_var') + 1)) - - def test_import_statement_finding2(self): - code = 'import a.b.c.d\nresult = a.b.c.d.f()\n' - word_finder = worder.Worder(code) - self.assertFalse(word_finder.is_import_statement(code.rindex('d') + 1)) - - def test_word_parens_range(self): - code = 's = str()\ns.title()\n' - word_finder = worder.Worder(code) - result = word_finder.get_word_parens_range(code.rindex('()') - 1) - self.assertEquals((len(code) - 3, len(code) - 1), result) - - def test_getting_primary_before_get_index(self): - code = '\na = (b + c).d[0]()\n' - result = self._find_primary(code, len(code) - 2) - self.assertEquals('(b + c).d[0]()', result) - - def test_getting_primary_and_strings_at_the_end_of_line(self): - code = 'f(\'\\\'\')\n' - result = self._find_primary(code, len(code) - 1) - - def test_getting_primary_and_not_crossing_newlines(self): - code = '\na = (b + c)\n(4 + 1).x\n' - result = self._find_primary(code, len(code) - 1) - self.assertEquals('(4 + 1).x', result) - - # XXX: cancatenated string literals - def xxx_test_getting_primary_cancatenating_strs(self): - code = 's = "a"\n"b" "c"\n' - result = self._find_primary(code, len(code) - 2) - self.assertEquals('"b" "c"', result) - - def test_is_a_function_being_called_with_parens_on_next_line(self): - code = 'func\n(1, 2)\n' - word_finder = worder.Worder(code) - self.assertFalse(word_finder.is_a_function_being_called(1)) - - # XXX: handling triple quotes - def xxx_test_triple_quotes(self): - code = 's = """string"""\n' - result = self._find_primary(code, len(code) - 1) - self.assertEquals('"""string"""', result) - - def test_triple_quotes_spanning_multiple_lines(self): - code = 's = """\\\nl1\nl2\n """\n' - result = self._find_primary(code, len(code) - 2) - self.assertEquals('"""\\\nl1\nl2\n """', result) - - def test_get_word_parens_range_and_string_literals(self): - code = 'f(1, ")", 2)\n' - word_finder = worder.Worder(code) - result = word_finder.get_word_parens_range(0) - self.assertEquals((1, len(code) - 1), result) - - def test_is_assigned_here_for_equality_test(self): - code = 'a == 1\n' - word_finder = worder.Worder(code) - self.assertFalse(word_finder.is_assigned_here(0)) - - def test_is_assigned_here_for_not_equal_test(self): - code = 'a != 1\n' - word_finder = worder.Worder(code) - self.assertFalse(word_finder.is_assigned_here(0)) - - # XXX: is_assigned_here should work for tuple assignments - def xxx_test_is_assigned_here_for_tuple_assignment(self): - code = 'a, b = (1, 2)\n' - word_finder = worder.Worder(code) - self.assertTrue(word_finder.is_assigned_here(0)) - - def test_is_from_with_from_import_and_multiline_parens(self): - code = 'from mod import \\\n (f,\n g, h)\n' - word_finder = worder.Worder(code) - self.assertTrue(word_finder.is_from_statement(code.rindex('g'))) - - def test_is_from_with_from_import_and_line_breaks_in_the_middle(self): - code = 'from mod import f,\\\n g\n' - word_finder = worder.Worder(code) - self.assertTrue(word_finder.is_from_statement(code.rindex('g'))) - - def test_one_letter_function_keyword_arguments(self): - code = 'f(p=1)\n' - word_finder = worder.Worder(code) - index = code.rindex('p') - self.assertTrue(word_finder.is_function_keyword_parameter(index)) - - def test_find_parens_start(self): - code = 'f(p)\n' - finder = worder.Worder(code) - self.assertEquals(1, finder.find_parens_start_from_inside(2)) - - def test_underlined_find_parens_start(self): - code = 'f(p="")\n' - finder = worder.Worder(code) - self.assertEquals(1, finder._find_parens_start(len(code) - 2)) - - def test_find_parens_start_with_multiple_entries(self): - code = 'myfunc(p1, p2, p3\n' - finder = worder.Worder(code) - self.assertEquals(code.index('('), - finder.find_parens_start_from_inside(len(code) - 1)) - - def test_find_parens_start_with_nested_parens(self): - code = 'myfunc(p1, (p2, p3), p4\n' - finder = worder.Worder(code) - self.assertEquals(code.index('('), - finder.find_parens_start_from_inside(len(code) - 1)) - - def test_find_parens_start_with_parens_in_strs(self): - code = 'myfunc(p1, "(", p4\n' - finder = worder.Worder(code) - self.assertEquals(code.index('('), - finder.find_parens_start_from_inside(len(code) - 1)) - - def test_find_parens_start_with_parens_in_strs_in_multiple_lines(self): - code = 'myfunc (\np1\n , \n "(" \n, \np4\n' - finder = worder.Worder(code) - self.assertEquals(code.index('('), - finder.find_parens_start_from_inside(len(code) - 1)) - - def test_is_on_function_keyword(self): - code = 'myfunc(va' - finder = worder.Worder(code) - self.assertTrue(finder.is_on_function_call_keyword(len(code) - 1)) - - -class ScopeNameFinderTest(unittest.TestCase): - - def setUp(self): - super(ScopeNameFinderTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - - def tearDown(self): - testutils.remove_project(self.project) - super(ScopeNameFinderTest, self).tearDown() - - # FIXME: in normal scopes the interpreter raises `UnboundLocalName` - # exception, but not in class bodies - def xxx_test_global_name_in_class_body(self): - code = 'a_var = 10\nclass C(object):\n a_var = a_var\n' - scope = self.pycore.get_string_scope(code) - name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) - result = name_finder.get_pyname_at(len(code) - 3) - self.assertEquals(scope['a_var'], result) - - def test_class_variable_attribute_in_class_body(self): - code = 'a_var = 10\nclass C(object):\n a_var = a_var\n' - scope = self.pycore.get_string_scope(code) - name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) - a_var_pyname = scope['C'].get_object()['a_var'] - result = name_finder.get_pyname_at(len(code) - 12) - self.assertEquals(a_var_pyname, result) - - def test_class_variable_attribute_in_class_body2(self): - code = 'a_var = 10\nclass C(object):\n a_var \\\n= a_var\n' - scope = self.pycore.get_string_scope(code) - name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) - a_var_pyname = scope['C'].get_object()['a_var'] - result = name_finder.get_pyname_at(len(code) - 12) - self.assertEquals(a_var_pyname, result) - - def test_class_method_attribute_in_class_body(self): - code = 'class C(object):\n def a_method(self):\n pass\n' - scope = self.pycore.get_string_scope(code) - name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) - a_method_pyname = scope['C'].get_object()['a_method'] - result = name_finder.get_pyname_at(code.index('a_method') + 2) - self.assertEquals(a_method_pyname, result) - - def test_inner_class_attribute_in_class_body(self): - code = 'class C(object):\n class CC(object):\n pass\n' - scope = self.pycore.get_string_scope(code) - name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) - a_class_pyname = scope['C'].get_object()['CC'] - result = name_finder.get_pyname_at(code.index('CC') + 2) - self.assertEquals(a_class_pyname, result) - - def test_class_method_in_class_body_but_not_indexed(self): - code = 'class C(object):\n def func(self, func):\n pass\n' - scope = self.pycore.get_string_scope(code) - a_func_pyname = scope.get_scopes()[0].get_scopes()[0]['func'] - name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) - result = name_finder.get_pyname_at(code.index(', func') + 3) - self.assertEquals(a_func_pyname, result) - - def test_function_but_not_indexed(self): - code = 'def a_func(a_func):\n pass\n' - scope = self.pycore.get_string_scope(code) - a_func_pyname = scope['a_func'] - name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) - result = name_finder.get_pyname_at(code.index('a_func') + 3) - self.assertEquals(a_func_pyname, result) - - def test_modules_after_from_statements(self): - root_folder = self.project.root - mod = testutils.create_module(self.project, 'mod', root_folder) - mod.write('def a_func():\n pass\n') - code = 'from mod import a_func\n' - scope = self.pycore.get_string_scope(code) - name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) - mod_pyobject = self.pycore.resource_to_pyobject(mod) - found_pyname = name_finder.get_pyname_at(code.index('mod') + 1) - self.assertEquals(mod_pyobject, found_pyname.get_object()) - - def test_renaming_functions_with_from_import_and_parens(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('def afunc():\n pass\n') - code = 'from mod1 import (\n afunc as func)\n' - scope = self.pycore.get_string_scope(code) - name_finder = rope.base.evaluate.ScopeNameFinder(scope.pyobject) - mod_pyobject = self.pycore.resource_to_pyobject(mod1) - afunc = mod_pyobject['afunc'] - found_pyname = name_finder.get_pyname_at(code.index('afunc') + 1) - self.assertEquals(afunc.get_object(), found_pyname.get_object()) - - @testutils.run_only_for_25 - def test_relative_modules_after_from_statements(self): - pkg1 = testutils.create_package(self.project, 'pkg1') - pkg2 = testutils.create_package(self.project, 'pkg2', pkg1) - mod1 = testutils.create_module(self.project, 'mod1', pkg1) - mod2 = testutils.create_module(self.project, 'mod2', pkg2) - mod1.write('def a_func():\n pass\n') - code = 'from ..mod1 import a_func\n' - mod2.write(code) - mod2_scope = self.pycore.resource_to_pyobject(mod2).get_scope() - name_finder = rope.base.evaluate.ScopeNameFinder(mod2_scope.pyobject) - mod1_pyobject = self.pycore.resource_to_pyobject(mod1) - found_pyname = name_finder.get_pyname_at(code.index('mod1') + 1) - self.assertEquals(mod1_pyobject, found_pyname.get_object()) - - def test_relative_modules_after_from_statements2(self): - mod1 = testutils.create_module(self.project, 'mod1') - pkg1 = testutils.create_package(self.project, 'pkg1') - pkg2 = testutils.create_package(self.project, 'pkg2', pkg1) - mod2 = testutils.create_module(self.project, 'mod2', pkg2) - mod1.write('import pkg1.pkg2.mod2') - - mod1_scope = self.pycore.resource_to_pyobject(mod1).get_scope() - name_finder = rope.base.evaluate.ScopeNameFinder(mod1_scope.pyobject) - pkg2_pyobject = self.pycore.resource_to_pyobject(pkg2) - found_pyname = name_finder.get_pyname_at(mod1.read().index('pkg2') + 1) - self.assertEquals(pkg2_pyobject, found_pyname.get_object()) - - @testutils.assert_raises(exceptions.RopeError) - def test_get_pyname_at_on_language_keywords(self): - code = 'def a_func(a_func):\n pass\n' - pymod = self.pycore.get_string_module(code) - name_finder = rope.base.evaluate.ScopeNameFinder(pymod) - name_finder.get_pyname_at(code.index('pass')) - - def test_one_liners(self): - code = 'var = 1\ndef f(): var = 2\nprint var\n' - pymod = self.pycore.get_string_module(code) - name_finder = rope.base.evaluate.ScopeNameFinder(pymod) - pyname = name_finder.get_pyname_at(code.rindex('var')) - self.assertEquals(pymod['var'], pyname) - - def test_one_liners_with_line_breaks(self): - code = 'var = 1\ndef f(\n): var = 2\nprint var\n' - pymod = self.pycore.get_string_module(code) - name_finder = rope.base.evaluate.ScopeNameFinder(pymod) - pyname = name_finder.get_pyname_at(code.rindex('var')) - self.assertEquals(pymod['var'], pyname) - - def test_one_liners_with_line_breaks2(self): - code = 'var = 1\ndef f(\np): var = 2\nprint var\n' - pymod = self.pycore.get_string_module(code) - name_finder = rope.base.evaluate.ScopeNameFinder(pymod) - pyname = name_finder.get_pyname_at(code.rindex('var')) - self.assertEquals(pymod['var'], pyname) - - -class LogicalLineFinderTest(unittest.TestCase): - - def setUp(self): - super(LogicalLineFinderTest, self).setUp() - - def tearDown(self): - super(LogicalLineFinderTest, self).tearDown() - - def _logical_finder(self, code): - return LogicalLineFinder(SourceLinesAdapter(code)) - - def test_normal_lines(self): - code = 'a_var = 10' - line_finder = self._logical_finder(code) - self.assertEquals((1, 1), line_finder.logical_line_in(1)) - - def test_normal_lines2(self): - code = 'another = 10\na_var = 20\n' - line_finder = self._logical_finder(code) - self.assertEquals((1, 1), line_finder.logical_line_in(1)) - self.assertEquals((2, 2), line_finder.logical_line_in(2)) - - def test_implicit_continuation(self): - code = 'a_var = 3 + \\\n 4 + \\\n 5' - line_finder = self._logical_finder(code) - self.assertEquals((1, 3), line_finder.logical_line_in(2)) - - def test_explicit_continuation(self): - code = 'print 2\na_var = (3 + \n 4, \n 5)\n' - line_finder = self._logical_finder(code) - self.assertEquals((2, 4), line_finder.logical_line_in(2)) - - def test_explicit_continuation_comments(self): - code = '#\na_var = 3\n' - line_finder = self._logical_finder(code) - self.assertEquals((2, 2), line_finder.logical_line_in(2)) - - def test_multiple_indented_ifs(self): - code = 'if True:\n if True:\n if True:\n pass\n a = 10\n' - line_finder = self._logical_finder(code) - self.assertEquals((5, 5), line_finder.logical_line_in(5)) - - def test_list_comprehensions_and_fors(self): - code = 'a_list = [i\n for i in range(10)]\n' - line_finder = self._logical_finder(code) - self.assertEquals((1, 2), line_finder.logical_line_in(2)) - - def test_generator_expressions_and_fors(self): - code = 'a_list = (i\n for i in range(10))\n' - line_finder = self._logical_finder(code) - self.assertEquals((1, 2), line_finder.logical_line_in(2)) - - def test_fors_and_block_start(self): - code = 'l = range(10)\nfor i in l:\n print i\n' - self.assertEquals(2, get_block_start(SourceLinesAdapter(code), 2)) - - def test_problems_with_inner_indentations(self): - code = 'if True:\n if True:\n if True:\n pass\n' \ - ' a = \\\n 1\n' - line_finder = self._logical_finder(code) - self.assertEquals((5, 6), line_finder.logical_line_in(6)) - - def test_problems_with_inner_indentations2(self): - code = 'if True:\n if True:\n pass\n' \ - 'a = 1\n' - line_finder = self._logical_finder(code) - self.assertEquals((4, 4), line_finder.logical_line_in(4)) - - def test_logical_lines_for_else(self): - code = 'if True:\n pass\nelse:\n pass\n' - line_finder = self._logical_finder(code) - self.assertEquals((3, 3), line_finder.logical_line_in(3)) - - def test_logical_lines_for_lines_with_wrong_continues(self): - code = 'var = 1 + \\' - line_finder = self._logical_finder(code) - self.assertEquals((1, 1), line_finder.logical_line_in(1)) - - def test_generating_line_starts(self): - code = 'a = 1\na = 2\n\na = 3\n' - line_finder = self._logical_finder(code) - self.assertEquals([1, 2, 4], list(line_finder.generate_starts())) - - def test_generating_line_starts2(self): - code = 'a = 1\na = 2\n\na = \\ 3\n' - line_finder = LogicalLineFinder(SourceLinesAdapter(code)) - self.assertEquals([2, 4], list(line_finder.generate_starts(2))) - - def test_generating_line_starts3(self): - code = 'a = 1\na = 2\n\na = \\ 3\n' - line_finder = LogicalLineFinder(SourceLinesAdapter(code)) - self.assertEquals([2], list(line_finder.generate_starts(2, 3))) - - def test_generating_line_starts_for_multi_line_statements(self): - code = '\na = \\\n 1 + \\\n 1\n' - line_finder = self._logical_finder(code) - self.assertEquals([2], list(line_finder.generate_starts())) - - def test_generating_line_starts_and_unmatched_deindents(self): - code = 'if True:\n if True:\n if True:\n' \ - ' a = 1\n b = 1\n' - line_finder = self._logical_finder(code) - self.assertEquals([4, 5], list(line_finder.generate_starts(4))) - -class TokenizerLogicalLineFinderTest(LogicalLineFinderTest): - - def _logical_finder(self, code): - lines = SourceLinesAdapter(code) - return codeanalyze.CachingLogicalLineFinder( - lines, codeanalyze.tokenizer_generator) - -class CustomLogicalLineFinderTest(LogicalLineFinderTest): - - def _logical_finder(self, code): - lines = SourceLinesAdapter(code) - return codeanalyze.CachingLogicalLineFinder( - lines, codeanalyze.custom_generator) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(SourceLinesAdapterTest)) - result.addTests(unittest.makeSuite(WordRangeFinderTest)) - result.addTests(unittest.makeSuite(ScopeNameFinderTest)) - result.addTests(unittest.makeSuite(LogicalLineFinderTest)) - result.addTests(unittest.makeSuite(TokenizerLogicalLineFinderTest)) - result.addTests(unittest.makeSuite(CustomLogicalLineFinderTest)) - return result - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/contrib/__init__.py --- a/vim/sadness/ropevim/src/rope/ropetest/contrib/__init__.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -import sys -import unittest - -import ropetest.contrib.autoimporttest -import ropetest.contrib.changestacktest -import ropetest.contrib.codeassisttest -import ropetest.contrib.finderrorstest -import ropetest.contrib.findittest -import ropetest.contrib.fixmodnamestest -import ropetest.contrib.generatetest - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(ropetest.contrib.generatetest. - GenerateTest)) - result.addTests(ropetest.contrib.codeassisttest.suite()) - result.addTests(ropetest.contrib.autoimporttest.suite()) - result.addTests(ropetest.contrib.findittest.suite()) - result.addTests(unittest.makeSuite(ropetest.contrib.changestacktest. - ChangeStackTest)) - result.addTests(unittest.makeSuite(ropetest.contrib.fixmodnamestest. - FixModuleNamesTest)) - result.addTests(unittest.makeSuite(ropetest.contrib.finderrorstest. - FindErrorsTest)) - return result - - -if __name__ == '__main__': - runner = unittest.TextTestRunner() - result = runner.run(suite()) - sys.exit(not result.wasSuccessful()) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/contrib/autoimporttest.py --- a/vim/sadness/ropevim/src/rope/ropetest/contrib/autoimporttest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,166 +0,0 @@ -import unittest - -from ropetest import testutils -from rope.contrib import autoimport - - -class AutoImportTest(unittest.TestCase): - - def setUp(self): - super(AutoImportTest, self).setUp() - self.project = testutils.sample_project(extension_modules=['sys']) - self.mod1 = testutils.create_module(self.project, 'mod1') - self.pkg = testutils.create_package(self.project, 'pkg') - self.mod2 = testutils.create_module(self.project, 'mod2', self.pkg) - self.importer = autoimport.AutoImport(self.project, observe=False) - - def tearDown(self): - testutils.remove_project(self.project) - super(AutoImportTest, self).tearDown() - - def test_simple_case(self): - self.assertEquals([], self.importer.import_assist('A')) - - def test_update_resource(self): - self.mod1.write('myvar = None\n') - self.importer.update_resource(self.mod1) - self.assertEquals([('myvar', 'mod1')], - self.importer.import_assist('myva')) - - def test_update_module(self): - self.mod1.write('myvar = None') - self.importer.update_module('mod1') - self.assertEquals([('myvar', 'mod1')], - self.importer.import_assist('myva')) - - def test_update_non_existent_module(self): - self.importer.update_module('does_not_exists_this') - self.assertEquals([], self.importer.import_assist('myva')) - - def test_module_with_syntax_errors(self): - self.mod1.write('this is a syntax error\n') - self.importer.update_resource(self.mod1) - self.assertEquals([], self.importer.import_assist('myva')) - - def test_excluding_imported_names(self): - self.mod1.write('import pkg\n') - self.importer.update_resource(self.mod1) - self.assertEquals([], self.importer.import_assist('pkg')) - - def test_get_modules(self): - self.mod1.write('myvar = None\n') - self.importer.update_resource(self.mod1) - self.assertEquals(['mod1'], self.importer.get_modules('myvar')) - - def test_get_modules_inside_packages(self): - self.mod1.write('myvar = None\n') - self.mod2.write('myvar = None\n') - self.importer.update_resource(self.mod1) - self.importer.update_resource(self.mod2) - self.assertEquals(set(['mod1', 'pkg.mod2']), - set(self.importer.get_modules('myvar'))) - - def test_trivial_insertion_line(self): - result = self.importer.find_insertion_line('') - self.assertEquals(1, result) - - def test_insertion_line(self): - result = self.importer.find_insertion_line('import mod\n') - self.assertEquals(2, result) - - def test_insertion_line_with_pydocs(self): - result = self.importer.find_insertion_line( - '"""docs\n\ndocs"""\nimport mod\n') - self.assertEquals(5, result) - - def test_insertion_line_with_multiple_imports(self): - result = self.importer.find_insertion_line( - 'import mod1\n\nimport mod2\n') - self.assertEquals(4, result) - - def test_insertion_line_with_blank_lines(self): - result = self.importer.find_insertion_line( - 'import mod1\n\n# comment\n') - self.assertEquals(2, result) - - def test_empty_cache(self): - self.mod1.write('myvar = None\n') - self.importer.update_resource(self.mod1) - self.assertEquals(['mod1'], self.importer.get_modules('myvar')) - self.importer.clear_cache() - self.assertEquals([], self.importer.get_modules('myvar')) - - def test_not_caching_underlined_names(self): - self.mod1.write('_myvar = None\n') - self.importer.update_resource(self.mod1, underlined=False) - self.assertEquals([], self.importer.get_modules('_myvar')) - self.importer.update_resource(self.mod1, underlined=True) - self.assertEquals(['mod1'], self.importer.get_modules('_myvar')) - - def test_caching_underlined_names_passing_to_the_constructor(self): - importer = autoimport.AutoImport(self.project, False, True) - self.mod1.write('_myvar = None\n') - importer.update_resource(self.mod1) - self.assertEquals(['mod1'], importer.get_modules('_myvar')) - - def test_name_locations(self): - self.mod1.write('myvar = None\n') - self.importer.update_resource(self.mod1) - self.assertEquals([(self.mod1, 1)], - self.importer.get_name_locations('myvar')) - - def test_name_locations_with_multiple_occurrences(self): - self.mod1.write('myvar = None\n') - self.mod2.write('\nmyvar = None\n') - self.importer.update_resource(self.mod1) - self.importer.update_resource(self.mod2) - self.assertEquals(set([(self.mod1, 1), (self.mod2, 2)]), - set(self.importer.get_name_locations('myvar'))) - - def test_handling_builtin_modules(self): - self.importer.update_module('sys') - self.assertTrue('sys' in self.importer.get_modules('exit')) - - def test_submodules(self): - self.assertEquals(set([self.mod1]), - autoimport.submodules(self.mod1)) - self.assertEquals(set([self.mod2, self.pkg]), - autoimport.submodules(self.pkg)) - -class AutoImportObservingTest(unittest.TestCase): - - def setUp(self): - super(AutoImportObservingTest, self).setUp() - self.project = testutils.sample_project() - self.mod1 = testutils.create_module(self.project, 'mod1') - self.pkg = testutils.create_package(self.project, 'pkg') - self.mod2 = testutils.create_module(self.project, 'mod2', self.pkg) - self.importer = autoimport.AutoImport(self.project, observe=True) - - def tearDown(self): - testutils.remove_project(self.project) - super(AutoImportObservingTest, self).tearDown() - - def test_writing_files(self): - self.mod1.write('myvar = None\n') - self.assertEquals(['mod1'], self.importer.get_modules('myvar')) - - def test_moving_files(self): - self.mod1.write('myvar = None\n') - self.mod1.move('mod3.py') - self.assertEquals(['mod3'], self.importer.get_modules('myvar')) - - def test_removing_files(self): - self.mod1.write('myvar = None\n') - self.mod1.remove() - self.assertEquals([], self.importer.get_modules('myvar')) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(AutoImportTest)) - result.addTests(unittest.makeSuite(AutoImportObservingTest)) - return result - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/contrib/changestacktest.py --- a/vim/sadness/ropevim/src/rope/ropetest/contrib/changestacktest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -import unittest - -import rope.base.history -import rope.contrib.changestack -from rope.base.change import * -from ropetest import testutils - - -class ChangeStackTest(unittest.TestCase): - - def setUp(self): - super(ChangeStackTest, self).setUp() - self.project = testutils.sample_project() - - def tearDown(self): - testutils.remove_project(self.project) - super(ChangeStackTest, self).tearDown() - - def test_change_stack(self): - myfile = self.project.root.create_file('myfile.txt') - myfile.write('1') - stack = rope.contrib.changestack.ChangeStack(self.project) - stack.push(ChangeContents(myfile, '2')) - self.assertEquals('2', myfile.read()) - stack.push(ChangeContents(myfile, '3')) - self.assertEquals('3', myfile.read()) - stack.pop_all() - self.assertEquals('1', myfile.read()) - changes = stack.merged() - self.project.do(changes) - self.assertEquals('3', myfile.read()) - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/contrib/codeassisttest.py --- a/vim/sadness/ropevim/src/rope/ropetest/contrib/codeassisttest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1065 +0,0 @@ -# coding: utf-8 -import unittest - -from rope.base import exceptions -from rope.contrib.codeassist import (get_definition_location, get_doc, - starting_expression, code_assist, - sorted_proposals, starting_offset, - get_calltip) -from ropetest import testutils - - -class CodeAssistTest(unittest.TestCase): - - def setUp(self): - super(CodeAssistTest, self).setUp() - self.project = testutils.sample_project() - - def tearDown(self): - testutils.remove_project(self.project) - super(CodeAssistTest, self).tearDown() - - def _assist(self, code, offset=None, **args): - if offset is None: - offset = len(code) - return code_assist(self.project, code, offset, **args) - - def test_simple_assist(self): - self._assist('', 0) - - def assert_completion_in_result(self, name, scope, result, type=None): - for proposal in result: - if proposal.name == name: - self.assertEqual(scope, proposal.scope, - "proposal <%s> has wrong scope, expected " \ - "%r, got %r" % (name, scope, proposal.scope)) - if type is not None: - self.assertEqual(type, proposal.type, - "proposal <%s> has wrong type, expected " \ - "%r, got %r" % (name, type, proposal.type)) - return - self.fail('completion <%s> not proposed' % name) - - def assert_completion_not_in_result(self, name, scope, result): - for proposal in result: - if proposal.name == name and proposal.scope == scope: - self.fail('completion <%s> was proposed' % name) - - def test_completing_global_variables(self): - code = 'my_global = 10\nt = my' - result = self._assist(code) - self.assert_completion_in_result('my_global', 'global', result) - - def test_not_proposing_unmatched_vars(self): - code = 'my_global = 10\nt = you' - result = self._assist(code) - self.assert_completion_not_in_result('my_global', 'global', result) - - def test_not_proposing_unmatched_vars_with_underlined_starting(self): - code = 'my_global = 10\nt = your_' - result = self._assist(code) - self.assert_completion_not_in_result('my_global', 'global', result) - - def test_not_proposing_local_assigns_as_global_completions(self): - code = 'def f(): my_global = 10\nt = my_' - result = self._assist(code) - self.assert_completion_not_in_result('my_global', 'global', result) - - def test_proposing_functions(self): - code = 'def my_func(): return 2\nt = my_' - result = self._assist(code) - self.assert_completion_in_result('my_func', 'global', result) - - def test_proposing_classes(self): - code = 'class Sample(object): pass\nt = Sam' - result = self._assist(code) - self.assert_completion_in_result('Sample', 'global', result) - - def test_proposing_each_name_at_most_once(self): - code = 'variable = 10\nvariable = 20\nt = vari' - result = self._assist(code) - count = len([x for x in result - if x.name == 'variable' and x.scope == 'global']) - self.assertEquals(1, count) - - @testutils.assert_raises(exceptions.ModuleSyntaxError) - def test_throwing_exception_in_case_of_syntax_errors(self): - code = 'sample (sdf+)\n' - self._assist(code, maxfixes=0) - - def test_fixing_errors_with_maxfixes(self): - code = 'def f():\n sldj sldj\ndef g():\n ran' - result = self._assist(code, maxfixes=2) - self.assertTrue(len(result) > 0) - - def test_ignoring_errors_in_current_line(self): - code = 'def my_func():\n return 2\nt = ' - result = self._assist(code) - self.assert_completion_in_result('my_func', 'global', result) - - def test_not_reporting_variables_in_current_line(self): - code = 'def my_func(): return 2\nt = my_' - result = self._assist(code) - self.assert_completion_not_in_result('my_', 'global', result) - - def test_completion_result(self): - code = 'my_global = 10\nt = my' - self.assertEquals(len(code) - 2, starting_offset(code, len(code))) - - def test_completing_imported_names(self): - code = 'import sys\na = sy' - result = self._assist(code) - self.assert_completion_in_result('sys', 'imported', result) - - def test_completing_imported_names_with_as(self): - code = 'import sys as mysys\na = mys' - result = self._assist(code) - self.assert_completion_in_result('mysys', 'imported', result) - - def test_not_completing_imported_names_with_as(self): - code = 'import sys as mysys\na = sy' - result = self._assist(code) - self.assert_completion_not_in_result('sys', 'global', result) - - def test_including_matching_builtins_types(self): - code = 'my_var = Excep' - result = self._assist(code) - self.assert_completion_in_result('Exception', 'builtin', result) - self.assert_completion_not_in_result('zip', 'builtin', result) - - def test_including_matching_builtins_functions(self): - code = 'my_var = zi' - result = self._assist(code) - self.assert_completion_in_result('zip', 'builtin', result) - - def test_builtin_instances(self): - # ``import_dynload_stdmods`` pref is disabled for test project. - # we need to have it enabled to make pycore._find_module() - # load ``sys`` module. - self.project.prefs['import_dynload_stdmods'] = True - code = 'from sys import stdout\nstdout.wr' - result = self._assist(code) - self.assert_completion_in_result('write', 'builtin', result) - self.assert_completion_in_result('writelines', 'builtin', result) - - def test_including_keywords(self): - code = 'fo' - result = self._assist(code) - self.assert_completion_in_result('for', 'keyword', result) - - def test_not_reporting_proposals_after_dot(self): - code = 'a_dict = {}\nkey = 3\na_dict.ke' - result = self._assist(code) - self.assert_completion_not_in_result('key', 'global', result) - - def test_proposing_local_variables_in_functions(self): - code = 'def f(self):\n my_var = 10\n my_' - result = self._assist(code) - self.assert_completion_in_result('my_var', 'local', result) - - def test_local_variables_override_global_ones(self): - code = 'my_var = 20\ndef f(self):\n my_var = 10\n my_' - result = self._assist(code) - self.assert_completion_in_result('my_var', 'local', result) - - def test_not_including_class_body_variables(self): - code = 'class C(object):\n my_var = 20\n' \ - ' def f(self):\n a = 20\n my_' - result = self._assist(code) - self.assert_completion_not_in_result('my_var', 'local', result) - - def test_nested_functions(self): - code = 'def my_func():\n func_var = 20\n ' \ - 'def inner_func():\n a = 20\n func' - result = self._assist(code) - self.assert_completion_in_result('func_var', 'local', result) - - def test_scope_endpoint_selection(self): - code = "def my_func():\n func_var = 20\n" - result = self._assist(code) - self.assert_completion_not_in_result('func_var', 'local', result) - - def test_scope_better_endpoint_selection(self): - code = "if True:\n def f():\n my_var = 10\n my_" - result = self._assist(code) - self.assert_completion_not_in_result('my_var', 'local', result) - - def test_imports_inside_function(self): - code = "def f():\n import sys\n sy" - result = self._assist(code) - self.assert_completion_in_result('sys', 'imported', result) - - def test_imports_inside_function_dont_mix_with_globals(self): - code = "def f():\n import sys\nsy" - result = self._assist(code) - self.assert_completion_not_in_result('sys', 'local', result) - - def test_nested_classes_local_names(self): - code = 'global_var = 10\n' \ - 'def my_func():\n' \ - ' func_var = 20\n' \ - ' class C(object):\n' \ - ' def another_func(self):\n' \ - ' local_var = 10\n' \ - ' func' - result = self._assist(code) - self.assert_completion_in_result('func_var', 'local', result) - - def test_nested_classes_global(self): - code = 'global_var = 10\n' \ - 'def my_func():\n' \ - ' func_var = 20\n' \ - ' class C(object):\n' \ - ' def another_func(self):\n' \ - ' local_var = 10\n' \ - ' globa' - result = self._assist(code) - self.assert_completion_in_result('global_var', 'global', result) - - def test_nested_classes_global_function(self): - code = 'global_var = 10\n' \ - 'def my_func():\n' \ - ' func_var = 20\n' \ - ' class C(object):\n' \ - ' def another_func(self):\n' \ - ' local_var = 10\n' \ - ' my_f' - result = self._assist(code) - self.assert_completion_in_result('my_func', 'global', result) - - def test_proposing_function_parameters_in_functions(self): - code = 'def my_func(my_param):\n my_var = 20\n my_' - result = self._assist(code) - self.assert_completion_in_result('my_param', 'local', result) - - def test_proposing_function_keyword_parameters_in_functions(self): - code = 'def my_func(my_param, *my_list, **my_kws):\n' \ - ' my_var = 20\n' \ - ' my_' - result = self._assist(code) - self.assert_completion_in_result('my_param', 'local', result) - self.assert_completion_in_result('my_list', 'local', result) - self.assert_completion_in_result('my_kws', 'local', result) - - def test_not_proposing_unmatching_function_parameters_in_functions(self): - code = "def my_func(my_param):\n my_var = 20\n you_" - result = self._assist(code) - self.assert_completion_not_in_result('my_param', 'local', result) - - def test_ignoring_current_statement(self): - code = "my_var = 10\nmy_tuple = (10, \n my_" - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_ignoring_current_statement_brackets_continuation(self): - code = "my_var = 10\n'hello'[10:\n my_" - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_ignoring_current_statement_explicit_continuation(self): - code = "my_var = 10\nmy_var2 = 2 + \\\n my_" - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_ignoring_current_statement_while_the_first_statement_of_the_block(self): - code = "my_var = 10\ndef f():\n my_" - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_ignoring_current_statement_while_current_line_ends_with_a_colon(self): - code = "my_var = 10\nif my_:\n pass" - result = self._assist(code, 18) - self.assert_completion_in_result('my_var', 'global', result) - - def test_ignoring_string_contents(self): - code = "my_var = '('\nmy_" - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_ignoring_comment_contents(self): - code = "my_var = 10 #(\nmy_" - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_ignoring_string_contents_backslash_plus_quotes(self): - code = "my_var = '\\''\nmy_" - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_ignoring_string_contents_backslash_plus_backslash(self): - code = "my_var = '\\\\'\nmy_" - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_not_proposing_later_defined_variables_in_current_block(self): - code = "my_\nmy_var = 10\n" - result = self._assist(code, 3, later_locals=False) - self.assert_completion_not_in_result('my_var', 'global', result) - - def test_not_proposing_later_defined_variables_in_current_function(self): - code = "def f():\n my_\n my_var = 10\n" - result = self._assist(code, 16, later_locals=False) - self.assert_completion_not_in_result('my_var', 'local', result) - - def test_ignoring_string_contents_with_triple_quotes(self): - code = "my_var = '''(\n'('''\nmy_" - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_ignoring_string_contents_with_triple_quotes_and_backslash(self): - code = 'my_var = """\\"""("""\nmy_' - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_ignoring_string_contents_with_triple_quotes_and_double_backslash(self): - code = 'my_var = """\\\\"""\nmy_' - result = self._assist(code) - self.assert_completion_in_result('my_var', 'global', result) - - def test_reporting_params_when_in_the_first_line_of_a_function(self): - code = 'def f(param):\n para' - result = self._assist(code) - self.assert_completion_in_result('param', 'local', result) - - def test_code_assist_when_having_a_two_line_function_header(self): - code = 'def f(param1,\n param2):\n para' - result = self._assist(code) - self.assert_completion_in_result('param1', 'local', result) - - def test_code_assist_with_function_with_two_line_return(self): - code = 'def f(param1, param2):\n return(param1,\n para' - result = self._assist(code) - self.assert_completion_in_result('param2', 'local', result) - - def test_get_definition_location(self): - code = 'def a_func():\n pass\na_func()' - result = get_definition_location(self.project, code, len(code) - 3) - self.assertEquals((None, 1), result) - - def test_get_definition_location_underlined_names(self): - code = 'def a_sample_func():\n pass\na_sample_func()' - result = get_definition_location(self.project, code, len(code) - 11) - self.assertEquals((None, 1), result) - - def test_get_definition_location_dotted_names(self): - code = 'class AClass(object):\n' \ - ' @staticmethod\n' \ - ' def a_method():\n' \ - ' pass\n' \ - 'AClass.a_method()' - result = get_definition_location(self.project, code, len(code) - 3) - self.assertEquals((None, 2), result) - - def test_get_definition_location_dotted_module_names(self): - module_resource = testutils.create_module(self.project, 'mod') - module_resource.write('def a_func():\n pass\n') - code = 'import mod\nmod.a_func()' - result = get_definition_location(self.project, code, len(code) - 3) - self.assertEquals((module_resource, 1), result) - - def test_get_definition_location_for_nested_packages(self): - pycore = self.project.pycore - mod1 = testutils.create_module(self.project, 'mod1') - pkg1 = testutils.create_package(self.project, 'pkg1') - pkg2 = testutils.create_package(self.project, 'pkg2', pkg1) - mod2 = testutils.create_module(self.project, 'mod2', pkg2) - mod1.write('import pkg1.pkg2.mod2') - - mod1_scope = pycore.resource_to_pyobject(mod1).get_scope() - init_dot_py = pkg2.get_child('__init__.py') - found_pyname = get_definition_location(self.project, mod1.read(), - mod1.read().index('pkg2') + 1) - self.assertEquals(init_dot_py, found_pyname[0]) - - def test_get_definition_location_unknown(self): - code = 'a_func()\n' - result = get_definition_location(self.project, code, len(code) - 3) - self.assertEquals((None, None), result) - - def test_get_definition_location_dot_spaces(self): - code = 'class AClass(object):\n ' \ - '@staticmethod\n def a_method():\n' \ - ' pass\nAClass.\\\n a_method()' - result = get_definition_location(self.project, code, len(code) - 3) - self.assertEquals((None, 2), result) - - def test_get_definition_location_dot_line_break_inside_parens(self): - code = 'class A(object):\n def a_method(self):\n pass\n' + \ - '(A.\na_method)' - result = get_definition_location(self.project, code, - code.rindex('a_method') + 1) - self.assertEquals((None, 2), result) - - def test_if_scopes_in_other_scopes_for_get_definition_location(self): - code = 'def f(a_var):\n pass\na_var = 10\nif True:\n print a_var\n' - result = get_definition_location(self.project, code, len(code) - 3) - self.assertEquals((None, 3), result) - - def test_code_assists_in_parens(self): - code = 'def a_func(a_var):\n pass\na_var = 10\na_func(a_' - result = self._assist(code) - self.assert_completion_in_result('a_var', 'global', result) - - def test_simple_type_inferencing(self): - code = 'class Sample(object):\n' \ - ' def __init__(self, a_param):\n' \ - ' pass\n' \ - ' def a_method(self):\n' \ - ' pass\n' \ - 'Sample("hey").a_' - result = self._assist(code) - self.assert_completion_in_result('a_method', 'attribute', result) - - def test_proposals_sorter(self): - code = 'def my_sample_function(self):\n' + \ - ' my_sample_var = 20\n' + \ - ' my_sample_' - proposals = sorted_proposals(self._assist(code)) - self.assertEquals('my_sample_var', proposals[0].name) - self.assertEquals('my_sample_function', proposals[1].name) - - def test_proposals_sorter_for_methods_and_attributes(self): - code = 'class A(object):\n' + \ - ' def __init__(self):\n' + \ - ' self.my_a_var = 10\n' + \ - ' def my_b_func(self):\n' + \ - ' pass\n' + \ - ' def my_c_func(self):\n' + \ - ' pass\n' + \ - 'a_var = A()\n' + \ - 'a_var.my_' - proposals = sorted_proposals(self._assist(code)) - self.assertEquals('my_b_func', proposals[0].name) - self.assertEquals('my_c_func', proposals[1].name) - self.assertEquals('my_a_var', proposals[2].name) - - def test_proposals_sorter_for_global_methods_and_funcs(self): - code = 'def my_b_func(self):\n' + \ - ' pass\n' + \ - 'my_a_var = 10\n' + \ - 'my_' - proposals = sorted_proposals(self._assist(code)) - self.assertEquals('my_b_func', proposals[0].name) - self.assertEquals('my_a_var', proposals[1].name) - - def test_proposals_sorter_underlined_methods(self): - code = 'class A(object):\n' + \ - ' def _my_func(self):\n' + \ - ' self.my_a_var = 10\n' + \ - ' def my_func(self):\n' + \ - ' pass\n' + \ - 'a_var = A()\n' + \ - 'a_var.' - proposals = sorted_proposals(self._assist(code)) - self.assertEquals('my_func', proposals[0].name) - self.assertEquals('_my_func', proposals[1].name) - - def test_proposals_sorter_and_scope_prefs(self): - code = 'my_global_var = 1\n' \ - 'def func(self):\n' \ - ' my_local_var = 2\n' \ - ' my_' - result = self._assist(code) - proposals = sorted_proposals(result, scopepref=['global', 'local']) - self.assertEquals('my_global_var', proposals[0].name) - self.assertEquals('my_local_var', proposals[1].name) - - def test_proposals_sorter_and_type_prefs(self): - code = 'my_global_var = 1\n' \ - 'def my_global_func(self):\n' \ - ' pass\n' \ - 'my_' - result = self._assist(code) - proposals = sorted_proposals(result, typepref=['instance', 'function']) - self.assertEquals('my_global_var', proposals[0].name) - self.assertEquals('my_global_func', proposals[1].name) - - def test_proposals_sorter_and_missing_type_in_typepref(self): - code = 'my_global_var = 1\n' \ - 'def my_global_func():\n' \ - ' pass\n' \ - 'my_' - result = self._assist(code) - proposals = sorted_proposals(result, typepref=['function']) - - def test_get_pydoc_unicode(self): - src = u'# coding: utf-8\ndef foo():\n u"юникод-объект"' - doc = get_doc(self.project, src, src.index('foo') + 1) - self.assertTrue(isinstance(doc, unicode)) - self.assertTrue(u'юникод-объект' in doc) - - def test_get_pydoc_utf8_bytestring(self): - src = u'# coding: utf-8\ndef foo():\n "байтстринг"' - doc = get_doc(self.project, src, src.index('foo') + 1) - self.assertTrue(isinstance(doc, unicode)) - self.assertTrue(u'байтстринг' in doc) - - def test_get_pydoc_for_functions(self): - src = 'def a_func():\n' \ - ' """a function"""\n' \ - ' a_var = 10\n' \ - 'a_func()' - self.assertTrue(get_doc(self.project, src, len(src) - 4). - endswith('a function')) - get_doc(self.project, src, len(src) - 4).index('a_func()') - - def test_get_pydoc_for_classes(self): - src = 'class AClass(object):\n pass\n' - get_doc(self.project, src, src.index('AClass') + 1).index('AClass') - - def test_get_pydoc_for_classes_with_init(self): - src = 'class AClass(object):\n def __init__(self):\n pass\n' - get_doc(self.project, src, src.index('AClass') + 1).index('AClass') - - def test_get_pydoc_for_modules(self): - pycore = self.project.pycore - mod = testutils.create_module(self.project, 'mod') - mod.write('"""a module"""\n') - src = 'import mod\nmod' - self.assertEquals('a module', get_doc(self.project, src, len(src) - 1)) - - def test_get_pydoc_for_builtins(self): - src = 'print(object)\n' - self.assertTrue(get_doc(self.project, src, - src.index('obj')) is not None) - - def test_get_pydoc_for_methods_should_include_class_name(self): - src = 'class AClass(object):\n' \ - ' def a_method(self):\n'\ - ' """hey"""\n' \ - ' pass\n' - doc = get_doc(self.project, src, src.index('a_method') + 1) - doc.index('AClass.a_method') - doc.index('hey') - - def test_get_pydoc_for_methods_should_include_methods_from_super_classes(self): - src = 'class A(object):\n' \ - ' def a_method(self):\n' \ - ' """hey1"""\n' \ - ' pass\n' \ - 'class B(A):\n' \ - ' def a_method(self):\n' \ - ' """hey2"""\n' \ - ' pass\n' - doc = get_doc(self.project, src, src.rindex('a_method') + 1) - doc.index('A.a_method') - doc.index('hey1') - doc.index('B.a_method') - doc.index('hey2') - - def test_get_pydoc_for_classes_should_name_super_classes(self): - src = 'class A(object):\n pass\n' \ - 'class B(A):\n pass\n' - doc = get_doc(self.project, src, src.rindex('B') + 1) - doc.index('B(A)') - - def test_get_pydoc_for_builtin_functions(self): - src = 's = "hey"\ns.replace\n' - doc = get_doc(self.project, src, src.rindex('replace') + 1) - self.assertTrue(doc is not None) - - def test_commenting_errors_before_offset(self): - src = 'lsjd lsjdf\ns = "hey"\ns.replace()\n' - doc = get_doc(self.project, src, src.rindex('replace') + 1) - - def test_proposing_variables_defined_till_the_end_of_scope(self): - code = 'if True:\n a_v\na_var = 10\n' - result = self._assist(code, code.index('a_v') + 3) - self.assert_completion_in_result('a_var', 'global', result) - - def test_completing_in_uncomplete_try_blocks(self): - code = 'try:\n a_var = 10\n a_' - result = self._assist(code) - self.assert_completion_in_result('a_var', 'global', result) - - def test_completing_in_uncomplete_try_blocks_in_functions(self): - code = 'def a_func():\n try:\n a_var = 10\n a_' - result = self._assist(code) - self.assert_completion_in_result('a_var', 'local', result) - - def test_already_complete_try_blocks_with_finally(self): - code = 'def a_func():\n try:\n a_var = 10\n a_' - result = self._assist(code) - self.assert_completion_in_result('a_var', 'local', result) - - def test_already_complete_try_blocks_with_finally2(self): - code = 'try:\n a_var = 10\n a_\nfinally:\n pass\n' - result = self._assist(code, code.rindex('a_') + 2) - self.assert_completion_in_result('a_var', 'global', result) - - def test_already_complete_try_blocks_with_except(self): - code = 'try:\n a_var = 10\n a_\nexcept Exception:\n pass\n' - result = self._assist(code, code.rindex('a_') + 2) - self.assert_completion_in_result('a_var', 'global', result) - - def test_already_complete_try_blocks_with_except2(self): - code = 'a_var = 10\ntry:\n another_var = a_\n another_var = 10\n' \ - 'except Exception:\n pass\n' - result = self._assist(code, code.rindex('a_') + 2) - self.assert_completion_in_result('a_var', 'global', result) - - def test_completing_ifs_in_uncomplete_try_blocks(self): - code = 'try:\n if True:\n a_var = 10\n a_' - result = self._assist(code) - self.assert_completion_in_result('a_var', 'global', result) - - def test_completing_ifs_in_uncomplete_try_blocks2(self): - code = 'try:\n if True:\n a_var = 10\n a_' - result = self._assist(code) - self.assert_completion_in_result('a_var', 'global', result) - - def test_completing_excepts_in_uncomplete_try_blocks(self): - code = 'try:\n pass\nexcept Exc' - result = self._assist(code) - self.assert_completion_in_result('Exception', 'builtin', result) - - def test_and_normal_complete_blocks_and_single_fixing(self): - code = 'try:\n range.\nexcept:\n pass\n' - result = self._assist(code, code.index('.'), maxfixes=1) - - def test_nested_blocks(self): - code = 'a_var = 10\ntry:\n try:\n a_v' - result = self._assist(code) - self.assert_completion_in_result('a_var', 'global', result) - - def test_proposing_function_keywords_when_calling(self): - code = 'def f(p):\n pass\nf(p' - result = self._assist(code) - self.assert_completion_in_result('p=', 'parameter_keyword', result) - - def test_proposing_function_keywords_when_calling_for_non_functions(self): - code = 'f = 1\nf(p' - result = self._assist(code) - - def test_proposing_function_keywords_when_calling_extra_spaces(self): - code = 'def f(p):\n pass\nf( p' - result = self._assist(code) - self.assert_completion_in_result('p=', 'parameter_keyword', result) - - def test_proposing_function_keywords_when_calling_on_second_argument(self): - code = 'def f(p1, p2):\n pass\nf(1, p' - result = self._assist(code) - self.assert_completion_in_result('p2=', 'parameter_keyword', result) - - def test_proposing_function_keywords_when_calling_not_proposing_args(self): - code = 'def f(p1, *args):\n pass\nf(1, a' - result = self._assist(code) - self.assert_completion_not_in_result('args=', 'parameter_keyword', result) - - def test_proposing_function_keywords_when_calling_with_no_nothing_after_parens(self): - code = 'def f(p):\n pass\nf(' - result = self._assist(code) - self.assert_completion_in_result('p=', 'parameter_keyword', result) - - def test_proposing_function_keywords_when_calling_with_no_nothing_after_parens2(self): - code = 'def f(p):\n pass\ndef g():\n h = f\n f(' - result = self._assist(code) - self.assert_completion_in_result('p=', 'parameter_keyword', result) - - def test_codeassists_before_opening_of_parens(self): - code = 'def f(p):\n pass\na_var = 1\nf(1)\n' - result = self._assist(code, code.rindex('f') + 1) - self.assert_completion_not_in_result('a_var', 'global', result) - - def test_codeassist_before_single_line_indents(self): - code = 'myvar = 1\nif True:\n (myv\nif True:\n pass\n' - result = self._assist(code, code.rindex('myv') + 3) - self.assert_completion_not_in_result('myvar', 'local', result) - - def test_codeassist_before_line_indents_in_a_blank_line(self): - code = 'myvar = 1\nif True:\n \nif True:\n pass\n' - result = self._assist(code, code.rindex(' ') + 4) - self.assert_completion_not_in_result('myvar', 'local', result) - - def test_simple_get_calltips(self): - src = 'def f():\n pass\nvar = f()\n' - doc = get_calltip(self.project, src, src.rindex('f')) - self.assertEquals('f()', doc) - - def test_get_calltips_for_classes(self): - src = 'class C(object):\n' \ - ' def __init__(self):\n pass\nC(' - doc = get_calltip(self.project, src, len(src) - 1) - self.assertEquals('C.__init__(self)', doc) - - def test_get_calltips_for_objects_with_call(self): - src = 'class C(object):\n' \ - ' def __call__(self, p):\n pass\n' \ - 'c = C()\nc(1,' - doc = get_calltip(self.project, src, src.rindex('c')) - self.assertEquals('C.__call__(self, p)', doc) - - def test_get_calltips_and_including_module_name(self): - src = 'class C(object):\n' \ - ' def __call__(self, p):\n pass\n' \ - 'c = C()\nc(1,' - mod = testutils.create_module(self.project, 'mod') - mod.write(src) - doc = get_calltip(self.project, src, src.rindex('c'), mod) - self.assertEquals('mod.C.__call__(self, p)', doc) - - def test_get_calltips_and_including_module_name(self): - src = 'range()\n' - doc = get_calltip(self.project, src, 1, ignore_unknown=True) - self.assertTrue(doc is None) - - def test_removing_self_parameter(self): - src = 'class C(object):\n' \ - ' def f(self):\n'\ - ' pass\n' \ - 'C().f()' - doc = get_calltip(self.project, src, src.rindex('f'), remove_self=True) - self.assertEquals('C.f()', doc) - - def test_removing_self_parameter_and_more_than_one_parameter(self): - src = 'class C(object):\n' \ - ' def f(self, p1):\n'\ - ' pass\n' \ - 'C().f()' - doc = get_calltip(self.project, src, src.rindex('f'), remove_self=True) - self.assertEquals('C.f(p1)', doc) - - def test_lambda_calltip(self): - src = 'foo = lambda x, y=1: None\n' \ - 'foo()' - doc = get_calltip(self.project, src, src.rindex('f')) - self.assertEqual(doc, 'lambda(x, y)') - - def test_keyword_before_parens(self): - code = 'if (1).:\n pass' - result = self._assist(code, offset=len('if (1).')) - self.assertTrue(result) - - # TESTING PROPOSAL'S KINDS AND TYPES. - # SEE RELATION MATRIX IN `CompletionProposal`'s DOCSTRING - - def test_local_variable_completion_proposal(self): - code = 'def foo():\n xvar = 5\n x' - result = self._assist(code) - self.assert_completion_in_result('xvar', 'local', result, 'instance') - - def test_global_variable_completion_proposal(self): - code = 'yvar = 5\ny' - result = self._assist(code) - self.assert_completion_in_result('yvar', 'global', result, 'instance') - - def test_builtin_variable_completion_proposal(self): - for varname in ('False', 'True'): - result = self._assist(varname[0]) - self.assert_completion_in_result(varname, 'builtin', result, - type='instance') - - def test_attribute_variable_completion_proposal(self): - code = 'class AClass(object):\n def foo(self):\n ' \ - 'self.bar = 1\n self.b' - result = self._assist(code) - self.assert_completion_in_result('bar', 'attribute', result, - type='instance') - - def test_local_class_completion_proposal(self): - code = 'def foo():\n class LocalClass(object): pass\n Lo' - result = self._assist(code) - self.assert_completion_in_result('LocalClass', 'local', result, - type='class') - - def test_global_class_completion_proposal(self): - code = 'class GlobalClass(object): pass\nGl' - result = self._assist(code) - self.assert_completion_in_result('GlobalClass', 'global', result, - type='class') - - def test_builtin_class_completion_proposal(self): - for varname in ('object', 'dict', 'file'): - result = self._assist(varname[0]) - self.assert_completion_in_result(varname, 'builtin', result, - type='class') - - def test_attribute_class_completion_proposal(self): - code = 'class Outer(object):\n class Inner(object): pass\nOuter.' - result = self._assist(code) - self.assert_completion_in_result('Inner', 'attribute', result, - type='class') - - def test_local_function_completion_proposal(self): - code = 'def outer():\n def inner(): pass\n in' - result = self._assist(code) - self.assert_completion_in_result('inner', 'local', result, - type='function') - - def test_global_function_completion_proposal(self): - code = 'def foo(): pass\nf' - result = self._assist(code) - self.assert_completion_in_result('foo', 'global', result, - type='function') - - def test_builtin_function_completion_proposal(self): - code = 'a' - result = self._assist(code) - for expected in ('all', 'any', 'abs'): - self.assert_completion_in_result(expected, 'builtin', result, - type='function') - - def test_attribute_function_completion_proposal(self): - code = 'class Some(object):\n def method(self):\n self.' - result = self._assist(code) - self.assert_completion_in_result('method', 'attribute', result, - type='function') - - def test_local_module_completion_proposal(self): - code = 'def foo():\n import types\n t' - result = self._assist(code) - self.assert_completion_in_result('types', 'imported', result, - type='module') - - def test_global_module_completion_proposal(self): - code = 'import operator\no' - result = self._assist(code) - self.assert_completion_in_result('operator', 'imported', result, - type='module') - - def test_attribute_module_completion_proposal(self): - code = 'class Some(object):\n import os\nSome.o' - result = self._assist(code) - self.assert_completion_in_result('os', 'imported', result, - type='module') - - def test_builtin_exception_completion_proposal(self): - code = 'def blah():\n Z' - result = self._assist(code) - self.assert_completion_in_result('ZeroDivisionError', 'builtin', - result, type='class') - - def test_keyword_completion_proposal(self): - code = 'f' - result = self._assist(code) - self.assert_completion_in_result('for', 'keyword', result, type=None) - self.assert_completion_in_result('from', 'keyword', result, type=None) - - def test_parameter_keyword_completion_proposal(self): - code = 'def func(abc, aloha, alpha, amigo): pass\nfunc(a' - result = self._assist(code) - for expected in ('abc=', 'aloha=', 'alpha=', 'amigo='): - self.assert_completion_in_result(expected, 'parameter_keyword', - result, type=None) - - -class CodeAssistInProjectsTest(unittest.TestCase): - - def setUp(self): - super(CodeAssistInProjectsTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - samplemod = testutils.create_module(self.project, 'samplemod') - code = 'class SampleClass(object):\n' \ - ' def sample_method():\n pass\n\n' \ - 'def sample_func():\n pass\n' \ - 'sample_var = 10\n\n' \ - 'def _underlined_func():\n pass\n\n' - samplemod.write(code) - package = testutils.create_package(self.project, 'package') - nestedmod = testutils.create_module(self.project, 'nestedmod', package) - - def tearDown(self): - testutils.remove_project(self.project) - super(self.__class__, self).tearDown() - - def _assist(self, code, resource=None, **kwds): - return code_assist(self.project, code, len(code), resource, **kwds) - - def assert_completion_in_result(self, name, scope, result): - for proposal in result: - if proposal.name == name and proposal.scope == scope: - return - self.fail('completion <%s> not proposed' % name) - - def assert_completion_not_in_result(self, name, scope, result): - for proposal in result: - if proposal.name == name and proposal.scope == scope: - self.fail('completion <%s> was proposed' % name) - - def test_simple_import(self): - code = 'import samplemod\nsample' - result = self._assist(code) - self.assert_completion_in_result('samplemod', 'imported', result) - - def test_from_import_class(self): - code = 'from samplemod import SampleClass\nSample' - result = self._assist(code) - self.assert_completion_in_result('SampleClass', 'imported', result) - - def test_from_import_function(self): - code = 'from samplemod import sample_func\nsample' - result = self._assist(code) - self.assert_completion_in_result('sample_func', 'imported', result) - - def test_from_import_variable(self): - code = 'from samplemod import sample_var\nsample' - result = self._assist(code) - self.assert_completion_in_result('sample_var', 'imported', result) - - def test_from_imports_inside_functions(self): - code = 'def f():\n from samplemod import SampleClass\n Sample' - result = self._assist(code) - self.assert_completion_in_result('SampleClass', 'imported', result) - - def test_from_import_only_imports_imported(self): - code = 'from samplemod import sample_func\nSample' - result = self._assist(code) - self.assert_completion_not_in_result('SampleClass', 'global', result) - - def test_from_import_star(self): - code = 'from samplemod import *\nSample' - result = self._assist(code) - self.assert_completion_in_result('SampleClass', 'imported', result) - - def test_from_import_star2(self): - code = 'from samplemod import *\nsample' - result = self._assist(code) - self.assert_completion_in_result('sample_func', 'imported', result) - self.assert_completion_in_result('sample_var', 'imported', result) - - def test_from_import_star_not_imporing_underlined(self): - code = 'from samplemod import *\n_under' - result = self._assist(code) - self.assert_completion_not_in_result('_underlined_func', 'global', result) - - def test_from_package_import_mod(self): - code = 'from package import nestedmod\nnest' - result = self._assist(code) - self.assert_completion_in_result('nestedmod', 'imported', result) - - def test_completing_after_dot(self): - code = 'class SampleClass(object):\n' \ - ' def sample_method(self):\n' \ - ' pass\n' \ - 'SampleClass.sam' - result = self._assist(code) - self.assert_completion_in_result('sample_method', 'attribute', result) - - def test_completing_after_multiple_dots(self): - code = 'class Class1(object):\n' \ - ' class Class2(object):\n' \ - ' def sample_method(self):\n' \ - ' pass\n' \ - 'Class1.Class2.sam' - result = self._assist(code) - self.assert_completion_in_result('sample_method', 'attribute', result) - - def test_completing_after_self_dot(self): - code = 'class Sample(object):\n' \ - ' def method1(self):\n' \ - ' pass\n' \ - ' def method2(self):\n' \ - ' self.m' - result = self._assist(code) - self.assert_completion_in_result('method1', 'attribute', result) - - def test_result_start_offset_for_dotted_completions(self): - code = 'class Sample(object):\n' \ - ' def method1(self):\n' \ - ' pass\n' \ - 'Sample.me' - self.assertEquals(len(code) - 2, starting_offset(code, len(code))) - - def test_backslash_after_dots(self): - code = 'class Sample(object):\n' \ - ' def a_method(self):\n' \ - ' pass\n' \ - 'Sample.\\\n a_m' - result = self._assist(code) - self.assert_completion_in_result('a_method', 'attribute', result) - - def test_not_proposing_global_names_after_dot(self): - code = 'class Sample(object):\n' \ - ' def a_method(self):\n' \ - ' pass\n' \ - 'Sample.' - result = self._assist(code) - self.assert_completion_not_in_result('Sample', 'global', result) - - def test_assist_on_relative_imports(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod1.write('def a_func():\n pass\n') - code = 'import mod1\nmod1.' - result = self._assist(code, resource=mod2) - self.assert_completion_in_result('a_func', 'imported', result) - - def test_get_location_on_relative_imports(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod1.write('def a_func():\n pass\n') - code = 'import mod1\nmod1.a_func\n' - result = get_definition_location(self.project, code, - len(code) - 2, mod2) - self.assertEquals((mod1, 1), result) - - def test_get_definition_location_for_builtins(self): - code = 'import sys\n' - result = get_definition_location(self.project, code, - len(code) - 2) - self.assertEquals((None, None), result) - - def test_get_doc_on_relative_imports(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod1.write('def a_func():\n """hey"""\n pass\n') - code = 'import mod1\nmod1.a_func\n' - result = get_doc(self.project, code, len(code) - 2, mod2) - self.assertTrue(result.endswith('hey')) - - def test_get_doc_on_from_import_module(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('"""mod1 docs"""\nvar = 1\n') - code = 'from mod1 import var\n' - result = get_doc(self.project, code, code.index('mod1')) - result.index('mod1 docs') - - def test_fixing_errors_with_maxfixes_in_resources(self): - mod = testutils.create_module(self.project, 'mod') - code = 'def f():\n sldj sldj\ndef g():\n ran' - mod.write(code) - result = self._assist(code, maxfixes=2, resource=mod) - self.assertTrue(len(result) > 0) - - def test_completing_names_after_from_import(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('myvar = None\n') - result = self._assist('from mod1 import myva', resource=mod2) - self.assertTrue(len(result) > 0) - self.assert_completion_in_result('myvar', 'global', result) - - def test_completing_names_after_from_import_and_sorted_proposals(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('myvar = None\n') - result = self._assist('from mod1 import myva', resource=mod2) - result = sorted_proposals(result) - self.assertTrue(len(result) > 0) - self.assert_completion_in_result('myvar', 'global', result) - - def test_completing_names_after_from_import2(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('myvar = None\n') - result = self._assist('from mod1 import ', resource=mod2) - self.assertTrue(len(result) > 0) - self.assert_completion_in_result('myvar', 'global', result) - - def test_starting_expression(self): - code = 'l = list()\nl.app' - self.assertEquals('l.app', starting_expression(code, len(code))) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(CodeAssistTest)) - result.addTests(unittest.makeSuite(CodeAssistInProjectsTest)) - return result - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/contrib/finderrorstest.py --- a/vim/sadness/ropevim/src/rope/ropetest/contrib/finderrorstest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -import unittest - -from rope.contrib import finderrors -from ropetest import testutils - - -class FindErrorsTest(unittest.TestCase): - - def setUp(self): - super(FindErrorsTest, self).setUp() - self.project = testutils.sample_project() - self.mod = self.project.root.create_file('mod.py') - - def tearDown(self): - testutils.remove_project(self.project) - super(FindErrorsTest, self).tearDown() - - def test_unresolved_variables(self): - self.mod.write('print(var)\n') - result = finderrors.find_errors(self.project, self.mod) - self.assertEquals(1, len(result)) - self.assertEquals(1, result[0].lineno) - - def test_defined_later(self): - self.mod.write('print(var)\nvar = 1\n') - result = finderrors.find_errors(self.project, self.mod) - self.assertEquals(1, len(result)) - self.assertEquals(1, result[0].lineno) - - def test_ignoring_builtins(self): - self.mod.write('range(2)\n') - result = finderrors.find_errors(self.project, self.mod) - self.assertEquals(0, len(result)) - - def test_ignoring_none(self): - self.mod.write('var = None\n') - result = finderrors.find_errors(self.project, self.mod) - self.assertEquals(0, len(result)) - - def test_bad_attributes(self): - code = 'class C(object):\n' \ - ' pass\n' \ - 'c = C()\n' \ - 'print(c.var)\n' - self.mod.write(code) - result = finderrors.find_errors(self.project, self.mod) - self.assertEquals(1, len(result)) - self.assertEquals(4, result[0].lineno) - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/contrib/findittest.py --- a/vim/sadness/ropevim/src/rope/ropetest/contrib/findittest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -from rope.base import exceptions -import unittest - -from rope.contrib.findit import (find_occurrences, find_implementations, - find_definition) -from ropetest import testutils - - -class FindItTest(unittest.TestCase): - - def setUp(self): - super(FindItTest, self).setUp() - self.project = testutils.sample_project() - - def tearDown(self): - testutils.remove_project(self.project) - super(FindItTest, self).tearDown() - - def test_finding_occurrences(self): - mod = testutils.create_module(self.project, 'mod') - mod.write('a_var = 1\n') - result = find_occurrences(self.project, mod, 1) - self.assertEquals(mod, result[0].resource) - self.assertEquals(0, result[0].offset) - self.assertEquals(False, result[0].unsure) - - def test_finding_occurrences_in_more_than_one_module(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('a_var = 1\n') - mod2.write('import mod1\nmy_var = mod1.a_var') - result = find_occurrences(self.project, mod1, 1) - self.assertEquals(2, len(result)) - modules = (result[0].resource, result[1].resource) - self.assertTrue(mod1 in modules and mod2 in modules) - - def test_finding_occurrences_matching_when_unsure(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('class C(object):\n def a_func(self):\n pass\n' - 'def f(arg):\n arg.a_func()\n') - result = find_occurrences( - self.project, mod1, mod1.read().index('a_func'), unsure=True) - self.assertEquals(2, len(result)) - - def test_find_occurrences_resources_parameter(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('a_var = 1\n') - mod2.write('import mod1\nmy_var = mod1.a_var') - result = find_occurrences(self.project, mod1, 1, resources=[mod1]) - self.assertEquals(1, len(result)) - self.assertEquals((mod1, 0), (result[0].resource, result[0].offset)) - - def test_find_occurrences_and_class_hierarchies(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('class A(object):\n def f():\n pass\n' - 'class B(A):\n def f():\n pass\n') - offset = mod1.read().rindex('f') - result1 = find_occurrences(self.project, mod1, offset) - result2 = find_occurrences(self.project, mod1, - offset, in_hierarchy=True) - self.assertEquals(1, len(result1)) - self.assertEquals(2, len(result2)) - - def test_trivial_find_implementations(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('class A(object):\n def f(self):\n pass\n') - offset = mod1.read().rindex('f(') - result = find_implementations(self.project, mod1, offset) - self.assertEquals([], result) - - def test_find_implementations_and_not_returning_parents(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('class A(object):\n def f(self):\n pass\n' - 'class B(A):\n def f(self):\n pass\n') - offset = mod1.read().rindex('f(') - result = find_implementations(self.project, mod1, offset) - self.assertEquals([], result) - - def test_find_implementations_real_implementation(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('class A(object):\n def f(self):\n pass\n' - 'class B(A):\n def f(self):\n pass\n') - offset = mod1.read().index('f(') - result = find_implementations(self.project, mod1, offset) - self.assertEquals(1, len(result)) - self.assertEquals(mod1.read().rindex('f('), result[0].offset) - - @testutils.assert_raises(exceptions.BadIdentifierError) - def test_find_implementations_real_implementation(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('class A(object):\n pass\n') - offset = mod1.read().index('A') - result = find_implementations(self.project, mod1, offset) - - def test_trivial_find_definition(self): - code = 'def a_func():\n pass\na_func()' - result = find_definition(self.project, code, code.rindex('a_func')) - start = code.index('a_func') - self.assertEquals(start, result.offset) - self.assertEquals(None, result.resource) - self.assertEquals(1, result.lineno) - self.assertEquals((start, start + len('a_func')), result.region) - - def test_find_definition_in_other_modules(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('var = 1\n') - code = 'import mod1\nprint(mod1.var)\n' - result = find_definition(self.project, code, code.index('var')) - self.assertEquals(mod1, result.resource) - self.assertEquals(0, result.offset) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(FindItTest)) - return result - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/contrib/fixmodnamestest.py --- a/vim/sadness/ropevim/src/rope/ropetest/contrib/fixmodnamestest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -import unittest - -from ropetest import testutils -from rope.contrib.fixmodnames import FixModuleNames -from rope.contrib.generate import create_module, create_package - - -# HACK: for making this test work on case-insensitive file-systems, it -# uses a name.replace('x', '_') fixer. -class FixModuleNamesTest(unittest.TestCase): - - def setUp(self): - super(FixModuleNamesTest, self).setUp() - self.project = testutils.sample_project() - - def tearDown(self): - testutils.remove_project(self.project) - super(FixModuleNamesTest, self).tearDown() - - def test_simple_module_renaming(self): - mod = create_module(self.project, 'xod') - self.project.do(FixModuleNames(self.project).get_changes(_fixer)) - self.assertFalse(mod.exists()) - self.assertTrue(self.project.get_resource('_od.py').exists()) - - def test_packages_module_renaming(self): - pkg = create_package(self.project, 'xkg') - self.project.do(FixModuleNames(self.project).get_changes(_fixer)) - self.assertFalse(pkg.exists()) - self.assertTrue(self.project.get_resource('_kg/__init__.py').exists()) - - def test_fixing_contents(self): - mod1 = create_module(self.project, 'xod1') - mod2 = create_module(self.project, 'xod2') - mod1.write('import xod2\n') - mod2.write('import xod1\n') - self.project.do(FixModuleNames(self.project).get_changes(_fixer)) - newmod1 = self.project.get_resource('_od1.py') - newmod2 = self.project.get_resource('_od2.py') - self.assertEquals('import _od2\n', newmod1.read()) - self.assertEquals('import _od1\n', newmod2.read()) - - def test_handling_nested_modules(self): - pkg = create_package(self.project, 'xkg') - mod = create_module(self.project, 'xkg.xod') - self.project.do(FixModuleNames(self.project).get_changes(_fixer)) - self.assertFalse(pkg.exists()) - self.assertTrue(self.project.get_resource('_kg/__init__.py').exists()) - self.assertTrue(self.project.get_resource('_kg/_od.py').exists()) - - -def _fixer(name): - return name.replace('x', '_') - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/contrib/generatetest.py --- a/vim/sadness/ropevim/src/rope/ropetest/contrib/generatetest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,265 +0,0 @@ -import unittest - -from rope.base import exceptions -from rope.contrib import generate -from ropetest import testutils - - -class GenerateTest(unittest.TestCase): - - def setUp(self): - super(GenerateTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod1') - self.mod2 = testutils.create_module(self.project, 'mod2') - self.pkg = testutils.create_package(self.project, 'pkg') - - def tearDown(self): - testutils.remove_project(self.project) - super(GenerateTest, self).tearDown() - - def _get_generate(self, offset): - return generate.GenerateVariable(self.project, self.mod, offset) - - def _get_generate_class(self, offset): - return generate.GenerateClass(self.project, self.mod, offset) - - def _get_generate_module(self, offset): - return generate.GenerateModule(self.project, self.mod, offset) - - def _get_generate_package(self, offset): - return generate.GeneratePackage(self.project, self.mod, offset) - - def _get_generate_function(self, offset): - return generate.GenerateFunction(self.project, self.mod, offset) - - def test_getting_location(self): - code = 'a_var = name\n' - self.mod.write(code) - generator = self._get_generate(code.index('name')) - self.assertEquals((self.mod, 1), generator.get_location()) - - def test_generating_variable(self): - code = 'a_var = name\n' - self.mod.write(code) - changes = self._get_generate(code.index('name')).get_changes() - self.project.do(changes) - self.assertEquals('name = None\n\n\na_var = name\n', self.mod.read()) - - def test_generating_variable_inserting_before_statement(self): - code = 'c = 1\nc = b\n' - self.mod.write(code) - changes = self._get_generate(code.index('b')).get_changes() - self.project.do(changes) - self.assertEquals('c = 1\nb = None\n\n\nc = b\n', self.mod.read()) - - def test_generating_variable_in_local_scopes(self): - code = 'def f():\n c = 1\n c = b\n' - self.mod.write(code) - changes = self._get_generate(code.index('b')).get_changes() - self.project.do(changes) - self.assertEquals('def f():\n c = 1\n b = None\n c = b\n', - self.mod.read()) - - def test_generating_variable_in_other_modules(self): - code = 'import mod2\nc = mod2.b\n' - self.mod.write(code) - generator = self._get_generate(code.index('b')) - self.project.do(generator.get_changes()) - self.assertEquals((self.mod2, 1), generator.get_location()) - self.assertEquals('b = None\n', self.mod2.read()) - - def test_generating_variable_in_classes(self): - code = 'class C(object):\n def f(self):\n pass\n' \ - 'c = C()\na_var = c.attr' - self.mod.write(code) - changes = self._get_generate(code.index('attr')).get_changes() - self.project.do(changes) - self.assertEquals( - 'class C(object):\n def f(self):\n pass\n\n attr = None\n' \ - 'c = C()\na_var = c.attr', self.mod.read()) - - def test_generating_variable_in_classes_removing_pass(self): - code = 'class C(object):\n pass\nc = C()\na_var = c.attr' - self.mod.write(code) - changes = self._get_generate(code.index('attr')).get_changes() - self.project.do(changes) - self.assertEquals('class C(object):\n\n attr = None\n' \ - 'c = C()\na_var = c.attr', self.mod.read()) - - def test_generating_variable_in_packages(self): - code = 'import pkg\na = pkg.a\n' - self.mod.write(code) - generator = self._get_generate(code.rindex('a')) - self.project.do(generator.get_changes()) - init = self.pkg.get_child('__init__.py') - self.assertEquals((init, 1), generator.get_location()) - self.assertEquals('a = None\n', init.read()) - - def test_generating_classes(self): - code = 'c = C()\n' - self.mod.write(code) - changes = self._get_generate_class(code.index('C')).get_changes() - self.project.do(changes) - self.assertEquals('class C(object):\n pass\n\n\nc = C()\n', - self.mod.read()) - - def test_generating_modules(self): - code = 'import pkg\npkg.mod\n' - self.mod.write(code) - generator = self._get_generate_module(code.rindex('mod')) - self.project.do(generator.get_changes()) - mod = self.pkg.get_child('mod.py') - self.assertEquals((mod, 1), generator.get_location()) - self.assertEquals('import pkg.mod\npkg.mod\n', self.mod.read()) - - def test_generating_packages(self): - code = 'import pkg\npkg.pkg2\n' - self.mod.write(code) - generator = self._get_generate_package(code.rindex('pkg2')) - self.project.do(generator.get_changes()) - pkg2 = self.pkg.get_child('pkg2') - init = pkg2.get_child('__init__.py') - self.assertEquals((init, 1), generator.get_location()) - self.assertEquals('import pkg.pkg2\npkg.pkg2\n', self.mod.read()) - - def test_generating_function(self): - code = 'a_func()\n' - self.mod.write(code) - changes = self._get_generate_function(code.index('a_func')).get_changes() - self.project.do(changes) - self.assertEquals('def a_func():\n pass\n\n\na_func()\n', - self.mod.read()) - - def test_generating_modules_with_empty_primary(self): - code = 'mod\n' - self.mod.write(code) - generator = self._get_generate_module(code.rindex('mod')) - self.project.do(generator.get_changes()) - mod = self.project.root.get_child('mod.py') - self.assertEquals((mod, 1), generator.get_location()) - self.assertEquals('import mod\nmod\n', self.mod.read()) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_generating_variable_already_exists(self): - code = 'b = 1\nc = b\n' - self.mod.write(code) - changes = self._get_generate(code.index('b')).get_changes() - - @testutils.assert_raises(exceptions.RefactoringError) - def test_generating_variable_primary_cannot_be_determined(self): - code = 'c = can_not_be_found.b\n' - self.mod.write(code) - changes = self._get_generate(code.rindex('b')).get_changes() - - @testutils.assert_raises(exceptions.RefactoringError) - def test_generating_modules_when_already_exists(self): - code = 'mod2\n' - self.mod.write(code) - generator = self._get_generate_module(code.rindex('mod')) - self.project.do(generator.get_changes()) - - def test_generating_static_methods(self): - code = 'class C(object):\n pass\nC.a_func()\n' - self.mod.write(code) - changes = self._get_generate_function(code.index('a_func')).get_changes() - self.project.do(changes) - self.assertEquals( - 'class C(object):\n\n @staticmethod\n def a_func():\n pass\nC.a_func()\n', - self.mod.read()) - - def test_generating_methods(self): - code = 'class C(object):\n pass\nc = C()\nc.a_func()\n' - self.mod.write(code) - changes = self._get_generate_function(code.index('a_func')).get_changes() - self.project.do(changes) - self.assertEquals( - 'class C(object):\n\n def a_func(self):\n pass\n' - 'c = C()\nc.a_func()\n', - self.mod.read()) - - def test_generating_constructors(self): - code = 'class C(object):\n pass\nc = C()\n' - self.mod.write(code) - changes = self._get_generate_function(code.rindex('C')).get_changes() - self.project.do(changes) - self.assertEquals( - 'class C(object):\n\n def __init__(self):\n pass\n' - 'c = C()\n', - self.mod.read()) - - def test_generating_calls(self): - code = 'class C(object):\n pass\nc = C()\nc()\n' - self.mod.write(code) - changes = self._get_generate_function(code.rindex('c')).get_changes() - self.project.do(changes) - self.assertEquals( - 'class C(object):\n\n def __call__(self):\n pass\n' - 'c = C()\nc()\n', - self.mod.read()) - - def test_generating_calls_in_other_modules(self): - self.mod2.write('class C(object):\n pass\n') - code = 'import mod2\nc = mod2.C()\nc()\n' - self.mod.write(code) - changes = self._get_generate_function(code.rindex('c')).get_changes() - self.project.do(changes) - self.assertEquals( - 'class C(object):\n\n def __call__(self):\n pass\n', - self.mod2.read()) - - def test_generating_function_handling_arguments(self): - code = 'a_func(1)\n' - self.mod.write(code) - changes = self._get_generate_function(code.index('a_func')).get_changes() - self.project.do(changes) - self.assertEquals('def a_func(arg0):\n pass\n\n\na_func(1)\n', - self.mod.read()) - - def test_generating_function_handling_keyword_xarguments(self): - code = 'a_func(p=1)\n' - self.mod.write(code) - changes = self._get_generate_function(code.index('a_func')).get_changes() - self.project.do(changes) - self.assertEquals('def a_func(p):\n pass\n\n\na_func(p=1)\n', - self.mod.read()) - - def test_generating_function_handling_arguments_better_naming(self): - code = 'a_var = 1\na_func(a_var)\n' - self.mod.write(code) - changes = self._get_generate_function(code.index('a_func')).get_changes() - self.project.do(changes) - self.assertEquals('a_var = 1\ndef a_func(a_var):\n pass\n\n\na_func(a_var)\n', - self.mod.read()) - - def test_generating_variable_in_other_modules2(self): - self.mod2.write('\n\n\nprint(1)\n') - code = 'import mod2\nc = mod2.b\n' - self.mod.write(code) - generator = self._get_generate(code.index('b')) - self.project.do(generator.get_changes()) - self.assertEquals((self.mod2, 5), generator.get_location()) - self.assertEquals('\n\n\nprint(1)\n\n\nb = None\n', self.mod2.read()) - - def test_generating_function_in_a_suite(self): - code = 'if True:\n a_func()\n' - self.mod.write(code) - changes = self._get_generate_function(code.index('a_func')).get_changes() - self.project.do(changes) - self.assertEquals('def a_func():\n pass\n\n\nif True:\n a_func()\n', - self.mod.read()) - - def test_generating_function_in_a_suite_in_a_function(self): - code = 'def f():\n a = 1\n if 1:\n g()\n' - self.mod.write(code) - changes = self._get_generate_function(code.index('g()')).get_changes() - self.project.do(changes) - self.assertEquals( - 'def f():\n a = 1\n def g():\n pass\n' - ' if 1:\n g()\n', - self.mod.read()) - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/historytest.py --- a/vim/sadness/ropevim/src/rope/ropetest/historytest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,409 +0,0 @@ -import unittest - -import rope.base.history -from rope.base import exceptions -from rope.base.change import * -from ropetest import testutils - - -class HistoryTest(unittest.TestCase): - - def setUp(self): - super(HistoryTest, self).setUp() - self.project = testutils.sample_project() - self.history = self.project.history - - def tearDown(self): - testutils.remove_project(self.project) - super(HistoryTest, self).tearDown() - - def test_undoing_writes(self): - my_file = self.project.root.create_file('my_file.txt') - my_file.write('text1') - self.history.undo() - self.assertEquals('', my_file.read()) - - def test_moving_files(self): - my_file = self.project.root.create_file('my_file.txt') - my_file.move('new_file.txt') - self.history.undo() - self.assertEquals('', my_file.read()) - - def test_moving_files_to_folders(self): - my_file = self.project.root.create_file('my_file.txt') - my_folder = self.project.root.create_folder('my_folder') - my_file.move(my_folder.path) - self.history.undo() - self.assertEquals('', my_file.read()) - - def test_writing_files_that_does_not_change_contents(self): - my_file = self.project.root.create_file('my_file.txt') - my_file.write('') - self.project.history.undo() - self.assertFalse(my_file.exists()) - -class IsolatedHistoryTest(unittest.TestCase): - - def setUp(self): - super(IsolatedHistoryTest, self).setUp() - self.project = testutils.sample_project() - self.history = rope.base.history.History(self.project) - self.file1 = self.project.root.create_file('file1.txt') - self.file2 = self.project.root.create_file('file2.txt') - - def tearDown(self): - testutils.remove_project(self.project) - super(IsolatedHistoryTest, self).tearDown() - - def test_simple_undo(self): - change = ChangeContents(self.file1, '1') - self.history.do(change) - self.assertEquals('1', self.file1.read()) - self.history.undo() - self.assertEquals('', self.file1.read()) - - def test_tobe_undone(self): - change1 = ChangeContents(self.file1, '1') - self.assertEquals(None, self.history.tobe_undone) - self.history.do(change1) - self.assertEquals(change1, self.history.tobe_undone) - change2 = ChangeContents(self.file1, '2') - self.history.do(change2) - self.assertEquals(change2, self.history.tobe_undone) - self.history.undo() - self.assertEquals(change1, self.history.tobe_undone) - - def test_tobe_redone(self): - change = ChangeContents(self.file1, '1') - self.history.do(change) - self.assertEquals(None, self.history.tobe_redone) - self.history.undo() - self.assertEquals(change, self.history.tobe_redone) - - @testutils.assert_raises(exceptions.HistoryError) - def test_undo_limit(self): - history = rope.base.history.History(self.project, maxundos=1) - history.do(ChangeContents(self.file1, '1')) - history.do(ChangeContents(self.file1, '2')) - try: - history.undo() - history.undo() - finally: - self.assertEquals('1', self.file1.read()) - - def test_simple_redo(self): - change = ChangeContents(self.file1, '1') - self.history.do(change) - self.history.undo() - self.history.redo() - self.assertEquals('1', self.file1.read()) - - def test_simple_re_undo(self): - change = ChangeContents(self.file1, '1') - self.history.do(change) - self.history.undo() - self.history.redo() - self.history.undo() - self.assertEquals('', self.file1.read()) - - def test_multiple_undos(self): - change = ChangeContents(self.file1, '1') - self.history.do(change) - change = ChangeContents(self.file1, '2') - self.history.do(change) - self.history.undo() - self.assertEquals('1', self.file1.read()) - change = ChangeContents(self.file1, '3') - self.history.do(change) - self.history.undo() - self.assertEquals('1', self.file1.read()) - self.history.redo() - self.assertEquals('3', self.file1.read()) - - @testutils.assert_raises(exceptions.HistoryError) - def test_undo_list_underflow(self): - self.history.undo() - - @testutils.assert_raises(exceptions.HistoryError) - def test_redo_list_underflow(self): - self.history.redo() - - @testutils.assert_raises(exceptions.HistoryError) - def test_dropping_undone_changes(self): - self.file1.write('1') - self.history.undo(drop=True) - self.history.redo() - - def test_undoing_choosen_changes(self): - change = ChangeContents(self.file1, '1') - self.history.do(change) - self.history.undo(change) - self.assertEquals('', self.file1.read()) - self.assertFalse(self.history.undo_list) - - def test_undoing_choosen_changes2(self): - change1 = ChangeContents(self.file1, '1') - self.history.do(change1) - self.history.do(ChangeContents(self.file1, '2')) - self.history.undo(change1) - self.assertEquals('', self.file1.read()) - self.assertFalse(self.history.undo_list) - - def test_undoing_choosen_changes_not_undoing_others(self): - change1 = ChangeContents(self.file1, '1') - self.history.do(change1) - self.history.do(ChangeContents(self.file2, '2')) - self.history.undo(change1) - self.assertEquals('', self.file1.read()) - self.assertEquals('2', self.file2.read()) - - def test_undoing_writing_after_moving(self): - change1 = ChangeContents(self.file1, '1') - self.history.do(change1) - self.history.do(MoveResource(self.file1, 'file3.txt')) - file3 = self.project.get_resource('file3.txt') - self.history.undo(change1) - self.assertEquals('', self.file1.read()) - self.assertFalse(file3.exists()) - - def test_undoing_folder_movements_for_undoing_writes_inside_it(self): - folder = self.project.root.create_folder('folder') - file3 = folder.create_file('file3.txt') - change1 = ChangeContents(file3, '1') - self.history.do(change1) - self.history.do(MoveResource(folder, 'new_folder')) - new_folder = self.project.get_resource('new_folder') - self.history.undo(change1) - self.assertEquals('', file3.read()) - self.assertFalse(new_folder.exists()) - - def test_undoing_changes_that_depend_on_a_dependant_change(self): - change1 = ChangeContents(self.file1, '1') - self.history.do(change1) - changes = ChangeSet('2nd change') - changes.add_change(ChangeContents(self.file1, '2')) - changes.add_change(ChangeContents(self.file2, '2')) - self.history.do(changes) - self.history.do(MoveResource(self.file2, 'file3.txt')) - file3 = self.project.get_resource('file3.txt') - - self.history.undo(change1) - self.assertEquals('', self.file1.read()) - self.assertEquals('', self.file2.read()) - self.assertFalse(file3.exists()) - - def test_undoing_writes_for_undoing_folder_movements_containing_it(self): - folder = self.project.root.create_folder('folder') - old_file = folder.create_file('file3.txt') - change1 = MoveResource(folder, 'new_folder') - self.history.do(change1) - new_file = self.project.get_resource('new_folder/file3.txt') - self.history.do(ChangeContents(new_file, '1')) - self.history.undo(change1) - self.assertEquals('', old_file.read()) - self.assertFalse(new_file.exists()) - - @testutils.assert_raises(exceptions.HistoryError) - def test_undoing_not_available_change(self): - change = ChangeContents(self.file1, '1') - self.history.undo(change) - - def test_ignoring_ignored_resources(self): - self.project.set('ignored_resources', ['ignored*']) - ignored = self.project.get_file('ignored.txt') - change = CreateResource(ignored) - self.history.do(change) - self.assertTrue(ignored.exists()) - self.assertEquals(0, len(self.history.undo_list)) - - def test_get_file_undo_list_simple(self): - change = ChangeContents(self.file1, '1') - self.history.do(change) - self.assertEquals(set([change]), - set(self.history.get_file_undo_list(self.file1))) - - def test_get_file_undo_list_for_moves(self): - change = MoveResource(self.file1, 'file2.txt') - self.history.do(change) - self.assertEquals(set([change]), - set(self.history.get_file_undo_list(self.file1))) - - # XXX: What happens for moves before the file is created? - def xxx_test_get_file_undo_list_and_moving_its_contining_folder(self): - folder = self.project.root.create_folder('folder') - old_file = folder.create_file('file3.txt') - change1 = MoveResource(folder, 'new_folder') - self.history.do(change1) - self.assertEquals(set([change1]), - set(self.history.get_file_undo_list(old_file))) - - def test_clearing_redo_list_after_do(self): - change = ChangeContents(self.file1, '1') - self.history.do(change) - self.history.undo() - self.history.do(change) - self.assertEquals(0, len(self.history.redo_list)) - - @testutils.assert_raises(exceptions.HistoryError) - def test_undoing_a_not_yet_performed_change(self): - change = ChangeContents(self.file1, '1') - str(change) - change.undo() - - def test_clearing_up_the_history(self): - change1 = ChangeContents(self.file1, '1') - change2 = ChangeContents(self.file1, '2') - self.history.do(change1) - self.history.do(change2) - self.history.undo() - self.history.clear() - self.assertEquals(0, len(self.history.undo_list)) - self.assertEquals(0, len(self.history.redo_list)) - - def test_redoing_choosen_changes_not_undoing_others(self): - change1 = ChangeContents(self.file1, '1') - change2 = ChangeContents(self.file2, '2') - self.history.do(change1) - self.history.do(change2) - self.history.undo() - self.history.undo() - redone = self.history.redo(change2) - self.assertEquals([change2], redone) - self.assertEquals('', self.file1.read()) - self.assertEquals('2', self.file2.read()) - - -class SavingHistoryTest(unittest.TestCase): - - def setUp(self): - super(SavingHistoryTest, self).setUp() - self.project = testutils.sample_project() - self.history = rope.base.history.History(self.project) - self.to_data = ChangeToData() - self.to_change = DataToChange(self.project) - - def tearDown(self): - testutils.remove_project(self.project) - super(SavingHistoryTest, self).tearDown() - - def test_simple_set_saving(self): - data = self.to_data(ChangeSet('testing')) - change = self.to_change(data) - self.assertEquals('testing', str(change)) - - def test_simple_change_content_saving(self): - myfile = self.project.get_file('myfile.txt') - myfile.create() - myfile.write('1') - data = self.to_data(ChangeContents(myfile, '2')) - change = self.to_change(data) - self.history.do(change) - self.assertEquals('2', myfile.read()) - self.history.undo() - self.assertEquals('1', change.old_contents) - - def test_move_resource_saving(self): - myfile = self.project.root.create_file('myfile.txt') - myfolder = self.project.root.create_folder('myfolder') - data = self.to_data(MoveResource(myfile, 'myfolder')) - change = self.to_change(data) - self.history.do(change) - self.assertFalse(myfile.exists()) - self.assertTrue(myfolder.has_child('myfile.txt')) - self.history.undo() - self.assertTrue(myfile.exists()) - self.assertFalse(myfolder.has_child('myfile.txt')) - - def test_move_resource_saving_for_folders(self): - myfolder = self.project.root.create_folder('myfolder') - newfolder = self.project.get_folder('newfolder') - change = MoveResource(myfolder, 'newfolder') - self.history.do(change) - - data = self.to_data(change) - change = self.to_change(data) - change.undo() - self.assertTrue(myfolder.exists()) - self.assertFalse(newfolder.exists()) - - def test_create_file_saving(self): - myfile = self.project.get_file('myfile.txt') - data = self.to_data(CreateFile(self.project.root, 'myfile.txt')) - change = self.to_change(data) - self.history.do(change) - self.assertTrue(myfile.exists()) - self.history.undo() - self.assertFalse(myfile.exists()) - - def test_create_folder_saving(self): - myfolder = self.project.get_folder('myfolder') - data = self.to_data(CreateFolder(self.project.root, 'myfolder')) - change = self.to_change(data) - self.history.do(change) - self.assertTrue(myfolder.exists()) - self.history.undo() - self.assertFalse(myfolder.exists()) - - def test_create_resource_saving(self): - myfile = self.project.get_file('myfile.txt') - data = self.to_data(CreateResource(myfile)) - change = self.to_change(data) - self.history.do(change) - self.assertTrue(myfile.exists()) - self.history.undo() - self.assertFalse(myfile.exists()) - - def test_remove_resource_saving(self): - myfile = self.project.root.create_file('myfile.txt') - data = self.to_data(RemoveResource(myfile)) - change = self.to_change(data) - self.history.do(change) - self.assertFalse(myfile.exists()) - - def test_change_set_saving(self): - change = ChangeSet('testing') - myfile = self.project.get_file('myfile.txt') - change.add_change(CreateResource(myfile)) - change.add_change(ChangeContents(myfile, '1')) - - data = self.to_data(change) - change = self.to_change(data) - self.history.do(change) - self.assertEquals('1', myfile.read()) - self.history.undo() - self.assertFalse(myfile.exists()) - - def test_writing_and_reading_history(self): - history_file = self.project.get_file('history.pickle') - self.project.set('save_history', True) - history = rope.base.history.History(self.project) - myfile = self.project.get_file('myfile.txt') - history.do(CreateResource(myfile)) - history.write() - - history = rope.base.history.History(self.project) - history.undo() - self.assertFalse(myfile.exists()) - - def test_writing_and_reading_history2(self): - history_file = self.project.get_file('history.pickle') - self.project.set('save_history', True) - history = rope.base.history.History(self.project) - myfile = self.project.get_file('myfile.txt') - history.do(CreateResource(myfile)) - history.undo() - history.write() - - history = rope.base.history.History(self.project) - history.redo() - self.assertTrue(myfile.exists()) - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(HistoryTest)) - result.addTests(unittest.makeSuite(IsolatedHistoryTest)) - result.addTests(unittest.makeSuite(SavingHistoryTest)) - return result - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/objectdbtest.py --- a/vim/sadness/ropevim/src/rope/ropetest/objectdbtest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -import unittest - -from rope.base.oi import objectdb, memorydb -from ropetest import testutils - - -def _do_for_all_dbs(function): - def called(self): - for db in self.dbs: - function(self, db) - return called - - -class _MockValidation(object): - - def is_value_valid(self, value): - return value != -1 - - def is_more_valid(self, new, old): - return new != -1 - - def is_file_valid(self, path): - return path != 'invalid' - - def is_scope_valid(self, path, key): - return path != 'invalid' and key != 'invalid' - - -class _MockFileListObserver(object): - - log = '' - - def added(self, path): - self.log += 'added %s ' % path - - def removed(self, path): - self.log += 'removed %s ' % path - - -class ObjectDBTest(unittest.TestCase): - - def setUp(self): - super(ObjectDBTest, self).setUp() - self.project = testutils.sample_project() - validation = _MockValidation() - self.dbs = [ - objectdb.ObjectDB(memorydb.MemoryDB(self.project), validation)] - - def tearDown(self): - for db in self.dbs: - db.write() - testutils.remove_project(self.project) - super(ObjectDBTest, self).tearDown() - - @_do_for_all_dbs - def test_simple_per_name(self, db): - db.add_pername('file', 'key', 'name', 1) - self.assertEqual(1, db.get_pername('file', 'key', 'name')) - - @_do_for_all_dbs - def test_simple_per_name_does_not_exist(self, db): - self.assertEquals(None, db.get_pername('file', 'key', 'name')) - - @_do_for_all_dbs - def test_simple_per_name_after_syncing(self, db): - db.add_pername('file', 'key', 'name', 1) - db.write() - self.assertEquals(1, db.get_pername('file', 'key', 'name')) - - @_do_for_all_dbs - def test_getting_returned(self, db): - db.add_callinfo('file', 'key', (1, 2), 3) - self.assertEquals(3, db.get_returned('file', 'key', (1, 2))) - - @_do_for_all_dbs - def test_getting_returned_when_does_not_match(self, db): - db.add_callinfo('file', 'key', (1, 2), 3) - self.assertEquals(None, db.get_returned('file', 'key', (1, 1))) - - @_do_for_all_dbs - def test_getting_call_info(self, db): - db.add_callinfo('file', 'key', (1, 2), 3) - - call_infos = list(db.get_callinfos('file', 'key')) - self.assertEquals(1, len(call_infos)) - self.assertEquals((1, 2), call_infos[0].get_parameters()) - self.assertEquals(3, call_infos[0].get_returned()) - - @_do_for_all_dbs - def test_invalid_per_name(self, db): - db.add_pername('file', 'key', 'name', -1) - self.assertEquals(None, db.get_pername('file', 'key', 'name')) - - @_do_for_all_dbs - def test_overwriting_per_name(self, db): - db.add_pername('file', 'key', 'name', 1) - db.add_pername('file', 'key', 'name', 2) - self.assertEquals(2, db.get_pername('file', 'key', 'name')) - - @_do_for_all_dbs - def test_not_overwriting_with_invalid_per_name(self, db): - db.add_pername('file', 'key', 'name', 1) - db.add_pername('file', 'key', 'name', -1) - self.assertEquals(1, db.get_pername('file', 'key', 'name')) - - @_do_for_all_dbs - def test_getting_invalid_returned(self, db): - db.add_callinfo('file', 'key', (1, 2), -1) - self.assertEquals(None, db.get_returned('file', 'key', (1, 2))) - - @_do_for_all_dbs - def test_not_overwriting_with_invalid_returned(self, db): - db.add_callinfo('file', 'key', (1, 2), 3) - db.add_callinfo('file', 'key', (1, 2), -1) - self.assertEquals(3, db.get_returned('file', 'key', (1, 2))) - - @_do_for_all_dbs - def test_get_files(self, db): - db.add_callinfo('file1', 'key', (1, 2), 3) - db.add_callinfo('file2', 'key', (1, 2), 3) - self.assertEquals(set(['file1', 'file2']), set(db.get_files())) - - @_do_for_all_dbs - def test_validating_files(self, db): - db.add_callinfo('invalid', 'key', (1, 2), 3) - db.validate_files() - self.assertEquals(0, len(db.get_files())) - - @_do_for_all_dbs - def test_validating_file_for_scopes(self, db): - db.add_callinfo('file', 'invalid', (1, 2), 3) - db.validate_file('file') - self.assertEquals(1, len(db.get_files())) - self.assertEquals(0, len(list(db.get_callinfos('file', 'invalid')))) - - @_do_for_all_dbs - def test_validating_file_moved(self, db): - db.add_callinfo('file', 'key', (1, 2), 3) - - db.file_moved('file', 'newfile') - self.assertEquals(1, len(db.get_files())) - self.assertEquals(1, len(list(db.get_callinfos('newfile', 'key')))) - - @_do_for_all_dbs - def test_using_file_list_observer(self, db): - db.add_callinfo('invalid', 'key', (1, 2), 3) - observer = _MockFileListObserver() - db.add_file_list_observer(observer) - db.validate_files() - self.assertEquals('removed invalid ', observer.log) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(ObjectDBTest)) - return result - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/objectinfertest.py --- a/vim/sadness/ropevim/src/rope/ropetest/objectinfertest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,329 +0,0 @@ -import unittest - -import rope.base.project -import rope.base.builtins -from ropetest import testutils - - -class ObjectInferTest(unittest.TestCase): - - def setUp(self): - super(ObjectInferTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - - def tearDown(self): - testutils.remove_project(self.project) - super(ObjectInferTest, self).tearDown() - - def test_simple_type_inferencing(self): - code = 'class Sample(object):\n pass\na_var = Sample()\n' - scope = self.pycore.get_string_scope(code) - sample_class = scope['Sample'].get_object() - a_var = scope['a_var'].get_object() - self.assertEquals(sample_class, a_var.get_type()) - - def test_simple_type_inferencing_classes_defined_in_holding_scope(self): - code = 'class Sample(object):\n pass\n' \ - 'def a_func():\n a_var = Sample()\n' - scope = self.pycore.get_string_scope(code) - sample_class = scope['Sample'].get_object() - a_var = scope['a_func'].get_object().\ - get_scope()['a_var'].get_object() - self.assertEquals(sample_class, a_var.get_type()) - - def test_simple_type_inferencing_classes_in_class_methods(self): - code = 'class Sample(object):\n pass\n' \ - 'class Another(object):\n' \ - ' def a_method():\n a_var = Sample()\n' - scope = self.pycore.get_string_scope(code) - sample_class = scope['Sample'].get_object() - another_class = scope['Another'].get_object() - a_var = another_class['a_method'].\ - get_object().get_scope()['a_var'].get_object() - self.assertEquals(sample_class, a_var.get_type()) - - def test_simple_type_inferencing_class_attributes(self): - code = 'class Sample(object):\n pass\n' \ - 'class Another(object):\n' \ - ' def __init__(self):\n self.a_var = Sample()\n' - scope = self.pycore.get_string_scope(code) - sample_class = scope['Sample'].get_object() - another_class = scope['Another'].get_object() - a_var = another_class['a_var'].get_object() - self.assertEquals(sample_class, a_var.get_type()) - - def test_simple_type_inferencing_for_in_class_assignments(self): - code = 'class Sample(object):\n pass\n' \ - 'class Another(object):\n an_attr = Sample()\n' - scope = self.pycore.get_string_scope(code) - sample_class = scope['Sample'].get_object() - another_class = scope['Another'].get_object() - an_attr = another_class['an_attr'].get_object() - self.assertEquals(sample_class, an_attr.get_type()) - - def test_simple_type_inferencing_for_chained_assignments(self): - mod = 'class Sample(object):\n pass\n' \ - 'copied_sample = Sample' - mod_scope = self.project.pycore.get_string_scope(mod) - sample_class = mod_scope['Sample'] - copied_sample = mod_scope['copied_sample'] - self.assertEquals(sample_class.get_object(), - copied_sample.get_object()) - - def test_following_chained_assignments_avoiding_circles(self): - mod = 'class Sample(object):\n pass\n' \ - 'sample_class = Sample\n' \ - 'sample_class = sample_class\n' - mod_scope = self.project.pycore.get_string_scope(mod) - sample_class = mod_scope['Sample'] - sample_class_var = mod_scope['sample_class'] - self.assertEquals(sample_class.get_object(), - sample_class_var.get_object()) - - def test_function_returned_object_static_type_inference1(self): - src = 'class Sample(object):\n pass\n' \ - 'def a_func():\n return Sample\n' \ - 'a_var = a_func()\n' - scope = self.project.pycore.get_string_scope(src) - sample_class = scope['Sample'] - a_var = scope['a_var'] - self.assertEquals(sample_class.get_object(), a_var.get_object()) - - def test_function_returned_object_static_type_inference2(self): - src = 'class Sample(object):\n pass\n' \ - 'def a_func():\n return Sample()\n' \ - 'a_var = a_func()\n' - scope = self.project.pycore.get_string_scope(src) - sample_class = scope['Sample'].get_object() - a_var = scope['a_var'].get_object() - self.assertEquals(sample_class, a_var.get_type()) - - def test_recursive_function_returned_object_static_type_inference(self): - src = 'class Sample(object):\n pass\n' \ - 'def a_func():\n' \ - ' if True:\n return Sample()\n' \ - ' else:\n return a_func()\n' \ - 'a_var = a_func()\n' - scope = self.project.pycore.get_string_scope(src) - sample_class = scope['Sample'].get_object() - a_var = scope['a_var'].get_object() - self.assertEquals(sample_class, a_var.get_type()) - - def test_function_returned_object_using_call_special_function_static_type_inference(self): - src = 'class Sample(object):\n' \ - ' def __call__(self):\n return Sample\n' \ - 'sample = Sample()\na_var = sample()' - scope = self.project.pycore.get_string_scope(src) - sample_class = scope['Sample'] - a_var = scope['a_var'] - self.assertEquals(sample_class.get_object(), a_var.get_object()) - - def test_list_type_inferencing(self): - src = 'class Sample(object):\n pass\na_var = [Sample()]\n' - scope = self.pycore.get_string_scope(src) - sample_class = scope['Sample'].get_object() - a_var = scope['a_var'].get_object() - self.assertNotEquals(sample_class, a_var.get_type()) - - def test_attributed_object_inference(self): - src = 'class Sample(object):\n' \ - ' def __init__(self):\n self.a_var = None\n' \ - ' def set(self):\n self.a_var = Sample()\n' - scope = self.pycore.get_string_scope(src) - sample_class = scope['Sample'].get_object() - a_var = sample_class['a_var'].get_object() - self.assertEquals(sample_class, a_var.get_type()) - - def test_getting_property_attributes(self): - src = 'class A(object):\n pass\n' \ - 'def f(*args):\n return A()\n' \ - 'class B(object):\n p = property(f)\n' \ - 'a_var = B().p\n' - pymod = self.pycore.get_string_module(src) - a_class = pymod['A'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(a_class, a_var.get_type()) - - def test_getting_property_attributes_with_method_getters(self): - src = 'class A(object):\n pass\n' \ - 'class B(object):\n def p_get(self):\n return A()\n' \ - ' p = property(p_get)\n' \ - 'a_var = B().p\n' - pymod = self.pycore.get_string_module(src) - a_class = pymod['A'].get_object() - a_var = pymod['a_var'].get_object() - self.assertEquals(a_class, a_var.get_type()) - - def test_lambda_functions(self): - code = 'class C(object):\n pass\n' \ - 'l = lambda: C()\na_var = l()' - mod = self.pycore.get_string_module(code) - c_class = mod['C'].get_object() - a_var = mod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_mixing_subscript_with_tuple_assigns(self): - code = 'class C(object):\n attr = 0\n' \ - 'd = {}\nd[0], b = (0, C())\n' - mod = self.pycore.get_string_module(code) - c_class = mod['C'].get_object() - a_var = mod['b'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_mixing_ass_attr_with_tuple_assignment(self): - code = 'class C(object):\n attr = 0\n' \ - 'c = C()\nc.attr, b = (0, C())\n' - mod = self.pycore.get_string_module(code) - c_class = mod['C'].get_object() - a_var = mod['b'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_mixing_slice_with_tuple_assigns(self): - mod = self.pycore.get_string_module( - 'class C(object):\n attr = 0\n' - 'd = [None] * 3\nd[0:2], b = ((0,), C())\n') - c_class = mod['C'].get_object() - a_var = mod['b'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_nested_tuple_assignments(self): - mod = self.pycore.get_string_module( - 'class C1(object):\n pass\nclass C2(object):\n pass\n' - 'a, (b, c) = (C1(), (C2(), C1()))\n') - c1_class = mod['C1'].get_object() - c2_class = mod['C2'].get_object() - a_var = mod['a'].get_object() - b_var = mod['b'].get_object() - c_var = mod['c'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - self.assertEquals(c1_class, c_var.get_type()) - - def test_empty_tuples(self): - mod = self.pycore.get_string_module('t = ()\na, b = t\n') - a = mod['a'].get_object() - - def test_handling_generator_functions(self): - code = 'class C(object):\n pass\n' \ - 'def f():\n yield C()\n' \ - 'for c in f():\n a_var = c\n' - mod = self.pycore.get_string_module(code) - c_class = mod['C'].get_object() - a_var = mod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_handling_generator_functions_for_strs(self): - mod = testutils.create_module(self.project, 'mod') - mod.write('def f():\n yield ""\n' - 'for s in f():\n a_var = s\n') - pymod = self.pycore.resource_to_pyobject(mod) - a_var = pymod['a_var'].get_object() - self.assertTrue(isinstance(a_var.get_type(), rope.base.builtins.Str)) - - def test_considering_nones_to_be_unknowns(self): - code = 'class C(object):\n pass\n' \ - 'a_var = None\na_var = C()\na_var = None\n' - mod = self.pycore.get_string_module(code) - c_class = mod['C'].get_object() - a_var = mod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_basic_list_comprehensions(self): - code = 'class C(object):\n pass\n' \ - 'l = [C() for i in range(1)]\na_var = l[0]\n' - mod = self.pycore.get_string_module(code) - c_class = mod['C'].get_object() - a_var = mod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_basic_generator_expressions(self): - code = 'class C(object):\n pass\n' \ - 'l = (C() for i in range(1))\na_var = list(l)[0]\n' - mod = self.pycore.get_string_module(code) - c_class = mod['C'].get_object() - a_var = mod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_list_comprehensions_and_loop_var(self): - code = 'class C(object):\n pass\n' \ - 'c_objects = [C(), C()]\n' \ - 'l = [c for c in c_objects]\na_var = l[0]\n' - mod = self.pycore.get_string_module(code) - c_class = mod['C'].get_object() - a_var = mod['a_var'].get_object() - self.assertEquals(c_class, a_var.get_type()) - - def test_list_comprehensions_and_multiple_loop_var(self): - code = 'class C1(object):\n pass\n' \ - 'class C2(object):\n pass\n' \ - 'l = [(c1, c2) for c1 in [C1()] for c2 in [C2()]]\n' \ - 'a, b = l[0]\n' - mod = self.pycore.get_string_module(code) - c1_class = mod['C1'].get_object() - c2_class = mod['C2'].get_object() - a_var = mod['a'].get_object() - b_var = mod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_list_comprehensions_and_multiple_iters(self): - mod = self.pycore.get_string_module( - 'class C1(object):\n pass\nclass C2(object):\n pass\n' - 'l = [(c1, c2) for c1, c2 in [(C1(), C2())]]\n' - 'a, b = l[0]\n') - c1_class = mod['C1'].get_object() - c2_class = mod['C2'].get_object() - a_var = mod['a'].get_object() - b_var = mod['b'].get_object() - self.assertEquals(c1_class, a_var.get_type()) - self.assertEquals(c2_class, b_var.get_type()) - - def test_we_know_the_type_of_catched_exceptions(self): - code = 'class MyError(Exception):\n pass\n' \ - 'try:\n raise MyError()\n' \ - 'except MyError, e:\n pass\n' - mod = self.pycore.get_string_module( - code) - my_error = mod['MyError'].get_object() - e_var = mod['e'].get_object() - self.assertEquals(my_error, e_var.get_type()) - - def test_we_know_the_type_of_catched_multiple_excepts(self): - code = 'class MyError(Exception):\n pass\n' \ - 'try:\n raise MyError()\n' \ - 'except (MyError, Exception), e:\n pass\n' - mod = self.pycore.get_string_module( - code) - my_error = mod['MyError'].get_object() - e_var = mod['e'].get_object() - self.assertEquals(my_error, e_var.get_type()) - - def test_using_property_as_decorators(self): - code = 'class A(object):\n pass\n' \ - 'class B(object):\n' \ - ' @property\n def f(self):\n return A()\n' \ - 'b = B()\nvar = b.f\n' - mod = self.pycore.get_string_module(code) - var = mod['var'].get_object() - a = mod['A'].get_object() - self.assertEquals(a, var.get_type()) - - def test_using_property_as_decorators_and_passing_parameter(self): - code = 'class B(object):\n' \ - ' @property\n def f(self):\n return self\n' \ - 'b = B()\nvar = b.f\n' - mod = self.pycore.get_string_module(code) - var = mod['var'].get_object() - a = mod['B'].get_object() - self.assertEquals(a, var.get_type()) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(ObjectInferTest)) - return result - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/projecttest.py --- a/vim/sadness/ropevim/src/rope/ropetest/projecttest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,958 +0,0 @@ -import os.path -import unittest - -from rope.base.exceptions import RopeError, ResourceNotFoundError -from rope.base.fscommands import FileSystemCommands -from rope.base.libutils import path_to_resource -from rope.base.project import Project, NoProject, _realpath -from ropetest import testutils -from rope.base.resourceobserver import ResourceObserver, FilteredResourceObserver - - - -class ProjectTest(unittest.TestCase): - - def setUp(self): - unittest.TestCase.setUp(self) - self.project = testutils.sample_project(foldername='sampleproject', - ropefolder=None) - self.project_root = self.project.address - self._make_sample_project() - self.no_project = NoProject() - - def _make_sample_project(self): - self.sample_file = 'sample_file.txt' - self.sample_path = os.path.join(self.project_root, 'sample_file.txt') - if not os.path.exists(self.project_root): - os.mkdir(self.project_root) - self.sample_folder = 'sample_folder' - os.mkdir(os.path.join(self.project_root, self.sample_folder)) - sample = open(self.sample_path, 'w') - sample.write('sample text\n') - sample.close() - - def tearDown(self): - testutils.remove_project(self.project) - unittest.TestCase.tearDown(self) - - def test_project_creation(self): - self.assertEquals(_realpath(self.project_root), - self.project.address) - - def test_getting_project_file(self): - project_file = self.project.get_resource(self.sample_file) - self.assertTrue(project_file is not None) - - def test_project_file_reading(self): - projectFile = self.project.get_resource(self.sample_file) - self.assertEquals('sample text\n', projectFile.read()) - - @testutils.assert_raises(ResourceNotFoundError) - def test_getting_not_existing_project_file(self): - projectFile = self.project.get_resource('DoesNotExistFile.txt') - self.fail('Should have failed') - - def test_writing_in_project_files(self): - project_file = self.project.get_resource(self.sample_file) - project_file.write('another text\n') - self.assertEquals('another text\n', project_file.read()) - - def test_creating_files(self): - project_file = 'newfile.txt' - self.project.root.create_file(project_file) - newFile = self.project.get_resource(project_file) - self.assertTrue(newFile is not None) - - @testutils.assert_raises(RopeError) - def test_creating_files_that_already_exist(self): - self.project.root.create_file(self.sample_file) - self.fail('Should have failed') - - def test_making_root_folder_if_it_does_not_exist(self): - project = Project('sampleproject2') - try: - self.assertTrue(os.path.exists('sampleproject2') and - os.path.isdir('sampleproject2')) - finally: - testutils.remove_project(project) - - @testutils.assert_raises(RopeError) - def test_failure_when_project_root_exists_and_is_a_file(self): - try: - project_root = 'sampleproject2' - open(project_root, 'w').close() - project = Project(project_root) - finally: - testutils.remove_recursively(project_root) - - def test_creating_folders(self): - folderName = 'SampleFolder' - self.project.root.create_folder(folderName) - folderPath = os.path.join(self.project.address, folderName) - self.assertTrue(os.path.exists(folderPath) and os.path.isdir(folderPath)) - - @testutils.assert_raises(RopeError) - def test_making_folder_that_already_exists(self): - folderName = 'SampleFolder' - self.project.root.create_folder(folderName) - self.project.root.create_folder(folderName) - - @testutils.assert_raises(RopeError) - def test_failing_if_creating_folder_while_file_already_exists(self): - folderName = 'SampleFolder' - self.project.root.create_file(folderName) - self.project.root.create_folder(folderName) - - def test_creating_file_inside_folder(self): - folder_name = 'sampleFolder' - file_name = 'sample2.txt' - file_path = folder_name + '/' + file_name - parent_folder = self.project.root.create_folder(folder_name) - parent_folder.create_file(file_name) - file = self.project.get_resource(file_path) - file.write('sample notes') - self.assertEquals(file_path, file.path) - self.assertEquals('sample notes', open(os.path.join(self.project.address, - file_path)).read()) - - @testutils.assert_raises(ResourceNotFoundError) - def test_failing_when_creating_file_inside_non_existent_folder(self): - self.project.root.create_file('NonexistentFolder/SomeFile.txt') - - def test_nested_directories(self): - folder_name = 'SampleFolder' - parent = self.project.root.create_folder(folder_name) - parent.create_folder(folder_name) - folder_path = os.path.join(self.project.address, folder_name, folder_name) - self.assertTrue(os.path.exists(folder_path) and os.path.isdir(folder_path)) - - def test_removing_files(self): - self.assertTrue(os.path.exists(self.sample_path)) - self.project.get_resource(self.sample_file).remove() - self.assertFalse(os.path.exists(self.sample_path)) - - def test_removing_files_invalidating_in_project_resource_pool(self): - root_folder = self.project.root - my_file = root_folder.create_file('my_file.txt') - my_file.remove() - self.assertFalse(root_folder.has_child('my_file.txt')) - - def test_removing_directories(self): - self.assertTrue(os.path.exists(os.path.join(self.project.address, - self.sample_folder))) - self.project.get_resource(self.sample_folder).remove() - self.assertFalse(os.path.exists(os.path.join(self.project.address, - self.sample_folder))) - - @testutils.assert_raises(ResourceNotFoundError) - def test_removing_non_existent_files(self): - self.project.get_resource('NonExistentFile.txt').remove() - - def test_removing_nested_files(self): - file_name = self.sample_folder + '/sample_file.txt' - self.project.root.create_file(file_name) - self.project.get_resource(file_name).remove() - self.assertTrue(os.path.exists(os.path.join(self.project.address, - self.sample_folder))) - self.assertTrue(not os.path.exists(os.path.join(self.project.address, - file_name))) - - def test_file_get_name(self): - file = self.project.get_resource(self.sample_file) - self.assertEquals(self.sample_file, file.name) - file_name = 'nestedFile.txt' - parent = self.project.get_resource(self.sample_folder) - filePath = self.sample_folder + '/' + file_name - parent.create_file(file_name) - nestedFile = self.project.get_resource(filePath) - self.assertEquals(file_name, nestedFile.name) - - def test_folder_get_name(self): - folder = self.project.get_resource(self.sample_folder) - self.assertEquals(self.sample_folder, folder.name) - - def test_file_get_path(self): - file = self.project.get_resource(self.sample_file) - self.assertEquals(self.sample_file, file.path) - fileName = 'nestedFile.txt' - parent = self.project.get_resource(self.sample_folder) - filePath = self.sample_folder + '/' + fileName - parent.create_file(fileName) - nestedFile = self.project.get_resource(filePath) - self.assertEquals(filePath, nestedFile.path) - - def test_folder_get_path(self): - folder = self.project.get_resource(self.sample_folder) - self.assertEquals(self.sample_folder, folder.path) - - def test_is_folder(self): - self.assertTrue(self.project.get_resource(self.sample_folder).is_folder()) - self.assertTrue(not self.project.get_resource(self.sample_file).is_folder()) - - def testget_children(self): - children = self.project.get_resource(self.sample_folder).get_children() - self.assertEquals([], children) - - def test_nonempty_get_children(self): - file_name = 'nestedfile.txt' - filePath = self.sample_folder + '/' + file_name - parent = self.project.get_resource(self.sample_folder) - parent.create_file(file_name) - children = parent.get_children() - self.assertEquals(1, len(children)) - self.assertEquals(filePath, children[0].path) - - def test_nonempty_get_children2(self): - file_name = 'nestedfile.txt' - folder_name = 'nestedfolder.txt' - filePath = self.sample_folder + '/' + file_name - folderPath = self.sample_folder + '/' + folder_name - parent = self.project.get_resource(self.sample_folder) - parent.create_file(file_name) - parent.create_folder(folder_name) - children = parent.get_children() - self.assertEquals(2, len(children)) - self.assertTrue(filePath == children[0].path or filePath == children[1].path) - self.assertTrue(folderPath == children[0].path or folderPath == children[1].path) - - def test_getting_files(self): - files = self.project.root.get_files() - self.assertEquals(1, len(files)) - self.assertTrue(self.project.get_resource(self.sample_file) in files) - - def test_getting_folders(self): - folders = self.project.root.get_folders() - self.assertEquals(1, len(folders)) - self.assertTrue(self.project.get_resource(self.sample_folder) in folders) - - def test_nested_folder_get_files(self): - parent = self.project.root.create_folder('top') - parent.create_file('file1.txt') - parent.create_file('file2.txt') - files = parent.get_files() - self.assertEquals(2, len(files)) - self.assertTrue(self.project.get_resource('top/file2.txt') in files) - self.assertEquals(0, len(parent.get_folders())) - - def test_nested_folder_get_folders(self): - parent = self.project.root.create_folder('top') - parent.create_folder('dir1') - parent.create_folder('dir2') - folders = parent.get_folders() - self.assertEquals(2, len(folders)) - self.assertTrue(self.project.get_resource('top/dir1') in folders) - self.assertEquals(0, len(parent.get_files())) - - def test_root_folder(self): - root_folder = self.project.root - self.assertEquals(2, len(root_folder.get_children())) - self.assertEquals('', root_folder.path) - self.assertEquals('', root_folder.name) - - def test_get_all_files(self): - files = tuple(self.project.get_files()) - self.assertEquals(1, len(files)) - self.assertEquals(self.sample_file, files[0].name) - - def test_get_all_files_after_changing(self): - self.assertEquals(1, len(self.project.get_files())) - myfile = self.project.root.create_file('myfile.txt') - self.assertEquals(2, len(self.project.get_files())) - myfile.move('newfile.txt') - self.assertEquals(2, len(self.project.get_files())) - self.project.get_file('newfile.txt').remove() - self.assertEquals(1, len(self.project.get_files())) - - def test_multifile_get_all_files(self): - fileName = 'nestedFile.txt' - parent = self.project.get_resource(self.sample_folder) - parent.create_file(fileName) - files = list(self.project.get_files()) - self.assertEquals(2, len(files)) - self.assertTrue(fileName == files[0].name or fileName == files[1].name) - - def test_ignoring_dot_pyc_files_in_get_files(self): - root = self.project.address - src_folder = os.path.join(root, 'src') - os.mkdir(src_folder) - test_pyc = os.path.join(src_folder, 'test.pyc') - file(test_pyc, 'w').close() - for x in self.project.get_files(): - self.assertNotEquals('src/test.pyc', x.path) - - def test_folder_creating_files(self): - projectFile = 'NewFile.txt' - self.project.root.create_file(projectFile) - new_file = self.project.get_resource(projectFile) - self.assertTrue(new_file is not None and not new_file.is_folder()) - - def test_folder_creating_nested_files(self): - project_file = 'NewFile.txt' - parent_folder = self.project.get_resource(self.sample_folder) - parent_folder.create_file(project_file) - new_file = self.project.get_resource(self.sample_folder - + '/' + project_file) - self.assertTrue(new_file is not None and not new_file.is_folder()) - - def test_folder_creating_files2(self): - projectFile = 'newfolder' - self.project.root.create_folder(projectFile) - new_folder = self.project.get_resource(projectFile) - self.assertTrue(new_folder is not None and new_folder.is_folder()) - - def test_folder_creating_nested_files2(self): - project_file = 'newfolder' - parent_folder = self.project.get_resource(self.sample_folder) - parent_folder.create_folder(project_file) - new_folder = self.project.get_resource(self.sample_folder - + '/' + project_file) - self.assertTrue(new_folder is not None and new_folder.is_folder()) - - def test_folder_get_child(self): - folder = self.project.root - folder.create_file('myfile.txt') - folder.create_folder('myfolder') - self.assertEquals(self.project.get_resource('myfile.txt'), - folder.get_child('myfile.txt')) - self.assertEquals(self.project.get_resource('myfolder'), - folder.get_child('myfolder')) - - def test_folder_get_child_nested(self): - root = self.project.root - folder = root.create_folder('myfolder') - folder.create_file('myfile.txt') - folder.create_folder('myfolder') - self.assertEquals(self.project.get_resource('myfolder/myfile.txt'), - folder.get_child('myfile.txt')) - self.assertEquals(self.project.get_resource('myfolder/myfolder'), - folder.get_child('myfolder')) - - def test_project_root_is_root_folder(self): - self.assertEquals('', self.project.root.path) - - def test_moving_files(self): - root_folder = self.project.root - my_file = root_folder.create_file('my_file.txt') - my_file.move('my_other_file.txt') - self.assertFalse(my_file.exists()) - root_folder.get_child('my_other_file.txt') - - def test_moving_folders(self): - root_folder = self.project.root - my_folder = root_folder.create_folder('my_folder') - my_file = my_folder.create_file('my_file.txt') - my_folder.move('new_folder') - self.assertFalse(root_folder.has_child('my_folder')) - self.assertFalse(my_file.exists()) - self.assertTrue(root_folder.get_child('new_folder') is not None) - - def test_moving_destination_folders(self): - root_folder = self.project.root - my_folder = root_folder.create_folder('my_folder') - my_file = root_folder.create_file('my_file.txt') - my_file.move('my_folder') - self.assertFalse(root_folder.has_child('my_file.txt')) - self.assertFalse(my_file.exists()) - my_folder.get_child('my_file.txt') - - def test_moving_files_and_resource_objects(self): - root_folder = self.project.root - my_file = root_folder.create_file('my_file.txt') - old_hash = hash(my_file) - my_file.move('my_other_file.txt') - self.assertEquals(old_hash, hash(my_file)) - - def test_file_encoding_reading(self): - sample_file = self.project.root.create_file('my_file.txt') - contents = u'# -*- coding: utf-8 -*-\n#\N{LATIN SMALL LETTER I WITH DIAERESIS}\n' - file = open(sample_file.real_path, 'w') - file.write(contents.encode('utf-8')) - file.close() - self.assertEquals(contents, sample_file.read()) - - def test_file_encoding_writing(self): - sample_file = self.project.root.create_file('my_file.txt') - contents = u'# -*- coding: utf-8 -*-\n\N{LATIN SMALL LETTER I WITH DIAERESIS}\n' - sample_file.write(contents) - self.assertEquals(contents, sample_file.read()) - - def test_using_utf8_when_writing_in_case_of_errors(self): - sample_file = self.project.root.create_file('my_file.txt') - contents = u'\n\N{LATIN SMALL LETTER I WITH DIAERESIS}\n' - sample_file.write(contents) - self.assertEquals(contents, sample_file.read()) - - def test_encoding_declaration_in_the_second_line(self): - sample_file = self.project.root.create_file('my_file.txt') - contents = '\n# -*- coding: latin-1 -*-\n\xa9\n' - file = open(sample_file.real_path, 'wb') - file.write(contents) - file.close() - self.assertEquals(contents, sample_file.read().encode('latin-1')) - - def test_read_bytes(self): - sample_file = self.project.root.create_file('my_file.txt') - contents = '\n# -*- coding: latin-1 -*-\n\xa9\n' - file = open(sample_file.real_path, 'wb') - file.write(contents) - file.close() - self.assertEquals(contents, sample_file.read_bytes()) - - # TODO: Detecting utf-16 encoding - def xxx_test_using_utf16(self): - sample_file = self.project.root.create_file('my_file.txt') - contents = '# -*- coding: utf-16 -*-\n# This is a sample file ...\n' - file = open(sample_file.real_path, 'w') - file.write(contents.encode('utf-16')) - file.close() - sample_file.write(contents) - self.assertEquals(contents, sample_file.read()) - - # XXX: supporting utf_8_sig - def xxx_test_file_encoding_reading_for_notepad_styles(self): - sample_file = self.project.root.create_file('my_file.txt') - contents = u'#\N{LATIN SMALL LETTER I WITH DIAERESIS}\n' - file = open(sample_file.real_path, 'w') - # file.write('\xef\xbb\xbf') - file.write(contents.encode('utf-8-sig')) - file.close() - self.assertEquals(contents, sample_file.read()) - - def test_using_project_get_file(self): - myfile = self.project.get_file(self.sample_file) - self.assertTrue(myfile.exists()) - - def test_using_file_create(self): - myfile = self.project.get_file('myfile.txt') - self.assertFalse(myfile.exists()) - myfile.create() - self.assertTrue(myfile.exists()) - self.assertFalse(myfile.is_folder()) - - def test_using_folder_create(self): - myfolder = self.project.get_folder('myfolder') - self.assertFalse(myfolder.exists()) - myfolder.create() - self.assertTrue(myfolder.exists()) - self.assertTrue(myfolder.is_folder()) - - @testutils.assert_raises(RopeError) - def test_exception_when_creating_twice(self): - myfile = self.project.get_file('myfile.txt') - myfile.create() - myfile.create() - - @testutils.assert_raises(ResourceNotFoundError) - def test_exception_when_parent_does_not_exist(self): - myfile = self.project.get_file('myfolder/myfile.txt') - myfile.create() - - def test_simple_path_to_resource(self): - myfile = self.project.root.create_file('myfile.txt') - self.assertEquals(myfile, path_to_resource(self.project, - myfile.real_path)) - self.assertEquals(myfile, path_to_resource( - self.project, myfile.real_path, type='file')) - myfolder = self.project.root.create_folder('myfolder') - self.assertEquals(myfolder, path_to_resource(self.project, - myfolder.real_path)) - self.assertEquals(myfolder, path_to_resource( - self.project, myfolder.real_path, type='folder')) - - @testutils.run_only_for_unix - def test_ignoring_symlinks_inside_project(self): - project2 = testutils.sample_project(folder_name='sampleproject2') - mod = project2.root.create_file('mod.py') - try: - path = os.path.join(self.project.address, 'linkedfile.txt') - os.symlink(mod.real_path, path) - files = self.project.root.get_files() - self.assertEquals(1, len(files)) - finally: - testutils.remove_project(project2) - - -class ResourceObserverTest(unittest.TestCase): - - def setUp(self): - super(ResourceObserverTest, self).setUp() - self.project = testutils.sample_project() - - def tearDown(self): - testutils.remove_project(self.project) - super(ResourceObserverTest, self).tearDown() - - def test_resource_change_observer(self): - sample_file = self.project.root.create_file('my_file.txt') - sample_file.write('a sample file version 1') - sample_observer = _SampleObserver() - self.project.add_observer(sample_observer) - sample_file.write('a sample file version 2') - self.assertEquals(1, sample_observer.change_count) - self.assertEquals(sample_file, sample_observer.last_changed) - - def test_resource_change_observer_after_removal(self): - sample_file = self.project.root.create_file('my_file.txt') - sample_file.write('text') - sample_observer = _SampleObserver() - self.project.add_observer(FilteredResourceObserver(sample_observer, - [sample_file])) - sample_file.remove() - self.assertEquals(1, sample_observer.change_count) - self.assertEquals(sample_file, sample_observer.last_removed) - - def test_resource_change_observer2(self): - sample_file = self.project.root.create_file('my_file.txt') - sample_observer = _SampleObserver() - self.project.add_observer(sample_observer) - self.project.remove_observer(sample_observer) - sample_file.write('a sample file version 2') - self.assertEquals(0, sample_observer.change_count) - - def test_resource_change_observer_for_folders(self): - root_folder = self.project.root - my_folder = root_folder.create_folder('my_folder') - my_folder_observer = _SampleObserver() - root_folder_observer = _SampleObserver() - self.project.add_observer(FilteredResourceObserver(my_folder_observer, - [my_folder])) - self.project.add_observer(FilteredResourceObserver(root_folder_observer, - [root_folder])) - my_file = my_folder.create_file('my_file.txt') - self.assertEquals(1, my_folder_observer.change_count) - my_file.move('another_file.txt') - self.assertEquals(2, my_folder_observer.change_count) - self.assertEquals(1, root_folder_observer.change_count) - self.project.get_resource('another_file.txt').remove() - self.assertEquals(2, my_folder_observer.change_count) - self.assertEquals(2, root_folder_observer.change_count) - - def test_resource_change_observer_after_moving(self): - sample_file = self.project.root.create_file('my_file.txt') - sample_observer = _SampleObserver() - self.project.add_observer(sample_observer) - sample_file.move('new_file.txt') - self.assertEquals(1, sample_observer.change_count) - self.assertEquals((sample_file, self.project.get_resource('new_file.txt')), - sample_observer.last_moved) - - def test_revalidating_files(self): - root = self.project.root - my_file = root.create_file('my_file.txt') - sample_observer = _SampleObserver() - self.project.add_observer(FilteredResourceObserver(sample_observer, - [my_file])) - os.remove(my_file.real_path) - self.project.validate(root) - self.assertEquals(my_file, sample_observer.last_removed) - self.assertEquals(1, sample_observer.change_count) - - def test_revalidating_files_and_no_changes2(self): - root = self.project.root - my_file = root.create_file('my_file.txt') - sample_observer = _SampleObserver() - self.project.add_observer(FilteredResourceObserver(sample_observer, - [my_file])) - self.project.validate(root) - self.assertEquals(None, sample_observer.last_moved) - self.assertEquals(0, sample_observer.change_count) - - def test_revalidating_folders(self): - root = self.project.root - my_folder = root.create_folder('myfolder') - my_file = my_folder.create_file('myfile.txt') - sample_observer = _SampleObserver() - self.project.add_observer(FilteredResourceObserver(sample_observer, - [my_folder])) - testutils.remove_recursively(my_folder.real_path) - self.project.validate(root) - self.assertEquals(my_folder, sample_observer.last_removed) - self.assertEquals(1, sample_observer.change_count) - - def test_removing_and_adding_resources_to_filtered_observer(self): - my_file = self.project.root.create_file('my_file.txt') - sample_observer = _SampleObserver() - filtered_observer = FilteredResourceObserver(sample_observer) - self.project.add_observer(filtered_observer) - my_file.write('1') - self.assertEquals(0, sample_observer.change_count) - filtered_observer.add_resource(my_file) - my_file.write('2') - self.assertEquals(1, sample_observer.change_count) - filtered_observer.remove_resource(my_file) - my_file.write('3') - self.assertEquals(1, sample_observer.change_count) - - def test_validation_and_changing_files(self): - my_file = self.project.root.create_file('my_file.txt') - sample_observer = _SampleObserver() - timekeeper = _MockChangeIndicator() - filtered_observer = FilteredResourceObserver(sample_observer, [my_file], - timekeeper=timekeeper) - self.project.add_observer(filtered_observer) - self._write_file(my_file.real_path) - timekeeper.set_indicator(my_file, 1) - self.project.validate(self.project.root) - self.assertEquals(1, sample_observer.change_count) - - def test_validation_and_changing_files2(self): - my_file = self.project.root.create_file('my_file.txt') - sample_observer = _SampleObserver() - timekeeper = _MockChangeIndicator() - self.project.add_observer(FilteredResourceObserver( - sample_observer, [my_file], - timekeeper=timekeeper)) - timekeeper.set_indicator(my_file, 1) - my_file.write('hey') - self.assertEquals(1, sample_observer.change_count) - self.project.validate(self.project.root) - self.assertEquals(1, sample_observer.change_count) - - def test_not_reporting_multiple_changes_to_folders(self): - root = self.project.root - file1 = root.create_file('file1.txt') - file2 = root.create_file('file2.txt') - sample_observer = _SampleObserver() - self.project.add_observer(FilteredResourceObserver( - sample_observer, [root, file1, file2])) - os.remove(file1.real_path) - os.remove(file2.real_path) - self.assertEquals(0, sample_observer.change_count) - self.project.validate(self.project.root) - self.assertEquals(3, sample_observer.change_count) - - def _write_file(self, path): - my_file = open(path, 'w') - my_file.write('\n') - my_file.close() - - def test_moving_and_being_interested_about_a_folder_and_a_child(self): - my_folder = self.project.root.create_folder('my_folder') - my_file = my_folder.create_file('my_file.txt') - sample_observer = _SampleObserver() - filtered_observer = FilteredResourceObserver( - sample_observer, [my_folder, my_file]) - self.project.add_observer(filtered_observer) - my_folder.move('new_folder') - self.assertEquals(2, sample_observer.change_count) - - def test_contains_for_folders(self): - folder1 = self.project.root.create_folder('folder') - folder2 = self.project.root.create_folder('folder2') - self.assertFalse(folder1.contains(folder2)) - - def test_validating_when_created(self): - root = self.project.root - my_file = self.project.get_file('my_file.txt') - sample_observer = _SampleObserver() - self.project.add_observer(FilteredResourceObserver(sample_observer, - [my_file])) - file(my_file.real_path, 'w').close() - self.project.validate(root) - self.assertEquals(my_file, sample_observer.last_created) - self.assertEquals(1, sample_observer.change_count) - - def test_validating_twice_when_created(self): - root = self.project.root - my_file = self.project.get_file('my_file.txt') - sample_observer = _SampleObserver() - self.project.add_observer(FilteredResourceObserver(sample_observer, - [my_file])) - file(my_file.real_path, 'w').close() - self.project.validate(root) - self.project.validate(root) - self.assertEquals(my_file, sample_observer.last_created) - self.assertEquals(1, sample_observer.change_count) - - def test_changes_and_adding_resources(self): - root = self.project.root - file1 = self.project.get_file('file1.txt') - file2 = self.project.get_file('file2.txt') - file1.create() - sample_observer = _SampleObserver() - self.project.add_observer(FilteredResourceObserver(sample_observer, - [file1, file2])) - file1.move(file2.path) - self.assertEquals(2, sample_observer.change_count) - self.assertEquals(file2, sample_observer.last_created) - self.assertEquals((file1, file2), sample_observer.last_moved) - - def test_validating_get_files_list(self): - root = self.project.root - self.assertEquals(0, len(self.project.get_files())) - file = open(os.path.join(self.project.address, 'myfile.txt'), 'w') - file.close() - self.project.validate() - self.assertEquals(1, len(self.project.get_files())) - - def test_clear_observered_resources_for_filtered_observers(self): - sample_file = self.project.root.create_file('myfile.txt') - sample_observer = _SampleObserver() - filtered = FilteredResourceObserver(sample_observer) - self.project.add_observer(filtered) - filtered.add_resource(sample_file) - filtered.clear_resources() - sample_file.write('1') - self.assertEquals(0, sample_observer.change_count) - - -class _MockChangeIndicator(object): - - def __init__(self): - self.times = {} - - def set_indicator(self, resource, time): - self.times[resource] = time - - def get_indicator(self, resource): - return self.times.get(resource, 0) - - -class _SampleObserver(object): - - def __init__(self): - self.change_count = 0 - self.last_changed = None - self.last_moved = None - self.last_created = None - self.last_removed = None - - def resource_changed(self, resource): - self.last_changed = resource - self.change_count += 1 - - def resource_moved(self, resource, new_resource): - self.last_moved = (resource, new_resource) - self.change_count += 1 - - def resource_created(self, resource): - self.last_created = resource - self.change_count += 1 - - def resource_removed(self, resource): - self.last_removed = resource - self.change_count += 1 - - -class OutOfProjectTest(unittest.TestCase): - - def setUp(self): - super(OutOfProjectTest, self).setUp() - self.test_directory = 'temp_test_directory' - testutils.remove_recursively(self.test_directory) - os.mkdir(self.test_directory) - self.project = testutils.sample_project() - self.no_project = NoProject() - - def tearDown(self): - testutils.remove_project(self.project) - testutils.remove_recursively(self.test_directory) - super(OutOfProjectTest, self).tearDown() - - def test_simple_out_of_project_file(self): - sample_file_path = os.path.join(self.test_directory, 'sample.txt') - sample_file = file(sample_file_path, 'w') - sample_file.write('sample content\n') - sample_file.close() - sample_resource = self.no_project.get_resource(sample_file_path) - self.assertEquals('sample content\n', sample_resource.read()) - - def test_simple_out_of_project_folder(self): - sample_folder_path = os.path.join(self.test_directory, 'sample_folder') - os.mkdir(sample_folder_path) - sample_folder = self.no_project.get_resource(sample_folder_path) - self.assertEquals([], sample_folder.get_children()) - - sample_file_path = os.path.join(sample_folder_path, 'sample.txt') - file(sample_file_path, 'w').close() - sample_resource = self.no_project.get_resource(sample_file_path) - self.assertEquals(sample_resource, sample_folder.get_children()[0]) - - def test_using_absolute_path(self): - sample_file_path = os.path.join(self.test_directory, 'sample.txt') - file(sample_file_path, 'w').close() - normal_sample_resource = self.no_project.get_resource(sample_file_path) - absolute_sample_resource = \ - self.no_project.get_resource(os.path.abspath(sample_file_path)) - self.assertEquals(normal_sample_resource, absolute_sample_resource) - - def test_folder_get_child(self): - sample_folder_path = os.path.join(self.test_directory, 'sample_folder') - os.mkdir(sample_folder_path) - sample_folder = self.no_project.get_resource(sample_folder_path) - self.assertEquals([], sample_folder.get_children()) - - sample_file_path = os.path.join(sample_folder_path, 'sample.txt') - file(sample_file_path, 'w').close() - sample_resource = self.no_project.get_resource(sample_file_path) - self.assertTrue(sample_folder.has_child('sample.txt')) - self.assertFalse(sample_folder.has_child('doesnothave.txt')) - self.assertEquals(sample_resource, sample_folder.get_child('sample.txt')) - - def test_out_of_project_files_and_path_to_resource(self): - sample_file_path = os.path.join(self.test_directory, 'sample.txt') - sample_file = file(sample_file_path, 'w') - sample_file.write('sample content\n') - sample_file.close() - sample_resource = self.no_project.get_resource(sample_file_path) - self.assertEquals(sample_resource, - path_to_resource(self.project, sample_file_path)) - - -class _MockFSCommands(object): - - def __init__(self): - self.log = '' - self.fscommands = FileSystemCommands() - - def create_file(self, path): - self.log += 'create_file ' - self.fscommands.create_file(path) - - def create_folder(self, path): - self.log += 'create_folder ' - self.fscommands.create_folder(path) - - def move(self, path, new_location): - self.log += 'move ' - self.fscommands.move(path, new_location) - - def remove(self, path): - self.log += 'remove ' - self.fscommands.remove(path) - - -class RopeFolderTest(unittest.TestCase): - - def setUp(self): - super(RopeFolderTest, self).setUp() - self.project = None - - def tearDown(self): - if self.project: - testutils.remove_project(self.project) - super(RopeFolderTest, self).tearDown() - - def test_none_project_rope_folder(self): - self.project = testutils.sample_project(ropefolder=None) - self.assertTrue(self.project.ropefolder is None) - - def test_getting_project_rope_folder(self): - self.project = testutils.sample_project(ropefolder='.ropeproject') - self.assertTrue(self.project.ropefolder.exists()) - self.assertTrue('.ropeproject', self.project.ropefolder.path) - - def test_setting_ignored_resources(self): - self.project = testutils.sample_project(ignored_resources=['myfile.txt']) - myfile = self.project.get_file('myfile.txt') - file2 = self.project.get_file('file2.txt') - self.assertTrue(self.project.is_ignored(myfile)) - self.assertFalse(self.project.is_ignored(file2)) - - def test_ignored_folders(self): - self.project = testutils.sample_project(ignored_resources=['myfolder']) - myfolder = self.project.root.create_folder('myfolder') - self.assertTrue(self.project.is_ignored(myfolder)) - myfile = myfolder.create_file('myfile.txt') - self.assertTrue(self.project.is_ignored(myfile)) - - def test_ignored_resources_and_get_files(self): - self.project = testutils.sample_project( - ignored_resources=['myfile.txt'], ropefolder=None) - myfile = self.project.get_file('myfile.txt') - self.assertEquals(0, len(self.project.get_files())) - myfile.create() - self.assertEquals(0, len(self.project.get_files())) - - def test_ignored_resources_and_get_files2(self): - self.project = testutils.sample_project( - ignored_resources=['myfile.txt'], ropefolder=None) - myfile = self.project.root.create_file('myfile.txt') - self.assertEquals(0, len(self.project.get_files())) - - def test_setting_ignored_resources_patterns(self): - self.project = testutils.sample_project(ignored_resources=['m?file.*']) - myfile = self.project.get_file('myfile.txt') - file2 = self.project.get_file('file2.txt') - self.assertTrue(self.project.is_ignored(myfile)) - self.assertFalse(self.project.is_ignored(file2)) - - def test_star_should_not_include_slashes(self): - self.project = testutils.sample_project(ignored_resources=['f*.txt']) - folder = self.project.root.create_folder('folder') - file1 = folder.create_file('myfile.txt') - file2 = folder.create_file('file2.txt') - self.assertFalse(self.project.is_ignored(file1)) - self.assertTrue(self.project.is_ignored(file2)) - - def test_normal_fscommands(self): - fscommands = _MockFSCommands() - self.project = testutils.sample_project(fscommands=fscommands) - myfile = self.project.get_file('myfile.txt') - myfile.create() - self.assertTrue('create_file ', fscommands.log) - - def test_fscommands_and_ignored_resources(self): - fscommands = _MockFSCommands() - self.project = testutils.sample_project( - fscommands=fscommands, ignored_resources=['myfile.txt'], ropefolder=None) - myfile = self.project.get_file('myfile.txt') - myfile.create() - self.assertEquals('', fscommands.log) - - def test_ignored_resources_and_prefixes(self): - self.project = testutils.sample_project( - ignored_resources=['.hg']) - myfile = self.project.root.create_file('.hgignore') - self.assertFalse(self.project.is_ignored(myfile)) - - def test_loading_config_dot_py(self): - self.project = testutils.sample_project(ropefolder='.ropeproject') - config = self.project.get_file('.ropeproject/config.py') - if not config.exists(): - config.create() - config.write('def set_prefs(prefs):\n' - ' prefs["ignored_resources"] = ["myfile.txt"]\n' - 'def project_opened(project):\n' - ' project.root.create_file("loaded")\n') - self.project.close() - self.project = Project(self.project.address, ropefolder='.ropeproject') - self.assertTrue(self.project.get_file('loaded').exists()) - myfile = self.project.get_file('myfile.txt') - self.assertTrue(self.project.is_ignored(myfile)) - - def test_ignoring_syntax_errors(self): - self.project = testutils.sample_project(ropefolder=None, - ignore_syntax_errors=True) - pycore = self.project.pycore - mod = testutils.create_module(self.project, 'mod') - mod.write('xyz print') - pymod = pycore.resource_to_pyobject(mod) - - def test_compressed_history(self): - self.project = testutils.sample_project(compress_history=True) - mod = testutils.create_module(self.project, 'mod') - mod.write('') - - def test_compressed_objectdb(self): - self.project = testutils.sample_project(compress_objectdb=True) - mod = testutils.create_module(self.project, 'mod') - self.project.pycore.analyze_module(mod) - - def test_nested_dot_ropeproject_folder(self): - self.project = testutils.sample_project(ropefolder='.f1/f2') - ropefolder = self.project.ropefolder - self.assertEquals('.f1/f2', ropefolder.path) - self.assertTrue(ropefolder.exists()) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(ProjectTest)) - result.addTests(unittest.makeSuite(ResourceObserverTest)) - result.addTests(unittest.makeSuite(OutOfProjectTest)) - result.addTests(unittest.makeSuite(RopeFolderTest)) - return result - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/pycoretest.py --- a/vim/sadness/ropevim/src/rope/ropetest/pycoretest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1110 +0,0 @@ -import sys -import unittest - -from rope.base import exceptions -from rope.base.pycore import _TextChangeDetector -from rope.base.pyobjects import get_base_type, AbstractFunction -from ropetest import testutils - - -class PyCoreTest(unittest.TestCase): - - def setUp(self): - super(PyCoreTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - - def tearDown(self): - testutils.remove_project(self.project) - super(PyCoreTest, self).tearDown() - - def test_simple_module(self): - testutils.create_module(self.project, 'mod') - result = self.pycore.get_module('mod') - self.assertEquals(get_base_type('Module'), result.type) - self.assertEquals(0, len(result.get_attributes())) - - def test_nested_modules(self): - pkg = testutils.create_package(self.project, 'pkg') - mod = testutils.create_module(self.project, 'mod', pkg) - package = self.pycore.get_module('pkg') - self.assertEquals(get_base_type('Module'), package.get_type()) - self.assertEquals(1, len(package.get_attributes())) - module = package['mod'].get_object() - self.assertEquals(get_base_type('Module'), module.get_type()) - - def test_package(self): - pkg = testutils.create_package(self.project, 'pkg') - mod = testutils.create_module(self.project, 'mod', pkg) - result = self.pycore.get_module('pkg') - self.assertEquals(get_base_type('Module'), result.type) - - def test_simple_class(self): - mod = testutils.create_module(self.project, 'mod') - mod.write('class SampleClass(object):\n pass\n') - mod_element = self.pycore.get_module('mod') - result = mod_element['SampleClass'].get_object() - self.assertEquals(get_base_type('Type'), result.get_type()) - - def test_simple_function(self): - mod = testutils.create_module(self.project, 'mod') - mod.write('def sample_function():\n pass\n') - mod_element = self.pycore.get_module('mod') - result = mod_element['sample_function'].get_object() - self.assertEquals(get_base_type('Function'), result.get_type()) - - def test_class_methods(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class SampleClass(object):\n' \ - ' def sample_method(self):\n' \ - ' pass\n' - mod.write(code) - mod_element = self.pycore.get_module('mod') - sample_class = mod_element['SampleClass'].get_object() - self.assertTrue('sample_method' in sample_class) - method = sample_class['sample_method'].get_object() - self.assertEquals(get_base_type('Function'), method.get_type()) - - def test_global_variables(self): - mod = testutils.create_module(self.project, 'mod') - mod.write('var = 10') - mod_element = self.pycore.get_module('mod') - result = mod_element['var'] - - def test_class_variables(self): - mod = testutils.create_module(self.project, 'mod') - mod.write('class SampleClass(object):\n var = 10\n') - mod_element = self.pycore.get_module('mod') - sample_class = mod_element['SampleClass'].get_object() - var = sample_class['var'] - - def test_class_attributes_set_in_init(self): - mod = testutils.create_module(self.project, 'mod') - mod.write('class C(object):\n' - ' def __init__(self):\n self.var = 20\n') - mod_element = self.pycore.get_module('mod') - sample_class = mod_element['C'].get_object() - var = sample_class['var'] - - def test_class_attributes_set_in_init_overwriting_a_defined(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C(object):\n' \ - ' def __init__(self):\n' \ - ' self.f = 20\n' \ - ' def f():\n' \ - ' pass\n' - mod.write(code) - mod_element = self.pycore.get_module('mod') - sample_class = mod_element['C'].get_object() - f = sample_class['f'].get_object() - self.assertTrue(isinstance(f, AbstractFunction)) - - def test_classes_inside_other_classes(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class SampleClass(object):\n' \ - ' class InnerClass(object):\n' \ - ' pass\n\n' - mod.write(code) - mod_element = self.pycore.get_module('mod') - sample_class = mod_element['SampleClass'].get_object() - var = sample_class['InnerClass'].get_object() - self.assertEquals(get_base_type('Type'), var.get_type()) - - @testutils.assert_raises(exceptions.ModuleNotFoundError) - def test_non_existent_module(self): - self.pycore.get_module('doesnotexistmodule') - - def test_imported_names(self): - testutils.create_module(self.project, 'mod1') - mod = testutils.create_module(self.project, 'mod2') - mod.write('import mod1\n') - module = self.pycore.get_module('mod2') - imported_sys = module['mod1'].get_object() - self.assertEquals(get_base_type('Module'), imported_sys.get_type()) - - def test_imported_as_names(self): - testutils.create_module(self.project, 'mod1') - mod = testutils.create_module(self.project, 'mod2') - mod.write('import mod1 as my_import\n') - module = self.pycore.get_module('mod2') - imported_mod = module['my_import'].get_object() - self.assertEquals(get_base_type('Module'), imported_mod.get_type()) - - def test_get_string_module(self): - mod = self.pycore.get_string_module('class Sample(object):\n pass\n') - sample_class = mod['Sample'].get_object() - self.assertEquals(get_base_type('Type'), sample_class.get_type()) - - def test_get_string_module_with_extra_spaces(self): - mod = self.pycore.get_string_module('a = 10\n ') - - def test_parameter_info_for_functions(self): - code = 'def func(param1, param2=10, *param3, **param4):\n pass' - mod = self.pycore.get_string_module(code) - sample_function = mod['func'] - self.assertEquals(['param1', 'param2', 'param3', 'param4'], - sample_function.get_object().get_param_names()) - - # FIXME: Not found modules - def xxx_test_not_found_module_is_module(self): - mod = self.pycore.get_string_module('import doesnotexist\n') - self.assertEquals(get_base_type('Module'), - mod['doesnotexist']. - get_object().get_type()) - - def test_mixing_scopes_and_objects_hierarchy(self): - mod = self.pycore.get_string_module('var = 200\n') - scope = mod.get_scope() - self.assertTrue('var' in scope.get_names()) - - def test_inheriting_base_class_attributes(self): - code = 'class Base(object):\n' \ - ' def method(self):\n' \ - ' pass\n' \ - 'class Derived(Base):\n' \ - ' pass\n' - mod = self.pycore.get_string_module(code) - derived = mod['Derived'].get_object() - self.assertTrue('method' in derived) - self.assertEquals(get_base_type('Function'), - derived['method'].get_object().get_type()) - - def test_inheriting_multiple_base_class_attributes(self): - code = 'class Base1(object):\n def method1(self):\n pass\n' \ - 'class Base2(object):\n def method2(self):\n pass\n' \ - 'class Derived(Base1, Base2):\n pass\n' - mod = self.pycore.get_string_module(code) - derived = mod['Derived'].get_object() - self.assertTrue('method1' in derived) - self.assertTrue('method2' in derived) - - def test_inheriting_multiple_base_class_attributes_with_the_same_name(self): - code = 'class Base1(object):\n def method(self):\n pass\n' \ - 'class Base2(object):\n def method(self):\n pass\n' \ - 'class Derived(Base1, Base2):\n pass\n' - mod = self.pycore.get_string_module(code) - base1 = mod['Base1'].get_object() - derived = mod['Derived'].get_object() - self.assertEquals(base1['method'].get_object(), - derived['method'].get_object()) - - def test_inheriting_unknown_base_class(self): - code = 'class Derived(NotFound):\n' \ - ' def f(self):\n' \ - ' pass\n' - mod = self.pycore.get_string_module(code) - derived = mod['Derived'].get_object() - self.assertTrue('f' in derived) - - def test_module_creation(self): - new_module = testutils.create_module(self.project, 'module') - self.assertFalse(new_module.is_folder()) - self.assertEquals(self.project.get_resource('module.py'), new_module) - - def test_packaged_module_creation(self): - package = self.project.root.create_folder('package') - new_module = testutils.create_module(self.project, 'package.module') - self.assertEquals(self.project.get_resource('package/module.py'), new_module) - - def test_packaged_module_creation_with_nested_src(self): - src = self.project.root.create_folder('src') - package = src.create_folder('pkg') - new_module = testutils.create_module(self.project, 'pkg.mod', src) - self.assertEquals(self.project.get_resource('src/pkg/mod.py'), new_module) - - def test_package_creation(self): - new_package = testutils.create_package(self.project, 'pkg') - self.assertTrue(new_package.is_folder()) - self.assertEquals(self.project.get_resource('pkg'), new_package) - self.assertEquals(self.project.get_resource('pkg/__init__.py'), - new_package.get_child('__init__.py')); - - def test_nested_package_creation(self): - package = testutils.create_package(self.project, 'pkg1') - nested_package = testutils.create_package(self.project, 'pkg1.pkg2') - self.assertEquals(self.project.get_resource('pkg1/pkg2'), nested_package) - - def test_packaged_package_creation_with_nested_src(self): - src = self.project.root.create_folder('src') - package = testutils.create_package(self.project, 'pkg1', src) - nested_package = testutils.create_package(self.project, 'pkg1.pkg2', src) - self.assertEquals(self.project.get_resource('src/pkg1/pkg2'), nested_package) - - def test_find_module(self): - src = self.project.root.create_folder('src') - samplemod = testutils.create_module(self.project, 'samplemod', src) - found_module = self.pycore.find_module('samplemod') - self.assertEquals(samplemod, found_module) - - def test_find_nested_module(self): - src = self.project.root.create_folder('src') - samplepkg = testutils.create_package(self.project, 'samplepkg', src) - samplemod = testutils.create_module(self.project, 'samplemod', samplepkg) - found_module = self.pycore.find_module('samplepkg.samplemod') - self.assertEquals(samplemod, found_module) - - def test_find_multiple_module(self): - src = self.project.root.create_folder('src') - samplemod1 = testutils.create_module(self.project, 'samplemod', src) - samplemod2 = testutils.create_module(self.project, 'samplemod') - test = self.project.root.create_folder('test') - samplemod3 = testutils.create_module(self.project, 'samplemod', test) - found_module = self.pycore.find_module('samplemod') - self.assertTrue(samplemod1 == found_module or - samplemod2 == found_module or - samplemod3 == found_module) - - def test_find_module_packages(self): - src = self.project.root - samplepkg = testutils.create_package(self.project, 'samplepkg', src) - found_module = self.pycore.find_module('samplepkg') - self.assertEquals(samplepkg, found_module) - - def test_find_module_when_module_and_package_with_the_same_name(self): - src = self.project.root - samplemod = testutils.create_module(self.project, 'sample', src) - samplepkg = testutils.create_package(self.project, 'sample', src) - found_module = self.pycore.find_module('sample') - self.assertEquals(samplepkg, found_module) - - def test_source_folders_preference(self): - pkg1 = testutils.create_package(self.project, 'pkg1') - src2 = testutils.create_package(self.project, 'pkg1.src2') - lost = testutils.create_module(self.project, 'pkg1.src2.lost') - self.assertEqual(self.project.pycore.find_module('lost'), None) - self.project.close() - from rope.base.project import Project - self.project = Project(self.project.address, - source_folders=['pkg1/src2']) - self.assertEqual(self.project.pycore.find_module('lost'), lost) - - def test_getting_empty_source_folders(self): - self.assertEquals([], self.pycore.get_source_folders()) - - def test_root_source_folder(self): - self.project.root.create_file('sample.py') - source_folders = self.pycore.get_source_folders() - self.assertEquals(1, len(source_folders)) - self.assertTrue(self.project.root in source_folders) - - def test_root_source_folder2(self): - self.project.root.create_file('mod1.py') - self.project.root.create_file('mod2.py') - source_folders = self.pycore.get_source_folders() - self.assertEquals(1, len(source_folders)) - self.assertTrue(self.project.root in source_folders) - - def test_src_source_folder(self): - src = self.project.root.create_folder('src') - src.create_file('sample.py') - source_folders = self.pycore.get_source_folders() - self.assertEquals(1, len(source_folders)) - self.assertTrue(self.project.get_resource('src') in source_folders) - - def test_packages(self): - src = self.project.root.create_folder('src') - pkg = src.create_folder('package') - pkg.create_file('__init__.py') - source_folders = self.pycore.get_source_folders() - self.assertEquals(1, len(source_folders)) - self.assertTrue(src in source_folders) - - def test_multi_source_folders(self): - src = self.project.root.create_folder('src') - package = src.create_folder('package') - package.create_file('__init__.py') - test = self.project.root.create_folder('test') - test.create_file('alltests.py') - source_folders = self.pycore.get_source_folders() - self.assertEquals(2, len(source_folders)) - self.assertTrue(src in source_folders) - self.assertTrue(test in source_folders) - - def test_multi_source_folders2(self): - mod1 = testutils.create_module(self.project, 'mod1') - src = self.project.root.create_folder('src') - package = testutils.create_package(self.project, 'package', src) - mod2 = testutils.create_module(self.project, 'mod2', package) - source_folders = self.pycore.get_source_folders() - self.assertEquals(2, len(source_folders)) - self.assertTrue(self.project.root in source_folders and \ - src in source_folders) - - def test_get_pyname_definition_location(self): - mod = self.pycore.get_string_module('a_var = 20\n') - a_var = mod['a_var'] - self.assertEquals((mod, 1), a_var.get_definition_location()) - - def test_get_pyname_definition_location_functions(self): - mod = self.pycore.get_string_module('def a_func():\n pass\n') - a_func = mod['a_func'] - self.assertEquals((mod, 1), a_func.get_definition_location()) - - def test_get_pyname_definition_location_class(self): - code = 'class AClass(object):\n pass\n\n' - mod = self.pycore.get_string_module(code) - a_class = mod['AClass'] - self.assertEquals((mod, 1), a_class.get_definition_location()) - - def test_get_pyname_definition_location_local_variables(self): - mod = self.pycore.get_string_module('def a_func():\n a_var = 10\n') - a_func_scope = mod.get_scope().get_scopes()[0] - a_var = a_func_scope['a_var'] - self.assertEquals((mod, 2), a_var.get_definition_location()) - - def test_get_pyname_definition_location_reassigning(self): - mod = self.pycore.get_string_module('a_var = 20\na_var=30\n') - a_var = mod['a_var'] - self.assertEquals((mod, 1), a_var.get_definition_location()) - - def test_get_pyname_definition_location_importes(self): - module = testutils.create_module(self.project, 'mod') - mod = self.pycore.get_string_module('import mod\n') - imported_module = self.pycore.get_module('mod') - module_pyname = mod['mod'] - self.assertEquals((imported_module, 1), - module_pyname.get_definition_location()) - - def test_get_pyname_definition_location_imports(self): - module_resource = testutils.create_module(self.project, 'mod') - module_resource.write('\ndef a_func():\n pass\n') - imported_module = self.pycore.get_module('mod') - mod = self.pycore.get_string_module('from mod import a_func\n') - a_func = mod['a_func'] - self.assertEquals((imported_module, 2), a_func.get_definition_location()) - - def test_get_pyname_definition_location_parameters(self): - code = 'def a_func(param1, param2):\n a_var = param\n' - mod = self.pycore.get_string_module(code) - a_func_scope = mod.get_scope().get_scopes()[0] - param1 = a_func_scope['param1'] - self.assertEquals((mod, 1), param1.get_definition_location()) - param2 = a_func_scope['param2'] - self.assertEquals((mod, 1), param2.get_definition_location()) - - def test_module_get_resource(self): - module_resource = testutils.create_module(self.project, 'mod') - module = self.pycore.get_module('mod') - self.assertEquals(module_resource, module.get_resource()) - string_module = self.pycore.get_string_module('from mod import a_func\n') - self.assertEquals(None, string_module.get_resource()) - - def test_get_pyname_definition_location_class2(self): - code = 'class AClass(object):\n' \ - ' def __init__(self):\n' \ - ' self.an_attr = 10\n' - mod = self.pycore.get_string_module(code) - a_class = mod['AClass'].get_object() - an_attr = a_class['an_attr'] - self.assertEquals((mod, 3), an_attr.get_definition_location()) - - def test_import_not_found_module_get_definition_location(self): - mod = self.pycore.get_string_module('import doesnotexist\n') - does_not_exist = mod['doesnotexist'] - self.assertEquals((None, None), does_not_exist.get_definition_location()) - - def test_from_not_found_module_get_definition_location(self): - mod = self.pycore.get_string_module('from doesnotexist import Sample\n') - sample = mod['Sample'] - self.assertEquals((None, None), sample.get_definition_location()) - - def test_from_package_import_module_get_definition_location(self): - pkg = testutils.create_package(self.project, 'pkg') - testutils.create_module(self.project, 'mod', pkg) - pkg_mod = self.pycore.get_module('pkg.mod') - mod = self.pycore.get_string_module('from pkg import mod\n') - imported_mod = mod['mod'] - self.assertEquals((pkg_mod, 1), - imported_mod.get_definition_location()) - - def test_get_module_for_defined_pyobjects(self): - mod = self.pycore.get_string_module('class AClass(object):\n pass\n') - a_class = mod['AClass'].get_object() - self.assertEquals(mod, a_class.get_module()) - - def test_get_definition_location_for_packages(self): - pkg = testutils.create_package(self.project, 'pkg') - init_module = self.pycore.get_module('pkg.__init__') - mod = self.pycore.get_string_module('import pkg\n') - pkg_pyname = mod['pkg'] - self.assertEquals((init_module, 1), pkg_pyname.get_definition_location()) - - def test_get_definition_location_for_filtered_packages(self): - pkg = testutils.create_package(self.project, 'pkg') - testutils.create_module(self.project, 'mod', pkg) - init_module = self.pycore.get_module('pkg.__init__') - mod = self.pycore.get_string_module('import pkg.mod') - pkg_pyname = mod['pkg'] - self.assertEquals((init_module, 1), pkg_pyname.get_definition_location()) - - def test_out_of_project_modules(self): - scope = self.pycore.get_string_scope('import rope.base.project as project\n') - imported_module = scope['project'].get_object() - self.assertTrue('Project' in imported_module) - - def test_file_encoding_reading(self): - contents = u'# -*- coding: utf-8 -*-\n#\N{LATIN SMALL LETTER I WITH DIAERESIS}\n' - mod = testutils.create_module(self.project, 'mod') - mod.write(contents) - self.pycore.get_module('mod') - - def test_global_keyword(self): - contents = 'a_var = 1\ndef a_func():\n global a_var\n' - mod = self.pycore.get_string_module(contents) - global_var = mod['a_var'] - func_scope = mod['a_func'].get_object().get_scope() - local_var = func_scope['a_var'] - self.assertEquals(global_var, local_var) - - def test_not_leaking_for_vars_inside_parent_scope(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C(object):\n' \ - ' def f(self):\n' \ - ' for my_var1, my_var2 in []:\n' \ - ' pass\n' - mod.write(code) - pymod = self.pycore.resource_to_pyobject(mod) - c_class = pymod['C'].get_object() - self.assertFalse('my_var1' in c_class) - self.assertFalse('my_var2' in c_class) - - def test_not_leaking_for_vars_inside_parent_scope2(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C(object):\n' \ - ' def f(self):\n' \ - ' for my_var in []:\n' \ - ' pass\n' - mod.write(code) - pymod = self.pycore.resource_to_pyobject(mod) - c_class = pymod['C'].get_object() - self.assertFalse('my_var' in c_class) - - def test_variables_defined_in_excepts(self): - mod = testutils.create_module(self.project, 'mod') - code = 'try:\n' \ - ' myvar1 = 1\n' \ - 'except:\n' \ - ' myvar2 = 1\n' \ - 'finally:\n' \ - ' myvar3 = 1\n' - mod.write(code) - pymod = self.pycore.resource_to_pyobject(mod) - self.assertTrue('myvar1' in pymod) - self.assertTrue('myvar2' in pymod) - self.assertTrue('myvar3' in pymod) - - def test_not_leaking_tuple_assigned_names_inside_parent_scope(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C(object):\n' \ - ' def f(self):\n' \ - ' var1, var2 = range(2)\n' - mod.write(code) - pymod = self.pycore.resource_to_pyobject(mod) - c_class = pymod['C'].get_object() - self.assertFalse('var1' in c_class) - - @testutils.run_only_for_25 - def test_with_statement_variables(self): - code = 'import threading\nwith threading.lock() as var: pass\n' - if sys.version_info < (2, 6, 0): - code = 'from __future__ import with_statement\n' + code - pymod = self.pycore.get_string_module(code) - self.assertTrue('var' in pymod) - - @testutils.run_only_for_25 - def test_with_statement_variables_and_tuple_assignment(self): - code = 'class A(object):\n' \ - ' def __enter__(self):' \ - ' return (1, 2)\n' \ - ' def __exit__(self, type, value, tb):\n' \ - ' pass\n'\ - 'with A() as (a, b):\n' \ - ' pass\n' - if sys.version_info < (2, 6, 0): - code = 'from __future__ import with_statement\n' + code - pymod = self.pycore.get_string_module(code) - self.assertTrue('a' in pymod) - self.assertTrue('b' in pymod) - - @testutils.run_only_for_25 - def test_with_statement_variable_type(self): - code = 'class A(object):\n' \ - ' def __enter__(self):\n' \ - ' return self\n'\ - ' def __exit__(self, type, value, tb):\n' \ - ' pass\n' \ - 'with A() as var:\n' \ - ' pass\n' - if sys.version_info < (2, 6, 0): - code = 'from __future__ import with_statement\n' + code - pymod = self.pycore.get_string_module(code) - a_class = pymod['A'].get_object() - var = pymod['var'].get_object() - self.assertEquals(a_class, var.get_type()) - - @testutils.run_only_for_25 - def test_with_statement_with_no_vars(self): - code = 'with open("file"): pass\n' - if sys.version_info < (2, 6, 0): - code = 'from __future__ import with_statement\n' + code - pymod = self.pycore.get_string_module(code) - pymod.get_attributes() - - def test_check_for_else_block(self): - code = 'for i in range(10):\n' \ - ' pass\n' \ - 'else:\n' \ - ' myvar = 1\n' - mod = self.pycore.get_string_module(code) - a_var = mod['myvar'] - self.assertEquals((mod, 4), a_var.get_definition_location()) - - def test_check_names_defined_in_whiles(self): - mod = self.pycore.get_string_module('while False:\n myvar = 1\n') - a_var = mod['myvar'] - self.assertEquals((mod, 2), a_var.get_definition_location()) - - def test_get_definition_location_in_tuple_assnames(self): - mod = self.pycore.get_string_module( - 'def f(x):\n x.z, a = range(2)\n') - x = mod['f'].get_object().get_scope()['x'] - a = mod['f'].get_object().get_scope()['a'] - self.assertEquals((mod, 1), x.get_definition_location()) - self.assertEquals((mod, 2), a.get_definition_location()) - - @testutils.assert_raises(exceptions.ModuleSyntaxError) - def test_syntax_errors_in_code(self): - mod = self.pycore.get_string_module('xyx print\n') - - def test_holding_error_location_information(self): - try: - mod = self.pycore.get_string_module('xyx print\n') - except exceptions.ModuleSyntaxError, e: - self.assertEquals(1, e.lineno) - - def test_no_exceptions_on_module_encoding_problems(self): - mod = testutils.create_module(self.project, 'mod') - contents = '\nsdsdsd\n\xa9\n' - file = open(mod.real_path, 'wb') - file.write(contents) - file.close() - mod.read() - - @testutils.assert_raises(exceptions.ModuleSyntaxError) - def test_syntax_errors_when_cannot_decode_file2(self): - mod = testutils.create_module(self.project, 'mod') - contents = '\n\xa9\n' - file = open(mod.real_path, 'wb') - file.write(contents) - file.close() - self.pycore.resource_to_pyobject(mod) - - @testutils.assert_raises(exceptions.ModuleSyntaxError) - def test_syntax_errors_when_null_bytes(self): - mod = testutils.create_module(self.project, 'mod') - contents = '\n\x00\n' - file = open(mod.real_path, 'wb') - file.write(contents) - file.close() - self.pycore.resource_to_pyobject(mod) - - @testutils.assert_raises(exceptions.ModuleSyntaxError) - def test_syntax_errors_when_bad_strs(self): - mod = testutils.create_module(self.project, 'mod') - contents = '\n"\\x0"\n' - file = open(mod.real_path, 'wb') - file.write(contents) - file.close() - self.pycore.resource_to_pyobject(mod) - - def test_not_reaching_maximum_recursions_with_from_star_imports(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('from mod2 import *\n') - mod2.write('from mod1 import *\n') - pymod1 = self.pycore.resource_to_pyobject(mod1) - pymod1.get_attributes() - - def test_not_reaching_maximum_recursions_when_importing_variables(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('from mod2 import myvar\n') - mod2.write('from mod1 import myvar\n') - pymod1 = self.pycore.resource_to_pyobject(mod1) - pymod1['myvar'].get_object() - - def test_not_reaching_maximum_recursions_when_importing_variables2(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('from mod1 import myvar\n') - pymod1 = self.pycore.resource_to_pyobject(mod1) - pymod1['myvar'].get_object() - - def test_pyobject_equality_should_compare_types(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('var1 = ""\nvar2 = ""\n') - pymod1 = self.pycore.resource_to_pyobject(mod1) - self.assertEquals(pymod1['var1'].get_object(), - pymod1['var2'].get_object()) - - -class PyCoreInProjectsTest(unittest.TestCase): - - def setUp(self): - super(self.__class__, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - samplemod = testutils.create_module(self.project, 'samplemod') - code = 'class SampleClass(object):\n' \ - ' def sample_method():\n' \ - ' pass\n\n' \ - 'def sample_func():\n' \ - ' pass\n' \ - 'sample_var = 10\n\n' \ - 'def _underlined_func():\n' \ - ' pass\n\n' - samplemod.write(code) - package = testutils.create_package(self.project, 'package') - nestedmod = testutils.create_module(self.project, 'nestedmod', package) - - def tearDown(self): - testutils.remove_project(self.project) - super(self.__class__, self).tearDown() - - def test_simple_import(self): - mod = self.pycore.get_string_module('import samplemod\n') - samplemod = mod['samplemod'].get_object() - self.assertEquals(get_base_type('Module'), samplemod.get_type()) - - def test_from_import_class(self): - mod = self.pycore.get_string_module('from samplemod import SampleClass\n') - result = mod['SampleClass'].get_object() - self.assertEquals(get_base_type('Type'), result.get_type()) - self.assertTrue('sample_func' not in mod.get_attributes()) - - def test_from_import_star(self): - mod = self.pycore.get_string_module('from samplemod import *\n') - self.assertEquals(get_base_type('Type'), - mod['SampleClass'].get_object().get_type()) - self.assertEquals(get_base_type('Function'), - mod['sample_func'].get_object().get_type()) - self.assertTrue(mod['sample_var'] is not None) - - def test_from_import_star_overwriting(self): - code = 'from samplemod import *\n' \ - 'class SampleClass(object):\n pass\n' - mod = self.pycore.get_string_module(code) - samplemod = self.pycore.get_module('samplemod') - sample_class = samplemod['SampleClass'].get_object() - self.assertNotEquals(sample_class, - mod.get_attributes()['SampleClass'].get_object()) - - def test_from_import_star_not_imporing_underlined(self): - mod = self.pycore.get_string_module('from samplemod import *') - self.assertTrue('_underlined_func' not in mod.get_attributes()) - - def test_from_import_star_imports_in_functions(self): - mod = self.pycore.get_string_module('def f():\n from os import *\n') - mod['f'].get_object().get_scope().get_names() - - def test_from_package_import_mod(self): - mod = self.pycore.get_string_module('from package import nestedmod\n') - self.assertEquals(get_base_type('Module'), - mod['nestedmod'].get_object().get_type()) - - # XXX: Deciding to import everything on import start from packages - def xxx_test_from_package_import_star(self): - mod = self.pycore.get_string_module('from package import *\n') - self.assertTrue('nestedmod' not in mod.get_attributes()) - - def test_unknown_when_module_cannot_be_found(self): - mod = self.pycore.get_string_module('from doesnotexist import nestedmod\n') - self.assertTrue('nestedmod' in mod) - - def test_from_import_function(self): - code = 'def f():\n from samplemod import SampleClass\n' - scope = self.pycore.get_string_scope(code) - self.assertEquals(get_base_type('Type'), - scope.get_scopes()[0]['SampleClass']. - get_object().get_type()) - - def test_circular_imports(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('import mod2\n') - mod2.write('import mod1\n') - module1 = self.pycore.get_module('mod1') - - def test_circular_imports2(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('from mod2 import Sample2\nclass Sample1(object):\n pass\n') - mod2.write('from mod1 import Sample1\nclass Sample2(object):\n pass\n') - module1 = self.pycore.get_module('mod1').get_attributes() - - def test_multi_dot_imports(self): - pkg = testutils.create_package(self.project, 'pkg') - pkg_mod = testutils.create_module(self.project, 'mod', pkg) - pkg_mod.write('def sample_func():\n pass\n') - mod = self.pycore.get_string_module('import pkg.mod\n') - self.assertTrue('pkg' in mod) - self.assertTrue('sample_func' in mod['pkg'].get_object()['mod']. - get_object()) - - def test_multi_dot_imports2(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod = self.pycore.get_string_module('import pkg.mod1\nimport pkg.mod2\n') - package = mod['pkg'].get_object() - self.assertEquals(2, len(package.get_attributes())) - self.assertTrue('mod1' in package and - 'mod2' in package) - - def test_multi_dot_imports3(self): - pkg1 = testutils.create_package(self.project, 'pkg1') - pkg2 = testutils.create_package(self.project, 'pkg2', pkg1) - mod1 = testutils.create_module(self.project, 'mod1', pkg2) - mod2 = testutils.create_module(self.project, 'mod2', pkg2) - code = 'import pkg1.pkg2.mod1\nimport pkg1.pkg2.mod2\n' - mod = self.pycore.get_string_module(code) - package1 = mod['pkg1'].get_object() - package2 = package1['pkg2'].get_object() - self.assertEquals(2, len(package2.get_attributes())) - self.assertTrue('mod1' in package2 and 'mod2' in package2) - - def test_multi_dot_imports_as(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod1.write('def f():\n pass\n') - mod = self.pycore.get_string_module('import pkg.mod1 as mod1\n') - module = mod['mod1'].get_object() - self.assertTrue('f' in module) - - # TODO: not showing unimported names as attributes of packages - def xxx_test_from_package_import_package(self): - pkg1 = testutils.create_package(self.project, 'pkg1') - pkg2 = testutils.create_package(self.project, 'pkg2', pkg1) - module = testutils.create_module(self.project, 'mod', pkg2) - mod = self.pycore.get_string_module('from pkg1 import pkg2\n') - package = mod['pkg2'] - self.assertEquals(0, len(package.get_attributes())) - - def test_invalidating_cache_after_resource_change(self): - module = testutils.create_module(self.project, 'mod') - module.write('import sys\n') - mod1 = self.pycore.get_module('mod') - self.assertTrue('var' not in mod1.get_attributes()) - module.write('var = 10\n') - mod2 = self.pycore.get_module('mod') - self.assertTrue('var' in mod2) - - def test_invalidating_cache_after_resource_change_for_init_dot_pys(self): - pkg = testutils.create_package(self.project, 'pkg') - mod = testutils.create_module(self.project, 'mod') - init_dot_py = pkg.get_child('__init__.py') - init_dot_py.write('a_var = 10\n') - mod.write('import pkg\n') - pymod = self.pycore.get_module('mod') - self.assertTrue('a_var' in pymod['pkg'].get_object()) - init_dot_py.write('new_var = 10\n') - self.assertTrue('a_var' not in pymod['pkg'].get_object().get_attributes()) - - def test_invalidating_cache_after_resource_change_for_nested_init_dot_pys(self): - pkg1 = testutils.create_package(self.project, 'pkg1') - pkg2 = testutils.create_package(self.project, 'pkg2', pkg1) - mod = testutils.create_module(self.project, 'mod') - init_dot_py = pkg2.get_child('__init__.py') - init_dot_py.write('a_var = 10\n') - mod.write('import pkg1\n') - pymod = self.pycore.get_module('mod') - self.assertTrue('a_var' in pymod['pkg1'].get_object()['pkg2'].get_object()) - init_dot_py.write('new_var = 10\n') - self.assertTrue('a_var' not in pymod['pkg1'].get_object()['pkg2'].get_object()) - - def test_from_import_nonexistent_module(self): - code = 'from doesnotexistmod import DoesNotExistClass\n' - mod = self.pycore.get_string_module(code) - self.assertTrue('DoesNotExistClass' in mod) - self.assertEquals(get_base_type('Unknown'), - mod['DoesNotExistClass']. - get_object().get_type()) - - def test_from_import_nonexistent_name(self): - code = 'from samplemod import DoesNotExistClass\n' - mod = self.pycore.get_string_module(code) - self.assertTrue('DoesNotExistClass' in mod) - self.assertEquals(get_base_type('Unknown'), - mod['DoesNotExistClass']. - get_object().get_type()) - - def test_not_considering_imported_names_as_sub_scopes(self): - code = 'from samplemod import SampleClass\n' - scope = self.pycore.get_string_scope(code) - self.assertEquals(0, len(scope.get_scopes())) - - def test_not_considering_imported_modules_as_sub_scopes(self): - scope = self.pycore.get_string_scope('import samplemod\n') - self.assertEquals(0, len(scope.get_scopes())) - - def test_inheriting_dotted_base_class(self): - code = 'import samplemod\n' \ - 'class Derived(samplemod.SampleClass):\n' \ - ' pass\n' - mod = self.pycore.get_string_module(code) - derived = mod['Derived'].get_object() - self.assertTrue('sample_method' in derived) - - def test_self_in_methods(self): - code = 'class Sample(object):\n' \ - ' def func(self):\n' \ - ' pass\n' - scope = self.pycore.get_string_scope(code) - sample_class = scope['Sample'].get_object() - func_scope = scope.get_scopes()[0].get_scopes()[0] - self.assertEquals(sample_class, - func_scope['self'].get_object().get_type()) - self.assertTrue('func' in func_scope['self']. - get_object()) - - def test_none_assignments_in_classes(self): - code = 'class C(object):\n' \ - ' var = ""\n' \ - ' def f(self):\n' \ - ' self.var += "".join([])\n' - scope = self.pycore.get_string_scope( - code) - c_class = scope['C'].get_object() - self.assertTrue('var' in c_class) - - def test_self_in_methods_with_decorators(self): - code = 'class Sample(object):\n' \ - ' @staticmethod\n' \ - ' def func(self):\n' \ - ' pass\n' - scope = self.pycore.get_string_scope(code) - sample_class = scope['Sample'].get_object() - func_scope = scope.get_scopes()[0].get_scopes()[0] - self.assertNotEquals(sample_class, - func_scope['self'].get_object().get_type()) - - def test_location_of_imports_when_importing(self): - mod = testutils.create_module(self.project, 'mod') - mod.write('from samplemod import SampleClass\n') - scope = self.pycore.get_string_scope('from mod import SampleClass\n') - sample_class = scope['SampleClass'] - samplemod = self.pycore.get_module('samplemod') - self.assertEquals((samplemod, 1), sample_class.get_definition_location()) - - def test_nested_modules(self): - pkg = testutils.create_package(self.project, 'pkg') - mod = testutils.create_module(self.project, 'mod', pkg) - imported_module = self.pycore.get_module('pkg.mod') - scope = self.pycore.get_string_scope('import pkg.mod\n') - mod_pyobject = scope['pkg'].get_object()['mod'] - self.assertEquals((imported_module, 1), - mod_pyobject.get_definition_location()) - - def test_reading_init_dot_py(self): - pkg = testutils.create_package(self.project, 'pkg') - init_dot_py = pkg.get_child('__init__.py') - init_dot_py.write('a_var = 1\n') - pkg_object = self.pycore.get_module('pkg') - self.assertTrue('a_var' in pkg_object) - - def test_relative_imports(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod2.write('import mod1\n') - mod1_object = self.pycore.resource_to_pyobject(mod1) - mod2_object = self.pycore.resource_to_pyobject(mod2) - self.assertEquals(mod1_object, mod2_object.get_attributes()['mod1'].get_object()) - - def test_relative_froms(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod1.write('def a_func():\n pass\n') - mod2.write('from mod1 import a_func\n') - mod1_object = self.pycore.resource_to_pyobject(mod1) - mod2_object = self.pycore.resource_to_pyobject(mod2) - self.assertEquals(mod1_object['a_func'].get_object(), - mod2_object['a_func'].get_object()) - - def test_relative_imports_for_string_modules(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod2.write('import mod1\n') - mod1_object = self.pycore.resource_to_pyobject(mod1) - mod2_object = self.pycore.get_string_module(mod2.read(), mod2) - self.assertEquals(mod1_object, mod2_object['mod1'].get_object()) - - def test_relative_imports_for_string_scopes(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod2.write('import mod1\n') - mod1_object = self.pycore.resource_to_pyobject(mod1) - mod2_scope = self.pycore.get_string_scope(mod2.read(), mod2) - self.assertEquals(mod1_object, mod2_scope['mod1'].get_object()) - - @testutils.run_only_for_25 - def test_new_style_relative_imports(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod2.write('from . import mod1\n') - mod1_object = self.pycore.resource_to_pyobject(mod1) - mod2_object = self.pycore.resource_to_pyobject(mod2) - self.assertEquals(mod1_object, mod2_object['mod1'].get_object()) - - @testutils.run_only_for_25 - def test_new_style_relative_imports2(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod1.write('def a_func():\n pass\n') - mod2.write('from ..mod1 import a_func\n') - mod1_object = self.pycore.resource_to_pyobject(mod1) - mod2_object = self.pycore.resource_to_pyobject(mod2) - self.assertEquals(mod1_object['a_func'].get_object(), - mod2_object['a_func'].get_object()) - - def test_invalidating_cache_for_from_imports_after_resource_change(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('def a_func():\n print(1)\n') - mod1.write('from mod2 import a_func\na_func()\n') - - pymod1 = self.pycore.get_module('mod1') - pymod2 = self.pycore.get_module('mod2') - self.assertEquals(pymod1['a_func'].get_object(), - pymod2['a_func'].get_object()) - mod2.write(mod2.read() + '\n') - pymod2 = self.pycore.get_module('mod2') - self.assertEquals(pymod1['a_func'].get_object(), - pymod2['a_func'].get_object()) - - def test_invalidating_superclasses_after_change(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('class A(object):\n def func1(self):\n pass\n') - mod2.write('import mod1\nclass B(mod1.A):\n pass\n') - - b_class = self.pycore.get_module('mod2')['B'].get_object() - self.assertTrue('func1' in b_class) - - mod1.write('class A(object):\n def func2(self):\n pass\n') - self.assertTrue('func2' in b_class) - - def test_caching_pymodule_with_syntax_errors(self): - self.project.prefs['ignore_syntax_errors'] = True - self.project.prefs['automatic_soa'] = True - self.project.pycore._init_automatic_soa() - source = 'import sys\nab cd' - mod = testutils.create_module(self.project, 'mod') - mod.write(source) - from rope.contrib import fixsyntax - fixer = fixsyntax.FixSyntax(self.project.pycore, source, mod, 10) - pymodule = fixer.get_pymodule() - self.assertTrue(pymodule.source_code.startswith('import sys\npass\n')) - - -class TextChangeDetectorTest(unittest.TestCase): - - def test_trivial_case(self): - detector = _TextChangeDetector('\n', '\n') - self.assertFalse(detector.is_changed(1, 1)) - - def test_one_line_change(self): - detector = _TextChangeDetector('1\n2\n', '1\n3\n') - self.assertFalse(detector.is_changed(1, 1)) - self.assertTrue(detector.is_changed(2, 2)) - - def test_line_expansion(self): - detector = _TextChangeDetector('1\n2\n', '1\n3\n4\n2\n') - self.assertFalse(detector.is_changed(1, 1)) - self.assertFalse(detector.is_changed(2, 2)) - - def test_line_removals(self): - detector = _TextChangeDetector('1\n3\n4\n2\n', '1\n2\n') - self.assertFalse(detector.is_changed(1, 1)) - self.assertTrue(detector.is_changed(2, 3)) - self.assertFalse(detector.is_changed(4, 4)) - - def test_multi_line_checks(self): - detector = _TextChangeDetector('1\n2\n', '1\n3\n') - self.assertTrue(detector.is_changed(1, 2)) - - def test_consume_change(self): - detector = _TextChangeDetector('1\n2\n', '1\n3\n') - self.assertTrue(detector.is_changed(1, 2)) - self.assertTrue(detector.consume_changes(1, 2)) - self.assertFalse(detector.is_changed(1, 2)) - - -class PyCoreProjectConfigsTest(unittest.TestCase): - - def setUp(self): - super(PyCoreProjectConfigsTest, self).setUp() - self.project = None - - def tearDown(self): - if self.project: - testutils.remove_project(self.project) - super(PyCoreProjectConfigsTest, self).tearDown() - - def test_python_files_config(self): - self.project = testutils.sample_project(python_files=['myscript']) - myscript = self.project.root.create_file('myscript') - self.assertTrue(self.project.pycore.is_python_file(myscript)) - - def test_ignore_bad_imports(self): - self.project = testutils.sample_project(ignore_bad_imports=True) - pymod = self.project.pycore.get_string_module( - 'import some_nonexistent_module\n') - self.assertFalse('some_nonexistent_module' in pymod) - - def test_ignore_bad_imports_for_froms(self): - self.project = testutils.sample_project(ignore_bad_imports=True) - pymod = self.project.pycore.get_string_module( - 'from some_nonexistent_module import var\n') - self.assertFalse('var' in pymod) - - @testutils.assert_raises(exceptions.ModuleSyntaxError) - def test_reporting_syntax_errors_with_force_errors(self): - self.project = testutils.sample_project(ignore_syntax_errors=True) - mod = testutils.create_module(self.project, 'mod') - mod.write('syntax error ...\n') - self.project.pycore.resource_to_pyobject(mod, force_errors=True) - - @testutils.assert_raises(exceptions.ModuleSyntaxError) - def test_reporting_syntax_errors_in_strings_with_force_errors(self): - self.project = testutils.sample_project(ignore_syntax_errors=True) - self.project.pycore.get_string_module('syntax error ...', - force_errors=True) - - def test_not_raising_errors_for_strings_with_ignore_errors(self): - self.project = testutils.sample_project(ignore_syntax_errors=True) - self.project.pycore.get_string_module('syntax error ...') - - @testutils.assert_raises(exceptions.ModuleSyntaxError) - def test_reporting_syntax_errors_with_force_errors_for_packages(self): - self.project = testutils.sample_project(ignore_syntax_errors=True) - pkg = testutils.create_package(self.project, 'pkg') - pkg.get_child('__init__.py').write('syntax error ...\n') - self.project.pycore.resource_to_pyobject(pkg, force_errors=True) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(PyCoreTest)) - result.addTests(unittest.makeSuite(PyCoreInProjectsTest)) - result.addTests(unittest.makeSuite(TextChangeDetectorTest)) - result.addTests(unittest.makeSuite(PyCoreProjectConfigsTest)) - return result - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/pyscopestest.py --- a/vim/sadness/ropevim/src/rope/ropetest/pyscopestest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -import unittest - -from rope.base.pyobjects import get_base_type -from ropetest import testutils - - -class PyCoreScopesTest(unittest.TestCase): - - def setUp(self): - super(PyCoreScopesTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - - def tearDown(self): - testutils.remove_project(self.project) - super(PyCoreScopesTest, self).tearDown() - - def test_simple_scope(self): - scope = self.pycore.get_string_scope('def sample_func():\n pass\n') - sample_func = scope['sample_func'].get_object() - self.assertEquals(get_base_type('Function'), sample_func.get_type()) - - def test_simple_function_scope(self): - scope = self.pycore.get_string_scope( - 'def sample_func():\n a = 10\n') - self.assertEquals(1, len(scope.get_scopes())) - sample_func_scope = scope.get_scopes()[0] - self.assertEquals(1, len(sample_func_scope.get_names())) - self.assertEquals(0, len(sample_func_scope.get_scopes())) - - def test_classes_inside_function_scopes(self): - scope = self.pycore.get_string_scope( - 'def sample_func():\n' - ' class SampleClass(object):\n pass\n') - self.assertEquals(1, len(scope.get_scopes())) - sample_func_scope = scope.get_scopes()[0] - self.assertEquals(get_base_type('Type'), - scope.get_scopes()[0]['SampleClass'].get_object().get_type()) - - def test_simple_class_scope(self): - scope = self.pycore.get_string_scope( - 'class SampleClass(object):\n' - ' def f(self):\n var = 10\n') - self.assertEquals(1, len(scope.get_scopes())) - sample_class_scope = scope.get_scopes()[0] - self.assertTrue('f' in sample_class_scope) - self.assertEquals(1, len(sample_class_scope.get_scopes())) - f_in_class = sample_class_scope.get_scopes()[0] - self.assertTrue('var' in f_in_class) - - def test_get_lineno(self): - scope = self.pycore.get_string_scope( - '\ndef sample_func():\n a = 10\n') - self.assertEquals(1, len(scope.get_scopes())) - sample_func_scope = scope.get_scopes()[0] - self.assertEquals(1, scope.get_start()) - self.assertEquals(2, sample_func_scope.get_start()) - - def test_scope_kind(self): - scope = self.pycore.get_string_scope( - 'class SampleClass(object):\n pass\n' - 'def sample_func():\n pass\n') - sample_class_scope = scope.get_scopes()[0] - sample_func_scope = scope.get_scopes()[1] - self.assertEquals('Module', scope.get_kind()) - self.assertEquals('Class', sample_class_scope.get_kind()) - self.assertEquals('Function', sample_func_scope.get_kind()) - - def test_function_parameters_in_scope_names(self): - scope = self.pycore.get_string_scope( - 'def sample_func(param):\n a = 10\n') - sample_func_scope = scope.get_scopes()[0] - self.assertTrue('param' in sample_func_scope) - - def test_get_names_contains_only_names_defined_in_a_scope(self): - scope = self.pycore.get_string_scope( - 'var1 = 10\ndef sample_func(param):\n var2 = 20\n') - sample_func_scope = scope.get_scopes()[0] - self.assertTrue('var1' not in sample_func_scope) - - def test_scope_lookup(self): - scope = self.pycore.get_string_scope( - 'var1 = 10\ndef sample_func(param):\n var2 = 20\n') - self.assertTrue(scope.lookup('var2') is None) - self.assertEquals(get_base_type('Function'), - scope.lookup('sample_func').get_object().get_type()) - sample_func_scope = scope.get_scopes()[0] - self.assertTrue(sample_func_scope.lookup('var1') is not None) - - def test_function_scopes(self): - scope = self.pycore.get_string_scope('def func():\n var = 10\n') - func_scope = scope.get_scopes()[0] - self.assertTrue('var' in func_scope) - - def test_function_scopes_classes(self): - scope = self.pycore.get_string_scope( - 'def func():\n class Sample(object):\n pass\n') - func_scope = scope.get_scopes()[0] - self.assertTrue('Sample' in func_scope) - - def test_function_getting_scope(self): - mod = self.pycore.get_string_module('def func(): var = 10\n') - func_scope = mod['func'].get_object().get_scope() - self.assertTrue('var' in func_scope) - - def test_scopes_in_function_scopes(self): - scope = self.pycore.get_string_scope( - 'def func():\n def inner():\n var = 10\n') - func_scope = scope.get_scopes()[0] - inner_scope = func_scope.get_scopes()[0] - self.assertTrue('var' in inner_scope) - - def test_for_variables_in_scopes(self): - scope = self.pycore.get_string_scope( - 'for a_var in range(10):\n pass\n') - self.assertTrue('a_var' in scope) - - def test_assists_inside_fors(self): - scope = self.pycore.get_string_scope( - 'for i in range(10):\n a_var = i\n') - self.assertTrue('a_var' in scope) - - def test_first_parameter_of_a_method(self): - code = 'class AClass(object):\n' \ - ' def a_func(self, param):\n pass\n' - a_class = self.pycore.get_string_module(code)['AClass']. get_object() - function_scope = a_class['a_func'].get_object().get_scope() - self.assertEquals(a_class, function_scope['self'].get_object().get_type()) - self.assertNotEquals(a_class, function_scope['param']. - get_object().get_type()) - - def test_first_parameter_of_static_methods(self): - code = 'class AClass(object):\n' \ - ' @staticmethod\n def a_func(param):\n pass\n' - a_class = self.pycore.get_string_module(code)['AClass']. get_object() - function_scope = a_class['a_func'].\ - get_object().get_scope() - self.assertNotEquals(a_class, function_scope['param'].get_object().get_type()) - - def test_first_parameter_of_class_methods(self): - code = 'class AClass(object):\n' \ - ' @classmethod\n def a_func(cls):\n pass\n' - a_class = self.pycore.get_string_module(code)['AClass']. get_object() - function_scope = a_class['a_func'].get_object().get_scope() - self.assertEquals(a_class, function_scope['cls'].get_object()) - - def test_first_parameter_with_self_as_name_and_unknown_decorator(self): - code = 'def my_decorator(func):\n return func\n'\ - 'class AClass(object):\n' \ - ' @my_decorator\n def a_func(self):\n pass\n' - a_class = self.pycore.get_string_module(code)['AClass']. get_object() - function_scope = a_class['a_func'].get_object().get_scope() - self.assertEquals(a_class, function_scope['self']. - get_object().get_type()) - - def test_inside_class_scope_attribute_lookup(self): - scope = self.pycore.get_string_scope( - 'class C(object):\n' - ' an_attr = 1\n' - ' def a_func(self):\n pass') - self.assertEquals(1, len(scope.get_scopes())) - c_scope = scope.get_scopes()[0] - self.assertTrue('an_attr'in c_scope.get_names()) - self.assertTrue(c_scope.lookup('an_attr') is not None) - f_in_c = c_scope.get_scopes()[0] - self.assertTrue(f_in_c.lookup('an_attr') is None) - - def test_inside_class_scope_attribute_lookup2(self): - scope = self.pycore.get_string_scope( - 'class C(object):\n' - ' def __init__(self):\n self.an_attr = 1\n' - ' def a_func(self):\n pass') - self.assertEquals(1, len(scope.get_scopes())) - c_scope = scope.get_scopes()[0] - f_in_c = c_scope.get_scopes()[0] - self.assertTrue(f_in_c.lookup('an_attr') is None) - - def test_get_inner_scope_for_staticmethods(self): - scope = self.pycore.get_string_scope( - 'class C(object):\n' - ' @staticmethod\n' - ' def a_func(self):\n pass\n') - c_scope = scope.get_scopes()[0] - f_in_c = c_scope.get_scopes()[0] - self.assertEquals(f_in_c, scope.get_inner_scope_for_line(4)) - - def test_getting_overwritten_scopes(self): - scope = self.pycore.get_string_scope( - 'def f():\n pass\ndef f():\n pass\n') - self.assertEquals(2, len(scope.get_scopes())) - f1_scope = scope.get_scopes()[0] - f2_scope = scope.get_scopes()[1] - self.assertNotEquals(f1_scope, f2_scope) - - def test_assigning_builtin_names(self): - mod = self.pycore.get_string_module('range = 1\n') - range = mod.get_scope().lookup('range') - self.assertEquals((mod, 1), range.get_definition_location()) - - def test_get_inner_scope_and_logical_lines(self): - scope = self.pycore.get_string_scope( - 'class C(object):\n' - ' def f():\n s = """\n1\n2\n"""\n a = 1\n') - c_scope = scope.get_scopes()[0] - f_in_c = c_scope.get_scopes()[0] - self.assertEquals(f_in_c, scope.get_inner_scope_for_line(7)) - - def test_getting_defined_names_for_classes(self): - scope = self.pycore.get_string_scope( - 'class A(object):\n def a(self):\n pass\n' - 'class B(A):\n def b(self):\n pass\n') - a_scope = scope['A'].get_object().get_scope() - b_scope = scope['B'].get_object().get_scope() - self.assertTrue('a' in b_scope.get_names()) - self.assertTrue('b' in b_scope.get_names()) - self.assertTrue('a' not in b_scope.get_defined_names()) - self.assertTrue('b' in b_scope.get_defined_names()) - - def test_getting_defined_names_for_modules(self): - scope = self.pycore.get_string_scope( - 'class A(object):\n pass\n') - self.assertTrue('open' in scope.get_names()) - self.assertTrue('A' in scope.get_names()) - self.assertTrue('open' not in scope.get_defined_names()) - self.assertTrue('A' in scope.get_defined_names()) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(PyCoreScopesTest)) - return result - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/__init__.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/__init__.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,925 +0,0 @@ -import unittest - -import rope.base.taskhandle -import rope.refactor.introduce_parameter -import ropetest.refactor.extracttest -import ropetest.refactor.importutilstest -import ropetest.refactor.inlinetest -import ropetest.refactor.movetest -import ropetest.refactor.multiprojecttest -import ropetest.refactor.patchedasttest -import ropetest.refactor.renametest -import ropetest.refactor.restructuretest -import ropetest.refactor.suitestest -import ropetest.refactor.usefunctiontest -from rope.base.exceptions import RefactoringError, InterruptedTaskError -from rope.refactor.encapsulate_field import EncapsulateField -from rope.refactor.introduce_factory import IntroduceFactory -from rope.refactor.localtofield import LocalToField -from rope.refactor.method_object import MethodObject -from ropetest import testutils -from ropetest.refactor import change_signature_test, similarfindertest - - -class MethodObjectTest(unittest.TestCase): - - def setUp(self): - super(MethodObjectTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod') - - def tearDown(self): - testutils.remove_project(self.project) - super(MethodObjectTest, self).tearDown() - - def test_empty_method(self): - code = 'def func():\n pass\n' - self.mod.write(code) - replacer = MethodObject(self.project, self.mod, code.index('func')) - self.assertEquals( - 'class _New(object):\n\n def __call__(self):\n pass\n', - replacer.get_new_class('_New')) - - def test_trivial_return(self): - code = 'def func():\n return 1\n' - self.mod.write(code) - replacer = MethodObject(self.project, self.mod, code.index('func')) - self.assertEquals( - 'class _New(object):\n\n def __call__(self):\n return 1\n', - replacer.get_new_class('_New')) - - def test_multi_line_header(self): - code = 'def func(\n ):\n return 1\n' - self.mod.write(code) - replacer = MethodObject(self.project, self.mod, code.index('func')) - self.assertEquals( - 'class _New(object):\n\n def __call__(self):\n return 1\n', - replacer.get_new_class('_New')) - - def test_a_single_parameter(self): - code = 'def func(param):\n return 1\n' - self.mod.write(code) - replacer = MethodObject(self.project, self.mod, code.index('func')) - self.assertEquals( - 'class _New(object):\n\n' - ' def __init__(self, param):\n self.param = param\n\n' - ' def __call__(self):\n return 1\n', - replacer.get_new_class('_New')) - - def test_self_parameter(self): - code = 'def func(self):\n return 1\n' - self.mod.write(code) - replacer = MethodObject(self.project, self.mod, code.index('func')) - self.assertEquals( - 'class _New(object):\n\n' - ' def __init__(self, host):\n self.self = host\n\n' - ' def __call__(self):\n return 1\n', - replacer.get_new_class('_New')) - - def test_simple_using_passed_parameters(self): - code = 'def func(param):\n return param\n' - self.mod.write(code) - replacer = MethodObject(self.project, self.mod, code.index('func')) - self.assertEquals( - 'class _New(object):\n\n' - ' def __init__(self, param):\n self.param = param\n\n' - ' def __call__(self):\n return self.param\n', - replacer.get_new_class('_New')) - - def test_self_keywords_and_args_parameters(self): - code = 'def func(arg, *args, **kwds):\n' \ - ' result = arg + args[0] + kwds[arg]\n' \ - ' return result\n' - self.mod.write(code) - replacer = MethodObject(self.project, self.mod, code.index('func')) - expected = 'class _New(object):\n\n' \ - ' def __init__(self, arg, args, kwds):\n' \ - ' self.arg = arg\n' \ - ' self.args = args\n' \ - ' self.kwds = kwds\n\n' \ - ' def __call__(self):\n' \ - ' result = self.arg + self.args[0] + self.kwds[self.arg]\n' \ - ' return result\n' - self.assertEquals(expected, replacer.get_new_class('_New')) - - @testutils.assert_raises(RefactoringError) - def test_performing_on_not_a_function(self): - code = 'my_var = 10\n' - self.mod.write(code) - replacer = MethodObject(self.project, self.mod, code.index('my_var')) - - def test_changing_the_module(self): - code = 'def func():\n return 1\n' - self.mod.write(code) - replacer = MethodObject(self.project, self.mod, code.index('func')) - self.project.do(replacer.get_changes('_New')) - expected = 'def func():\n' \ - ' return _New()()\n\n\n' \ - 'class _New(object):\n\n' \ - ' def __call__(self):\n' \ - ' return 1\n' - self.assertEquals(expected, self.mod.read()) - - def test_changing_the_module_and_class_methods(self): - code = 'class C(object):\n\n' \ - ' def a_func(self):\n' \ - ' return 1\n\n' \ - ' def another_func(self):\n' \ - ' pass\n' - self.mod.write(code) - replacer = MethodObject(self.project, self.mod, code.index('func')) - self.project.do(replacer.get_changes('_New')) - expected = 'class C(object):\n\n' \ - ' def a_func(self):\n' \ - ' return _New(self)()\n\n' \ - ' def another_func(self):\n' \ - ' pass\n\n\n' \ - 'class _New(object):\n\n' \ - ' def __init__(self, host):\n' \ - ' self.self = host\n\n' \ - ' def __call__(self):\n' \ - ' return 1\n' - self.assertEquals(expected, self.mod.read()) - - -class IntroduceFactoryTest(unittest.TestCase): - - def setUp(self): - super(IntroduceFactoryTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - - def tearDown(self): - testutils.remove_project(self.project) - super(IntroduceFactoryTest, self).tearDown() - - def _introduce_factory(self, resource, offset, *args, **kwds): - factory_introducer = IntroduceFactory(self.project, - resource, offset) - changes = factory_introducer.get_changes(*args, **kwds) - self.project.do(changes) - - def test_adding_the_method(self): - code = 'class AClass(object):\n an_attr = 10\n' - mod = testutils.create_module(self.project, 'mod') - mod.write(code) - expected = 'class AClass(object):\n' \ - ' an_attr = 10\n\n' \ - ' @staticmethod\n' \ - ' def create(*args, **kwds):\n' \ - ' return AClass(*args, **kwds)\n' - self._introduce_factory(mod, mod.read().index('AClass') + 1, 'create') - self.assertEquals(expected, mod.read()) - - def test_changing_occurances_in_the_main_module(self): - code = 'class AClass(object):\n' \ - ' an_attr = 10\n' \ - 'a_var = AClass()' - mod = testutils.create_module(self.project, 'mod') - mod.write(code) - expected = 'class AClass(object):\n' \ - ' an_attr = 10\n\n' \ - ' @staticmethod\n' \ - ' def create(*args, **kwds):\n' \ - ' return AClass(*args, **kwds)\n'\ - 'a_var = AClass.create()' - self._introduce_factory(mod, mod.read().index('AClass') + 1, 'create') - self.assertEquals(expected, mod.read()) - - def test_changing_occurances_with_arguments(self): - code = 'class AClass(object):\n' \ - ' def __init__(self, arg):\n' \ - ' pass\n' \ - 'a_var = AClass(10)\n' - mod = testutils.create_module(self.project, 'mod') - mod.write(code) - expected = 'class AClass(object):\n' \ - ' def __init__(self, arg):\n' \ - ' pass\n\n' \ - ' @staticmethod\n' \ - ' def create(*args, **kwds):\n' \ - ' return AClass(*args, **kwds)\n' \ - 'a_var = AClass.create(10)\n' - self._introduce_factory(mod, mod.read().index('AClass') + 1, 'create') - self.assertEquals(expected, mod.read()) - - def test_changing_occurances_in_other_modules(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('class AClass(object):\n an_attr = 10\n') - mod2.write('import mod1\na_var = mod1.AClass()\n') - self._introduce_factory(mod1, mod1.read().index('AClass') + 1, 'create') - expected1 = 'class AClass(object):\n' \ - ' an_attr = 10\n\n' \ - ' @staticmethod\n' \ - ' def create(*args, **kwds):\n' \ - ' return AClass(*args, **kwds)\n' - expected2 = 'import mod1\n' \ - 'a_var = mod1.AClass.create()\n' - self.assertEquals(expected1, mod1.read()) - self.assertEquals(expected2, mod2.read()) - - @testutils.assert_raises(RefactoringError) - def test_raising_exception_for_non_classes(self): - mod = testutils.create_module(self.project, 'mod') - mod.write('def a_func():\n pass\n') - self._introduce_factory(mod, mod.read().index('a_func') + 1, 'create') - - def test_undoing_introduce_factory(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - code1 = 'class AClass(object):\n an_attr = 10\n' - mod1.write(code1) - code2 = 'from mod1 import AClass\na_var = AClass()\n' - mod2.write(code2) - self._introduce_factory(mod1, mod1.read().index('AClass') + 1, 'create') - self.project.history.undo() - self.assertEquals(code1, mod1.read()) - self.assertEquals(code2, mod2.read()) - - def test_using_on_an_occurance_outside_the_main_module(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('class AClass(object):\n an_attr = 10\n') - mod2.write('import mod1\na_var = mod1.AClass()\n') - self._introduce_factory(mod2, mod2.read().index('AClass') + 1, 'create') - expected1 = 'class AClass(object):\n' \ - ' an_attr = 10\n\n' \ - ' @staticmethod\n' \ - ' def create(*args, **kwds):\n' \ - ' return AClass(*args, **kwds)\n' - expected2 = 'import mod1\n' \ - 'a_var = mod1.AClass.create()\n' - self.assertEquals(expected1, mod1.read()) - self.assertEquals(expected2, mod2.read()) - - def test_introduce_factory_in_nested_scopes(self): - code = 'def create_var():\n'\ - ' class AClass(object):\n'\ - ' an_attr = 10\n'\ - ' return AClass()\n' - mod = testutils.create_module(self.project, 'mod') - mod.write(code) - expected = 'def create_var():\n'\ - ' class AClass(object):\n'\ - ' an_attr = 10\n\n'\ - ' @staticmethod\n def create(*args, **kwds):\n'\ - ' return AClass(*args, **kwds)\n'\ - ' return AClass.create()\n' - self._introduce_factory(mod, mod.read().index('AClass') + 1, 'create') - self.assertEquals(expected, mod.read()) - - def test_adding_factory_for_global_factories(self): - code = 'class AClass(object):\n an_attr = 10\n' - mod = testutils.create_module(self.project, 'mod') - mod.write(code) - expected = 'class AClass(object):\n' \ - ' an_attr = 10\n\n' \ - 'def create(*args, **kwds):\n' \ - ' return AClass(*args, **kwds)\n' - self._introduce_factory(mod, mod.read().index('AClass') + 1, - 'create', global_factory=True) - self.assertEquals(expected, mod.read()) - - def test_get_name_for_factories(self): - code = 'class C(object):\n pass\n' - mod = testutils.create_module(self.project, 'mod') - mod.write(code) - factory = IntroduceFactory(self.project, mod, - mod.read().index('C') + 1) - self.assertEquals('C', factory.get_name()) - - @testutils.assert_raises(RefactoringError) - def test_raising_exception_for_global_factory_for_nested_classes(self): - code = 'def create_var():\n'\ - ' class AClass(object):\n'\ - ' an_attr = 10\n'\ - ' return AClass()\n' - mod = testutils.create_module(self.project, 'mod') - mod.write(code) - self._introduce_factory(mod, mod.read().index('AClass') + 1, - 'create', global_factory=True) - - def test_changing_occurances_in_the_main_module_for_global_factories(self): - code = 'class AClass(object):\n' \ - ' an_attr = 10\n' \ - 'a_var = AClass()' - mod = testutils.create_module(self.project, 'mod') - mod.write(code) - expected = 'class AClass(object):\n an_attr = 10\n\n' \ - 'def create(*args, **kwds):\n' \ - ' return AClass(*args, **kwds)\n'\ - 'a_var = create()' - self._introduce_factory(mod, mod.read().index('AClass') + 1, - 'create', global_factory=True) - self.assertEquals(expected, mod.read()) - - def test_changing_occurances_in_other_modules_for_global_factories(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('class AClass(object):\n an_attr = 10\n') - mod2.write('import mod1\na_var = mod1.AClass()\n') - self._introduce_factory(mod1, mod1.read().index('AClass') + 1, - 'create', global_factory=True) - expected1 = 'class AClass(object):\n' \ - ' an_attr = 10\n\n' \ - 'def create(*args, **kwds):\n' \ - ' return AClass(*args, **kwds)\n' - expected2 = 'import mod1\n' \ - 'a_var = mod1.create()\n' - self.assertEquals(expected1, mod1.read()) - self.assertEquals(expected2, mod2.read()) - - def test_importing_if_necessary_in_other_modules_for_global_factories(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('class AClass(object):\n an_attr = 10\n') - mod2.write('from mod1 import AClass\npair = AClass(), AClass\n') - self._introduce_factory(mod1, mod1.read().index('AClass') + 1, - 'create', global_factory=True) - expected1 = 'class AClass(object):\n' \ - ' an_attr = 10\n\n' \ - 'def create(*args, **kwds):\n' \ - ' return AClass(*args, **kwds)\n' - expected2 = 'from mod1 import AClass, create\n' \ - 'pair = create(), AClass\n' - self.assertEquals(expected1, mod1.read()) - self.assertEquals(expected2, mod2.read()) - - def test_changing_occurances_for_renamed_classes(self): - code = 'class AClass(object):\n an_attr = 10\na_class = AClass\na_var = a_class()' - mod = testutils.create_module(self.project, 'mod') - mod.write(code) - expected = 'class AClass(object):\n' \ - ' an_attr = 10\n\n' \ - ' @staticmethod\n' \ - ' def create(*args, **kwds):\n' \ - ' return AClass(*args, **kwds)\n' \ - 'a_class = AClass\n' \ - 'a_var = a_class()' - self._introduce_factory(mod, mod.read().index('a_class') + 1, 'create') - self.assertEquals(expected, mod.read()) - - def test_changing_occurrences_in_the_same_module_with_conflicting_ranges(self): - mod = testutils.create_module(self.project, 'mod') - code = 'class C(object):\n' \ - ' def create(self):\n' \ - ' return C()\n' - mod.write(code) - self._introduce_factory(mod, mod.read().index('C'), 'create_c', True) - expected = 'class C(object):\n' \ - ' def create(self):\n' \ - ' return create_c()\n' - self.assertTrue(mod.read().startswith(expected)) - - def _transform_module_to_package(self, resource): - self.project.do(rope.refactor.ModuleToPackage( - self.project, resource).get_changes()) - - def test_transform_module_to_package(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('import mod2\nfrom mod2 import AClass\n') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('class AClass(object):\n pass\n') - self._transform_module_to_package(mod2) - mod2 = self.project.get_resource('mod2') - root_folder = self.project.root - self.assertFalse(root_folder.has_child('mod2.py')) - self.assertEquals('class AClass(object):\n pass\n', - root_folder.get_child('mod2'). - get_child('__init__.py').read()) - - def test_transform_module_to_package_undoing(self): - pkg = testutils.create_package(self.project, 'pkg') - mod = testutils.create_module(self.project, 'mod', pkg) - self._transform_module_to_package(mod) - self.assertFalse(pkg.has_child('mod.py')) - self.assertTrue(pkg.get_child('mod').has_child('__init__.py')) - self.project.history.undo() - self.assertTrue(pkg.has_child('mod.py')) - self.assertFalse(pkg.has_child('mod')) - - def test_transform_module_to_package_with_relative_imports(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod1.write('import mod2\nfrom mod2 import AClass\n') - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod2.write('class AClass(object):\n pass\n') - self._transform_module_to_package(mod1) - new_init = self.project.get_resource('pkg/mod1/__init__.py') - self.assertEquals('import pkg.mod2\nfrom pkg.mod2 import AClass\n', - new_init.read()) - - def test_resources_parameter(self): - code = 'class A(object):\n an_attr = 10\n' - code1 = 'import mod\na = mod.A()\n' - mod = testutils.create_module(self.project, 'mod') - mod1 = testutils.create_module(self.project, 'mod1') - mod.write(code) - mod1.write(code1) - expected = 'class A(object):\n' \ - ' an_attr = 10\n\n' \ - ' @staticmethod\n' \ - ' def create(*args, **kwds):\n' \ - ' return A(*args, **kwds)\n' - self._introduce_factory(mod, mod.read().index('A') + 1, - 'create', resources=[mod]) - self.assertEquals(expected, mod.read()) - self.assertEquals(code1, mod1.read()) - - -class EncapsulateFieldTest(unittest.TestCase): - - def setUp(self): - super(EncapsulateFieldTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod') - self.mod1 = testutils.create_module(self.project, 'mod1') - self.a_class = 'class A(object):\n' \ - ' def __init__(self):\n' \ - ' self.attr = 1\n' - self.added_methods = '\n' \ - ' def get_attr(self):\n' \ - ' return self.attr\n\n' \ - ' def set_attr(self, value):\n' \ - ' self.attr = value\n' - self.encapsulated = self.a_class + self.added_methods - - def tearDown(self): - testutils.remove_project(self.project) - super(EncapsulateFieldTest, self).tearDown() - - def _encapsulate(self, resource, offset, **args): - changes = EncapsulateField(self.project, resource, offset).\ - get_changes(**args) - self.project.do(changes) - - def test_adding_getters_and_setters(self): - code = self.a_class - self.mod.write(code) - self._encapsulate(self.mod, code.index('attr') + 1) - self.assertEquals(self.encapsulated, self.mod.read()) - - def test_changing_getters_in_other_modules(self): - code = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'range(a_var.attr)\n' - self.mod1.write(code) - self.mod.write(self.a_class) - self._encapsulate(self.mod, self.mod.read().index('attr') + 1) - expected = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'range(a_var.get_attr())\n' - self.assertEquals(expected, self.mod1.read()) - - def test_changing_setters_in_other_modules(self): - code = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a_var.attr = 1\n' - self.mod1.write(code) - self.mod.write(self.a_class) - self._encapsulate(self.mod, self.mod.read().index('attr') + 1) - expected = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a_var.set_attr(1)\n' - self.assertEquals(expected, self.mod1.read()) - - def test_changing_getters_in_setters(self): - code = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a_var.attr = 1 + a_var.attr\n' - self.mod1.write(code) - self.mod.write(self.a_class) - self._encapsulate(self.mod, self.mod.read().index('attr') + 1) - expected = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a_var.set_attr(1 + a_var.get_attr())\n' - self.assertEquals(expected, self.mod1.read()) - - def test_appending_to_class_end(self): - self.mod1.write(self.a_class + 'a_var = A()\n') - self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1) - self.assertEquals(self.encapsulated + 'a_var = A()\n', - self.mod1.read()) - - def test_performing_in_other_modules(self): - code = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'range(a_var.attr)\n' - self.mod1.write(code) - self.mod.write(self.a_class) - self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1) - self.assertEquals(self.encapsulated, self.mod.read()) - expected = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'range(a_var.get_attr())\n' - self.assertEquals(expected, self.mod1.read()) - - def test_changing_main_module_occurances(self): - code = self.a_class + \ - 'a_var = A()\n' \ - 'a_var.attr = a_var.attr * 2\n' - self.mod1.write(code) - self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1) - expected = self.encapsulated + \ - 'a_var = A()\n' \ - 'a_var.set_attr(a_var.get_attr() * 2)\n' - self.assertEquals(expected, self.mod1.read()) - - @testutils.assert_raises(RefactoringError) - def test_raising_exception_when_performed_on_non_attributes(self): - self.mod1.write('attr = 10') - self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1) - - @testutils.assert_raises(RefactoringError) - def test_raising_exception_on_tuple_assignments(self): - self.mod.write(self.a_class) - code = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a_var.attr = 1\n' \ - 'a_var.attr, b = 1, 2\n' - self.mod1.write(code) - self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1) - - @testutils.assert_raises(RefactoringError) - def test_raising_exception_on_tuple_assignments2(self): - self.mod.write(self.a_class) - code = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a_var.attr = 1\n' \ - 'b, a_var.attr = 1, 2\n' - self.mod1.write(code) - self._encapsulate(self.mod1, self.mod1.read().index('attr') + 1) - - def test_tuple_assignments_and_function_calls(self): - code = 'import mod\n' \ - 'def func(a1=0, a2=0):\n' \ - ' pass\n' \ - 'a_var = mod.A()\n' \ - 'func(a_var.attr, a2=2)\n' - self.mod1.write(code) - self.mod.write(self.a_class) - self._encapsulate(self.mod, self.mod.read().index('attr') + 1) - expected = 'import mod\n' \ - 'def func(a1=0, a2=0):\n' \ - ' pass\n' \ - 'a_var = mod.A()\n' \ - 'func(a_var.get_attr(), a2=2)\n' - self.assertEquals(expected, self.mod1.read()) - - def test_tuple_assignments(self): - code = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a, b = a_var.attr, 1\n' - self.mod1.write(code) - self.mod.write(self.a_class) - self._encapsulate(self.mod, self.mod.read().index('attr') + 1) - expected = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a, b = a_var.get_attr(), 1\n' - self.assertEquals(expected, self.mod1.read()) - - def test_changing_augmented_assignments(self): - code = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a_var.attr += 1\n' - self.mod1.write(code) - self.mod.write(self.a_class) - self._encapsulate(self.mod, self.mod.read().index('attr') + 1) - expected = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a_var.set_attr(a_var.get_attr() + 1)\n' - self.assertEquals(expected, self.mod1.read()) - - def test_changing_augmented_assignments2(self): - code = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a_var.attr <<= 1\n' - self.mod1.write(code) - self.mod.write(self.a_class) - self._encapsulate(self.mod, self.mod.read().index('attr') + 1) - expected = 'import mod\n' \ - 'a_var = mod.A()\n' \ - 'a_var.set_attr(a_var.get_attr() << 1)\n' - self.assertEquals(expected, self.mod1.read()) - - def test_changing_occurrences_inside_the_class(self): - new_class = self.a_class + '\n' \ - ' def a_func(self):\n' \ - ' self.attr = 1\n' - self.mod.write(new_class) - self._encapsulate(self.mod, self.mod.read().index('attr') + 1) - expected = self.a_class + '\n' \ - ' def a_func(self):\n' \ - ' self.set_attr(1)\n' + \ - self.added_methods - self.assertEquals(expected, self.mod.read()) - - def test_getter_and_setter_parameters(self): - self.mod.write(self.a_class) - self._encapsulate(self.mod, self.mod.read().index('attr') + 1, - getter='getAttr', setter='setAttr') - new_methods = self.added_methods.replace('get_attr', 'getAttr').\ - replace('set_attr', 'setAttr') - expected = self.a_class + new_methods - self.assertEquals(expected, self.mod.read()) - - def test_using_resources_parameter(self): - self.mod1.write('import mod\na = mod.A()\nvar = a.attr\n') - self.mod.write(self.a_class) - self._encapsulate(self.mod, self.mod.read().index('attr') + 1, - resources=[self.mod]) - self.assertEquals('import mod\na = mod.A()\nvar = a.attr\n', - self.mod1.read()) - expected = self.a_class + self.added_methods - self.assertEquals(expected, self.mod.read()) - - -class LocalToFieldTest(unittest.TestCase): - - def setUp(self): - super(LocalToFieldTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod') - - def tearDown(self): - testutils.remove_project(self.project) - super(LocalToFieldTest, self).tearDown() - - def _perform_convert_local_variable_to_field(self, resource, offset): - changes = LocalToField( - self.project, resource, offset).get_changes() - self.project.do(changes) - - def test_simple_local_to_field(self): - code = 'class A(object):\n' \ - ' def a_func(self):\n' \ - ' var = 10\n' - self.mod.write(code) - self._perform_convert_local_variable_to_field(self.mod, - code.index('var') + 1) - expected = 'class A(object):\n' \ - ' def a_func(self):\n' \ - ' self.var = 10\n' - self.assertEquals(expected, self.mod.read()) - - @testutils.assert_raises(RefactoringError) - def test_raising_exception_when_performed_on_a_global_var(self): - self.mod.write('var = 10\n') - self._perform_convert_local_variable_to_field( - self.mod, self.mod.read().index('var') + 1) - - @testutils.assert_raises(RefactoringError) - def test_raising_exception_when_performed_on_field(self): - code = 'class A(object):\n' \ - ' def a_func(self):\n' \ - ' self.var = 10\n' - self.mod.write(code) - self._perform_convert_local_variable_to_field( - self.mod, self.mod.read().index('var') + 1) - - @testutils.assert_raises(RefactoringError) - def test_raising_exception_when_performed_on_a_parameter(self): - code = 'class A(object):\n' \ - ' def a_func(self, var):\n' \ - ' a = var\n' - self.mod.write(code) - self._perform_convert_local_variable_to_field( - self.mod, self.mod.read().index('var') + 1) - - # NOTE: This situation happens alot and is normally not an error - #@testutils.assert_raises(RefactoringError) - def test_not_raising_exception_when_there_is_a_field_with_the_same_name(self): - code = 'class A(object):\n' \ - ' def __init__(self):\n' \ - ' self.var = 1\n' \ - ' def a_func(self):\n var = 10\n' - self.mod.write(code) - self._perform_convert_local_variable_to_field( - self.mod, self.mod.read().rindex('var') + 1) - - def test_local_to_field_with_self_renamed(self): - code = 'class A(object):\n' \ - ' def a_func(myself):\n' \ - ' var = 10\n' - self.mod.write(code) - self._perform_convert_local_variable_to_field(self.mod, - code.index('var') + 1) - expected = 'class A(object):\n' \ - ' def a_func(myself):\n' \ - ' myself.var = 10\n' - self.assertEquals(expected, self.mod.read()) - - -class IntroduceParameterTest(unittest.TestCase): - - def setUp(self): - super(IntroduceParameterTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod') - - def tearDown(self): - testutils.remove_project(self.project) - super(IntroduceParameterTest, self).tearDown() - - def _introduce_parameter(self, offset, name): - rope.refactor.introduce_parameter.IntroduceParameter( - self.project, self.mod, offset).get_changes(name).do() - - def test_simple_case(self): - code = 'var = 1\n' \ - 'def f():\n' \ - ' b = var\n' - self.mod.write(code) - offset = self.mod.read().rindex('var') - self._introduce_parameter(offset, 'var') - expected = 'var = 1\n' \ - 'def f(var=var):\n' \ - ' b = var\n' - self.assertEquals(expected, self.mod.read()) - - def test_changing_function_body(self): - code = 'var = 1\n' \ - 'def f():\n' \ - ' b = var\n' - self.mod.write(code) - offset = self.mod.read().rindex('var') - self._introduce_parameter(offset, 'p1') - expected = 'var = 1\n' \ - 'def f(p1=var):\n' \ - ' b = p1\n' - self.assertEquals(expected, self.mod.read()) - - @testutils.assert_raises(RefactoringError) - def test_unknown_variables(self): - self.mod.write('def f():\n b = var + c\n') - offset = self.mod.read().rindex('var') - self._introduce_parameter(offset, 'p1') - self.assertEquals('def f(p1=var):\n b = p1 + c\n', - self.mod.read()) - - @testutils.assert_raises(RefactoringError) - def test_failing_when_not_inside(self): - self.mod.write('var = 10\nb = var\n') - offset = self.mod.read().rindex('var') - self._introduce_parameter(offset, 'p1') - - def test_attribute_accesses(self): - code = 'class C(object):\n' \ - ' a = 10\nc = C()\n' \ - 'def f():\n' \ - ' b = c.a\n' - self.mod.write(code) - offset = self.mod.read().rindex('a') - self._introduce_parameter(offset, 'p1') - expected = 'class C(object):\n' \ - ' a = 10\n' \ - 'c = C()\n' \ - 'def f(p1=c.a):\n' \ - ' b = p1\n' - self.assertEquals(expected, self.mod.read()) - - def test_introducing_parameters_for_methods(self): - code = 'var = 1\n' \ - 'class C(object):\n' \ - ' def f(self):\n' \ - ' b = var\n' - self.mod.write(code) - offset = self.mod.read().rindex('var') - self._introduce_parameter(offset, 'p1') - expected = 'var = 1\n' \ - 'class C(object):\n' \ - ' def f(self, p1=var):\n' \ - ' b = p1\n' - self.assertEquals(expected, self.mod.read()) - - -class _MockTaskObserver(object): - - def __init__(self): - self.called = 0 - - def __call__(self): - self.called += 1 - -class TaskHandleTest(unittest.TestCase): - - def test_trivial_case(self): - handle = rope.base.taskhandle.TaskHandle() - self.assertFalse(handle.is_stopped()) - - def test_stopping(self): - handle = rope.base.taskhandle.TaskHandle() - handle.stop() - self.assertTrue(handle.is_stopped()) - - def test_job_sets(self): - handle = rope.base.taskhandle.TaskHandle() - jobs = handle.create_jobset() - self.assertEquals([jobs], handle.get_jobsets()) - - def test_starting_and_finishing_jobs(self): - handle = rope.base.taskhandle.TaskHandle() - jobs = handle.create_jobset(name='test job set', count=1) - jobs.started_job('job1') - jobs.finished_job() - - @testutils.assert_raises(InterruptedTaskError) - def test_test_checking_status(self): - handle = rope.base.taskhandle.TaskHandle() - jobs = handle.create_jobset() - handle.stop() - jobs.check_status() - - @testutils.assert_raises(InterruptedTaskError) - def test_test_checking_status_when_starting(self): - handle = rope.base.taskhandle.TaskHandle() - jobs = handle.create_jobset() - handle.stop() - jobs.started_job('job1') - - def test_calling_the_observer_after_stopping(self): - handle = rope.base.taskhandle.TaskHandle() - observer = _MockTaskObserver() - handle.add_observer(observer) - handle.stop() - self.assertEquals(1, observer.called) - - def test_calling_the_observer_after_creating_job_sets(self): - handle = rope.base.taskhandle.TaskHandle() - observer = _MockTaskObserver() - handle.add_observer(observer) - jobs = handle.create_jobset() - self.assertEquals(1, observer.called) - - def test_calling_the_observer_when_starting_and_finishing_jobs(self): - handle = rope.base.taskhandle.TaskHandle() - observer = _MockTaskObserver() - handle.add_observer(observer) - jobs = handle.create_jobset(name='test job set', count=1) - jobs.started_job('job1') - jobs.finished_job() - self.assertEquals(3, observer.called) - - def test_job_set_get_percent_done(self): - handle = rope.base.taskhandle.TaskHandle() - jobs = handle.create_jobset(name='test job set', count=2) - self.assertEquals(0, jobs.get_percent_done()) - jobs.started_job('job1') - jobs.finished_job() - self.assertEquals(50, jobs.get_percent_done()) - jobs.started_job('job2') - jobs.finished_job() - self.assertEquals(100, jobs.get_percent_done()) - - def test_getting_job_name(self): - handle = rope.base.taskhandle.TaskHandle() - jobs = handle.create_jobset(name='test job set', count=1) - self.assertEquals('test job set', jobs.get_name()) - self.assertEquals(None, jobs.get_active_job_name()) - jobs.started_job('job1') - self.assertEquals('job1', jobs.get_active_job_name()) - - -def suite(): - result = unittest.TestSuite() - result.addTests(ropetest.refactor.renametest.suite()) - result.addTests(unittest.makeSuite( - ropetest.refactor.extracttest.ExtractMethodTest)) - result.addTests(unittest.makeSuite(IntroduceFactoryTest)) - result.addTests(unittest.makeSuite( - ropetest.refactor.movetest.MoveRefactoringTest)) - result.addTests(ropetest.refactor.inlinetest.suite()) - result.addTests(unittest.makeSuite( - ropetest.refactor.patchedasttest.PatchedASTTest)) - result.addTests(unittest.makeSuite(EncapsulateFieldTest)) - result.addTests(unittest.makeSuite(LocalToFieldTest)) - result.addTests(unittest.makeSuite( - change_signature_test.ChangeSignatureTest)) - result.addTests(unittest.makeSuite(IntroduceParameterTest)) - result.addTests(ropetest.refactor.importutilstest.suite()) - result.addTests(similarfindertest.suite()) - result.addTests(unittest.makeSuite(TaskHandleTest)) - result.addTests(unittest.makeSuite(ropetest.refactor. - restructuretest.RestructureTest)) - result.addTests(unittest.makeSuite(ropetest.refactor. - suitestest.SuiteTest)) - result.addTests(unittest.makeSuite(ropetest.refactor.multiprojecttest. - MultiProjectRefactoringTest)) - result.addTests(unittest.makeSuite(ropetest.refactor.usefunctiontest. - UseFunctionTest)) - return result - - -if __name__ == '__main__': - import sys - if len(sys.argv) > 1: - unittest.main() - else: - runner = unittest.TextTestRunner() - result = runner.run(suite()) - sys.exit(not result.wasSuccessful()) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/change_signature_test.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/change_signature_test.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,413 +0,0 @@ -import unittest - -import rope.base.exceptions -from rope.refactor import change_signature -from rope.refactor.change_signature import * -from ropetest import testutils - - -class ChangeSignatureTest(unittest.TestCase): - - def setUp(self): - super(ChangeSignatureTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod') - - def tearDown(self): - testutils.remove_project(self.project) - super(ChangeSignatureTest, self).tearDown() - - def test_normalizing_parameters_for_trivial_case(self): - code = 'def a_func():\n pass\na_func()' - self.mod.write(code) - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentNormalizer()])) - self.assertEquals(code, self.mod.read()) - - def test_normalizing_parameters_for_trivial_case2(self): - code = 'def a_func(param):\n pass\na_func(2)' - self.mod.write(code) - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentNormalizer()])) - self.assertEquals(code, self.mod.read()) - - def test_normalizing_parameters_for_unneeded_keyword(self): - self.mod.write('def a_func(param):\n pass\na_func(param=1)') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentNormalizer()])) - self.assertEquals('def a_func(param):\n pass\na_func(1)', self.mod.read()) - - def test_normalizing_parameters_for_unneeded_keyword_for_methods(self): - code = 'class A(object):\n' \ - ' def a_func(self, param):\n' \ - ' pass\n' \ - 'a_var = A()\n' \ - 'a_var.a_func(param=1)\n' - self.mod.write(code) - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentNormalizer()])) - expected = 'class A(object):\n' \ - ' def a_func(self, param):\n' \ - ' pass\n' \ - 'a_var = A()\n' \ - 'a_var.a_func(1)\n' - self.assertEquals(expected, self.mod.read()) - - def test_normalizing_parameters_for_unsorted_keyword(self): - self.mod.write('def a_func(p1, p2):\n pass\na_func(p2=2, p1=1)') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentNormalizer()])) - self.assertEquals('def a_func(p1, p2):\n pass\na_func(1, 2)', - self.mod.read()) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_raising_exceptions_for_non_functions(self): - self.mod.write('a_var = 10') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_var') + 1) - - def test_normalizing_parameters_for_args_parameter(self): - self.mod.write('def a_func(*arg):\n pass\na_func(1, 2)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentNormalizer()])) - self.assertEquals('def a_func(*arg):\n pass\na_func(1, 2)\n', - self.mod.read()) - - def test_normalizing_parameters_for_args_parameter_and_keywords(self): - self.mod.write('def a_func(param, *args):\n pass\na_func(*[1, 2, 3])\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentNormalizer()])) - self.assertEquals('def a_func(param, *args):\n pass\n' - 'a_func(*[1, 2, 3])\n', self.mod.read()) - - def test_normalizing_functions_from_other_modules(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('def a_func(param):\n pass\n') - self.mod.write('import mod1\nmod1.a_func(param=1)\n') - signature = ChangeSignature(self.project, mod1, - mod1.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentNormalizer()])) - self.assertEquals('import mod1\nmod1.a_func(1)\n', self.mod.read()) - - def test_normalizing_parameters_for_keyword_parameters(self): - self.mod.write('def a_func(p1, **kwds):\n pass\n' - 'a_func(p2=2, p1=1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentNormalizer()])) - self.assertEquals('def a_func(p1, **kwds):\n pass\n' - 'a_func(1, p2=2)\n', self.mod.read()) - - def test_removing_arguments(self): - self.mod.write('def a_func(p1):\n pass\na_func(1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentRemover(0)])) - self.assertEquals('def a_func():\n pass\na_func()\n', - self.mod.read()) - - def test_removing_arguments_with_multiple_args(self): - self.mod.write('def a_func(p1, p2):\n pass\na_func(1, 2)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentRemover(0)])) - self.assertEquals('def a_func(p2):\n pass\na_func(2)\n', - self.mod.read()) - - def test_removing_arguments_passed_as_keywords(self): - self.mod.write('def a_func(p1):\n pass\na_func(p1=1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentRemover(0)])) - self.assertEquals('def a_func():\n pass\na_func()\n', - self.mod.read()) - - def test_removing_arguments_with_defaults(self): - self.mod.write('def a_func(p1=1):\n pass\na_func(1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentRemover(0)])) - self.assertEquals('def a_func():\n pass\na_func()\n', - self.mod.read()) - - def test_removing_arguments_star_args(self): - self.mod.write('def a_func(p1, *args):\n pass\na_func(1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentRemover(1)])) - self.assertEquals('def a_func(p1):\n pass\na_func(1)\n', - self.mod.read()) - - def test_removing_keyword_arg(self): - self.mod.write('def a_func(p1, **kwds):\n pass\na_func(1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentRemover(1)])) - self.assertEquals('def a_func(p1):\n pass\na_func(1)\n', - self.mod.read()) - - def test_removing_keyword_arg2(self): - self.mod.write('def a_func(p1, *args, **kwds):\n pass\na_func(1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentRemover(2)])) - self.assertEquals('def a_func(p1, *args):\n pass\na_func(1)\n', - self.mod.read()) - - # XXX: What to do here for star args? - def xxx_test_removing_arguments_star_args2(self): - self.mod.write('def a_func(p1, *args):\n pass\n' - 'a_func(2, 3, p1=1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentRemover(1)])) - self.assertEquals('def a_func(p1):\n pass\na_func(p1=1)\n', - self.mod.read()) - - # XXX: What to do here for star args? - def xxx_test_removing_arguments_star_args3(self): - self.mod.write('def a_func(p1, *args):\n pass\n' - 'a_func(*[1, 2, 3])\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentRemover(1)])) - self.assertEquals('def a_func(p1):\n pass\na_func(*[1, 2, 3])\n', - self.mod.read()) - - def test_adding_arguments_for_normal_args_changing_definition(self): - self.mod.write('def a_func():\n pass\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentAdder(0, 'p1')])) - self.assertEquals('def a_func(p1):\n pass\n', self.mod.read()) - - def test_adding_arguments_for_normal_args_with_defaults(self): - self.mod.write('def a_func():\n pass\na_func()\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - adder = ArgumentAdder(0, 'p1', 'None') - self.project.do(signature.get_changes([adder])) - self.assertEquals('def a_func(p1=None):\n pass\na_func()\n', - self.mod.read()) - - def test_adding_arguments_for_normal_args_changing_calls(self): - self.mod.write('def a_func():\n pass\na_func()\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - adder = ArgumentAdder(0, 'p1', 'None', '1') - self.project.do(signature.get_changes([adder])) - self.assertEquals('def a_func(p1=None):\n pass\na_func(1)\n', - self.mod.read()) - - def test_adding_arguments_for_normal_args_changing_calls_with_keywords(self): - self.mod.write('def a_func(p1=0):\n pass\na_func()\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - adder = ArgumentAdder(1, 'p2', '0', '1') - self.project.do(signature.get_changes([adder])) - self.assertEquals('def a_func(p1=0, p2=0):\n pass\na_func(p2=1)\n', - self.mod.read()) - - def test_adding_arguments_for_normal_args_changing_calls_with_no_value(self): - self.mod.write('def a_func(p2=0):\n pass\na_func(1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - adder = ArgumentAdder(0, 'p1', '0', None) - self.project.do(signature.get_changes([adder])) - self.assertEquals('def a_func(p1=0, p2=0):\n pass\na_func(p2=1)\n', - self.mod.read()) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_adding_duplicate_parameter_and_raising_exceptions(self): - self.mod.write('def a_func(p1):\n pass\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentAdder(1, 'p1')])) - - def test_inlining_default_arguments(self): - self.mod.write('def a_func(p1=0):\n pass\na_func()\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentDefaultInliner(0)])) - self.assertEquals('def a_func(p1=0):\n pass\n' - 'a_func(0)\n', self.mod.read()) - - def test_inlining_default_arguments2(self): - self.mod.write('def a_func(p1=0):\n pass\na_func(1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentDefaultInliner(0)])) - self.assertEquals('def a_func(p1=0):\n pass\n' - 'a_func(1)\n', self.mod.read()) - - def test_preserving_args_and_keywords_order(self): - self.mod.write('def a_func(*args, **kwds):\n pass\n' - 'a_func(3, 1, 2, a=1, c=3, b=2)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentNormalizer()])) - self.assertEquals('def a_func(*args, **kwds):\n pass\n' - 'a_func(3, 1, 2, a=1, c=3, b=2)\n', self.mod.read()) - - def test_change_order_for_only_one_parameter(self): - self.mod.write('def a_func(p1):\n pass\na_func(1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentReorderer([0])])) - self.assertEquals('def a_func(p1):\n pass\na_func(1)\n', - self.mod.read()) - - def test_change_order_for_two_parameter(self): - self.mod.write('def a_func(p1, p2):\n pass\na_func(1, 2)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentReorderer([1, 0])])) - self.assertEquals('def a_func(p2, p1):\n pass\na_func(2, 1)\n', - self.mod.read()) - - def test_reordering_multi_line_function_headers(self): - self.mod.write('def a_func(p1,\n p2):\n pass\na_func(1, 2)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentReorderer([1, 0])])) - self.assertEquals('def a_func(p2, p1):\n pass\na_func(2, 1)\n', - self.mod.read()) - - def test_changing_order_with_static_params(self): - self.mod.write('def a_func(p1, p2=0, p3=0):\n pass\na_func(1, 2)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentReorderer([0, 2, 1])])) - self.assertEquals('def a_func(p1, p3=0, p2=0):\n pass\n' - 'a_func(1, p2=2)\n', self.mod.read()) - - def test_doing_multiple_changes(self): - changers = [] - self.mod.write('def a_func(p1):\n pass\na_func(1)\n') - changers.append(change_signature.ArgumentRemover(0)) - changers.append(change_signature.ArgumentAdder(0, 'p2', None, None)) - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - signature.get_changes(changers).do() - self.assertEquals('def a_func(p2):\n pass\na_func()\n', - self.mod.read()) - - def test_doing_multiple_changes2(self): - changers = [] - self.mod.write('def a_func(p1, p2):\n pass\na_func(p2=2)\n') - changers.append(change_signature.ArgumentAdder(2, 'p3', None, '3')) - changers.append(change_signature.ArgumentReorderer([1, 0, 2])) - changers.append(change_signature.ArgumentRemover(1)) - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - signature.get_changes(changers).do() - self.assertEquals('def a_func(p2, p3):\n pass\na_func(2, 3)\n', - self.mod.read()) - - def test_changing_signature_in_subclasses(self): - self.mod.write( - 'class A(object):\n def a_method(self):\n pass\n' - 'class B(A):\n def a_method(self):\n pass\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_method') + 1) - signature.get_changes([change_signature.ArgumentAdder(1, 'p1')], - in_hierarchy=True).do() - self.assertEquals( - 'class A(object):\n def a_method(self, p1):\n pass\n' - 'class B(A):\n def a_method(self, p1):\n pass\n', - self.mod.read()) - - def test_differentiating_class_accesses_from_instance_accesses(self): - self.mod.write( - 'class A(object):\n def a_func(self, param):\n pass\n' - 'a_var = A()\nA.a_func(a_var, param=1)') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('a_func') + 1) - self.project.do(signature.get_changes([ArgumentRemover(1)])) - self.assertEquals( - 'class A(object):\n def a_func(self):\n pass\n' - 'a_var = A()\nA.a_func(a_var)', self.mod.read()) - - def test_changing_signature_for_constructors(self): - self.mod.write( - 'class C(object):\n def __init__(self, p):\n pass\n' - 'c = C(1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('C') + 1) - signature.get_changes([change_signature.ArgumentRemover(1)]).do() - self.assertEquals( - 'class C(object):\n def __init__(self):\n pass\n' - 'c = C()\n', - self.mod.read()) - - def test_changing_signature_for_constructors2(self): - self.mod.write( - 'class C(object):\n def __init__(self, p):\n pass\n' - 'c = C(1)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('__init__') + 1) - signature.get_changes([change_signature.ArgumentRemover(1)]).do() - self.assertEquals( - 'class C(object):\n def __init__(self):\n pass\n' - 'c = C()\n', - self.mod.read()) - - def test_changing_signature_for_constructors_when_using_super(self): - self.mod.write( - 'class A(object):\n def __init__(self, p):\n pass\n' - 'class B(A):\n ' - 'def __init__(self, p):\n super(B, self).__init__(p)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().index('__init__') + 1) - signature.get_changes([change_signature.ArgumentRemover(1)]).do() - self.assertEquals( - 'class A(object):\n def __init__(self):\n pass\n' - 'class B(A):\n ' - 'def __init__(self, p):\n super(B, self).__init__()\n', - self.mod.read()) - - def test_redordering_arguments_reported_by_mft(self): - self.mod.write('def f(a, b, c):\n pass\nf(1, 2, 3)\n') - signature = ChangeSignature(self.project, self.mod, - self.mod.read().rindex('f')) - signature.get_changes( - [change_signature.ArgumentReorderer([1, 2, 0])]).do() - self.assertEquals('def f(b, c, a):\n pass\nf(2, 3, 1)\n', - self.mod.read()) - - def test_resources_parameter(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('def a_func(param):\n pass\n') - self.mod.write('import mod1\nmod1.a_func(1)\n') - signature = ChangeSignature(self.project, mod1, - mod1.read().index('a_func') + 1) - signature.get_changes([change_signature.ArgumentRemover(0)], - resources=[mod1]).do() - self.assertEquals('import mod1\nmod1.a_func(1)\n', self.mod.read()) - self.assertEquals('def a_func():\n pass\n', mod1.read()) - - def test_reordering_and_automatic_defaults(self): - code = 'def f(p1, p2=2):\n' \ - ' pass\n' \ - 'f(1, 2)\n' - self.mod.write(code) - signature = ChangeSignature(self.project, self.mod, - code.index('f(')) - reorder = change_signature.ArgumentReorderer([1, 0], autodef='1') - signature.get_changes([reorder]).do() - expected = 'def f(p2=2, p1=1):\n' \ - ' pass\n' \ - 'f(2, 1)\n' - self.assertEquals(expected, self.mod.read()) - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/extracttest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/extracttest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,877 +0,0 @@ -import unittest - -import rope.base.codeanalyze -import rope.base.exceptions -import ropetest.testutils as testutils -from rope.refactor import extract -from ropetest import testutils - - -class ExtractMethodTest(unittest.TestCase): - - def setUp(self): - super(ExtractMethodTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - - def tearDown(self): - testutils.remove_project(self.project) - super(ExtractMethodTest, self).tearDown() - - def do_extract_method(self, source_code, start, end, extracted, **kwds): - testmod = testutils.create_module(self.project, 'testmod') - testmod.write(source_code) - extractor = extract.ExtractMethod( - self.project, testmod, start, end) - self.project.do(extractor.get_changes(extracted, **kwds)) - return testmod.read() - - def do_extract_variable(self, source_code, start, end, extracted, **kwds): - testmod = testutils.create_module(self.project, 'testmod') - testmod.write(source_code) - extractor = extract.ExtractVariable( self.project, testmod, start, end) - self.project.do(extractor.get_changes(extracted, **kwds)) - return testmod.read() - - def _convert_line_range_to_offset(self, code, start, end): - lines = rope.base.codeanalyze.SourceLinesAdapter(code) - return lines.get_line_start(start), lines.get_line_end(end) - - def test_simple_extract_function(self): - code = "def a_func():\n print('one')\n print('two')\n" - start, end = self._convert_line_range_to_offset(code, 2, 2) - refactored = self.do_extract_method(code, start, end, 'extracted') - expected = "def a_func():\n extracted()\n print('two')\n\n" \ - "def extracted():\n print('one')\n" - self.assertEquals(expected, refactored) - - def test_extract_function_at_the_end_of_file(self): - code = "def a_func():\n print('one')" - start, end = self._convert_line_range_to_offset(code, 2, 2) - refactored = self.do_extract_method(code, start, end, 'extracted') - expected = "def a_func():\n extracted()\n" \ - "def extracted():\n print('one')\n" - self.assertEquals(expected, refactored) - - def test_extract_function_after_scope(self): - code = "def a_func():\n print('one')\n print('two')\n\nprint('hey')\n" - start, end = self._convert_line_range_to_offset(code, 2, 2) - refactored = self.do_extract_method(code, start, end, 'extracted') - expected = "def a_func():\n extracted()\n print('two')\n\n" \ - "def extracted():\n print('one')\n\nprint('hey')\n" - self.assertEquals(expected, refactored) - - def test_simple_extract_function_with_parameter(self): - code = "def a_func():\n a_var = 10\n print(a_var)\n" - start, end = self._convert_line_range_to_offset(code, 3, 3) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = "def a_func():\n a_var = 10\n new_func(a_var)\n\n" \ - "def new_func(a_var):\n print(a_var)\n" - self.assertEquals(expected, refactored) - - def test_not_unread_variables_as_parameter(self): - code = "def a_func():\n a_var = 10\n print('hey')\n" - start, end = self._convert_line_range_to_offset(code, 3, 3) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = "def a_func():\n a_var = 10\n new_func()\n\n" \ - "def new_func():\n print('hey')\n" - self.assertEquals(expected, refactored) - - def test_simple_extract_function_with_two_parameter(self): - code = 'def a_func():\n a_var = 10\n another_var = 20\n' \ - ' third_var = a_var + another_var\n' - start, end = self._convert_line_range_to_offset(code, 4, 4) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func():\n a_var = 10\n another_var = 20\n' \ - ' new_func(a_var, another_var)\n\n' \ - 'def new_func(a_var, another_var):\n' \ - ' third_var = a_var + another_var\n' - self.assertEquals(expected, refactored) - - def test_simple_extract_function_with_return_value(self): - code = 'def a_func():\n a_var = 10\n print(a_var)\n' - start, end = self._convert_line_range_to_offset(code, 2, 2) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func():\n a_var = new_func()\n print(a_var)\n\n' \ - 'def new_func():\n a_var = 10\n return a_var\n' - self.assertEquals(expected, refactored) - - def test_extract_function_with_multiple_return_values(self): - code = 'def a_func():\n a_var = 10\n another_var = 20\n' \ - ' third_var = a_var + another_var\n' - start, end = self._convert_line_range_to_offset(code, 2, 3) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func():\n a_var, another_var = new_func()\n' \ - ' third_var = a_var + another_var\n\n' \ - 'def new_func():\n a_var = 10\n another_var = 20\n' \ - ' return a_var, another_var\n' - self.assertEquals(expected, refactored) - - def test_simple_extract_method(self): - code = 'class AClass(object):\n\n' \ - ' def a_func(self):\n print(1)\n print(2)\n' - start, end = self._convert_line_range_to_offset(code, 4, 4) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'class AClass(object):\n\n' \ - ' def a_func(self):\n' \ - ' self.new_func()\n' \ - ' print(2)\n\n' \ - ' def new_func(self):\n print(1)\n' - self.assertEquals(expected, refactored) - - def test_extract_method_with_args_and_returns(self): - code = 'class AClass(object):\n' \ - ' def a_func(self):\n' \ - ' a_var = 10\n' \ - ' another_var = a_var * 3\n' \ - ' third_var = a_var + another_var\n' - start, end = self._convert_line_range_to_offset(code, 4, 4) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'class AClass(object):\n' \ - ' def a_func(self):\n' \ - ' a_var = 10\n' \ - ' another_var = self.new_func(a_var)\n' \ - ' third_var = a_var + another_var\n\n' \ - ' def new_func(self, a_var):\n' \ - ' another_var = a_var * 3\n' \ - ' return another_var\n' - self.assertEquals(expected, refactored) - - def test_extract_method_with_self_as_argument(self): - code = 'class AClass(object):\n' \ - ' def a_func(self):\n' \ - ' print(self)\n' - start, end = self._convert_line_range_to_offset(code, 3, 3) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'class AClass(object):\n' \ - ' def a_func(self):\n' \ - ' self.new_func()\n\n' \ - ' def new_func(self):\n' \ - ' print(self)\n' - self.assertEquals(expected, refactored) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_extract_method_with_no_self_as_argument(self): - code = 'class AClass(object):\n' \ - ' def a_func():\n' \ - ' print(1)\n' - start, end = self._convert_line_range_to_offset(code, 3, 3) - refactored = self.do_extract_method(code, start, end, 'new_func') - - def test_extract_method_with_multiple_methods(self): - code = 'class AClass(object):\n' \ - ' def a_func(self):\n' \ - ' print(self)\n\n' \ - ' def another_func(self):\n' \ - ' pass\n' - start, end = self._convert_line_range_to_offset(code, 3, 3) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'class AClass(object):\n' \ - ' def a_func(self):\n' \ - ' self.new_func()\n\n' \ - ' def new_func(self):\n' \ - ' print(self)\n\n' \ - ' def another_func(self):\n' \ - ' pass\n' - self.assertEquals(expected, refactored) - - def test_extract_function_with_function_returns(self): - code = 'def a_func():\n def inner_func():\n pass\n' \ - ' inner_func()\n' - start, end = self._convert_line_range_to_offset(code, 2, 3) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func():\n' \ - ' inner_func = new_func()\n inner_func()\n\n' \ - 'def new_func():\n' \ - ' def inner_func():\n pass\n' \ - ' return inner_func\n' - self.assertEquals(expected, refactored) - - def test_simple_extract_global_function(self): - code = "print('one')\nprint('two')\nprint('three')\n" - start, end = self._convert_line_range_to_offset(code, 2, 2) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = "print('one')\n\ndef new_func():\n print('two')\n" \ - "\nnew_func()\nprint('three')\n" - self.assertEquals(expected, refactored) - - def test_extract_global_function_inside_ifs(self): - code = 'if True:\n a = 10\n' - start, end = self._convert_line_range_to_offset(code, 2, 2) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = '\ndef new_func():\n a = 10\n\nif True:\n' \ - ' new_func()\n' - self.assertEquals(expected, refactored) - - def test_extract_function_while_inner_function_reads(self): - code = 'def a_func():\n a_var = 10\n' \ - ' def inner_func():\n print(a_var)\n' \ - ' return inner_func\n' - start, end = self._convert_line_range_to_offset(code, 3, 4) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func():\n a_var = 10\n' \ - ' inner_func = new_func(a_var)\n return inner_func\n\n' \ - 'def new_func(a_var):\n' \ - ' def inner_func():\n print(a_var)\n' \ - ' return inner_func\n' - self.assertEquals(expected, refactored) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_extract_method_bad_range(self): - code = "def a_func():\n pass\na_var = 10\n" - start, end = self._convert_line_range_to_offset(code, 2, 3) - self.do_extract_method(code, start, end, 'new_func') - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_extract_method_bad_range2(self): - code = "class AClass(object):\n pass\n" - start, end = self._convert_line_range_to_offset(code, 1, 1) - self.do_extract_method(code, start, end, 'new_func') - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_extract_method_containing_return(self): - code = 'def a_func(arg):\n if arg:\n return arg * 2\n return 1' - start, end = self._convert_line_range_to_offset(code, 2, 4) - self.do_extract_method(code, start, end, 'new_func') - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_extract_method_containing_yield(self): - code = "def a_func(arg):\n yield arg * 2\n" - start, end = self._convert_line_range_to_offset(code, 2, 2) - self.do_extract_method(code, start, end, 'new_func') - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_extract_method_containing_uncomplete_lines(self): - code = 'a_var = 20\nanother_var = 30\n' - start = code.index('20') - end = code.index('30') + 2 - self.do_extract_method(code, start, end, 'new_func') - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_extract_method_containing_uncomplete_lines2(self): - code = 'a_var = 20\nanother_var = 30\n' - start = code.index('20') - end = code.index('another') + 5 - self.do_extract_method(code, start, end, 'new_func') - - def test_extract_function_and_argument_as_paramenter(self): - code = 'def a_func(arg):\n print(arg)\n' - start, end = self._convert_line_range_to_offset(code, 2, 2) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func(arg):\n new_func(arg)\n\n' \ - 'def new_func(arg):\n print(arg)\n' - self.assertEquals(expected, refactored) - - def test_extract_function_and_end_as_the_start_of_a_line(self): - code = 'print("hey")\nif True:\n pass\n' - start = 0 - end = code.index('\n') + 1 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = '\ndef new_func():\n print("hey")\n\n' \ - 'new_func()\nif True:\n pass\n' - self.assertEquals(expected, refactored) - - def test_extract_function_and_indented_blocks(self): - code = 'def a_func(arg):\n if True:\n' \ - ' if True:\n print(arg)\n' - start, end = self._convert_line_range_to_offset(code, 3, 4) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func(arg):\n if True:\n new_func(arg)\n\n' \ - 'def new_func(arg):\n if True:\n print(arg)\n' - self.assertEquals(expected, refactored) - - def test_extract_method_and_multi_line_headers(self): - code = 'def a_func(\n arg):\n print(arg)\n' - start, end = self._convert_line_range_to_offset(code, 3, 3) - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func(\n arg):\n new_func(arg)\n\n' \ - 'def new_func(arg):\n print(arg)\n' - self.assertEquals(expected, refactored) - - def test_single_line_extract_function(self): - code = 'a_var = 10 + 20\n' - start = code.index('10') - end = code.index('20') + 2 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = "\ndef new_func():\n return 10 + 20\n\na_var = new_func()\n" - self.assertEquals(expected, refactored) - - def test_single_line_extract_function2(self): - code = 'def a_func():\n a = 10\n b = a * 20\n' - start = code.rindex('a') - end = code.index('20') + 2 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func():\n a = 10\n b = new_func(a)\n' \ - '\ndef new_func(a):\n return a * 20\n' - self.assertEquals(expected, refactored) - - def test_single_line_extract_method_and_logical_lines(self): - code = 'a_var = 10 +\\\n 20\n' - start = code.index('10') - end = code.index('20') + 2 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = '\ndef new_func():\n return 10 + 20\n\na_var = new_func()\n' - self.assertEquals(expected, refactored) - - def test_single_line_extract_method_and_logical_lines2(self): - code = 'a_var = (10,\\\n 20)\n' - start = code.index('10') - 1 - end = code.index('20') + 3 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = '\ndef new_func():\n' \ - ' return (10, 20)\n\na_var = new_func()\n' - self.assertEquals(expected, refactored) - - def test_single_line_extract_method(self): - code = "class AClass(object):\n\n" \ - " def a_func(self):\n a = 10\n b = a * a\n" - start = code.rindex('=') + 2 - end = code.rindex('a') + 1 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'class AClass(object):\n\n' \ - ' def a_func(self):\n' \ - ' a = 10\n b = self.new_func(a)\n\n' \ - ' def new_func(self, a):\n return a * a\n' - self.assertEquals(expected, refactored) - - def test_single_line_extract_function_if_condition(self): - code = 'if True:\n pass\n' - start = code.index('True') - end = code.index('True') + 4 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = "\ndef new_func():\n return True\n\nif new_func():\n pass\n" - self.assertEquals(expected, refactored) - - def test_unneeded_params(self): - code = 'class A(object):\n ' \ - 'def a_func(self):\n a_var = 10\n a_var += 2\n' - start = code.rindex('2') - end = code.rindex('2') + 1 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'class A(object):\n' \ - ' def a_func(self):\n a_var = 10\n' \ - ' a_var += self.new_func()\n\n' \ - ' def new_func(self):\n return 2\n' - self.assertEquals(expected, refactored) - - def test_breaks_and_continues_inside_loops(self): - code = 'def a_func():\n for i in range(10):\n continue\n' - start = code.index('for') - end = len(code) - 1 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func():\n new_func()\n\n' \ - 'def new_func():\n' \ - ' for i in range(10):\n continue\n' - self.assertEquals(expected, refactored) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_breaks_and_continues_outside_loops(self): - code = 'def a_func():\n' \ - ' for i in range(10):\n a = i\n continue\n' - start = code.index('a = i') - end = len(code) - 1 - refactored = self.do_extract_method(code, start, end, 'new_func') - - def test_variable_writes_followed_by_variable_reads_after_extraction(self): - code = 'def a_func():\n a = 1\n a = 2\n b = a\n' - start = code.index('a = 1') - end = code.index('a = 2') - 1 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func():\n new_func()\n a = 2\n b = a\n\n' \ - 'def new_func():\n a = 1\n' - self.assertEquals(expected, refactored) - - def test_variable_writes_followed_by_variable_reads_inside_extraction(self): - code = 'def a_func():\n a = 1\n a = 2\n b = a\n' - start = code.index('a = 2') - end = len(code) - 1 - refactored = self.do_extract_method(code, start, end, 'new_func') - expected = 'def a_func():\n a = 1\n new_func()\n\n' \ - 'def new_func():\n a = 2\n b = a\n' - self.assertEquals(expected, refactored) - - def test_extract_variable(self): - code = 'a_var = 10 + 20\n' - start = code.index('10') - end = code.index('20') + 2 - refactored = self.do_extract_variable(code, start, end, 'new_var') - expected = 'new_var = 10 + 20\na_var = new_var\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_multiple_lines(self): - code = 'a = 1\nb = 2\n' - start = code.index('1') - end = code.index('1') + 1 - refactored = self.do_extract_variable(code, start, end, 'c') - expected = 'c = 1\na = c\nb = 2\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_in_the_middle_of_statements(self): - code = 'a = 1 + 2\n' - start = code.index('1') - end = code.index('1') + 1 - refactored = self.do_extract_variable(code, start, end, 'c') - expected = 'c = 1\na = c + 2\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_for_a_tuple(self): - code = 'a = 1, 2\n' - start = code.index('1') - end = code.index('2') + 1 - refactored = self.do_extract_variable(code, start, end, 'c') - expected = 'c = 1, 2\na = c\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_for_a_string(self): - code = 'def a_func():\n a = "hey!"\n' - start = code.index('"') - end = code.rindex('"') + 1 - refactored = self.do_extract_variable(code, start, end, 'c') - expected = 'def a_func():\n c = "hey!"\n a = c\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_inside_ifs(self): - code = 'if True:\n a = 1 + 2\n' - start = code.index('1') - end = code.rindex('2') + 1 - refactored = self.do_extract_variable(code, start, end, 'b') - expected = 'if True:\n b = 1 + 2\n a = b\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_inside_ifs_and_logical_lines(self): - code = 'if True:\n a = (3 + \n(1 + 2))\n' - start = code.index('1') - end = code.index('2') + 1 - refactored = self.do_extract_variable(code, start, end, 'b') - expected = 'if True:\n b = 1 + 2\n a = (3 + \n(b))\n' - self.assertEquals(expected, refactored) - - # TODO: Handle when extracting a subexpression - def xxx_test_extract_variable_for_a_subexpression(self): - code = 'a = 3 + 1 + 2\n' - start = code.index('1') - end = code.index('2') + 1 - refactored = self.do_extract_variable(code, start, end, 'b') - expected = 'b = 1 + 2\na = 3 + b\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_starting_from_the_start_of_the_line(self): - code = 'a_dict = {1: 1}\na_dict.values().count(1)\n' - start = code.rindex('a_dict') - end = code.index('count') - 1 - refactored = self.do_extract_variable(code, start, end, 'values') - expected = 'a_dict = {1: 1}\nvalues = a_dict.values()\nvalues.count(1)\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_on_the_last_line_of_a_function(self): - code = 'def f():\n a_var = {}\n a_var.keys()\n' - start = code.rindex('a_var') - end = code.index('.keys') - refactored = self.do_extract_variable(code, start, end, 'new_var') - expected = 'def f():\n a_var = {}\n new_var = a_var\n new_var.keys()\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_on_the_indented_function_statement(self): - code = 'def f():\n if True:\n a_var = 1 + 2\n' - start = code.index('1') - end = code.index('2') + 1 - refactored = self.do_extract_variable(code, start, end, 'new_var') - expected = 'def f():\n if True:\n' \ - ' new_var = 1 + 2\n a_var = new_var\n' - self.assertEquals(expected, refactored) - - def test_extract_method_on_the_last_line_of_a_function(self): - code = 'def f():\n a_var = {}\n a_var.keys()\n' - start = code.rindex('a_var') - end = code.index('.keys') - refactored = self.do_extract_method(code, start, end, 'new_f') - expected = 'def f():\n a_var = {}\n new_f(a_var).keys()\n\n' \ - 'def new_f(a_var):\n return a_var\n' - self.assertEquals(expected, refactored) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_raising_exception_when_on_incomplete_variables(self): - code = 'a_var = 10 + 20\n' - start = code.index('10') + 1 - end = code.index('20') + 2 - refactored = self.do_extract_method(code, start, end, 'new_func') - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_raising_exception_when_on_incomplete_variables_on_end(self): - code = 'a_var = 10 + 20\n' - start = code.index('10') - end = code.index('20') + 1 - refactored = self.do_extract_method(code, start, end, 'new_func') - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_raising_exception_on_bad_parens(self): - code = 'a_var = (10 + 20) + 30\n' - start = code.index('20') - end = code.index('30') + 2 - refactored = self.do_extract_method(code, start, end, 'new_func') - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_raising_exception_on_bad_operators(self): - code = 'a_var = 10 + 20 + 30\n' - start = code.index('10') - end = code.rindex('+') + 1 - refactored = self.do_extract_method(code, start, end, 'new_func') - - # FIXME: Extract method should be more intelligent about bad ranges - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def xxx_test_raising_exception_on_function_parens(self): - code = 'a = range(10)' - start = code.index('(') - end = code.rindex(')') + 1 - refactored = self.do_extract_method(code, start, end, 'new_func') - - def test_extract_method_and_extra_blank_lines(self): - code = '\nprint(1)\n' - refactored = self.do_extract_method(code, 0, len(code), 'new_f') - expected = '\n\ndef new_f():\n print(1)\n\nnew_f()\n' - self.assertEquals(expected, refactored) - - def test_variable_writes_in_the_same_line_as_variable_read(self): - code = 'a = 1\na = 1 + a\n' - start = code.index('\n') + 1 - end = len(code) - refactored = self.do_extract_method(code, start, end, 'new_f', - global_=True) - expected = 'a = 1\n\ndef new_f(a):\n a = 1 + a\n\nnew_f(a)\n' - self.assertEquals(expected, refactored) - - def test_variable_writes_in_the_same_line_as_variable_read2(self): - code = 'a = 1\na += 1\n' - start = code.index('\n') + 1 - end = len(code) - refactored = self.do_extract_method(code, start, end, 'new_f', - global_=True) - expected = 'a = 1\n\ndef new_f():\n a += 1\n\nnew_f()\n' - self.assertEquals(expected, refactored) - - def test_variable_and_similar_expressions(self): - code = 'a = 1\nb = 1\n' - start = code.index('1') - end = start + 1 - refactored = self.do_extract_variable(code, start, end, - 'one', similar=True) - expected = 'one = 1\na = one\nb = one\n' - self.assertEquals(expected, refactored) - - def test_definition_should_appear_before_the_first_use(self): - code = 'a = 1\nb = 1\n' - start = code.rindex('1') - end = start + 1 - refactored = self.do_extract_variable(code, start, end, - 'one', similar=True) - expected = 'one = 1\na = one\nb = one\n' - self.assertEquals(expected, refactored) - - def test_extract_method_and_similar_expressions(self): - code = 'a = 1\nb = 1\n' - start = code.index('1') - end = start + 1 - refactored = self.do_extract_method(code, start, end, - 'one', similar=True) - expected = '\ndef one():\n return 1\n\na = one()\nb = one()\n' - self.assertEquals(expected, refactored) - - def test_simple_extract_method_and_similar_statements(self): - code = 'class AClass(object):\n\n' \ - ' def func1(self):\n a = 1 + 2\n b = a\n' \ - ' def func2(self):\n a = 1 + 2\n b = a\n' - start, end = self._convert_line_range_to_offset(code, 4, 4) - refactored = self.do_extract_method(code, start, end, - 'new_func', similar=True) - expected = 'class AClass(object):\n\n' \ - ' def func1(self):\n' \ - ' a = self.new_func()\n b = a\n\n' \ - ' def new_func(self):\n' \ - ' a = 1 + 2\n return a\n' \ - ' def func2(self):\n' \ - ' a = self.new_func()\n b = a\n' - self.assertEquals(expected, refactored) - - def test_extract_method_and_similar_statements2(self): - code = 'class AClass(object):\n\n' \ - ' def func1(self, p1):\n a = p1 + 2\n' \ - ' def func2(self, p2):\n a = p2 + 2\n' - start = code.rindex('p1') - end = code.index('2\n') + 1 - refactored = self.do_extract_method(code, start, end, - 'new_func', similar=True) - expected = 'class AClass(object):\n\n' \ - ' def func1(self, p1):\n a = self.new_func(p1)\n\n' \ - ' def new_func(self, p1):\n return p1 + 2\n' \ - ' def func2(self, p2):\n a = self.new_func(p2)\n' - self.assertEquals(expected, refactored) - - def test_extract_method_and_similar_statements_where_return_is_different(self): - code = 'class AClass(object):\n\n' \ - ' def func1(self, p1):\n a = p1 + 2\n' \ - ' def func2(self, p2):\n self.attr = p2 + 2\n' - start = code.rindex('p1') - end = code.index('2\n') + 1 - refactored = self.do_extract_method(code, start, end, - 'new_func', similar=True) - expected = 'class AClass(object):\n\n' \ - ' def func1(self, p1):\n a = self.new_func(p1)\n\n' \ - ' def new_func(self, p1):\n return p1 + 2\n' \ - ' def func2(self, p2):\n self.attr = self.new_func(p2)\n' - self.assertEquals(expected, refactored) - - def test_definition_should_appear_where_it_is_visible(self): - code = 'if True:\n a = 1\nelse:\n b = 1\n' - start = code.rindex('1') - end = start + 1 - refactored = self.do_extract_variable(code, start, end, - 'one', similar=True) - expected = 'one = 1\nif True:\n a = one\nelse:\n b = one\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_and_similar_statements_in_classes(self): - code = 'class AClass(object):\n\n' \ - ' def func1(self):\n a = 1\n' \ - ' def func2(self):\n b = 1\n' - start = code.index(' 1') + 1 - refactored = self.do_extract_variable(code, start, start + 1, - 'one', similar=True) - expected = 'class AClass(object):\n\n' \ - ' def func1(self):\n one = 1\n a = one\n' \ - ' def func2(self):\n b = 1\n' - self.assertEquals(expected, refactored) - - def test_extract_method_in_staticmethods(self): - code = 'class AClass(object):\n\n' \ - ' @staticmethod\n def func2():\n b = 1\n' - start = code.index(' 1') + 1 - refactored = self.do_extract_method(code, start, start + 1, - 'one', similar=True) - expected = 'class AClass(object):\n\n' \ - ' @staticmethod\n def func2():\n' \ - ' b = AClass.one()\n\n' \ - ' @staticmethod\n def one():\n' \ - ' return 1\n' - self.assertEquals(expected, refactored) - - def test_extract_normal_method_with_staticmethods(self): - code = 'class AClass(object):\n\n' \ - ' @staticmethod\n def func1():\n b = 1\n' \ - ' def func2(self):\n b = 1\n' - start = code.rindex(' 1') + 1 - refactored = self.do_extract_method(code, start, start + 1, - 'one', similar=True) - expected = 'class AClass(object):\n\n' \ - ' @staticmethod\n def func1():\n b = 1\n' \ - ' def func2(self):\n b = self.one()\n\n' \ - ' def one(self):\n return 1\n' - self.assertEquals(expected, refactored) - - def test_extract_variable_with_no_new_lines_at_the_end(self): - code = 'a_var = 10' - start = code.index('10') - end = start + 2 - refactored = self.do_extract_variable(code, start, end, 'new_var') - expected = 'new_var = 10\na_var = new_var' - self.assertEquals(expected, refactored) - - def test_extract_method_containing_return_in_functions(self): - code = 'def f(arg):\n return arg\nprint(f(1))\n' - start, end = self._convert_line_range_to_offset(code, 1, 3) - refactored = self.do_extract_method(code, start, end, 'a_func') - expected = '\ndef a_func():\n def f(arg):\n return arg\n' \ - ' print(f(1))\n\na_func()\n' - self.assertEquals(expected, refactored) - - def test_extract_method_and_varying_first_parameter(self): - code = 'class C(object):\n' \ - ' def f1(self):\n print(str(self))\n' \ - ' def f2(self):\n print(str(1))\n' - start = code.index('print(') + 6 - end = code.index('))\n') + 1 - refactored = self.do_extract_method(code, start, end, - 'to_str', similar=True) - expected = 'class C(object):\n' \ - ' def f1(self):\n print(self.to_str())\n\n' \ - ' def to_str(self):\n return str(self)\n' \ - ' def f2(self):\n print(str(1))\n' - self.assertEquals(expected, refactored) - - def test_extract_method_when_an_attribute_exists_in_function_scope(self): - code = 'class A(object):\n def func(self):\n pass\n' \ - 'a = A()\n' \ - 'def f():\n' \ - ' func = a.func()\n' \ - ' print func\n' - - start, end = self._convert_line_range_to_offset(code, 6, 6) - refactored = self.do_extract_method(code, start, end, 'g') - refactored = refactored[refactored.index('A()') + 4:] - expected = 'def f():\n func = g()\n print func\n\n' \ - 'def g():\n func = a.func()\n return func\n' - self.assertEquals(expected, refactored) - - def test_global_option_for_extract_method(self): - code = 'def a_func():\n print(1)\n' - start, end = self._convert_line_range_to_offset(code, 2, 2) - refactored = self.do_extract_method(code, start, end, - 'extracted', global_=True) - expected = 'def a_func():\n extracted()\n\n' \ - 'def extracted():\n print(1)\n' - self.assertEquals(expected, refactored) - - def test_global_extract_method(self): - code = 'class AClass(object):\n\n' \ - ' def a_func(self):\n print(1)\n' - start, end = self._convert_line_range_to_offset(code, 4, 4) - refactored = self.do_extract_method(code, start, end, - 'new_func', global_=True) - expected = 'class AClass(object):\n\n' \ - ' def a_func(self):\n new_func()\n\n' \ - 'def new_func():\n print(1)\n' - self.assertEquals(expected, refactored) - - def test_extract_method_with_multiple_methods(self): - code = 'class AClass(object):\n' \ - ' def a_func(self):\n' \ - ' print(1)\n\n' \ - ' def another_func(self):\n' \ - ' pass\n' - start, end = self._convert_line_range_to_offset(code, 3, 3) - refactored = self.do_extract_method(code, start, end, - 'new_func', global_=True) - expected = 'class AClass(object):\n' \ - ' def a_func(self):\n' \ - ' new_func()\n\n' \ - ' def another_func(self):\n' \ - ' pass\n\n' \ - 'def new_func():\n' \ - ' print(1)\n' - self.assertEquals(expected, refactored) - - def test_where_to_seach_when_extracting_global_names(self): - code = 'def a():\n return 1\ndef b():\n return 1\nb = 1\n' - start = code.index('1') - end = start + 1 - refactored = self.do_extract_variable(code, start, end, 'one', - similar=True, global_=True) - expected = 'def a():\n return one\none = 1\n' \ - 'def b():\n return one\nb = one\n' - self.assertEquals(expected, refactored) - - def test_extracting_pieces_with_distinct_temp_names(self): - code = 'a = 1\nprint a\nb = 1\nprint b\n' - start = code.index('a') - end = code.index('\nb') - refactored = self.do_extract_method(code, start, end, 'f', - similar=True, global_=True) - expected = '\ndef f():\n a = 1\n print a\n\nf()\nf()\n' - self.assertEquals(expected, refactored) - - def test_extracting_methods_in_global_functions_should_be_global(self): - code = 'def f():\n a = 1\ndef g():\n b = 1\n' - start = code.rindex('1') - refactored = self.do_extract_method(code, start, start + 1, 'one', - similar=True, global_=False) - expected = 'def f():\n a = one()\ndef g():\n b = one()\n\n' \ - 'def one():\n return 1\n' - self.assertEquals(expected, refactored) - - def test_extracting_methods_in_global_functions_should_be_global(self): - code = 'if 1:\n var = 2\n' - start = code.rindex('2') - refactored = self.do_extract_method(code, start, start + 1, 'two', - similar=True, global_=False) - expected = '\ndef two():\n return 2\n\nif 1:\n var = two()\n' - self.assertEquals(expected, refactored) - - def test_extract_method_and_try_blocks(self): - code = 'def f():\n try:\n pass\n' \ - ' except Exception:\n pass\n' - start, end = self._convert_line_range_to_offset(code, 2, 5) - refactored = self.do_extract_method(code, start, end, 'g') - expected = 'def f():\n g()\n\ndef g():\n try:\n pass\n' \ - ' except Exception:\n pass\n' - self.assertEquals(expected, refactored) - - def test_extract_and_not_passing_global_functions(self): - code = 'def next(p):\n return p + 1\nvar = next(1)\n' - start = code.rindex('next') - refactored = self.do_extract_method(code, start, len(code) - 1, 'two') - expected = 'def next(p):\n return p + 1\n' \ - '\ndef two():\n return next(1)\n\nvar = two()\n' - self.assertEquals(expected, refactored) - - def test_extracting_with_only_one_return(self): - code = 'def f():\n var = 1\n return var\n' - start, end = self._convert_line_range_to_offset(code, 2, 3) - refactored = self.do_extract_method(code, start, end, 'g') - expected = 'def f():\n return g()\n\n' \ - 'def g():\n var = 1\n return var\n' - self.assertEquals(expected, refactored) - - def test_extracting_variable_and_implicit_continuations(self): - code = 's = ("1"\n "2")\n' - start = code.index('"') - end = code.rindex('"') + 1 - refactored = self.do_extract_variable(code, start, end, 's2') - expected = 's2 = "1" "2"\ns = (s2)\n' - self.assertEquals(expected, refactored) - - def test_extracting_method_and_implicit_continuations(self): - code = 's = ("1"\n "2")\n' - start = code.index('"') - end = code.rindex('"') + 1 - refactored = self.do_extract_method(code, start, end, 'f') - expected = '\ndef f():\n return "1" "2"\n\ns = (f())\n' - self.assertEquals(expected, refactored) - - def test_passing_conditional_updated_vars_in_extracted(self): - code = 'def f(a):\n' \ - ' if 0:\n' \ - ' a = 1\n' \ - ' print(a)\n' - start, end = self._convert_line_range_to_offset(code, 2, 4) - refactored = self.do_extract_method(code, start, end, 'g') - expected = 'def f(a):\n' \ - ' g(a)\n\n' \ - 'def g(a):\n' \ - ' if 0:\n' \ - ' a = 1\n' \ - ' print(a)\n' - self.assertEquals(expected, refactored) - - def test_returning_conditional_updated_vars_in_extracted(self): - code = 'def f(a):\n' \ - ' if 0:\n' \ - ' a = 1\n' \ - ' print(a)\n' - start, end = self._convert_line_range_to_offset(code, 2, 3) - refactored = self.do_extract_method(code, start, end, 'g') - expected = 'def f(a):\n' \ - ' a = g(a)\n' \ - ' print(a)\n\n' \ - 'def g(a):\n' \ - ' if 0:\n' \ - ' a = 1\n' \ - ' return a\n' - self.assertEquals(expected, refactored) - - def test_extract_method_with_variables_possibly_written_to(self): - code = "def a_func(b):\n" \ - " if b > 0:\n" \ - " a = 2\n" \ - " print a\n" - start, end = self._convert_line_range_to_offset(code, 2, 3) - refactored = self.do_extract_method(code, start, end, 'extracted') - expected = "def a_func(b):\n" \ - " a = extracted(b)\n" \ - " print a\n\n" \ - "def extracted(b):\n" \ - " if b > 0:\n" \ - " a = 2\n" \ - " return a\n" - self.assertEquals(expected, refactored) - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/importutilstest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/importutilstest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,990 +0,0 @@ -import unittest - -from rope.refactor.importutils import ImportTools, importinfo, add_import -from ropetest import testutils - - -class ImportUtilsTest(unittest.TestCase): - - def setUp(self): - super(ImportUtilsTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.import_tools = ImportTools(self.pycore) - - self.mod = testutils.create_module(self.project, 'mod') - self.pkg1 = testutils.create_package(self.project, 'pkg1') - self.mod1 = testutils.create_module(self.project, 'mod1', self.pkg1) - self.pkg2 = testutils.create_package(self.project, 'pkg2') - self.mod2 = testutils.create_module(self.project, 'mod2', self.pkg2) - self.mod3 = testutils.create_module(self.project, 'mod3', self.pkg2) - p1 = testutils.create_package(self.project, 'p1') - p2 = testutils.create_package(self.project, 'p2', p1) - p3 = testutils.create_package(self.project, 'p3', p2) - m1 = testutils.create_module(self.project, 'm1', p3) - l = testutils.create_module(self.project, 'l', p3) - - def tearDown(self): - testutils.remove_project(self.project) - super(ImportUtilsTest, self).tearDown() - - def test_get_import_for_module(self): - mod = self.pycore.find_module('mod') - import_statement = self.import_tools.get_import(mod) - self.assertEquals('import mod', import_statement.get_import_statement()) - - def test_get_import_for_module_in_nested_modules(self): - mod = self.pycore.find_module('pkg1.mod1') - import_statement = self.import_tools.get_import(mod) - self.assertEquals('import pkg1.mod1', import_statement.get_import_statement()) - - def test_get_import_for_module_in_init_dot_py(self): - init_dot_py = self.pkg1.get_child('__init__.py') - import_statement = self.import_tools.get_import(init_dot_py) - self.assertEquals('import pkg1', import_statement.get_import_statement()) - - - def test_get_from_import_for_module(self): - mod = self.pycore.find_module('mod') - import_statement = self.import_tools.get_from_import(mod, 'a_func') - self.assertEquals('from mod import a_func', - import_statement.get_import_statement()) - - def test_get_from_import_for_module_in_nested_modules(self): - mod = self.pycore.find_module('pkg1.mod1') - import_statement = self.import_tools.get_from_import(mod, 'a_func') - self.assertEquals('from pkg1.mod1 import a_func', - import_statement.get_import_statement()) - - def test_get_from_import_for_module_in_init_dot_py(self): - init_dot_py = self.pkg1.get_child('__init__.py') - import_statement = self.import_tools.\ - get_from_import(init_dot_py, 'a_func') - self.assertEquals('from pkg1 import a_func', - import_statement.get_import_statement()) - - - def test_get_import_statements(self): - self.mod.write('import pkg1\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.imports - self.assertEquals('import pkg1', - imports[0].import_info.get_import_statement()) - - def test_get_import_statements_with_alias(self): - self.mod.write('import pkg1.mod1 as mod1\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.imports - self.assertEquals('import pkg1.mod1 as mod1', - imports[0].import_info.get_import_statement()) - - def test_get_import_statements_for_froms(self): - self.mod.write('from pkg1 import mod1\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.imports - self.assertEquals('from pkg1 import mod1', - imports[0].import_info.get_import_statement()) - - def test_get_multi_line_import_statements_for_froms(self): - self.mod.write('from pkg1 \\\n import mod1\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.imports - self.assertEquals('from pkg1 import mod1', - imports[0].import_info.get_import_statement()) - - def test_get_import_statements_for_from_star(self): - self.mod.write('from pkg1 import *\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.imports - self.assertEquals('from pkg1 import *', - imports[0].import_info.get_import_statement()) - - @testutils.run_only_for_25 - def test_get_import_statements_for_new_relatives(self): - self.mod2.write('from .mod3 import x\n') - pymod = self.pycore.get_module('pkg2.mod2') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.imports - self.assertEquals('from .mod3 import x', - imports[0].import_info.get_import_statement()) - - def test_ignoring_indented_imports(self): - self.mod.write('if True:\n import pkg1\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.imports - self.assertEquals(0, len(imports)) - - def test_import_get_names(self): - self.mod.write('import pkg1 as pkg\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.imports - context = importinfo.ImportContext(self.pycore, self.project.root) - self.assertEquals(['pkg'], - imports[0].import_info.get_imported_names(context)) - - def test_import_get_names_with_alias(self): - self.mod.write('import pkg1.mod1\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.imports - context = importinfo.ImportContext(self.pycore, self.project.root) - self.assertEquals(['pkg1'], - imports[0].import_info.get_imported_names(context)) - - def test_import_get_names_with_alias2(self): - self.mod1.write('def a_func():\n pass\n') - self.mod.write('from pkg1.mod1 import *\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.imports - context = importinfo.ImportContext(self.pycore, self.project.root) - self.assertEquals(['a_func'], - imports[0].import_info.get_imported_names(context)) - - def test_empty_getting_used_imports(self): - self.mod.write('') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.get_used_imports(pymod) - self.assertEquals(0, len(imports)) - - def test_empty_getting_used_imports2(self): - self.mod.write('import pkg\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.get_used_imports(pymod) - self.assertEquals(0, len(imports)) - - def test_simple_getting_used_imports(self): - self.mod.write('import pkg\nprint(pkg)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.get_used_imports(pymod) - self.assertEquals(1, len(imports)) - self.assertEquals('import pkg', imports[0].get_import_statement()) - - def test_simple_getting_used_imports2(self): - self.mod.write('import pkg\ndef a_func():\n print(pkg)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.get_used_imports(pymod) - self.assertEquals(1, len(imports)) - self.assertEquals('import pkg', imports[0].get_import_statement()) - - def test_getting_used_imports_for_nested_scopes(self): - self.mod.write('import pkg1\nprint(pkg1)\ndef a_func():\n pass\nprint(pkg1)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.get_used_imports( - pymod['a_func'].get_object()) - self.assertEquals(0, len(imports)) - - def test_getting_used_imports_for_nested_scopes2(self): - self.mod.write('from pkg1 import mod1\ndef a_func():\n print(mod1)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.get_used_imports( - pymod['a_func'].get_object()) - self.assertEquals(1, len(imports)) - self.assertEquals('from pkg1 import mod1', imports[0].get_import_statement()) - - def test_empty_removing_unused_imports(self): - self.mod.write('import pkg1\nprint(pkg1)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('import pkg1\nprint(pkg1)\n', - module_with_imports.get_changed_source()) - - def test_simple_removing_unused_imports(self): - self.mod.write('import pkg1\n\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('', module_with_imports.get_changed_source()) - - def test_simple_removing_unused_imports_for_froms(self): - self.mod1.write('def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import a_func, another_func\n\na_func()\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('from pkg1.mod1 import a_func\n\na_func()\n', - module_with_imports.get_changed_source()) - - def test_simple_removing_unused_imports_for_from_stars(self): - self.mod.write('from pkg1.mod1 import *\n\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('', module_with_imports.get_changed_source()) - - def test_simple_removing_unused_imports_for_nested_modules(self): - self.mod1.write('def a_func():\n pass\n') - self.mod.write('import pkg1.mod1\npkg1.mod1.a_func()') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('import pkg1.mod1\npkg1.mod1.a_func()', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_functions_of_the_same_name(self): - self.mod.write('def a_func():\n pass\ndef a_func():\n pass\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('def a_func():\n pass\ndef a_func():\n pass\n', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_for_from_import_with_as(self): - self.mod.write('a_var = 1\n') - self.mod1.write('from mod import a_var as myvar\na_var = myvar\n') - pymod = self.pycore.resource_to_pyobject(self.mod1) - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('from mod import a_var as myvar\na_var = myvar\n', - module_with_imports.get_changed_source()) - - def test_not_removing_imports_that_conflict_with_class_names(self): - code = 'import pkg1\nclass A(object):\n pkg1 = 0\n' \ - ' def f(self):\n a_var = pkg1\n' - self.mod.write(code) - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals(code, module_with_imports.get_changed_source()) - - def test_adding_imports(self): - self.mod.write('\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - new_import = self.import_tools.get_import(self.mod1) - module_with_imports.add_import(new_import) - self.assertEquals('import pkg1.mod1\n', - module_with_imports.get_changed_source()) - - def test_adding_from_imports(self): - self.mod1.write('def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import a_func\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - new_import = self.import_tools.get_from_import( - self.mod1, 'another_func') - module_with_imports.add_import(new_import) - self.assertEquals('from pkg1.mod1 import a_func, another_func\n', - module_with_imports.get_changed_source()) - - def test_adding_to_star_imports(self): - self.mod1.write('def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import *\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - new_import = self.import_tools.get_from_import( - self.mod1, 'another_func') - module_with_imports.add_import(new_import) - self.assertEquals('from pkg1.mod1 import *\n', - module_with_imports.get_changed_source()) - - def test_adding_star_imports(self): - self.mod1.write('def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import a_func\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - new_import = self.import_tools.get_from_import(self.mod1, - '*') - module_with_imports.add_import(new_import) - self.assertEquals('from pkg1.mod1 import *\n', - module_with_imports.get_changed_source()) - - def test_adding_imports_and_preserving_spaces_after_imports(self): - self.mod.write('import pkg1\n\n\nprint(pkg1)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - new_import = self.import_tools.get_import(self.pkg2) - module_with_imports.add_import(new_import) - self.assertEquals('import pkg1\nimport pkg2\n\n\nprint(pkg1)\n', - module_with_imports.get_changed_source()) - - def test_not_changing_the_format_of_unchanged_imports(self): - self.mod1.write('def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import (a_func,\n another_func)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - self.assertEquals( - 'from pkg1.mod1 import (a_func,\n another_func)\n', - module_with_imports.get_changed_source()) - - def test_not_changing_the_format_of_unchanged_imports2(self): - self.mod1.write('def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import (a_func)\na_func()\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('from pkg1.mod1 import (a_func)\na_func()\n', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_reoccuring_names(self): - self.mod1.write('def a_func():\n pass\n' - 'def another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import *\n' - 'from pkg1.mod1 import a_func\na_func()\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('from pkg1.mod1 import *\na_func()\n', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_reoccuring_names2(self): - self.mod.write('import pkg2.mod2\nimport pkg2.mod3\n' - 'print(pkg2.mod2, pkg2.mod3)') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals( - 'import pkg2.mod2\nimport pkg2.mod3\nprint(pkg2.mod2, pkg2.mod3)', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_common_packages(self): - self.mod.write('import pkg1.mod1\nimport pkg1\nprint(pkg1, pkg1.mod1)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('import pkg1.mod1\nprint(pkg1, pkg1.mod1)\n', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_common_packages_reversed(self): - self.mod.write('import pkg1\nimport pkg1.mod1\nprint(pkg1, pkg1.mod1)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_duplicates() - self.assertEquals('import pkg1.mod1\nprint(pkg1, pkg1.mod1)\n', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_common_packages2(self): - self.mod.write('import pkg1.mod1\nimport pkg1.mod2\nprint(pkg1)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('import pkg1.mod1\nprint(pkg1)\n', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_froms(self): - self.mod1.write('def func1():\n pass\n') - self.mod.write('from pkg1.mod1 import func1\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('', module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_froms2(self): - self.mod1.write('def func1():\n pass\n') - self.mod.write('from pkg1.mod1 import func1\nfunc1()') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('from pkg1.mod1 import func1\nfunc1()', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_froms3(self): - self.mod1.write('def func1():\n pass\n') - self.mod.write('from pkg1.mod1 import func1\n' - 'def a_func():\n func1()\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals( - 'from pkg1.mod1 import func1\ndef a_func():\n func1()\n', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_froms4(self): - self.mod1.write('def func1():\n pass\n') - self.mod.write('from pkg1.mod1 import func1\nclass A(object):\n' - ' def a_func(self):\n func1()\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('from pkg1.mod1 import func1\nclass A(object):\n' - ' def a_func(self):\n func1()\n', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_and_getting_attributes(self): - self.mod1.write('class A(object):\n def f(self):\n pass\n') - self.mod.write('from pkg1.mod1 import A\nvar = A().f()') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('from pkg1.mod1 import A\nvar = A().f()', - module_with_imports.get_changed_source()) - - def test_removing_unused_imports_function_parameters(self): - self.mod1.write('def func1():\n pass\n') - self.mod.write('import pkg1\ndef a_func(pkg1):\n my_var = pkg1\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('def a_func(pkg1):\n my_var = pkg1\n', - module_with_imports.get_changed_source()) - - def test_trivial_expanding_star_imports(self): - self.mod1.write('def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import *\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.expand_stars() - self.assertEquals('', module_with_imports.get_changed_source()) - - def test_expanding_star_imports(self): - self.mod1.write('def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import *\na_func()\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.expand_stars() - self.assertEquals('from pkg1.mod1 import a_func\na_func()\n', - module_with_imports.get_changed_source()) - - def test_removing_duplicate_imports(self): - self.mod.write('import pkg1\nimport pkg1\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_duplicates() - self.assertEquals('import pkg1\n', - module_with_imports.get_changed_source()) - - def test_removing_duplicates_and_reoccuring_names(self): - self.mod.write('import pkg2.mod2\nimport pkg2.mod3\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_duplicates() - self.assertEquals('import pkg2.mod2\nimport pkg2.mod3\n', - module_with_imports.get_changed_source()) - - def test_removing_duplicate_imports_for_froms(self): - self.mod1.write( - 'def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1 import a_func\n' - 'from pkg1 import a_func, another_func\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_duplicates() - self.assertEquals('from pkg1 import a_func, another_func\n', - module_with_imports.get_changed_source()) - - def test_transforming_froms_to_normal_changing_imports(self): - self.mod1.write('def a_func():\n pass\n') - self.mod.write('from pkg1.mod1 import a_func\nprint(a_func)\n') - pymod = self.pycore.get_module('mod') - changed_module = self.import_tools.froms_to_imports(pymod) - self.assertEquals('import pkg1.mod1\nprint(pkg1.mod1.a_func)\n', - changed_module) - - def test_transforming_froms_to_normal_changing_occurances(self): - self.mod1.write('def a_func():\n pass\n') - self.mod.write('from pkg1.mod1 import a_func\na_func()') - pymod = self.pycore.get_module('mod') - changed_module = self.import_tools.froms_to_imports(pymod) - self.assertEquals('import pkg1.mod1\npkg1.mod1.a_func()', - changed_module) - - def test_transforming_froms_to_normal_for_multi_imports(self): - self.mod1.write('def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import *\na_func()\nanother_func()\n') - pymod = self.pycore.get_module('mod') - changed_module = self.import_tools.froms_to_imports(pymod) - self.assertEquals( - 'import pkg1.mod1\npkg1.mod1.a_func()\npkg1.mod1.another_func()\n', - changed_module) - - def test_transforming_froms_to_normal_for_multi_imports_inside_parens(self): - self.mod1.write('def a_func():\n pass\ndef another_func():\n pass\n') - self.mod.write('from pkg1.mod1 import (a_func, \n another_func)' \ - '\na_func()\nanother_func()\n') - pymod = self.pycore.get_module('mod') - changed_module = self.import_tools.froms_to_imports(pymod) - self.assertEquals( - 'import pkg1.mod1\npkg1.mod1.a_func()\npkg1.mod1.another_func()\n', - changed_module) - - def test_transforming_froms_to_normal_from_stars(self): - self.mod1.write('def a_func():\n pass\n') - self.mod.write('from pkg1.mod1 import *\na_func()\n') - pymod = self.pycore.get_module('mod') - changed_module = self.import_tools.froms_to_imports(pymod) - self.assertEquals('import pkg1.mod1\npkg1.mod1.a_func()\n', changed_module) - - def test_transforming_froms_to_normal_from_stars2(self): - self.mod1.write('a_var = 10') - self.mod.write('import pkg1.mod1\nfrom pkg1.mod1 import a_var\n' \ - 'def a_func():\n print(pkg1.mod1, a_var)\n') - pymod = self.pycore.get_module('mod') - changed_module = self.import_tools.froms_to_imports(pymod) - self.assertEquals('import pkg1.mod1\n' \ - 'def a_func():\n print(pkg1.mod1, pkg1.mod1.a_var)\n', - changed_module) - - def test_transforming_froms_to_normal_from_with_alias(self): - self.mod1.write('def a_func():\n pass\n') - self.mod.write( - 'from pkg1.mod1 import a_func as another_func\nanother_func()\n') - pymod = self.pycore.get_module('mod') - changed_module = self.import_tools.froms_to_imports(pymod) - self.assertEquals('import pkg1.mod1\npkg1.mod1.a_func()\n', - changed_module) - - def test_transforming_froms_to_normal_for_relatives(self): - self.mod2.write('def a_func():\n pass\n') - self.mod3.write('from mod2 import *\na_func()\n') - pymod = self.pycore.resource_to_pyobject(self.mod3) - changed_module = self.import_tools.froms_to_imports(pymod) - self.assertEquals('import pkg2.mod2\npkg2.mod2.a_func()\n', - changed_module) - - def test_transforming_froms_to_normal_for_os_path(self): - self.mod.write('from os import path\npath.exists(\'.\')\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - changed_module = self.import_tools.froms_to_imports(pymod) - self.assertEquals('import os\nos.path.exists(\'.\')\n', changed_module) - - def test_transform_relatives_imports_to_absolute_imports_doing_nothing(self): - self.mod2.write('from pkg1 import mod1\nimport mod1\n') - pymod = self.pycore.resource_to_pyobject(self.mod2) - self.assertEquals('from pkg1 import mod1\nimport mod1\n', - self.import_tools.relatives_to_absolutes(pymod)) - - def test_transform_relatives_to_absolute_imports_for_normal_imports(self): - self.mod2.write('import mod3\n') - pymod = self.pycore.resource_to_pyobject(self.mod2) - self.assertEquals('import pkg2.mod3\n', - self.import_tools.relatives_to_absolutes(pymod)) - - def test_transform_relatives_imports_to_absolute_imports_for_froms(self): - self.mod3.write('def a_func():\n pass\n') - self.mod2.write('from mod3 import a_func\n') - pymod = self.pycore.resource_to_pyobject(self.mod2) - self.assertEquals('from pkg2.mod3 import a_func\n', - self.import_tools.relatives_to_absolutes(pymod)) - - @testutils.run_only_for_25 - def test_transform_relatives_imports_to_absolute_imports_for_new_relatives(self): - self.mod3.write('def a_func():\n pass\n') - self.mod2.write('from .mod3 import a_func\n') - pymod = self.pycore.resource_to_pyobject(self.mod2) - self.assertEquals('from pkg2.mod3 import a_func\n', - self.import_tools.relatives_to_absolutes(pymod)) - - def test_transform_relatives_to_absolute_imports_for_normal_imports2(self): - self.mod2.write('import mod3\nprint(mod3)') - pymod = self.pycore.resource_to_pyobject(self.mod2) - self.assertEquals('import pkg2.mod3\nprint(pkg2.mod3)', - self.import_tools.relatives_to_absolutes(pymod)) - - def test_transform_relatives_to_absolute_imports_for_aliases(self): - self.mod2.write('import mod3 as mod3\nprint(mod3)') - pymod = self.pycore.resource_to_pyobject(self.mod2) - self.assertEquals('import pkg2.mod3 as mod3\nprint(mod3)', - self.import_tools.relatives_to_absolutes(pymod)) - - def test_organizing_imports(self): - self.mod1.write('import mod1\n') - pymod = self.pycore.resource_to_pyobject(self.mod1) - self.assertEquals('', self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports(self): - self.mod.write('import mod\nmod.a_var = 1\nprint(mod.a_var)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('a_var = 1\nprint(a_var)\n', - self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports2(self): - self.mod1.write('import pkg1.mod1\npkg1.mod1.a_var = 1\n' - 'print(pkg1.mod1.a_var)\n') - pymod = self.pycore.resource_to_pyobject(self.mod1) - self.assertEquals('a_var = 1\nprint(a_var)\n', - self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports_with_as(self): - self.mod.write('import mod as mymod\n' - 'mymod.a_var = 1\nprint(mymod.a_var)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('a_var = 1\nprint(a_var)\n', - self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports_for_froms(self): - self.mod1.write('from pkg1 import mod1\n' - 'mod1.a_var = 1\nprint(mod1.a_var)\n') - pymod = self.pycore.resource_to_pyobject(self.mod1) - self.assertEquals('a_var = 1\nprint(a_var)\n', - self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports_for_froms_with_as(self): - self.mod1.write('from pkg1 import mod1 as mymod\n' - 'mymod.a_var = 1\nprint(mymod.a_var)\n') - pymod = self.pycore.resource_to_pyobject(self.mod1) - self.assertEquals('a_var = 1\nprint(a_var)\n', - self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports_for_froms2(self): - self.mod.write('from mod import a_var\na_var = 1\nprint(a_var)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('a_var = 1\nprint(a_var)\n', - self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports_for_froms3(self): - self.mod.write('from mod import a_var\na_var = 1\nprint(a_var)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('a_var = 1\nprint(a_var)\n', - self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports_for_froms4(self): - self.mod.write('from mod import a_var as myvar\n' - 'a_var = 1\nprint(myvar)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('a_var = 1\nprint(a_var)\n', - self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports_with_no_dot_after_mod(self): - self.mod.write('import mod\nprint(mod)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('import mod\n\n\nprint(mod)\n', - self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports_with_no_dot_after_mod2(self): - self.mod.write('import mod\na_var = 1\n' - 'print(mod\\\n \\\n .var)\n\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('a_var = 1\nprint(var)\n\n', - self.import_tools.organize_imports(pymod)) - - def test_removing_self_imports_for_from_import_star(self): - self.mod.write('from mod import *\na_var = 1\nprint(myvar)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('a_var = 1\nprint(myvar)\n', - self.import_tools.organize_imports(pymod)) - - def test_not_removing_future_imports(self): - self.mod.write('from __future__ import division\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('from __future__ import division\n', - self.import_tools.organize_imports(pymod)) - - def test_sorting_empty_imports(self): - self.mod.write('') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('', self.import_tools.sort_imports(pymod)) - - def test_sorting_one_import(self): - self.mod.write('import pkg1.mod1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('import pkg1.mod1\n', - self.import_tools.sort_imports(pymod)) - - def test_sorting_imports_alphabetically(self): - self.mod.write('import pkg2.mod2\nimport pkg1.mod1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('import pkg1.mod1\nimport pkg2.mod2\n', - self.import_tools.sort_imports(pymod)) - - def test_sorting_imports_and_froms(self): - self.mod.write('import pkg2.mod2\nfrom pkg1 import mod1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('import pkg2.mod2\nfrom pkg1 import mod1\n', - self.import_tools.sort_imports(pymod)) - - def test_sorting_imports_and_standard_modules(self): - self.mod.write('import pkg1\nimport sys\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('import sys\n\nimport pkg1\n', - self.import_tools.sort_imports(pymod)) - - def test_sorting_imports_and_standard_modules2(self): - self.mod.write('import sys\n\nimport time\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('import sys\nimport time\n', - self.import_tools.sort_imports(pymod)) - - def test_sorting_only_standard_modules(self): - self.mod.write('import sys\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('import sys\n', - self.import_tools.sort_imports(pymod)) - - def test_sorting_third_party(self): - self.mod.write('import pkg1\nimport a_third_party\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('import a_third_party\n\nimport pkg1\n', - self.import_tools.sort_imports(pymod)) - - def test_sorting_only_third_parties(self): - self.mod.write('import a_third_party\na_var = 1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals('import a_third_party\n\n\na_var = 1\n', - self.import_tools.sort_imports(pymod)) - - def test_simple_handling_long_imports(self): - self.mod.write('import pkg1.mod1\n\n\nm = pkg1.mod1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'import pkg1.mod1\n\n\nm = pkg1.mod1\n', - self.import_tools.handle_long_imports(pymod, maxdots=2)) - - def test_handling_long_imports_for_many_dots(self): - self.mod.write('import p1.p2.p3.m1\n\n\nm = p1.p2.p3.m1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'from p1.p2.p3 import m1\n\n\nm = m1\n', - self.import_tools.handle_long_imports(pymod, maxdots=2)) - - def test_handling_long_imports_for_their_length(self): - self.mod.write('import p1.p2.p3.m1\n\n\nm = p1.p2.p3.m1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'import p1.p2.p3.m1\n\n\nm = p1.p2.p3.m1\n', - self.import_tools.handle_long_imports(pymod, maxdots=3, - maxlength=20)) - - def test_handling_long_imports_for_many_dots2(self): - self.mod.write('import p1.p2.p3.m1\n\n\nm = p1.p2.p3.m1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'from p1.p2.p3 import m1\n\n\nm = m1\n', - self.import_tools.handle_long_imports(pymod, maxdots=3, - maxlength=10)) - - def test_handling_long_imports_with_one_letter_last(self): - self.mod.write('import p1.p2.p3.l\n\n\nm = p1.p2.p3.l\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'from p1.p2.p3 import l\n\n\nm = l\n', - self.import_tools.handle_long_imports(pymod, maxdots=2)) - - def test_empty_removing_unused_imports_and_eating_blank_lines(self): - self.mod.write('import pkg1\nimport pkg2\n\n\nprint(pkg1)\n') - pymod = self.pycore.get_module('mod') - module_with_imports = self.import_tools.module_imports(pymod) - module_with_imports.remove_unused_imports() - self.assertEquals('import pkg1\n\n\nprint(pkg1)\n', - module_with_imports.get_changed_source()) - - def test_sorting_imports_moving_to_top(self): - self.mod.write('import mod\ndef f():\n print(mod, pkg1, pkg2)\n' - 'import pkg1\nimport pkg2\n') - pymod = self.pycore.get_module('mod') - self.assertEquals('import mod\nimport pkg1\nimport pkg2\n\n\n' - 'def f():\n print(mod, pkg1, pkg2)\n', - self.import_tools.sort_imports(pymod)) - - def test_sorting_imports_moving_to_top2(self): - self.mod.write('def f():\n print(mod)\nimport mod\n') - pymod = self.pycore.get_module('mod') - self.assertEquals('import mod\n\n\ndef f():\n print(mod)\n', - self.import_tools.sort_imports(pymod)) - - def test_sorting_imports_moving_to_top_and_module_docs(self): - self.mod.write('"""\ndocs\n"""\ndef f():\n print(mod)\nimport mod\n') - pymod = self.pycore.get_module('mod') - self.assertEquals( - '"""\ndocs\n"""\nimport mod\n\n\ndef f():\n print(mod)\n', - self.import_tools.sort_imports(pymod)) - - def test_sorting_future_imports(self): - self.mod.write('import os\nfrom __future__ import devision\n') - pymod = self.pycore.get_module('mod') - self.assertEquals( - 'from __future__ import devision\n\nimport os\n', - self.import_tools.sort_imports(pymod)) - - def test_customized_import_organization(self): - self.mod.write('import sys\nimport sys\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'import sys\n', - self.import_tools.organize_imports(pymod, unused=False)) - - def test_customized_import_organization2(self): - self.mod.write('import sys\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'import sys\n', - self.import_tools.organize_imports(pymod, unused=False)) - - def test_customized_import_organization3(self): - self.mod.write('import sys\nimport mod\n\n\nvar = 1\nprint(mod.var)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'import sys\n\n\nvar = 1\nprint(var)\n', - self.import_tools.organize_imports(pymod, unused=False)) - - def test_trivial_filtered_expand_stars(self): - self.pkg1.get_child('__init__.py').write('var1 = 1\n') - self.pkg2.get_child('__init__.py').write('var2 = 1\n') - self.mod.write('from pkg1 import *\nfrom pkg2 import *\n\n' - 'print(var1, var2)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'from pkg1 import *\nfrom pkg2 import *\n\nprint(var1, var2)\n', - self.import_tools.expand_stars(pymod, lambda stmt: False)) - - def _line_filter(self, lineno): - def import_filter(import_stmt): - return import_stmt.start_line <= lineno < import_stmt.end_line - return import_filter - - def test_filtered_expand_stars(self): - self.pkg1.get_child('__init__.py').write('var1 = 1\n') - self.pkg2.get_child('__init__.py').write('var2 = 1\n') - self.mod.write('from pkg1 import *\nfrom pkg2 import *\n\n' - 'print(var1, var2)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'from pkg1 import *\nfrom pkg2 import var2\n\nprint(var1, var2)\n', - self.import_tools.expand_stars(pymod, self._line_filter(2))) - - def test_filtered_relative_to_absolute(self): - self.mod3.write('var = 1') - self.mod2.write('import mod3\n\nprint(mod3.var)\n') - pymod = self.pycore.resource_to_pyobject(self.mod2) - self.assertEquals( - 'import mod3\n\nprint(mod3.var)\n', - self.import_tools.relatives_to_absolutes( - pymod, lambda stmt: False)) - self.assertEquals( - 'import pkg2.mod3\n\nprint(pkg2.mod3.var)\n', - self.import_tools.relatives_to_absolutes( - pymod, self._line_filter(1))) - - def test_filtered_froms_to_normals(self): - self.pkg1.get_child('__init__.py').write('var1 = 1\n') - self.pkg2.get_child('__init__.py').write('var2 = 1\n') - self.mod.write('from pkg1 import var1\nfrom pkg2 import var2\n\n' - 'print(var1, var2)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'from pkg1 import var1\nfrom pkg2 import var2\n\nprint(var1, var2)\n', - self.import_tools.expand_stars(pymod, lambda stmt: False)) - self.assertEquals( - 'from pkg1 import var1\nimport pkg2\n\nprint(var1, pkg2.var2)\n', - self.import_tools.froms_to_imports(pymod, self._line_filter(2))) - - def test_filtered_froms_to_normals2(self): - self.pkg1.get_child('__init__.py').write('var1 = 1\n') - self.pkg2.get_child('__init__.py').write('var2 = 1\n') - self.mod.write('from pkg1 import *\nfrom pkg2 import *\n\n' - 'print(var1, var2)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'from pkg1 import *\nimport pkg2\n\nprint(var1, pkg2.var2)\n', - self.import_tools.froms_to_imports(pymod, self._line_filter(2))) - - def test_filtered_handle_long_imports(self): - self.mod.write('import p1.p2.p3.m1\nimport pkg1.mod1\n\n\n' - 'm = p1.p2.p3.m1, pkg1.mod1\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'import p1.p2.p3.m1\nfrom pkg1 import mod1\n\n\n' - 'm = p1.p2.p3.m1, mod1\n', - self.import_tools.handle_long_imports( - pymod, maxlength=5, - import_filter=self._line_filter(2))) - - def test_filtering_and_import_actions_with_more_than_one_phase(self): - self.pkg1.get_child('__init__.py').write('var1 = 1\n') - self.pkg2.get_child('__init__.py').write('var2 = 1\n') - self.mod.write('from pkg1 import *\nfrom pkg2 import *\n\n' - 'print(var2)\n') - pymod = self.pycore.resource_to_pyobject(self.mod) - self.assertEquals( - 'from pkg2 import *\n\nprint(var2)\n', - self.import_tools.expand_stars(pymod, self._line_filter(1))) - - def test_non_existent_module_and_used_imports(self): - self.mod.write( - 'from does_not_exist import func\n\nfunc()\n') - pymod = self.pycore.get_module('mod') - - module_with_imports = self.import_tools.module_imports(pymod) - imports = module_with_imports.get_used_imports(pymod) - self.assertEquals(1, len(imports)) - - -class AddImportTest(unittest.TestCase): - - def setUp(self): - super(AddImportTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - - self.mod1 = testutils.create_module(self.project, 'mod1') - self.mod2 = testutils.create_module(self.project, 'mod2') - self.pkg = testutils.create_package(self.project, 'pkg') - self.mod3 = testutils.create_module(self.project, 'mod3', self.pkg) - - def tearDown(self): - testutils.remove_project(self.project) - super(AddImportTest, self).tearDown() - - def test_normal_imports(self): - self.mod2.write('myvar = None\n') - self.mod1.write('\n') - pymod = self.pycore.get_module('mod1') - result, name = add_import(self.pycore, pymod, 'mod2', 'myvar') - self.assertEquals('import mod2\n', result) - self.assertEquals('mod2.myvar', name) - - def test_not_reimporting_a_name(self): - self.mod2.write('myvar = None\n') - self.mod1.write('from mod2 import myvar\n') - pymod = self.pycore.get_module('mod1') - result, name = add_import(self.pycore, pymod, 'mod2', 'myvar') - self.assertEquals('from mod2 import myvar\n', result) - self.assertEquals('myvar', name) - - def test_adding_import_when_siblings_are_imported(self): - self.mod2.write('var1 = None\nvar2 = None\n') - self.mod1.write('from mod2 import var1\n') - pymod = self.pycore.get_module('mod1') - result, name = add_import(self.pycore, pymod, 'mod2', 'var2') - self.assertEquals('from mod2 import var1, var2\n', result) - self.assertEquals('var2', name) - - def test_adding_import_when_the_package_is_imported(self): - self.pkg.get_child('__init__.py').write('var1 = None\n') - self.mod3.write('var2 = None\n') - self.mod1.write('from pkg import var1\n') - pymod = self.pycore.get_module('mod1') - result, name = add_import(self.pycore, pymod, 'pkg.mod3', 'var2') - self.assertEquals('from pkg import var1, mod3\n', result) - self.assertEquals('mod3.var2', name) - - def test_adding_import_for_modules_instead_of_names(self): - self.pkg.get_child('__init__.py').write('var1 = None\n') - self.mod3.write('\n') - self.mod1.write('from pkg import var1\n') - pymod = self.pycore.get_module('mod1') - result, name = add_import(self.pycore, pymod, 'pkg.mod3', None) - self.assertEquals('from pkg import var1, mod3\n', result) - self.assertEquals('mod3', name) - - def test_adding_import_for_modules_with_normal_duplicate_imports(self): - self.pkg.get_child('__init__.py').write('var1 = None\n') - self.mod3.write('\n') - self.mod1.write('import pkg.mod3\n') - pymod = self.pycore.get_module('mod1') - result, name = add_import(self.pycore, pymod, 'pkg.mod3', None) - self.assertEquals('import pkg.mod3\n', result) - self.assertEquals('pkg.mod3', name) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(ImportUtilsTest)) - result.addTests(unittest.makeSuite(AddImportTest)) - return result - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/inlinetest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/inlinetest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,616 +0,0 @@ -from ropetest.testutils import only_for -import unittest - -import rope.base.exceptions -from rope.refactor import inline -from ropetest import testutils - - -class InlineTest(unittest.TestCase): - - def setUp(self): - super(InlineTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod') - self.mod2 = testutils.create_module(self.project, 'mod2') - - def tearDown(self): - testutils.remove_project(self.project) - super(InlineTest, self).tearDown() - - def _inline(self, code, offset, **kwds): - self.mod.write(code) - self._inline2(self.mod, offset, **kwds) - return self.mod.read() - - def _inline2(self, resource, offset, **kwds): - inliner = inline.create_inline(self.project, resource, offset) - changes = inliner.get_changes(**kwds) - self.project.do(changes) - return self.mod.read() - - def test_simple_case(self): - code = 'a_var = 10\nanother_var = a_var\n' - refactored = self._inline(code, code.index('a_var') + 1) - self.assertEquals('another_var = 10\n', refactored) - - def test_empty_case(self): - code = 'a_var = 10\n' - refactored = self._inline(code, code.index('a_var') + 1) - self.assertEquals('', refactored) - - def test_long_definition(self): - code = 'a_var = 10 + (10 + 10)\nanother_var = a_var\n' - refactored = self._inline(code, code.index('a_var') + 1) - self.assertEquals('another_var = 10 + (10 + 10)\n', refactored) - - def test_explicit_continuation(self): - code = 'a_var = (10 +\n 10)\nanother_var = a_var\n' - refactored = self._inline(code, code.index('a_var') + 1) - self.assertEquals('another_var = (10 + 10)\n', refactored) - - def test_implicit_continuation(self): - code = 'a_var = 10 +\\\n 10\nanother_var = a_var\n' - refactored = self._inline(code, code.index('a_var') + 1) - self.assertEquals('another_var = 10 + 10\n', refactored) - - def test_inlining_at_the_end_of_input(self): - code = 'a = 1\nb = a' - refactored = self._inline(code, code.index('a') + 1) - self.assertEquals('b = 1', refactored) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_on_classes(self): - code = 'class AClass(object):\n pass\n' - refactored = self._inline(code, code.index('AClass') + 1) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_multiple_assignments(self): - code = 'a_var = 10\na_var = 20\n' - refactored = self._inline(code, code.index('a_var') + 1) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_tuple_assignments(self): - code = 'a_var, another_var = (20, 30)\n' - refactored = self._inline(code, code.index('a_var') + 1) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_on_unknown_vars(self): - code = 'a_var = another_var\n' - refactored = self._inline(code, code.index('another_var') + 1) - - def test_attribute_inlining(self): - code = 'class A(object):\n def __init__(self):\n' \ - ' self.an_attr = 3\n range(self.an_attr)\n' - refactored = self._inline(code, code.index('an_attr') + 1) - expected = 'class A(object):\n def __init__(self):\n' \ - ' range(3)\n' - self.assertEquals(expected, refactored) - - def test_attribute_inlining2(self): - code = 'class A(object):\n def __init__(self):\n' \ - ' self.an_attr = 3\n range(self.an_attr)\n' \ - 'a = A()\nrange(a.an_attr)' - refactored = self._inline(code, code.index('an_attr') + 1) - expected = 'class A(object):\n def __init__(self):\n' \ - ' range(3)\n' \ - 'a = A()\nrange(3)' - self.assertEquals(expected, refactored) - - - def test_a_function_with_no_occurance(self): - self.mod.write('def a_func():\n pass\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('', self.mod.read()) - - def test_a_function_with_no_occurance2(self): - self.mod.write('a_var = 10\ndef a_func():\n pass\nprint(a_var)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('a_var = 10\nprint(a_var)\n', self.mod.read()) - - def test_replacing_calls_with_function_definition_in_other_modules(self): - self.mod.write('def a_func():\n print(1)\n') - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('import mod\nmod.a_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('import mod\nprint(1)\n', mod1.read()) - - def test_replacing_calls_with_function_definition_in_other_modules2(self): - self.mod.write('def a_func():\n print(1)\n') - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('import mod\nif True:\n mod.a_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('import mod\nif True:\n print(1)\n', mod1.read()) - - def test_replacing_calls_with_method_definition_in_other_modules(self): - self.mod.write('class A(object):\n var = 10\n' - ' def a_func(self):\n print(1)\n') - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('import mod\nmod.A().a_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('import mod\nprint(1)\n', mod1.read()) - self.assertEquals('class A(object):\n var = 10\n', self.mod.read()) - - def test_replacing_calls_with_function_definition_in_defining_module(self): - self.mod.write('def a_func():\n print(1)\na_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('print(1)\n', self.mod.read()) - - def test_replacing_calls_with_function_definition_in_defining_module2(self): - self.mod.write('def a_func():\n for i in range(10):\n print(1)\na_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('for i in range(10):\n print(1)\n', self.mod.read()) - - def test_replacing_calls_with_method_definition_in_defining_modules(self): - self.mod.write('class A(object):\n var = 10\n' - ' def a_func(self):\n print(1)\nA().a_func()') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('class A(object):\n var = 10\nprint(1)\n', self.mod.read()) - - def test_parameters_with_the_same_name_as_passed(self): - self.mod.write('def a_func(var):\n print(var)\nvar = 1\na_func(var)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('var = 1\nprint(var)\n', self.mod.read()) - - def test_parameters_with_the_same_name_as_passed2(self): - self.mod.write('def a_func(var):\n print(var)\nvar = 1\na_func(var=var)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('var = 1\nprint(var)\n', self.mod.read()) - - def test_simple_parameters_renaming(self): - self.mod.write('def a_func(param):\n print(param)\nvar = 1\na_func(var)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('var = 1\nprint(var)\n', self.mod.read()) - - def test_simple_parameters_renaming_for_multiple_params(self): - self.mod.write('def a_func(param1, param2):\n p = param1 + param2\n' - 'var1 = 1\nvar2 = 1\na_func(var1, var2)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('var1 = 1\nvar2 = 1\np = var1 + var2\n', self.mod.read()) - - def test_parameters_renaming_for_passed_constants(self): - self.mod.write('def a_func(param):\n print(param)\na_func(1)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('print(1)\n', self.mod.read()) - - def test_parameters_renaming_for_passed_statements(self): - self.mod.write('def a_func(param):\n print(param)\na_func((1 + 2) / 3)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('print((1 + 2) / 3)\n', self.mod.read()) - - def test_simple_parameters_renaming_for_multiple_params_using_keywords(self): - self.mod.write('def a_func(param1, param2):\n p = param1 + param2\n' - 'var1 = 1\nvar2 = 1\na_func(param2=var1, param1=var2)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('var1 = 1\nvar2 = 1\np = var2 + var1\n', self.mod.read()) - - def test_simple_parameters_renaming_for_multiple_params_using_mixed_keywords(self): - self.mod.write('def a_func(param1, param2):\n p = param1 + param2\n' - 'var1 = 1\nvar2 = 1\na_func(var2, param2=var1)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('var1 = 1\nvar2 = 1\np = var2 + var1\n', self.mod.read()) - - def test_simple_putting_in_default_arguments(self): - self.mod.write('def a_func(param=None):\n print(param)\n' - 'a_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('print(None)\n', self.mod.read()) - - def test_overriding_default_arguments(self): - self.mod.write('def a_func(param1=1, param2=2):\n print(param1, param2)\n' - 'a_func(param2=3)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('print(1, 3)\n', self.mod.read()) - - def test_badly_formatted_text(self): - self.mod.write('def a_func ( param1 = 1 ,param2 = 2 ) :\n print(param1, param2)\n' - 'a_func ( param2 \n = 3 ) \n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('print(1, 3)\n', self.mod.read()) - - def test_passing_first_arguments_for_methods(self): - a_class = 'class A(object):\n' \ - ' def __init__(self):\n' \ - ' self.var = 1\n' \ - ' self.a_func(self.var)\n' \ - ' def a_func(self, param):\n' \ - ' print(param)\n' - self.mod.write(a_class) - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - expected = 'class A(object):\n' \ - ' def __init__(self):\n' \ - ' self.var = 1\n' \ - ' print(self.var)\n' - self.assertEquals(expected, self.mod.read()) - - def test_passing_first_arguments_for_methods2(self): - a_class = 'class A(object):\n' \ - ' def __init__(self):\n' \ - ' self.var = 1\n' \ - ' def a_func(self, param):\n' \ - ' print(param, self.var)\n' \ - 'an_a = A()\n' \ - 'an_a.a_func(1)\n' - self.mod.write(a_class) - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - expected = 'class A(object):\n' \ - ' def __init__(self):\n' \ - ' self.var = 1\n' \ - 'an_a = A()\n' \ - 'print(1, an_a.var)\n' - self.assertEquals(expected, self.mod.read()) - - def test_passing_first_arguments_for_methods3(self): - a_class = 'class A(object):\n' \ - ' def __init__(self):\n' \ - ' self.var = 1\n' \ - ' def a_func(self, param):\n' \ - ' print(param, self.var)\n' \ - 'an_a = A()\n' \ - 'A.a_func(an_a, 1)\n' - self.mod.write(a_class) - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - expected = 'class A(object):\n' \ - ' def __init__(self):\n' \ - ' self.var = 1\n' \ - 'an_a = A()\n' \ - 'print(1, an_a.var)\n' - self.assertEquals(expected, self.mod.read()) - - def test_inlining_staticmethods(self): - a_class = 'class A(object):\n' \ - ' @staticmethod\n' \ - ' def a_func(param):\n' \ - ' print(param)\n' \ - 'A.a_func(1)\n' - self.mod.write(a_class) - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - expected = 'class A(object):\n' \ - ' pass\n' \ - 'print(1)\n' - self.assertEquals(expected, self.mod.read()) - - def test_static_methods2(self): - a_class = 'class A(object):\n' \ - ' var = 10\n' \ - ' @staticmethod\n' \ - ' def a_func(param):\n' \ - ' print(param)\n' \ - 'an_a = A()\n' \ - 'an_a.a_func(1)\n' \ - 'A.a_func(2)\n' - self.mod.write(a_class) - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - expected = 'class A(object):\n' \ - ' var = 10\n' \ - 'an_a = A()\n' \ - 'print(1)\n' \ - 'print(2)\n' - self.assertEquals(expected, self.mod.read()) - - def test_inlining_classmethods(self): - a_class = 'class A(object):\n' \ - ' @classmethod\n' \ - ' def a_func(cls, param):\n' \ - ' print(param)\n' \ - 'A.a_func(1)\n' - self.mod.write(a_class) - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - expected = 'class A(object):\n' \ - ' pass\n' \ - 'print(1)\n' - self.assertEquals(expected, self.mod.read()) - - def test_inlining_classmethods2(self): - a_class = 'class A(object):\n' \ - ' @classmethod\n' \ - ' def a_func(cls, param):\n' \ - ' return cls\n' \ - 'print(A.a_func(1))\n' - self.mod.write(a_class) - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - expected = 'class A(object):\n' \ - ' pass\n' \ - 'print(A)\n' - self.assertEquals(expected, self.mod.read()) - - def test_simple_return_values_and_inlining_functions(self): - self.mod.write('def a_func():\n return 1\na = a_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('a = 1\n', - self.mod.read()) - - def test_simple_return_values_and_inlining_lonely_functions(self): - self.mod.write('def a_func():\n return 1\na_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('1\n', self.mod.read()) - - def test_empty_returns_and_inlining_lonely_functions(self): - self.mod.write('def a_func():\n if True:\n return\na_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('if True:\n pass\n', self.mod.read()) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_multiple_returns(self): - self.mod.write('def less_than_five(var):\n if var < 5:\n' - ' return True\n return False\n' - 'a = less_than_five(2)\n') - self._inline2(self.mod, self.mod.read().index('less') + 1) - - def test_multiple_returns_and_not_using_the_value(self): - self.mod.write('def less_than_five(var):\n if var < 5:\n' - ' return True\n return False\nless_than_five(2)\n') - self._inline2(self.mod, self.mod.read().index('less') + 1) - self.assertEquals('if 2 < 5:\n True\nFalse\n', self.mod.read()) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_raising_exception_for_list_arguments(self): - self.mod.write('def a_func(*args):\n print(args)\na_func(1)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_raising_exception_for_list_keywods(self): - self.mod.write('def a_func(**kwds):\n print(kwds)\na_func(n=1)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - - def test_function_parameters_and_returns_in_other_functions(self): - code = 'def a_func(param1, param2):\n' \ - ' return param1 + param2\n' \ - 'range(a_func(20, param2=abs(10)))\n' - self.mod.write(code) - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('range(20 + abs(10))\n', self.mod.read()) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_function_references_other_than_call(self): - self.mod.write('def a_func(param):\n print(param)\nf = a_func\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_function_referencing_itself(self): - self.mod.write('def a_func(var):\n func = a_func\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - - @testutils.assert_raises(rope.base.exceptions.RefactoringError) - def test_recursive_functions(self): - self.mod.write('def a_func(var):\n a_func(var)\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - - # TODO: inlining on function parameters - def xxx_test_inlining_function_default_parameters(self): - self.mod.write('def a_func(p1=1):\n pass\na_func()\n') - self._inline2(self.mod, self.mod.read().index('p1') + 1) - self.assertEquals('def a_func(p1=1):\n pass\na_func()\n', self.mod.read()) - - def test_simple_inlining_after_extra_indented_lines(self): - self.mod.write('def a_func():\n for i in range(10):\n pass\n' - 'if True:\n pass\na_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('if True:\n pass\nfor i in range(10):\n pass\n', - self.mod.read()) - - def test_inlining_a_function_with_pydoc(self): - self.mod.write('def a_func():\n """docs"""\n a = 1\na_func()') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('a = 1\n', self.mod.read()) - - def test_inlining_methods(self): - self.mod.write("class A(object):\n name = 'hey'\n" - " def get_name(self):\n return self.name\n" - "a = A()\nname = a.get_name()\n") - self._inline2(self.mod, self.mod.read().rindex('get_name') + 1) - self.assertEquals("class A(object):\n name = 'hey'\n" - "a = A()\nname = a.name\n", self.mod.read()) - - def test_simple_returns_with_backslashes(self): - self.mod.write('def a_func():\n return 1\\\n + 2\na = a_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('a = 1 + 2\n', self.mod.read()) - - def test_a_function_with_pass_body(self): - self.mod.write('def a_func():\n print(1)\na = a_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func') + 1) - self.assertEquals('print(1)\na = None\n', self.mod.read()) - - def test_inlining_the_last_method_of_a_class(self): - self.mod.write('class A(object):\n' - ' def a_func(self):\n pass\n') - self._inline2(self.mod, self.mod.read().rindex('a_func') + 1) - self.assertEquals('class A(object):\n pass\n', - self.mod.read()) - - def test_adding_needed_imports_in_the_dest_module(self): - self.mod.write('import sys\n\ndef ver():\n print(sys.version)\n') - self.mod2.write('import mod\n\nmod.ver()') - self._inline2(self.mod, self.mod.read().index('ver') + 1) - self.assertEquals('import mod\nimport sys\n\nprint(sys.version)\n', - self.mod2.read()) - - def test_adding_needed_imports_in_the_dest_module_removing_selfs(self): - self.mod.write('import mod2\n\ndef f():\n print(mod2.var)\n') - self.mod2.write('import mod\n\nvar = 1\nmod.f()\n') - self._inline2(self.mod, self.mod.read().index('f(') + 1) - self.assertEquals('import mod\n\nvar = 1\nprint(var)\n', - self.mod2.read()) - - def test_handling_relative_imports_when_inlining(self): - pkg = testutils.create_package(self.project, 'pkg') - mod3 = testutils.create_module(self.project, 'mod3', pkg) - mod4 = testutils.create_module(self.project, 'mod4', pkg) - mod4.write('var = 1\n') - mod3.write('from . import mod4\n\ndef f():\n print(mod4.var)\n') - self.mod.write('import pkg.mod3\n\npkg.mod3.f()\n') - self._inline2(self.mod, self.mod.read().index('f(') + 1) - # Cannot determine the exact import - self.assertTrue('\n\nprint(mod4.var)\n' in self.mod.read()) - - def test_adding_needed_imports_for_elements_in_source(self): - self.mod.write('def f1():\n return f2()\ndef f2():\n return 1\n') - self.mod2.write('import mod\n\nprint(mod.f1())\n') - self._inline2(self.mod, self.mod.read().index('f1') + 1) - self.assertEquals('import mod\nfrom mod import f2\n\nprint(f2())\n', - self.mod2.read()) - - def test_relative_imports_and_changing_inlining_body(self): - pkg = testutils.create_package(self.project, 'pkg') - mod3 = testutils.create_module(self.project, 'mod3', pkg) - mod4 = testutils.create_module(self.project, 'mod4', pkg) - mod4.write('var = 1\n') - mod3.write('import mod4\n\ndef f():\n print(mod4.var)\n') - self.mod.write('import pkg.mod3\n\npkg.mod3.f()\n') - self._inline2(self.mod, self.mod.read().index('f(') + 1) - self.assertEquals( - 'import pkg.mod3\nimport pkg.mod4\n\nprint(pkg.mod4.var)\n', - self.mod.read()) - - def test_inlining_with_different_returns(self): - self.mod.write('def f(p):\n return p\n' - 'print(f(1))\nprint(f(2))\nprint(f(1))\n') - self._inline2(self.mod, self.mod.read().index('f(') + 1) - self.assertEquals('print(1)\nprint(2)\nprint(1)\n', - self.mod.read()) - - def test_not_removing_definition_for_variables(self): - code = 'a_var = 10\nanother_var = a_var\n' - refactored = self._inline(code, code.index('a_var') + 1, - remove=False) - self.assertEquals('a_var = 10\nanother_var = 10\n', refactored) - - def test_not_removing_definition_for_methods(self): - code = 'def func():\n print(1)\n\nfunc()\n' - refactored = self._inline(code, code.index('func') + 1, - remove=False) - self.assertEquals('def func():\n print(1)\n\nprint(1)\n', - refactored) - - def test_only_current_for_methods(self): - code = 'def func():\n print(1)\n\nfunc()\nfunc()\n' - refactored = self._inline(code, code.rindex('func') + 1, - remove=False, only_current=True) - self.assertEquals('def func():\n print(1)\n\nfunc()\nprint(1)\n', - refactored) - - def test_only_current_for_variables(self): - code = 'one = 1\n\na = one\nb = one\n' - refactored = self._inline(code, code.rindex('one') + 1, - remove=False, only_current=True) - self.assertEquals('one = 1\n\na = one\nb = 1\n', refactored) - - def test_inlining_one_line_functions(self): - code = 'def f(): return 1\nvar = f()\n' - refactored = self._inline(code, code.rindex('f')) - self.assertEquals('var = 1\n', refactored) - - def test_inlining_one_line_functions_with_breaks(self): - code = 'def f(\np): return p\nvar = f(1)\n' - refactored = self._inline(code, code.rindex('f')) - self.assertEquals('var = 1\n', refactored) - - def test_inlining_one_line_functions_with_breaks2(self): - code = 'def f(\n): return 1\nvar = f()\n' - refactored = self._inline(code, code.rindex('f')) - self.assertEquals('var = 1\n', refactored) - - def test_resources_parameter(self): - self.mod.write('def a_func():\n print(1)\n') - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('import mod\nmod.a_func()\n') - self._inline2(self.mod, self.mod.read().index('a_func'), - resources=[self.mod]) - self.assertEquals('', self.mod.read()) - self.assertEquals('import mod\nmod.a_func()\n', mod1.read()) - - def test_inlining_parameters(self): - code = 'def f(p=1):\n pass\nf()\n' - result = self._inline(code, code.index('p')) - self.assertEquals('def f(p=1):\n pass\nf(1)\n', result) - - def test_inlining_function_with_line_breaks_in_args(self): - code = 'def f(p): return p\nvar = f(1 +\n1)\n' - refactored = self._inline(code, code.rindex('f')) - self.assertEquals('var = 1 + 1\n', refactored) - - def test_inlining_variables_before_comparison(self): - code = 'start = 1\nprint(start <= 2)\n' - refactored = self._inline(code, code.index('start')) - self.assertEquals('print(1 <= 2)\n', refactored) - - def test_inlining_variables_in_other_modules(self): - self.mod.write('myvar = 1\n') - self.mod2.write('import mod\nprint(mod.myvar)\n') - self._inline2(self.mod, 2) - self.assertEquals('import mod\nprint(1)\n', self.mod2.read()) - - def test_inlining_variables_and_back_importing(self): - self.mod.write('mainvar = 1\nmyvar = mainvar\n') - self.mod2.write('import mod\nprint(mod.myvar)\n') - self._inline2(self.mod, self.mod.read().index('myvar')) - expected = 'import mod\n' \ - 'from mod import mainvar\n' \ - 'print(mainvar)\n' - self.assertEquals(expected, self.mod2.read()) - - def test_inlining_variables_and_importing_used_imports(self): - self.mod.write('import sys\nmyvar = sys.argv\n') - self.mod2.write('import mod\nprint(mod.myvar)\n') - self._inline2(self.mod, self.mod.read().index('myvar')) - expected = 'import mod\n' \ - 'import sys\n' \ - 'print(sys.argv)\n' - self.assertEquals(expected, self.mod2.read()) - - def test_inlining_variables_and_removing_old_froms(self): - self.mod.write('var = 1\n') - self.mod2.write('from mod import var\nprint(var)\n') - self._inline2(self.mod2, self.mod2.read().rindex('var')) - self.assertEquals('print(1)\n', self.mod2.read()) - - def test_inlining_method_and_removing_old_froms(self): - self.mod.write('def f(): return 1\n') - self.mod2.write('from mod import f\nprint(f())\n') - self._inline2(self.mod2, self.mod2.read().rindex('f')) - self.assertEquals('print(1)\n', self.mod2.read()) - - def test_inlining_functions_in_other_modules_and_only_current(self): - code1 = 'def f():\n' \ - ' return 1\n' \ - 'print(f())\n' - code2 = 'import mod\n' \ - 'print(mod.f())\n' \ - 'print(mod.f())\n' - self.mod.write(code1) - self.mod2.write(code2) - self._inline2(self.mod2, self.mod2.read().rindex('f'), - remove=False, only_current=True) - expected2 = 'import mod\n' \ - 'print(mod.f())\n' \ - 'print(1)\n' - self.assertEquals(code1, self.mod.read()) - self.assertEquals(expected2, self.mod2.read()) - - def test_inlining_variables_in_other_modules_and_only_current(self): - code1 = 'var = 1\n' \ - 'print(var)\n' - code2 = 'import mod\n' \ - 'print(mod.var)\n' \ - 'print(mod.var)\n' - self.mod.write(code1) - self.mod2.write(code2) - self._inline2(self.mod2, self.mod2.read().rindex('var'), - remove=False, only_current=True) - expected2 = 'import mod\n' \ - 'print(mod.var)\n' \ - 'print(1)\n' - self.assertEquals(code1, self.mod.read()) - self.assertEquals(expected2, self.mod2.read()) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(InlineTest)) - return result - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/movetest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/movetest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,507 +0,0 @@ -import unittest - -from rope.base import exceptions -from rope.refactor import move -from ropetest import testutils - - -class MoveRefactoringTest(unittest.TestCase): - - def setUp(self): - super(MoveRefactoringTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod1 = testutils.create_module(self.project, 'mod1') - self.mod2 = testutils.create_module(self.project, 'mod2') - self.mod3 = testutils.create_module(self.project, 'mod3') - self.pkg = testutils.create_package(self.project, 'pkg') - self.mod4 = testutils.create_module(self.project, 'mod4', self.pkg) - self.mod5 = testutils.create_module(self.project, 'mod5', self.pkg) - - def tearDown(self): - testutils.remove_project(self.project) - super(MoveRefactoringTest, self).tearDown() - - def _move(self, resource, offset, dest_resource): - changes = move.create_move(self.project, resource, offset).\ - get_changes(dest_resource) - self.project.do(changes) - - def test_simple_moving(self): - self.mod1.write('class AClass(object):\n pass\n') - self._move(self.mod1, self.mod1.read().index('AClass') + 1, - self.mod2) - self.assertEquals('', self.mod1.read()) - self.assertEquals('class AClass(object):\n pass\n', - self.mod2.read()) - - def test_changing_other_modules_adding_normal_imports(self): - self.mod1.write('class AClass(object):\n pass\n') - self.mod3.write('import mod1\na_var = mod1.AClass()\n') - self._move(self.mod1, self.mod1.read().index('AClass') + 1, - self.mod2) - self.assertEquals('import mod1\nimport mod2\na_var = mod2.AClass()\n', - self.mod3.read()) - - def test_changing_other_modules_removing_from_imports(self): - self.mod1.write('class AClass(object):\n pass\n') - self.mod3.write('from mod1 import AClass\na_var = AClass()\n') - self._move(self.mod1, self.mod1.read().index('AClass') + 1, - self.mod2) - self.assertEquals('import mod2\na_var = mod2.AClass()\n', - self.mod3.read()) - - def test_changing_source_module(self): - self.mod1.write('class AClass(object):\n pass\na_var = AClass()\n') - self._move(self.mod1, self.mod1.read().index('AClass') + 1, - self.mod2) - self.assertEquals('import mod2\na_var = mod2.AClass()\n', - self.mod1.read()) - - def test_changing_destination_module(self): - self.mod1.write('class AClass(object):\n pass\n') - self.mod2.write('from mod1 import AClass\na_var = AClass()\n') - self._move(self.mod1, self.mod1.read().index('AClass') + 1, - self.mod2) - self.assertEquals('class AClass(object):\n pass\na_var = AClass()\n', - self.mod2.read()) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_folder_destination(self): - folder = self.project.root.create_folder('folder') - self.mod1.write('class AClass(object):\n pass\n') - self._move(self.mod1, self.mod1.read().index('AClass') + 1, folder) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_raising_exception_for_moving_non_global_elements(self): - self.mod1.write('def a_func():\n class AClass(object):\n pass\n') - self._move(self.mod1, self.mod1.read().index('AClass') + 1, - self.mod2) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_raising_exception_for_moving_global_elements_to_the_same_module(self): - self.mod1.write('def a_func():\n pass\n') - self._move(self.mod1, self.mod1.read().index('a_func'), self.mod1) - - def test_moving_used_imports_to_destination_module(self): - self.mod3.write('a_var = 10') - code = 'import mod3\n' \ - 'from mod3 import a_var\n' \ - 'def a_func():\n' \ - ' print(mod3, a_var)\n' - self.mod1.write(code) - self._move(self.mod1, code.index('a_func') + 1, self.mod2) - expected = 'import mod3\n' \ - 'from mod3 import a_var\n\n\n' \ - 'def a_func():\n print(mod3, a_var)\n' - self.assertEquals(expected, self.mod2.read()) - - def test_moving_used_names_to_destination_module2(self): - code = 'a_var = 10\n' \ - 'def a_func():\n' \ - ' print(a_var)\n' - self.mod1.write(code) - self._move(self.mod1, code.index('a_func') + 1, self.mod2) - self.assertEquals('a_var = 10\n', self.mod1.read()) - expected = 'from mod1 import a_var\n\n\n' \ - 'def a_func():\n' \ - ' print(a_var)\n' - self.assertEquals(expected, self.mod2.read()) - - def test_moving_used_underlined_names_to_destination_module(self): - code = '_var = 10\n' \ - 'def a_func():\n' \ - ' print(_var)\n' - self.mod1.write(code) - self._move(self.mod1, code.index('a_func') + 1, self.mod2) - expected = 'from mod1 import _var\n\n\n' \ - 'def a_func():\n' \ - ' print(_var)\n' - self.assertEquals(expected, self.mod2.read()) - - def test_moving_and_used_relative_imports(self): - code = 'import mod5\n' \ - 'def a_func():\n' \ - ' print(mod5)\n' - self.mod4.write(code) - self._move(self.mod4, code.index('a_func') + 1, self.mod1) - expected = 'import pkg.mod5\n\n\n' \ - 'def a_func():\n' \ - ' print(pkg.mod5)\n' - self.assertEquals(expected, self.mod1.read()) - - def test_moving_modules(self): - code = 'import mod1\nprint(mod1)' - self.mod2.write(code) - self._move(self.mod2, code.index('mod1') + 1, self.pkg) - expected = 'import pkg.mod1\nprint(pkg.mod1)' - self.assertEquals(expected, self.mod2.read()) - self.assertTrue(not self.mod1.exists() and - self.pycore.find_module('pkg.mod1') is not None) - - def test_moving_modules_and_removing_out_of_date_imports(self): - code = 'import pkg.mod4\nprint(pkg.mod4)' - self.mod2.write(code) - self._move(self.mod2, code.index('mod4') + 1, self.project.root) - expected = 'import mod4\nprint(mod4)' - self.assertEquals(expected, self.mod2.read()) - self.assertTrue(self.pycore.find_module('mod4') is not None) - - def test_moving_modules_and_removing_out_of_date_froms(self): - code = 'from pkg import mod4\nprint(mod4)' - self.mod2.write(code) - self._move(self.mod2, code.index('mod4') + 1, self.project.root) - self.assertEquals('import mod4\nprint(mod4)', self.mod2.read()) - - def test_moving_modules_and_removing_out_of_date_froms2(self): - self.mod4.write('a_var = 10') - code = 'from pkg.mod4 import a_var\nprint(a_var)\n' - self.mod2.write(code) - self._move(self.mod2, code.index('mod4') + 1, self.project.root) - expected = 'from mod4 import a_var\nprint(a_var)\n' - self.assertEquals(expected, self.mod2.read()) - - def test_moving_modules_and_relative_import(self): - self.mod4.write('import mod5\nprint(mod5)\n') - code = 'import pkg.mod4\nprint(pkg.mod4)' - self.mod2.write(code) - self._move(self.mod2, code.index('mod4') + 1, self.project.root) - moved = self.pycore.find_module('mod4') - expected = 'import pkg.mod5\nprint(pkg.mod5)\n' - self.assertEquals(expected, moved.read()) - - def test_moving_packages(self): - pkg2 = testutils.create_package(self.project, 'pkg2') - code = 'import pkg.mod4\nprint(pkg.mod4)' - self.mod1.write(code) - self._move(self.mod1, code.index('pkg') + 1, pkg2) - self.assertFalse(self.pkg.exists()) - self.assertTrue(self.pycore.find_module('pkg2.pkg.mod4') is not None) - self.assertTrue(self.pycore.find_module('pkg2.pkg.mod4') is not None) - self.assertTrue(self.pycore.find_module('pkg2.pkg.mod5') is not None) - expected = 'import pkg2.pkg.mod4\nprint(pkg2.pkg.mod4)' - self.assertEquals(expected, self.mod1.read()) - - def test_moving_modules_with_self_imports(self): - self.mod1.write('import mod1\nprint(mod1)\n') - self.mod2.write('import mod1\n') - self._move(self.mod2, self.mod2.read().index('mod1') + 1, self.pkg) - moved = self.pycore.find_module('pkg.mod1') - self.assertEquals('import pkg.mod1\nprint(pkg.mod1)\n', moved.read()) - - def test_moving_funtions_to_imported_module(self): - code = 'import mod1\n' \ - 'def a_func():\n' \ - ' var = mod1.a_var\n' - self.mod1.write('a_var = 1\n') - self.mod2.write(code) - self._move(self.mod2, code.index('a_func') + 1, self.mod1) - expected = 'def a_func():\n' \ - ' var = a_var\n' \ - 'a_var = 1\n' - self.assertEquals(expected, self.mod1.read()) - - def test_moving_resources_using_move_module_refactoring(self): - self.mod1.write('a_var = 1') - self.mod2.write('import mod1\nmy_var = mod1.a_var\n') - mover = move.create_move(self.project, self.mod1) - mover.get_changes(self.pkg).do() - expected = 'import pkg.mod1\nmy_var = pkg.mod1.a_var\n' - self.assertEquals(expected, self.mod2.read()) - self.assertTrue(self.pkg.get_child('mod1.py') is not None) - - def test_moving_resources_using_move_module_for_packages(self): - self.mod1.write('import pkg\nmy_pkg = pkg') - pkg2 = testutils.create_package(self.project, 'pkg2') - mover = move.create_move(self.project, self.pkg) - mover.get_changes(pkg2).do() - expected = 'import pkg2.pkg\nmy_pkg = pkg2.pkg' - self.assertEquals(expected, self.mod1.read()) - self.assertTrue(pkg2.get_child('pkg') is not None) - - def test_moving_resources_using_move_module_for_init_dot_py(self): - self.mod1.write('import pkg\nmy_pkg = pkg') - pkg2 = testutils.create_package(self.project, 'pkg2') - init = self.pkg.get_child('__init__.py') - mover = move.create_move(self.project, init) - mover.get_changes(pkg2).do() - self.assertEquals('import pkg2.pkg\nmy_pkg = pkg2.pkg', - self.mod1.read()) - self.assertTrue(pkg2.get_child('pkg') is not None) - - def test_moving_module_and_star_imports(self): - self.mod1.write('a_var = 1') - self.mod2.write('from mod1 import *\na = a_var\n') - mover = move.create_move(self.project, self.mod1) - mover.get_changes(self.pkg).do() - self.assertEquals('from pkg.mod1 import *\na = a_var\n', - self.mod2.read()) - - def test_moving_module_and_not_removing_blanks_after_imports(self): - self.mod4.write('a_var = 1') - self.mod2.write('from pkg import mod4\n' - 'import os\n\n\nprint(mod4.a_var)\n') - mover = move.create_move(self.project, self.mod4) - mover.get_changes(self.project.root).do() - self.assertEquals('import os\nimport mod4\n\n\n' - 'print(mod4.a_var)\n', self.mod2.read()) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_moving_module_refactoring_and_nonexistent_destinations(self): - self.mod4.write('a_var = 1') - self.mod2.write('from pkg import mod4\n' - 'import os\n\n\nprint(mod4.a_var)\n') - mover = move.create_move(self.project, self.mod4) - mover.get_changes(None).do() - - def test_moving_methods_choosing_the_correct_class(self): - code = 'class A(object):\n def a_method(self):\n pass\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, code.index('a_method')) - self.assertTrue(isinstance(mover, move.MoveMethod)) - - def test_moving_methods_getting_new_method_for_empty_methods(self): - code = 'class A(object):\n def a_method(self):\n pass\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - self.assertEquals('def new_method(self):\n pass\n', - mover.get_new_method('new_method')) - - def test_moving_methods_getting_new_method_for_constant_methods(self): - code = 'class A(object):\n def a_method(self):\n return 1\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - self.assertEquals('def new_method(self):\n return 1\n', - mover.get_new_method('new_method')) - - def test_moving_methods_getting_new_method_passing_simple_paremters(self): - code = 'class A(object):\n' \ - ' def a_method(self, p):\n return p\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - self.assertEquals('def new_method(self, p):\n return p\n', - mover.get_new_method('new_method')) - - def test_moving_methods_getting_new_method_using_main_object(self): - code = 'class A(object):\n attr = 1\n' \ - ' def a_method(host):\n return host.attr\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - self.assertEquals('def new_method(self, host):\n return host.attr\n', - mover.get_new_method('new_method')) - - def test_moving_methods_getting_new_method_renaming_main_object(self): - code = 'class A(object):\n attr = 1\n' \ - ' def a_method(self):\n return self.attr\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - self.assertEquals('def new_method(self, host):\n return host.attr\n', - mover.get_new_method('new_method')) - - def test_moving_methods_gettin_new_method_with_keyword_arguments(self): - code = 'class A(object):\n attr = 1\n' \ - ' def a_method(self, p=None):\n return p\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - self.assertEquals('def new_method(self, p=None):\n return p\n', - mover.get_new_method('new_method')) - - def test_moving_methods_gettin_new_method_with_many_kinds_arguments(self): - code = 'class A(object):\n attr = 1\n' \ - ' def a_method(self, p1, *args, **kwds):\n' \ - ' return self.attr\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - expected = 'def new_method(self, host, p1, *args, **kwds):\n' \ - ' return host.attr\n' - self.assertEquals(expected, mover.get_new_method('new_method')) - - def test_moving_methods_getting_new_method_for_multi_line_methods(self): - code = 'class A(object):\n' \ - ' def a_method(self):\n' \ - ' a = 2\n' \ - ' return a\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - self.assertEquals( - 'def new_method(self):\n a = 2\n return a\n', - mover.get_new_method('new_method')) - - def test_moving_methods_getting_old_method_for_constant_methods(self): - self.mod2.write('class B(object):\n pass\n') - code = 'import mod2\n\n' \ - 'class A(object):\n' \ - ' attr = mod2.B()\n' \ - ' def a_method(self):\n' \ - ' return 1\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - mover.get_changes('attr', 'new_method').do() - expected = 'import mod2\n\n' \ - 'class A(object):\n' \ - ' attr = mod2.B()\n' \ - ' def a_method(self):\n' \ - ' return self.attr.new_method()\n' - self.assertEquals(expected, self.mod1.read()) - - def test_moving_methods_getting_getting_changes_for_goal_class(self): - self.mod2.write('class B(object):\n var = 1\n') - code = 'import mod2\n\n' \ - 'class A(object):\n' \ - ' attr = mod2.B()\n' \ - ' def a_method(self):\n' \ - ' return 1\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - mover.get_changes('attr', 'new_method').do() - expected = 'class B(object):\n' \ - ' var = 1\n\n\n' \ - ' def new_method(self):\n' \ - ' return 1\n' - self.assertEquals(expected, self.mod2.read()) - - def test_moving_methods_getting_getting_changes_for_goal_class2(self): - code = 'class B(object):\n var = 1\n\n' \ - 'class A(object):\n attr = B()\n' \ - ' def a_method(self):\n return 1\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - mover.get_changes('attr', 'new_method').do() - self.assertEquals( - 'class B(object):\n var = 1\n\n\n' - ' def new_method(self):\n' - ' return 1\n\n' - 'class A(object):\n attr = B()\n' - ' def a_method(self):\n' - ' return self.attr.new_method()\n', - self.mod1.read()) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_moving_methods_and_nonexistent_attributes(self): - code = 'class A(object):\n' \ - ' def a_method(self):\n return 1\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - mover.get_changes('x', 'new_method') - - @testutils.assert_raises(exceptions.RefactoringError) - def test_unknown_attribute_type(self): - code = 'class A(object):\n attr = 1\n' \ - ' def a_method(self):\n return 1\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - mover.get_changes('attr', 'new_method') - - def test_moving_methods_and_moving_used_imports(self): - self.mod2.write('class B(object):\n var = 1\n') - code = 'import sys\nimport mod2\n\n' \ - 'class A(object):\n' \ - ' attr = mod2.B()\n' \ - ' def a_method(self):\n' \ - ' return sys.version\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - mover.get_changes('attr', 'new_method').do() - code = 'import sys\n' \ - 'class B(object):\n' \ - ' var = 1\n\n\n' \ - ' def new_method(self):\n' \ - ' return sys.version\n' - self.assertEquals(code, self.mod2.read()) - - def test_moving_methods_getting_getting_changes_for_goal_class3(self): - self.mod2.write('class B(object):\n pass\n') - code = 'import mod2\n\n' \ - 'class A(object):\n' \ - ' attr = mod2.B()\n' \ - ' def a_method(self):\n' \ - ' return 1\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - mover.get_changes('attr', 'new_method').do() - expected = 'class B(object):\n\n' \ - ' def new_method(self):\n' \ - ' return 1\n' - self.assertEquals(expected, self.mod2.read()) - - def test_moving_methods_and_source_class_with_parameters(self): - self.mod2.write('class B(object):\n pass\n') - code = 'import mod2\n\n' \ - 'class A(object):\n' \ - ' attr = mod2.B()\n' \ - ' def a_method(self, p):\n return p\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('a_method')) - mover.get_changes('attr', 'new_method').do() - expected1 = 'import mod2\n\n' \ - 'class A(object):\n' \ - ' attr = mod2.B()\n' \ - ' def a_method(self, p):\n' \ - ' return self.attr.new_method(p)\n' - self.assertEquals(expected1, self.mod1.read()) - expected2 = 'class B(object):\n\n' \ - ' def new_method(self, p):\n' \ - ' return p\n' - self.assertEquals(expected2, self.mod2.read()) - - def test_moving_globals_to_a_module_with_only_docstrings(self): - self.mod1.write('import sys\n\n\ndef f():\n print(sys.version)\n') - self.mod2.write('"""doc\n\nMore docs ...\n\n"""\n') - mover = move.create_move(self.project, self.mod1, - self.mod1.read().index('f()') + 1) - self.project.do(mover.get_changes(self.mod2)) - self.assertEquals( - '"""doc\n\nMore docs ...\n\n"""\n' - 'import sys\n\n\ndef f():\n print(sys.version)\n', - self.mod2.read()) - - def test_moving_globals_to_a_module_with_only_docstrings2(self): - code = 'import os\n' \ - 'import sys\n\n\n' \ - 'def f():\n' \ - ' print(sys.version, os.path)\n' - self.mod1.write(code) - self.mod2.write('"""doc\n\nMore docs ...\n\n"""\n') - mover = move.create_move(self.project, self.mod1, - self.mod1.read().index('f()') + 1) - self.project.do(mover.get_changes(self.mod2)) - expected = '"""doc\n\nMore docs ...\n\n"""\n' \ - 'import os\n' \ - 'import sys\n\n\n' \ - 'def f():\n' \ - ' print(sys.version, os.path)\n' - self.assertEquals(expected, self.mod2.read()) - - def test_moving_a_global_when_it_is_used_after_a_multiline_str(self): - code = 'def f():\n pass\ns = """\\\n"""\nr = f()\n' - self.mod1.write(code) - mover = move.create_move(self.project, self.mod1, - code.index('f()') + 1) - self.project.do(mover.get_changes(self.mod2)) - expected = 'import mod2\ns = """\\\n"""\nr = mod2.f()\n' - self.assertEquals(expected, self.mod1.read()) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_raising_an_exception_when_moving_non_package_folders(self): - dir = self.project.root.create_folder('dir') - mover = move.create_move(self.project, dir) - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/multiprojecttest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/multiprojecttest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -import unittest - -import rope.base.codeanalyze -import rope.refactor.occurrences -from rope.refactor import multiproject, rename, move -from ropetest import testutils - - -class MultiProjectRefactoringTest(unittest.TestCase): - - def setUp(self): - super(MultiProjectRefactoringTest, self).setUp() - self.project1 = testutils.sample_project(foldername='testproject1') - self.project2 = testutils.sample_project(foldername='testproject2') - self.mod1 = self.project1.root.create_file('mod1.py') - self.other = self.project1.root.create_file('other.py') - self.mod2 = self.project2.root.create_file('mod2.py') - - def tearDown(self): - testutils.remove_project(self.project1) - testutils.remove_project(self.project2) - super(MultiProjectRefactoringTest, self).tearDown() - - def test_trivial_rename(self): - self.mod1.write('var = 1\n') - refactoring = multiproject.MultiProjectRefactoring( - rename.Rename, []) - renamer = refactoring(self.project1, self.mod1, 1) - multiproject.perform(renamer.get_all_changes('newvar')) - self.assertEquals('newvar = 1\n', self.mod1.read()) - - def test_rename(self): - self.mod1.write('var = 1\n') - self.mod2.write('import mod1\nmyvar = mod1.var\n') - refactoring = multiproject.MultiProjectRefactoring( - rename.Rename, [self.project2]) - renamer = refactoring(self.project1, self.mod1, 1) - multiproject.perform(renamer.get_all_changes('newvar')) - self.assertEquals('newvar = 1\n', self.mod1.read()) - self.assertEquals('import mod1\nmyvar = mod1.newvar\n', - self.mod2.read()) - - def test_move(self): - self.mod1.write('def a_func():\n pass\n') - self.mod2.write('import mod1\nmyvar = mod1.a_func()\n') - refactoring = multiproject.MultiProjectRefactoring( - move.create_move, [self.project2]) - renamer = refactoring(self.project1, self.mod1, - self.mod1.read().index('_func')) - multiproject.perform(renamer.get_all_changes(self.other)) - self.assertEquals('', self.mod1.read()) - self.assertEquals('def a_func():\n pass\n', self.other.read()) - self.assertEquals( - 'import mod1\nimport other\nmyvar = other.a_func()\n', - self.mod2.read()) - - def test_rename_from_the_project_not_containing_the_change(self): - self.project2.get_prefs().add('python_path', self.project1.address) - self.mod1.write('var = 1\n') - self.mod2.write('import mod1\nmyvar = mod1.var\n') - refactoring = multiproject.MultiProjectRefactoring( - rename.Rename, [self.project1]) - renamer = refactoring(self.project2, self.mod2, - self.mod2.read().rindex('var')) - multiproject.perform(renamer.get_all_changes('newvar')) - self.assertEquals('newvar = 1\n', self.mod1.read()) - self.assertEquals('import mod1\nmyvar = mod1.newvar\n', - self.mod2.read()) - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/patchedasttest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/patchedasttest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,832 +0,0 @@ -import unittest - -from rope.base import ast -from rope.refactor import patchedast -from ropetest import testutils - - -class PatchedASTTest(unittest.TestCase): - - def setUp(self): - super(PatchedASTTest, self).setUp() - - def tearDown(self): - super(PatchedASTTest, self).tearDown() - - def test_integer_literals_and_region(self): - source = 'a = 10\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - start = source.index('10') - checker.check_region('Num', start, start + 2) - - def test_integer_literals_and_sorted_children(self): - source = 'a = 10\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - start = source.index('10') - checker.check_children('Num', ['10']) - - def test_ass_name_node(self): - source = 'a = 10\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - start = source.index('a') - checker.check_region('Name', start, start + 1) - checker.check_children('Name', ['a']) - - def test_assign_node(self): - source = 'a = 10\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - start = source.index('a') - checker.check_region('Assign', 0, len(source) - 1) - checker.check_children( - 'Assign', ['Name', ' ', '=', ' ', 'Num']) - - def test_add_node(self): - source = '1 + 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('BinOp', 0, len(source) - 1) - checker.check_children( - 'BinOp', ['Num', ' ', '+', ' ', 'Num']) - - def test_lshift_node(self): - source = '1 << 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('BinOp', 0, len(source) - 1) - checker.check_children( - 'BinOp', ['Num', ' ', '<<', ' ', 'Num']) - - def test_and_node(self): - source = 'True and True\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('BoolOp', 0, len(source) - 1) - checker.check_children( - 'BoolOp', ['Name', ' ', 'and', ' ', 'Name']) - - def test_basic_closing_parens(self): - source = '1 + (2)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('BinOp', 0, len(source) - 1) - checker.check_children( - 'BinOp', ['Num', ' ', '+', ' (', 'Num', ')']) - - def test_basic_opening_parens(self): - source = '(1) + 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('BinOp', 0, len(source) - 1) - checker.check_children( - 'BinOp', ['(', 'Num', ') ', '+', ' ', 'Num']) - - def test_basic_opening_biway(self): - source = '(1) + (2)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('BinOp', 0, len(source) - 1) - checker.check_children( - 'BinOp', ['(', 'Num', ') ', '+', ' (', 'Num', ')']) - - def test_basic_opening_double(self): - source = '1 + ((2))\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('BinOp', 0, len(source) - 1) - checker.check_children( - 'BinOp', ['Num', ' ', '+', ' ((', 'Num', '))']) - - def test_handling_comments(self): - source = '(1 + #(\n2)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'BinOp', ['Num', ' ', '+', ' #(\n', 'Num']) - - def test_handling_parens_with_spaces(self): - source = '1 + (2\n )\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'BinOp', ['Num', ' ', '+', ' (', 'Num', '\n )']) - - def test_handling_strings(self): - source = '1 + "("\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'BinOp', ['Num', ' ', '+', ' ', 'Str']) - - def test_handling_implicit_string_concatenation(self): - source = "a = '1''2'" - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Assign', ['Name' , ' ', '=', ' ', 'Str']) - checker.check_children('Str', ["'1''2'"]) - - def test_handling_implicit_string_concatenation_line_breaks(self): - source = "a = '1' \\\n'2'" - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Assign', ['Name' , ' ', '=', ' ', 'Str']) - checker.check_children('Str', ["'1' \\\n'2'"]) - - def test_handling_explicit_string_concatenation_line_breaks(self): - source = "a = ('1' \n'2')" - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Assign', ['Name' , ' ', '=', ' (', 'Str', ')']) - checker.check_children('Str', ["'1' \n'2'"]) - - def test_not_concatenating_strings_on_separate_lines(self): - source = "'1'\n'2'\n" - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children('Module', ['', 'Expr', '\n', 'Expr', '\n']) - - def test_long_integer_literals(self): - source = "0x1L + a" - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'BinOp', ['Num' , ' ', '+', ' ', 'Name']) - checker.check_children('Num', ['0x1L']) - - def test_complex_number_literals(self): - source = "1.0e2j + a" - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'BinOp', ['Num' , ' ', '+', ' ', 'Name']) - checker.check_children('Num', ['1.0e2j']) - - def test_ass_attr_node(self): - source = 'a.b = 1\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Attribute', 0, source.index('=') - 1) - checker.check_children('Attribute', ['Name', '', '.', '', 'b']) - - def test_ass_list_node(self): - source = '[a, b] = 1, 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('List', 0, source.index(']') + 1) - checker.check_children('List', ['[', '', 'Name', '', ',', - ' ', 'Name', '', ']']) - - def test_ass_tuple(self): - source = 'a, b = range(2)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Tuple', 0, source.index('=') - 1) - checker.check_children( - 'Tuple', ['Name', '', ',', ' ', 'Name']) - - def test_ass_tuple2(self): - source = '(a, b) = range(2)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Tuple', 0, source.index('=') - 1) - checker.check_children( - 'Tuple', ['(', '', 'Name', '', ',', ' ', 'Name', '', ')']) - - def test_assert(self): - source = 'assert True\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Assert', 0, len(source) - 1) - checker.check_children( - 'Assert', ['assert', ' ', 'Name']) - - def test_assert2(self): - source = 'assert True, "error"\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Assert', 0, len(source) - 1) - checker.check_children( - 'Assert', ['assert', ' ', 'Name', '', ',', ' ', 'Str']) - - def test_aug_assign_node(self): - source = 'a += 1\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - start = source.index('a') - checker.check_region('AugAssign', 0, len(source) - 1) - checker.check_children( - 'AugAssign', ['Name', ' ', '+', '', '=', ' ', 'Num']) - - def test_back_quotenode(self): - source = '`1`\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Repr', 0, len(source) - 1) - checker.check_children( - 'Repr', ['`', '', 'Num', '', '`']) - - def test_bitand(self): - source = '1 & 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('BinOp', 0, len(source) - 1) - checker.check_children( - 'BinOp', ['Num', ' ', '&', ' ', 'Num']) - - def test_bitor(self): - source = '1 | 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'BinOp', ['Num', ' ', '|', ' ', 'Num']) - - def test_call_func(self): - source = 'f(1, 2)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Call', 0, len(source) - 1) - checker.check_children( - 'Call', ['Name', '', '(', '', 'Num', '', ',', - ' ', 'Num', '', ')']) - - def test_call_func_and_keywords(self): - source = 'f(1, p=2)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Call', ['Name', '', '(', '', 'Num', '', ',', - ' ', 'keyword', '', ')']) - - def test_call_func_and_start_args(self): - source = 'f(1, *args)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Call', ['Name', '', '(', '', 'Num', '', ',', - ' ', '*', '', 'Name', '', ')']) - - def test_call_func_and_only_dstart_args(self): - source = 'f(**kwds)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Call', ['Name', '', '(', '', '**', '', 'Name', '', ')']) - - def test_call_func_and_both_varargs_and_kwargs(self): - source = 'f(*args, **kwds)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Call', ['Name', '', '(', '', '*', '', 'Name', '', ',', - ' ', '**', '', 'Name', '', ')']) - - def test_class_node(self): - source = 'class A(object):\n """class docs"""\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Class', 0, len(source) - 1) - checker.check_children( - 'Class', ['class', ' ', 'A', '', '(', '', 'Name', '', ')', - '', ':', '\n ', 'Expr', '\n ', 'Pass']) - - def test_class_with_no_bases(self): - source = 'class A:\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Class', 0, len(source) - 1) - checker.check_children( - 'Class', ['class', ' ', 'A', '', ':', '\n ', 'Pass']) - - def test_simple_compare(self): - source = '1 < 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Compare', 0, len(source) - 1) - checker.check_children( - 'Compare', ['Num', ' ', '<', ' ', 'Num']) - - def test_multiple_compare(self): - source = '1 < 2 <= 3\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Compare', 0, len(source) - 1) - checker.check_children( - 'Compare', ['Num', ' ', '<', ' ', 'Num', ' ', - '<=', ' ', 'Num']) - - def test_decorators_node(self): - source = '@d\ndef f():\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('FunctionDef', 0, len(source) - 1) - checker.check_children( - 'FunctionDef', - ['@', '', 'Name', '\n', 'def', ' ', 'f', '', '(', '', 'arguments', - '', ')', '', ':', '\n ', 'Pass']) - - @testutils.only_for('2.6') - def test_decorators_for_classes(self): - source = '@d\nclass C(object):\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('ClassDef', 0, len(source) - 1) - checker.check_children( - 'ClassDef', - ['@', '', 'Name', '\n', 'class', ' ', 'C', '', '(', '', 'Name', - '', ')', '', ':', '\n ', 'Pass']) - - def test_both_varargs_and_kwargs(self): - source = 'def f(*args, **kwds):\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'arguments', ['*', '', 'args' , '', ',' , ' ', '**', '', 'kwds']) - - def test_function_node(self): - source = 'def f():\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Function', 0, len(source) - 1) - checker.check_children('Function', ['def', ' ', 'f', '', '(', '', 'arguments', '', - ')', '', ':', '\n ', 'Pass']) - - def test_function_node2(self): - source = 'def f(p1, **p2):\n """docs"""\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Function', 0, len(source) - 1) - checker.check_children( - 'Function', ['def', ' ', 'f', '', '(', '', 'arguments', - '', ')' , '', ':', '\n ', 'Expr', '\n ', 'Pass']) - checker.check_children( - 'arguments', ['Name', '', ',', - ' ', '**', '', 'p2']) - - def test_function_node_and_tuple_parameters(self): - source = 'def f(a, (b, c)):\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Function', 0, len(source) - 1) - checker.check_children( - 'Function', ['def', ' ', 'f', '', '(', '', 'arguments', - '', ')' , '', ':', '\n ', 'Pass']) - checker.check_children( - 'arguments', ['Name', '', ',', ' ', 'Tuple']) - - def test_dict_node(self): - source = '{1: 2, 3: 4}\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Dict', 0, len(source) - 1) - checker.check_children( - 'Dict', ['{', '', 'Num', '', ':', ' ', 'Num', '', ',', - ' ', 'Num', '', ':', ' ', 'Num', '', '}']) - - def test_div_node(self): - source = '1 / 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('BinOp', 0, len(source) - 1) - checker.check_children('BinOp', ['Num', ' ', '/', ' ', 'Num']) - - def test_simple_exec_node(self): - source = 'exec ""\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Exec', 0, len(source) - 1) - checker.check_children('Exec', ['exec', ' ', 'Str']) - - def test_exec_node(self): - source = 'exec "" in locals(), globals()\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Exec', 0, len(source) - 1) - checker.check_children( - 'Exec', ['exec', ' ', 'Str', ' ', 'in', - ' ', 'Call', '', ',', ' ', 'Call']) - - def test_for_node(self): - source = 'for i in range(1):\n pass\nelse:\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('For', 0, len(source) - 1) - checker.check_children( - 'For', ['for', ' ', 'Name', ' ', 'in', ' ', 'Call', '', - ':', '\n ', 'Pass', '\n', - 'else', '', ':', '\n ', 'Pass']) - - def test_normal_from_node(self): - source = 'from x import y\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('ImportFrom', 0, len(source) - 1) - checker.check_children( - 'ImportFrom', ['from', ' ', 'x', ' ', 'import', ' ', 'alias']) - checker.check_children('alias', ['y']) - - @testutils.run_only_for_25 - def test_from_node(self): - source = 'from ..x import y as z\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('ImportFrom', 0, len(source) - 1) - checker.check_children( - 'ImportFrom', ['from', ' ', '..', '', 'x', ' ', - 'import', ' ', 'alias']) - checker.check_children('alias', ['y', ' ', 'as', ' ', 'z']) - - def test_simple_gen_expr_node(self): - source = 'zip(i for i in x)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('GeneratorExp', 4, len(source) - 2) - checker.check_children( - 'GeneratorExp', ['Name', ' ', 'comprehension']) - checker.check_children( - 'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ', 'Name']) - - def test_gen_expr_node_handling_surrounding_parens(self): - source = '(i for i in x)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('GeneratorExp', 0, len(source) - 1) - checker.check_children( - 'GeneratorExp', ['(', '', 'Name', ' ', 'comprehension', '', ')']) - - def test_gen_expr_node2(self): - source = 'zip(i for i in range(1) if i == 1)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ', 'Call', - ' ', 'if', ' ', 'Compare']) - - def test_get_attr_node(self): - source = 'a.b\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Attribute', 0, len(source) - 1) - checker.check_children('Attribute', ['Name', '', '.', '', 'b']) - - def test_global_node(self): - source = 'global a, b\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Global', 0, len(source) - 1) - checker.check_children('Global', ['global', ' ', 'a', '', ',', ' ', 'b']) - - def test_if_node(self): - source = 'if True:\n pass\nelse:\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('If', 0, len(source) - 1) - checker.check_children( - 'If', ['if', ' ', 'Name', '', ':', '\n ', 'Pass', '\n', - 'else', '', ':', '\n ', 'Pass']) - - def test_if_node2(self): - source = 'if True:\n pass\nelif False:\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('If', 0, len(source) - 1) - checker.check_children( - 'If', ['if', ' ', 'Name', '', ':', '\n ', 'Pass', '\n', - 'If']) - - def test_if_node3(self): - source = 'if True:\n pass\nelse:\n' \ - ' if True:\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('If', 0, len(source) - 1) - checker.check_children( - 'If', ['if', ' ', 'Name', '', ':', '\n ', 'Pass', '\n', - 'else', '', ':', '\n ', 'If']) - - def test_import_node(self): - source = 'import a, b as c\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Import', 0, len(source) - 1) - checker.check_children( - 'Import', ['import', ' ', 'alias', '', ',', ' ', 'alias']) - - def test_lambda_node(self): - source = 'lambda a, b=1, *z: None\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Lambda', 0, len(source) - 1) - checker.check_children( - 'Lambda', ['lambda', ' ', 'arguments', '', ':', ' ', 'Name']) - checker.check_children( - 'arguments', ['Name', '', ',', ' ', 'Name', '', '=', '', - 'Num', '', ',', ' ', '*', '', 'z']) - - def test_list_node(self): - source = '[1, 2]\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('List', 0, len(source) - 1) - checker.check_children( - 'List', ['[', '', 'Num', '', ',', ' ', 'Num', '', ']']) - - def test_list_comp_node(self): - source = '[i for i in range(1) if True]\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('ListComp', 0, len(source) - 1) - checker.check_children( - 'ListComp', ['[', '', 'Name', ' ', 'comprehension', '', ']']) - checker.check_children( - 'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ', - 'Call', ' ', 'if', ' ', 'Name']) - - def test_list_comp_node_with_multiple_comprehensions(self): - source = '[i for i in range(1) for j in range(1) if True]\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('ListComp', 0, len(source) - 1) - checker.check_children( - 'ListComp', ['[', '', 'Name', ' ', 'comprehension', - ' ', 'comprehension', '', ']']) - checker.check_children( - 'comprehension', ['for', ' ', 'Name', ' ', 'in', ' ', - 'Call', ' ', 'if', ' ', 'Name']) - - def test_ext_slice_node(self): - source = 'x = xs[0,:]\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('ExtSlice', 7, len(source) - 2) - checker.check_children('ExtSlice', ['Index', '', ',', '', 'Slice']) - - def test_simple_module_node(self): - source = 'pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Module', 0, len(source)) - checker.check_children('Module', ['', 'Pass', '\n']) - - def test_module_node(self): - source = '"""docs"""\npass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Module', 0, len(source)) - checker.check_children('Module', ['', 'Expr', '\n', 'Pass', '\n']) - checker.check_children('Str', ['"""docs"""']) - - def test_not_and_or_nodes(self): - source = 'not True or False\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children('Expr', ['BoolOp']) - checker.check_children('BoolOp', ['UnaryOp', ' ', 'or', ' ', 'Name']) - - def test_print_node(self): - source = 'print >>out, 1,\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Print', 0, len(source) - 1) - checker.check_children('Print', ['print', ' ', '>>', '', 'Name', '', - ',', ' ', 'Num', '', ',']) - - def test_printnl_node(self): - source = 'print 1\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Print', 0, len(source) - 1) - checker.check_children('Print', ['print', ' ', 'Num']) - - def test_raise_node(self): - source = 'raise x, y, z\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_region('Raise', 0, len(source) - 1) - checker.check_children( - 'Raise', ['raise', ' ', 'Name', '', ',', ' ', 'Name', '', ',', - ' ', 'Name']) - - def test_return_node(self): - source = 'def f():\n return None\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children('Return', ['return', ' ', 'Name']) - - def test_empty_return_node(self): - source = 'def f():\n return\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children('Return', ['return']) - - def test_simple_slice_node(self): - source = 'a[1:2]\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Subscript', ['Name', '', '[', '', 'Slice', '', ']']) - checker.check_children( - 'Slice', ['Num', '', ':', '', 'Num']) - - def test_slice_node2(self): - source = 'a[:]\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children('Subscript', ['Name', '', '[', '', 'Slice', '', ']']) - checker.check_children('Slice', [':']) - - def test_simple_subscript(self): - source = 'a[1]\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Subscript', ['Name', '', '[', '', 'Index', '', ']']) - checker.check_children('Index', ['Num']) - - def test_tuple_node(self): - source = '(1, 2)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Tuple', ['(', '', 'Num', '', ',', ' ', 'Num', '', ')']) - - def test_tuple_node2(self): - source = '#(\n1, 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children('Tuple', ['Num', '', ',', ' ', 'Num']) - - def test_one_item_tuple_node(self): - source = '(1,)\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children('Tuple', ['(', '', 'Num', ',', ')']) - - def test_empty_tuple_node(self): - source = '()\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children('Tuple', ['(', '', ')']) - - def test_yield_node(self): - source = 'def f():\n yield None\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children('Yield', ['yield', ' ', 'Name']) - - def test_while_node(self): - source = 'while True:\n pass\nelse:\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'While', ['while', ' ', 'Name', '', ':', '\n ', 'Pass', '\n', - 'else', '', ':', '\n ', 'Pass']) - - @testutils.run_only_for_25 - def test_with_node(self): - source = 'from __future__ import with_statement\nwith a as b:\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'With', ['with', ' ', 'Name', ' ', 'as', ' ', 'Name', '', ':', - '\n ', 'Pass']) - - def test_try_finally_node(self): - source = 'try:\n pass\nfinally:\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'TryFinally', ['try', '', ':', '\n ', 'Pass', '\n', 'finally', - '', ':', '\n ', 'Pass']) - - def test_try_except_node(self): - source = 'try:\n pass\nexcept Exception, e:\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'TryExcept', ['try', '', ':', '\n ', 'Pass', '\n', - ('excepthandler', 'ExceptHandler')]) - checker.check_children( - ('excepthandler', 'ExceptHandler'), - ['except', ' ', 'Name', '', ',', ' ', 'Name', '', ':', - '\n ', 'Pass']) - - @testutils.run_only_for_25 - def test_try_except_and_finally_node(self): - source = 'try:\n pass\nexcept:\n pass\nfinally:\n pass\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'TryFinally', ['TryExcept', '\n', 'finally', - '', ':', '\n ', 'Pass']) - - def test_ignoring_comments(self): - source = '#1\n1\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - start = source.rindex('1') - checker.check_region('Num', start, start + 1) - - def test_simple_sliceobj(self): - source = 'a[1::3]\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Slice', ['Num', '', ':', '', ':', '', 'Num']) - - def test_ignoring_strings_that_start_with_a_char(self): - source = 'r"""("""\n1\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Module', ['', 'Expr', '\n', 'Expr', '\n']) - - def test_how_to_handle_old_not_equals(self): - source = '1 <> 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Compare', ['Num', ' ', '<>', ' ', 'Num']) - - def test_semicolon(self): - source = '1;\n' - ast = patchedast.get_patched_ast(source, True) - - @testutils.run_only_for_25 - def test_if_exp_node(self): - source = '1 if True else 2\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'IfExp', ['Num', ' ', 'if', ' ', 'Name', ' ', 'else', - ' ', 'Num']) - - def test_delete_node(self): - source = 'del a, b\n' - ast = patchedast.get_patched_ast(source, True) - checker = _ResultChecker(self, ast) - checker.check_children( - 'Delete', ['del', ' ', 'Name', '', ',', ' ', 'Name']) - - -class _ResultChecker(object): - - def __init__(self, test_case, ast): - self.test_case = test_case - self.ast = ast - - def check_region(self, text, start, end): - node = self._find_node(text) - if node is None: - self.test_case.fail('Node <%s> cannot be found' % text) - self.test_case.assertEquals((start, end), node.region) - - def _find_node(self, text): - goal = text - if not isinstance(text, (tuple, list)): - goal = [text] - class Search(object): - result = None - def __call__(self, node): - for text in goal: - if str(node).startswith(text): - self.result = node - break - if node.__class__.__name__.startswith(text): - self.result = node - break - return self.result is not None - search = Search() - ast.call_for_nodes(self.ast, search, recursive=True) - return search.result - - def check_children(self, text, children): - node = self._find_node(text) - if node is None: - self.test_case.fail('Node <%s> cannot be found' % text) - result = list(node.sorted_children) - self.test_case.assertEquals(len(children), len(result)) - for expected, child in zip(children, result): - goals = expected - if not isinstance(expected, (tuple, list)): - goals = [expected] - for goal in goals: - if goal == '' or isinstance(child, basestring): - self.test_case.assertEquals(goal, child) - break - else: - self.test_case.assertNotEquals( - '', text, 'probably ignoring some node') - self.test_case.assertTrue( - child.__class__.__name__.startswith(expected), - msg='Expected <%s> but was <%s>' % - (expected, child.__class__.__name__)) - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/renametest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/renametest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,676 +0,0 @@ -import sys -import unittest - -import rope.base.codeanalyze -import rope.refactor.occurrences -from rope.refactor import rename -from rope.refactor.rename import Rename -from ropetest import testutils - - -class RenameRefactoringTest(unittest.TestCase): - - def setUp(self): - super(RenameRefactoringTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - - def tearDown(self): - testutils.remove_project(self.project) - super(RenameRefactoringTest, self).tearDown() - - def _local_rename(self, source_code, offset, new_name): - testmod = testutils.create_module(self.project, 'testmod') - testmod.write(source_code) - changes = Rename(self.project, testmod, offset).\ - get_changes(new_name, resources=[testmod]) - self.project.do(changes) - return testmod.read() - - def _rename(self, resource, offset, new_name, **kwds): - changes = Rename(self.project, resource, offset).\ - get_changes(new_name, **kwds) - self.project.do(changes) - - def test_simple_global_variable_renaming(self): - refactored = self._local_rename('a_var = 20\n', 2, 'new_var') - self.assertEquals('new_var = 20\n', refactored) - - def test_variable_renaming_only_in_its_scope(self): - refactored = self._local_rename( - 'a_var = 20\ndef a_func():\n a_var = 10\n', 32, 'new_var') - self.assertEquals('a_var = 20\ndef a_func():\n new_var = 10\n', - refactored) - - def test_not_renaming_dot_name(self): - refactored = self._local_rename( - "replace = True\n'aaa'.replace('a', 'b')\n", 1, 'new_var') - self.assertEquals("new_var = True\n'aaa'.replace('a', 'b')\n", - refactored) - - def test_renaming_multiple_names_in_the_same_line(self): - refactored = self._local_rename( - 'a_var = 10\na_var = 10 + a_var / 2\n', 2, 'new_var') - self.assertEquals('new_var = 10\nnew_var = 10 + new_var / 2\n', - refactored) - - def test_renaming_names_when_getting_some_attribute(self): - refactored = self._local_rename( - "a_var = 'a b c'\na_var.split('\\n')\n", 2, 'new_var') - self.assertEquals("new_var = 'a b c'\nnew_var.split('\\n')\n", - refactored) - - def test_renaming_names_when_getting_some_attribute2(self): - refactored = self._local_rename( - "a_var = 'a b c'\na_var.split('\\n')\n", 20, 'new_var') - self.assertEquals("new_var = 'a b c'\nnew_var.split('\\n')\n", - refactored) - - def test_renaming_function_parameters1(self): - refactored = self._local_rename( - "def f(a_param):\n print(a_param)\n", 8, 'new_param') - self.assertEquals("def f(new_param):\n print(new_param)\n", - refactored) - - def test_renaming_function_parameters2(self): - refactored = self._local_rename( - "def f(a_param):\n print(a_param)\n", 30, 'new_param') - self.assertEquals("def f(new_param):\n print(new_param)\n", - refactored) - - def test_renaming_occurrences_inside_functions(self): - code = 'def a_func(p1):\n a = p1\na_func(1)\n' - refactored = self._local_rename(code, code.index('p1') + 1, 'new_param') - self.assertEquals( - 'def a_func(new_param):\n a = new_param\na_func(1)\n', - refactored) - - def test_renaming_arguments_for_normal_args_changing_calls(self): - code = 'def a_func(p1=None, p2=None):\n pass\na_func(p2=1)\n' - refactored = self._local_rename(code, code.index('p2') + 1, 'p3') - self.assertEquals( - 'def a_func(p1=None, p3=None):\n pass\na_func(p3=1)\n', - refactored) - - def test_renaming_function_parameters_of_class_init(self): - code = 'class A(object):\n def __init__(self, a_param):\n pass\n' \ - 'a_var = A(a_param=1)\n' - refactored = self._local_rename(code, code.index('a_param') + 1, 'new_param') - expected = 'class A(object):\n def __init__(self, new_param):\n pass\n' \ - 'a_var = A(new_param=1)\n' - self.assertEquals(expected, refactored) - - def test_renaming_functions_parameters_and_occurances_in_other_modules(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('def a_func(a_param):\n print(a_param)\n') - mod2.write('from mod1 import a_func\na_func(a_param=10)\n') - self._rename(mod1, mod1.read().index('a_param') + 1, 'new_param') - self.assertEquals('def a_func(new_param):\n print(new_param)\n', - mod1.read()) - self.assertEquals('from mod1 import a_func\na_func(new_param=10)\n', - mod2.read()) - - def test_renaming_with_backslash_continued_names(self): - refactored = self._local_rename( - "replace = True\n'ali'.\\\nreplace\n", 2, 'is_replace') - self.assertEquals("is_replace = True\n'ali'.\\\nreplace\n", - refactored) - - def test_not_renaming_string_contents(self): - refactored = self._local_rename("a_var = 20\na_string='a_var'\n", - 2, 'new_var') - self.assertEquals("new_var = 20\na_string='a_var'\n", - refactored) - - def test_not_renaming_comment_contents(self): - refactored = self._local_rename("a_var = 20\n# a_var\n", - 2, 'new_var') - self.assertEquals("new_var = 20\n# a_var\n", refactored) - - def test_renaming_all_occurances_in_containing_scope(self): - code = 'if True:\n a_var = 1\nelse:\n a_var = 20\n' - refactored = self._local_rename(code, 16, 'new_var') - self.assertEquals( - 'if True:\n new_var = 1\nelse:\n new_var = 20\n', refactored) - - def test_renaming_a_variable_with_arguement_name(self): - code = 'a_var = 10\ndef a_func(a_var):\n print(a_var)\n' - refactored = self._local_rename(code, 1, 'new_var') - self.assertEquals( - 'new_var = 10\ndef a_func(a_var):\n print(a_var)\n', refactored) - - def test_renaming_an_arguement_with_variable_name(self): - code = 'a_var = 10\ndef a_func(a_var):\n print(a_var)\n' - refactored = self._local_rename(code, len(code) - 3, 'new_var') - self.assertEquals( - 'a_var = 10\ndef a_func(new_var):\n print(new_var)\n', - refactored) - - def test_renaming_function_with_local_variable_name(self): - code = 'def a_func():\n a_func=20\na_func()' - refactored = self._local_rename(code, len(code) - 3, 'new_func') - self.assertEquals('def new_func():\n a_func=20\nnew_func()', - refactored) - - def test_renaming_functions(self): - code = 'def a_func():\n pass\na_func()\n' - refactored = self._local_rename(code, len(code) - 5, 'new_func') - self.assertEquals('def new_func():\n pass\nnew_func()\n', - refactored) - - def test_renaming_functions_across_modules(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('def a_func():\n pass\na_func()\n') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('import mod1\nmod1.a_func()\n') - self._rename(mod1, len(mod1.read()) - 5, 'new_func') - self.assertEquals('def new_func():\n pass\nnew_func()\n', - mod1.read()) - self.assertEquals('import mod1\nmod1.new_func()\n', mod2.read()) - - def test_renaming_functions_across_modules_from_import(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('def a_func():\n pass\na_func()\n') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('from mod1 import a_func\na_func()\n') - self._rename(mod1, len(mod1.read()) - 5, 'new_func') - self.assertEquals('def new_func():\n pass\nnew_func()\n', - mod1.read()) - self.assertEquals('from mod1 import new_func\nnew_func()\n', - mod2.read()) - - def test_renaming_functions_from_another_module(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('def a_func():\n pass\na_func()\n') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('import mod1\nmod1.a_func()\n') - self._rename(mod2, len(mod2.read()) - 5, 'new_func') - self.assertEquals('def new_func():\n pass\nnew_func()\n', - mod1.read()) - self.assertEquals('import mod1\nmod1.new_func()\n', mod2.read()) - - def test_applying_all_changes_together(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('import mod2\nmod2.a_func()\n') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('def a_func():\n pass\na_func()\n') - self._rename(mod2, len(mod2.read()) - 5, 'new_func') - self.assertEquals('import mod2\nmod2.new_func()\n', mod1.read()) - self.assertEquals('def new_func():\n pass\nnew_func()\n', - mod2.read()) - - def test_renaming_modules(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('def a_func():\n pass\n') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('from mod1 import a_func\n') - self._rename(mod2, mod2.read().index('mod1') + 1, 'newmod') - self.assertTrue(not mod1.exists() and - self.pycore.find_module('newmod') is not None) - self.assertEquals('from newmod import a_func\n', mod2.read()) - - def test_renaming_packages(self): - pkg = testutils.create_package(self.project, 'pkg') - mod1 = testutils.create_module(self.project, 'mod1', pkg) - mod1.write('def a_func():\n pass\n') - mod2 = testutils.create_module(self.project, 'mod2', pkg) - mod2.write('from pkg.mod1 import a_func\n') - self._rename(mod2, 6, 'newpkg') - self.assertTrue(self.pycore.find_module('newpkg.mod1') is not None) - new_mod2 = self.pycore.find_module('newpkg.mod2') - self.assertEquals('from newpkg.mod1 import a_func\n', new_mod2.read()) - - def test_module_dependencies(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('class AClass(object):\n pass\n') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('import mod1\na_var = mod1.AClass()\n') - self.pycore.resource_to_pyobject(mod2).get_attributes()['mod1'] - mod1.write('def AClass():\n return 0\n') - - self._rename(mod2, len(mod2.read()) - 3, 'a_func') - self.assertEquals('def a_func():\n return 0\n', mod1.read()) - self.assertEquals('import mod1\na_var = mod1.a_func()\n', mod2.read()) - - def test_renaming_class_attributes(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('class AClass(object):\n def __init__(self):\n' - ' self.an_attr = 10\n') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('import mod1\na_var = mod1.AClass()\n' - 'another_var = a_var.an_attr') - - self._rename(mod1, mod1.read().index('an_attr'), 'attr') - self.assertEquals('class AClass(object):\n def __init__(self):\n' - ' self.attr = 10\n', mod1.read()) - self.assertEquals( - 'import mod1\na_var = mod1.AClass()\nanother_var = a_var.attr', - mod2.read()) - - def test_renaming_class_attributes2(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('class AClass(object):\n def __init__(self):\n' - ' an_attr = 10\n self.an_attr = 10\n') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('import mod1\na_var = mod1.AClass()\n' - 'another_var = a_var.an_attr') - - self._rename(mod1, mod1.read().rindex('an_attr'), 'attr') - self.assertEquals( - 'class AClass(object):\n def __init__(self):\n' - ' an_attr = 10\n self.attr = 10\n', mod1.read()) - self.assertEquals( - 'import mod1\na_var = mod1.AClass()\nanother_var = a_var.attr', - mod2.read()) - - def test_renaming_methods_in_subclasses(self): - mod = testutils.create_module(self.project, 'mod1') - mod.write('class A(object):\n def a_method(self):\n pass\n' - 'class B(A):\n def a_method(self):\n pass\n') - - self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method', - in_hierarchy=True) - self.assertEquals( - 'class A(object):\n def new_method(self):\n pass\n' - 'class B(A):\n def new_method(self):\n pass\n', mod.read()) - - def test_renaming_methods_in_sibling_classes(self): - mod = testutils.create_module(self.project, 'mod1') - mod.write('class A(object):\n def a_method(self):\n pass\n' - 'class B(A):\n def a_method(self):\n pass\n' - 'class C(A):\n def a_method(self):\n pass\n') - - self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method', - in_hierarchy=True) - self.assertEquals( - 'class A(object):\n def new_method(self):\n pass\n' - 'class B(A):\n def new_method(self):\n pass\n' - 'class C(A):\n def new_method(self):\n pass\n', mod.read()) - - def test_not_renaming_methods_in_hierarchies(self): - mod = testutils.create_module(self.project, 'mod1') - mod.write('class A(object):\n def a_method(self):\n pass\n' - 'class B(A):\n def a_method(self):\n pass\n') - - self._rename(mod, mod.read().rindex('a_method') + 1, 'new_method', - in_hierarchy=False) - self.assertEquals( - 'class A(object):\n def a_method(self):\n pass\n' - 'class B(A):\n def new_method(self):\n pass\n', mod.read()) - - def test_undoing_refactorings(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('def a_func():\n pass\na_func()\n') - self._rename(mod1, len(mod1.read()) - 5, 'new_func') - self.project.history.undo() - self.assertEquals('def a_func():\n pass\na_func()\n', mod1.read()) - - def test_undoing_renaming_modules(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('def a_func():\n pass\n') - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('from mod1 import a_func\n') - self._rename(mod2, 6, 'newmod') - self.project.history.undo() - self.assertEquals('mod1.py', mod1.path) - self.assertEquals('from mod1 import a_func\n', mod2.read()) - - def test_rename_in_module_renaming_one_letter_names_for_expressions(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write('a = 10\nprint(1+a)\n') - pymod = self.pycore.get_module('mod1') - old_pyname = pymod['a'] - finder = rope.refactor.occurrences.create_finder( - self.pycore, 'a', old_pyname) - refactored = rename.rename_in_module( - finder, 'new_var', pymodule=pymod, replace_primary=True) - self.assertEquals('new_var = 10\nprint(1+new_var)\n', refactored) - - def test_renaming_for_loop_variable(self): - code = 'for var in range(10):\n print(var)\n' - refactored = self._local_rename(code, code.find('var') + 1, 'new_var') - self.assertEquals('for new_var in range(10):\n print(new_var)\n', - refactored) - - def test_renaming_parameters(self): - code = 'def a_func(param):\n print(param)\na_func(param=hey)\n' - refactored = self._local_rename(code, code.find('param') + 1, - 'new_param') - self.assertEquals('def a_func(new_param):\n print(new_param)\n' - 'a_func(new_param=hey)\n', refactored) - - def test_renaming_assigned_parameters(self): - code = 'def f(p):\n p = p + 1\n return p\nf(p=1)\n' - refactored = self._local_rename(code, code.find('p'), 'arg') - self.assertEquals('def f(arg):\n arg = arg + 1\n' - ' return arg\nf(arg=1)\n', refactored) - - def test_renaming_parameters_not_renaming_others(self): - code = 'def a_func(param):\n print(param)\nparam=10\na_func(param)\n' - refactored = self._local_rename(code, code.find('param') + 1, 'new_param') - self.assertEquals('def a_func(new_param):\n print(new_param)\n' - 'param=10\na_func(param)\n', refactored) - - def test_renaming_parameters_not_renaming_others2(self): - code = 'def a_func(param):\n print(param)\nparam=10\na_func(param=param)' - refactored = self._local_rename(code, code.find('param') + 1, 'new_param') - self.assertEquals('def a_func(new_param):\n print(new_param)\n' - 'param=10\na_func(new_param=param)', refactored) - - def test_renaming_parameters_with_multiple_params(self): - code = 'def a_func(param1, param2):\n print(param1)\n'\ - 'a_func(param1=1, param2=2)\n' - refactored = self._local_rename(code, code.find('param1') + 1, 'new_param') - self.assertEquals( - 'def a_func(new_param, param2):\n print(new_param)\n' - 'a_func(new_param=1, param2=2)\n', refactored) - - def test_renaming_parameters_with_multiple_params2(self): - code = 'def a_func(param1, param2):\n print(param1)\n' \ - 'a_func(param1=1, param2=2)\n' - refactored = self._local_rename(code, code.rfind('param2') + 1, - 'new_param') - self.assertEquals('def a_func(param1, new_param):\n print(param1)\n' - 'a_func(param1=1, new_param=2)\n', refactored) - - def test_renaming_parameters_on_calls(self): - code = 'def a_func(param):\n print(param)\na_func(param = hey)\n' - refactored = self._local_rename(code, code.rfind('param') + 1, - 'new_param') - self.assertEquals('def a_func(new_param):\n print(new_param)\n' - 'a_func(new_param = hey)\n', refactored) - - def test_renaming_parameters_spaces_before_call(self): - code = 'def a_func(param):\n print(param)\na_func (param=hey)\n' - refactored = self._local_rename(code, code.rfind('param') + 1, - 'new_param') - self.assertEquals('def a_func(new_param):\n print(new_param)\n' - 'a_func (new_param=hey)\n', refactored) - - def test_renaming_parameter_like_objects_after_keywords(self): - code = 'def a_func(param):\n print(param)\ndict(param=hey)\n' - refactored = self._local_rename(code, code.find('param') + 1, 'new_param') - self.assertEquals('def a_func(new_param):\n print(new_param)\n' - 'dict(param=hey)\n', refactored) - - def test_renaming_variables_in_init_dot_pys(self): - pkg = testutils.create_package(self.project, 'pkg') - init_dot_py = pkg.get_child('__init__.py') - init_dot_py.write('a_var = 10\n') - mod = testutils.create_module(self.project, 'mod') - mod.write('import pkg\nprint(pkg.a_var)\n') - self._rename(mod, mod.read().index('a_var') + 1, 'new_var') - self.assertEquals('new_var = 10\n', init_dot_py.read()) - self.assertEquals('import pkg\nprint(pkg.new_var)\n', mod.read()) - - def test_renaming_variables_in_init_dot_pys2(self): - pkg = testutils.create_package(self.project, 'pkg') - init_dot_py = pkg.get_child('__init__.py') - init_dot_py.write('a_var = 10\n') - mod = testutils.create_module(self.project, 'mod') - mod.write('import pkg\nprint(pkg.a_var)\n') - self._rename(init_dot_py, - init_dot_py.read().index('a_var') + 1, 'new_var') - self.assertEquals('new_var = 10\n', init_dot_py.read()) - self.assertEquals('import pkg\nprint(pkg.new_var)\n', mod.read()) - - def test_renaming_variables_in_init_dot_pys3(self): - pkg = testutils.create_package(self.project, 'pkg') - init_dot_py = pkg.get_child('__init__.py') - init_dot_py.write('a_var = 10\n') - mod = testutils.create_module(self.project, 'mod') - mod.write('import pkg\nprint(pkg.a_var)\n') - self._rename(mod, mod.read().index('a_var') + 1, 'new_var') - self.assertEquals('new_var = 10\n', init_dot_py.read()) - self.assertEquals('import pkg\nprint(pkg.new_var)\n', mod.read()) - - def test_renaming_resources_using_rename_module_refactoring(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('a_var = 1') - mod2.write('import mod1\nmy_var = mod1.a_var\n') - renamer = rename.Rename(self.project, mod1) - renamer.get_changes('newmod').do() - self.assertEquals('import newmod\nmy_var = newmod.a_var\n', mod2.read()) - - def test_renaming_resources_using_rename_module_refactoring_for_packages(self): - mod1 = testutils.create_module(self.project, 'mod1') - pkg = testutils.create_package(self.project, 'pkg') - mod1.write('import pkg\nmy_pkg = pkg') - renamer = rename.Rename(self.project, pkg) - renamer.get_changes('newpkg').do() - self.assertEquals('import newpkg\nmy_pkg = newpkg', mod1.read()) - - def test_renaming_resources_using_rename_module_refactoring_for_init_dot_py(self): - mod1 = testutils.create_module(self.project, 'mod1') - pkg = testutils.create_package(self.project, 'pkg') - mod1.write('import pkg\nmy_pkg = pkg') - renamer = rename.Rename(self.project, pkg.get_child('__init__.py')) - renamer.get_changes('newpkg').do() - self.assertEquals('import newpkg\nmy_pkg = newpkg', mod1.read()) - - def test_renaming_global_variables(self): - code = 'a_var = 1\ndef a_func():\n global a_var\n var = a_var\n' - refactored = self._local_rename(code, code.index('a_var'), 'new_var') - self.assertEquals( - 'new_var = 1\ndef a_func():\n global new_var\n var = new_var\n', - refactored) - - def test_renaming_global_variables2(self): - code = 'a_var = 1\ndef a_func():\n global a_var\n var = a_var\n' - refactored = self._local_rename(code, code.rindex('a_var'), 'new_var') - self.assertEquals( - 'new_var = 1\ndef a_func():\n global new_var\n var = new_var\n', - refactored) - - def test_renaming_when_unsure(self): - code = 'class C(object):\n def a_func(self):\n pass\n' \ - 'def f(arg):\n arg.a_func()\n' - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write(code) - self._rename(mod1, code.index('a_func'), - 'new_func', unsure=self._true) - self.assertEquals( - 'class C(object):\n def new_func(self):\n pass\n' \ - 'def f(arg):\n arg.new_func()\n', - mod1.read()) - - def _true(self, *args): - return True - - def test_renaming_when_unsure_with_confirmation(self): - def confirm(occurrence): - return False - code = 'class C(object):\n def a_func(self):\n pass\n' \ - 'def f(arg):\n arg.a_func()\n' - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write(code) - self._rename(mod1, code.index('a_func'), 'new_func', unsure=confirm) - self.assertEquals( - 'class C(object):\n def new_func(self):\n pass\n' \ - 'def f(arg):\n arg.a_func()\n', mod1.read()) - - def test_renaming_when_unsure_not_renaming_knowns(self): - code = 'class C1(object):\n def a_func(self):\n pass\n' \ - 'class C2(object):\n def a_func(self):\n pass\n' \ - 'c1 = C1()\nc1.a_func()\nc2 = C2()\nc2.a_func()\n' - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write(code) - self._rename(mod1, code.index('a_func'), 'new_func', unsure=self._true) - self.assertEquals( - 'class C1(object):\n def new_func(self):\n pass\n' \ - 'class C2(object):\n def a_func(self):\n pass\n' \ - 'c1 = C1()\nc1.new_func()\nc2 = C2()\nc2.a_func()\n', - mod1.read()) - - def test_renaming_in_strings_and_comments(self): - code = 'a_var = 1\n# a_var\n' - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write(code) - self._rename(mod1, code.index('a_var'), 'new_var', docs=True) - self.assertEquals('new_var = 1\n# new_var\n', mod1.read()) - - def test_not_renaming_in_strings_and_comments_where_not_visible(self): - code = 'def f():\n a_var = 1\n# a_var\n' - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write(code) - self._rename(mod1, code.index('a_var'), 'new_var', docs=True) - self.assertEquals('def f():\n new_var = 1\n# a_var\n', mod1.read()) - - def test_not_renaming_all_text_occurrences_in_strings_and_comments(self): - code = 'a_var = 1\n# a_vard _a_var\n' - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write(code) - self._rename(mod1, code.index('a_var'), 'new_var', docs=True) - self.assertEquals('new_var = 1\n# a_vard _a_var\n', mod1.read()) - - def test_renaming_occurrences_in_overwritten_scopes(self): - refactored = self._local_rename( - 'a_var = 20\ndef f():\n print(a_var)\n' - 'def f():\n print(a_var)\n', 2, 'new_var') - self.assertEquals('new_var = 20\ndef f():\n print(new_var)\n' - 'def f():\n print(new_var)\n', refactored) - - def test_renaming_occurrences_in_overwritten_scopes2(self): - code = 'def f():\n a_var = 1\n print(a_var)\n' \ - 'def f():\n a_var = 1\n print(a_var)\n' - refactored = self._local_rename(code, code.index('a_var') + 1, 'new_var') - self.assertEquals(code.replace('a_var', 'new_var', 2), refactored) - - def test_dos_line_ending_and_renaming(self): - code = '\r\na = 1\r\n\r\nprint(2 + a + 2)\r\n' - offset = code.replace('\r\n', '\n').rindex('a') - refactored = self._local_rename(code, offset, 'b') - self.assertEquals('\nb = 1\n\nprint(2 + b + 2)\n', - refactored.replace('\r\n', '\n')) - - def test_multi_byte_strs_and_renaming(self): - s = u'{LATIN SMALL LETTER I WITH DIAERESIS}' * 4 - code = u'# -*- coding: utf-8 -*-\n# ' + s + \ - '\na = 1\nprint(2 + a + 2)\n' - refactored = self._local_rename(code, code.rindex('a'), 'b') - self.assertEquals(u'# -*- coding: utf-8 -*-\n# ' + s + - '\nb = 1\nprint(2 + b + 2)\n', refactored) - - def test_resources_parameter(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('def f():\n pass\n') - mod2.write('import mod1\nmod1.f()\n') - self._rename(mod1, mod1.read().rindex('f'), 'g', - resources=[mod1]) - self.assertEquals('def g():\n pass\n', mod1.read()) - self.assertEquals('import mod1\nmod1.f()\n', mod2.read()) - - def test_resources_parameter_not_changing_defining_module(self): - mod1 = testutils.create_module(self.project, 'mod1') - mod2 = testutils.create_module(self.project, 'mod2') - mod1.write('def f():\n pass\n') - mod2.write('import mod1\nmod1.f()\n') - self._rename(mod1, mod1.read().rindex('f'), 'g', - resources=[mod2]) - self.assertEquals('def f():\n pass\n', mod1.read()) - self.assertEquals('import mod1\nmod1.g()\n', mod2.read()) - - # XXX: with variables should not leak - @testutils.only_for('2.5') - def xxx_test_with_statement_variables_should_not_leak(self): - code = 'f = 1\nwith open("1.txt") as f:\n print(f)\n' - if sys.version_info < (2, 6, 0): - code = 'from __future__ import with_statement\n' + code - mod1 = testutils.create_module(self.project, 'mod1') - mod1.write(code) - self._rename(mod1, code.rindex('f'), 'file') - expected = 'f = 1\nwith open("1.txt") as file:\n print(file)\n' - self.assertEquals(expected, mod1.read()) - - -class ChangeOccurrencesTest(unittest.TestCase): - - def setUp(self): - self.project = testutils.sample_project() - self.mod = testutils.create_module(self.project, 'mod') - - def tearDown(self): - testutils.remove_project(self.project) - super(ChangeOccurrencesTest, self).tearDown() - - def test_simple_case(self): - self.mod.write('a_var = 1\nprint(a_var)\n') - changer = rename.ChangeOccurrences(self.project, self.mod, - self.mod.read().index('a_var')) - changer.get_changes('new_var').do() - self.assertEquals('new_var = 1\nprint(new_var)\n', self.mod.read()) - - def test_only_performing_inside_scopes(self): - self.mod.write('a_var = 1\nnew_var = 2\ndef f():\n print(a_var)\n') - changer = rename.ChangeOccurrences(self.project, self.mod, - self.mod.read().rindex('a_var')) - changer.get_changes('new_var').do() - self.assertEquals( - 'a_var = 1\nnew_var = 2\ndef f():\n print(new_var)\n', - self.mod.read()) - - def test_only_performing_on_calls(self): - self.mod.write('def f1():\n pass\ndef f2():\n pass\n' - 'g = f1\na = f1()\n') - changer = rename.ChangeOccurrences(self.project, self.mod, - self.mod.read().rindex('f1')) - changer.get_changes('f2', only_calls=True).do() - self.assertEquals( - 'def f1():\n pass\ndef f2():\n pass\ng = f1\na = f2()\n', - self.mod.read()) - - def test_only_performing_on_reads(self): - self.mod.write('a = 1\nb = 2\nprint(a)\n') - changer = rename.ChangeOccurrences(self.project, self.mod, - self.mod.read().rindex('a')) - changer.get_changes('b', writes=False).do() - self.assertEquals('a = 1\nb = 2\nprint(b)\n', self.mod.read()) - - -class ImplicitInterfacesTest(unittest.TestCase): - - def setUp(self): - super(ImplicitInterfacesTest, self).setUp() - self.project = testutils.sample_project(validate_objectdb=True) - self.pycore = self.project.pycore - self.mod1 = testutils.create_module(self.project, 'mod1') - self.mod2 = testutils.create_module(self.project, 'mod2') - - def tearDown(self): - testutils.remove_project(self.project) - super(ImplicitInterfacesTest, self).tearDown() - - def _rename(self, resource, offset, new_name, **kwds): - changes = Rename(self.project, resource, offset).\ - get_changes(new_name, **kwds) - self.project.do(changes) - - def test_performing_rename_on_parameters(self): - self.mod1.write('def f(arg):\n arg.run()\n') - self.mod2.write('import mod1\n\n\n' - 'class A(object):\n def run(self):\n pass\n' - 'class B(object):\n def run(self):\n pass\n' - 'mod1.f(A())\nmod1.f(B())\n') - self.pycore.analyze_module(self.mod2) - self._rename(self.mod1, self.mod1.read().index('run'), 'newrun') - self.assertEquals('def f(arg):\n arg.newrun()\n', self.mod1.read()) - self.assertEquals( - 'import mod1\n\n\n' - 'class A(object):\n def newrun(self):\n pass\n' - 'class B(object):\n def newrun(self):\n pass\n' - 'mod1.f(A())\nmod1.f(B())\n', self.mod2.read()) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(RenameRefactoringTest)) - result.addTests(unittest.makeSuite(ChangeOccurrencesTest)) - result.addTests(unittest.makeSuite(ImplicitInterfacesTest)) - return result - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/restructuretest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/restructuretest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -from rope.refactor import restructure -from ropetest import testutils - -import unittest - - -class RestructureTest(unittest.TestCase): - - def setUp(self): - super(RestructureTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod = testutils.create_module(self.project, 'mod') - - def tearDown(self): - testutils.remove_project(self.project) - super(RestructureTest, self).tearDown() - - def test_trivial_case(self): - refactoring = restructure.Restructure(self.project, - 'a = 1', 'a = 0') - self.mod.write('b = 1\n') - self.project.do(refactoring.get_changes()) - self.assertEquals('b = 1\n', self.mod.read()) - - def test_replacing_simple_patterns(self): - refactoring = restructure.Restructure(self.project, - 'a = 1', 'a = int(1)') - self.mod.write('a = 1\nb = 1\n') - self.project.do(refactoring.get_changes()) - self.assertEquals('a = int(1)\nb = 1\n', self.mod.read()) - - def test_replacing_patterns_with_normal_names(self): - refactoring = restructure.Restructure( - self.project, '${a} = 1', '${a} = int(1)', args={'a': 'exact'}) - self.mod.write('a = 1\nb = 1\n') - self.project.do(refactoring.get_changes()) - self.assertEquals('a = int(1)\nb = 1\n', self.mod.read()) - - def test_replacing_patterns_with_any_names(self): - refactoring = restructure.Restructure(self.project, - '${a} = 1', '${a} = int(1)') - self.mod.write('a = 1\nb = 1\n') - self.project.do(refactoring.get_changes()) - self.assertEquals('a = int(1)\nb = int(1)\n', self.mod.read()) - - def test_replacing_patterns_with_any_names2(self): - refactoring = restructure.Restructure( - self.project, '${x} + ${x}', '${x} * 2') - self.mod.write('a = 1 + 1\n') - self.project.do(refactoring.get_changes()) - self.assertEquals('a = 1 * 2\n', self.mod.read()) - - def test_replacing_patterns_with_checks(self): - self.mod.write('def f(p=1):\n return p\ng = f\ng()\n') - refactoring = restructure.Restructure( - self.project, '${f}()', '${f}(2)', args={'f': 'object=mod.f'}) - self.project.do(refactoring.get_changes()) - self.assertEquals('def f(p=1):\n return p\ng = f\ng(2)\n', - self.mod.read()) - - def test_replacing_assignments_with_sets(self): - refactoring = restructure.Restructure( - self.project, '${a} = ${b}', '${a}.set(${b})') - self.mod.write('a = 1\nb = 1\n') - self.project.do(refactoring.get_changes()) - self.assertEquals('a.set(1)\nb.set(1)\n', self.mod.read()) - - def test_replacing_sets_with_assignments(self): - refactoring = restructure.Restructure( - self.project, '${a}.set(${b})', '${a} = ${b}') - self.mod.write('a.set(1)\nb.set(1)\n') - self.project.do(refactoring.get_changes()) - self.assertEquals('a = 1\nb = 1\n', self.mod.read()) - - def test_using_make_checks(self): - self.mod.write('def f(p=1):\n return p\ng = f\ng()\n') - refactoring = restructure.Restructure( - self.project, '${f}()', '${f}(2)', args={'f': 'object=mod.f'}) - self.project.do(refactoring.get_changes()) - self.assertEquals('def f(p=1):\n return p\ng = f\ng(2)\n', - self.mod.read()) - - def test_using_make_checking_builtin_types(self): - self.mod.write('a = 1 + 1\n') - refactoring = restructure.Restructure( - self.project, '${i} + ${i}', '${i} * 2', - args={'i': 'type=__builtin__.int'}) - self.project.do(refactoring.get_changes()) - self.assertEquals('a = 1 * 2\n', self.mod.read()) - - def test_auto_indentation_when_no_indentation(self): - self.mod.write('a = 2\n') - refactoring = restructure.Restructure( - self.project, '${a} = 2', '${a} = 1\n${a} += 1') - self.project.do(refactoring.get_changes()) - self.assertEquals('a = 1\na += 1\n', self.mod.read()) - - def test_auto_indentation(self): - self.mod.write('def f():\n a = 2\n') - refactoring = restructure.Restructure( - self.project, '${a} = 2', '${a} = 1\n${a} += 1') - self.project.do(refactoring.get_changes()) - self.assertEquals('def f():\n a = 1\n a += 1\n', self.mod.read()) - - def test_auto_indentation_and_not_indenting_blanks(self): - self.mod.write('def f():\n a = 2\n') - refactoring = restructure.Restructure( - self.project, '${a} = 2', '${a} = 1\n\n${a} += 1') - self.project.do(refactoring.get_changes()) - self.assertEquals('def f():\n a = 1\n\n a += 1\n', - self.mod.read()) - - def test_importing_names(self): - self.mod.write('a = 2\n') - refactoring = restructure.Restructure( - self.project, '${a} = 2', '${a} = myconsts.two', - imports=['import myconsts']) - self.project.do(refactoring.get_changes()) - self.assertEquals('import myconsts\na = myconsts.two\n', - self.mod.read()) - - def test_not_importing_names_when_there_are_no_changes(self): - self.mod.write('a = True\n') - refactoring = restructure.Restructure( - self.project, '${a} = 2', '${a} = myconsts.two', - imports=['import myconsts']) - self.project.do(refactoring.get_changes()) - self.assertEquals('a = True\n', self.mod.read()) - - def test_handling_containing_matches(self): - self.mod.write('a = 1 / 2 / 3\n') - refactoring = restructure.Restructure( - self.project, '${a} / ${b}', '${a} // ${b}') - self.project.do(refactoring.get_changes()) - self.assertEquals('a = 1 // 2 // 3\n', self.mod.read()) - - def test_handling_overlapping_matches(self): - self.mod.write('a = 1\na = 1\na = 1\n') - refactoring = restructure.Restructure( - self.project, 'a = 1\na = 1\n', 'b = 1') - self.project.do(refactoring.get_changes()) - self.assertEquals('b = 1\na = 1\n', self.mod.read()) - - def test_preventing_stack_overflow_when_matching(self): - self.mod.write('1\n') - refactoring = restructure.Restructure(self.project, '${a}', '${a}') - self.project.do(refactoring.get_changes()) - self.assertEquals('1\n', self.mod.read()) - - def test_performing_a_restructuring_to_all_modules(self): - mod2 = testutils.create_module(self.project, 'mod2') - self.mod.write('a = 1\n') - mod2.write('b = 1\n') - refactoring = restructure.Restructure(self.project, '1', '2 / 1') - self.project.do(refactoring.get_changes()) - self.assertEquals('a = 2 / 1\n', self.mod.read()) - self.assertEquals('b = 2 / 1\n', mod2.read()) - - def test_performing_a_restructuring_to_selected_modules(self): - mod2 = testutils.create_module(self.project, 'mod2') - self.mod.write('a = 1\n') - mod2.write('b = 1\n') - refactoring = restructure.Restructure(self.project, '1', '2 / 1') - self.project.do(refactoring.get_changes(resources=[mod2])) - self.assertEquals('a = 1\n', self.mod.read()) - self.assertEquals('b = 2 / 1\n', mod2.read()) - - def test_unsure_argument_of_default_wildcard(self): - self.mod.write('def f(p):\n return p * 2\nx = "" * 2\ni = 1 * 2\n') - refactoring = restructure.Restructure( - self.project, '${s} * 2', 'dup(${s})', - args={'s': {'type': '__builtins__.str','unsure': True}}) - self.project.do(refactoring.get_changes()) - self.assertEquals('def f(p):\n return dup(p)\nx = dup("")\n' - 'i = 1 * 2\n', self.mod.read()) - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/similarfindertest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/similarfindertest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,284 +0,0 @@ -import unittest - -from rope.refactor import similarfinder -from ropetest import testutils - - -class SimilarFinderTest(unittest.TestCase): - - def setUp(self): - super(SimilarFinderTest, self).setUp() - self.project = testutils.sample_project() - self.mod = testutils.create_module(self.project, 'mod') - - def tearDown(self): - testutils.remove_project(self.project) - super(SimilarFinderTest, self).tearDown() - - def _create_finder(self, source, **kwds): - self.mod.write(source) - pymodule = self.project.pycore.resource_to_pyobject(self.mod) - return similarfinder.SimilarFinder(pymodule, **kwds) - - def test_trivial_case(self): - finder = self._create_finder('') - self.assertEquals([], list(finder.get_match_regions('10'))) - - def test_constant_integer(self): - source = 'a = 10\n' - finder = self._create_finder(source) - result = [(source.index('10'), source.index('10') + 2)] - self.assertEquals(result, list(finder.get_match_regions('10'))) - - def test_simple_addition(self): - source = 'a = 1 + 2\n' - finder = self._create_finder(source) - result = [(source.index('1'), source.index('2') + 1)] - self.assertEquals(result, list(finder.get_match_regions('1 + 2'))) - - def test_simple_addition2(self): - source = 'a = 1 +2\n' - finder = self._create_finder(source) - result = [(source.index('1'), source.index('2') + 1)] - self.assertEquals(result, list(finder.get_match_regions('1 + 2'))) - - def test_simple_assign_statements(self): - source = 'a = 1 + 2\n' - finder = self._create_finder(source) - self.assertEquals([(0, len(source) - 1)], - list(finder.get_match_regions('a = 1 + 2'))) - - def test_simple_multiline_statements(self): - source = 'a = 1\nb = 2\n' - finder = self._create_finder(source) - self.assertEquals([(0, len(source) - 1)], - list(finder.get_match_regions('a = 1\nb = 2'))) - - def test_multiple_matches(self): - source = 'a = 1 + 1\n' - finder = self._create_finder(source) - result = list(finder.get_match_regions('1')) - self.assertEquals(2, len(result)) - start1 = source.index('1') - self.assertEquals((start1, start1 + 1) , result[0]) - start2 = source.rindex('1') - self.assertEquals((start2, start2 + 1) , result[1]) - - def test_multiple_matches2(self): - source = 'a = 1\nb = 2\n\na = 1\nb = 2\n' - finder = self._create_finder(source) - self.assertEquals( - 2, len(list(finder.get_match_regions('a = 1\nb = 2')))) - - def test_restricting_the_region_to_search(self): - source = '1\n\n1\n' - finder = self._create_finder(source) - result = list(finder.get_match_regions('1', start=2)) - start = source.rfind('1') - self.assertEquals([(start, start + 1)], result) - - def test_matching_basic_patterns(self): - source = 'b = a\n' - finder = self._create_finder(source) - result = list(finder.get_match_regions('${a}', args={'a': 'exact'})) - start = source.rfind('a') - self.assertEquals([(start, start + 1)], result) - - def test_match_get_ast(self): - source = 'b = a\n' - finder = self._create_finder(source) - result = list(finder.get_matches('${a}', args={'a': 'exact'})) - self.assertEquals('a', result[0].get_ast('a').id) - - def test_match_get_ast_for_statements(self): - source = 'b = a\n' - finder = self._create_finder(source) - result = list(finder.get_matches('b = ${a}')) - self.assertEquals('a', result[0].get_ast('a').id) - - def test_matching_multiple_patterns(self): - source = 'c = a + b\n' - finder = self._create_finder(source) - result = list(finder.get_matches('${a} + ${b}')) - self.assertEquals('a', result[0].get_ast('a').id) - self.assertEquals('b', result[0].get_ast('b').id) - - def test_matching_any_patterns(self): - source = 'b = a\n' - finder = self._create_finder(source) - result = list(finder.get_matches('b = ${x}')) - self.assertEquals('a', result[0].get_ast('x').id) - - def test_matching_any_patterns_repeating(self): - source = 'b = 1 + 1\n' - finder = self._create_finder(source) - result = list(finder.get_matches('b = ${x} + ${x}')) - self.assertEquals(1, result[0].get_ast('x').n) - - def test_matching_any_patterns_not_matching_different_nodes(self): - source = 'b = 1 + 2\n' - finder = self._create_finder(source) - result = list(finder.get_matches('b = ${x} + ${x}')) - self.assertEquals(0, len(result)) - - def test_matching_normal_names_and_assname(self): - source = 'a = 1\n' - finder = self._create_finder(source) - result = list(finder.get_matches('${a} = 1')) - self.assertEquals('a', result[0].get_ast('a').id) - - def test_matching_normal_names_and_assname2(self): - source = 'a = 1\n' - finder = self._create_finder(source) - result = list(finder.get_matches('${a}', args={'a': 'exact'})) - self.assertEquals(1, len(result)) - - def test_matching_normal_names_and_attributes(self): - source = 'x.a = 1\n' - finder = self._create_finder(source) - result = list(finder.get_matches('${a} = 1', args={'a': 'exact'})) - self.assertEquals(0, len(result)) - - def test_functions_not_matching_when_only_first_parameters(self): - source = 'f(1, 2)\n' - finder = self._create_finder(source) - self.assertEquals(0, len(list(finder.get_matches('f(1)')))) - - def test_matching_nested_try_finally(self): - source = 'if 1:\n try:\n pass\n except:\n pass\n' - pattern = 'try:\n pass\nexcept:\n pass\n' - finder = self._create_finder(source) - self.assertEquals(1, len(list(finder.get_matches(pattern)))) - - def test_matching_dicts_inside_functions(self): - source = 'def f(p):\n d = {1: p.x}\n' - pattern = '{1: ${a}.x}' - finder = self._create_finder(source) - self.assertEquals(1, len(list(finder.get_matches(pattern)))) - - -class CheckingFinderTest(unittest.TestCase): - - def setUp(self): - super(CheckingFinderTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - self.mod1 = testutils.create_module(self.project, 'mod1') - - def tearDown(self): - testutils.remove_project(self.project) - super(CheckingFinderTest, self).tearDown() - - def test_trivial_case(self): - self.mod1.write('') - pymodule = self.pycore.resource_to_pyobject(self.mod1) - finder = similarfinder.SimilarFinder(pymodule) - self.assertEquals([], list(finder.get_matches('10', {}))) - - def test_simple_finding(self): - self.mod1.write('class A(object):\n pass\na = A()\n') - pymodule = self.pycore.resource_to_pyobject(self.mod1) - finder = similarfinder.SimilarFinder(pymodule) - result = list(finder.get_matches('${anything} = ${A}()', {})) - self.assertEquals(1, len(result)) - - def test_not_matching_when_the_name_does_not_match(self): - self.mod1.write('class A(object):\n pass\na = list()\n') - pymodule = self.pycore.resource_to_pyobject(self.mod1) - finder = similarfinder.SimilarFinder(pymodule) - result = list(finder.get_matches('${anything} = ${C}()', - {'C': 'name=mod1.A'})) - self.assertEquals(0, len(result)) - - def test_not_matching_unknowns_finding(self): - self.mod1.write('class A(object):\n pass\na = unknown()\n') - pymodule = self.pycore.resource_to_pyobject(self.mod1) - finder = similarfinder.SimilarFinder(pymodule) - result = list(finder.get_matches('${anything} = ${C}()', - {'C': 'name=mod1.A'})) - self.assertEquals(0, len(result)) - - def test_finding_and_matching_pyobjects(self): - source = 'class A(object):\n pass\nNewA = A\na = NewA()\n' - self.mod1.write(source) - pymodule = self.pycore.resource_to_pyobject(self.mod1) - finder = similarfinder.SimilarFinder(pymodule) - result = list(finder.get_matches('${anything} = ${A}()', - {'A': 'object=mod1.A'})) - self.assertEquals(1, len(result)) - start = source.rindex('a =') - self.assertEquals((start, len(source) - 1), result[0].get_region()) - - def test_finding_and_matching_types(self): - source = 'class A(object):\n def f(self):\n pass\n' \ - 'a = A()\nb = a.f()\n' - self.mod1.write(source) - pymodule = self.pycore.resource_to_pyobject(self.mod1) - finder = similarfinder.SimilarFinder(pymodule) - result = list(finder.get_matches('${anything} = ${inst}.f()', - {'inst': 'type=mod1.A'})) - self.assertEquals(1, len(result)) - start = source.rindex('b') - self.assertEquals((start, len(source) - 1), result[0].get_region()) - - def test_checking_the_type_of_an_ass_name_node(self): - self.mod1.write('class A(object):\n pass\nan_a = A()\n') - pymodule = self.pycore.resource_to_pyobject(self.mod1) - finder = similarfinder.SimilarFinder(pymodule) - result = list(finder.get_matches('${a} = ${assigned}', - {'a': 'type=mod1.A'})) - self.assertEquals(1, len(result)) - - def test_checking_instance_of_an_ass_name_node(self): - self.mod1.write('class A(object):\n pass\n' - 'class B(A):\n pass\nb = B()\n') - pymodule = self.pycore.resource_to_pyobject(self.mod1) - finder = similarfinder.SimilarFinder(pymodule) - result = list(finder.get_matches('${a} = ${assigned}', - {'a': 'instance=mod1.A'})) - self.assertEquals(1, len(result)) - - def test_checking_equality_of_imported_pynames(self): - mod2 = testutils.create_module(self.project, 'mod2') - mod2.write('class A(object):\n pass\n') - self.mod1.write('from mod2 import A\nan_a = A()\n') - pymod2 = self.pycore.resource_to_pyobject(mod2) - pymod1 = self.pycore.resource_to_pyobject(self.mod1) - finder = similarfinder.SimilarFinder(pymod1) - result = list(finder.get_matches('${a_class}()', - {'a_class': 'name=mod2.A'})) - self.assertEquals(1, len(result)) - - -class TemplateTest(unittest.TestCase): - - def test_simple_templates(self): - template = similarfinder.CodeTemplate('${a}\n') - self.assertEquals(set(['a']), set(template.get_names())) - - def test_ignoring_matches_in_comments(self): - template = similarfinder.CodeTemplate('#${a}\n') - self.assertEquals([], template.get_names()) - - def test_ignoring_matches_in_strings(self): - template = similarfinder.CodeTemplate("'${a}'\n") - self.assertEquals([], template.get_names()) - - def test_simple_substitution(self): - template = similarfinder.CodeTemplate('${a}\n') - self.assertEquals('b\n', template.substitute({'a': 'b'})) - - def test_substituting_multiple_names(self): - template = similarfinder.CodeTemplate('${a}, ${b}\n') - self.assertEquals('1, 2\n', template.substitute({'a': '1', 'b': '2'})) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(SimilarFinderTest)) - result.addTests(unittest.makeSuite(CheckingFinderTest)) - result.addTests(unittest.makeSuite(TemplateTest)) - return result - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/suitestest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/suitestest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ -import unittest - -from rope.base import ast -from rope.refactor import suites - - -class SuiteTest(unittest.TestCase): - - def setUp(self): - super(SuiteTest, self).setUp() - - def tearDown(self): - super(SuiteTest, self).tearDown() - - def test_trivial_case(self): - root = source_suite_tree('') - self.assertEquals(1, root.get_start()) - self.assertEquals(0, len(root.get_children())) - - def test_simple_ifs(self): - root = source_suite_tree('if True:\n pass') - self.assertEquals(1, len(root.get_children())) - - def test_simple_else(self): - root = source_suite_tree( - 'if True:\n pass\nelse:\n pass\n') - self.assertEquals(2, len(root.get_children())) - self.assertEquals(1, root.get_children()[1].get_start()) - - def test_for(self): - root = source_suite_tree( - '\nfor i in range(10):\n pass\nelse:\n pass\n') - self.assertEquals(2, len(root.get_children())) - self.assertEquals(2, root.get_children()[1].get_start()) - - def test_while(self): - root = source_suite_tree( - 'while True:\n pass\n') - self.assertEquals(1, len(root.get_children())) - self.assertEquals(1, root.get_children()[0].get_start()) - - def test_with(self): - root = source_suite_tree( - 'from __future__ import with_statement\nwith file(x): pass\n') - self.assertEquals(1, len(root.get_children())) - self.assertEquals(2, root.get_children()[0].get_start()) - - def test_try_finally(self): - root = source_suite_tree( - 'try:\n pass\nfinally:\n pass\n') - self.assertEquals(2, len(root.get_children())) - self.assertEquals(1, root.get_children()[0].get_start()) - - def test_try_except(self): - root = source_suite_tree( - 'try:\n pass\nexcept:\n pass\nelse:\n pass\n') - self.assertEquals(3, len(root.get_children())) - self.assertEquals(1, root.get_children()[2].get_start()) - - def test_try_except_finally(self): - root = source_suite_tree( - 'try:\n pass\nexcept:\n pass\nfinally:\n pass\n') - self.assertEquals(3, len(root.get_children())) - self.assertEquals(1, root.get_children()[2].get_start()) - - def test_local_start_and_end(self): - root = source_suite_tree('if True:\n pass\nelse:\n pass\n') - self.assertEquals(1, root.local_start()) - self.assertEquals(4, root.local_end()) - if_suite = root.get_children()[0] - self.assertEquals(2, if_suite.local_start()) - self.assertEquals(2, if_suite.local_end()) - else_suite = root.get_children()[1] - self.assertEquals(4, else_suite.local_start()) - self.assertEquals(4, else_suite.local_end()) - - def test_find_suite(self): - root = source_suite_tree('\n') - self.assertEquals(root, root.find_suite(1)) - - def test_find_suite_for_ifs(self): - root = source_suite_tree('if True:\n pass\n') - if_suite = root.get_children()[0] - self.assertEquals(if_suite, root.find_suite(2)) - - def test_find_suite_for_between_suites(self): - root = source_suite_tree( - 'if True:\n pass\nprint(1)\nif True:\n pass\n') - if_suite1 = root.get_children()[0] - if_suite2 = root.get_children()[1] - self.assertEquals(if_suite1, root.find_suite(2)) - self.assertEquals(if_suite2, root.find_suite(5)) - self.assertEquals(root, root.find_suite(3)) - - def test_simple_find_visible(self): - root = source_suite_tree('a = 1\n') - self.assertEquals(1, suites.find_visible_for_suite(root, [1])) - - def test_simple_find_visible_ifs(self): - root = source_suite_tree('\nif True:\n a = 1\n b = 2\n') - self.assertEquals(root.find_suite(3), root.find_suite(4)) - self.assertEquals(3, suites.find_visible_for_suite(root, [3, 4])) - - def test_simple_find_visible_for_else(self): - root = source_suite_tree('\nif True:\n pass\nelse: pass\n') - self.assertEquals(2, suites.find_visible_for_suite(root, [2, 4])) - - def test_simple_find_visible_for_different_suites(self): - root = source_suite_tree('if True:\n pass\na = 1\n' - 'if False:\n pass\n') - self.assertEquals(1, suites.find_visible_for_suite(root, [2, 3])) - self.assertEquals(5, suites.find_visible_for_suite(root, [5])) - self.assertEquals(1, suites.find_visible_for_suite(root, [2, 5])) - - def test_not_always_selecting_scope_start(self): - root = source_suite_tree( - 'if True:\n a = 1\n if True:\n pass\n' - ' else:\n pass\n') - self.assertEquals(3, suites.find_visible_for_suite(root, [4, 6])) - self.assertEquals(3, suites.find_visible_for_suite(root, [3, 5])) - self.assertEquals(3, suites.find_visible_for_suite(root, [4, 5])) - - def test_ignoring_functions(self): - root = source_suite_tree( - 'def f():\n pass\na = 1\n') - self.assertEquals(3, suites.find_visible_for_suite(root, [2, 3])) - - def test_ignoring_classes(self): - root = source_suite_tree( - 'a = 1\nclass C():\n pass\n') - self.assertEquals(1, suites.find_visible_for_suite(root, [1, 3])) - - -def source_suite_tree(source): - return suites.ast_suite_tree(ast.parse(source)) - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/refactor/usefunctiontest.py --- a/vim/sadness/ropevim/src/rope/ropetest/refactor/usefunctiontest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -import unittest - -from rope.base import exceptions -from ropetest import testutils -from rope.refactor.usefunction import UseFunction - - -class UseFunctionTest(unittest.TestCase): - - def setUp(self): - super(UseFunctionTest, self).setUp() - self.project = testutils.sample_project() - self.mod1 = testutils.create_module(self.project, 'mod1') - self.mod2 = testutils.create_module(self.project, 'mod2') - - def tearDown(self): - testutils.remove_project(self.project) - super(UseFunctionTest, self).tearDown() - - def test_simple_case(self): - code = 'def f():\n pass\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.rindex('f')) - self.project.do(user.get_changes()) - self.assertEquals(code, self.mod1.read()) - - def test_simple_function(self): - code = 'def f(p):\n print(p)\nprint(1)\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.rindex('f')) - self.project.do(user.get_changes()) - self.assertEquals('def f(p):\n print(p)\nf(1)\n', - self.mod1.read()) - - def test_simple_function2(self): - code = 'def f(p):\n print(p + 1)\nprint(1 + 1)\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.rindex('f')) - self.project.do(user.get_changes()) - self.assertEquals('def f(p):\n print(p + 1)\nf(1)\n', - self.mod1.read()) - - def test_functions_with_multiple_statements(self): - code = 'def f(p):\n r = p + 1\n print(r)\nr = 2 + 1\nprint(r)\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.rindex('f')) - self.project.do(user.get_changes()) - self.assertEquals('def f(p):\n r = p + 1\n print(r)\nf(2)\n', - self.mod1.read()) - - def test_returning(self): - code = 'def f(p):\n return p + 1\nr = 2 + 1\nprint(r)\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.rindex('f')) - self.project.do(user.get_changes()) - self.assertEquals( - 'def f(p):\n return p + 1\nr = f(2)\nprint(r)\n', - self.mod1.read()) - - def test_returning_a_single_expression(self): - code = 'def f(p):\n return p + 1\nprint(2 + 1)\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.rindex('f')) - self.project.do(user.get_changes()) - self.assertEquals( - 'def f(p):\n return p + 1\nprint(f(2))\n', - self.mod1.read()) - - def test_occurrences_in_other_modules(self): - code = 'def f(p):\n return p + 1\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.rindex('f')) - self.mod2.write('print(2 + 1)\n') - self.project.do(user.get_changes()) - self.assertEquals('import mod1\nprint(mod1.f(2))\n', - self.mod2.read()) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_when_performing_on_non_functions(self): - code = 'var = 1\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.rindex('var')) - - def test_differing_in_the_inner_temp_names(self): - code = 'def f(p):\n a = p + 1\n print(a)\nb = 2 + 1\nprint(b)\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.rindex('f')) - self.project.do(user.get_changes()) - self.assertEquals('def f(p):\n a = p + 1\n print(a)\nf(2)\n', - self.mod1.read()) - - # TODO: probably new options should be added to restructure - def xxx_test_being_a_bit_more_intelligent_when_returning_assigneds(self): - code = 'def f(p):\n a = p + 1\n return a\n'\ - 'var = 2 + 1\nprint(var)\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.rindex('f')) - self.project.do(user.get_changes()) - self.assertEquals('def f(p):\n a = p + 1\n return a\n' - 'var = f(p)\nprint(var)\n', self.mod1.read()) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_exception_when_performing_a_function_with_yield(self): - code = 'def func():\n yield 1\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.index('func')) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_exception_when_performing_a_function_two_returns(self): - code = 'def func():\n return 1\n return 2\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.index('func')) - - @testutils.assert_raises(exceptions.RefactoringError) - def test_exception_when_returns_is_not_the_last_statement(self): - code = 'def func():\n return 2\n a = 1\n' - self.mod1.write(code) - user = UseFunction(self.project, self.mod1, code.index('func')) - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/runmodtest.py --- a/vim/sadness/ropevim/src/rope/ropetest/runmodtest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -import os -import unittest - -from rope.base import exceptions -from ropetest import testutils - - -class PythonFileRunnerTest(unittest.TestCase): - - def setUp(self): - super(PythonFileRunnerTest, self).setUp() - self.project = testutils.sample_project() - self.pycore = self.project.pycore - - def tearDown(self): - testutils.remove_project(self.project) - super(PythonFileRunnerTest, self).tearDown() - - def make_sample_python_file(self, file_path, get_text_function_source=None): - self.project.root.create_file(file_path) - file = self.project.get_resource(file_path) - if not get_text_function_source: - get_text_function_source = "def get_text():\n return 'run'\n\n" - file_content = get_text_function_source + \ - "output = open('output.txt', 'w')\n" \ - "output.write(get_text())\noutput.close()\n" - file.write(file_content) - - def get_output_file_content(self, file_path): - try: - output_path = '' - last_slash = file_path.rfind('/') - if last_slash != -1: - output_path = file_path[0:last_slash + 1] - file = self.project.get_resource(output_path + 'output.txt') - return file.read() - except exceptions.ResourceNotFoundError: - return '' - - def test_making_runner(self): - file_path = 'sample.py' - self.make_sample_python_file(file_path) - file_resource = self.project.get_resource(file_path) - runner = self.pycore.run_module(file_resource) - runner.wait_process() - self.assertEquals('run', self.get_output_file_content(file_path)) - - def test_passing_arguments(self): - file_path = 'sample.py' - function_source = 'import sys\ndef get_text():\n return str(sys.argv[1:])\n' - self.make_sample_python_file(file_path, function_source) - file_resource = self.project.get_resource(file_path) - runner = self.pycore.run_module(file_resource, args=['hello', 'world']) - runner.wait_process() - self.assertTrue(self.get_output_file_content(file_path).endswith("['hello', 'world']")) - - def test_passing_arguments_with_spaces(self): - file_path = 'sample.py' - function_source = 'import sys\ndef get_text():\n return str(sys.argv[1:])\n' - self.make_sample_python_file(file_path, function_source) - file_resource = self.project.get_resource(file_path) - runner = self.pycore.run_module(file_resource, args=['hello world']) - runner.wait_process() - self.assertTrue(self.get_output_file_content(file_path).endswith("['hello world']")) - - def test_killing_runner(self): - file_path = 'sample.py' - self.make_sample_python_file(file_path, - "def get_text():" + - "\n import time\n time.sleep(1)\n return 'run'\n") - file_resource = self.project.get_resource(file_path) - runner = self.pycore.run_module(file_resource) - runner.kill_process() - self.assertEquals('', self.get_output_file_content(file_path)) - - def test_running_nested_files(self): - self.project.root.create_folder('src') - file_path = 'src/sample.py' - self.make_sample_python_file(file_path) - file_resource = self.project.get_resource(file_path) - runner = self.pycore.run_module(file_resource) - runner.wait_process() - self.assertEquals('run', self.get_output_file_content(file_path)) - - def test_setting_process_input(self): - file_path = 'sample.py' - self.make_sample_python_file(file_path, - "def get_text():" + - "\n import sys\n return sys.stdin.readline()\n") - temp_file_name = 'processtest.tmp' - try: - temp_file = open(temp_file_name, 'w') - temp_file.write('input text\n') - temp_file.close() - file_resource = self.project.get_resource(file_path) - stdin = open(temp_file_name) - runner = self.pycore.run_module(file_resource, stdin=stdin) - runner.wait_process() - stdin.close() - self.assertEquals('input text\n', self.get_output_file_content(file_path)) - finally: - os.remove(temp_file_name) - - def test_setting_process_output(self): - file_path = 'sample.py' - self.make_sample_python_file(file_path, - "def get_text():" + - "\n print 'output text'\n return 'run'\n") - temp_file_name = 'processtest.tmp' - try: - file_resource = self.project.get_resource(file_path) - stdout = open(temp_file_name, 'w') - runner = self.pycore.run_module(file_resource, stdout=stdout) - runner.wait_process() - stdout.close() - temp_file = open(temp_file_name, 'r') - self.assertEquals('output text\n', temp_file.read()) - temp_file.close() - finally: - os.remove(temp_file_name) - - def test_setting_pythonpath(self): - src = self.project.root.create_folder('src') - src.create_file('sample.py') - src.get_child('sample.py').write('def f():\n pass\n') - self.project.root.create_folder('test') - file_path = 'test/test.py' - self.make_sample_python_file(file_path, - "def get_text():\n" - " import sample\n sample.f()\n return'run'\n") - file_resource = self.project.get_resource(file_path) - runner = self.pycore.run_module(file_resource) - runner.wait_process() - self.assertEquals('run', self.get_output_file_content(file_path)) - - def test_making_runner_when_doi_is_disabled(self): - self.project.set('enable_doi', False) - file_path = 'sample.py' - self.make_sample_python_file(file_path) - file_resource = self.project.get_resource(file_path) - runner = self.pycore.run_module(file_resource) - runner.wait_process() - self.assertEquals('run', self.get_output_file_content(file_path)) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(PythonFileRunnerTest)) - return result - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/simplifytest.py --- a/vim/sadness/ropevim/src/rope/ropetest/simplifytest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -import unittest - -from rope.base import simplify - - -class SimplifyTest(unittest.TestCase): - - def setUp(self): - super(SimplifyTest, self).setUp() - - def tearDown(self): - super(SimplifyTest, self).tearDown() - - def test_trivial_case(self): - self.assertEquals('', simplify.real_code('')) - - def test_empty_strs(self): - code = 's = ""\n' - self.assertEquals(code, simplify.real_code(code)) - - def test_blanking_strs(self): - code = 's = "..."\n' - self.assertEquals('s = " "\n', simplify.real_code(code)) - - def test_changing_to_double_quotes(self): - code = 's = \'\'\n' - self.assertEquals('s = ""\n', simplify.real_code(code)) - - def test_changing_to_double_quotes2(self): - code = 's = """\n"""\n' - self.assertEquals('s = " "\n', simplify.real_code(code)) - - def test_removing_comments(self): - code = '# c\n' - self.assertEquals(' \n', simplify.real_code(code)) - - def test_removing_comments_that_contain_strings(self): - code = '# "c"\n' - self.assertEquals(' \n', simplify.real_code(code)) - - def test_removing_strings_containing_comments(self): - code = '"#c"\n' - self.assertEquals('" "\n', simplify.real_code(code)) - - def test_joining_implicit_continuations(self): - code = '(\n)\n' - self.assertEquals('( )\n', simplify.real_code(code)) - - def test_joining_explicit_continuations(self): - code = '1 + \\\n 2\n' - self.assertEquals('1 + 2\n', simplify.real_code(code)) - - def test_replacing_tabs(self): - code = '1\t+\t2\n' - self.assertEquals('1 + 2\n', simplify.real_code(code)) - - def test_replacing_semicolons(self): - code = 'a = 1;b = 2\n' - self.assertEquals('a = 1\nb = 2\n', simplify.real_code(code)) - - -def suite(): - result = unittest.TestSuite() - result.addTests(unittest.makeSuite(SimplifyTest)) - return result - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/ropetest/testutils.py --- a/vim/sadness/ropevim/src/rope/ropetest/testutils.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -import os.path -import shutil -import sys - -import rope.base.project -from rope.contrib import generate - - -def sample_project(root=None, foldername=None, **kwds): - if root is None: - root = 'sample_project' - if foldername: - root = foldername - # HACK: Using ``/dev/shm/`` for faster tests - if os.name == 'posix' and os.path.isdir('/dev/shm'): - root = '/dev/shm/' + root - # Using these prefs for faster tests - prefs = {'save_objectdb': False, 'save_history': False, - 'validate_objectdb': False, 'automatic_soa': False, - 'ignored_resources': ['.ropeproject', '*.pyc'], - 'import_dynload_stdmods': False} - prefs.update(kwds) - remove_recursively(root) - project = rope.base.project.Project(root, **prefs) - return project - -create_module = generate.create_module -create_package = generate.create_package - -def remove_project(project): - project.close() - remove_recursively(project.address) - - -def remove_recursively(path): - import time - # windows sometimes raises exceptions instead of removing files - if os.name == 'nt' or sys.platform == 'cygwin': - for i in range(12): - try: - _remove_recursively(path) - except OSError, e: - if e.errno not in (13, 16, 32): - raise - time.sleep(0.3) - else: - break - else: - _remove_recursively(path) - -def _remove_recursively(path): - if not os.path.exists(path): - return - if os.path.isfile(path): - os.remove(path) - else: - shutil.rmtree(path) - - -def run_only_for_25(func): - """Should be used as a decorator for a unittest.TestCase test method""" - if sys.version_info >= (2, 5, 0): - return func - else: - def do_nothing(self): - pass - return do_nothing - - -def only_for(version): - """Should be used as a decorator for a unittest.TestCase test method""" - def decorator(func): - if sys.version >= version: - return func - else: - def do_nothing(self): - pass - return do_nothing - return decorator - - -def run_only_for_unix(func): - """Should be used as a decorator for a unittest.TestCase test method""" - if os.name == 'posix': - return func - else: - def do_nothing(self): - pass - return do_nothing - - -def assert_raises(exception_class): - """Should be used as a decorator for a unittest.TestCase test method""" - def _assert_raises(func): - def call_func(self, *args, **kws): - self.assertRaises(exception_class, func, self, *args, **kws) - return call_func - return _assert_raises diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/rope/setup.py --- a/vim/sadness/ropevim/src/rope/setup.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -import glob -import os -import shutil - -extra_kwargs = {} -try: - # we don't want to depend on setuptools - # please don't use any setuptools specific API - from setuptools import setup - extra_kwargs['test_suite'] = 'ropetest' -except ImportError: - from distutils.core import setup - -import rope - - -classifiers=[ - 'Development Status :: 4 - Beta', - 'Operating System :: OS Independent', - 'Environment :: X11 Applications', - 'Environment :: Win32 (MS Windows)', - 'Environment :: MacOS X', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: GNU General Public License (GPL)', - 'Natural Language :: English', - 'Programming Language :: Python', - 'Topic :: Software Development'] - -def get_long_description(): - lines = open('README.txt').read().splitlines(False) - end = lines.index('Getting Started') - return '\n' + '\n'.join(lines[:end]) + '\n' - -setup(name='rope', - version=rope.VERSION, - description='a python refactoring library...', - long_description=get_long_description(), - author='Ali Gholami Rudi', - author_email='aligrudi@users.sourceforge.net', - url='http://rope.sf.net/', - packages=['rope', 'rope.base', 'rope.base.oi', 'rope.refactor', - 'rope.refactor.importutils', 'rope.contrib'], - license='GNU GPL', - classifiers=classifiers, - **extra_kwargs) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/.hgignore --- a/vim/sadness/ropevim/src/ropemode/.hgignore Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -syntax:glob - -*.pyc -*.*~ -*.*.orig -*.egg-info -doc/build -build -dist diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/.hgtags --- a/vim/sadness/ropevim/src/ropemode/.hgtags Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -e75b75d70ac93804e9e4f90ddab8c294df8088b5 0.1-rc diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/ropemode/__init__.py --- a/vim/sadness/ropevim/src/ropemode/ropemode/__init__.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -"""ropemode, a helper for using rope refactoring library in IDEs""" - -INFO = __doc__ -VERSION = '0.1-rc2' -COPYRIGHT = """\ -Copyright (C) 2007-2008 Ali Gholami Rudi - -This program is free software; you can redistribute it and/or modify it -under the terms of GNU General Public License as published by the -Free Software Foundation; either version 2 of the license, or (at your -opinion) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details.""" diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/ropemode/decorators.py --- a/vim/sadness/ropevim/src/ropemode/ropemode/decorators.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -import traceback - -from rope.base import exceptions - - -class Logger(object): - - message = None - only_short = False - - def __call__(self, message, short=None): - if short is None or not self.only_short: - self._show(message) - if short is not None: - self._show(short) - - def _show(self, message): - if message is None: - print message - else: - self.message(message) - -logger = Logger() - - -def lisphook(func): - def newfunc(*args, **kwds): - try: - func(*args, **kwds) - except Exception, e: - trace = str(traceback.format_exc()) - short = 'Ignored an exception in ropemode hook: %s' % \ - _exception_message(e) - logger(trace, short) - newfunc.lisp = None - newfunc.__name__ = func.__name__ - newfunc.__doc__ = func.__doc__ - return newfunc - - -def lispfunction(func): - func.lisp = None - return func - - -input_exceptions = (exceptions.RefactoringError, - exceptions.ModuleSyntaxError, - exceptions.BadIdentifierError) - -def _exception_handler(func): - def newfunc(*args, **kwds): - try: - return func(*args, **kwds) - except exceptions.RopeError, e: - short = None - if isinstance(e, input_exceptions): - short = _exception_message(e) - logger(str(traceback.format_exc()), short) - newfunc.__name__ = func.__name__ - newfunc.__doc__ = func.__doc__ - return newfunc - -def _exception_message(e): - return '%s: %s' % (e.__class__.__name__, str(e)) - -def rope_hook(hook): - def decorator(func): - func = lisphook(func) - func.name = func.__name__ - func.kind = 'hook' - func.hook = hook - return func - return decorator - - -def local_command(key=None, prefix=False, shortcut=None, name=None): - def decorator(func, name=name): - func = _exception_handler(func) - func.kind = 'local' - func.prefix = prefix - func.local_key = key - func.shortcut_key = shortcut - if name is None: - name = func.__name__ - func.name = name - return func - return decorator - - -def global_command(key=None, prefix=False): - def decorator(func): - func = _exception_handler(func) - func.kind = 'global' - func.prefix = prefix - func.global_key = key - func.name = func.__name__ - return func - return decorator diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/ropemode/dialog.py --- a/vim/sadness/ropevim/src/ropemode/ropemode/dialog.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -class Data(object): - - def __init__(self, prompt=None, default=None, values=None, - kind=None, decode=None): - self.prompt = prompt - self.default = default - self.values = values - self.kind = kind - self._decode = decode - - def decode(self, value): - if self._decode: - return self._decode(value) - return value - - -class Boolean(Data): - - def __init__(self, prompt=None, default=False): - Data.__init__(self, prompt, self._encode(default), - [self._encode(True), self._encode(False)]) - - def _encode(self, value): - if value: - return 'yes' - return 'no' - - def decode(self, value): - if value.lower() in ('yes', '1', 'true'): - return True - return False - - -def show_dialog(askdata, actions, confs={}, optionals={}, initial_asking=True): - result = {} - if initial_asking: - for name, conf in confs.items(): - result[name] = askdata(conf) - actions.append('batchset') - names = list(actions) - names.extend(optionals.keys()) - names.extend(confs.keys()) - base_question = Data('Choose what to do: ', - default=actions[0], values=names) - batchset_question = Data('Batch sets: ') - while True: - response = askdata(base_question) - if response == '': - response = base_question.default - elif response == 'batchset': - sets = askdata(batchset_question) - for key, value in _parse_batchset(sets).items(): - if key.endswith(':'): - key = key[:-1] - if key in names: - conf = confs.get(key, optionals.get(key)) - result[key] = value - elif response in actions: - break - else: - if response in confs: - conf = confs[response] - else: - conf = optionals[response] - oldvalue = result.get(response, None) - result[response] = askdata(conf, starting=oldvalue) - decoded = {} - all_confs = dict(confs) - all_confs.update(optionals) - for key in all_confs: - conf = all_confs.get(key) - if key in result: - decoded[key] = conf.decode(result[key]) - else: - decoded[key] = conf.decode(conf.default) - return response, decoded - - -def _parse_batchset(sets): - result = [] - multiline = False - for line in sets.splitlines(True): - if line[0].isspace(): - if multiline: - result[-1][1] += line[1:] - else: - if not line.strip(): - continue - multiline= False - tokens = line.split(None, 1) - value = '' - if len(tokens) > 1: - result.append([tokens[0], tokens[1].rstrip('\r\n')]) - else: - multiline = True - result.append([tokens[0], '']) - return dict(result) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/ropemode/environment.py --- a/vim/sadness/ropevim/src/ropemode/ropemode/environment.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -class Environment(object): - - def ask(self, prompt, default=None, starting=None): - pass - - def ask_values(self, prompt, values, default=None, starting=None): - pass - - def ask_directory(self, prompt, default=None, starting=None): - pass - - def ask_completion(self, prompt, values, starting=None): - pass - - def message(self, message): - pass - - def yes_or_no(self, prompt): - pass - - def y_or_n(self, prompt): - pass - - def get(self, name, default=None): - pass - - def get_offset(self): - pass - - def get_text(self): - pass - - def get_region(self): - pass - - def filename(self): - pass - - def is_modified(self): - pass - - def goto_line(self, lineno): - pass - - def insert_line(self, line, lineno): - pass - - def insert(self, text): - pass - - def delete(self, start, end): - pass - - def filenames(self): - pass - - def save_files(self, filenames): - pass - - def reload_files(self, filenames, moves={}): - pass - - def find_file(self, filename, readonly=False, other=False): - pass - - def create_progress(self, name): - pass - - def current_word(self): - pass - - def push_mark(self): - pass - - def prefix_value(self, prefix): - pass - - def show_occurrences(self, locations): - pass - - def show_doc(self, docs, altview=False): - pass - - def preview_changes(self, diffs): - pass - - def local_command(self, name, callback, key=None, prefix=False): - pass - - def global_command(self, name, callback, key=None, prefix=False): - pass - - def add_hook(self, name, callback, hook): - pass - - def _completion_text(self, proposal): - return proposal.name - - def _completion_data(self, proposal): - return self._completion_text(proposal) - diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/ropemode/filter.py --- a/vim/sadness/ropevim/src/ropemode/ropemode/filter.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -from rope.base import exceptions - - -def resources(project, rules): - """Find python files in the `project` matching `rules` - - `rules` is a multi-line `str`; each line starts with either a '+' - or '-'. Each '+' means include the file (or its children if it's - a folder) that comes after it. '-' has the same meaning for - exclusion. - - """ - all = set(project.pycore.get_python_files()) - files = None - for line in rules.splitlines(): - if not line.strip(): - continue - first, path = (line[0], line[1:]) - if first not in '+-': - continue - try: - resource = project.get_resource(path.strip()) - except exceptions.ResourceNotFoundError: - continue - if resource.is_folder(): - matches = set(filter(lambda item: resource.contains(item), all)) - else: - matches = set([resource]) - if first == '+': - if files is None: - files = set() - files.update(matches) - if first == '-': - if files is None: - files = set(all) - files -= matches - if files is None: - return all - return files diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/ropemode/interface.py --- a/vim/sadness/ropevim/src/ropemode/ropemode/interface.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,677 +0,0 @@ -import os - -import rope.base.change -from rope.base import libutils, utils, exceptions -from rope.contrib import codeassist, generate, autoimport, findit - -from ropemode import refactor, decorators, dialog - - -class RopeMode(object): - - def __init__(self, env): - self.project = None - self.old_content = None - self.env = env - - self._prepare_refactorings() - self.autoimport = None - self._init_mode() - - def init(self): - """Initialize rope mode""" - - def _init_mode(self): - for attrname in dir(self): - attr = getattr(self, attrname) - if not callable(attr): - continue - kind = getattr(attr, 'kind', None) - if kind == 'local': - key = getattr(attr, 'local_key', None) - prefix = getattr(attr, 'prefix', None) - self.env.local_command(attrname, attr, key, prefix) - if kind == 'global': - key = getattr(attr, 'global_key', None) - prefix = getattr(attr, 'prefix', None) - self.env.global_command(attrname, attr, key, prefix) - if kind == 'hook': - hook = getattr(attr, 'hook', None) - self.env.add_hook(attrname, attr, hook) - - def _prepare_refactorings(self): - for name in dir(refactor): - if not name.startswith('_') and name != 'Refactoring': - attr = getattr(refactor, name) - if isinstance(attr, type) and \ - issubclass(attr, refactor.Refactoring): - refname = self._refactoring_name(attr) - @decorators.local_command(attr.key, 'P', None, refname) - def do_refactor(prefix, self=self, refactoring=attr): - initial_asking = prefix is None - refactoring(self, self.env).show(initial_asking=initial_asking) - setattr(self, refname, do_refactor) - - def _refactoring_name(self, refactoring): - return refactor.refactoring_name(refactoring) - - @decorators.rope_hook('before_save') - def before_save_actions(self): - if self.project is not None: - if not self._is_python_file(self.env.filename()): - return - resource = self._get_resource() - if resource.exists(): - self.old_content = resource.read() - else: - self.old_content = '' - - @decorators.rope_hook('after_save') - def after_save_actions(self): - if self.project is not None and self.old_content is not None: - libutils.report_change(self.project, self.env.filename(), - self.old_content) - self.old_content = None - - @decorators.rope_hook('exit') - def exiting_actions(self): - if self.project is not None: - self.close_project() - - @decorators.global_command('o') - def open_project(self, root=None): - if not root: - root = self.env.ask_directory('Rope project root folder: ') - if self.project is not None: - self.close_project() - address = rope.base.project._realpath(os.path.join(root, - '.ropeproject')) - if not os.path.exists(address): - if not self.env.y_or_n('Project not exists in %s, ' \ - 'create one?' % root): - self.env.message("Project creation aborted") - return - progress = self.env.create_progress('Opening [%s] project' % root) - self.project = rope.base.project.Project(root) - if self.env.get('enable_autoimport'): - underlined = self.env.get('autoimport_underlineds') - self.autoimport = autoimport.AutoImport(self.project, - underlined=underlined) - progress.done() - - @decorators.global_command('k') - def close_project(self): - if self.project is not None: - progress = self.env.create_progress('Closing [%s] project' % - self.project.address) - self.project.close() - self.project = None - progress.done() - - @decorators.global_command() - def write_project(self): - if self.project is not None: - progress = self.env.create_progress( - 'Writing [%s] project data to disk' % self.project.address) - self.project.sync() - progress.done() - - @decorators.global_command('u') - def undo(self): - self._check_project() - change = self.project.history.tobe_undone - if change is None: - self.env.message('Nothing to undo!') - return - if self.env.y_or_n('Undo [%s]? ' % str(change)): - def undo(handle): - for changes in self.project.history.undo(task_handle=handle): - self._reload_buffers(changes, undo=True) - refactor.runtask(self.env, undo, 'Undo refactoring', - interrupts=False) - - @decorators.global_command('r') - def redo(self): - self._check_project() - change = self.project.history.tobe_redone - if change is None: - self.env.message('Nothing to redo!') - return - if self.env.y_or_n('Redo [%s]? ' % str(change)): - def redo(handle): - for changes in self.project.history.redo(task_handle=handle): - self._reload_buffers(changes) - refactor.runtask(self.env, redo, 'Redo refactoring', - interrupts=False) - - @decorators.local_command('a g', shortcut='C-c g') - def goto_definition(self): - definition = self._base_definition_location() - if definition: - self.env.push_mark() - self._goto_location(definition[0], definition[1]) - else: - self.env.message('Cannot find the definition!') - - @decorators.local_command() - def definition_location(self): - definition = self._base_definition_location() - if definition: - return str(definition[0].real_path), definition[1] - return None - - def _base_definition_location(self): - self._check_project() - resource, offset = self._get_location() - maxfixes = self.env.get('codeassist_maxfixes') - try: - definition = codeassist.get_definition_location( - self.project, self._get_text(), offset, resource, maxfixes) - except exceptions.BadIdentifierError: - return None - if tuple(definition) != (None, None): - return definition - return None - - @decorators.local_command('a d', 'P', 'C-c d') - def show_doc(self, prefix): - self._check_project() - self._base_show_doc(prefix, codeassist.get_doc) - - @decorators.local_command('a c', 'P') - def show_calltip(self, prefix): - self._check_project() - def _get_doc(project, text, offset, *args, **kwds): - try: - offset = text.rindex('(', 0, offset) - 1 - except ValueError: - return None - return codeassist.get_calltip(project, text, offset, *args, **kwds) - self._base_show_doc(prefix, _get_doc) - - def _base_show_doc(self, prefix, get_doc): - docs = self._base_get_doc(get_doc) - if docs: - self.env.show_doc(docs, prefix) - else: - self.env.message('No docs available!') - - @decorators.local_command() - def get_doc(self): - self._check_project() - return self._base_get_doc(codeassist.get_doc) - - def _base_get_doc(self, get_doc): - maxfixes = self.env.get('codeassist_maxfixes') - text = self._get_text() - offset = self.env.get_offset() - try: - return get_doc(self.project, text, offset, - self.resource, maxfixes) - except exceptions.BadIdentifierError: - return None - - def _get_text(self): - resource = self.resource - if not self.env.is_modified() and resource is not None: - return resource.read() - return self.env.get_text() - - def _base_findit(self, do_find, optionals, get_kwds): - self._check_project() - self._save_buffers() - resource, offset = self._get_location() - - action, values = dialog.show_dialog( - self._askdata, ['search', 'cancel'], optionals=optionals) - if action == 'search': - kwds = get_kwds(values) - def calculate(handle): - resources = refactor._resources(self.project, - values.get('resources')) - return do_find(self.project, resource, offset, - resources=resources, task_handle=handle, **kwds) - result = refactor.runtask(self.env, calculate, 'Find Occurrences') - locations = [Location(location) for location in result] - self.env.show_occurrences(locations) - - @decorators.local_command('a f', shortcut='C-c f') - def find_occurrences(self): - optionals = { - 'unsure': dialog.Data('Find uncertain occurrences: ', - default='no', values=['yes', 'no']), - 'resources': dialog.Data('Files to search: '), - 'in_hierarchy': dialog.Data( - 'Rename methods in class hierarchy: ', - default='no', values=['yes', 'no'])} - def get_kwds(values): - return {'unsure': values.get('unsure') == 'yes', - 'in_hierarchy': values.get('in_hierarchy') == 'yes'} - self._base_findit(findit.find_occurrences, optionals, get_kwds) - - @decorators.local_command('a i') - def find_implementations(self): - optionals = {'resources': dialog.Data('Files to search: ')} - def get_kwds(values): - return {} - self._base_findit(findit.find_implementations, optionals, get_kwds) - - @decorators.local_command('a /', 'P', 'M-/') - def code_assist(self, prefix): - _CodeAssist(self, self.env).code_assist(prefix) - - @decorators.local_command('a ?', 'P', 'M-?') - def lucky_assist(self, prefix): - _CodeAssist(self, self.env).lucky_assist(prefix) - - @decorators.local_command() - def auto_import(self): - _CodeAssist(self, self.env).auto_import() - - @decorators.local_command() - def completions(self): - return _CodeAssist(self, self.env).completions() - - @decorators.local_command() - def extended_completions(self): - return _CodeAssist(self, self.env).extended_completions() - - def _check_autoimport(self): - self._check_project() - if self.autoimport is None: - self.env.message('autoimport is disabled; ' - 'see `enable_autoimport\' variable') - return False - return True - - @decorators.global_command() - def generate_autoimport_cache(self): - if not self._check_autoimport(): - return - modules = self.env.get('autoimport_modules') - modnames = [] - if modules: - for i in range(len(modules)): - modname = modules[i] - if not isinstance(modname, basestring): - modname = modname.value() - modnames.append(modname) - else: - modules = [] - def generate(handle): - self.autoimport.generate_cache(task_handle=handle) - self.autoimport.generate_modules_cache(modules, task_handle=handle) - refactor.runtask(self.env, generate, 'Generate autoimport cache') - - @decorators.global_command('f', 'P') - def find_file(self, prefix): - file = self._base_find_file(prefix) - if file is not None: - self.env.find_file(file.real_path) - - @decorators.global_command('4 f', 'P') - def find_file_other_window(self, prefix): - file = self._base_find_file(prefix) - if file is not None: - self.env.find_file(file.real_path, other=True) - - def _base_find_file(self, prefix): - self._check_project() - if prefix: - files = self.project.pycore.get_python_files() - else: - files = self.project.get_files() - return self._ask_file(files) - - def _ask_file(self, files): - names = [] - for file in files: - names.append('<'.join(reversed(file.path.split('/')))) - result = self.env.ask_values('Rope Find File: ', names) - if result is not None: - path = '/'.join(reversed(result.split('<'))) - file = self.project.get_file(path) - return file - self.env.message('No file selected') - - @decorators.local_command('a j') - def jump_to_global(self): - if not self._check_autoimport(): - return - all_names = list(self.autoimport.get_all_names()) - name = self.env.ask_values('Global name: ', all_names) - result = dict(self.autoimport.get_name_locations(name)) - if len(result) == 1: - resource = list(result.keys())[0] - else: - resource = self._ask_file(result.keys()) - if resource: - self._goto_location(resource, result[resource]) - - @decorators.global_command('c') - def project_config(self): - self._check_project() - if self.project.ropefolder is not None: - config = self.project.ropefolder.get_child('config.py') - self.env.find_file(config.real_path) - else: - self.env.message('No rope project folder found') - - @decorators.global_command('n m') - def create_module(self): - def callback(sourcefolder, name): - return generate.create_module(self.project, name, sourcefolder) - self._create('module', callback) - - @decorators.global_command('n p') - def create_package(self): - def callback(sourcefolder, name): - folder = generate.create_package(self.project, name, sourcefolder) - return folder.get_child('__init__.py') - self._create('package', callback) - - @decorators.global_command('n f') - def create_file(self): - def callback(parent, name): - return parent.create_file(name) - self._create('file', callback, 'parent') - - @decorators.global_command('n d') - def create_directory(self): - def callback(parent, name): - parent.create_folder(name) - self._create('directory', callback, 'parent') - - @decorators.local_command() - def analyze_module(self): - """Perform static object analysis on this module""" - self._check_project() - self.project.pycore.analyze_module(self.resource) - - @decorators.global_command() - def analyze_modules(self): - """Perform static object analysis on all project modules""" - self._check_project() - def _analyze_modules(handle): - libutils.analyze_modules(self.project, task_handle=handle) - refactor.runtask(self.env, _analyze_modules, 'Analyze project modules') - - @decorators.local_command() - def run_module(self): - """Run and perform dynamic object analysis on this module""" - self._check_project() - process = self.project.pycore.run_module(self.resource) - try: - process.wait_process() - finally: - process.kill_process() - - def _create(self, name, callback, parentname='source'): - self._check_project() - confs = {'name': dialog.Data(name.title() + ' name: ')} - parentname = parentname + 'folder' - optionals = {parentname: dialog.Data( - parentname.title() + ' Folder: ', - default=self.project.address, kind='directory')} - action, values = dialog.show_dialog( - self._askdata, ['perform', 'cancel'], confs, optionals) - if action == 'perform': - parent = libutils.path_to_resource( - self.project, values.get(parentname, self.project.address)) - resource = callback(parent, values['name']) - if resource: - self.env.find_file(resource.real_path) - - def _goto_location(self, resource, lineno): - if resource: - self.env.find_file(str(resource.real_path), - other=self.env.get('goto_def_newwin')) - if lineno: - self.env.goto_line(lineno) - - def _get_location(self): - offset = self.env.get_offset() - return self.resource, offset - - def _get_resource(self, filename=None): - if filename is None: - filename = self.env.filename() - if filename is None or self.project is None: - return - resource = libutils.path_to_resource(self.project, filename, 'file') - return resource - - @property - def resource(self): - """the current resource - - Returns `None` when file does not exist. - """ - resource = self._get_resource() - if resource and resource.exists(): - return resource - - def _check_project(self): - if self.project is None: - if self.env.get('guess_project'): - self.open_project(self._guess_project()) - else: - self.open_project() - else: - self.project.validate(self.project.root) - - def _guess_project(self): - cwd = self.env.filename() - if cwd is not None: - while True: - ropefolder = os.path.join(cwd, '.ropeproject') - if os.path.exists(ropefolder) and os.path.isdir(ropefolder): - return cwd - newcwd = os.path.dirname(cwd) - if newcwd == cwd: - break - cwd = newcwd - - def _reload_buffers(self, changes, undo=False): - self._reload_buffers_for_changes( - changes.get_changed_resources(), - self._get_moved_resources(changes, undo)) - - def _reload_buffers_for_changes(self, changed, moved={}): - filenames = [resource.real_path for resource in changed] - moved = dict([(resource.real_path, moved[resource].real_path) - for resource in moved]) - self.env.reload_files(filenames, moved) - - def _get_moved_resources(self, changes, undo=False): - result = {} - if isinstance(changes, rope.base.change.ChangeSet): - for change in changes.changes: - result.update(self._get_moved_resources(change)) - if isinstance(changes, rope.base.change.MoveResource): - result[changes.resource] = changes.new_resource - if undo: - return dict([(value, key) for key, value in result.items()]) - return result - - def _save_buffers(self, only_current=False): - if only_current: - filenames = [self.env.filename()] - else: - filenames = self.env.filenames() - pythons = [] - for filename in filenames: - if self._is_python_file(filename): - pythons.append(filename) - self.env.save_files(pythons) - - def _is_python_file(self, path): - resource = self._get_resource(path) - return (resource is not None and - resource.project == self.project and - self.project.pycore.is_python_file(resource)) - - def _askdata(self, data, starting=None): - ask_func = self.env.ask - ask_args = {'prompt': data.prompt, 'starting': starting, - 'default': data.default} - if data.values: - ask_func = self.env.ask_values - ask_args['values'] = data.values - elif data.kind == 'directory': - ask_func = self.env.ask_directory - return ask_func(**ask_args) - - -class Location(object): - def __init__(self, location): - self.location = location - self.filename = location.resource.real_path - self.offset = location.offset - self.note = '' - if location.unsure: - self.note = '?' - - @property - def lineno(self): - if hasattr(self.location, 'lineno'): - return self.location.lineno - return self.location.resource.read().count('\n', 0, self.offset) + 1 - - -class _CodeAssist(object): - - def __init__(self, interface, env): - self.interface = interface - self.env = env - - def code_assist(self, prefix): - proposals = self._calculate_proposals() - if prefix is not None: - arg = self.env.prefix_value(prefix) - if arg == 0: - arg = len(proposals) - common_start = self._calculate_prefix(proposals[:arg]) - self.env.insert(common_start[self.offset - self.starting_offset:]) - self._starting = common_start - self._offset = self.starting_offset + len(common_start) - prompt = 'Completion for %s: ' % self.expression - proposals = map(self.env._completion_data, proposals) - result = self.env.ask_completion(prompt, proposals, self.starting) - if result is not None: - self._apply_assist(result) - - def lucky_assist(self, prefix): - proposals = self._calculate_proposals() - selected = 0 - if prefix is not None: - selected = self.env.prefix_value(prefix) - if 0 <= selected < len(proposals): - result = self.env._completion_text(proposals[selected]) - else: - self.env.message('Not enough proposals!') - return - self._apply_assist(result) - - def auto_import(self): - if not self.interface._check_autoimport(): - return - name = self.env.current_word() - modules = self.autoimport.get_modules(name) - if modules: - if len(modules) == 1: - module = modules[0] - else: - module = self.env.ask_values( - 'Which module to import: ', modules) - self._insert_import(name, module) - else: - self.env.message('Global name %s not found!' % name) - - def completions(self): - proposals = self._calculate_proposals() - prefix = self.offset - self.starting_offset - return [self.env._completion_text(proposal)[prefix:] - for proposal in proposals] - - def extended_completions(self): - proposals = self._calculate_proposals() - prefix = self.offset - self.starting_offset - return [[proposal.name[prefix:], proposal.get_doc(), - proposal.type] for proposal in proposals] - - def _apply_assist(self, assist): - if ' : ' in assist: - name, module = assist.rsplit(' : ', 1) - self.env.delete(self.starting_offset + 1, self.offset + 1) - self.env.insert(name) - self._insert_import(name, module) - else: - self.env.delete(self.starting_offset + 1, self.offset + 1) - self.env.insert(assist) - - def _calculate_proposals(self): - self.interface._check_project() - resource = self.interface.resource - maxfixes = self.env.get('codeassist_maxfixes') - proposals = codeassist.code_assist( - self.interface.project, self.source, self.offset, - resource, maxfixes=maxfixes) - if self.env.get('sorted_completions', True): - proposals = codeassist.sorted_proposals(proposals) - if self.autoimport is not None: - if self.starting.strip() and '.' not in self.expression: - import_assists = self.autoimport.import_assist(self.starting) - for assist in import_assists: - p = codeassist.CompletionProposal(' : '.join(assist), - 'autoimport') - proposals.append(p) - return proposals - - def _insert_import(self, name, module): - lineno = self.autoimport.find_insertion_line(self.source) - line = 'from %s import %s' % (module, name) - self.env.insert_line(line, lineno) - - def _calculate_prefix(self, proposals): - if not proposals: - return '' - prefix = self.env._completion_text(proposals[0]) - for proposal in proposals: - common = 0 - name = self.env._completion_text(proposal) - for c1, c2 in zip(prefix, name): - if c1 != c2 or ' ' in (c1, c2): - break - common += 1 - prefix = prefix[:common] - return prefix - - @property - @utils.cacheit - def offset(self): - return self.env.get_offset() - - @property - @utils.cacheit - def source(self): - return self.interface._get_text() - - @property - @utils.cacheit - def starting_offset(self): - return codeassist.starting_offset(self.source, self.offset) - - @property - @utils.cacheit - def starting(self): - return self.source[self.starting_offset:self.offset] - - @property - @utils.cacheit - def expression(self): - return codeassist.starting_expression(self.source, self.offset) - - @property - def autoimport(self): - return self.interface.autoimport diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/ropemode/refactor.py --- a/vim/sadness/ropevim/src/ropemode/ropemode/refactor.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,491 +0,0 @@ -import re - -import rope.base.change -import rope.contrib.generate -import rope.refactor.change_signature -import rope.refactor.extract -import rope.refactor.inline -import rope.refactor.introduce_factory -import rope.refactor.method_object -import rope.refactor.move -import rope.refactor.rename -import rope.refactor.restructure -import rope.refactor.usefunction -from rope.base import taskhandle - -from ropemode import dialog, filter - - -class Refactoring(object): - key = None - confs = {} - optionals = {} - saveall = True - - def __init__(self, interface, env): - self.interface = interface - self.env = env - - def show(self, initial_asking=True): - self.interface._check_project() - self.interface._save_buffers(only_current=not self.saveall) - self._create_refactoring() - action, result = dialog.show_dialog( - self.interface._askdata, ['perform', 'preview', 'cancel'], - self._get_confs(), self._get_optionals(), - initial_asking=initial_asking) - if action == 'cancel': - self.env.message('Cancelled!') - return - def calculate(handle): - return self._calculate_changes(result, handle) - name = 'Calculating %s changes' % self.name - changes = runtask(self.env, calculate, name=name) - if action == 'perform': - self._perform(changes) - if action == 'preview': - if changes is not None: - diffs = changes.get_description() - if self.env.preview_changes(diffs): - self._perform(changes) - else: - self.env.message('Thrown away!') - else: - self.env.message('No changes!') - - @property - def project(self): - return self.interface.project - - @property - def resource(self): - return self.interface._get_resource() - - @property - def offset(self): - return self.env.get_offset() - - @property - def region(self): - return self.env.get_region() - - @property - def name(self): - return refactoring_name(self.__class__) - - def _calculate_changes(self, option_values, task_handle): - pass - - def _create_refactoring(self): - pass - - def _done(self): - pass - - def _perform(self, changes): - if changes is None: - self.env.message('No changes!') - return - def perform(handle, self=self, changes=changes): - self.project.do(changes, task_handle=handle) - self.interface._reload_buffers(changes) - self._done() - runtask(self.env, perform, 'Making %s changes' % self.name, - interrupts=False) - self.env.message(str(changes.description) + ' finished') - - def _get_confs(self): - return self.confs - - def _get_optionals(self): - return self.optionals - - @property - def resources_option(self): - return dialog.Data('Files to apply this refactoring on: ', - decode=self._decode_resources) - - def _decode_resources(self, value): - return _resources(self.project, value) - - -class Rename(Refactoring): - key = 'r' - - saveall = True - - def _create_refactoring(self): - self.renamer = rope.refactor.rename.Rename( - self.project, self.resource, self.offset) - - def _calculate_changes(self, values, task_handle): - return self.renamer.get_changes(task_handle=task_handle, **values) - - def _get_optionals(self): - opts = {} - opts['docs'] = dialog.Boolean('Search comments and docs: ', True) - if self.renamer.is_method(): - opts['in_hierarchy'] = dialog.Boolean('Rename methods in ' - 'class hierarchy: ') - opts['resources'] = self.resources_option - opts['unsure'] = dialog.Data('Unsure occurrences: ', - decode=self._decode_unsure, - values=['ignore', 'match'], - default='ignore') - return opts - - def _get_confs(self): - oldname = str(self.renamer.get_old_name()) - return {'new_name': dialog.Data('New name: ', default=oldname)} - - def _decode_unsure(self, value): - unsure = value == 'match' - return lambda occurrence: unsure - - -class RenameCurrentModule(Rename): - key = '1 r' - offset = None - - -class Restructure(Refactoring): - key = 'x' - confs = {'pattern': dialog.Data('Restructuring pattern: '), - 'goal': dialog.Data('Restructuring goal: ')} - - def _calculate_changes(self, values, task_handle): - restructuring = rope.refactor.restructure.Restructure( - self.project, values['pattern'], values['goal'], - args=values['args'], imports=values['imports']) - return restructuring.get_changes(resources=values['resources'], - task_handle=task_handle) - - def _get_optionals(self): - return { - 'args': dialog.Data('Arguments: ', decode=self._decode_args), - 'imports': dialog.Data('Imports: ', decode=self._decode_imports), - 'resources': self.resources_option} - - def _decode_args(self, value): - if value: - args = {} - for raw_check in value.split('\n'): - if raw_check: - key, value = raw_check.split(':', 1) - args[key.strip()] = value.strip() - return args - - def _decode_imports(self, value): - if value: - return [line.strip() for line in value.split('\n')] - - -class UseFunction(Refactoring): - key = 'u' - - def _create_refactoring(self): - self.user = rope.refactor.usefunction.UseFunction( - self.project, self.resource, self.offset) - - def _calculate_changes(self, values, task_handle): - return self.user.get_changes(task_handle=task_handle, **values) - - def _get_optionals(self): - return {'resources': self.resources_option} - - -class Move(Refactoring): - key = 'v' - - def _create_refactoring(self): - self.mover = rope.refactor.move.create_move(self.project, - self.resource, - self.offset) - - def _calculate_changes(self, values, task_handle): - destination = values['destination'] - resources = values.get('resources', None) - if isinstance(self.mover, rope.refactor.move.MoveGlobal): - return self._move_global(destination, resources, task_handle) - if isinstance(self.mover, rope.refactor.move.MoveModule): - return self._move_module(destination, resources, task_handle) - if isinstance(self.mover, rope.refactor.move.MoveMethod): - return self._move_method(destination, resources, task_handle) - - def _move_global(self, dest, resources, handle): - destination = self.project.pycore.find_module(dest) - return self.mover.get_changes( - destination, resources=resources, task_handle=handle) - - def _move_method(self, dest, resources, handle): - return self.mover.get_changes( - dest, self.mover.get_method_name(), - resources=resources, task_handle=handle) - - def _move_module(self, dest, resources, handle): - destination = self.project.pycore.find_module(dest) - return self.mover.get_changes( - destination, resources=resources, task_handle=handle) - - def _get_confs(self): - if isinstance(self.mover, rope.refactor.move.MoveGlobal): - prompt = 'Destination module: ' - if isinstance(self.mover, rope.refactor.move.MoveModule): - prompt = 'Destination package: ' - if isinstance(self.mover, rope.refactor.move.MoveMethod): - prompt = 'Destination attribute: ' - return {'destination': dialog.Data(prompt)} - - def _get_optionals(self): - return {'resources': self.resources_option} - - -class MoveCurrentModule(Move): - key = '1 v' - offset = None - - -class ModuleToPackage(Refactoring): - key = '1 p' - saveall = False - - def _create_refactoring(self): - self.packager = rope.refactor.ModuleToPackage( - self.project, self.resource) - - def _calculate_changes(self, values, task_handle): - return self.packager.get_changes() - - -class Inline(Refactoring): - key = 'i' - - def _create_refactoring(self): - self.inliner = rope.refactor.inline.create_inline( - self.project, self.resource, self.offset) - - def _calculate_changes(self, values, task_handle): - return self.inliner.get_changes(task_handle=task_handle, **values) - - def _get_optionals(self): - opts = {'resources': self.resources_option} - if self.inliner.get_kind() == 'parameter': - opts['in_hierarchy'] = dialog.Boolean( - 'Apply on all matching methods in class hierarchy: ', False) - else: - opts['remove'] = dialog.Boolean('Remove the definition: ', True) - opts['only_current'] = dialog.Boolean('Inline this ' - 'occurrence only: ') - return opts - - -class _Extract(Refactoring): - saveall = False - optionals = {'similar': dialog.Boolean('Extract similar pieces: ', True), - 'global_': dialog.Boolean('Make global: ')} - kind = None - constructor = None - - def _create_refactoring(self): - start, end = self.region - self.extractor = self.constructor(self.project, - self.resource, start, end) - - def _calculate_changes(self, values, task_handle): - similar = values.get('similar') - global_ = values.get('global_') - return self.extractor.get_changes(values['name'], similar=similar, - global_=global_) - - def _get_confs(self): - return {'name': dialog.Data('Extracted %s name: ' % self.kind)} - - -class ExtractVariable(_Extract): - key = 'l' - kind = 'variable' - constructor = rope.refactor.extract.ExtractVariable - - -class ExtractMethod(_Extract): - key = 'm' - kind = 'method' - constructor = rope.refactor.extract.ExtractMethod - - -class OrganizeImports(Refactoring): - key = 'o' - saveall = False - - def _create_refactoring(self): - self.organizer = rope.refactor.ImportOrganizer(self.project) - - def _calculate_changes(self, values, task_handle): - return self.organizer.organize_imports(self.resource) - - -class MethodObject(Refactoring): - saveall = False - confs = {'classname': dialog.Data('New class name: ', - default='_ExtractedClass')} - - def _create_refactoring(self): - self.objecter = rope.refactor.method_object.MethodObject( - self.project, self.resource, self.offset) - - def _calculate_changes(self, values, task_handle): - classname = values.get('classname') - return self.objecter.get_changes(classname) - - -class IntroduceFactory(Refactoring): - saveall = True - key = 'f' - - def _create_refactoring(self): - self.factory = rope.refactor.introduce_factory.IntroduceFactory( - self.project, self.resource, self.offset) - - def _calculate_changes(self, values, task_handle): - return self.factory.get_changes(task_handle=task_handle, **values) - - def _get_confs(self): - default = 'create_%s' % self.factory.old_name.lower() - return {'factory_name': dialog.Data('Factory name: ', default)} - - def _get_optionals(self): - return {'global_factory': dialog.Boolean('Make global: ', True), - 'resources': self.resources_option} - - -class ChangeSignature(Refactoring): - saveall = True - key = 's' - - def _create_refactoring(self): - self.changer = rope.refactor.change_signature.ChangeSignature( - self.project, self.resource, self.offset) - - def _calculate_changes(self, values, task_handle): - signature = values.get('signature') - args = re.sub(r'[\s\(\)]+', '', signature).split(',') - olds = [arg[0] for arg in self._get_args()] - - changers = [] - for arg in list(olds): - if arg in args: - continue - changers.append(rope.refactor.change_signature. - ArgumentRemover(olds.index(arg))) - olds.remove(arg) - - order = [] - for index, arg in enumerate(args): - if arg not in olds: - changers.append(rope.refactor.change_signature. - ArgumentAdder(index, arg)) - olds.insert(index, arg) - order.append(olds.index(arg)) - changers.append(rope.refactor.change_signature. - ArgumentReorderer(order, autodef='None')) - - del values['signature'] - return self.changer.get_changes(changers, task_handle=task_handle, - **values) - - def _get_args(self): - if hasattr(self.changer, 'get_args'): - return self.changer.get_args() - return self.changer.get_definition_info().args_with_defaults - - def _get_confs(self): - args = [] - for arg, default in self._get_args(): - args.append(arg) - signature = '(' + ', '.join(args) + ')' - return {'signature': dialog.Data('Change the signature: ', - default=signature)} - - def _get_optionals(self): - opts = {'resources': self.resources_option} - if self.changer.is_method(): - opts['in_hierarchy'] = dialog.Boolean('Rename methods in ' - 'class hierarchy: ') - return opts - - -class _GenerateElement(Refactoring): - - def _create_refactoring(self): - kind = self.name.split('_')[-1] - self.generator = rope.contrib.generate.create_generate( - kind, self.project, self.resource, self.offset) - - def _calculate_changes(self, values, task_handle): - return self.generator.get_changes() - - def _done(self): - resource, lineno = self.generator.get_location() - self.interface._goto_location(resource, lineno) - - -class GenerateVariable(_GenerateElement): - key = 'n v' - - -class GenerateFunction(_GenerateElement): - key = 'n f' - - -class GenerateClass(_GenerateElement): - key = 'n c' - - -class GenerateModule(_GenerateElement): - key = 'n m' - - -class GeneratePackage(_GenerateElement): - key = 'n p' - - -def refactoring_name(refactoring): - classname = refactoring.__name__ - result = [] - for c in classname: - if result and c.isupper(): - result.append('_') - result.append(c.lower()) - name = ''.join(result) - return name - -def _resources(project, text): - if text is None or text.strip() == '': - return None - return filter.resources(project, text) - - -def runtask(env, command, name, interrupts=True): - return RunTask(env, command, name, interrupts)() - -class RunTask(object): - - def __init__(self, env, task, name, interrupts=True): - self.env = env - self.task = task - self.name = name - self.interrupts = interrupts - - def __call__(self): - handle = taskhandle.TaskHandle(name=self.name) - progress = self.env.create_progress(self.name) - def update_progress(): - jobset = handle.current_jobset() - if jobset: - percent = jobset.get_percent_done() - if percent is not None: - progress.update(percent) - handle.add_observer(update_progress) - result = self.task(handle) - progress.done() - return result diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/ropemodetest.py --- a/vim/sadness/ropevim/src/ropemode/ropemodetest.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -import unittest - -from ropemode import dialog - - -class ConfigTest(unittest.TestCase): - - def setUp(self): - super(ConfigTest, self).setUp() - - def tearDown(self): - super(ConfigTest, self).tearDown() - - def test_trivial_case(self): - action, confs = dialog.show_dialog(_MockAskConfig(['done']), ['done']) - self.assertEquals('done', action) - self.assertEquals({}, confs) - - def test_asking_normal_configs(self): - confs = {'name': dialog.Data()} - minibuffer = _MockAskConfig(['value', 'done']) - action, result = dialog.show_dialog(minibuffer, - ['done', 'cancel'], confs) - self.assertEquals({'name': 'value'}, result) - self.assertEquals('done', action) - - def test_optional_confs(self): - optionals = {'name': dialog.Data()} - minibuffer = _MockAskConfig(['done']) - action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'], - optionals=optionals) - self.assertEquals(None, result.get('name', None)) - self.assertEquals('done', action) - - def test_optional_confs2(self): - optionals = {'name': dialog.Data()} - minibuffer = _MockAskConfig(['name', 'value', 'done']) - action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'], - optionals=optionals) - self.assertEquals({'name': 'value'}, result) - self.assertEquals('done', action) - - def test_trivial_batchset(self): - optionals = {'name': dialog.Data()} - minibuffer = _MockAskConfig(['batchset', 'name value', 'done']) - action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'], - optionals=optionals) - self.assertEquals({'name': 'value'}, result) - self.assertEquals('done', action) - - def test_batchset_multiple_sets(self): - optionals = {'name1': dialog.Data(), 'name2': dialog.Data()} - minibuffer = _MockAskConfig(['batchset', - 'name1 value1\nname2 value2', 'done']) - action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'], - optionals=optionals) - self.assertEquals({'name1': 'value1', 'name2': 'value2'}, result) - self.assertEquals('done', action) - - def test_multiline_sets(self): - optionals = {'name': dialog.Data()} - minibuffer = _MockAskConfig( - ['batchset', 'name\n line1\n line2\n', 'done']) - action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'], - optionals=optionals) - self.assertEquals({'name': 'line1\n line2\n'}, result) - self.assertEquals('done', action) - - def test_complex_batchset(self): - optionals = {'name1': dialog.Data(), 'name2': dialog.Data(), - 'name3': dialog.Data()} - minibuffer = _MockAskConfig( - ['batchset', 'name3\n value3\nname1\n line1\n ' - 'line2\n\nname2 value2\n', 'done']) - action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'], - optionals=optionals) - self.assertEquals( - {'name1': 'line1\n line2\n', 'name2': 'value2', - 'name3': 'value3\n'}, result) - self.assertEquals('done', action) - - def test_skipping_blanks(self): - optionals = {'name1': dialog.Data(), 'name2': dialog.Data()} - minibuffer = _MockAskConfig( - ['batchset', '\nname1\n value1\n\nname2 value2\n\n', 'done']) - action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'], - optionals=optionals) - self.assertEquals({'name1': 'value1\n', 'name2': 'value2'}, result) - self.assertEquals('done', action) - - def test_skip_initial_asking(self): - confs = {'name': dialog.Data()} - minibuffer = _MockAskConfig( - ['name', 'value', 'done']) - action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'], - confs=confs, initial_asking=False) - self.assertEquals({'name': 'value'}, result) - self.assertEquals('done', action) - - def test_ignoring_trailing_colon_in_config_names(self): - optionals = {'name1': dialog.Data()} - minibuffer = _MockAskConfig( - ['batchset', 'name1: value1\n', 'done']) - action, result = dialog.show_dialog(minibuffer, ['done', 'cancel'], - optionals=optionals) - self.assertEquals({'name1': 'value1'}, result) - self.assertEquals('done', action) - - -class _MockAskConfig(object): - - def __init__(self, responses=[]): - self.responses = responses - self.asked = [] - - def __call__(self, config, starting=None): - self.asked.append(config) - return self.responses[len(self.asked) - 1] - - -if __name__ == '__main__': - unittest.main() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropemode/setup.py --- a/vim/sadness/ropevim/src/ropemode/setup.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -extra_kwargs = {} -try: - from setuptools import setup - extra_kwargs['install_requires'] = ['rope >= 0.9.2'] -except ImportError: - from distutils.core import setup - -import ropemode - - -classifiers=[ - 'Development Status :: 4 - Beta', - 'Operating System :: OS Independent', - 'Environment :: X11 Applications', - 'Environment :: Win32 (MS Windows)', - 'Environment :: MacOS X', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: GNU General Public License (GPL)', - 'Natural Language :: English', - 'Programming Language :: Python', - 'Topic :: Software Development'] - -setup(name='ropemode', - version=ropemode.VERSION, - description=ropemode.INFO, - author='Ali Gholami Rudi', - author_email='aligrudi@users.sourceforge.net', - url='http://rope.sf.net/', - packages=['ropemode'], - license='GNU GPL', - classifiers=classifiers, - requires=['rope (>= 0.9.2)'], - **extra_kwargs -) - diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/.hgtags --- a/vim/sadness/ropevim/src/ropevim/.hgtags Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -dd2506d135c323e95f1033c488817ade2d1fbbc1 0.1 -43dcf217265c3beba85c7fe0b139df9d8b167ced 0.2c1 -f548c711e86af8cc62c0fc9df186516c416a4f22 0.2 -511c3b16f57c785b0e9fdc8d095e6325684e7415 0.3-rc diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/CONTRIBUTORS --- a/vim/sadness/ropevim/src/ropevim/CONTRIBUTORS Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -====================== - Ropevim Contributors -====================== - -* Alon Levy -* Matthieu Tanguay-Carel -* Jesse Zhang -* Ben Davis -* Anton Gritsay diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/COPYING --- a/vim/sadness/ropevim/src/ropevim/COPYING Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/MANIFEST.in --- a/vim/sadness/ropevim/src/ropevim/MANIFEST.in Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -include README.txt COPYING setup.py MANIFEST.in -include ropevim.py ropevim.vim -recursive-include ropemode *.py -recursive-include docs *.txt diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/README.txt --- a/vim/sadness/ropevim/src/ropevim/README.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,337 +0,0 @@ -====================== - ropevim, rope in vim -====================== - -Ropevim is a vim mode that uses rope_ library to provide features like -python refactorings and code-assists. You should install rope_ -library before using ropevim. - -.. _rope: http://rope.sf.net/ - - -New Features -============ - -* improved support of multibyte sources -* implemented `extended complete` feature (disabled by default) -* ropemode is not the part of distribution now - - -Setting Up -========== - -First add ropevim folder to the ``PYTHONPATH`` (or install it using -``python setup.py install``). - -Then load ``ropevim.vim`` in vim. That can be done either by adding -``source path/to/ropevim.vim`` to your ``~/.vimrc`` or copying it to -``~/.vim/plugin/`` folder. - -If you don't want to install rope and ropevim you can add something -like this to your ``~/.vimrc``:: - - let $PYTHONPATH .= ":/path/to/rope:/path/to/ropevim" - source /path/to/ropevim.vim - -For using the repository version of rope, see ``docs/ropevim.txt``. - - -Getting Started -=============== - -Refactoring Dialog ------------------- - -Ropevim refactorings use a special kind of dialog. Depending on the -refactoring, you'll be asked about the essential information a -refactoring needs to know (like the new name in rename refactoring). - -Next you'll see the base prompt of a refactoring dialog that shows -something like "Choose what to do". By entering the name of a -refactoring option you can set its value. After setting each option -you'll be returned back to the base prompt. Finally, you can ask rope -to perform, preview or cancel the refactoring. - -See keybinding_ section and try the refactorings yourself. - - -Finding Files -------------- - -By using ``RopeFindFile`` (``C-x p f`` by default), you can search for -files in your project. When you complete the minibuffer you'll see -all files in the project; files are shown as their reversed paths. -For instance ``projectroot/docs/todo.txt`` is shown like -``todo.txt" if it is not. - -Note that you'll need rope r1558:0d76aa9d0614 or later and ropemode -r35:bd77ca42b04d or later for extended complete feature to work. - - -Enabling Autoimport -------------------- - -Rope can propose and automatically import global names in other -modules. Rope maintains a cache of global names for each project. It -updates the cache only when modules are changed; if you want to cache -all your modules at once, use ``RopeGenerateAutoimportCache``. It -will cache all of the modules inside the project plus those whose -names are listed in ``ropevim_autoimport_modules`` list:: - - # add the name of modules you want to autoimport - let g:ropevim_autoimport_modules = ["os", "shutil"] - -Now if you are in a buffer that contains:: - - rmtree - -and you execute ``RopevimAutoImport`` you'll end up with:: - - from shutil import rmtree - rmtree - -Also ``RopeCodeAssist`` and ``RopeLuckyAssist`` propose auto-imported -names by using ``name : module`` style. Selecting them will import -the module automatically. - - -Filtering Resources -------------------- - -Some refactorings, restructuring and find occurrences take an option -called resources. This option can be used to limit the resources on -which a refactoring should be applied. - -It uses a simple format: each line starts with either '+' or '-'. -Each '+' means include the file (or its children if it's a folder) -that comes after it. '-' has the same meaning for exclusion. So -using:: - - +rope - +ropetest - -rope/contrib - -means include all python files inside ``rope`` and ``ropetest`` -folders and their subfolder, but those that are in ``rope/contrib``. -Or:: - - -ropetest - -setup.py - -means include all python files inside the project but ``setup.py`` and -those under ``ropetest`` folder. - - -Finding Occurrences -------------------- - -The find occurrences command (``C-c f`` by default) can be used to -find the occurrences of a python name. If ``unsure`` option is -``yes``, it will also show unsure occurrences; unsure occurrences are -indicated with a ``?`` mark in the end. Note that ropevim uses the -quickfix feature of vim for marking occurrence locations. - - -Dialog ``batchset`` Command ---------------------------- - -When you use ropevim dialogs there is a command called ``batchset``. -It can set many options at the same time. After selecting this -command from dialog base prompt, you are asked to enter a string. - -``batchset`` strings can set the value of configs in two ways. The -single line form is like this:: - - name1 value1 - name2 value2 - -That is the name of config is followed its value. For multi-line -values you can use:: - - name1 - line1 - line2 - - name2 - line3 - -Each line of the definition should start with a space or a tab. Note -that blank lines before the name of config definitions are ignored. - -``batchset`` command is useful when performing refactorings with long -configs, like restructurings:: - - pattern ${pycore}.create_module(${project}.root, ${name}) - - goal generate.create_module(${project}, ${name}) - - imports - from rope.contrib import generate - - args - pycore: type=rope.base.pycore.PyCore - project: type=rope.base.project.Project - -.. ignore the two-space indents - -This is a valid ``batchset`` string for restructurings. - -Just for the sake of completeness, the reverse of the above -restructuring can be:: - - pattern ${create_module}(${project}, ${name}) - - goal ${project}.pycore.create_module(${project}.root, ${name}) - - args - create_module: name=rope.contrib.generate.create_module - project: type=rope.base.project.Project - - -Variables -========= - -* ``ropevim_codeassist_maxfixes``: The maximum number of syntax errors - to fix for code assists. The default value is ``1``. -* ``ropevim_local_prefix``: The prefix for ropevim refactorings. - Defaults to ``C-c r``. -* ``ropevim_global_prefix``: The prefix for ropevim project commands - Defaults to ``C-x p``. -* ``ropevim_enable_shortcuts``: Shows whether to bind ropevim - shortcuts keys. Defaults to ``1``. -* ``ropevim_guess_project``: If non-zero, ropevim tries to guess and - open the project that contains the file on which a ropevim command - is performed when no project is already open. - -* ``ropevim_enable_autoimport``: Shows whether to enable autoimport. -* ``ropevim_autoimport_modules``: The name of modules whose global - names should be cached. `RopeGenerateAutoimportCache' reads this - list and fills its cache. -* ``ropevim_autoimport_underlineds``: If set, autoimport will cache - names starting with underlines, too. - -* ``ropevim_goto_def_newwin``: If set, ropevim will open a new buffer - for "go to definition" result if the definition found is located - in another file. By default the file is open in the same buffer. - - -Keybinding -========== - -Uses almost the same keybinding as ropemacs. Note that global -commands have a ``C-x p`` prefix and local commands have a ``C-c r`` -prefix. You can change that (see variables_ section). - -================ ============================ -Key Command -================ ============================ -C-x p o RopeOpenProject -C-x p k RopeCloseProject -C-x p f RopeFindFile -C-x p 4 f RopeFindFileOtherWindow -C-x p u RopeUndo -C-x p r RopeRedo -C-x p c RopeProjectConfig -C-x p n [mpfd] RopeCreate(Module|Package|File|Directory) - RopeWriteProject - -C-c r r RopeRename -C-c r l RopeExtractVariable -C-c r m RopeExtractMethod -C-c r i RopeInline -C-c r v RopeMove -C-c r x RopeRestructure -C-c r u RopeUseFunction -C-c r f RopeIntroduceFactory -C-c r s RopeChangeSignature -C-c r 1 r RopeRenameCurrentModule -C-c r 1 v RopeMoveCurrentModule -C-c r 1 p RopeModuleToPackage - -C-c r o RopeOrganizeImports -C-c r n [vfcmp] RopeGenerate(Variable|Function|Class|Module|Package) - -C-c r a / RopeCodeAssist -C-c r a g RopeGotoDefinition -C-c r a d RopeShowDoc -C-c r a f RopeFindOccurrences -C-c r a ? RopeLuckyAssist -C-c r a j RopeJumpToGlobal -C-c r a c RopeShowCalltip - RopeAnalyzeModule - - RopeAutoImport - RopeGenerateAutoimportCache -=============== ============================ - - -Shortcuts ---------- - -Some commands are used very frequently; specially the commands in -code-assist group. You can define your own shortcuts like this:: - - :map g :call RopeGotoDefinition() - -Ropevim itself comes with a few shortcuts. These shortcuts will be -used only when ``ropevim_enable_shortcuts`` is set. - -================ ============================ -Key Command -================ ============================ -M-/ RopeCodeAssist -M-? RopeLuckyAssist -C-c g RopeGotoDefinition -C-c d RopeShowDoc -C-c f RopeFindOccurrences -================ ============================ - - -Contributing -============ - -Send your bug reports, feature requests and patches to `rope-dev (at) -googlegroups.com`_. - -.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev - - -License -======= - -This program is under the terms of GPL (GNU General Public License). -Have a look at ``COPYING`` file for more information. diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/docs/done.txt --- a/vim/sadness/ropevim/src/ropevim/docs/done.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -====== - Done -====== - -> Public Release 0.3 : Febrary 5, 2010 - -* ropemode is not the part of distribution : Febrary 5, 2010 -* implemented `extended complete` feature : January 26, 2010 -* improved support of multibyte sources : June 24, 2009 - -> Public Release 0.2 : October 3, 2008 - -* fixed quickfix error format : August 18, 2008 -* ropevim_guess_project variable : June 18, 2008 - -> Public Release 0.2c1 : June 12, 2008 - -* not showing python traceback for bad inputs : May 23, 2008 -* interrupting refactorings : May 22, 2008 - -> Public Release 0.1 : May 22, 2008 - -* ropvim menu : May 21, 2008 -* code-assist in insert mode : May 21, 2008 -* using vim quickfix for showing occurrences : May 20, 2008 -* better dialogs : May 19, 2008 -* implementing basic ropemode commands : May 15, 2008 -* project started! : May 12, 2008 diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/docs/ropevim.txt --- a/vim/sadness/ropevim/src/ropevim/docs/ropevim.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -====================== - ropevim, rope in vim -====================== - -Ropevim is a plugin for performing python refactorings in vim. It -uses rope_ library. - -You should install `rope`_ library before using ropevim. You can -download ropevim from `project download page`_. - -.. _rope: http://rope.sf.net/ - - -Features -======== - -* Supports many of the refactorings that are supported by rope_ - library: - - * Rename - * Extract method/local variable - * Move class/function/module/package/method - * Inline method/local variable/parameter - * Restructuring - * Change signature - * ... - -* Other refactoring-related features - - * Previewing refactorings - * Undo/redo refactorings - * Showing refactoring progress - -* Code-assists - - * Code-completion - * Goto definition - * Show pydoc - * Find occurrences - * Organize imports (remove unused and duplicate imports and sort them) - * Generating python elements - - -Source Repository -================= - -The repository version needs ropemode (which was once part of -ropemacs); in order to use the repository version of ropevim you need -to put ropemode in your ``PYTHONPATH``. Note that ropemode is -included in released packages. - -Ropevim: - -* repo url: http://bitbucket.org/agr/ropevim -* snapshot: http://bitbucket.org/agr/ropevim/get/tip.gz - -Ropemode: - -* repo url: http://bitbucket.org/agr/ropemode -* snapshot: http://bitbucket.org/agr/ropemode/get/tip.gz - - -Feedback -======== - -Send your bug reports, feature requests and patches to `rope-dev (at) -googlegroups.com`_. - - -License -======= - -Ropevim is under the terms of GNU GPL (GNU General Public License). - -.. _project download page: http://sf.net/projects/rope/files -.. _`rope-dev (at) googlegroups.com`: http://groups.google.com/group/rope-dev -.. _Mercurial: http://selenic.com/mercurial diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/docs/todo.txt --- a/vim/sadness/ropevim/src/ropevim/docs/todo.txt Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -============== - Ropevim TODO -============== - -* preventing changed file warnings -* interrupting refactorings -* better progress bar -* prefixing functions diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/ropevim.py --- a/vim/sadness/ropevim/src/ropevim/ropevim.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,459 +0,0 @@ -"""ropevim, a vim mode for using rope refactoring library""" -import os -import tempfile -import re - -import ropemode.decorators -import ropemode.environment -import ropemode.interface - -import vim - - -class VimUtils(ropemode.environment.Environment): - - def ask(self, prompt, default=None, starting=None): - if starting is None: - starting = '' - if default is not None: - prompt = prompt + ('[%s] ' % default) - result = call('input("%s", "%s")' % (prompt, starting)) - if default is not None and result == '': - return default - return result - - def ask_values(self, prompt, values, default=None, - starting=None, show_values=None): - if show_values or (show_values is None and len(values) < 14): - self._print_values(values) - if default is not None: - prompt = prompt + ('[%s] ' % default) - starting = starting or '' - _completer.values = values - answer = call('input("%s", "%s", "customlist,RopeValueCompleter")' % - (prompt, starting)) - if answer is None: - if 'cancel' in values: - return 'cancel' - return - if default is not None and not answer: - return default - if answer.isdigit() and 0 <= int(answer) < len(values): - return values[int(answer)] - return answer - - def _print_values(self, values): - numbered = [] - for index, value in enumerate(values): - numbered.append('%s. %s' % (index, str(value))) - echo('\n'.join(numbered) + '\n') - - def ask_directory(self, prompt, default=None, starting=None): - return call('input("%s", ".", "dir")' % prompt) - - def ask_completion(self, prompt, values, starting=None): - if self.get('vim_completion') and 'i' in call('mode()'): - if not self.get('extended_complete', False): - proposals = u','.join(u"'%s'" % self._completion_text(proposal) - for proposal in values) - else: - proposals = u','.join(self._extended_completion(proposal) - for proposal in values) - - col = int(call('col(".")')) - if starting: - col -= len(starting) - command = u'call complete(%s, [%s])' % (col, proposals) - vim.command(command.encode(self._get_encoding())) - return None - return self.ask_values(prompt, values, starting=starting, - show_values=False) - - def message(self, message): - echo(message) - - def yes_or_no(self, prompt): - return self.ask_values(prompt, ['yes', 'no']) == 'yes' - - def y_or_n(self, prompt): - return self.yes_or_no(prompt) - - def get(self, name, default=None): - vimname = 'g:ropevim_%s' % name - if str(vim.eval('exists("%s")' % vimname)) == '0': - return default - result = vim.eval(vimname) - if isinstance(result, str) and result.isdigit(): - return int(result) - return result - - def get_offset(self): - result = self._position_to_offset(*self.cursor) - return result - - def _get_encoding(self): - return vim.eval('&encoding') - def _encode_line(self, line): - return line.encode(self._get_encoding()) - def _decode_line(self, line): - return line.decode(self._get_encoding()) - - def _position_to_offset(self, lineno, colno): - result = min(colno, len(self.buffer[lineno -1]) + 1) - for line in self.buffer[:lineno-1]: - line = self._decode_line(line) - result += len(line) + 1 - return result - - def get_text(self): - return self._decode_line('\n'.join(self.buffer)) + u'\n' - - def get_region(self): - start = self._position_to_offset(*self.buffer.mark('<')) - end = self._position_to_offset(*self.buffer.mark('>')) - return start, end - - @property - def buffer(self): - return vim.current.buffer - - def _get_cursor(self): - lineno, col = vim.current.window.cursor - line = self._decode_line(vim.current.line[:col]) - col = len(line) - return (lineno, col) - - def _set_cursor(self, cursor): - lineno, col = cursor - line = self._decode_line(vim.current.line) - line = self._encode_line(line[:col]) - col = len(line) - vim.current.window.cursor = (lineno, col) - - cursor = property(_get_cursor, _set_cursor) - - def filename(self): - return self.buffer.name - - def is_modified(self): - return vim.eval('&modified') - - def goto_line(self, lineno): - self.cursor = (lineno, 0) - - def insert_line(self, line, lineno): - self.buffer[lineno - 1:lineno - 1] = [line] - - def insert(self, text): - lineno, colno = self.cursor - line = self.buffer[lineno - 1] - self.buffer[lineno - 1] = line[:colno] + text + line[colno:] - self.cursor = (lineno, colno + len(text)) - - def delete(self, start, end): - lineno1, colno1 = self._offset_to_position(start - 1) - lineno2, colno2 = self._offset_to_position(end - 1) - lineno, colno = self.cursor - if lineno1 == lineno2: - line = self.buffer[lineno1 - 1] - self.buffer[lineno1 - 1] = line[:colno1] + line[colno2:] - if lineno == lineno1 and colno >= colno1: - diff = colno2 - colno1 - self.cursor = (lineno, max(0, colno - diff)) - - def _offset_to_position(self, offset): - text = self.get_text() - lineno = text.count('\n', 0, offset) + 1 - try: - colno = offset - text.rindex('\n', 0, offset) - 1 - except ValueError: - colno = offset - return lineno, colno - - def filenames(self): - result = [] - for buffer in vim.buffers: - if buffer.name: - result.append(buffer.name) - return result - - def save_files(self, filenames): - vim.command('wall') - - def reload_files(self, filenames, moves={}): - initial = self.filename() - for filename in filenames: - self.find_file(moves.get(filename, filename), force=True) - if initial: - self.find_file(initial) - - def find_file(self, filename, readonly=False, other=False, force=False): - if filename != self.filename() or force: - if other: - vim.command('new') - vim.command('e %s' % filename) - if readonly: - vim.command('set nomodifiable') - - def create_progress(self, name): - return VimProgress(name) - - def current_word(self): - return vim.eval('expand("")') - - def push_mark(self): - vim.command('mark `') - - def prefix_value(self, prefix): - return prefix - - def show_occurrences(self, locations): - self._quickfixdefs(locations) - - def _quickfixdefs(self, locations): - filename = os.path.join(tempfile.gettempdir(), tempfile.mktemp()) - try: - self._writedefs(locations, filename) - vim.command('let old_errorfile = &errorfile') - vim.command('let old_errorformat = &errorformat') - vim.command('set errorformat=%f:%l:\ %m') - vim.command('cfile ' + filename) - vim.command('let &errorformat = old_errorformat') - vim.command('let &errorfile = old_errorfile') - finally: - os.remove(filename) - - def _writedefs(self, locations, filename): - tofile = open(filename, 'w') - try: - for location in locations: - err = '%s:%d: - %s\n' % (location.filename, - location.lineno, location.note) - echo(err) - tofile.write(err) - finally: - tofile.close() - - def show_doc(self, docs, altview=False): - if docs: - echo(docs) - - def preview_changes(self, diffs): - echo(diffs) - return self.y_or_n('Do the changes? ') - - def local_command(self, name, callback, key=None, prefix=False): - self._add_command(name, callback, key, prefix, - prekey=self.get('local_prefix')) - - def global_command(self, name, callback, key=None, prefix=False): - self._add_command(name, callback, key, prefix, - prekey=self.get('global_prefix')) - - def add_hook(self, name, callback, hook): - mapping = {'before_save': 'FileWritePre,BufWritePre', - 'after_save': 'FileWritePost,BufWritePost', - 'exit': 'VimLeave'} - self._add_function(name, callback) - vim.command('autocmd %s *.py call %s()' % - (mapping[hook], _vim_name(name))) - - def _add_command(self, name, callback, key, prefix, prekey): - self._add_function(name, callback, prefix) - vim.command('command! -range %s call %s()' % - (_vim_name(name), _vim_name(name))) - if key is not None: - key = prekey + key.replace(' ', '') - vim.command('map %s :call %s()' % (key, _vim_name(name))) - - def _add_function(self, name, callback, prefix=False): - globals()[name] = callback - arg = 'None' if prefix else '' - vim.command('function! %s()\n' % _vim_name(name) + - 'python ropevim.%s(%s)\n' % (name, arg) + - 'endfunction\n') - - def _completion_data(self, proposal): - return proposal - - _docstring_re = re.compile('^[\s\t\n]*([^\n]*)') - def _extended_completion(self, proposal): - # we are using extended complete and return dicts instead of strings. - # `ci` means "completion item". see `:help complete-items` - ci = {'word': proposal.name} - - scope = proposal.scope[0].upper() - type_ = proposal.type - info = None - - if proposal.scope == 'parameter_keyword': - scope = ' ' - type_ = 'param' - if not hasattr(proposal, 'get_default'): - # old version of rope - pass - else: - default = proposal.get_default() - if default is None: - info = '*' - else: - info = '= %s' % default - - elif proposal.scope == 'keyword': - scope = ' ' - type_ = 'keywd' - - elif proposal.scope == 'attribute': - scope = 'M' - if proposal.type == 'function': - type_ = 'meth' - elif proposal.type == 'instance': - type_ = 'prop' - - elif proposal.type == 'function': - type_ = 'func' - - elif proposal.type == 'instance': - type_ = 'inst' - - elif proposal.type == 'module': - type_ = 'mod' - - if info is None: - obj_doc = proposal.get_doc() - if obj_doc: - info = self._docstring_re.match(obj_doc).group(1) - else: - info = '' - - if type_ is None: - type_ = ' ' - else: - type_ = type_.ljust(5)[:5] - ci['menu'] = ' '.join((scope, type_, info)) - ret = u'{%s}' % \ - u','.join(u'"%s":"%s"' % \ - (key, value.replace('"', '\\"')) \ - for (key, value) in ci.iteritems()) - return ret - - -def _vim_name(name): - tokens = name.split('_') - newtokens = ['Rope'] + [token.title() for token in tokens] - return ''.join(newtokens) - - -class VimProgress(object): - - def __init__(self, name): - self.name = name - self.last = 0 - echo('%s ... ' % self.name) - - def update(self, percent): - try: - vim.eval('getchar(0)') - except vim.error: - raise KeyboardInterrupt('Task %s was interrupted!' % self.name) - if percent > self.last + 4: - echo('%s ... %s%%%%' % (self.name, percent)) - self.last = percent - - def done(self): - echo('%s ... done' % self.name) - - -def echo(message): - if isinstance(message, unicode): - message = message.encode(vim.eval('&encoding')) - print message - -def call(command): - return vim.eval(command) - - -class _ValueCompleter(object): - - def __init__(self): - self.values = [] - vim.command('python import vim') - vim.command('function! RopeValueCompleter(A, L, P)\n' - 'python args = [vim.eval("a:" + p) for p in "ALP"]\n' - 'python ropevim._completer(*args)\n' - 'return s:completions\n' - 'endfunction\n') - - def __call__(self, arg_lead, cmd_line, cursor_pos): - result = [proposal.name for proposal in self.values \ - if proposal.name.startswith(arg_lead)] - vim.command('let s:completions = %s' % result) - - -variables = {'ropevim_enable_autoimport': 1, - 'ropevim_autoimport_underlineds': 0, - 'ropevim_codeassist_maxfixes' : 1, - 'ropevim_enable_shortcuts' : 1, - 'ropevim_autoimport_modules': '[]', - 'ropevim_confirm_saving': 0, - 'ropevim_local_prefix': '"r"', - 'ropevim_global_prefix': '"p"', - 'ropevim_vim_completion': 0, - 'ropevim_guess_project': 0} - -shortcuts = {'code_assist': '', - 'lucky_assist': '', - 'goto_definition': 'g', - 'show_doc': 'd', - 'find_occurrences': 'f'} - -insert_shortcuts = {'code_assist': '', - 'lucky_assist': ''} - -def _init_variables(): - for variable, default in variables.items(): - vim.command('if !exists("g:%s")\n' % variable + - ' let g:%s = %s\n' % (variable, default)) - -def _enable_shortcuts(env): - if env.get('enable_shortcuts'): - for command, shortcut in shortcuts.items(): - vim.command('map %s :call %s()' % - (shortcut, _vim_name(command))) - for command, shortcut in insert_shortcuts.items(): - command_name = _vim_name(command) + 'InsertMode' - vim.command('func! %s()\n' % command_name + - 'call %s()\n' % _vim_name(command) + - 'return ""\n' - 'endfunc') - vim.command('imap %s =%s()' % (shortcut, command_name)) - -def _add_menu(env): - project = ['open_project', 'close_project', 'find_file', 'undo', 'redo'] - refactor = ['rename', 'extract_variable', 'extract_method', 'inline', - 'move', 'restructure', 'use_function', 'introduce_factory', - 'change_signature', 'rename_current_module', - 'move_current_module', 'module_to_package'] - assists = ['code_assist', 'goto_definition', 'show_doc', 'find_occurrences', - 'lucky_assist', 'jump_to_global', 'show_calltip'] - vim.command('silent! aunmenu Ropevim') - for index, items in enumerate([project, assists, refactor]): - if index != 0: - vim.command('amenu &Ropevim.-SEP%s- :' % index) - for name in items: - item = '\ '.join(token.title() for token in name.split('_')) - for command in ['amenu', 'vmenu']: - vim.command('%s &Ropevim.%s :call %s()' % - (command, item, _vim_name(name))) - - -ropemode.decorators.logger.message = echo -ropemode.decorators.logger.only_short = True -_completer = _ValueCompleter() - -_init_variables() -_env = VimUtils() -_interface = ropemode.interface.RopeMode(env=_env) -_interface.init() -_enable_shortcuts(_env) -_add_menu(_env) diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/ropevim.vim --- a/vim/sadness/ropevim/src/ropevim/ropevim.vim Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -function! LoadRope() -python << EOF -import ropevim -EOF -endfunction - -call LoadRope() diff -r 27ec8da23760 -r b503af8e2bbe vim/sadness/ropevim/src/ropevim/setup.py --- a/vim/sadness/ropevim/src/ropevim/setup.py Thu Nov 10 10:12:24 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -extra_kwargs = {} -try: - from setuptools import setup - extra_kwargs['install_requires'] = ['rope >= 0.9.3', 'ropemode'] - extra_kwargs['zip_safe'] = False -except ImportError: - from distutils.core import setup - - -classifiers=[ - 'Development Status :: 4 - Beta', - 'Operating System :: OS Independent', - 'Environment :: X11 Applications', - 'Environment :: Win32 (MS Windows)', - # Have not been tested on MacOS - # 'Environment :: MacOS X', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: GNU General Public License (GPL)', - 'Natural Language :: English', - 'Programming Language :: Python', - 'Topic :: Software Development'] - -def get_long_description(): - lines = open('README.txt').read().splitlines(False) - end = lines.index('Setting Up') - return '\n' + '\n'.join(lines[:end]) + '\n' - -setup(name='ropevim', - version='0.3-rc', - description='A vim plugin for using rope python refactoring library', - long_description=get_long_description(), - py_modules=['ropevim'], - author='Ali Gholami Rudi', - author_email='aligrudi@users.sourceforge.net', - url='http://rope.sf.net/ropevim.html', - license='GNU GPL', - classifiers=classifiers, - requires=['ropemode'], - data_files=[('share/vim/plugin', ['ropevim.vim'])], - **extra_kwargs -)