diff --git a/.gitignore b/.gitignore
index b981b0a8a..91e559379 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,35 +1,19 @@
.hg
.hgignore
.metadata
-External Plug-in Libraries
plugins/com.python.pydev.docs/merged_homepage/final/*.*
-plugins/org.python.pydev.releng/results/*
-plugins/com.python.pydev.releng/results/*
-org.python.pydev/bin
-plugins/com.python.pydev.fastparser/bin
-plugins/org.python.pydev.refactoring/bin
-plugins/org.python.pydev.parser/bin
plugins/com.python.pydev.docs/new_homepage/final/*
plugins/com.python.pydev.docs/open_source/final/*
-features/org.python.pydev.feature/bin/
-features/org.python.pydev.django_templates.feature/bin/
git-kdiff3
-plugins/com.python.pydev.docs/.pydevproject
-plugins/com.python.pydev.fastparser/.pydevproject
-plugins/com.python.pydev/.pydevproject
-plugins/org.python.pydev.debug/.pydevproject
-plugins/org.python.pydev.help/.pydevproject
-plugins/org.python.pydev.jython/.pydevproject
-plugins/org.python.pydev.runalltests/bin/
-plugins/org.python.pydev/.pydevproject
+plugins/org.python.pydev.jython/cachedir
plugins/**/bin/
-plugins/com.python.pydev.pytoobjectivec/
+features/**/bin/
+plugins/**/indexcache/
*.pyc
*.idx
*.orig
CVS
.svn
-indexcache
v1_indexcache
v1_astmanager
*.pyc
@@ -43,9 +27,6 @@ Thumbs.db
ProfileProject
de.loskutov.anyedit.AnyEditTools.prefs
*asthelper.completions
-plugins/org.kacprzak.eclipse.django.editor.plugin/
-plugins/org.python.pydev.django_templates/bin
-etc/
plugins/org.python.pydev/tests/pysrc/extendable/bootstrap_dll/umath.pyd
plugins/com.python.pydev.runalltests/Configuration*
external-sources
@@ -67,4 +48,7 @@ Desktop DB
.fseventsd
.syncinfo
.TemporaryItems
-report/
+plugins/org.python.pydev/pysrc/.git
+plugins/org.python.pydev/pysrc/.project
+plugins/org.python.pydev/pysrc/.settings
+**/v2_indexcache/**
\ No newline at end of file
diff --git a/builders/org.python.pydev.build/build.xml b/builders/org.python.pydev.build/build.xml
index d357c0232..8051699ab 100644
--- a/builders/org.python.pydev.build/build.xml
+++ b/builders/org.python.pydev.build/build.xml
@@ -162,7 +162,7 @@
-
+
@@ -212,7 +212,7 @@
If this doesn't properly work, the command above should be used.
- - - - - - - - - - - - - - - - - -->
-
+
diff --git a/builders/org.python.pydev.build/build_cmd.bat b/builders/org.python.pydev.build/build_cmd.bat
index 7d1edaa3a..e32b6e510 100644
--- a/builders/org.python.pydev.build/build_cmd.bat
+++ b/builders/org.python.pydev.build/build_cmd.bat
@@ -2,65 +2,70 @@
@echo X:\pydev\builders\org.python.pydev.build\build_cmd.bat
+@echo If needed to update version:
+@echo x:
+@echo cd x:\pydev
+@echo python update_version.py 3.6.0
+
@echo Note: instructions for properly updating the variables are in the end of the file
@echo The contents here may just be copied into cmd.exe or some other shell (just note that
@echo in some cases a call to git may stop executing, so, you may need to copy the commands in chunks).
set BRANCH=development
+set DRIVE=x:
set BASE_LOCAL_PYDEV_GIT=x:\pydev
-set BUILD_DIR=W:\git_build_dir
-set DEPLOY_DIR=W:\git_deploy_dir
-set JAVA_HOME=D:\bin\jdk1.7.0_10
-set MAVEN_BIN=D:\bin\apache-maven-3.0.5\bin
-set GIT_EXECUTABLE="d:\bin\git\bin\git.exe"
-set ECLIPSE_CLEAN=D:\bin\eclipse_43_final_clean
-set LAUNCHER_PLUGIN=org.eclipse.equinox.launcher_1.3.0.v20130327-1440
-set BUILDER_PLUGIN=org.eclipse.pde.build_3.8.100.v20130514-1028
-set KEYSTORE=%DEPLOY_DIR%\pydevkeystore
+set BUILD_DIR=X:\pydev_build\build_dir
+set DEPLOY_DIR=X:\pydev_build\deploy_dir
+set JAVA_HOME=C:\bin\jdk1.7.0_55
+set MAVEN_BIN=C:\bin\maven-3.2.1\bin
+set GIT_EXECUTABLE="p:\git\bin\git.exe"
+set ECLIPSE_CLEAN=C:\bin\eclipse45final
+set LAUNCHER_PLUGIN=org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar
+set BUILDER_PLUGIN=org.eclipse.pde.build_3.9.100.v20150521-1524
+set KEYSTORE=X:\release_tools\pydevkeystore
set KEYSTORE_ALIAS=pydev
-set SIGN_KEYSTORE=%DEPLOY_DIR%\pydevkeystore
+set SIGN_KEYSTORE=X:\release_tools\pydevkeystore
set SIGN_ALIAS=pydev
SET MAVEN_OPTS=-Xmx1024m
+
set BASEOS=win32
set BASEWS=win32
set BASEARCH=x86
set PATH=
-set PATH=d:\bin\python265;%PATH%
-set PATH=D:\bin\FastCopy199r4;%PATH%
+set PATH=C:\bin\Python27
+set PATH=p:\FastCopy211;%PATH%
set PATH=C:\Windows\system32;%PATH%
set PATH=%MAVEN_BIN%;%PATH%
set PATH=%JAVA_HOME%\bin;%PATH%
-set PATH=d:\bin\git\bin;%PATH%
-set PATH=%ECLIPSE_CLEAN%\plugins\org.apache.ant_1.8.4.v201303080030\bin;%PATH%
+set PATH=p:\git\bin;%PATH%
+set PATH=%ECLIPSE_CLEAN%\plugins\org.apache.ant_1.9.2.v201404171502\bin;%PATH%
@echo actual build command
mkdir %BUILD_DIR%
mkdir %DEPLOY_DIR%
-w:
+%DRIVE%
cd %BUILD_DIR%
git clone %BASE_LOCAL_PYDEV_GIT%
@echo git clone git://github.com/fabioz/Pydev.git -- this could be used when building against the base git instead of a local git
cd Pydev
-git clean -f -d builders
-git clean -f -d features
-git clean -f -d I.PyDev
-git clean -f -d plugins
-git clean -f -d repo
-del *.* /Q
-rm -rf features\org.python.pydev.p2-repo
git reset --hard
+git clean -f -d -x
git checkout -f
git remote update
git checkout %BRANCH%
git pull origin %BRANCH%
@echo If copied/pasted into cmd.exe, it will break here
+@echo Create builtin modules
+set PYTHONPATH=%BUILD_DIR%/Pydev/plugins/org.python.pydev/pysrc
+C:\tools\Miniconda32\envs\py27_32\python %BUILD_DIR%/Pydev/plugins/org.python.pydev/pysrc/build_tools/build_binaries_windows.py
+
@echo to clean after the build: -DcleanAfter.set=true
-mvn -o install
+mvn install
@@ -68,8 +73,8 @@ mvn -o install
@echo Notes on customizing parameters / making the build:
@echo If signing is needed, then the keystore needs to be created before (see commands below)
-@echo and also a variable named STOREPASS must be set with the same password used when the keystore is created
-@echo i.e.: set STOREPASS=my store pass
+@echo and also a variable named SIGN_STOREPASS must be set with the same password used when the keystore is created
+@echo i.e.: set SIGN_STOREPASS=my store pass
@echo
@echo BRANCH: the branch to be used to do the build (e.g.: master/development/etc) -- it's recommended that you create your own branch from a base branch in pydev and use it
@echo
@@ -79,14 +84,14 @@ mvn -o install
@echo
@echo DEPLOY_DIR: The directory where the final artifacts of the build will be put
@echo
-@echo KEYSTORE: A keystore needs to be created and available at %DEPLOY_DIR%\pydevkeystore
+@echo KEYSTORE: A keystore needs to be created and available at X:\release_tools\pydevkeystore
@echo
-@echo %JAVA_HOME%\bin\keytool -genkey -dname "CN=Brainwy Software, OU=PyDev, O=Brainwy, L=Florianopolis, ST=SC, C=Brazil" -keystore %DEPLOY_DIR%\pydevkeystore -alias pydev -validity 3650
-@echo %JAVA_HOME%\bin\keytool -selfcert -alias pydev -keystore %DEPLOY_DIR%\pydevkeystore -validity 3650
-@echo %JAVA_HOME%\bin\keytool -export -keystore %DEPLOY_DIR%\pydevkeystore -alias pydev -file pydev_certificate.cer
+@echo %JAVA_HOME%\bin\keytool -genkey -dname "CN=Brainwy Software, OU=PyDev, O=Brainwy, L=Florianopolis, ST=SC, C=Brazil" -keystore X:\release_tools\pydevkeystore -alias pydev -validity 3650
+@echo %JAVA_HOME%\bin\keytool -selfcert -alias pydev -keystore X:\release_tools\pydevkeystore -validity 3650
+@echo %JAVA_HOME%\bin\keytool -export -keystore X:\release_tools\pydevkeystore -alias pydev -file pydev_certificate.cer
@echo
@echo To sign
-@echo %JAVA_HOME%\bin\jarsigner -keystore %DEPLOY_DIR%\pydevkeystore -storepass PASSUSED JAR_TO_SIGN pydev
+@echo %JAVA_HOME%\bin\jarsigner -keystore X:\release_tools\pydevkeystore -storepass PASSUSED JAR_TO_SIGN pydev
@echo
@echo
@echo KEYSTORE_ALIAS: The alias used during the keystore creation
diff --git a/features/org.python.pydev.feature/feature.xml b/features/org.python.pydev.feature/feature.xml
index 32784008e..2c7531c33 100644
--- a/features/org.python.pydev.feature/feature.xml
+++ b/features/org.python.pydev.feature/feature.xml
@@ -1,243 +1,243 @@
-
-
-
-
-
- Python Development Environment
-
-
-
- © Appcelerator, Inc.
-
-
-
- Eclipse Public License - v 1.0
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT’S ACCEPTANCE OF THIS AGREEMENT.
-
-1. DEFINITIONS
-
-"Contribution" means:
-
- a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
- b) in the case of each subsequent Contributor:
-
- i)changes to the Program, and
-
- ii)additions to the Program;
-
- where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor’s behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
-
-"Contributor" means any person or entity that distributes the Program.
-
-"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
-
-"Program" means the Contributions distributed in accordance with this Agreement.
-
-"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
-
-2. GRANT OF RIGHTS
-
-a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
-
-b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
-
-c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient’s responsibility to acquire that license before distributing the Program.
-
-d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
-
-3. REQUIREMENTS
-
-A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
-
- a) it complies with the terms and conditions of this Agreement; and
-
- b) its license agreement:
-
- i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
-
- ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
-
- iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
-
- iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
-
-When the Program is made available in source code form:
-
- a) it must be made available under this Agreement; and
-
- b) a copy of this Agreement must be included with each copy of the Program.
-
-Contributors may not remove or alter any copyright notices contained within the Program.
-
-Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
-
-4. COMMERCIAL DISTRIBUTION
-
-Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
-
-For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor’s responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
-
-5. NO WARRANTY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
-
-6. DISCLAIMER OF LIABILITY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-7. GENERAL
-
-If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient’s patent(s), then such Recipient’s rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
-
-All Recipient’s rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient’s rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient’s obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
-
-Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ Python Development Environment
+
+
+
+ © Fabio Zadrozny.
+
+
+
+ Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT’S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+ a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+ b) in the case of each subsequent Contributor:
+
+ i)changes to the Program, and
+
+ ii)additions to the Program;
+
+ where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor’s behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient’s responsibility to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+ a) it complies with the terms and conditions of this Agreement; and
+
+ b) its license agreement:
+
+ i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+ iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+ iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+ a) it must be made available under this Agreement; and
+
+ b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor’s responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient’s patent(s), then such Recipient’s rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient’s rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient’s rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient’s obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/features/org.python.pydev.feature/pom.xml b/features/org.python.pydev.feature/pom.xml
index 73473c3dc..536f4157f 100644
--- a/features/org.python.pydev.feature/pom.xml
+++ b/features/org.python.pydev.feature/pom.xml
@@ -1,25 +1,25 @@
-
-
-
- 4.0.0
-
- org.python.pydev
- features
- 3.0.0-SNAPSHOT
- ../pom.xml
-
- org.python.pydev
- org.python.pydev.feature
- eclipse-feature
-
+
+
+
+ 4.0.0
+
+ org.python.pydev
+ features
+ 4.5.3-SNAPSHOT
+ ../pom.xml
+
+ org.python.pydev
+ org.python.pydev.feature
+ eclipse-feature
+
diff --git a/features/org.python.pydev.mylyn.feature/feature.xml b/features/org.python.pydev.mylyn.feature/feature.xml
index fb4d94a52..cd9261e44 100644
--- a/features/org.python.pydev.mylyn.feature/feature.xml
+++ b/features/org.python.pydev.mylyn.feature/feature.xml
@@ -2,7 +2,7 @@
@@ -35,7 +35,7 @@
id="org.python.pydev.mylyn"
download-size="0"
install-size="0"
- version="0.4.0"
+ version="0.6.0"
unpack="false"/>
diff --git a/features/org.python.pydev.mylyn.feature/pom.xml b/features/org.python.pydev.mylyn.feature/pom.xml
index a4a509b5d..b3594d940 100644
--- a/features/org.python.pydev.mylyn.feature/pom.xml
+++ b/features/org.python.pydev.mylyn.feature/pom.xml
@@ -1,26 +1,26 @@
-
-
-
- 4.0.0
-
- org.python.pydev
- features
- 3.0.0-SNAPSHOT
- ../pom.xml
-
- org.python.pydev
- org.python.pydev.mylyn.feature
- 0.4.0
- eclipse-feature
-
+
+
+
+ 4.0.0
+
+ org.python.pydev
+ features
+ 4.5.3-SNAPSHOT
+ ../pom.xml
+
+ org.python.pydev
+ org.python.pydev.mylyn.feature
+ 0.6.0
+ eclipse-feature
+
diff --git a/features/org.python.pydev.p2-repo/pom.xml b/features/org.python.pydev.p2-repo/pom.xml
index bf39d6d07..bc4fbd23e 100644
--- a/features/org.python.pydev.p2-repo/pom.xml
+++ b/features/org.python.pydev.p2-repo/pom.xml
@@ -1,71 +1,71 @@
-
-
-
-
- 4.0.0
-
-
- org.python.pydev
- features
- 3.0.0-SNAPSHOT
- ../pom.xml
-
-
- org.python.pydev.p2-repo
- eclipse-repository
- Pydev p2 Repository
-
-
-
-
- org.eclipse.tycho.extras
- tycho-eclipserun-plugin
- ${tycho-version}
-
- -consoleLog -application org.eclipse.equinox.p2.repository.repo2runnable -source file:${basedir}/target/repository/ -destination ${basedir}/target/runnable/
-
-
- org.eclipse.equinox.p2.core.feature
- eclipse-feature
-
-
- org.eclipse.equinox.p2.discovery.feature
- eclipse-feature
-
-
- org.eclipse.equinox.p2.extras.feature
- eclipse-feature
-
-
-
-
- ${repository.id}
- p2
- ${repository.url}
-
-
-
-
-
-
- eclipse-run
-
- package
-
-
-
-
-
-
+
+
+
+
+ 4.0.0
+
+
+ org.python.pydev
+ features
+ 4.5.3-SNAPSHOT
+ ../pom.xml
+
+
+ org.python.pydev.p2-repo
+ eclipse-repository
+ Pydev p2 Repository
+
+
+
+
+ org.eclipse.tycho.extras
+ tycho-eclipserun-plugin
+ ${tycho-version}
+
+ -consoleLog -application org.eclipse.equinox.p2.repository.repo2runnable -source file:${basedir}/target/repository/ -destination ${basedir}/target/runnable/
+
+
+ org.eclipse.equinox.p2.core.feature
+ eclipse-feature
+
+
+ org.eclipse.equinox.p2.discovery.feature
+ eclipse-feature
+
+
+ org.eclipse.equinox.p2.extras.feature
+ eclipse-feature
+
+
+
+
+ ${repository.id}
+ p2
+ ${repository.url}
+
+
+
+
+
+
+ eclipse-run
+
+ package
+
+
+
+
+
+
diff --git a/features/pom.xml b/features/pom.xml
index e92338220..67ee9696f 100644
--- a/features/pom.xml
+++ b/features/pom.xml
@@ -1,40 +1,40 @@
-
-
-
- 4.0.0
-
- org.python.pydev
- parent
- 3.0.0-SNAPSHOT
- ../pom.xml
-
- features
- Pydev Features Parent
- pom
-
- org.python.pydev.feature
- org.python.pydev.mylyn.feature
- org.python.pydev.p2-repo
-
-
-
-
- org.eclipse.tycho
- tycho-maven-plugin
- ${tycho-version}
- true
-
-
-
-
+
+
+
+ 4.0.0
+
+ org.python.pydev
+ parent
+ 4.5.3-SNAPSHOT
+ ../pom.xml
+
+ features
+ Pydev Features Parent
+ pom
+
+ org.python.pydev.feature
+ org.python.pydev.mylyn.feature
+ org.python.pydev.p2-repo
+
+
+
+
+ org.eclipse.tycho
+ tycho-maven-plugin
+ ${tycho-version}
+ true
+
+
+
+
diff --git a/plugins/com.python.pydev.analysis/META-INF/MANIFEST.MF b/plugins/com.python.pydev.analysis/META-INF/MANIFEST.MF
index 828b0e2e7..14c5f3194 100644
--- a/plugins/com.python.pydev.analysis/META-INF/MANIFEST.MF
+++ b/plugins/com.python.pydev.analysis/META-INF/MANIFEST.MF
@@ -1,43 +1,46 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Analysis Plug-in
-Bundle-SymbolicName: com.python.pydev.analysis; singleton:=true
-Bundle-Version: 3.0.0.qualifier
-Bundle-Activator: com.python.pydev.analysis.AnalysisPlugin
-Bundle-Vendor: Aptana
-Bundle-Localization: plugin
-Eclipse-BundleShape: dir
-Require-Bundle: org.eclipse.ui,
- org.eclipse.core.runtime,
- org.eclipse.jface.text,
- org.python.pydev;bundle-version="2.7.6",
- com.python.pydev,
- org.junit;bundle-version="4.0";resolution:=optional,
- org.python.pydev.core,
- org.python.pydev.ast,
- org.python.pydev.parser,
- org.eclipse.core.resources,
- org.eclipse.ui.editors,
- org.eclipse.ui.workbench.texteditor,
- org.eclipse.search,
- org.eclipse.ui.ide,
- org.python.pydev.jython,
- org.python.pydev.debug,
- org.python.pydev.shared_ui,
- org.python.pydev.shared_core
-Bundle-ActivationPolicy: lazy
-Bundle-ClassPath: analysis.jar
-Export-Package: com.python.pydev.analysis,
- com.python.pydev.analysis.actions,
- com.python.pydev.analysis.additionalinfo,
- com.python.pydev.analysis.additionalinfo.builders,
- com.python.pydev.analysis.additionalinfo.dependencies,
- com.python.pydev.analysis.builder,
- com.python.pydev.analysis.ctrl_1,
- com.python.pydev.analysis.messages,
- com.python.pydev.analysis.organizeimports,
- com.python.pydev.analysis.scopeanalysis,
- com.python.pydev.analysis.tabnanny,
- com.python.pydev.analysis.ui,
- com.python.pydev.analysis.visitors
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Analysis Plug-in
+Bundle-SymbolicName: com.python.pydev.analysis; singleton:=true
+Bundle-Version: 4.5.3.qualifier
+Bundle-Activator: com.python.pydev.analysis.AnalysisPlugin
+Bundle-Vendor: Aptana
+Bundle-Localization: plugin
+Eclipse-BundleShape: dir
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.jface.text,
+ org.python.pydev;bundle-version="[4.5.3,4.5.4)",
+ com.python.pydev;bundle-version="[4.5.3,4.5.4)",
+ org.junit;bundle-version="4.0";resolution:=optional,
+ org.python.pydev.core;bundle-version="[4.5.3,4.5.4)",
+ org.python.pydev.ast;bundle-version="[4.5.3,4.5.4)",
+ org.python.pydev.parser;bundle-version="[4.5.3,4.5.4)",
+ org.eclipse.core.resources,
+ org.eclipse.ui.editors,
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.search,
+ org.eclipse.ui.ide,
+ org.python.pydev.jython;bundle-version="[4.5.3,4.5.4)",
+ org.python.pydev.debug;bundle-version="[4.5.3,4.5.4)",
+ org.python.pydev.shared_ui;bundle-version="[4.5.3,4.5.4)",
+ org.python.pydev.shared_core;bundle-version="[4.5.3,4.5.4)",
+ org.eclipse.ltk.core.refactoring,
+ org.python.pydev.refactoring,
+ org.eclipse.ltk.ui.refactoring
+Bundle-ActivationPolicy: lazy
+Bundle-ClassPath: analysis.jar
+Export-Package: com.python.pydev.analysis,
+ com.python.pydev.analysis.actions,
+ com.python.pydev.analysis.additionalinfo,
+ com.python.pydev.analysis.additionalinfo.builders,
+ com.python.pydev.analysis.additionalinfo.dependencies,
+ com.python.pydev.analysis.builder,
+ com.python.pydev.analysis.ctrl_1,
+ com.python.pydev.analysis.messages,
+ com.python.pydev.analysis.organizeimports,
+ com.python.pydev.analysis.scopeanalysis,
+ com.python.pydev.analysis.tabnanny,
+ com.python.pydev.analysis.ui,
+ com.python.pydev.analysis.visitors
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
diff --git a/plugins/com.python.pydev.analysis/icons/Copy of opentype.gif b/plugins/com.python.pydev.analysis/icons/Copy of opentype.gif
deleted file mode 100644
index e8c49481c..000000000
Binary files a/plugins/com.python.pydev.analysis/icons/Copy of opentype.gif and /dev/null differ
diff --git a/plugins/com.python.pydev.analysis/icons/python_file.gif b/plugins/com.python.pydev.analysis/icons/python_file.gif
new file mode 100644
index 000000000..6a85042c2
Binary files /dev/null and b/plugins/com.python.pydev.analysis/icons/python_file.gif differ
diff --git a/plugins/com.python.pydev.analysis/plugin.xml b/plugins/com.python.pydev.analysis/plugin.xml
index 64f07efba..b2a7cbf78 100644
--- a/plugins/com.python.pydev.analysis/plugin.xml
+++ b/plugins/com.python.pydev.analysis/plugin.xml
@@ -3,7 +3,7 @@
-
+
-
+
-
+
@@ -46,7 +46,7 @@
-
+
@@ -62,11 +62,11 @@
-
+
-
+
@@ -82,6 +82,29 @@
+
+
+
+
+
+
+
+
+
@@ -162,7 +185,7 @@
-
+
-
-
- 4.0.0
-
- org.python.pydev
- plugins
- 3.0.0-SNAPSHOT
- ../pom.xml
-
- org.python.pydev
- com.python.pydev.analysis
- eclipse-test-plugin
-
+
+
+
+ 4.0.0
+
+ org.python.pydev
+ plugins
+ 4.5.3-SNAPSHOT
+ ../pom.xml
+
+ org.python.pydev
+ com.python.pydev.analysis
+ eclipse-test-plugin
+
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AbstractAnalysisPreferences.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AbstractAnalysisPreferences.java
index 84f161e37..b9a869963 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AbstractAnalysisPreferences.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AbstractAnalysisPreferences.java
@@ -11,28 +11,27 @@
public abstract class AbstractAnalysisPreferences implements IAnalysisPreferences {
- private volatile Map typeToIgnoreMessage;
+ private static final Map typeToIgnoreMessage = new HashMap();
+ static {
+ typeToIgnoreMessage.put(TYPE_UNUSED_IMPORT, MSG_TO_IGNORE_TYPE_UNUSED_IMPORT);
+ typeToIgnoreMessage.put(TYPE_UNUSED_VARIABLE, MSG_TO_IGNORE_TYPE_UNUSED_VARIABLE);
+ typeToIgnoreMessage.put(TYPE_UNUSED_PARAMETER, MSG_TO_IGNORE_TYPE_UNUSED_PARAMETER);
+ typeToIgnoreMessage.put(TYPE_UNDEFINED_VARIABLE, MSG_TO_IGNORE_TYPE_UNDEFINED_VARIABLE);
+ typeToIgnoreMessage.put(TYPE_DUPLICATED_SIGNATURE, MSG_TO_IGNORE_TYPE_DUPLICATED_SIGNATURE);
+ typeToIgnoreMessage.put(TYPE_REIMPORT, MSG_TO_IGNORE_TYPE_REIMPORT);
+ typeToIgnoreMessage.put(TYPE_UNRESOLVED_IMPORT, MSG_TO_IGNORE_TYPE_UNRESOLVED_IMPORT);
+ typeToIgnoreMessage.put(TYPE_NO_SELF, MSG_TO_IGNORE_TYPE_NO_SELF);
+ typeToIgnoreMessage.put(TYPE_UNUSED_WILD_IMPORT, MSG_TO_IGNORE_TYPE_UNUSED_WILD_IMPORT);
+ typeToIgnoreMessage.put(TYPE_UNDEFINED_IMPORT_VARIABLE, MSG_TO_IGNORE_TYPE_UNDEFINED_IMPORT_VARIABLE);
+ typeToIgnoreMessage.put(TYPE_NO_EFFECT_STMT, MSG_TO_IGNORE_TYPE_NO_EFFECT_STMT);
+ typeToIgnoreMessage.put(TYPE_INDENTATION_PROBLEM, MSG_TO_IGNORE_TYPE_INDENTATION_PROBLEM);
+ typeToIgnoreMessage.put(TYPE_ASSIGNMENT_TO_BUILT_IN_SYMBOL,
+ MSG_TO_IGNORE_TYPE_ASSIGNMENT_TO_BUILT_IN_SYMBOL);
+ typeToIgnoreMessage.put(TYPE_PEP8, MSG_TO_IGNORE_TYPE_PEP8);
+ typeToIgnoreMessage.put(TYPE_ARGUMENTS_MISATCH, MSG_TO_IGNORE_TYPE_ARGUMENTS_MISATCH);
+ }
public String getRequiredMessageToIgnore(int type) {
- if (typeToIgnoreMessage == null) {
- typeToIgnoreMessage = new HashMap();
- typeToIgnoreMessage.put(TYPE_UNUSED_IMPORT, MSG_TO_IGNORE_TYPE_UNUSED_IMPORT);
- typeToIgnoreMessage.put(TYPE_UNUSED_VARIABLE, MSG_TO_IGNORE_TYPE_UNUSED_VARIABLE);
- typeToIgnoreMessage.put(TYPE_UNUSED_PARAMETER, MSG_TO_IGNORE_TYPE_UNUSED_PARAMETER);
- typeToIgnoreMessage.put(TYPE_UNDEFINED_VARIABLE, MSG_TO_IGNORE_TYPE_UNDEFINED_VARIABLE);
- typeToIgnoreMessage.put(TYPE_DUPLICATED_SIGNATURE, MSG_TO_IGNORE_TYPE_DUPLICATED_SIGNATURE);
- typeToIgnoreMessage.put(TYPE_REIMPORT, MSG_TO_IGNORE_TYPE_REIMPORT);
- typeToIgnoreMessage.put(TYPE_UNRESOLVED_IMPORT, MSG_TO_IGNORE_TYPE_UNRESOLVED_IMPORT);
- typeToIgnoreMessage.put(TYPE_NO_SELF, MSG_TO_IGNORE_TYPE_NO_SELF);
- typeToIgnoreMessage.put(TYPE_UNUSED_WILD_IMPORT, MSG_TO_IGNORE_TYPE_UNUSED_WILD_IMPORT);
- typeToIgnoreMessage.put(TYPE_UNDEFINED_IMPORT_VARIABLE, MSG_TO_IGNORE_TYPE_UNDEFINED_IMPORT_VARIABLE);
- typeToIgnoreMessage.put(TYPE_NO_EFFECT_STMT, MSG_TO_IGNORE_TYPE_NO_EFFECT_STMT);
- typeToIgnoreMessage.put(TYPE_INDENTATION_PROBLEM, MSG_TO_IGNORE_TYPE_INDENTATION_PROBLEM);
- typeToIgnoreMessage.put(TYPE_ASSIGNMENT_TO_BUILT_IN_SYMBOL,
- MSG_TO_IGNORE_TYPE_ASSIGNMENT_TO_BUILT_IN_SYMBOL);
- typeToIgnoreMessage.put(TYPE_PEP8, MSG_TO_IGNORE_TYPE_PEP8);
- typeToIgnoreMessage.put(TYPE_ARGUMENTS_MISATCH, MSG_TO_IGNORE_TYPE_ARGUMENTS_MISATCH);
- }
return typeToIgnoreMessage.get(type);
}
}
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPlugin.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPlugin.java
index c631f9cc6..dada3748b 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPlugin.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPlugin.java
@@ -7,7 +7,10 @@
package com.python.pydev.analysis;
import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
@@ -20,14 +23,20 @@
import org.python.pydev.core.IDefinition;
import org.python.pydev.core.IModule;
import org.python.pydev.core.IPythonNature;
+import org.python.pydev.core.IToken;
import org.python.pydev.editor.codecompletion.revisited.CompletionStateFactory;
+import org.python.pydev.editor.codecompletion.revisited.modules.SourceToken;
import org.python.pydev.editor.codecompletion.revisited.visitors.Definition;
+import org.python.pydev.editor.codecompletion.revisited.visitors.HeuristicFindAttrs;
import org.python.pydev.editor.model.ItemPointer;
import org.python.pydev.editor.refactoring.PyRefactoringFindDefinition;
+import org.python.pydev.parser.jython.ast.FunctionDef;
+import org.python.pydev.parser.jython.ast.exprType;
import org.python.pydev.shared_ui.ImageCache;
import org.python.pydev.shared_ui.UIConstants;
import com.python.pydev.analysis.additionalinfo.IInfo;
+import com.python.pydev.analysis.additionalinfo.ReferenceSearchesLucene;
/**
* The main plugin class to be used in the desktop.
@@ -49,6 +58,7 @@ public AnalysisPlugin() {
/**
* This method is called upon plug-in activation
*/
+ @Override
public void start(BundleContext context) throws Exception {
super.start(context);
@@ -57,21 +67,21 @@ public void start(BundleContext context) throws Exception {
// Display.getDefault().asyncExec(new Runnable() {
// public void run() {
// IWorkbench workbench = PlatformUI.getWorkbench();
- //
+ //
// activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
// handleActivePage();
- //
+ //
// workbench.addWindowListener(new IWindowListener() {
- //
+ //
// public void windowOpened(IWorkbenchWindow window) {
// }
- //
+ //
// public void windowDeactivated(IWorkbenchWindow window) {
// }
- //
+ //
// public void windowClosed(IWorkbenchWindow window) {
// }
- //
+ //
// public void windowActivated(IWorkbenchWindow window) {
// //When a window is activated, remove from the previous and add to the new one.
// if(activeWorkbenchWindow != null){
@@ -102,8 +112,10 @@ public void start(BundleContext context) throws Exception {
/**
* This method is called when the plug-in is stopped
*/
+ @Override
public void stop(BundleContext context) throws Exception {
super.stop(context);
+ ReferenceSearchesLucene.disposeAll();
plugin = null;
}
@@ -146,12 +158,44 @@ public static void getDefinitionFromIInfo(List pointers, ICodeCompl
//so, we'de get a find definition for Bar.__init__.xxx which is something we won't find
//for now, let's simply return a match in the correct context (although the correct way of doing
//it would be analyzing that context to find the match)
- definitions = mod.findDefinition(
+ IDefinition[] contextDefinitions = mod.findDefinition(
CompletionStateFactory.getEmptyCompletionState(path, nature, completionCache), -1, -1,
nature);
+ if (contextDefinitions != null && contextDefinitions.length > 0) {
+ for (IDefinition iDefinition : contextDefinitions) {
+ if (iDefinition instanceof Definition) {
+ Definition definition = (Definition) iDefinition;
+ if (definition.ast instanceof FunctionDef) {
+ FunctionDef functionDef = (FunctionDef) definition.ast;
+ if (functionDef.args != null) {
+ exprType[] args = functionDef.args.args;
+ if (args != null && args.length > 0) {
+ //I.e.: only analyze functions with at least one argument (for self or cls).
+ Map repToTokenWithArgs = new HashMap();
+ HeuristicFindAttrs heuristicFindAttrs = new HeuristicFindAttrs(
+ HeuristicFindAttrs.WHITIN_ANY, HeuristicFindAttrs.IN_ASSIGN, "",
+ definition.module.getName(), null, repToTokenWithArgs);
+ heuristicFindAttrs.visitFunctionDef(functionDef);
+
+ List tokens = heuristicFindAttrs.getTokens();
+ List newDefs = new ArrayList<>();
+ for (IToken iToken : tokens) {
+ if (info.getName().equals(iToken.getRepresentation())) {
+ newDefs.add(new Definition(iToken, definition.scope,
+ definition.module));
+ }
+ }
+ definitions = newDefs.toArray(new IDefinition[newDefs.size()]);
+ }
+ }
+ }
+ }
+ }
+ }
+
}
- PyRefactoringFindDefinition.getAsPointers(pointers, (Definition[]) definitions);
+ PyRefactoringFindDefinition.getAsPointers(pointers, definitions);
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPreferenceInitializer.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPreferenceInitializer.java
index 96461104a..c1b255ec5 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPreferenceInitializer.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPreferenceInitializer.java
@@ -10,13 +10,9 @@
package com.python.pydev.analysis;
import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.osgi.service.prefs.Preferences;
-import org.python.pydev.core.log.Log;
-import org.python.pydev.plugin.PydevPlugin;
import com.python.pydev.analysis.ui.AnalysisPreferencesPage;
@@ -95,7 +91,7 @@ public class AnalysisPreferenceInitializer extends AbstractPreferenceInitializer
@Override
public void initializeDefaultPreferences() {
- Preferences node = new DefaultScope().getNode(DEFAULT_SCOPE);
+ Preferences node = DefaultScope.INSTANCE.getNode(DEFAULT_SCOPE);
for (int i = 0; i < AnalysisPreferences.completeSeverityMap.length; i++) {
Object[] s = AnalysisPreferences.completeSeverityMap[i];
@@ -112,15 +108,8 @@ public void initializeDefaultPreferences() {
node.putBoolean(DO_IGNORE_IMPORTS_STARTING_WITH_UNDER, DEFAULT_DO_IGNORE_FIELDS_WITH_UNDER);
//pep8 related.
- node.putBoolean(AnalysisPreferencesPage.USE_PEP8_CONSOLE, false);
- try {
- node.put(
- AnalysisPreferencesPage.PEP8_FILE_LOCATION,
- PydevPlugin.getScriptWithinPySrc(
- new Path("third_party").append("pep8").append("pep8.py").toString()).toString());
- } catch (CoreException e) {
- Log.log(e);
- }
+ node.putBoolean(AnalysisPreferencesPage.USE_PEP8_CONSOLE, AnalysisPreferencesPage.DEFAULT_USE_PEP8_CONSOLE);
+ node.putBoolean(AnalysisPreferencesPage.PEP8_USE_SYSTEM, AnalysisPreferencesPage.DEFAULT_PEP8_USE_SYSTEM);
}
}
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPreferences.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPreferences.java
index f7815c956..15529e8ca 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPreferences.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/AnalysisPreferences.java
@@ -15,28 +15,21 @@
import java.util.Set;
import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.python.pydev.shared_core.preferences.IScopedPreferences;
public class AnalysisPreferences extends AbstractAnalysisPreferences {
- /**
- * singleton
- */
- private static IAnalysisPreferences analysisPreferences;
+ private final IAdaptable projectAdaptable;
- /**
- * lock
- */
- public static final Object lock = new Object();
+ public AnalysisPreferences(IAdaptable projectAdaptable) {
+ this.projectAdaptable = projectAdaptable;
+ }
- /**
- * @return get the preferences for analysis based on the preferences
- */
- public static IAnalysisPreferences getAnalysisPreferences() {
- if (analysisPreferences == null) {
- analysisPreferences = new AnalysisPreferences();
- }
- return analysisPreferences;
+ @Override
+ public IAdaptable getProjectAdaptable() {
+ return projectAdaptable;
}
/**
@@ -82,30 +75,31 @@ public static IAnalysisPreferences getAnalysisPreferences() {
{ IAnalysisPreferences.TYPE_ARGUMENTS_MISATCH, AnalysisPreferenceInitializer.SEVERITY_ARGUMENTS_MISMATCH,
AnalysisPreferenceInitializer.DEFAULT_SEVERITY_ARGUMENTS_MISMATCH }, };
- public void clearCaches() {
- synchronized (lock) {
- severityTypeMapCache = null;
- }
- }
-
- HashMap severityTypeMapCache = null;
+ private HashMap severityTypeMapCache;
+ private final Object lock = new Object();
private Map getSeverityTypeMap() {
- synchronized (lock) {
- if (severityTypeMapCache == null) {
- severityTypeMapCache = new HashMap();
- Preferences pluginPreferences = AnalysisPlugin.getDefault().getPluginPreferences();
-
- for (int i = 0; i < completeSeverityMap.length; i++) {
- Object[] s = completeSeverityMap[i];
- severityTypeMapCache.put((Integer) s[0], pluginPreferences.getInt((String) s[1]));
+ if (severityTypeMapCache == null) {
+ synchronized (lock) {
+ if (severityTypeMapCache == null) {
+ //Do it lazily as it's possible we don't need it...
+ HashMap temp = new HashMap();
+ IPreferenceStore pluginPreferences = AnalysisPlugin.getDefault().getPreferenceStore();
+ IScopedPreferences iScopedPreferences = PyAnalysisScopedPreferences.get();
+
+ for (int i = 0; i < completeSeverityMap.length; i++) {
+ Object[] s = completeSeverityMap[i];
+ int v = iScopedPreferences.getInt(pluginPreferences, (String) s[1], projectAdaptable);
+ temp.put((Integer) s[0], v);
+ }
+
+ //TODO: Add ARGUMENTS_MISMATCH again later on
+ temp.put(IAnalysisPreferences.TYPE_ARGUMENTS_MISATCH, IMarker.SEVERITY_INFO); //Force it to be disabled for now!
+ severityTypeMapCache = temp;
}
-
- //TODO: Add ARGUMENTS_MISMATCH again later on
- severityTypeMapCache.put(IAnalysisPreferences.TYPE_ARGUMENTS_MISATCH, IMarker.SEVERITY_INFO); //Force it to be disabled for now!
}
- return severityTypeMapCache;
}
+ return severityTypeMapCache;
}
/**
@@ -114,14 +108,12 @@ private Map getSeverityTypeMap() {
* @see com.python.pydev.analysis.IAnalysisPreferences#getSeverityForType(int)
*/
public int getSeverityForType(int type) {
- synchronized (lock) {
- Map severityTypeMap = getSeverityTypeMap();
- Integer sev = severityTypeMap.get(type);
- if (sev == null) {
- throw new RuntimeException("Unable to get severity for: " + type);
- }
- return sev;
+ Map severityTypeMap = getSeverityTypeMap();
+ Integer sev = severityTypeMap.get(type);
+ if (sev == null) {
+ throw new RuntimeException("Unable to get severity for: " + type);
}
+ return sev;
}
/**
@@ -130,14 +122,12 @@ public int getSeverityForType(int type) {
* @see com.python.pydev.analysis.IAnalysisPreferences#makeCodeAnalysis()
*/
public boolean makeCodeAnalysis() {
- synchronized (lock) {
- AnalysisPlugin plugin = AnalysisPlugin.getDefault();
- if (plugin == null) {
- return false;//in shutdown
- }
- Preferences pluginPreferences = plugin.getPluginPreferences();
- return pluginPreferences.getBoolean(AnalysisPreferenceInitializer.DO_CODE_ANALYSIS);
+ AnalysisPlugin plugin = AnalysisPlugin.getDefault();
+ if (plugin == null) {
+ return false;//in shutdown
}
+ return PyAnalysisScopedPreferences.getBoolean(AnalysisPreferenceInitializer.DO_CODE_ANALYSIS,
+ projectAdaptable);
}
/**
@@ -157,9 +147,7 @@ public Set getTokensAlwaysInGlobals() {
*/
private Set getSetOfNames(String preferencesName) {
HashSet names = new HashSet();
- Preferences pluginPreferences = AnalysisPlugin.getDefault().getPluginPreferences();
-
- String string = pluginPreferences.getString(preferencesName);
+ String string = PyAnalysisScopedPreferences.getString(preferencesName, projectAdaptable);
if (string != null) {
String[] strings = string.split(",");
for (int i = 0; i < strings.length; i++) {
@@ -187,8 +175,8 @@ public Set getModuleNamePatternsToBeIgnored() {
* @see com.python.pydev.analysis.IAnalysisPreferences#getWhenAnalyze()
*/
public int getWhenAnalyze() {
- Preferences pluginPreferences = AnalysisPlugin.getDefault().getPluginPreferences();
- return pluginPreferences.getInt(AnalysisPreferenceInitializer.WHEN_ANALYZE);
+ return PyAnalysisScopedPreferences.getInt(AnalysisPreferenceInitializer.WHEN_ANALYZE,
+ projectAdaptable, 0);
}
}
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/CtxInsensitiveImportComplProposal.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/CtxInsensitiveImportComplProposal.java
index f97dab7f0..c4b6eecac 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/CtxInsensitiveImportComplProposal.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/CtxInsensitiveImportComplProposal.java
@@ -11,6 +11,7 @@
import java.util.List;
+import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
@@ -97,13 +98,16 @@ public void setAddLocalImport(boolean b) {
*/
public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
IDocument document = viewer.getDocument();
+ IAdaptable projectAdaptable;
if (viewer instanceof PySourceViewer) {
PySourceViewer pySourceViewer = (PySourceViewer) viewer;
PyEdit pyEdit = pySourceViewer.getEdit();
this.indentString = pyEdit.getIndentPrefs().getIndentationString();
+ projectAdaptable = pyEdit;
} else {
//happens on compare editor
- this.indentString = new DefaultIndentPrefs().getIndentationString();
+ this.indentString = new DefaultIndentPrefs(null).getIndentationString();
+ projectAdaptable = null;
}
//If the completion is applied with shift pressed, do a local import. Note that the user is only actually
//able to do that if the popup menu is focused (i.e.: request completion and do a tab to focus it, instead
@@ -111,7 +115,7 @@ public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
if ((stateMask & SWT.SHIFT) != 0) {
this.setAddLocalImport(true);
}
- apply(document, trigger, stateMask, offset);
+ apply(document, trigger, stateMask, offset, projectAdaptable);
}
/**
@@ -128,6 +132,10 @@ public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
* (and it could be a multi-line import)
*/
public void apply(IDocument document, char trigger, int stateMask, int offset) {
+ apply(document, trigger, stateMask, offset, null);
+ }
+
+ public void apply(IDocument document, char trigger, int stateMask, int offset, IAdaptable projectAdaptable) {
if (this.indentString == null) {
throw new RuntimeException("Indent string not set (not called with a PyEdit as viewer?)");
}
@@ -143,7 +151,7 @@ public void apply(IDocument document, char trigger, int stateMask, int offset) {
ImportHandleInfo groupInto = null;
ImportHandleInfo realImportHandleInfo = null;
- boolean groupImports = ImportsPreferencesPage.getGroupImports();
+ boolean groupImports = ImportsPreferencesPage.getGroupImports(projectAdaptable);
LineStartingScope previousLineThatStartsScope = null;
PySelection ps = null;
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/IAnalysisPreferences.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/IAnalysisPreferences.java
index f5375514f..6cc71aad8 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/IAnalysisPreferences.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/IAnalysisPreferences.java
@@ -11,6 +11,7 @@
import java.util.Set;
+import org.eclipse.core.runtime.IAdaptable;
import org.python.pydev.core.IMiscConstants;
public interface IAnalysisPreferences {
@@ -98,15 +99,11 @@ public interface IAnalysisPreferences {
*/
Set getTokensAlwaysInGlobals();
- /**
- * The analysis preferences may have caches, so that we don't get all from the cache, but we must be able to clear them
- * if something changes (if user changes the preferences).
- */
- void clearCaches();
-
/**
* @return the message that should be in a line so that a warning of a given type is ignored.
* I.e.: @UnusedImport
*/
String getRequiredMessageToIgnore(int type);
+
+ IAdaptable getProjectAdaptable();
}
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/OccurrencesAnalyzer.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/OccurrencesAnalyzer.java
index 2afbb671d..9a5885380 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/OccurrencesAnalyzer.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/OccurrencesAnalyzer.java
@@ -34,9 +34,19 @@
*/
public class OccurrencesAnalyzer {
- public IMessage[] analyzeDocument(IPythonNature nature, SourceModule module, IAnalysisPreferences prefs,
- IDocument document, IProgressMonitor monitor, IIndentPrefs indentPrefs) {
+ public IMessage[] analyzeDocument(IPythonNature nature, final SourceModule module,
+ final IAnalysisPreferences prefs,
+ final IDocument document, final IProgressMonitor monitor, IIndentPrefs indentPrefs) {
+ //Do pep8 in a thread.
+ final List pep8Messages = new ArrayList<>();
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ pep8Messages.addAll(new Pep8Visitor().getMessages(module, document, monitor, prefs));
+ }
+ };
+ t.start();
OccurrencesVisitor visitor = new OccurrencesVisitor(nature, module.getName(), module, prefs, document, monitor);
try {
SimpleNode ast = module.getAst();
@@ -66,7 +76,12 @@ public IMessage[] analyzeDocument(IPythonNature nature, SourceModule module, IAn
}
if (!monitor.isCanceled()) {
- messages.addAll(new Pep8Visitor().getMessages(module, document, monitor, prefs));
+ try {
+ t.join();
+ messages.addAll(pep8Messages);
+ } catch (InterruptedException e) {
+ //If interrupted keep on going as it is.
+ }
}
return messages.toArray(new IMessage[messages.size()]);
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/PyAnalysisScopedPreferences.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/PyAnalysisScopedPreferences.java
new file mode 100644
index 000000000..02ebca9c4
--- /dev/null
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/PyAnalysisScopedPreferences.java
@@ -0,0 +1,41 @@
+package com.python.pydev.analysis;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.python.pydev.shared_core.preferences.IScopedPreferences;
+import org.python.pydev.shared_core.preferences.ScopedPreferences;
+
+public class PyAnalysisScopedPreferences {
+
+ public static final String ANALYSIS_SCOPE = "org.python.pydev.analysis";
+
+ public static boolean getBoolean(String setting, IAdaptable projectAdaptable) {
+ return get().getBoolean(AnalysisPlugin.getDefault().getPreferenceStore(), setting, projectAdaptable);
+ }
+
+ public static String getString(String setting, IAdaptable projectAdaptable) {
+ return get().getString(AnalysisPlugin.getDefault().getPreferenceStore(), setting, projectAdaptable);
+ }
+
+ public static int getInt(String setting, IAdaptable projectAdaptable, int minVal) {
+ int ret = get().getInt(AnalysisPlugin.getDefault().getPreferenceStore(), setting, projectAdaptable);
+ if (ret < minVal) {
+ return minVal;
+ }
+ return ret;
+ }
+
+ public static String getString(String setting, IAdaptable projectAdaptable, String defaultReturn) {
+ String ret = getString(setting, projectAdaptable);
+ if (ret.isEmpty()) {
+ return defaultReturn;
+ }
+ return ret;
+ }
+
+ public static IScopedPreferences get() {
+ // Note: our bundle is com.python.pydev.analysis, but for the user it can be presented as
+ // org.python.pydev.analysis as it's like that only because of historical reasons.
+ return ScopedPreferences.get(ANALYSIS_SCOPE);
+ }
+
+}
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/ForceCodeAnalysisOnTree.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/ForceCodeAnalysisOnTree.java
index 72f46504b..0dd84e2e5 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/ForceCodeAnalysisOnTree.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/ForceCodeAnalysisOnTree.java
@@ -7,7 +7,6 @@
package com.python.pydev.analysis.actions;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -22,6 +21,7 @@
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.IObjectActionDelegate;
import org.python.pydev.builder.PyDevBuilderVisitor;
+import org.python.pydev.builder.VisitorMemo;
import org.python.pydev.core.FileUtilsFileBuffer;
import org.python.pydev.core.IModule;
import org.python.pydev.core.MisconfigurationException;
@@ -99,9 +99,9 @@ protected int doActionOnResource(IResource next, IProgressMonitor monitor) {
filesVisited.add(f);
monitor.setTaskName(buf.clear().append("Scheduling: ").append(f.getName()).toString());
IDocument doc = FileUtilsFileBuffer.getDocFromResource(f);
- visitor.memo = new HashMap();
+ visitor.memo = new VisitorMemo();
visitor.memo.put(PyDevBuilderVisitor.IS_FULL_BUILD, false);
- long documentTime = f.getModificationStamp();
+ long documentTime = System.currentTimeMillis();
visitor.memo.put(PyDevBuilderVisitor.DOCUMENT_TIME, documentTime);
String moduleName;
try {
@@ -120,7 +120,7 @@ protected int doActionOnResource(IResource next, IProgressMonitor monitor) {
continue;
}
visitor.doVisitChangedResource(nature, f, doc, null, module, new NullProgressMonitor(), true,
- AnalysisBuilderRunnable.ANALYSIS_CAUSE_PARSER, documentTime);
+ AnalysisBuilderRunnable.ANALYSIS_CAUSE_PARSER, documentTime, false);
}
visitor.visitingEnded(new NullProgressMonitor());
return 1;
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/MatchHelper.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/MatchHelper.java
index 370270b51..9b2d0147b 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/MatchHelper.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/MatchHelper.java
@@ -9,8 +9,8 @@
import java.util.List;
import org.eclipse.ui.dialogs.SearchPattern;
-import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.shared_core.callbacks.ICallback2;
+import org.python.pydev.shared_core.string.StringUtils;
import com.python.pydev.analysis.additionalinfo.IInfo;
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/PyGlobalsBrowser.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/PyGlobalsBrowser.java
index 1ce17c412..cd76a9798 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/PyGlobalsBrowser.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/actions/PyGlobalsBrowser.java
@@ -6,6 +6,7 @@
*/
package com.python.pydev.analysis.actions;
+import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -40,6 +41,7 @@
public class PyGlobalsBrowser extends PyAction {
+ @Override
public void run(IAction action) {
IPythonNature pythonNature;
try {
@@ -72,7 +74,14 @@ public void run(IAction action) {
*/
private void getFromSystemManager(String selectedText) {
//is null
- Tuple infoForFile = PydevPlugin.getInfoForFile(getPyEdit().getEditorFile());
+ File editorFile = getPyEdit().getEditorFile();
+
+ Tuple infoForFile;
+ if (editorFile != null) {
+ infoForFile = PydevPlugin.getInfoForFile(editorFile);
+ } else {
+ infoForFile = null;
+ }
if (infoForFile != null) {
IPythonNature systemPythonNature = infoForFile.o1;
if (systemPythonNature == null) {
diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/AbstractAdditionalDependencyInfo.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/AbstractAdditionalDependencyInfo.java
index c058d0d9a..a8a7b2d31 100644
--- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/AbstractAdditionalDependencyInfo.java
+++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/AbstractAdditionalDependencyInfo.java
@@ -16,50 +16,45 @@
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
import org.python.pydev.core.FastBufferedReader;
-import org.python.pydev.core.FileUtilsFileBuffer;
+import org.python.pydev.core.IInterpreterManager;
+import org.python.pydev.core.IModule;
+import org.python.pydev.core.IToken;
import org.python.pydev.core.MisconfigurationException;
import org.python.pydev.core.ModulesKey;
-import org.python.pydev.core.ModulesKeyForZip;
-import org.python.pydev.core.ObjectsPool;
-import org.python.pydev.core.ObjectsPool.ObjectsPoolMap;
+import org.python.pydev.core.ObjectsInternPool;
+import org.python.pydev.core.ObjectsInternPool.ObjectsPoolMap;
import org.python.pydev.core.cache.CompleteIndexKey;
-import org.python.pydev.core.cache.CompleteIndexValue;
import org.python.pydev.core.cache.DiskCache;
-import org.python.pydev.core.docutils.PySelection;
-import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.core.log.Log;
import org.python.pydev.editor.codecompletion.revisited.PyPublicTreeMap;
import org.python.pydev.editor.codecompletion.revisited.PythonPathHelper;
+import org.python.pydev.editor.codecompletion.revisited.javaintegration.AbstractJavaClassModule;
import org.python.pydev.logging.DebugSettings;
import org.python.pydev.parser.jython.SimpleNode;
-import org.python.pydev.shared_core.callbacks.ICallback;
+import org.python.pydev.parser.jython.ast.Name;
+import org.python.pydev.parser.jython.ast.stmtType;
+import org.python.pydev.parser.jython.ast.factory.AdapterPrefs;
+import org.python.pydev.parser.jython.ast.factory.PyAstFactory;
+import org.python.pydev.shared_core.callbacks.CallbackWithListeners;
import org.python.pydev.shared_core.io.FileUtils;
import org.python.pydev.shared_core.string.FastStringBuffer;
+import org.python.pydev.shared_core.string.StringUtils;
import org.python.pydev.shared_core.structure.Tuple;
import org.python.pydev.shared_core.structure.Tuple3;
+import org.python.pydev.ui.pythonpathconf.InterpreterInfo;
/**
- * Adds dependency information to the interpreter information. This should be used only for
- * classes that are part of a project (this info will not be gotten for the system interpreter)
- *
- * (Basically, it will index all the names that are found in a module so that we can easily know all the
- * places where some name exists)
- *
- * This index was removed for now... it wasn't working properly because the AST info could be only partial
- * when it arrived here, thus, it didn't really serve its purpose well (this will have to be redone properly
- * later on).
- *
- * @author Fabio
+ * Adds information on the modules being tracked.
*/
public abstract class AbstractAdditionalDependencyInfo extends AbstractAdditionalTokensInfo {
@@ -69,17 +64,38 @@ public abstract class AbstractAdditionalDependencyInfo extends AbstractAdditiona
/**
* indexes all the names that are available
- *
+ *
* Note that the key in the disk cache is the module name and each
* module points to a Set
- *
+ *
* So the key is the module name and the value is a Set of the strings it contains.
*/
public DiskCache completeIndex;
+ private volatile IReferenceSearches referenceSearches;
+ private final Object referenceSearchesLock = new Object();
+
+ public IReferenceSearches getReferenceSearches() {
+ if (referenceSearches == null) {
+ synchronized (referenceSearchesLock) {
+ if (referenceSearches == null) {
+ referenceSearches = new ReferenceSearchesLucene(this);
+ }
+ }
+ }
+ return referenceSearches;
+ }
+
+ public void dispose() {
+ if (this.referenceSearches != null) {
+ this.referenceSearches.dispose();
+ this.referenceSearches = null;
+ }
+ }
+
/**
* default constructor
- * @throws MisconfigurationException
+ * @throws MisconfigurationException
*/
public AbstractAdditionalDependencyInfo() throws MisconfigurationException {
init();
@@ -91,58 +107,23 @@ public AbstractAdditionalDependencyInfo(boolean callInit) throws Misconfiguratio
}
}
- private static ICallback readFromFileMethod = new ICallback() {
-
- public CompleteIndexValue call(String arg) {
- CompleteIndexValue entry = new CompleteIndexValue();
- if (arg.equals("0")) {
- return entry;
- }
- //The set was written!
- HashSet hashSet = new HashSet();
- if (arg.length() > 0) {
- StringUtils.splitWithIntern(arg, '\n', hashSet);
- }
- entry.entries = hashSet;
-
- return entry;
- }
- };
-
- private static ICallback toFileMethod = new ICallback() {
-
- public String call(CompleteIndexValue arg) {
- FastStringBuffer buf;
- if (arg.entries == null) {
- return "0";
- }
- buf = new FastStringBuffer(arg.entries.size() * 20);
-
- for (String s : arg.entries) {
- buf.append(s);
- buf.append('\n');
- }
- return buf.toString();
- }
- };
-
/**
* Initializes the internal DiskCache with the indexes.
- * @throws MisconfigurationException
+ * @throws MisconfigurationException
*/
protected void init() throws MisconfigurationException {
File persistingFolder = getCompleteIndexPersistingFolder();
- completeIndex = new DiskCache(persistingFolder, ".v1_indexcache", readFromFileMethod, toFileMethod);
+ completeIndex = new DiskCache(persistingFolder, ".v2_indexcache");
}
/**
* @return a folder where the index should be persisted
- * @throws MisconfigurationException
+ * @throws MisconfigurationException
*/
protected File getCompleteIndexPersistingFolder() throws MisconfigurationException {
File persistingFolder = getPersistingFolder();
- persistingFolder = new File(persistingFolder, "v1_indexcache");
+ persistingFolder = new File(persistingFolder, "v2_indexcache");
if (persistingFolder.exists()) {
if (!persistingFolder.isDirectory()) {
@@ -167,7 +148,23 @@ public void clearAllInfo() {
}
}
- public void updateKeysIfNeededAndSave(PyPublicTreeMap keysFound) {
+ /**
+ * This is mostly for whitebox testing the updateKeysIfNeededAndSave. It'll called with a tuple containing
+ * the keys added and the keys removed.
+ */
+ public static final CallbackWithListeners modulesAddedAndRemoved = new CallbackWithListeners(1);
+
+ public final Object updateKeysLock = new Object(); // Calls to updateKeysIfNeededAndSave should be synchronized.
+
+ /**
+ * If info == null we're dealing with project info (otherwise we're dealing with interpreter info).
+ *
+ * The main difference is that we don't index builtin modules for projects (but maybe we should?). Still,
+ * to index builtin modules we have to be a bit more careful, especially on changes (i.e.: when a builtin
+ * becomes a source module and vice-versa).
+ */
+ public void updateKeysIfNeededAndSave(PyPublicTreeMap keysFound, InterpreterInfo info,
+ IProgressMonitor monitor) {
Map keys = this.completeIndex.keys();
ArrayList newKeys = new ArrayList();
@@ -176,246 +173,152 @@ public void updateKeysIfNeededAndSave(PyPublicTreeMap ke
//temporary
CompleteIndexKey tempKey = new CompleteIndexKey((ModulesKey) null);
+ boolean isJython = info != null ? info.getInterpreterType() == IInterpreterManager.INTERPRETER_TYPE_JYTHON
+ : true;
+
Iterator it = keysFound.values().iterator();
while (it.hasNext()) {
ModulesKey next = it.next();
- if (next.file != null) {
- long lastModified = next.file.lastModified();
+ if (next.file != null) { //Can be a .pyd or a .py
+ long lastModified = FileUtils.lastModified(next.file);
if (lastModified != 0) {
tempKey.key = next;
CompleteIndexKey completeIndexKey = keys.get(tempKey);
- boolean canAddAstInfoFor = PythonPathHelper.canAddAstInfoFor(next);
if (completeIndexKey == null) {
- if (canAddAstInfoFor) {
- newKeys.add(next);
- }
+ newKeys.add(next);
} else {
- if (canAddAstInfoFor) {
- if (completeIndexKey.lastModified != lastModified) {
- //Just re-add it if the time changed!
- newKeys.add(next);
- }
- } else {
- //It's there but it's not valid: Remove it!
- removedKeys.add(next);
+ if (completeIndexKey.lastModified != lastModified) {
+ //Just re-add it if the time changed!
+ newKeys.add(next);
}
}
}
+ } else { //at this point, it's always a compiled module (forced builtin), so, we can't check if it was modified (just re-add it).
+ tempKey.key = next;
+ CompleteIndexKey completeIndexKey = keys.get(tempKey);
+ if (completeIndexKey == null) {
+ newKeys.add(next); //Only add if it's not there already.
+ }
}
}
Iterator it2 = keys.values().iterator();
while (it2.hasNext()) {
CompleteIndexKey next = it2.next();
- if (!keysFound.containsKey(next.key) || !PythonPathHelper.canAddAstInfoFor(next.key)) {
+ if (!keysFound.containsKey(next.key)) {
removedKeys.add(next.key);
}
}
boolean hasNew = newKeys.size() != 0;
boolean hasRemoved = removedKeys.size() != 0;
+ modulesAddedAndRemoved.call(new Tuple(newKeys, removedKeys));
- if (hasNew) {
- for (ModulesKey newKey : newKeys) {
- try {
- this.addAstInfo(newKey, false);
- } catch (Exception e) {
- Log.log(e);
- }
- }
- }
+ Set ignoreFiles = new HashSet();
+ // Remove first!
if (hasRemoved) {
for (ModulesKey removedKey : removedKeys) {
+ // Don't generate deltas (we'll save it in the end).
this.removeInfoFromModule(removedKey.name, false);
}
}
- if (hasNew || hasRemoved) {
- if (DebugSettings.DEBUG_INTERPRETER_AUTO_UPDATE) {
- Log.toLogFile(this,
- org.python.pydev.shared_core.string.StringUtils.format("Additional info modules. Added: %s Removed: %s", newKeys, removedKeys));
- }
- save();
- }
- }
-
- @Override
- public List getModulesWithToken(String token, IProgressMonitor monitor) {
- FastStringBuffer temp = new FastStringBuffer();
- ArrayList ret = new ArrayList();
- if (monitor == null) {
- monitor = new NullProgressMonitor();
- }
- if (token == null || token.length() == 0) {
- return ret;
- }
-
- for (int i = 0; i < token.length(); i++) {
- if (!Character.isJavaIdentifierPart(token.charAt(i))) {
- throw new RuntimeException(org.python.pydev.shared_core.string.StringUtils.format("Token: %s is not a valid token to search for.", token));
- }
- }
- synchronized (lock) {
- FastStringBuffer bufProgress = new FastStringBuffer();
- //Note that this operation is not as fast as the others, as it relies on a cache that is optimized
- //for space and not for speed (but still, should be faster than having to do a text-search to know the
- //tokens when the cache is available).
-
- Tuple>, Collection> memoryInfo = completeIndex
- .getInMemoryInfo();
-
- long last = System.currentTimeMillis();
- int worked = 0;
- try {
- monitor.beginTask("Get modules with token", memoryInfo.o1.size() + memoryInfo.o2.size());
- for (Tuple tup : memoryInfo.o1) {
- CompleteIndexKey indexKey = tup.o1;
- CompleteIndexValue obj = tup.o2;
-
- worked++;
- if (monitor.isCanceled()) {
- return ret;
- }
- long current = System.currentTimeMillis();
- if (last + 200 < current) {
- last = current;
- monitor.setTaskName(bufProgress.clear().append("Searching: ").append(indexKey.key.name)
- .toString());
- monitor.worked(worked);
- }
- check(indexKey, obj, temp, token, ret);
+ // Add last (a module could be removed/added).
+ if (hasNew) {
+ FastStringBuffer buffer = new FastStringBuffer();
+ int currI = 0;
+ int total = newKeys.size();
+ for (ModulesKey newKey : newKeys) {
+ currI += 1;
+ if (monitor.isCanceled()) {
+ return;
}
-
- for (CompleteIndexKey indexKey : memoryInfo.o2) {
- worked++;
- if (monitor.isCanceled()) {
- return ret;
+ if (PythonPathHelper.canAddAstInfoForSourceModule(newKey)) {
+ buffer.clear().append("Indexing ").append(currI).append(" of ").append(total)
+ .append(" (source module): ").append(newKey.name).append(" (")
+ .append(currI).append(" of ").append(total).append(")");
+ try {
+ // Don't generate deltas (we'll save it in the end).
+ this.addAstInfo(newKey, false);
+ } catch (Exception e) {
+ Log.log(e);
}
- long current = System.currentTimeMillis();
- if (last + 200 < current) {
- last = current;
- monitor.setTaskName(bufProgress.clear().append("Searching: ").append(indexKey.key.name)
- .toString());
- monitor.worked(worked);
+ } else {
+ if (info != null) {
+ if (isJython && ignoreFiles.contains(newKey.file)) {
+ continue;
+ }
+ buffer.clear().append("Indexing ").append(currI).append(" of ").append(total)
+ .append(" (builtin module): ").append(newKey.name);
+ monitor.setTaskName(buffer.toString());
+ IModule builtinModule = info.getModulesManager().getModule(newKey.name,
+ info.getModulesManager().getNature(), true);
+ if (builtinModule != null) {
+ if (builtinModule instanceof AbstractJavaClassModule) {
+ if (newKey.file != null) {
+ ignoreFiles.add(newKey.file);
+ } else {
+ Log.log("Not expecting null file for java class module: " + newKey);
+ }
+ continue;
+ }
+ boolean removeFirst = keys.containsKey(newKey);
+ addAstForCompiledModule(builtinModule, info, newKey, removeFirst);
+ }
}
- check(indexKey, null, temp, token, ret);
}
- } finally {
- monitor.done();
}
}
- return ret;
- }
-
- private void check(CompleteIndexKey indexKey, CompleteIndexValue obj, FastStringBuffer temp, String token,
- ArrayList ret) {
- if (obj == null) {
- obj = completeIndex.getObj(indexKey);
- }
- boolean canAddAstInfoFor = PythonPathHelper.canAddAstInfoFor(indexKey.key);
- if (obj == null) {
- if (canAddAstInfoFor) {
- try {
- //Should be there (recreate the entry in the index and in the actual AST)
- this.addAstInfo(indexKey.key, true);
- } catch (Exception e) {
- Log.log(e);
- }
- obj = new CompleteIndexValue();
- } else {
- if (DEBUG) {
- System.out.println("Removing (file does not exist or is not a valid source module): "
- + indexKey.key.name);
- }
- this.removeInfoFromModule(indexKey.key.name, true);
- return;
+ if (hasNew || hasRemoved) {
+ if (DebugSettings.DEBUG_INTERPRETER_AUTO_UPDATE) {
+ Log.toLogFile(this,
+ StringUtils.format(
+ "Additional info modules. Added: %s Removed: %s", newKeys, removedKeys));
}
+ save();
}
+ }
- long lastModified = indexKey.key.file.lastModified();
- if (lastModified == 0 || !canAddAstInfoFor) {
- //File no longer exists or is not a valid source module.
- if (DEBUG) {
- System.out.println("Removing (file no longer exists or is not a valid source module): "
- + indexKey.key.name + " indexKey.key.file: " + indexKey.key.file + " exists: "
- + indexKey.key.file.exists());
- }
- this.removeInfoFromModule(indexKey.key.name, true);
- return;
- }
+ private void addAstForCompiledModule(IModule module, InterpreterInfo info, ModulesKey newKey, boolean removeFirst) {
+ IToken[] globalTokens = module.getGlobalTokens();
+ PyAstFactory astFactory = new PyAstFactory(new AdapterPrefs("\n", info.getModulesManager().getNature()));
- //if it got here, it must be a valid source module!
+ List body = new ArrayList<>(globalTokens.length);
- if (obj.entries != null) {
- if (lastModified != indexKey.lastModified) {
- obj = new CompleteIndexValue();
- try {
- //Recreate the entry on the new time (recreate the entry in the index and in the actual AST)
- this.addAstInfo(indexKey.key, true);
- } catch (Exception e) {
- Log.log(e);
- }
- }
- }
+ for (IToken token : globalTokens) {
+ switch (token.getType()) {
- //The actual values are always recreated lazily (in the case that it's really needed).
- if (obj.entries == null) {
- FastStringBuffer buf;
- ModulesKey key = indexKey.key;
- try {
- if (key instanceof ModulesKeyForZip) {
- ModulesKeyForZip modulesKeyForZip = (ModulesKeyForZip) key;
- buf = (FastStringBuffer) FileUtilsFileBuffer.getCustomReturnFromZip(modulesKeyForZip.file,
- modulesKeyForZip.zipModulePath, FastStringBuffer.class);
- } else {
- buf = (FastStringBuffer) FileUtils.getFileContentsCustom(key.file, FastStringBuffer.class);
- }
- } catch (Exception e) {
- Log.log(e);
- return;
- }
+ case IToken.TYPE_CLASS:
+ body.add(astFactory.createClassDef(token.getRepresentation()));
+ break;
- HashSet set = new HashSet();
- temp = temp.clear();
- int length = buf.length();
- for (int i = 0; i < length; i++) {
- char c = buf.charAt(i);
- if (Character.isJavaIdentifierStart(c)) {
- temp.clear();
- temp.append(c);
- i++;
- for (; i < length; i++) {
- c = buf.charAt(i);
- if (c == ' ' || c == '\t') {
- break; //Fast forward through the most common case...
- }
- if (Character.isJavaIdentifierPart(c)) {
- temp.append(c);
- } else {
- break;
- }
- }
- String str = temp.toString();
- if (PySelection.ALL_KEYWORD_TOKENS.contains(str)) {
- continue;
- }
- set.add(str);
- }
- }
+ case IToken.TYPE_FUNCTION:
+ body.add(astFactory.createFunctionDef(token.getRepresentation()));
+ break;
- obj.entries = set;
- indexKey.lastModified = lastModified;
- completeIndex.add(indexKey, obj); //Serialize the new contents
+ default:
+ Name attr = astFactory.createName(token.getRepresentation());
+ body.add(astFactory.createAssign(attr, attr)); //assign to itself just for generation purposes.
+ break;
+ }
}
-
- if (obj.entries != null && obj.entries.contains(token)) {
- ret.add(indexKey.key);
+ //System.out.println("Creating info for: " + module.getName());
+ if (removeFirst) {
+ removeInfoFromModule(newKey.name, false);
}
+ addAstInfo(astFactory.createModule(body), newKey, false);
+ }
+ static interface IBufferFiller {
+ void fillBuffer(FastStringBuffer buf);
}
+ protected abstract String getUIRepresentation();
+
+ protected abstract Set getPythonPathFolders();
+
@Override
public List addAstInfo(SimpleNode node, ModulesKey key, boolean generateDelta) {
List addAstInfo = new ArrayList();
@@ -426,9 +329,11 @@ public List addAstInfo(SimpleNode node, ModulesKey key, boolean generateD
synchronized (lock) {
addAstInfo = super.addAstInfo(node, key, generateDelta);
+ CompleteIndexKey completeIndexKey = new CompleteIndexKey(key);
if (key.file != null) {
- completeIndex.add(new CompleteIndexKey(key), new CompleteIndexValue());
+ completeIndexKey.lastModified = FileUtils.lastModified(key.file);
}
+ completeIndex.add(completeIndexKey);
}
} catch (Exception e) {
@@ -473,8 +378,6 @@ protected void restoreSavedInfo(Object o) throws MisconfigurationException {
throw new RuntimeException(
"Type Error (index == null): the info must be regenerated (changed across versions).");
}
- completeIndex.readFromFileMethod = readFromFileMethod;
- completeIndex.toFileMethod = toFileMethod;
String shouldBeOn = FileUtils.getFileAbsolutePath(getCompleteIndexPersistingFolder());
if (!completeIndex.getFolderToPersist().equals(shouldBeOn)) {
@@ -505,7 +408,7 @@ protected boolean load() {
try {
return loadContentsFromFile(file) != null;
} catch (Throwable e) {
- errorFound = e;
+ errorFound = new RuntimeException("Unable to read: " + file, e);
}
}
}
@@ -524,7 +427,8 @@ protected boolean load() {
return false;
}
- private Object loadContentsFromFile(File file) throws FileNotFoundException, IOException, MisconfigurationException {
+ private Object loadContentsFromFile(File file)
+ throws FileNotFoundException, IOException, MisconfigurationException {
FileInputStream fileInputStream = new FileInputStream(file);
try {
// Timer timer = new Timer();
@@ -532,11 +436,12 @@ private Object loadContentsFromFile(File file) throws FileNotFoundException, IOE
InputStreamReader reader = new InputStreamReader(fileInputStream);
FastBufferedReader bufferedReader = new FastBufferedReader(reader);
FastStringBuffer string = bufferedReader.readLine();
- ObjectsPoolMap objectsPoolMap = new ObjectsPool.ObjectsPoolMap();
+ ObjectsPoolMap objectsPoolMap = new ObjectsInternPool.ObjectsPoolMap();
if (string != null && string.startsWith("-- VERSION_")) {
Tuple, Object> tupWithResults = new Tuple, Object>(
new Tuple3