From 4cfd99033c91ed1944b262b6badf5a6908a68c19 Mon Sep 17 00:00:00 2001 From: Fabio Zadrozny Date: Sun, 29 Sep 2024 10:57:08 -0300 Subject: [PATCH] Move code related to TDD actions to core plugins. --- .../META-INF/MANIFEST.MF | 2 + .../analysis/AbstractAnalysisPreferences.java | 2 +- .../pydev/analysis/AnalysisPreferences.java | 10 +- .../pydev/analysis/OccurrencesAnalyzer.java | 2 +- .../builders/AnalysisBuilderRunnable.java | 2 +- .../builders/AnalysisRunner.java | 3 +- .../DontAnalyzeFileMarkerParticipant.java | 6 +- .../IgnoreErrorParticipant.java | 25 +- .../UndefinedVariableFixParticipant.java | 20 +- .../pydev/analysis/pep8/Pep8Visitor.java | 2 +- .../DummyMarkerInfoForAnalysis.java | 60 ++ .../tdd/AbstractPyCreateAction.java | 8 +- .../AbstractPyCreateClassOrMethodOrField.java | 37 +- .../refactoring/tdd/NullPyCreateAction.java | 5 +- .../refactoring/tdd/PyCreateClass.java | 7 +- .../tdd/PyCreateMethodOrField.java | 7 +- .../refactoring/tdd/TemplateInfo.java | 85 +++ .../pydev/analysis/tabnanny/TabNanny.java | 2 +- .../analysis/visitors/DuplicationChecker.java | 2 +- .../analysis/visitors/MessagesManager.java | 2 +- .../analysis/visitors/NoSelfChecker.java | 2 +- .../analysis/visitors/OccurrencesVisitor.java | 2 +- .../com.python.pydev.refactoring/plugin.xml | 43 +- .../plugin_install.py | 4 +- ...erationQuickFixFromMarkersParticipant.java | 21 + ...ionQuickFixWithoutMarkersParticipant.java} | 681 +++++++++--------- ...=> TddQuickFixFromMarkersParticipant.java} | 35 +- .../tdd/TddRefactorCompletion.java | 38 +- ...dRefactorCompletionInInexistentModule.java | 3 + .../tdd/TddRefactorCompletionInModule.java | 6 +- .../refactoring/tdd/ExecutePyCreate.java | 16 +- .../refactoring/tdd/PyCreateClassTest.java | 46 +- .../refactoring/tdd/PyCreateMethodTest.java | 90 ++- ...CodeGenerationQuickFixParticipantTest.java | 120 ++- ...ionQuickFixParticipantWithMarkersTest.java | 309 ++++++++ .../refactoring/tdd/TddTestWorkbench.java | 191 ++--- .../ast/adapters/visitors/VisitorFactory.java | 29 +- .../analysis/messages/AbstractMessage.java | 2 +- .../analysis/messages/CompositeMessage.java | 2 +- .../pydev/ast/analysis/messages/IMessage.java | 30 +- .../pydev/ast/analysis/messages/Message.java | 2 +- .../ast/refactoring/RefactoringInfo.java | 2 +- .../templates/PyDocumentTemplateContext.java | 22 +- .../core}/IAnalysisMarkersParticipant.java | 8 +- .../pydev/core}/IAnalysisPreferences.java | 2 +- .../pydev/core/IMarkerInfoForAnalysis.java | 20 + .../proposals/ICompletionProposalFactory.java | 6 +- .../src/org/python/pydev/parser/PyParser.java | 5 + .../pydev/shared_core/io/FileUtils.java | 2 +- plugins/org.python.pydev/plugin.xml | 2 +- .../AbstractAnalysisMarkersParticipants.java | 6 +- .../ctrl_1/AnalysisMarkersParticipants.java | 2 + .../flake8/Flake8IgnoreErrorParticipant.java | 18 +- .../pylint/PyLintIgnoreErrorParticipant.java | 18 +- .../organizeimports/OrganizeImports.java | 7 +- .../codecompletion/PyTemplateProposal.java | 7 + .../DefaultCompletionProposalFactory.java | 6 +- .../MarkerAnnotationAndPosition.java | 79 ++ ...oreFlake8CompletionProposalInSameLine.java | 13 +- ...orePyLintCompletionProposalInSameLine.java | 14 +- .../heuristics/AssistSurroundWithTest.java | 282 +------- .../parser/PyParserEditorIntegrationTest.java | 181 +---- .../analysis/AnalysisPreferencesStub.java | 2 +- .../analysis/OccurrencesAnalyzerTest.java | 8 +- .../ctrl_1/IgnoreErrorFixParticipantTest.java | 15 +- .../UndefinedVariableFixParticipantTest.java | 19 +- .../organizeimports/OrganizeImportsTest.java | 2 +- .../revisited/CodeCompletionTestsBase.java | 6 + .../codecompletion/revisited/PyEditStub.java | 201 ++++++ .../revisited}/PydevFileEditorInputStub.java | 2 +- .../revisited/TextViewerStub.java | 423 +++++++++++ .../AbstractWorkbenchTestCase.java | 8 +- 72 files changed, 2090 insertions(+), 1259 deletions(-) rename plugins/{org.python.pydev/src/com/python/pydev/analysis/ctrl_1 => com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes}/DontAnalyzeFileMarkerParticipant.java (93%) rename plugins/{org.python.pydev/src/com/python/pydev/analysis/ctrl_1 => com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes}/IgnoreErrorParticipant.java (77%) rename plugins/{org.python.pydev/src/com/python/pydev/analysis/ctrl_1 => com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes}/UndefinedVariableFixParticipant.java (74%) create mode 100644 plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/quick_fixes/DummyMarkerInfoForAnalysis.java rename plugins/{com.python.pydev.refactoring/src/com/python/pydev => com.python.pydev.analysis/src/com/python/pydev/analysis}/refactoring/tdd/AbstractPyCreateAction.java (72%) rename plugins/{com.python.pydev.refactoring/src/com/python/pydev => com.python.pydev.analysis/src/com/python/pydev/analysis}/refactoring/tdd/AbstractPyCreateClassOrMethodOrField.java (89%) rename plugins/{com.python.pydev.refactoring/src/com/python/pydev => com.python.pydev.analysis/src/com/python/pydev/analysis}/refactoring/tdd/NullPyCreateAction.java (71%) rename plugins/{com.python.pydev.refactoring/src/com/python/pydev => com.python.pydev.analysis/src/com/python/pydev/analysis}/refactoring/tdd/PyCreateClass.java (89%) rename plugins/{com.python.pydev.refactoring/src/com/python/pydev => com.python.pydev.analysis/src/com/python/pydev/analysis}/refactoring/tdd/PyCreateMethodOrField.java (97%) create mode 100644 plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/TemplateInfo.java create mode 100644 plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixFromMarkersParticipant.java rename plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/{TddCodeGenerationQuickFixParticipant.java => TddCodeGenerationQuickFixWithoutMarkersParticipant.java} (85%) rename plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/{TddQuickFixParticipant.java => TddQuickFixFromMarkersParticipant.java} (95%) create mode 100644 plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipantWithMarkersTest.java rename plugins/{org.python.pydev/src/com/python/pydev/analysis/ctrl_1 => org.python.pydev.core/src/org/python/pydev/core}/IAnalysisMarkersParticipant.java (81%) rename plugins/{org.python.pydev.ast/src/org/python/pydev/ast/analysis => org.python.pydev.core/src/org/python/pydev/core}/IAnalysisPreferences.java (99%) create mode 100644 plugins/org.python.pydev.core/src/org/python/pydev/core/IMarkerInfoForAnalysis.java create mode 100644 plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/PyEditStub.java rename plugins/org.python.pydev/{tests/org/python/pydev/parser => tests_completions/org/python/pydev/ast/codecompletion/revisited}/PydevFileEditorInputStub.java (95%) create mode 100644 plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/TextViewerStub.java diff --git a/plugins/com.python.pydev.analysis/META-INF/MANIFEST.MF b/plugins/com.python.pydev.analysis/META-INF/MANIFEST.MF index 2965cdfffc..b48a02a7bc 100644 --- a/plugins/com.python.pydev.analysis/META-INF/MANIFEST.MF +++ b/plugins/com.python.pydev.analysis/META-INF/MANIFEST.MF @@ -24,12 +24,14 @@ Export-Package: com.python.pydev.analysis, com.python.pydev.analysis.additionalinfo.dependencies, com.python.pydev.analysis.external, com.python.pydev.analysis.flake8, + com.python.pydev.analysis.marker_quick_fixes, com.python.pydev.analysis.mypy, com.python.pydev.analysis.pep8, com.python.pydev.analysis.pylint, com.python.pydev.analysis.refactoring.changes, com.python.pydev.analysis.refactoring.quick_fixes, com.python.pydev.analysis.refactoring.refactorer, + com.python.pydev.analysis.refactoring.tdd, com.python.pydev.analysis.refactoring.wizards, com.python.pydev.analysis.refactoring.wizards.rename, com.python.pydev.analysis.refactoring.wizards.rename.visitors, 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 6cc650c400..b6a7983b41 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 @@ -9,7 +9,7 @@ import java.util.HashMap; import java.util.Map; -import org.python.pydev.ast.analysis.IAnalysisPreferences; +import org.python.pydev.core.IAnalysisPreferences; public abstract class AbstractAnalysisPreferences implements IAnalysisPreferences { 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 27f26c6daf..7d915a5da1 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 @@ -17,7 +17,7 @@ import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.preferences.IEclipsePreferences; -import org.python.pydev.ast.analysis.IAnalysisPreferences; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.preferences.PydevPrefs; import org.python.pydev.shared_core.SharedCorePlugin; import org.python.pydev.shared_core.preferences.IScopedPreferences; @@ -119,7 +119,7 @@ private Map getSeverityTypeMap() { /** * return the severity based on the user-set values * - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#getSeverityForType(int) + * @see org.python.pydev.core.IAnalysisPreferences#getSeverityForType(int) */ @Override public int getSeverityForType(int type) { @@ -134,7 +134,7 @@ public int getSeverityForType(int type) { /** * yeah, we always do code analysis... * - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#makeCodeAnalysis() + * @see org.python.pydev.core.IAnalysisPreferences#makeCodeAnalysis() */ @Override public boolean makeCodeAnalysis() { @@ -147,7 +147,7 @@ public boolean makeCodeAnalysis() { } /** - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#getNamesIgnoredByUnusedVariable() + * @see org.python.pydev.core.IAnalysisPreferences#getNamesIgnoredByUnusedVariable() */ @Override public Set getNamesIgnoredByUnusedVariable() { @@ -177,7 +177,7 @@ private Set getSetOfNames(String preferencesName) { } /** - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#getModuleNamePatternsToBeIgnored() + * @see org.python.pydev.core.IAnalysisPreferences#getModuleNamePatternsToBeIgnored() */ @Override public Set getModuleNamePatternsToBeIgnored() { 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 205da706cd..71caab3c6b 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 @@ -16,10 +16,10 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jface.text.IDocument; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.analysis.messages.IMessage; import org.python.pydev.ast.analysis.messages.Message; import org.python.pydev.ast.codecompletion.revisited.modules.SourceModule; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.IIndentPrefs; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.log.Log; diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/builders/AnalysisBuilderRunnable.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/builders/AnalysisBuilderRunnable.java index f2a8d617aa..cf26ce424d 100644 --- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/builders/AnalysisBuilderRunnable.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/builders/AnalysisBuilderRunnable.java @@ -20,11 +20,11 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jface.text.IDocument; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.analysis.messages.IMessage; import org.python.pydev.ast.builder.PyDevBuilderVisitor; import org.python.pydev.ast.codecompletion.revisited.modules.SourceModule; import org.python.pydev.core.CheckAnalysisErrors; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.IModule; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.MisconfigurationException; diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/builders/AnalysisRunner.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/builders/AnalysisRunner.java index a543d1d0ca..d2b1613891 100644 --- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/builders/AnalysisRunner.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/additionalinfo/builders/AnalysisRunner.java @@ -174,7 +174,8 @@ public List setMarkers(IResource resource, IDocument document, IMess return null; } - public ArrayList generateMarkers(IDocument document, IMessage[] messages, IProgressMonitor monitor) { + public static ArrayList generateMarkers(IDocument document, IMessage[] messages, + IProgressMonitor monitor) { ArrayList lst = new ArrayList(); //add the markers... the id is put as additional info for it for (IMessage m : messages) { diff --git a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/DontAnalyzeFileMarkerParticipant.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes/DontAnalyzeFileMarkerParticipant.java similarity index 93% rename from plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/DontAnalyzeFileMarkerParticipant.java rename to plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes/DontAnalyzeFileMarkerParticipant.java index 2c66067fe2..6ee48d39a7 100644 --- a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/DontAnalyzeFileMarkerParticipant.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes/DontAnalyzeFileMarkerParticipant.java @@ -4,7 +4,7 @@ * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ -package com.python.pydev.analysis.ctrl_1; +package com.python.pydev.analysis.marker_quick_fixes; import java.io.File; import java.util.ArrayList; @@ -16,12 +16,12 @@ import org.python.pydev.core.IPythonNature; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.proposals.CompletionProposalFactory; +import org.python.pydev.shared_core.SharedCorePlugin; import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; import org.python.pydev.shared_core.code_completion.IPyCompletionProposal; import org.python.pydev.shared_core.image.IImageCache; import org.python.pydev.shared_core.image.IImageHandle; import org.python.pydev.shared_core.image.UIConstants; -import org.python.pydev.shared_ui.SharedUiPlugin; import com.python.pydev.analysis.additionalinfo.builders.AnalysisRunner; @@ -30,7 +30,7 @@ public class DontAnalyzeFileMarkerParticipant implements IAssistProps { private IImageHandle annotationImage; public DontAnalyzeFileMarkerParticipant() { - IImageCache analysisImageCache = SharedUiPlugin.getImageCache(); + IImageCache analysisImageCache = SharedCorePlugin.getImageCache(); annotationImage = analysisImageCache.get(UIConstants.ASSIST_ANNOTATION); } diff --git a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/IgnoreErrorParticipant.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes/IgnoreErrorParticipant.java similarity index 77% rename from plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/IgnoreErrorParticipant.java rename to plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes/IgnoreErrorParticipant.java index b71052e3b9..2990328373 100644 --- a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/IgnoreErrorParticipant.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes/IgnoreErrorParticipant.java @@ -9,7 +9,7 @@ * * @author Fabio Zadrozny */ -package com.python.pydev.analysis.ctrl_1; +package com.python.pydev.analysis.marker_quick_fixes; import java.util.HashSet; import java.util.List; @@ -17,21 +17,20 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.BadLocationException; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.core.CheckAnalysisErrors; +import org.python.pydev.core.IAnalysisMarkersParticipant; +import org.python.pydev.core.IAnalysisPreferences; +import org.python.pydev.core.IMarkerInfoForAnalysis; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.formatter.FormatStd; import org.python.pydev.core.proposals.CompletionProposalFactory; -import org.python.pydev.editor.codefolding.MarkerAnnotationAndPosition; +import org.python.pydev.shared_core.SharedCorePlugin; import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; import org.python.pydev.shared_core.code_completion.IPyCompletionProposal; import org.python.pydev.shared_core.image.IImageCache; import org.python.pydev.shared_core.image.UIConstants; -import org.python.pydev.shared_ui.SharedUiPlugin; - -import com.python.pydev.analysis.additionalinfo.builders.AnalysisRunner; public class IgnoreErrorParticipant implements IAnalysisMarkersParticipant { @@ -43,19 +42,23 @@ public IgnoreErrorParticipant() { this(null); } + private IgnoreErrorParticipant(FormatStd format) { + this.format = format; + } + /** * Only for tests. */ - /*default*/ IgnoreErrorParticipant(FormatStd format) { - this.format = format; + public static IgnoreErrorParticipant createForTests(FormatStd format) { + return new IgnoreErrorParticipant(format); } @Override - public void addProps(MarkerAnnotationAndPosition marker, IAnalysisPreferences analysisPreferences, + public void addProps(IMarkerInfoForAnalysis markerInfo, IAnalysisPreferences analysisPreferences, final String line, final PySelection ps, int offset, IPythonNature nature, final IPyEdit edit, List props) throws BadLocationException, CoreException { - Integer id = (Integer) marker.markerAnnotation.getMarker().getAttribute(AnalysisRunner.PYDEV_ANALYSIS_TYPE); + Integer id = markerInfo.getPyDevAnalisysType(); if (handled.contains(id)) { return; } @@ -65,7 +68,7 @@ public void addProps(MarkerAnnotationAndPosition marker, IAnalysisPreferences an return; } - IImageCache imageCache = SharedUiPlugin.getImageCache(); + IImageCache imageCache = SharedCorePlugin.getImageCache(); ICompletionProposalHandle proposal = CompletionProposalFactory.get().createIgnoreCompletionProposalInSameLine( messageToIgnore, ps.getEndLineOffset(), 0, offset, imageCache != null ? imageCache.get(UIConstants.ASSIST_ANNOTATION) : null, diff --git a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/UndefinedVariableFixParticipant.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes/UndefinedVariableFixParticipant.java similarity index 74% rename from plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/UndefinedVariableFixParticipant.java rename to plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes/UndefinedVariableFixParticipant.java index 3cbf00ef54..88cb0a2e16 100644 --- a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/UndefinedVariableFixParticipant.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/marker_quick_fixes/UndefinedVariableFixParticipant.java @@ -7,22 +7,21 @@ /* * Created on 24/09/2005 */ -package com.python.pydev.analysis.ctrl_1; +package com.python.pydev.analysis.marker_quick_fixes; import java.util.List; -import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.BadLocationException; -import org.python.pydev.ast.analysis.IAnalysisPreferences; +import org.python.pydev.core.IAnalysisMarkersParticipant; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.ICodeCompletionASTManager; +import org.python.pydev.core.IMarkerInfoForAnalysis; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.docutils.PySelection; -import org.python.pydev.editor.codefolding.MarkerAnnotationAndPosition; import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; -import com.python.pydev.analysis.additionalinfo.builders.AnalysisRunner; import com.python.pydev.analysis.refactoring.quick_fixes.UndefinedVariableQuickFixCreator; /** @@ -46,12 +45,11 @@ public UndefinedVariableFixParticipant(boolean forceReparseOnApply) { } @Override - public void addProps(MarkerAnnotationAndPosition markerAnnotation, IAnalysisPreferences analysisPreferences, + public void addProps(IMarkerInfoForAnalysis markerInfoForAnalysis, IAnalysisPreferences analysisPreferences, String line, PySelection ps, int offset, IPythonNature initialNature, IPyEdit edit, List props) throws BadLocationException, CoreException { - IMarker marker = markerAnnotation.markerAnnotation.getMarker(); - Integer id = (Integer) marker.getAttribute(AnalysisRunner.PYDEV_ANALYSIS_TYPE); + Integer id = markerInfoForAnalysis.getPyDevAnalisysType(); if (id != IAnalysisPreferences.TYPE_UNDEFINED_VARIABLE) { return; } @@ -63,11 +61,11 @@ public void addProps(MarkerAnnotationAndPosition markerAnnotation, IAnalysisPref return; } - if (markerAnnotation.position == null) { + if (!markerInfoForAnalysis.hasPosition()) { return; } - int start = markerAnnotation.position.offset; - int end = start + markerAnnotation.position.length; + int start = markerInfoForAnalysis.getOffset(); + int end = start + markerInfoForAnalysis.getLength(); UndefinedVariableQuickFixCreator.createImportQuickProposalsFromMarkerSelectedText(edit, ps, offset, initialNature, props, astManager, start, end, forceReparseOnApply); } diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/pep8/Pep8Visitor.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/pep8/Pep8Visitor.java index 2df13c7fbd..4ab7dbd0ad 100644 --- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/pep8/Pep8Visitor.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/pep8/Pep8Visitor.java @@ -15,12 +15,12 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.analysis.messages.IMessage; import org.python.pydev.ast.analysis.messages.Message; import org.python.pydev.ast.codecompletion.revisited.modules.SourceModule; import org.python.pydev.core.CheckAnalysisErrors; import org.python.pydev.core.CorePlugin; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.log.Log; import org.python.pydev.core.pep8.Pep8Runner; diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/quick_fixes/DummyMarkerInfoForAnalysis.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/quick_fixes/DummyMarkerInfoForAnalysis.java new file mode 100644 index 0000000000..8d538f8c6c --- /dev/null +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/quick_fixes/DummyMarkerInfoForAnalysis.java @@ -0,0 +1,60 @@ +package com.python.pydev.analysis.refactoring.quick_fixes; + +import org.python.pydev.core.IMarkerInfoForAnalysis; + +public class DummyMarkerInfoForAnalysis implements IMarkerInfoForAnalysis { + + public Object message; + public Object flake8MessageId; + public int length; + public int offset; + public Integer pyDevAnalysisType; + public Object pyLintMessageId; + + public DummyMarkerInfoForAnalysis(int pyDevAnalysisType, int offset, int length) { + this.pyDevAnalysisType = pyDevAnalysisType; + this.offset = offset; + this.length = length; + } + + @Override + public Object getPyLintMessageIdAttribute() { + return pyLintMessageId; + } + + @Override + public Integer getPyDevAnalisysType() { + return pyDevAnalysisType; + } + + @Override + public boolean hasPosition() { + return true; + } + + @Override + public int getOffset() { + return offset; + } + + @Override + public int getLength() { + return length; + } + + @Override + public void delete() { + + } + + @Override + public Object getFlake8MessageId() { + return flake8MessageId; + } + + @Override + public Object getMessage() { + return message; + } + +} diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/AbstractPyCreateAction.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/AbstractPyCreateAction.java similarity index 72% rename from plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/AbstractPyCreateAction.java rename to plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/AbstractPyCreateAction.java index 081b370027..a34ae99f80 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/AbstractPyCreateAction.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/AbstractPyCreateAction.java @@ -4,14 +4,12 @@ * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ -package com.python.pydev.refactoring.tdd; +package com.python.pydev.analysis.refactoring.tdd; import java.util.List; -import org.eclipse.jface.action.IAction; import org.python.pydev.ast.refactoring.RefactoringInfo; import org.python.pydev.core.IPyEdit; -import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; public abstract class AbstractPyCreateAction { @@ -21,11 +19,11 @@ public abstract class AbstractPyCreateAction { protected IPyEdit targetEditor; - public void setActiveEditor(IAction action, IPyEdit edit) { + public void setActiveEditor(IPyEdit edit) { this.targetEditor = edit; } - public abstract ICompletionProposalHandle createProposal(RefactoringInfo refactoringInfo, String actTok, + public abstract TemplateInfo createProposal(RefactoringInfo refactoringInfo, String actTok, int locationStrategy, List parametersAfterCall); } diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/AbstractPyCreateClassOrMethodOrField.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/AbstractPyCreateClassOrMethodOrField.java similarity index 89% rename from plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/AbstractPyCreateClassOrMethodOrField.java rename to plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/AbstractPyCreateClassOrMethodOrField.java index 8a71b7b309..e1be76a5c8 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/AbstractPyCreateClassOrMethodOrField.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/AbstractPyCreateClassOrMethodOrField.java @@ -4,7 +4,7 @@ * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ -package com.python.pydev.refactoring.tdd; +package com.python.pydev.analysis.refactoring.tdd; import java.util.List; @@ -22,12 +22,10 @@ import org.python.pydev.core.docutils.PySelection.LineStartingScope; import org.python.pydev.core.docutils.PyStringUtils; import org.python.pydev.core.log.Log; -import org.python.pydev.core.proposals.CompletionProposalFactory; import org.python.pydev.core.templates.PyDocumentTemplateContext; import org.python.pydev.parser.jython.ast.ClassDef; import org.python.pydev.parser.jython.ast.Pass; import org.python.pydev.parser.visitors.NodeUtils; -import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; import org.python.pydev.shared_core.string.FastStringBuffer; import org.python.pydev.shared_core.string.StringUtils; import org.python.pydev.shared_core.structure.Tuple; @@ -36,14 +34,14 @@ public abstract class AbstractPyCreateClassOrMethodOrField extends AbstractPyCre public abstract String getCreationStr(); - protected abstract String getDefaultActTok(); + public abstract String getDefaultActTok(); - protected ICompletionProposalHandle createProposal(PySelection pySelection, String source, + protected TemplateInfo createProposal(PySelection pySelection, String source, Tuple offsetAndIndent) { return createProposal(pySelection, source, offsetAndIndent, true, null); } - protected ICompletionProposalHandle createProposal(PySelection pySelection, String source, + protected TemplateInfo createProposal(PySelection pySelection, String source, Tuple offsetAndIndent, boolean requireEmptyLines, Pass replacePassStatement) { int offset; int len; @@ -102,25 +100,22 @@ protected ICompletionProposalHandle createProposal(PySelection pySelection, Stri } } + String creationStr = getCreationStr(); + Region region = new Region(offset, len); + //Note: was using new PyContextType(), but when we had something as ${user} it + //would end up replacing it with the actual name of the user, which is not what + //we want! + PyDocumentTemplateContext context; if (targetEditor != null) { - String creationStr = getCreationStr(); - Region region = new Region(offset, len); - //Note: was using new PyContextType(), but when we had something as ${user} it - //would end up replacing it with the actual name of the user, which is not what - //we want! - PyDocumentTemplateContext context = PyDocumentTemplateContext.createContextWithCursor(targetEditor, region, + context = PyDocumentTemplateContext.createContextWithCursor(targetEditor, region, indent); - - Template template = new Template("Create " + creationStr, "Create " + creationStr, "", source, true); - ICompletionProposalHandle templateProposal = CompletionProposalFactory.get() - .createPyTemplateProposal(template, context, region, null, 0); - return templateProposal; - } else { - //This should only happen in tests. - source = StringUtils.indentTo(source, indent, false); - return CompletionProposalFactory.get().createPyCompletionProposal(source, offset, len, 0, 0); + context = PyDocumentTemplateContext.createContextWithCursor(targetEditor, pySelection.getDoc(), region, + indent); } + + Template template = new Template("Create " + creationStr, "Create " + creationStr, "", source, true); + return new TemplateInfo(template, context, region); } /** diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/NullPyCreateAction.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/NullPyCreateAction.java similarity index 71% rename from plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/NullPyCreateAction.java rename to plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/NullPyCreateAction.java index b34cabf63e..6c63ed9b13 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/NullPyCreateAction.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/NullPyCreateAction.java @@ -4,17 +4,16 @@ * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ -package com.python.pydev.refactoring.tdd; +package com.python.pydev.analysis.refactoring.tdd; import java.util.List; import org.python.pydev.ast.refactoring.RefactoringInfo; -import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; public class NullPyCreateAction extends AbstractPyCreateAction { @Override - public ICompletionProposalHandle createProposal(RefactoringInfo refactoringInfo, String actTok, + public TemplateInfo createProposal(RefactoringInfo refactoringInfo, String actTok, int locationStrategy, List parametersAfterCall) { return null; diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/PyCreateClass.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/PyCreateClass.java similarity index 89% rename from plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/PyCreateClass.java rename to plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/PyCreateClass.java index a2c49144e7..8c9ce5b8ed 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/PyCreateClass.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/PyCreateClass.java @@ -4,14 +4,13 @@ * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ -package com.python.pydev.refactoring.tdd; +package com.python.pydev.analysis.refactoring.tdd; import java.util.List; import org.python.pydev.ast.adapters.ModuleAdapter; import org.python.pydev.ast.refactoring.RefactoringInfo; import org.python.pydev.core.docutils.PySelection; -import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; import org.python.pydev.shared_core.string.FastStringBuffer; import org.python.pydev.shared_core.string.StringUtils; import org.python.pydev.shared_core.structure.Tuple; @@ -44,7 +43,7 @@ public String getCreationStr() { } @Override - protected String getDefaultActTok() { + public String getDefaultActTok() { return "MyClass"; } @@ -52,7 +51,7 @@ protected String getDefaultActTok() { * Returns a proposal that can be used to generate the code. */ @Override - public ICompletionProposalHandle createProposal(RefactoringInfo refactoringInfo, String actTok, + public TemplateInfo createProposal(RefactoringInfo refactoringInfo, String actTok, int locationStrategy, List parametersAfterCall) { PySelection pySelection = refactoringInfo.getPySelection(); diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/PyCreateMethodOrField.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/PyCreateMethodOrField.java similarity index 97% rename from plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/PyCreateMethodOrField.java rename to plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/PyCreateMethodOrField.java index c85b4b4a98..5df225e6ba 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/PyCreateMethodOrField.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/PyCreateMethodOrField.java @@ -4,7 +4,7 @@ * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ -package com.python.pydev.refactoring.tdd; +package com.python.pydev.analysis.refactoring.tdd; import java.util.ArrayList; import java.util.List; @@ -22,7 +22,6 @@ import org.python.pydev.parser.jython.ast.Pass; import org.python.pydev.parser.jython.ast.stmtType; import org.python.pydev.parser.visitors.NodeUtils; -import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; import org.python.pydev.shared_core.string.StringUtils; import org.python.pydev.shared_core.structure.Tuple; @@ -49,7 +48,7 @@ public String getCreationStr() { } @Override - protected String getDefaultActTok() { + public String getDefaultActTok() { if (createAs == FIELD) { return "my_field"; } @@ -63,7 +62,7 @@ protected String getDefaultActTok() { * Returns a proposal that can be used to generate the code. */ @Override - public ICompletionProposalHandle createProposal(RefactoringInfo refactoringInfo, String actTok, + public TemplateInfo createProposal(RefactoringInfo refactoringInfo, String actTok, int locationStrategy, List parametersAfterCall) { PySelection pySelection = refactoringInfo.getPySelection(); diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/TemplateInfo.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/TemplateInfo.java new file mode 100644 index 0000000000..afb6bd1e76 --- /dev/null +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/refactoring/tdd/TemplateInfo.java @@ -0,0 +1,85 @@ +package com.python.pydev.analysis.refactoring.tdd; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.templates.DocumentTemplateContext; +import org.eclipse.jface.text.templates.Template; +import org.eclipse.jface.text.templates.TemplateBuffer; +import org.eclipse.jface.text.templates.TemplateContext; +import org.eclipse.jface.text.templates.TemplateException; +import org.python.pydev.core.log.Log; + +public class TemplateInfo { + + public Template fTemplate; + public TemplateContext fContext; + public IRegion fRegion; + + public TemplateInfo(Template template, TemplateContext context, IRegion region) { + this.fTemplate = template; + this.fContext = context; + this.fRegion = region; + } + + /** + * Returns the offset of the range in the document that will be replaced by + * applying this template. + * + * @return the offset of the range in the document that will be replaced by + * applying this template + * @since 3.1 + */ + protected final int getReplaceOffset() { + int start; + if (fContext instanceof DocumentTemplateContext) { + DocumentTemplateContext docContext = (DocumentTemplateContext) fContext; + start = docContext.getStart(); + } else { + start = fRegion.getOffset(); + } + return start; + } + + /** + * Returns the end offset of the range in the document that will be replaced + * by applying this template. + * + * @return the end offset of the range in the document that will be replaced + * by applying this template + * @since 3.1 + */ + protected final int getReplaceEndOffset() { + int end; + if (fContext instanceof DocumentTemplateContext) { + DocumentTemplateContext docContext = (DocumentTemplateContext) fContext; + end = docContext.getEnd(); + } else { + end = fRegion.getOffset() + fRegion.getLength(); + } + return end; + } + + public void apply(IDocument document) { + try { + fContext.setReadOnly(false); + int start; + TemplateBuffer templateBuffer; + try { + // this may already modify the document (e.g. add imports) + templateBuffer = fContext.evaluate(fTemplate); + } catch (TemplateException e1) { + return; + } + + start = getReplaceOffset(); + int end = getReplaceEndOffset(); + + // insert template string + String templateString = templateBuffer.getString(); + document.replace(start, end - start, templateString); + } catch (Exception e) { + Log.log(e); + } + } + +} \ No newline at end of file diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/tabnanny/TabNanny.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/tabnanny/TabNanny.java index 0926d18f8c..b4e4b3f85e 100644 --- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/tabnanny/TabNanny.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/tabnanny/TabNanny.java @@ -14,9 +14,9 @@ import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.analysis.messages.IMessage; import org.python.pydev.ast.analysis.messages.Message; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.IIndentPrefs; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.docutils.TabNannyDocIterator; diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/DuplicationChecker.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/DuplicationChecker.java index eeaccade11..914f65f0f9 100644 --- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/DuplicationChecker.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/DuplicationChecker.java @@ -12,9 +12,9 @@ import java.util.HashMap; import java.util.Map; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.codecompletion.revisited.modules.SourceToken; import org.python.pydev.ast.codecompletion.revisited.visitors.AbstractVisitor; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.IModule; import org.python.pydev.core.IPythonNature; import org.python.pydev.parser.jython.SimpleNode; diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/MessagesManager.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/MessagesManager.java index 4de3f05bee..aed4a2d495 100644 --- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/MessagesManager.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/MessagesManager.java @@ -18,7 +18,6 @@ import org.eclipse.core.resources.IMarker; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.analysis.messages.CompositeMessage; import org.python.pydev.ast.analysis.messages.IMessage; import org.python.pydev.ast.analysis.messages.Message; @@ -26,6 +25,7 @@ import org.python.pydev.ast.codecompletion.revisited.visitors.AbstractVisitor; import org.python.pydev.ast.codecompletion.revisited.visitors.AbstractVisitor.ImportPartSourceToken; import org.python.pydev.core.CheckAnalysisErrors; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.IToken; import org.python.pydev.core.docutils.ParsingUtils; import org.python.pydev.core.docutils.PySelection; diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/NoSelfChecker.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/NoSelfChecker.java index ca9f9cfec3..08ba6a215c 100644 --- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/NoSelfChecker.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/NoSelfChecker.java @@ -12,9 +12,9 @@ import java.util.HashMap; import java.util.Map; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.codecompletion.revisited.modules.SourceToken; import org.python.pydev.ast.codecompletion.revisited.visitors.AbstractVisitor; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.ICompletionCache; import org.python.pydev.core.IModule; import org.python.pydev.parser.jython.ast.Assign; diff --git a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/OccurrencesVisitor.java b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/OccurrencesVisitor.java index dc15d3b8a1..be3744c907 100644 --- a/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/OccurrencesVisitor.java +++ b/plugins/com.python.pydev.analysis/src/com/python/pydev/analysis/visitors/OccurrencesVisitor.java @@ -19,12 +19,12 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.analysis.messages.IMessage; import org.python.pydev.ast.analysis.messages.Message; import org.python.pydev.ast.codecompletion.revisited.modules.SourceToken; import org.python.pydev.ast.codecompletion.revisited.visitors.AbstractVisitor; import org.python.pydev.ast.codecompletion.revisited.visitors.Definition; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.IDefinition; import org.python.pydev.core.IModule; import org.python.pydev.core.IPythonNature; diff --git a/plugins/com.python.pydev.refactoring/plugin.xml b/plugins/com.python.pydev.refactoring/plugin.xml index 6239749004..0ac9fa7919 100644 --- a/plugins/com.python.pydev.refactoring/plugin.xml +++ b/plugins/com.python.pydev.refactoring/plugin.xml @@ -4,7 +4,7 @@ - + @@ -43,7 +43,10 @@ - + + + + @@ -51,7 +54,7 @@ - + - - + + @@ -202,11 +205,11 @@ --> - + - + - + @@ -392,7 +395,7 @@ @@ -430,8 +433,8 @@ label="%peptic.InlineLocalLabel" menubarPath="org.python.pydev.refactoring.refactoringMenu/pepticRefactoringGroup" style="push"/> - - + + ''' - + for action in plugin_install.ACTIONS_AND_BINDING: cog.outl(template % (action.class_, action.id, action.id, action.desc, action.group)) ]]]--> @@ -538,7 +541,7 @@ label="%peptic.InlineLocalLabel" menubarPath="org.python.pydev.editor.refactoring/pepticRefactoringGroup"> - + diff --git a/plugins/com.python.pydev.refactoring/plugin_install.py b/plugins/com.python.pydev.refactoring/plugin_install.py index f06e022999..3ab497c2ba 100644 --- a/plugins/com.python.pydev.refactoring/plugin_install.py +++ b/plugins/com.python.pydev.refactoring/plugin_install.py @@ -13,7 +13,7 @@ def __init__(self, class_, key, desc, group): ACTIONS_AND_BINDING = [ #The actions below are now available through the Ctrl+1 quick fixes! - #Action('com.python.pydev.refactoring.tdd.PyCreateClass', 'Alt+Shift+S C', 'CreateClass', 'tddGroup'), - #Action('com.python.pydev.refactoring.tdd.PyCreateMethodOrField', 'Alt+Shift+S M', 'CreateMethod', 'tddGroup'), + #Action('com.python.pydev.analysis.refactoring.tdd.PyCreateClass', 'Alt+Shift+S C', 'CreateClass', 'tddGroup'), + #Action('com.python.pydev.analysis.refactoring.tdd.PyCreateMethodOrField', 'Alt+Shift+S M', 'CreateMethod', 'tddGroup'), Action('org.python.pydev.refactoring.ui.actions.ExtractMethodAction', ('M2+M3+M', 'M3+M2+T E'), 'ExtractMethod', 'pepticRefactoringGroup'), ] \ No newline at end of file diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixFromMarkersParticipant.java b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixFromMarkersParticipant.java new file mode 100644 index 0000000000..8f1c880662 --- /dev/null +++ b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixFromMarkersParticipant.java @@ -0,0 +1,21 @@ +package com.python.pydev.refactoring.tdd; + +import com.python.pydev.analysis.additionalinfo.builders.AnalysisRunner; +import com.python.pydev.analysis.ctrl_1.AbstractAnalysisMarkersParticipants; + +public class TddCodeGenerationQuickFixFromMarkersParticipant extends AbstractAnalysisMarkersParticipants { + + private TddQuickFixFromMarkersParticipant tddQuickFixParticipant; + + @Override + protected void fillParticipants() { + tddQuickFixParticipant = new TddQuickFixFromMarkersParticipant(); + participants.add(tddQuickFixParticipant); + } + + @Override + protected String getMarkerType() { + return AnalysisRunner.PYDEV_ANALYSIS_PROBLEM_MARKER; + } + +} diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipant.java b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixWithoutMarkersParticipant.java similarity index 85% rename from plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipant.java rename to plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixWithoutMarkersParticipant.java index a477151f39..0ee4eb05b0 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipant.java +++ b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixWithoutMarkersParticipant.java @@ -1,9 +1,3 @@ -/** - * Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved. - * Licensed under the terms of the Eclipse Public License (EPL). - * Please see the license.txt included with this distribution for details. - * Any modifications to this file must keep this entire header intact. - */ package com.python.pydev.refactoring.tdd; import java.io.File; @@ -23,6 +17,7 @@ import org.python.pydev.ast.refactoring.AbstractPyRefactoring; import org.python.pydev.ast.refactoring.IPyRefactoring; import org.python.pydev.ast.refactoring.RefactoringRequest; +import org.python.pydev.core.IAssistProps; import org.python.pydev.core.ICompletionCache; import org.python.pydev.core.IDefinition; import org.python.pydev.core.IPyEdit; @@ -51,177 +46,247 @@ import org.python.pydev.shared_core.string.FullRepIterable; import org.python.pydev.shared_core.string.StringUtils; -import com.python.pydev.analysis.additionalinfo.builders.AnalysisRunner; -import com.python.pydev.analysis.ctrl_1.AbstractAnalysisMarkersParticipants; +import com.python.pydev.analysis.refactoring.tdd.AbstractPyCreateAction; +import com.python.pydev.analysis.refactoring.tdd.PyCreateClass; +import com.python.pydev.analysis.refactoring.tdd.PyCreateMethodOrField; -public class TddCodeGenerationQuickFixParticipant extends AbstractAnalysisMarkersParticipants { +public class TddCodeGenerationQuickFixWithoutMarkersParticipant implements IAssistProps { - private TddQuickFixParticipant tddQuickFixParticipant; + /** + * Just to set in tests to raise an exception. + */ + public static ICallback onGetTddPropsError; @Override - protected void fillParticipants() { - tddQuickFixParticipant = new TddQuickFixParticipant(); - participants.add(tddQuickFixParticipant); + public List getProps(PySelection ps, IImageCache imageCache, File f, + IPythonNature nature, IPyEdit edit, int offset) throws BadLocationException, MisconfigurationException { + List ret = new ArrayList<>(); + TddCodeGenerationQuickFixWithoutMarkersParticipant.getTddProps(ps, imageCache, f, nature, edit, offset, ret); + return ret; } @Override - protected String getMarkerType() { - return AnalysisRunner.PYDEV_ANALYSIS_PROBLEM_MARKER; + public boolean isValid(PySelection ps, String sel, IPyEdit edit, int offset) { + return ps.getSelLength() == 0; } - @Override - public List getProps(PySelection ps, IImageCache imageCache, File f, - IPythonNature nature, - IPyEdit edit, int offset) throws BadLocationException { - List ret = super.getProps(ps, imageCache, f, nature, edit, offset); - TddCodeGenerationQuickFixParticipant.getTddProps(ps, imageCache, f, nature, edit, offset, ret); - return ret; - } + public static ASTEntry findInitInClass(ClassDef d) { + EasyASTIteratorVisitor visitor = EasyASTIteratorVisitor.create(d); - public static List getTddProps( - PySelection ps, - IImageCache imageCache, - File f, - IPythonNature nature, - IPyEdit edit, - int offset, - List ret) { - if (ret == null) { - ret = new ArrayList(); - } - if (imageCache == null) { - imageCache = new DummyImageCache(); + for (Iterator it = visitor.getMethodsIterator(); it.hasNext();) { + ASTEntry next = it.next(); + if (next.node != null) { + String rep = NodeUtils.getRepresentationString(next.node); + if ("__init__".equals(rep)) { + return next; + } + } } - //Additional option: Generate markers for 'self.' accesses - int lineOfOffset = ps.getLineOfOffset(offset); - String lineContents = ps.getLine(lineOfOffset); + return null; + } - //Additional option: Generate methods for function calls - List callsAtLine = ps.getTddPossibleMatchesAtLine(); - if (callsAtLine.size() > 0) { - //Make sure we don't check the same thing twice. - Map callsToCheck = new HashMap(); - for (TddPossibleMatches call : callsAtLine) { - String callString = call.initialPart + call.secondPart; - callsToCheck.put(callString, call); + static boolean checkInitCreation(IPyEdit edit, PySelection callPs, ItemPointer[] pointers, + List ret, IImageCache imageCache) { + for (ItemPointer pointer : pointers) { + Definition definition = pointer.definition; + if (definition != null && definition.ast instanceof ClassDef) { + ClassDef d = (ClassDef) definition.ast; + ASTEntry initEntry = TddCodeGenerationQuickFixWithoutMarkersParticipant.findInitInClass(d); + + if (initEntry == null) { + //Give the user a chance to create the __init__. + PyCreateMethodOrField pyCreateMethod = new PyCreateMethodOrField(); + pyCreateMethod.setCreateAs(PyCreateMethodOrField.BOUND_METHOD); + String className = NodeUtils.getRepresentationString(d); + pyCreateMethod.setCreateInClass(className); + + List parametersAfterCall = callPs.getParametersAfterCall(callPs.getAbsoluteCursorOffset()); + String displayString = StringUtils.format( + "Create %s __init__ (%s)", className, + definition.module.getName()); + TddRefactorCompletionInModule completion = new TddRefactorCompletionInModule("__init__", + imageCache.get(UIConstants.CREATE_METHOD_ICON), displayString, null, displayString, + IPyCompletionProposal.PRIORITY_CREATE, edit, definition.module.getFile(), + parametersAfterCall, pyCreateMethod, callPs, + AbstractPyCreateAction.LOCATION_STRATEGY_FIRST_METHOD); + ret.add(completion); + return true; + } } + } + return false; + } - CONTINUE_FOR: for (Map.Entry entry : callsToCheck.entrySet()) { - //we have at least something as SomeClass(a=2,c=3) or self.bar or self.foo.bar() or just foo.bar, etc. - IPyRefactoring pyRefactoring = AbstractPyRefactoring.getPyRefactoring(); - try { - TddPossibleMatches possibleMatch = entry.getValue(); - String callWithoutParens = entry.getKey(); + static void addCreateMethodOption(PySelection ps, IPyEdit edit, List props, + String markerContents, List parametersAfterCall, PyCreateMethodOrField pyCreateMethod, + String classNameInLine, IImageCache imageCache) { + String displayString = StringUtils.format("Create %s %s at %s", + markerContents, + pyCreateMethod.getCreationStr(), classNameInLine); + TddRefactorCompletion tddRefactorCompletion = new TddRefactorCompletion(markerContents, + imageCache.get(UIConstants.CREATE_METHOD_ICON), displayString, null, null, + IPyCompletionProposal.PRIORITY_CREATE, + edit, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT, parametersAfterCall, pyCreateMethod, ps); + props.add(tddRefactorCompletion); + } - ItemPointer[] pointers = null; - PySelection callPs = null; - TddPossibleMatches lastPossibleMatchNotFound = possibleMatch; + static List configCreateAsAndReturnParametersAfterCall(PySelection callPs, boolean isCall, + PyCreateMethodOrField pyCreateMethod, List parametersAfterCall, String methodToCreate) { + if (isCall) { + pyCreateMethod.setCreateAs(PyCreateMethodOrField.BOUND_METHOD); + parametersAfterCall = callPs.getParametersAfterCall(callPs.getAbsoluteCursorOffset()); + } else { + if (StringUtils.isAllUpper(methodToCreate)) { + pyCreateMethod.setCreateAs(PyCreateMethodOrField.CONSTANT); - for (int i = 0; i < 10; i++) { //more than 10 attribute accesses in a line? No way! + } else { + pyCreateMethod.setCreateAs(PyCreateMethodOrField.FIELD); + } + } + return parametersAfterCall; + } - lastPossibleMatchNotFound = possibleMatch; - if (i > 0) { - //We have to take 1 level out of the match... i.e.: if it was self.foo.get(), search now for self.foo. - String line = FullRepIterable.getWithoutLastPart(possibleMatch.full); - List tddPossibleMatchesAtLine = ps.getTddPossibleMatchesAtLine(line); - if (tddPossibleMatchesAtLine.size() > 0) { - possibleMatch = tddPossibleMatchesAtLine.get(0); - callWithoutParens = possibleMatch.initialPart + possibleMatch.secondPart; - } else { - continue CONTINUE_FOR; - } - } - String full = possibleMatch.full; - int indexOf = lineContents.indexOf(full); - if (indexOf < 0) { - Log.log("Did not expect index < 0."); - continue CONTINUE_FOR; - } - callPs = new PySelection(ps.getDoc(), - ps.getLineOffset() + indexOf + callWithoutParens.length()); + public static boolean checkCreationBasedOnFoundPointers(IPyEdit edit, PySelection callPs, + List ret, + TddPossibleMatches possibleMatch, ItemPointer[] pointers, String methodToCreate, PySelection newSelection, + IPythonNature nature, IImageCache imageCache) throws MisconfigurationException, Exception { + CompletionCache completionCache = new CompletionCache(); + for (ItemPointer pointer : pointers) { + Definition definition = pointer.definition; - RefactoringRequest request = new RefactoringRequest(f, callPs, null, nature, edit); - //Don't look in additional info. - request.setAdditionalInfo( - RefactoringRequest.FIND_DEFINITION_IN_ADDITIONAL_INFO, false); - pointers = pyRefactoring.findDefinition(request); + try { + definition = rebaseToClassDefDefinition(nature, completionCache, definition, null); + } catch (CompletionRecursionException e) { + Log.log(e); //Just keep going. + } - if (((pointers != null && pointers.length > 0) - || StringUtils.count(possibleMatch.full, '.') <= 1)) { - break; - } - } + if (definition.ast instanceof ClassDef) { + ClassDef d = (ClassDef) definition.ast; + String fullName = NodeUtils.getRepresentationString(d) + "." + methodToCreate; + IToken repInModule = nature.getAstManager().getRepInModule(definition.module, fullName, nature); + if (repInModule != null) { + //System.out.println("Skipping creation of: " + fullName); //We found it, so, don't suggest it. + continue; + } - if (pointers == null || callPs == null) { - continue CONTINUE_FOR; - } + for (Boolean isCall : new Boolean[] { true, false }) { + //Give the user a chance to create the method we didn't find. + PyCreateMethodOrField pyCreateMethod = new PyCreateMethodOrField(); + List parametersAfterCall = null; + parametersAfterCall = TddCodeGenerationQuickFixWithoutMarkersParticipant + .configCreateAsAndReturnParametersAfterCall(callPs, isCall, pyCreateMethod, + parametersAfterCall, methodToCreate); + String className = NodeUtils.getRepresentationString(d); + pyCreateMethod.setCreateInClass(className); - if (lastPossibleMatchNotFound != null && lastPossibleMatchNotFound != possibleMatch - && pointers.length >= 1) { - //Ok, as we were analyzing a string as self.bar.foo, we didn't find something in a pass - //i.e.: self.bar.foo, but we found it in a second pass - //as self.bar, so, this means we have to open the chance to create the 'foo' in self.bar. - String methodToCreate = FullRepIterable.getLastPart(lastPossibleMatchNotFound.secondPart); - int absoluteCursorOffset = callPs.getAbsoluteCursorOffset(); - absoluteCursorOffset = absoluteCursorOffset - (1 + methodToCreate.length()); //+1 for the dot removed too. - PySelection newSelection = new PySelection(callPs.getDoc(), absoluteCursorOffset); + String displayString = StringUtils.format( + "Create %s %s at %s (%s)", methodToCreate, + pyCreateMethod.getCreationStr(), className, definition.module.getName()); - checkCreationBasedOnFoundPointers(edit, callPs, ret, possibleMatch, pointers, methodToCreate, - newSelection, nature, imageCache); - continue CONTINUE_FOR; - } + TddRefactorCompletionInModule completion = new TddRefactorCompletionInModule(methodToCreate, + imageCache.get(UIConstants.CREATE_METHOD_ICON), displayString, + null, displayString, IPyCompletionProposal.PRIORITY_CREATE, edit, + definition.module.getFile(), parametersAfterCall, pyCreateMethod, newSelection, + AbstractPyCreateAction.LOCATION_STRATEGY_END); + ret.add(completion); + } + return true; + } + } + return false; + } - if (pointers.length >= 1) { + static Definition rebaseToClassDefDefinition(IPythonNature nature, CompletionCache completionCache, + Definition definition, CompletionState completionState) throws CompletionRecursionException, Exception { - //Ok, we found whatever was there, so, we don't need to create anything (except maybe do - //the __init__ or something at the class level). - if (!checkInitCreation(edit, callPs, pointers, ret, imageCache)) { - //This was called only when isCall == false - //Ok, if it's not a call and we found a field, it's still possible that we may want to create - //a field if it wasn't found in the __init__ - boolean foundInInit = false; - for (ItemPointer p : pointers) { - Definition definition = p.definition; - try { - Object peek = definition.scope.getScopeStack().peek(); - if (peek instanceof FunctionDef) { - FunctionDef functionDef = (FunctionDef) peek; - String rep = NodeUtils.getRepresentationString(functionDef); - if (rep != null && rep.equals("__init__")) { - foundInInit = true; - break; - } - } - } catch (Exception e) { - } - } - if (!foundInInit) { - checkMethodCreationAtClass(edit, pyRefactoring, callWithoutParens, callPs, ret, - lineContents, possibleMatch, f, nature, imageCache); - } - } + if (completionState == null) { + completionState = new CompletionState(); + } - } else if (pointers.length == 0) { - checkMethodCreationAtClass(edit, pyRefactoring, callWithoutParens, callPs, ret, lineContents, - possibleMatch, f, nature, imageCache); + if (definition.ast instanceof ClassDef) { + return definition; + } - } - } catch (Exception e) { - if (onGetTddPropsError != null) { - onGetTddPropsError.call(e); - } - Log.log(e); - } + if (definition instanceof AssignDefinition || definition.ast instanceof FunctionDef) { + //Avoid recursions. + completionState.checkDefinitionMemory(definition.module, definition); + if (definition instanceof AssignDefinition) { + definition = rebaseAssignDefinition((AssignDefinition) definition, nature, completionCache); + + } else { // definition.ast MUST BE FunctionDef + definition = rebaseFunctionDef(definition, nature, completionCache); } + + return rebaseToClassDefDefinition(nature, completionCache, definition, completionState); } - return ret; + return definition; } - public static ICallback onGetTddPropsError; + public static Definition rebaseFunctionDef(Definition definition, IPythonNature nature, + ICompletionCache completionCache) + throws Exception { + ITypeInfo type = NodeUtils.getReturnTypeFromFuncDefAST(definition.ast); + if (type != null) { + // ok, go to the definition of whatever is set + IDefinition[] definitions2 = definition.module.findDefinition( + CompletionStateFactory.getEmptyCompletionState(type.getActTok(), nature, completionCache), + definition.line, + definition.col, nature); + if (definitions2.length == 1) { + return (Definition) definitions2[0]; + } + } - private static boolean checkMethodCreationAtClass(IPyEdit edit, IPyRefactoring pyRefactoring, - String callWithoutParens, + List returns = ReturnVisitor.findReturns((FunctionDef) definition.ast); + for (Return returnFound : returns) { + String act = NodeUtils.getFullRepresentationString(returnFound.value); + if (act == null) { + continue; + } + //ok, go to the definition of whatever is set + IDefinition[] definitions2 = definition.module.findDefinition( + CompletionStateFactory.getEmptyCompletionState(act, nature, completionCache), definition.line, + definition.col, nature); + if (definitions2.length == 1) { + return (Definition) definitions2[0]; + } + } + return definition; + } + + public static Definition rebaseAssignDefinition(AssignDefinition assignDef, IPythonNature nature, + ICompletionCache completionCache) throws Exception { + IDefinition[] definitions2; + if ("None".equals(assignDef.type)) { + return assignDef; // keep the old one + } + if (assignDef.nodeType != null) { + definitions2 = assignDef.module.findDefinition( + CompletionStateFactory.getEmptyCompletionState(assignDef.type, nature, completionCache), + assignDef.line, assignDef.col, nature); + if (definitions2.length > 0) { + return (Definition) definitions2[0]; + } + } + if ("None".equals(assignDef.value)) { + return assignDef; // keep the old one + } + if (assignDef.nodeValue != null) { + //ok, go to the definition of whatever is set + definitions2 = assignDef.module.findDefinition( + CompletionStateFactory.getEmptyCompletionState(assignDef.value, nature, completionCache), + assignDef.line, assignDef.col, nature); + if (definitions2.length > 0) { + return (Definition) definitions2[0]; + } + } + + return assignDef; + } + + static boolean checkMethodCreationAtClass(IPyEdit edit, IPyRefactoring pyRefactoring, + String callWithoutParens, PySelection callPs, List ret, String lineContents, TddPossibleMatches possibleMatch, File f, IPythonNature nature, IImageCache imageCache) throws MisconfigurationException, Exception { @@ -244,14 +309,16 @@ private static boolean checkMethodCreationAtClass(IPyEdit edit, IPyRefactoring p for (Boolean isCall : new Boolean[] { true, false }) { PyCreateMethodOrField pyCreateMethod = new PyCreateMethodOrField(); List parametersAfterCall = null; - parametersAfterCall = configCreateAsAndReturnParametersAfterCall(callPs, isCall, - pyCreateMethod, parametersAfterCall, methodToCreate); + parametersAfterCall = TddCodeGenerationQuickFixWithoutMarkersParticipant + .configCreateAsAndReturnParametersAfterCall(callPs, isCall, + pyCreateMethod, parametersAfterCall, methodToCreate); String startingScopeLineContents = callPs.getLine(scopeStart.iLineStartingScope); classNameInLine = PySelection.getClassNameInLine(startingScopeLineContents); if (classNameInLine != null && classNameInLine.length() > 0) { pyCreateMethod.setCreateInClass(classNameInLine); - addCreateMethodOption(callPs, edit, ret, methodToCreate, parametersAfterCall, + TddCodeGenerationQuickFixWithoutMarkersParticipant.addCreateMethodOption(callPs, edit, ret, + methodToCreate, parametersAfterCall, pyCreateMethod, classNameInLine, imageCache); } } @@ -268,7 +335,8 @@ private static boolean checkMethodCreationAtClass(IPyEdit edit, IPyRefactoring p request.setAdditionalInfo(RefactoringRequest.FIND_DEFINITION_FOLLOW_PARAM_DECLARATION, true); pointers = pyRefactoring.findDefinition(request); if (pointers.length == 1) { - if (checkCreationBasedOnFoundPointers(edit, callPs, ret, possibleMatch, pointers, methodToCreate, + if (TddCodeGenerationQuickFixWithoutMarkersParticipant.checkCreationBasedOnFoundPointers(edit, callPs, + ret, possibleMatch, pointers, methodToCreate, newSelection, nature, imageCache)) { return true; } @@ -277,218 +345,151 @@ private static boolean checkMethodCreationAtClass(IPyEdit edit, IPyRefactoring p return false; } - public static Definition rebaseAssignDefinition(AssignDefinition assignDef, IPythonNature nature, - ICompletionCache completionCache) throws Exception { - IDefinition[] definitions2; - if ("None".equals(assignDef.type)) { - return assignDef; // keep the old one - } - if (assignDef.nodeType != null) { - definitions2 = assignDef.module.findDefinition( - CompletionStateFactory.getEmptyCompletionState(assignDef.type, nature, completionCache), - assignDef.line, assignDef.col, nature); - if (definitions2.length > 0) { - return (Definition) definitions2[0]; - } - } - if ("None".equals(assignDef.value)) { - return assignDef; // keep the old one - } - if (assignDef.nodeValue != null) { - //ok, go to the definition of whatever is set - definitions2 = assignDef.module.findDefinition( - CompletionStateFactory.getEmptyCompletionState(assignDef.value, nature, completionCache), - assignDef.line, assignDef.col, nature); - if (definitions2.length > 0) { - return (Definition) definitions2[0]; - } - } - - return assignDef; - } - - public static Definition rebaseFunctionDef(Definition definition, IPythonNature nature, - ICompletionCache completionCache) - throws Exception { - ITypeInfo type = NodeUtils.getReturnTypeFromFuncDefAST(definition.ast); - if (type != null) { - // ok, go to the definition of whatever is set - IDefinition[] definitions2 = definition.module.findDefinition( - CompletionStateFactory.getEmptyCompletionState(type.getActTok(), nature, completionCache), - definition.line, - definition.col, nature); - if (definitions2.length == 1) { - return (Definition) definitions2[0]; - } - } - - List returns = ReturnVisitor.findReturns((FunctionDef) definition.ast); - for (Return returnFound : returns) { - String act = NodeUtils.getFullRepresentationString(returnFound.value); - if (act == null) { - continue; - } - //ok, go to the definition of whatever is set - IDefinition[] definitions2 = definition.module.findDefinition( - CompletionStateFactory.getEmptyCompletionState(act, nature, completionCache), definition.line, - definition.col, nature); - if (definitions2.length == 1) { - return (Definition) definitions2[0]; - } - } - return definition; - } - - private static Definition rebaseToClassDefDefinition(IPythonNature nature, CompletionCache completionCache, - Definition definition, CompletionState completionState) throws CompletionRecursionException, Exception { - - if (completionState == null) { - completionState = new CompletionState(); + public static List getTddProps( + PySelection ps, + IImageCache imageCache, + File f, + IPythonNature nature, + IPyEdit edit, + int offset, + List ret) { + if (ret == null) { + ret = new ArrayList(); } - - if (definition.ast instanceof ClassDef) { - return definition; + if (imageCache == null) { + imageCache = new DummyImageCache(); } + //Additional option: Generate markers for 'self.' accesses + int lineOfOffset = ps.getLineOfOffset(offset); + String lineContents = ps.getLine(lineOfOffset); - if (definition instanceof AssignDefinition || definition.ast instanceof FunctionDef) { - //Avoid recursions. - completionState.checkDefinitionMemory(definition.module, definition); - if (definition instanceof AssignDefinition) { - definition = rebaseAssignDefinition((AssignDefinition) definition, nature, completionCache); - - } else { // definition.ast MUST BE FunctionDef - definition = rebaseFunctionDef(definition, nature, completionCache); + //Additional option: Generate methods for function calls + List callsAtLine = ps.getTddPossibleMatchesAtLine(); + if (callsAtLine.size() > 0) { + //Make sure we don't check the same thing twice. + Map callsToCheck = new HashMap(); + for (TddPossibleMatches call : callsAtLine) { + String callString = call.initialPart + call.secondPart; + callsToCheck.put(callString, call); } - return rebaseToClassDefDefinition(nature, completionCache, definition, completionState); - } - - return definition; - } + CONTINUE_FOR: for (Map.Entry entry : callsToCheck.entrySet()) { + //we have at least something as SomeClass(a=2,c=3) or self.bar or self.foo.bar() or just foo.bar, etc. + IPyRefactoring pyRefactoring = AbstractPyRefactoring.getPyRefactoring(); + try { + TddPossibleMatches possibleMatch = entry.getValue(); + String callWithoutParens = entry.getKey(); - public static boolean checkCreationBasedOnFoundPointers(IPyEdit edit, PySelection callPs, - List ret, - TddPossibleMatches possibleMatch, ItemPointer[] pointers, String methodToCreate, PySelection newSelection, - IPythonNature nature, IImageCache imageCache) throws MisconfigurationException, Exception { - CompletionCache completionCache = new CompletionCache(); - for (ItemPointer pointer : pointers) { - Definition definition = pointer.definition; + ItemPointer[] pointers = null; + PySelection callPs = null; + TddPossibleMatches lastPossibleMatchNotFound = possibleMatch; - try { - definition = rebaseToClassDefDefinition(nature, completionCache, definition, null); - } catch (CompletionRecursionException e) { - Log.log(e); //Just keep going. - } + for (int i = 0; i < 10; i++) { //more than 10 attribute accesses in a line? No way! - if (definition.ast instanceof ClassDef) { - ClassDef d = (ClassDef) definition.ast; - String fullName = NodeUtils.getRepresentationString(d) + "." + methodToCreate; - IToken repInModule = nature.getAstManager().getRepInModule(definition.module, fullName, nature); - if (repInModule != null) { - //System.out.println("Skipping creation of: " + fullName); //We found it, so, don't suggest it. - continue; - } + lastPossibleMatchNotFound = possibleMatch; + if (i > 0) { + //We have to take 1 level out of the match... i.e.: if it was self.foo.get(), search now for self.foo. + String line = FullRepIterable.getWithoutLastPart(possibleMatch.full); + List tddPossibleMatchesAtLine = ps.getTddPossibleMatchesAtLine(line); + if (tddPossibleMatchesAtLine.size() > 0) { + possibleMatch = tddPossibleMatchesAtLine.get(0); + callWithoutParens = possibleMatch.initialPart + possibleMatch.secondPart; + } else { + continue CONTINUE_FOR; + } + } + String full = possibleMatch.full; + int indexOf = lineContents.indexOf(full); + if (indexOf < 0) { + Log.log("Did not expect index < 0."); + continue CONTINUE_FOR; + } + callPs = new PySelection(ps.getDoc(), + ps.getLineOffset() + indexOf + callWithoutParens.length()); - for (Boolean isCall : new Boolean[] { true, false }) { - //Give the user a chance to create the method we didn't find. - PyCreateMethodOrField pyCreateMethod = new PyCreateMethodOrField(); - List parametersAfterCall = null; - parametersAfterCall = configCreateAsAndReturnParametersAfterCall(callPs, isCall, pyCreateMethod, - parametersAfterCall, methodToCreate); - String className = NodeUtils.getRepresentationString(d); - pyCreateMethod.setCreateInClass(className); + RefactoringRequest request = new RefactoringRequest(f, callPs, null, nature, edit); + //Don't look in additional info. + request.setAdditionalInfo( + RefactoringRequest.FIND_DEFINITION_IN_ADDITIONAL_INFO, false); + pointers = pyRefactoring.findDefinition(request); - String displayString = StringUtils.format( - "Create %s %s at %s (%s)", methodToCreate, - pyCreateMethod.getCreationStr(), className, definition.module.getName()); + if (((pointers != null && pointers.length > 0) + || StringUtils.count(possibleMatch.full, '.') <= 1)) { + break; + } + } - TddRefactorCompletionInModule completion = new TddRefactorCompletionInModule(methodToCreate, - imageCache.get(UIConstants.CREATE_METHOD_ICON), displayString, - null, displayString, IPyCompletionProposal.PRIORITY_CREATE, edit, - definition.module.getFile(), parametersAfterCall, pyCreateMethod, newSelection); - completion.locationStrategy = AbstractPyCreateAction.LOCATION_STRATEGY_END; - ret.add(completion); - } - return true; - } - } - return false; - } + if (pointers == null || callPs == null) { + continue CONTINUE_FOR; + } - private static List configCreateAsAndReturnParametersAfterCall(PySelection callPs, boolean isCall, - PyCreateMethodOrField pyCreateMethod, List parametersAfterCall, String methodToCreate) { - if (isCall) { - pyCreateMethod.setCreateAs(PyCreateMethodOrField.BOUND_METHOD); - parametersAfterCall = callPs.getParametersAfterCall(callPs.getAbsoluteCursorOffset()); - } else { - if (StringUtils.isAllUpper(methodToCreate)) { - pyCreateMethod.setCreateAs(PyCreateMethodOrField.CONSTANT); + if (lastPossibleMatchNotFound != null && lastPossibleMatchNotFound != possibleMatch + && pointers.length >= 1) { + //Ok, as we were analyzing a string as self.bar.foo, we didn't find something in a pass + //i.e.: self.bar.foo, but we found it in a second pass + //as self.bar, so, this means we have to open the chance to create the 'foo' in self.bar. + String methodToCreate = FullRepIterable.getLastPart(lastPossibleMatchNotFound.secondPart); + int absoluteCursorOffset = callPs.getAbsoluteCursorOffset(); + absoluteCursorOffset = absoluteCursorOffset - (1 + methodToCreate.length()); //+1 for the dot removed too. + PySelection newSelection = new PySelection(callPs.getDoc(), absoluteCursorOffset); - } else { - pyCreateMethod.setCreateAs(PyCreateMethodOrField.FIELD); - } - } - return parametersAfterCall; - } + TddCodeGenerationQuickFixWithoutMarkersParticipant.checkCreationBasedOnFoundPointers(edit, + callPs, + ret, possibleMatch, pointers, methodToCreate, + newSelection, nature, imageCache); + continue CONTINUE_FOR; + } - private static void addCreateMethodOption(PySelection ps, IPyEdit edit, List props, - String markerContents, List parametersAfterCall, PyCreateMethodOrField pyCreateMethod, - String classNameInLine, IImageCache imageCache) { - String displayString = StringUtils.format("Create %s %s at %s", - markerContents, - pyCreateMethod.getCreationStr(), classNameInLine); - TddRefactorCompletion tddRefactorCompletion = new TddRefactorCompletion(markerContents, - imageCache.get(UIConstants.CREATE_METHOD_ICON), displayString, null, null, - IPyCompletionProposal.PRIORITY_CREATE, - edit, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT, parametersAfterCall, pyCreateMethod, ps); - props.add(tddRefactorCompletion); - } + if (pointers.length >= 1) { - private static boolean checkInitCreation(IPyEdit edit, PySelection callPs, ItemPointer[] pointers, - List ret, IImageCache imageCache) { - for (ItemPointer pointer : pointers) { - Definition definition = pointer.definition; - if (definition != null && definition.ast instanceof ClassDef) { - ClassDef d = (ClassDef) definition.ast; - ASTEntry initEntry = findInitInClass(d); + //Ok, we found whatever was there, so, we don't need to create anything (except maybe do + //the __init__ or something at the class level). + if (!TddCodeGenerationQuickFixWithoutMarkersParticipant.checkInitCreation(edit, callPs, + pointers, + ret, imageCache)) { + //This was called only when isCall == false + //Ok, if it's not a call and we found a field, it's still possible that we may want to create + //a field if it wasn't found in the __init__ + boolean foundInInit = false; + for (ItemPointer p : pointers) { + Definition definition = p.definition; + try { + Object peek = definition.scope.getScopeStack().peek(); + if (peek instanceof FunctionDef) { + FunctionDef functionDef = (FunctionDef) peek; + String rep = NodeUtils.getRepresentationString(functionDef); + if (rep != null && rep.equals("__init__")) { + foundInInit = true; + break; + } + } + } catch (Exception e) { + } + } + if (!foundInInit) { + TddCodeGenerationQuickFixWithoutMarkersParticipant.checkMethodCreationAtClass(edit, + pyRefactoring, callWithoutParens, callPs, ret, + lineContents, possibleMatch, f, nature, imageCache); + } + } - if (initEntry == null) { - //Give the user a chance to create the __init__. - PyCreateMethodOrField pyCreateMethod = new PyCreateMethodOrField(); - pyCreateMethod.setCreateAs(PyCreateMethodOrField.BOUND_METHOD); - String className = NodeUtils.getRepresentationString(d); - pyCreateMethod.setCreateInClass(className); + } else if (pointers.length == 0) { + TddCodeGenerationQuickFixWithoutMarkersParticipant.checkMethodCreationAtClass(edit, + pyRefactoring, + callWithoutParens, callPs, ret, lineContents, + possibleMatch, f, nature, imageCache); - List parametersAfterCall = callPs.getParametersAfterCall(callPs.getAbsoluteCursorOffset()); - String displayString = StringUtils.format( - "Create %s __init__ (%s)", className, - definition.module.getName()); - TddRefactorCompletionInModule completion = new TddRefactorCompletionInModule("__init__", - imageCache.get(UIConstants.CREATE_METHOD_ICON), displayString, null, displayString, - IPyCompletionProposal.PRIORITY_CREATE, edit, definition.module.getFile(), - parametersAfterCall, pyCreateMethod, callPs); - completion.locationStrategy = AbstractPyCreateAction.LOCATION_STRATEGY_FIRST_METHOD; - ret.add(completion); - return true; + } + } catch (Exception e) { + if (TddCodeGenerationQuickFixWithoutMarkersParticipant.onGetTddPropsError != null) { + TddCodeGenerationQuickFixWithoutMarkersParticipant.onGetTddPropsError.call(e); + } + Log.log(e); } } } - return false; - } - public static ASTEntry findInitInClass(ClassDef d) { - EasyASTIteratorVisitor visitor = EasyASTIteratorVisitor.create(d); - - for (Iterator it = visitor.getMethodsIterator(); it.hasNext();) { - ASTEntry next = it.next(); - if (next.node != null) { - String rep = NodeUtils.getRepresentationString(next.node); - if ("__init__".equals(rep)) { - return next; - } - } - } - return null; + return ret; } } diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddQuickFixParticipant.java b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddQuickFixFromMarkersParticipant.java similarity index 95% rename from plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddQuickFixParticipant.java rename to plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddQuickFixFromMarkersParticipant.java index 6d19c1731c..873ea3cf98 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddQuickFixParticipant.java +++ b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddQuickFixFromMarkersParticipant.java @@ -11,12 +11,10 @@ import java.util.HashSet; import java.util.List; -import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.codecompletion.revisited.CompletionCache; import org.python.pydev.ast.codecompletion.revisited.CompletionState; import org.python.pydev.ast.codecompletion.revisited.CompletionStateFactory; @@ -25,9 +23,12 @@ import org.python.pydev.ast.codecompletion.revisited.visitors.Definition; import org.python.pydev.ast.refactoring.PyRefactoringFindDefinition; import org.python.pydev.ast.refactoring.RefactoringRequest; +import org.python.pydev.core.IAnalysisMarkersParticipant; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.ICodeCompletionASTManager; import org.python.pydev.core.ICompletionState; import org.python.pydev.core.IDefinition; +import org.python.pydev.core.IMarkerInfoForAnalysis; import org.python.pydev.core.IModule; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.IPythonNature; @@ -38,7 +39,6 @@ import org.python.pydev.core.log.Log; import org.python.pydev.core.preferences.FileTypesPreferences; import org.python.pydev.core.structure.CompletionRecursionException; -import org.python.pydev.editor.codefolding.MarkerAnnotationAndPosition; import org.python.pydev.parser.jython.SimpleNode; import org.python.pydev.parser.jython.ast.ClassDef; import org.python.pydev.parser.visitors.NodeUtils; @@ -54,19 +54,21 @@ import org.python.pydev.shared_core.structure.Tuple; import org.python.pydev.shared_ui.SharedUiPlugin; -import com.python.pydev.analysis.additionalinfo.builders.AnalysisRunner; -import com.python.pydev.analysis.ctrl_1.IAnalysisMarkersParticipant; +import com.python.pydev.analysis.refactoring.tdd.AbstractPyCreateAction; +import com.python.pydev.analysis.refactoring.tdd.NullPyCreateAction; +import com.python.pydev.analysis.refactoring.tdd.PyCreateClass; +import com.python.pydev.analysis.refactoring.tdd.PyCreateMethodOrField; /** * This participant will add a suggestion to create class/methods/attributes when an undefined variable error is found. */ -public class TddQuickFixParticipant implements IAnalysisMarkersParticipant { +public class TddQuickFixFromMarkersParticipant implements IAnalysisMarkersParticipant { /*default*/IImageHandle imageClass; /*default*/IImageHandle imageMethod; /*default*/IImageHandle imageModule; - public TddQuickFixParticipant() { + public TddQuickFixFromMarkersParticipant() { IImageCache imageCache = SharedUiPlugin.getImageCache(); if (imageCache != null) { //making tests imageClass = imageCache.get(UIConstants.CREATE_CLASS_ICON); @@ -76,7 +78,7 @@ public TddQuickFixParticipant() { } @Override - public void addProps(MarkerAnnotationAndPosition markerAnnotation, IAnalysisPreferences analysisPreferences, + public void addProps(IMarkerInfoForAnalysis markerInfo, IAnalysisPreferences analysisPreferences, String line, PySelection ps, int offset, IPythonNature nature, IPyEdit edit, List props) throws BadLocationException, CoreException { @@ -89,13 +91,13 @@ public void addProps(MarkerAnnotationAndPosition markerAnnotation, IAnalysisPref return; } - if (markerAnnotation.position == null) { + if (!markerInfo.hasPosition()) { return; } - IMarker marker = markerAnnotation.markerAnnotation.getMarker(); - Integer id = (Integer) marker.getAttribute(AnalysisRunner.PYDEV_ANALYSIS_TYPE); - int start = markerAnnotation.position.offset; - int end = start + markerAnnotation.position.length; + Integer id = markerInfo.getPyDevAnalisysType(); + int start = markerInfo.getOffset(); + int end = start + markerInfo.getLength(); + ps.setSelection(start, end); String markerContents; try { @@ -348,7 +350,7 @@ private void addCreateClassmethodOption(PySelection ps, IPyEdit edit, List props, @@ -358,7 +360,7 @@ private void addCreateMethodOption(PySelection ps, IPyEdit edit, List props, @@ -367,7 +369,8 @@ private void addCreateClassOption(PySelection ps, IPyEdit edit, List props, diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletion.java b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletion.java index 8adf0d2baa..a8f0607c3b 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletion.java +++ b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletion.java @@ -19,19 +19,25 @@ import org.python.pydev.core.MisconfigurationException; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.log.Log; +import org.python.pydev.core.proposals.CompletionProposalFactory; +import org.python.pydev.editor.codecompletion.PyTemplateProposal; import org.python.pydev.parser.PyParser; import org.python.pydev.shared_core.image.IImageHandle; +import com.python.pydev.analysis.refactoring.tdd.AbstractPyCreateAction; +import com.python.pydev.analysis.refactoring.tdd.TemplateInfo; + /** * This is the proposal that goes outside. It only creates the proposal that'll actually do something later, as * creating that proposal may be slower. */ public final class TddRefactorCompletion extends AbstractTddRefactorCompletion { - private TemplateProposal executed; + private PyTemplateProposal executed; private int locationStrategy; private List parametersAfterCall; private AbstractPyCreateAction pyCreateAction; private PySelection ps; + private TemplateInfo templateInfo; TddRefactorCompletion(String replacementString, IImageHandle image, String displayString, IContextInformation contextInformation, String additionalProposalInfo, int priority, IPyEdit edit, @@ -65,27 +71,33 @@ public Point getSelection(IDocument document) { return null; } + public PyTemplateProposal convertToTemplateProposal(TemplateInfo templateInfo) { + return (PyTemplateProposal) CompletionProposalFactory.get().createPyTemplateProposal(templateInfo.fTemplate, + templateInfo.fContext, + templateInfo.fRegion, null, 0); + } + @Override public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { if (edit != null) { //We have to reparse to make sure that we'll have an accurate AST. PyParser parser = (PyParser) edit.getParser(); - parser.reparseDocument(); + if (parser != null) { + parser.reparseDocument(); + } } - TemplateProposal executed2 = getAsTemplateProposal(); + PyTemplateProposal executed2 = getAsTemplateProposal(); if (executed2 != null) { executed2.apply(viewer, trigger, stateMask, 0); forceReparseInBaseEditorAnd(); } } - public TemplateProposal getAsTemplateProposal() { + public PyTemplateProposal getAsTemplateProposal() { if (executed == null) { - pyCreateAction.setActiveEditor(null, edit); try { - RefactoringInfo refactoringInfo = new RefactoringInfo(edit, ps.getTextSelection()); - executed = (TemplateProposal) pyCreateAction.createProposal(refactoringInfo, this.fReplacementString, - this.locationStrategy, parametersAfterCall); + TemplateInfo templateInfo = getAsTemplateInfo(); + executed = convertToTemplateProposal(templateInfo); } catch (MisconfigurationException e) { Log.log(e); } @@ -93,6 +105,16 @@ public TemplateProposal getAsTemplateProposal() { return executed; } + public TemplateInfo getAsTemplateInfo() throws MisconfigurationException { + if (templateInfo == null) { + pyCreateAction.setActiveEditor(edit); + RefactoringInfo refactoringInfo = new RefactoringInfo(edit, ps.getTextSelection()); + templateInfo = pyCreateAction.createProposal(refactoringInfo, this.fReplacementString, + this.locationStrategy, parametersAfterCall); + } + return templateInfo; + } + @Override public void selected(ITextViewer viewer, boolean smartToggle) { } diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletionInInexistentModule.java b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletionInInexistentModule.java index 8f2c50dfbd..067b49eaa3 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletionInInexistentModule.java +++ b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletionInInexistentModule.java @@ -33,6 +33,9 @@ import org.python.pydev.editor.actions.PyOpenAction; import org.python.pydev.shared_core.image.IImageHandle; +import com.python.pydev.analysis.refactoring.tdd.AbstractPyCreateAction; +import com.python.pydev.analysis.refactoring.tdd.PyCreateClass; + /** * This is the proposal that goes outside. It only creates the proposal that'll actually do something later, as * creating that proposal may be slower. diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletionInModule.java b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletionInModule.java index 31c7fbf183..734987c0d8 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletionInModule.java +++ b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/tdd/TddRefactorCompletionInModule.java @@ -22,6 +22,8 @@ import org.python.pydev.editor.actions.PyOpenAction; import org.python.pydev.shared_core.image.IImageHandle; +import com.python.pydev.analysis.refactoring.tdd.AbstractPyCreateAction; + /** * This is the proposal that goes outside. It only creates the proposal that'll actually do something later, as * creating that proposal may be slower. @@ -36,7 +38,8 @@ public final class TddRefactorCompletionInModule extends AbstractTddRefactorComp public TddRefactorCompletionInModule(String replacementString, IImageHandle image, String displayString, IContextInformation contextInformation, String additionalProposalInfo, int priority, IPyEdit edit, - File module, List parametersAfterCall, AbstractPyCreateAction pyCreateAction, PySelection ps) { + File module, List parametersAfterCall, AbstractPyCreateAction pyCreateAction, PySelection ps, + int locationStrategy) { super(edit, replacementString, 0, 0, 0, image, displayString, contextInformation, additionalProposalInfo, priority); @@ -44,6 +47,7 @@ public TddRefactorCompletionInModule(String replacementString, IImageHandle imag this.parametersAfterCall = parametersAfterCall; this.pyCreateAction = pyCreateAction; this.ps = ps; + this.locationStrategy = locationStrategy; } public List getParametersAfterCall() { diff --git a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/ExecutePyCreate.java b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/ExecutePyCreate.java index c5b15d12cf..149b614263 100644 --- a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/ExecutePyCreate.java +++ b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/ExecutePyCreate.java @@ -7,9 +7,14 @@ import org.python.pydev.ast.refactoring.RefactoringInfo; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.log.Log; +import org.python.pydev.core.proposals.CompletionProposalFactory; +import org.python.pydev.editor.codecompletion.PyTemplateProposal; import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; import org.python.pydev.shared_core.structure.Tuple; +import com.python.pydev.analysis.refactoring.tdd.AbstractPyCreateClassOrMethodOrField; +import com.python.pydev.analysis.refactoring.tdd.TemplateInfo; + public class ExecutePyCreate { public static void execute(AbstractPyCreateClassOrMethodOrField action, RefactoringInfo refactoringInfo, @@ -59,10 +64,15 @@ public static void execute(AbstractPyCreateClassOrMethodOrField action, Refactor String actTok, List parametersAfterCall, int locationStrategy) { try { - ICompletionProposalHandle proposal = action.createProposal(refactoringInfo, actTok, locationStrategy, + TemplateInfo templateInfo = action.createProposal(refactoringInfo, actTok, locationStrategy, parametersAfterCall); - if (proposal != null) { - if (proposal instanceof ICompletionProposalExtension2) { + if (templateInfo != null) { + ICompletionProposalHandle proposal = CompletionProposalFactory.get() + .createPyTemplateProposal(templateInfo.fTemplate, templateInfo.fContext, templateInfo.fRegion, + null, 0); + if (proposal instanceof PyTemplateProposal) { + ((PyTemplateProposal) proposal).getAsTemplateInfo().apply(refactoringInfo.getDocument()); + } else if (proposal instanceof ICompletionProposalExtension2) { ICompletionProposalExtension2 extension2 = (ICompletionProposalExtension2) proposal; extension2.apply(null, '\n', 0, 0); } else { diff --git a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/PyCreateClassTest.java b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/PyCreateClassTest.java index f4b20e79e6..6e5b6ca8df 100644 --- a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/PyCreateClassTest.java +++ b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/PyCreateClassTest.java @@ -19,6 +19,8 @@ import org.python.pydev.shared_core.string.CoreTextSelection; import org.python.pydev.shared_core.string.ICoreTextSelection; +import com.python.pydev.analysis.refactoring.tdd.PyCreateClass; + public class PyCreateClassTest extends TestCaseUtils { public static void main(String[] args) { @@ -70,8 +72,8 @@ public void testPyCreateClassInSameModule() throws Exception { ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT); assertContentsEqual("" + - "class MyClass(${object}):\n" + - " ${pass}${cursor}\n" + + "class MyClass(object):\n" + + " pass\n" + "\n" + "\n" + "MyClass()" @@ -106,8 +108,8 @@ public void testPyCreateClassInSameModule4() throws Exception { " pass\n" + "\n" + "\n" + - "class MyClass(${object}):\n" + - " ${pass}${cursor}\n" + + "class MyClass(object):\n" + + " pass\n" + "\n" + "\n" + @@ -144,9 +146,9 @@ public void testPyCreateClassInSameModule5() throws Exception { " pass\n" + "\n" + "\n" + - "class MyClass(${object}):\n" + "class MyClass(object):\n" + - " ${pass}${cursor}\n" + + " pass\n" + "\n" + "\n" + "MyClass()" + @@ -174,8 +176,8 @@ public void testPyCreateClassInSameModule6() throws Exception { "a = 10\n" + "\n" + "\n" + - "class MyClass(${object}):\n" + - " ${pass}${cursor}\n" + "class MyClass(object):\n" + + " pass\n" + "\n" + "\n" + @@ -199,11 +201,11 @@ public void testPyCreateClassWithParameters() throws Exception { ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT); assertContentsEqual("" + - "class MyClass(${object}):\n" + + "class MyClass(object):\n" + " \n" + - " def __init__(self, ${aa}, ${bb}, ${param2}):\n" + - " ${pass}${cursor}\n" + + " def __init__(self, aa, bb, param2):\n" + + " pass\n" + "\n" + "\n" + @@ -222,11 +224,11 @@ public void testPyCreateClassWithParameters2() throws Exception { ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT); assertContentsEqual("" + - "class MyClass(${object}):\n" + + "class MyClass(object):\n" + " \n" + - " def __init__(self, ${aa}, ${bb}, ${my_foo}):\n" + - " ${pass}${cursor}\n" + + " def __init__(self, aa, bb, my_foo):\n" + + " pass\n" + "\n" + "\n" + @@ -253,8 +255,8 @@ public void testPyCreateClassInSameModule2() throws Exception { assertContentsEqual("" + "import foo\n" + "\n" + - "class MyClass(${object}):\n" + - " ${pass}${cursor}\n" + "class MyClass(object):\n" + + " pass\n" + "\n" + "\n" + @@ -290,8 +292,8 @@ public void testPyCreateClassInSameModule3() throws Exception { "\n" + "\n" + - "class MyClass(${object}):\n" + - " ${pass}${cursor}\n" + + "class MyClass(object):\n" + + " pass\n" + "\n" + "\n" + "class Bar(object):\n" @@ -332,8 +334,8 @@ public void testPyCreateClassEndOfFile() throws Exception { "\n" + "\n" + - "class MyClass(${object}):\n" + - " ${pass}${cursor}\n" + + "class MyClass(object):\n" + + " pass\n" + "\n" + "\n", document.get()); } @@ -349,8 +351,8 @@ public void testPyCreateClassEndOfFile2() throws Exception { document); assertContentsEqual("" + - "class Foo(${object}):\n" + - " ${pass}${cursor}\n" + + "class Foo(object):\n" + + " pass\n" + "\n" + "\n", document.get()); } diff --git a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/PyCreateMethodTest.java b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/PyCreateMethodTest.java index c1ed56c2c5..c50a310f40 100644 --- a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/PyCreateMethodTest.java +++ b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/PyCreateMethodTest.java @@ -14,11 +14,16 @@ import org.python.pydev.core.IGrammarVersionProvider; import org.python.pydev.core.MisconfigurationException; import org.python.pydev.core.TestCaseUtils; +import org.python.pydev.core.autoedit.DefaultIndentPrefs; +import org.python.pydev.core.autoedit.TestIndentPrefs; import org.python.pydev.core.proposals.CompletionProposalFactory; import org.python.pydev.editor.codecompletion.proposals.DefaultCompletionProposalFactory; import org.python.pydev.shared_core.string.CoreTextSelection; import org.python.pydev.shared_core.string.ICoreTextSelection; +import com.python.pydev.analysis.refactoring.tdd.AbstractPyCreateAction; +import com.python.pydev.analysis.refactoring.tdd.PyCreateMethodOrField; + public class PyCreateMethodTest extends TestCaseUtils { public static void main(String[] args) { @@ -71,7 +76,7 @@ public void testPyCreateMethodGlobal() { assertContentsEqual("" + "def MyMethod():\n" + - " ${pass}${cursor}\n" + + " pass\n" + "\n" + "\n" + "MyMethod()" + @@ -90,8 +95,8 @@ public void testPyCreateMethodGlobalParams() { ExecutePyCreate.execute(pyCreateMethod, info, AbstractPyCreateAction.LOCATION_STRATEGY_BEFORE_CURRENT); assertContentsEqual("" + - "def MyMethod(${a}, ${b}):\n" + - " ${pass}${cursor}\n" + + "def MyMethod(a, b):\n" + + " pass\n" + "\n" + "\n" + @@ -113,7 +118,7 @@ public void testPyCreateMethodGlobal1() { "a = MyMethod()\n" + "\n" + "def MyMethod():\n" + - " ${pass}${cursor}\n" + + " pass\n" + "\n" + "\n" + @@ -133,7 +138,7 @@ public void testPyCreateMethodInEmptyDoc() { assertContentsEqual("" + "def MyMethod():\n" + - " ${pass}${cursor}\n" + + " pass\n" + "\n" + "\n" + "", document.get()); @@ -144,7 +149,7 @@ public void testPyCreateMethodInEmptyDoc() { assertContentsEqual("" + "def MyMethod2():\n" + - " ${pass}${cursor}\n" + + " pass\n" + "\n" + "\n" + "", document.get()); @@ -175,8 +180,8 @@ public void testPyCreateMethodInClass() { " \n" + " @classmethod\n" + - " def MyMethod(cls, ${a}, ${b}):\n" + - " ${pass}${cursor}\n" + " def MyMethod(cls, a, b):\n" + + " pass\n" + " \n" + " \n" + @@ -207,7 +212,7 @@ public void testPyCreateMethodInSelfWithDecorator() { " \n" + " def m2(self):\n" + - " ${pass}${cursor}\n" + + " pass\n" + " \n" + " \n" + " @decorator\n" + @@ -243,7 +248,7 @@ public void testPyCreateMethod() { "\n" + " def m2(self):\n" + - " ${pass}${cursor}\n" + + " pass\n" + " \n" + " \n" + " def m1(self):\n" + @@ -253,35 +258,42 @@ public void testPyCreateMethod() { } public void testPyCreateMethodWithTabs() { - PyCreateMethodOrField pyCreateMethod = new PyCreateMethodOrField(); - - String source = "" + - "class A(object):\n" + - "\n" + - "\n" + - "\n" + - "\tdef m1(self):\n" + - "\t\tself.m2()"; - IDocument document = new Document(source); - ICoreTextSelection selection = new CoreTextSelection(document, document.getLength() - "2()".length(), 0); - RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER); - - pyCreateMethod.setCreateInClass("A"); - pyCreateMethod.setCreateAs(PyCreateMethodOrField.BOUND_METHOD); - ExecutePyCreate.execute(pyCreateMethod, info, AbstractPyCreateAction.LOCATION_STRATEGY_BEFORE_CURRENT); - - String expected = "" + - "class A(object):\n" + - "\n" + - "\n" + - "\n" + - "\tdef m2(self):\n" - + - "\t\t${pass}${cursor}\n" + - "\t\n" + - "\t\n" + - "\tdef m1(self):\n" + - "\t\tself.m2()"; + DefaultIndentPrefs.set(new TestIndentPrefs(false, 4)); + IDocument document; + String expected; + try { + PyCreateMethodOrField pyCreateMethod = new PyCreateMethodOrField(); + + String source = "" + + "class A(object):\n" + + "\n" + + "\n" + + "\n" + + "\tdef m1(self):\n" + + "\t\tself.m2()"; + document = new Document(source); + ICoreTextSelection selection = new CoreTextSelection(document, document.getLength() - "2()".length(), 0); + RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER); + + pyCreateMethod.setCreateInClass("A"); + pyCreateMethod.setCreateAs(PyCreateMethodOrField.BOUND_METHOD); + ExecutePyCreate.execute(pyCreateMethod, info, AbstractPyCreateAction.LOCATION_STRATEGY_BEFORE_CURRENT); + + expected = "" + + "class A(object):\n" + + "\n" + + "\n" + + "\n" + + "\tdef m2(self):\n" + + + "\t\tpass\n" + + "\t\n" + + "\t\n" + + "\tdef m1(self):\n" + + "\t\tself.m2()"; + } finally { + DefaultIndentPrefs.set(null); + } assertContentsEqual(expected, document.get()); } diff --git a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipantTest.java b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipantTest.java index 434e3c06e7..d35120dc4e 100644 --- a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipantTest.java +++ b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipantTest.java @@ -6,13 +6,17 @@ */ package com.python.pydev.refactoring.tdd; +import java.io.File; import java.util.List; import org.eclipse.jface.text.Document; import org.python.pydev.ast.codecompletion.PyCodeCompletion; import org.python.pydev.ast.codecompletion.revisited.CodeCompletionTestsBase; +import org.python.pydev.ast.codecompletion.revisited.PyEditStub; import org.python.pydev.ast.codecompletion.revisited.modules.CompiledModule; import org.python.pydev.ast.refactoring.AbstractPyRefactoring; +import org.python.pydev.core.IPyEdit; +import org.python.pydev.core.MisconfigurationException; import org.python.pydev.core.TestDependent; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.structure.CompletionRecursionException; @@ -20,8 +24,11 @@ import org.python.pydev.shared_core.callbacks.ICallback; import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; import org.python.pydev.shared_core.string.FastStringBuffer; +import org.python.pydev.shared_ui.editor_input.PydevFileEditorInput; import com.python.pydev.analysis.refactoring.refactorer.Refactorer; +import com.python.pydev.analysis.refactoring.tdd.AbstractPyCreateClassOrMethodOrField; +import com.python.pydev.analysis.refactoring.tdd.TemplateInfo; /** * @author Fabio @@ -61,7 +68,7 @@ public void setUp() throws Exception { this.restorePythonPath(false); codeCompletion = new PyCodeCompletion(); - TddCodeGenerationQuickFixParticipant.onGetTddPropsError = new ICallback() { + TddCodeGenerationQuickFixWithoutMarkersParticipant.onGetTddPropsError = new ICallback() { @Override public Boolean call(Exception e) { @@ -90,26 +97,100 @@ public void tearDown() throws Exception { PyCodeCompletion.onCompletionRecursionException = null; } + public void testCreateInSelf1() throws Exception { + String s = """ + print i + class Foo(object): + + #comment + + def m1(self): + self.m2 + """; + String expected = """ + print i + class Foo(object): + + #comment + + + def m2(self): + pass + ---- + ---- + def m1(self): + self.m2 + """.replace('-', ' '); // Hack to keep whitespaces there + String label = "Create m2 method at Foo"; + + check(s, expected, label); + + } + + public void testCreateInSelf2() throws Exception { + String s = """ + print i + class Foo(object): + + #comment + + def m1(self): + self.m2() + """; + String expected = """ + print i + class Foo(object): + + #comment + + + def m2(self): + pass + ---- + ---- + def m1(self): + self.m2() + """.replace('-', ' '); // Hack to keep whitespaces there + String label = "Create m2 method at Foo"; + + check(s, expected, label); + } + + private void check(String s, String expected, String label) throws MisconfigurationException { + Document doc = new Document(s); + + File file = new File(TestDependent.TEST_PYSRC_TESTING_LOC + "extendable/check_analysis_and_tdd.py"); + PydevFileEditorInput editorInputStub = new PydevFileEditorInput(file); + IPyEdit edit = new PyEditStub(doc, editorInputStub, nature, file); + + List props = TddCodeGenerationQuickFixWithoutMarkersParticipant.getTddProps( + new PySelection(doc, s.length() - 1), null, null, nature, edit, s.length() - 1, null); + ICompletionProposalHandle handle = assertContains(label, props.toArray(new ICompletionProposalHandle[0])); + TddRefactorCompletion completion = (TddRefactorCompletion) handle; + TemplateInfo templateInfo = completion.getAsTemplateInfo(); + templateInfo.apply(doc); + assertEquals(expected, doc.get()); + } + public void testCreate() throws Exception { String s = "" + "class MyClass(object):\n" + " pass\n" + "\n" + - "def makeTestObj():\n" - + + "def makeTestObj():\n" + " return MyClass()\n" + "\n" + "def makeTestObj2():\n" + " return makeTestObj()\n" + - "\n" - + + "\n" + "def testName():\n" + " obj = makeTestObj2()\n" + " obj.unimplementedFunction()\n" + ""; - TddCodeGenerationQuickFixParticipant participant = new TddCodeGenerationQuickFixParticipant(); + Document doc = new Document(s); - List props = participant.getTddProps(new PySelection(doc, s.length() - 1), null, + List props = TddCodeGenerationQuickFixWithoutMarkersParticipant.getTddProps( + new PySelection(doc, s.length() - 1), null, null, nature, null, s.length() - 1, null); assertContains("Create unimplementedFunction method at MyClass (__module_not_in_the_pythonpath__)", @@ -124,9 +205,10 @@ public void testCreate2() throws Exception { " obj = MyClass()\n" + " obj.unimplementedFunction(a.x, 'Some comment in ticket.')\n" + ""; - TddCodeGenerationQuickFixParticipant participant = new TddCodeGenerationQuickFixParticipant(); + Document doc = new Document(s); - List props = participant.getTddProps(new PySelection(doc, s.length() - 1), null, + List props = TddCodeGenerationQuickFixWithoutMarkersParticipant.getTddProps( + new PySelection(doc, s.length() - 1), null, null, nature, null, s.length() - 1, null); TddRefactorCompletionInModule proposal = (TddRefactorCompletionInModule) assertContains( @@ -159,9 +241,10 @@ public void testDontCreate() throws Exception { + " obj.unimplementedFunction()\n" + ""; - TddCodeGenerationQuickFixParticipant participant = new TddCodeGenerationQuickFixParticipant(); + Document doc = new Document(s); - List props = participant.getTddProps(new PySelection(doc, s.length() - 1), null, + List props = TddCodeGenerationQuickFixWithoutMarkersParticipant.getTddProps( + new PySelection(doc, s.length() - 1), null, null, nature, null, s.length() - 1, null); assertNotContains("Create unimplementedFunction method at MyClass (__module_not_in_the_pythonpath__)", @@ -178,9 +261,10 @@ public void testCreateWithTypeAsParam() throws Exception { "\n" + "def method(foo: Foo = 'A'):\n" + " foo.bar()"; - TddCodeGenerationQuickFixParticipant participant = new TddCodeGenerationQuickFixParticipant(); + Document doc = new Document(s); - List props = participant.getTddProps(new PySelection(doc, s.length() - 1), null, + List props = TddCodeGenerationQuickFixWithoutMarkersParticipant.getTddProps( + new PySelection(doc, s.length() - 1), null, null, nature, null, s.length() - 1, null); assertContains("Create bar method at Foo (__module_not_in_the_pythonpath__)", @@ -200,9 +284,10 @@ public void testCreateWithTypeAsParam2() throws Exception { "\n" + "def method(foo = Foo()):\n" + " foo.bar()"; - TddCodeGenerationQuickFixParticipant participant = new TddCodeGenerationQuickFixParticipant(); + Document doc = new Document(s); - List props = participant.getTddProps(new PySelection(doc, s.length() - 1), null, + List props = TddCodeGenerationQuickFixWithoutMarkersParticipant.getTddProps( + new PySelection(doc, s.length() - 1), null, null, nature, null, s.length() - 1, null); assertContains("Create bar method at Foo (__module_not_in_the_pythonpath__)", @@ -226,9 +311,10 @@ public void testCreateWithTypeAsAnnotation() throws Exception { "def method():\n" + " foo = method2()\n" + " foo.bar()"; - TddCodeGenerationQuickFixParticipant participant = new TddCodeGenerationQuickFixParticipant(); + Document doc = new Document(s); - List props = participant.getTddProps(new PySelection(doc, s.length() - 1), null, + List props = TddCodeGenerationQuickFixWithoutMarkersParticipant.getTddProps( + new PySelection(doc, s.length() - 1), null, null, nature, null, s.length() - 1, null); assertContains("Create bar method at Foo (__module_not_in_the_pythonpath__)", diff --git a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipantWithMarkersTest.java b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipantWithMarkersTest.java new file mode 100644 index 0000000000..a1816a8acc --- /dev/null +++ b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddCodeGenerationQuickFixParticipantWithMarkersTest.java @@ -0,0 +1,309 @@ +/** + * Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved. + * Licensed under the terms of the Eclipse Public License (EPL). + * Please see the license.txt included with this distribution for details. + * Any modifications to this file must keep this entire header intact. + */ +package com.python.pydev.refactoring.tdd; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2; +import org.python.pydev.ast.analysis.messages.IMessage; +import org.python.pydev.ast.codecompletion.PyCodeCompletion; +import org.python.pydev.ast.codecompletion.revisited.PyEditStub; +import org.python.pydev.ast.codecompletion.revisited.modules.CompiledModule; +import org.python.pydev.ast.refactoring.AbstractPyRefactoring; +import org.python.pydev.core.IAnalysisPreferences; +import org.python.pydev.core.IMarkerInfoForAnalysis; +import org.python.pydev.core.IPyEdit; +import org.python.pydev.core.MisconfigurationException; +import org.python.pydev.core.TestDependent; +import org.python.pydev.core.docutils.PySelection; +import org.python.pydev.core.structure.CompletionRecursionException; +import org.python.pydev.plugin.nature.PythonNature; +import org.python.pydev.shared_core.IMiscConstants; +import org.python.pydev.shared_core.callbacks.ICallback; +import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; +import org.python.pydev.shared_core.markers.PyMarkerUtils.MarkerInfo; +import org.python.pydev.shared_core.string.StringUtils; +import org.python.pydev.shared_ui.editor_input.PydevFileEditorInput; + +import com.python.pydev.analysis.AnalysisPreferences; +import com.python.pydev.analysis.AnalysisTestsBase; +import com.python.pydev.analysis.additionalinfo.builders.AnalysisRunner; +import com.python.pydev.analysis.refactoring.quick_fixes.DummyMarkerInfoForAnalysis; +import com.python.pydev.analysis.refactoring.refactorer.Refactorer; +import com.python.pydev.analysis.refactoring.tdd.TemplateInfo; + +/** + * @author Fabio + * + */ +public class TddCodeGenerationQuickFixParticipantWithMarkersTest extends AnalysisTestsBase { + + public static void main(String[] args) { + + try { + //DEBUG_TESTS_BASE = true; + TddCodeGenerationQuickFixParticipantWithMarkersTest test = new TddCodeGenerationQuickFixParticipantWithMarkersTest(); + test.setUp(); + test.testCreateClass(); + test.tearDown(); + System.out.println("Finished"); + + junit.textui.TestRunner.run(TddCodeGenerationQuickFixParticipantWithMarkersTest.class); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + /* + * @see TestCase#setUp() + */ + @Override + public void setUp() throws Exception { + super.setUp(); + AbstractPyRefactoring.setPyRefactoring(new Refactorer()); + CompiledModule.COMPILED_MODULES_ENABLED = false; + this.restorePythonPath(TestDependent.getCompletePythonLib(true, isPython3Test()) + + "|" + TestDependent.PYTHON2_PIL_PACKAGES + + "|" + + TestDependent.TEST_PYSRC_TESTING_LOC + + "configobj-4.6.0-py2.6.egg", false); + + this.restorePythonPath(false); + codeCompletion = new PyCodeCompletion(); + TddCodeGenerationQuickFixWithoutMarkersParticipant.onGetTddPropsError = new ICallback() { + + @Override + public Boolean call(Exception e) { + throw new RuntimeException("Error:" + org.python.pydev.shared_core.log.Log.getExceptionStr(e)); + } + }; + PyCodeCompletion.onCompletionRecursionException = new ICallback() { + + @Override + public Object call(CompletionRecursionException e) { + throw new RuntimeException( + "Recursion error:" + org.python.pydev.shared_core.log.Log.getExceptionStr(e)); + } + + }; + } + + /* + * @see TestCase#tearDown() + */ + @Override + public void tearDown() throws Exception { + CompiledModule.COMPILED_MODULES_ENABLED = true; + super.tearDown(); + AbstractPyRefactoring.setPyRefactoring(null); + PyCodeCompletion.onCompletionRecursionException = null; + } + + public void testCreateClass() throws Exception { + String initial = """ + class Foo(object): + def m1(self): + NewClass + """; + String expected = """ + class NewClass(object): + pass + + + class Foo(object): + def m1(self): + NewClass + """; + String stringForRegion = "NewClass"; + String expectedLabel = "Create NewClass class"; + int markerType = IAnalysisPreferences.TYPE_UNDEFINED_VARIABLE; + + check(initial, expected, stringForRegion, expectedLabel, markerType); + } + + public void testFromActualError() throws Exception { + String initial = """ + class Foo(object): + def m1(self): + NewClass + """; + String expected = """ + class NewClass(object): + pass + + + class Foo(object): + def m1(self): + NewClass + """; + String expectedLabel = "Create NewClass class"; + + checkFromAnalysis(initial, expected, expectedLabel); + } + + public void testCreateModule() throws Exception { + String initial = """ + import some_module + """; + // i.e.: New empty module + String expected = """ + """; + String stringForRegion = "some_module"; + String expectedLabel = "Create some_module module"; + int markerType = IAnalysisPreferences.TYPE_UNRESOLVED_IMPORT; + + check(initial, expected, stringForRegion, expectedLabel, markerType); + } + + public void testCreateMethod() throws Exception { + String initial = """ + print i + class Foo(object): + + #comment + + def m1(self): + self.m2 + """; + String expected = """ + print i + class Foo(object): + + #comment + + + def m2(self): + pass + ---- + ---- + def m1(self): + self.m2 + """.replace('-', ' '); + String stringForRegion = "m2"; + String expectedLabel = "Create m2 method at Foo"; + + int markerType = -1; // No marker + check(initial, expected, stringForRegion, expectedLabel, markerType); + } + + private void check(String initial, String expected, String stringForRegion, String expectedLabel, int markerType) + throws BadLocationException, CoreException, MisconfigurationException { + int usedGrammar = GRAMMAR_TO_USE_FOR_PARSING; + GRAMMAR_TO_USE_FOR_PARSING = PythonNature.LATEST_GRAMMAR_PY3_VERSION; + try { + + Document doc = new Document(initial); + + int markerStart = initial.indexOf(stringForRegion); + int markerLen = stringForRegion.length(); + + IMarkerInfoForAnalysis markerInfo = new DummyMarkerInfoForAnalysis( + markerType, markerStart, markerLen); + IAnalysisPreferences analysisPreferences = new AnalysisPreferences(null); + int offset = markerStart; + PySelection ps = new PySelection(doc, offset); + String line = ps.getLine(); + File file = new File(TestDependent.TEST_PYSRC_TESTING_LOC + "extendable/check_analysis_and_tdd.py"); + PydevFileEditorInput editorInputStub = new PydevFileEditorInput(file); + IPyEdit edit = new PyEditStub(doc, editorInputStub, nature, file); + + TddCodeGenerationQuickFixWithoutMarkersParticipant participant2 = new TddCodeGenerationQuickFixWithoutMarkersParticipant(); + List props = participant2.getProps(ps, null, file, nature, edit, offset); + if (markerType != -1) { + TddQuickFixFromMarkersParticipant participant = new TddQuickFixFromMarkersParticipant(); + participant.addProps(markerInfo, analysisPreferences, line, ps, offset, nature, edit, props); + } + + ICompletionProposalExtension2 found = findCompletion(props, expectedLabel, true); + if (found instanceof TddRefactorCompletion) { + TddRefactorCompletion completion = (TddRefactorCompletion) found; + TemplateInfo templateInfo = completion.getAsTemplateInfo(); + templateInfo.apply(doc); + assertEquals(expected, doc.get()); + } else if (found instanceof TddRefactorCompletionInModule) { + TddRefactorCompletion completion = (TddRefactorCompletion) found; + TemplateInfo templateInfo = completion.getAsTemplateInfo(); + Document d = new Document(); + templateInfo.apply(d); + assertEquals(expected, d.get()); + } + + } finally { + GRAMMAR_TO_USE_FOR_PARSING = usedGrammar; + } + } + + private void checkFromAnalysis(String initial, String expected, String expectedLabel) + throws BadLocationException, CoreException, MisconfigurationException { + int usedGrammar = GRAMMAR_TO_USE_FOR_PARSING; + GRAMMAR_TO_USE_FOR_PARSING = PythonNature.LATEST_GRAMMAR_PY3_VERSION; + try { + + doc = new Document(initial); + IMessage[] messages = checkError(1); + ArrayList markers = AnalysisRunner.generateMarkers(doc, messages, new NullProgressMonitor()); + assertEquals(1, markers.size()); + MarkerInfo marker = markers.get(0); + marker.getAsMap(); // Updates absoluteStart/absoluteEnd + int markerStart = marker.absoluteStart; + int markerLen = marker.absoluteEnd - marker.absoluteStart; + + int offset = markerStart; + PySelection ps = new PySelection(doc, offset); + + int id = (int) marker.additionalInfo.get(IMiscConstants.PYDEV_ANALYSIS_TYPE); + IMarkerInfoForAnalysis markerInfo = new DummyMarkerInfoForAnalysis( + id, markerStart, markerLen); + IAnalysisPreferences analysisPreferences = new AnalysisPreferences(null); + String line = ps.getLine(); + File file = new File(TestDependent.TEST_PYSRC_TESTING_LOC + "extendable/check_analysis_and_tdd.py"); + PydevFileEditorInput editorInputStub = new PydevFileEditorInput(file); + IPyEdit edit = new PyEditStub(doc, editorInputStub, nature, file); + + TddCodeGenerationQuickFixWithoutMarkersParticipant participant2 = new TddCodeGenerationQuickFixWithoutMarkersParticipant(); + List props = participant2.getProps(ps, null, file, nature, edit, offset); + + TddQuickFixFromMarkersParticipant participant = new TddQuickFixFromMarkersParticipant(); + participant.addProps(markerInfo, analysisPreferences, line, ps, offset, nature, edit, props); + + TddRefactorCompletion completion = (TddRefactorCompletion) findCompletion(props, expectedLabel, + true); + TemplateInfo templateInfo = completion.getAsTemplateInfo(); + templateInfo.apply(doc); + assertEquals(expected, doc.get()); + + } finally { + GRAMMAR_TO_USE_FOR_PARSING = usedGrammar; + } + } + + private ICompletionProposalExtension2 findCompletion(List props, + String expectedCompletion, boolean throwException) { + List buf = new ArrayList(1 + (2 * props.size())); + buf.add("Available:"); + for (ICompletionProposalHandle iCompletionProposal : props) { + if (iCompletionProposal.getDisplayString().equals(expectedCompletion)) { + ICompletionProposalExtension2 p = (ICompletionProposalExtension2) iCompletionProposal; + return p; + } + buf.add("\n"); + buf.add(iCompletionProposal.getDisplayString()); + } + if (throwException) { + throw new AssertionError("Could not find completion: " + expectedCompletion + + "\n" + + StringUtils.join("\n", buf)); + } + return null; + } +} diff --git a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddTestWorkbench.java b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddTestWorkbench.java index db08bcc273..fc58ec572a 100644 --- a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddTestWorkbench.java +++ b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/tdd/TddTestWorkbench.java @@ -62,8 +62,6 @@ public void testCheckTddQuickFixes() throws Exception { //We have to wait a bit until the info is setup for the tests to work... waitForModulesManagerSetup(); - checkCreateMethod4(); - checkCreateMethod3(); checkCreateMethodAtField0(); @@ -82,8 +80,6 @@ public void testCheckTddQuickFixes() throws Exception { checkCreateFieldAtClass4(); - checkCreateMethod2(); - checkCreateFieldAtClass3(); checkCreateFieldAtClass2(); @@ -143,7 +139,7 @@ private void checkCreateField() throws CoreException, BadLocationException, Misc ""; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength(); PySelection ps = new PySelection(doc, offset); @@ -184,7 +180,7 @@ private void checkCreateMethodAtField0() throws CoreException, BadLocationExcept ""; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength(); PySelection ps = new PySelection(doc, offset); @@ -232,7 +228,7 @@ private void checkCreateMethodAtField() throws CoreException, BadLocationExcepti ""; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength(); PySelection ps = new PySelection(doc, offset); @@ -283,7 +279,7 @@ private void checkCreateFieldAtField() throws CoreException, BadLocationExceptio ""; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength(); PySelection ps = new PySelection(doc, offset); @@ -325,7 +321,7 @@ private void checkCreateBoundMethod() throws CoreException, BadLocationException " self.bar()"; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength() - "r()".length(); PySelection ps = new PySelection(doc, offset); @@ -369,7 +365,7 @@ private void checkCreateNewMethodInClass() throws CoreException, BadLocationExce " obj.unimplementedFunction()"; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength() - "()".length(); PySelection ps = new PySelection(doc, offset); @@ -419,7 +415,7 @@ private void checkCreateMethod3() throws CoreException, BadLocationException, Mi ""; setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -446,95 +442,11 @@ private void checkCreateMethod3() throws CoreException, BadLocationException, Mi } } - private void checkCreateMethod4() throws CoreException, BadLocationException, MisconfigurationException { - String mod1Contents = "" + - "print i\n" - + //just to have an error - "class Foo(object):\n" + - "\n" + - "#comment\n" + - "\n" + - " def m1(self):\n" + - " self.m2" + - "" - + - ""; - setContentsAndWaitReparseAndError(mod1Contents); - - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); - int offset = mod1Contents.length(); - PySelection ps = new PySelection(editor.getDocument(), offset); - assertTrue(quickFix.isValid(ps, "", editor, offset)); - try { - waitForQuickFixProps(quickFix, ps, offset, "Create m2 method at Foo").apply(editor.getISourceViewer(), - '\n', 0, offset); - assertContentsEqual("" + - "print i\n" - + //just to have an error - "class Foo(object):\n" + - "\n" + - "#comment\n" + - "\n" + - "\n" + - " def m2(self):\n" - + - " pass\n" + - " \n" + - " \n" + - " def m1(self):\n" + - " self.m2" + - "" + - "", - editor.getDocument().get()); - } finally { - editor.doRevertToSaved(); - } - } - - private void checkCreateMethod2() throws CoreException, BadLocationException, MisconfigurationException { - String mod1Contents = "" + - "print i\n" + //just to have an error - "class Foo(object):\n" + - "\n" + - "\n" + - " def m1(self):\n" + - " self.m2()" + - "" + - ""; - setContentsAndWaitReparseAndError(mod1Contents); - - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); - int offset = mod1Contents.length(); - PySelection ps = new PySelection(editor.getDocument(), offset); - assertTrue(quickFix.isValid(ps, "", editor, offset)); - try { - waitForQuickFixProps(quickFix, ps, offset, "Create m2 method at Foo").apply(editor.getISourceViewer(), - '\n', 0, offset); - assertContentsEqual("" + - "print i\n" - + //just to have an error - "class Foo(object):\n" + - "\n" + - "\n" + - " def m2(self):\n" + - " pass\n" + - " \n" - + - " \n" + - " def m1(self):\n" + - " self.m2()" + - "" + - "", editor.getDocument().get()); - } finally { - editor.doRevertToSaved(); - } - } - private void checkCreateMethod() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "Foo"; setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); PySelection ps = new PySelection(editor.getDocument(), 0); assertTrue(quickFix.isValid(ps, "", editor, 0)); List props = quickFix.getProps(ps, SharedUiPlugin.getImageCache(), @@ -559,7 +471,7 @@ private void checkCreateMethod() throws CoreException, BadLocationException, Mis private void checkCreateMethodAtOtherModule() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; IFile mod2 = initFile.getParent().getFile(new Path("other_module2.py")); mod2.create(new ByteArrayInputStream("".getBytes()), true, null); @@ -571,7 +483,7 @@ private void checkCreateMethodAtOtherModule() "other_module2.Foo(a, b)"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - "o(a, b)".length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -593,7 +505,7 @@ private void checkCreateMethodAtOtherModule() private void checkCreateMethodAtOtherModule2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; IFile mod2 = initFile.getParent().getFile(new Path("other_module3.py")); String str = "" + @@ -609,7 +521,7 @@ private void checkCreateMethodAtOtherModule2() throws CoreException, BadLocation "other_module3.Bar.Foo(10, 20)"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - "o(a, b)".length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -638,7 +550,7 @@ private void checkCreateMethodAtOtherModule2() throws CoreException, BadLocation private void checkCreateMethodAtOtherModule4() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; IFile mod2 = initFile.getParent().getFile(new Path("other_module4.py")); String str = ""; @@ -650,7 +562,7 @@ private void checkCreateMethodAtOtherModule4() throws CoreException, BadLocation "from pack1.pack2.other_module4 import Foo"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -673,7 +585,7 @@ private void checkCreateMethodAtOtherModule4() throws CoreException, BadLocation private void checkCreateNewModule() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; IFile mod2 = initFile.getParent().getFile(new Path("module_new.py")); final List pyEditCreated = new ArrayList(); @@ -693,7 +605,7 @@ public Object call(PyEdit obj) { "import pack1.pack2.module_new"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -715,7 +627,7 @@ public Object call(PyEdit obj) { private void checkCreateNewModule4() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; IFile mod3 = initFile.getParent().getFile(new Path("module_new3.py")); final List pyEditCreated = new ArrayList(); @@ -735,7 +647,7 @@ public Object call(PyEdit obj) { "from pack1.pack2 import module_new3"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -757,7 +669,7 @@ public Object call(PyEdit obj) { private void checkCreateNewModule2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; List props; IFile mod2 = initFile.getParent().getFile(new Path("pack2a/module_new.py")); @@ -778,7 +690,7 @@ public Object call(PyEdit obj) { "import pack1.pack2.pack2a.module_new"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -802,7 +714,7 @@ public Object call(PyEdit obj) { private void checkCreateNewModule3() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; List props; IFile mod2 = initFile.getParent().getParent().getParent().getFile(new Path("newpack/module_new.py")); @@ -824,7 +736,7 @@ public Object call(PyEdit obj) { "import newpack.module_new"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -844,7 +756,7 @@ public Object call(PyEdit obj) { "module_new.NewClass"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -872,7 +784,7 @@ public Object call(PyEdit obj) { " module_new.NewClass(param)"; //the 'undefined param' will be the error setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -905,7 +817,7 @@ public Object call(PyEdit obj) { } } - private ICompletionProposalExtension2 waitForQuickFixProps(TddCodeGenerationQuickFixParticipant quickFix, + private ICompletionProposalExtension2 waitForQuickFixProps(TddCodeGenerationQuickFixFromMarkersParticipant quickFix, PySelection ps, int offset, String expectedCompletion) throws MisconfigurationException, BadLocationException { @@ -927,7 +839,8 @@ private ICompletionProposalExtension2 waitForQuickFixProps(TddCodeGenerationQuic } - private List waitForQuickFixProps(TddCodeGenerationQuickFixParticipant quickFix, + private List waitForQuickFixProps( + TddCodeGenerationQuickFixFromMarkersParticipant quickFix, PySelection ps, int offset) throws BadLocationException, MisconfigurationException { for (int i = 0; i < 10; i++) { List props = quickFix.getProps(ps, SharedUiPlugin.getImageCache(), @@ -945,7 +858,7 @@ private List waitForQuickFixProps(TddCodeGenerationQu private void checkCreateNewModuleWithClass2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; List props; IFile mod2 = initFile.getParent().getParent().getParent().getFile(new Path("newpack2/module_new.py")); @@ -966,7 +879,7 @@ public Object call(PyEdit obj) { "from newpack2.module_new import Foo"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -992,7 +905,7 @@ public Object call(PyEdit obj) { private void checkCreateNewModuleWithClass3() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; List props; IFile mod2 = initFile.getParent().getParent().getParent().getFile(new Path("newpack2/module_new9.py")); @@ -1013,7 +926,7 @@ public Object call(PyEdit obj) { "class Foo:\n from newpack2.module_new9 import Foo"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1038,7 +951,7 @@ public Object call(PyEdit obj) { private void checkCreateNewModuleWithClass() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; List props; IFile mod2 = initFile.getParent().getFolder(new Path("pack3")).getFile(new Path("module_new2.py")); @@ -1059,7 +972,7 @@ public Object call(PyEdit obj) { "from pack1.pack2.pack3.module_new2 import Foo"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1094,7 +1007,7 @@ private void checkCreateClass() throws CoreException, BadLocationException, Misc String mod1Contents = "Foo"; setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); PySelection ps = new PySelection(editor.getDocument(), 0); assertTrue(quickFix.isValid(ps, "", editor, 0)); List props = quickFix.getProps(ps, SharedUiPlugin.getImageCache(), @@ -1126,7 +1039,7 @@ private void checkCreateMethodAtClass() throws CoreException, BadLocationExcepti "foo.Met1()"; setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1168,7 +1081,7 @@ private void checkCreateFieldAtClass() throws CoreException, BadLocationExceptio "foo.new_field"; setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1208,7 +1121,7 @@ private void checkCreateFieldAtClass5() throws CoreException, BadLocationExcepti " self.a = 10"; setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1248,7 +1161,7 @@ private void checkCreateFieldAtClass3() throws CoreException, BadLocationExcepti "foo.new_field"; setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1291,7 +1204,7 @@ private void checkCreateFieldAtClass4() throws CoreException, BadLocationExcepti ""; setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - secondPart.length(); PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1326,7 +1239,7 @@ private void checkCreateConstant() throws CoreException, BadLocationException, M setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1361,7 +1274,7 @@ private void checkCreateFieldAtClass2() throws CoreException, BadLocationExcepti "foo.new_field"; setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1395,7 +1308,7 @@ private void checkCreateMethodAtClass2() throws CoreException, BadLocationExcept "foo.Met1(param1=10)"; setContentsAndWaitReparseAndError(mod1Contents); - TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); + TddCodeGenerationQuickFixFromMarkersParticipant quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1426,12 +1339,12 @@ private void checkCreateMethodAtClass2() throws CoreException, BadLocationExcept private void checkCreateClassWithParams() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; List props; mod1Contents = "Foo(call1(ueo), 'aa,bb', 10, cc)"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); ps = new PySelection(editor.getDocument(), 0); assertTrue(quickFix.isValid(ps, "", editor, 0)); props = quickFix.getProps(ps, SharedUiPlugin.getImageCache(), editor.getEditorFile(), editor.getPythonNature(), @@ -1456,12 +1369,12 @@ private void checkCreateClassWithParams() throws CoreException, BadLocationExcep private void checkCreateClassWithParams2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; List props; mod1Contents = "Foo(a=10, b=20)"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); ps = new PySelection(editor.getDocument(), 0); assertTrue(quickFix.isValid(ps, "", editor, 0)); props = quickFix.getProps(ps, SharedUiPlugin.getImageCache(), editor.getEditorFile(), editor.getPythonNature(), @@ -1493,7 +1406,7 @@ private void checkCreateClassInit2() throws CoreException, BadLocationException, private void checkCreateClassInit3() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; List props; mod1Contents = "" + @@ -1507,7 +1420,7 @@ private void checkCreateClassInit3() throws CoreException, BadLocationException, + "Foo(a=10, b=20)"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1540,7 +1453,7 @@ private void checkCreateClassInit3() throws CoreException, BadLocationException, private void baseCheckCreateClassInit(int minusOffset) throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; List props; mod1Contents = "" + @@ -1551,7 +1464,7 @@ private void baseCheckCreateClassInit(int minusOffset) throws CoreException, Bad "\n" + "Foo(a=10, b=20)"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - minusOffset; ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); @@ -1582,7 +1495,7 @@ private void baseCheckCreateClassInit(int minusOffset) throws CoreException, Bad private void checkCreateClassAtOtherModule() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; - TddCodeGenerationQuickFixParticipant quickFix; + TddCodeGenerationQuickFixFromMarkersParticipant quickFix; PySelection ps; List props; IFile mod2 = initFile.getParent().getFile(new Path("other_module.py")); @@ -1595,7 +1508,7 @@ private void checkCreateClassAtOtherModule() throws CoreException, BadLocationEx "other_module.Foo"; setContentsAndWaitReparseAndError(mod1Contents); - quickFix = new TddCodeGenerationQuickFixParticipant(); + quickFix = new TddCodeGenerationQuickFixFromMarkersParticipant(); int offset = mod1Contents.length() - 1; ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/adapters/visitors/VisitorFactory.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/adapters/visitors/VisitorFactory.java index c5a2779e34..991594020e 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/adapters/visitors/VisitorFactory.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/adapters/visitors/VisitorFactory.java @@ -14,7 +14,6 @@ import org.python.pydev.ast.codecompletion.revisited.modules.SourceModule; import org.python.pydev.core.BaseModuleRequest; import org.python.pydev.core.IGrammarVersionProvider; -import org.python.pydev.core.IGrammarVersionProvider.AdditionalGrammarVersionsToCheck; import org.python.pydev.core.IModule; import org.python.pydev.core.IModulesManager; import org.python.pydev.core.IPythonNature; @@ -23,9 +22,12 @@ import org.python.pydev.core.preferences.FileTypesPreferences; import org.python.pydev.parser.PyParser; import org.python.pydev.parser.jython.SimpleNode; +import org.python.pydev.parser.jython.ast.Module; import org.python.pydev.parser.jython.ast.VisitorIF; import org.python.pydev.parser.jython.ast.exprType; import org.python.pydev.shared_core.io.FileUtils; +import org.python.pydev.shared_core.model.ISimpleNode; +import org.python.pydev.shared_core.parsing.BaseParser.ParseOutput; import org.python.pydev.shared_core.string.ICoreTextSelection; public final class VisitorFactory { @@ -76,15 +78,21 @@ public static T createVisitor(Class visitorClass, Simpl public static ModuleAdapter createModuleAdapter(PythonModuleManager pythonModuleManager, File file, IDocument doc, IPythonNature nature, IGrammarVersionProvider versionProvider) throws Throwable { + return createModuleAdapter(pythonModuleManager, file, doc, nature, versionProvider, false); + } + + public static ModuleAdapter createModuleAdapter(PythonModuleManager pythonModuleManager, File file, IDocument doc, + IPythonNature nature, IGrammarVersionProvider versionProvider, boolean acceptSyntaxErrors) + throws Throwable { if (file != null && file.exists()) { if (FileTypesPreferences.isCythonFile(file.getName())) { versionProvider = new IGrammarVersionProvider() { - + @Override public int getGrammarVersion() throws MisconfigurationException { return IPythonNature.GRAMMAR_PYTHON_VERSION_CYTHON; } - + @Override public AdditionalGrammarVersionsToCheck getAdditionalGrammarVersions() throws MisconfigurationException { @@ -100,8 +108,10 @@ public AdditionalGrammarVersionsToCheck getAdditionalGrammarVersions() IModule module = modulesManager.getModule(modName, nature, true, new BaseModuleRequest(false)); if (module instanceof ISourceModule) { SourceModule iSourceModule = (SourceModule) module; - if (iSourceModule.parseError != null) { - throw iSourceModule.parseError; + if (!acceptSyntaxErrors) { + if (iSourceModule.parseError != null) { + throw iSourceModule.parseError; + } } return new ModuleAdapter(pythonModuleManager, ((ISourceModule) module), nature, doc); } @@ -109,7 +119,14 @@ public AdditionalGrammarVersionsToCheck getAdditionalGrammarVersions() } } } - return new ModuleAdapter(pythonModuleManager, file, doc, org.python.pydev.parser.PyParser.parseSimple(doc, versionProvider), nature); + ParseOutput output = PyParser.parseFull(doc, versionProvider); + if (!acceptSyntaxErrors) { + if (output.error != null) { + throw output.error; + } + } + ISimpleNode module = output.ast; + return new ModuleAdapter(pythonModuleManager, file, doc, (Module) module, nature); } public static void validateSelection(ModuleAdapter scope) throws SelectionException { diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/AbstractMessage.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/AbstractMessage.java index 8ee7972383..522ce40b88 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/AbstractMessage.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/AbstractMessage.java @@ -18,9 +18,9 @@ import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.codecompletion.revisited.modules.SourceToken; import org.python.pydev.ast.codecompletion.revisited.visitors.AbstractVisitor; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.IToken; import org.python.pydev.parser.jython.SimpleNode; import org.python.pydev.parser.jython.ast.Import; diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/CompositeMessage.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/CompositeMessage.java index 49901785d7..81e4269a73 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/CompositeMessage.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/CompositeMessage.java @@ -14,7 +14,7 @@ import java.util.Iterator; import java.util.List; -import org.python.pydev.ast.analysis.IAnalysisPreferences; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.IToken; import org.python.pydev.shared_core.string.FastStringBuffer; diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/IMessage.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/IMessage.java index 6071b89cf1..1681140609 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/IMessage.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/IMessage.java @@ -25,21 +25,21 @@ public interface IMessage { int getSeverity(); /** - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_DUPLICATED_SIGNATURE - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_NO_SELF - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_REIMPORT - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_UNDEFINED_VARIABLE - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_UNRESOLVED_IMPORT - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_UNUSED_IMPORT - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_UNUSED_VARIABLE - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_UNUSED_PARAMETER - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_UNUSED_WILD_IMPORT - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_USED_WILD_IMPORT - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_NO_EFFECT_STMT - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_INDENTATION_PROBLEM - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_PEP8 - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_ARGUMENTS_MISATCH - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#TYPE_INVALID_ENCODING + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_DUPLICATED_SIGNATURE + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_NO_SELF + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_REIMPORT + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_UNDEFINED_VARIABLE + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_UNRESOLVED_IMPORT + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_UNUSED_IMPORT + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_UNUSED_VARIABLE + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_UNUSED_PARAMETER + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_UNUSED_WILD_IMPORT + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_USED_WILD_IMPORT + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_NO_EFFECT_STMT + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_INDENTATION_PROBLEM + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_PEP8 + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_ARGUMENTS_MISATCH + * @see org.python.pydev.core.IAnalysisPreferences#TYPE_INVALID_ENCODING * * @return this message type */ diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/Message.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/Message.java index 8477ed5a84..d986b689ec 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/Message.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/messages/Message.java @@ -10,7 +10,7 @@ package org.python.pydev.ast.analysis.messages; import org.eclipse.core.runtime.Assert; -import org.python.pydev.ast.analysis.IAnalysisPreferences; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.IToken; public class Message extends AbstractMessage { diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/refactoring/RefactoringInfo.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/refactoring/RefactoringInfo.java index 56080df07b..4ae50fccbe 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/refactoring/RefactoringInfo.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/refactoring/RefactoringInfo.java @@ -125,7 +125,7 @@ private void initInfo(ICoreTextSelection selection) { try { this.moduleAdapter = org.python.pydev.ast.adapters.visitors.VisitorFactory.createModuleAdapter( moduleManager, realFile, doc, nature, - this.versionProvider); + this.versionProvider, true); } catch (Throwable e) { throw new RuntimeException(e); } diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/core/templates/PyDocumentTemplateContext.java b/plugins/org.python.pydev.ast/src/org/python/pydev/core/templates/PyDocumentTemplateContext.java index 292e0e026f..ce633b7288 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/core/templates/PyDocumentTemplateContext.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/core/templates/PyDocumentTemplateContext.java @@ -21,6 +21,7 @@ import org.python.pydev.core.IPythonNature; import org.python.pydev.core.ISourceViewerForTemplates; import org.python.pydev.core.MisconfigurationException; +import org.python.pydev.core.autoedit.DefaultIndentPrefs; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.interactive_console.IScriptConsoleViewer; import org.python.pydev.parser.fastparser.FastParser; @@ -49,7 +50,8 @@ public PyDocumentTemplateContext(TemplateContextType type, IDocument document, i public PyDocumentTemplateContext(TemplateContextType type, IDocument document, int offset, int length, String indentTo, ISourceViewerForTemplates viewer) { - this(type, document, offset, length, indentTo, viewer.getIndentPrefs()); + this(type, document, offset, length, indentTo, + viewer != null ? viewer.getIndentPrefs() : DefaultIndentPrefs.get(null)); this.edit = viewer; } @@ -145,9 +147,8 @@ public String getModuleName() { * @return a template context that can handle template insertion at the given location, or null */ public static PyDocumentTemplateContext createContext(final TemplateContextType contextType, - final ISourceViewerForTemplates edit, final IRegion region, String indentTo) { + final ISourceViewerForTemplates edit, IDocument document, final IRegion region, String indentTo) { if (contextType != null) { - IDocument document = edit.getDocument(); return new PyDocumentTemplateContext(contextType, document, region.getOffset(), region.getLength(), indentTo, edit); } @@ -161,7 +162,7 @@ public static PyDocumentTemplateContext createContext(final TemplateContextType ICoreTextSelection textSelection = edit.getTextSelection(); PySelection selection = new PySelection(document, textSelection); String indent = selection.getIndentationFromLine(); - return PyDocumentTemplateContext.createContext(contextType, edit, region, indent); + return PyDocumentTemplateContext.createContext(contextType, edit, edit.getDocument(), region, indent); } return null; } @@ -170,14 +171,23 @@ public static PyDocumentTemplateContext createContextWithCursor(ISourceViewerFor IRegion region, String indent) { TemplateContextType contextType = new TemplateContextType(); contextType.addResolver(new GlobalTemplateVariables.Cursor()); //We do want the cursor thought. - return createContext(contextType, targetEditor, region, indent); + return createContext(contextType, targetEditor, targetEditor != null ? targetEditor.getDocument() : null, + region, indent); + } + + public static PyDocumentTemplateContext createContextWithCursor(ISourceViewerForTemplates targetEditor, + IDocument document, + IRegion region, String indent) { + TemplateContextType contextType = new TemplateContextType(); + contextType.addResolver(new GlobalTemplateVariables.Cursor()); //We do want the cursor thought. + return createContext(contextType, targetEditor, document, region, indent); } public static PyDocumentTemplateContext createContextWithDefaultResolvers(ISourceViewerForTemplates edit, IRegion region, String indentTo) { TemplateContextType contextType = new TemplateContextType(); PyAddTemplateResolvers.addDefaultResolvers(contextType); - return createContext(contextType, edit, region, indentTo); + return createContext(contextType, edit, edit != null ? edit.getDocument() : null, region, indentTo); } } \ No newline at end of file diff --git a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/IAnalysisMarkersParticipant.java b/plugins/org.python.pydev.core/src/org/python/pydev/core/IAnalysisMarkersParticipant.java similarity index 81% rename from plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/IAnalysisMarkersParticipant.java rename to plugins/org.python.pydev.core/src/org/python/pydev/core/IAnalysisMarkersParticipant.java index 7b89a3aeab..04f1b944b9 100644 --- a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/IAnalysisMarkersParticipant.java +++ b/plugins/org.python.pydev.core/src/org/python/pydev/core/IAnalysisMarkersParticipant.java @@ -7,17 +7,13 @@ /* * Created on 24/09/2005 */ -package com.python.pydev.analysis.ctrl_1; +package org.python.pydev.core; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.BadLocationException; -import org.python.pydev.ast.analysis.IAnalysisPreferences; -import org.python.pydev.core.IPyEdit; -import org.python.pydev.core.IPythonNature; import org.python.pydev.core.docutils.PySelection; -import org.python.pydev.editor.codefolding.MarkerAnnotationAndPosition; import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; public interface IAnalysisMarkersParticipant { @@ -38,7 +34,7 @@ public interface IAnalysisMarkersParticipant { * @throws BadLocationException * @throws CoreException */ - public abstract void addProps(MarkerAnnotationAndPosition marker, IAnalysisPreferences analysisPreferences, + public abstract void addProps(IMarkerInfoForAnalysis markerInfo, IAnalysisPreferences analysisPreferences, String line, PySelection ps, int offset, IPythonNature nature, IPyEdit edit, List props) throws BadLocationException, CoreException; diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/IAnalysisPreferences.java b/plugins/org.python.pydev.core/src/org/python/pydev/core/IAnalysisPreferences.java similarity index 99% rename from plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/IAnalysisPreferences.java rename to plugins/org.python.pydev.core/src/org/python/pydev/core/IAnalysisPreferences.java index ae2630bc86..e5ad44975c 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/analysis/IAnalysisPreferences.java +++ b/plugins/org.python.pydev.core/src/org/python/pydev/core/IAnalysisPreferences.java @@ -7,7 +7,7 @@ /* * Created on 24/07/2005 */ -package org.python.pydev.ast.analysis; +package org.python.pydev.core; import java.util.Set; diff --git a/plugins/org.python.pydev.core/src/org/python/pydev/core/IMarkerInfoForAnalysis.java b/plugins/org.python.pydev.core/src/org/python/pydev/core/IMarkerInfoForAnalysis.java new file mode 100644 index 0000000000..ee8e080424 --- /dev/null +++ b/plugins/org.python.pydev.core/src/org/python/pydev/core/IMarkerInfoForAnalysis.java @@ -0,0 +1,20 @@ +package org.python.pydev.core; + +public interface IMarkerInfoForAnalysis { + + Object getPyLintMessageIdAttribute(); + + Integer getPyDevAnalisysType(); + + boolean hasPosition(); + + int getOffset(); + + int getLength(); + + void delete(); + + Object getFlake8MessageId(); + + Object getMessage(); +} diff --git a/plugins/org.python.pydev.core/src/org/python/pydev/core/proposals/ICompletionProposalFactory.java b/plugins/org.python.pydev.core/src/org/python/pydev/core/proposals/ICompletionProposalFactory.java index 1f725835a9..26e887550d 100644 --- a/plugins/org.python.pydev.core/src/org/python/pydev/core/proposals/ICompletionProposalFactory.java +++ b/plugins/org.python.pydev.core/src/org/python/pydev/core/proposals/ICompletionProposalFactory.java @@ -2,11 +2,11 @@ import java.util.List; -import org.eclipse.core.resources.IMarker; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.templates.Template; import org.eclipse.jface.text.templates.TemplateContext; import org.python.pydev.core.ICompletionRequest; +import org.python.pydev.core.IMarkerInfoForAnalysis; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.IToken; import org.python.pydev.core.ShellId; @@ -34,13 +34,13 @@ ICompletionProposalHandle createIgnorePyLintCompletionProposalInSameLine( String replacementString, int replacementOffset, int replacementLength, int cursorPosition, IImageHandle image, String displayString, Object contextInformation, String additionalProposalInfo, int priority, IPyEdit edit, String line, PySelection ps, FormatStd format, - IMarker marker); + IMarkerInfoForAnalysis marker); ICompletionProposalHandle createIgnoreFlake8CompletionProposalInSameLine( String replacementString, int replacementOffset, int replacementLength, int cursorPosition, IImageHandle image, String displayString, Object contextInformation, String additionalProposalInfo, int priority, IPyEdit edit, String line, PySelection ps, FormatStd format, - IMarker marker); + IMarkerInfoForAnalysis marker); ICompletionProposalHandle createPyTemplateProposal(Template template, TemplateContext context, IRegion region, IImageHandle image, int relevance); diff --git a/plugins/org.python.pydev.parser/src/org/python/pydev/parser/PyParser.java b/plugins/org.python.pydev.parser/src/org/python/pydev/parser/PyParser.java index 58b747eed1..b5a617e1fa 100644 --- a/plugins/org.python.pydev.parser/src/org/python/pydev/parser/PyParser.java +++ b/plugins/org.python.pydev.parser/src/org/python/pydev/parser/PyParser.java @@ -575,6 +575,11 @@ public static Tuple reparseDocumentInternal(IDocument doc, return new Tuple(grammar.file_input(), grammar); // parses the file } + public static ParseOutput parseFull(IDocument doc, IGrammarVersionProvider versionProvider) + throws MisconfigurationException { + return parseFull(new ParserInfo(doc, versionProvider)); + } + /** * @return a tuple with the SimpleNode root(if parsed) and the error (if any). * if we are able to recover from a reparse, we have both, the root and the error. diff --git a/plugins/org.python.pydev.shared_core/src/org/python/pydev/shared_core/io/FileUtils.java b/plugins/org.python.pydev.shared_core/src/org/python/pydev/shared_core/io/FileUtils.java index 1d55a59352..f97dbd190c 100644 --- a/plugins/org.python.pydev.shared_core/src/org/python/pydev/shared_core/io/FileUtils.java +++ b/plugins/org.python.pydev.shared_core/src/org/python/pydev/shared_core/io/FileUtils.java @@ -1072,7 +1072,7 @@ public static long lastModified(File file) { return lastModified(path); } catch (IOException e) { final long lastModified = file.lastModified(); - Log.log("Error. returning: " + lastModified, e); + Log.logInfo("Exception checking file: " + file + ": " + e.getMessage() + " - returning: " + lastModified); return lastModified; } } diff --git a/plugins/org.python.pydev/plugin.xml b/plugins/org.python.pydev/plugin.xml index 33b5aeba7a..18ac6e8d17 100644 --- a/plugins/org.python.pydev/plugin.xml +++ b/plugins/org.python.pydev/plugin.xml @@ -3115,7 +3115,7 @@ The related image showing the error is at: http://i.stack.imgur.com/IfNFY.png - + diff --git a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/AbstractAnalysisMarkersParticipants.java b/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/AbstractAnalysisMarkersParticipants.java index f13555b97e..339bf92bfa 100644 --- a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/AbstractAnalysisMarkersParticipants.java +++ b/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/AbstractAnalysisMarkersParticipants.java @@ -11,7 +11,8 @@ import java.util.List; import org.eclipse.jface.text.BadLocationException; -import org.python.pydev.ast.analysis.IAnalysisPreferences; +import org.python.pydev.core.IAnalysisMarkersParticipant; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.IAssistProps; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.IPythonNature; @@ -67,7 +68,8 @@ public List getProps(PySelection ps, IImageCache imag for (MarkerAnnotationAndPosition marker : markersAtLine) { for (IAnalysisMarkersParticipant participant : participants) { try { - participant.addProps(marker, analysisPreferences, currLine, ps, offset, nature, edit, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), analysisPreferences, currLine, ps, + offset, nature, edit, props); } catch (Exception e) { Log.log("Error when getting proposals.", e); } diff --git a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/AnalysisMarkersParticipants.java b/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/AnalysisMarkersParticipants.java index bb886cd33f..b60e55d4b8 100644 --- a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/AnalysisMarkersParticipants.java +++ b/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/AnalysisMarkersParticipants.java @@ -1,6 +1,8 @@ package com.python.pydev.analysis.ctrl_1; import com.python.pydev.analysis.additionalinfo.builders.AnalysisRunner; +import com.python.pydev.analysis.marker_quick_fixes.IgnoreErrorParticipant; +import com.python.pydev.analysis.marker_quick_fixes.UndefinedVariableFixParticipant; /** * Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved. diff --git a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/flake8/Flake8IgnoreErrorParticipant.java b/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/flake8/Flake8IgnoreErrorParticipant.java index 97d824690b..9bee6b2eeb 100644 --- a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/flake8/Flake8IgnoreErrorParticipant.java +++ b/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/flake8/Flake8IgnoreErrorParticipant.java @@ -10,25 +10,22 @@ import java.util.List; import java.util.Set; -import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.BadLocationException; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.core.CheckAnalysisErrors; +import org.python.pydev.core.IAnalysisMarkersParticipant; +import org.python.pydev.core.IAnalysisPreferences; +import org.python.pydev.core.IMarkerInfoForAnalysis; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.formatter.FormatStd; import org.python.pydev.core.proposals.CompletionProposalFactory; -import org.python.pydev.editor.codefolding.MarkerAnnotationAndPosition; -import org.python.pydev.shared_core.IMiscConstants; import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; import org.python.pydev.shared_core.code_completion.IPyCompletionProposal; import org.python.pydev.shared_core.image.UIConstants; import org.python.pydev.shared_ui.SharedUiPlugin; -import com.python.pydev.analysis.ctrl_1.IAnalysisMarkersParticipant; - public class Flake8IgnoreErrorParticipant implements IAnalysisMarkersParticipant { private Set handled = new HashSet<>(); @@ -47,13 +44,12 @@ public Flake8IgnoreErrorParticipant() { } @Override - public void addProps(MarkerAnnotationAndPosition marker, IAnalysisPreferences analysisPreferences, + public void addProps(IMarkerInfoForAnalysis markerInfo, IAnalysisPreferences analysisPreferences, final String line, final PySelection ps, int offset, IPythonNature nature, final IPyEdit edit, List props) throws BadLocationException, CoreException { - IMarker m = marker.markerAnnotation.getMarker(); - Object attribute = m.getAttribute(IMiscConstants.FLAKE8_MESSAGE_ID); - Object message = m.getAttribute(IMarker.MESSAGE); + Object attribute = markerInfo.getFlake8MessageId(); + Object message = markerInfo.getMessage(); if (attribute == null || message == null) { return; } @@ -75,7 +71,7 @@ public void addProps(MarkerAnnotationAndPosition marker, IAnalysisPreferences an messageId, ps.getEndLineOffset(), 0, offset, SharedUiPlugin.getImageCache().get(UIConstants.ASSIST_ANNOTATION), displayString, null, - null, IPyCompletionProposal.PRIORITY_DEFAULT, edit, line, ps, format, m); + null, IPyCompletionProposal.PRIORITY_DEFAULT, edit, line, ps, format, markerInfo); props.add(proposal); } } diff --git a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/pylint/PyLintIgnoreErrorParticipant.java b/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/pylint/PyLintIgnoreErrorParticipant.java index e450442698..d45af6ad0e 100644 --- a/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/pylint/PyLintIgnoreErrorParticipant.java +++ b/plugins/org.python.pydev/src/com/python/pydev/analysis/ctrl_1/pylint/PyLintIgnoreErrorParticipant.java @@ -10,25 +10,22 @@ import java.util.List; import java.util.Set; -import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.BadLocationException; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.core.CheckAnalysisErrors; +import org.python.pydev.core.IAnalysisMarkersParticipant; +import org.python.pydev.core.IAnalysisPreferences; +import org.python.pydev.core.IMarkerInfoForAnalysis; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.formatter.FormatStd; import org.python.pydev.core.proposals.CompletionProposalFactory; -import org.python.pydev.editor.codefolding.MarkerAnnotationAndPosition; -import org.python.pydev.shared_core.IMiscConstants; import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; import org.python.pydev.shared_core.code_completion.IPyCompletionProposal; import org.python.pydev.shared_core.image.UIConstants; import org.python.pydev.shared_ui.SharedUiPlugin; -import com.python.pydev.analysis.ctrl_1.IAnalysisMarkersParticipant; - public class PyLintIgnoreErrorParticipant implements IAnalysisMarkersParticipant { private Set handled = new HashSet<>(); @@ -48,15 +45,14 @@ public PyLintIgnoreErrorParticipant() { /** * @throws CoreException - * @see org.python.pydev.ast.analysis.ctrl_1.IAnalysisMarkersParticipant#addProps(org.eclipse.core.resources.IMarker, org.python.pydev.ast.analysis.IAnalysisPreferences, java.lang.String, org.python.pydev.core.docutils.PySelection, int, org.python.pydev.editor.PyEdit, java.util.List) + * @see org.python.pydev.core.ctrl_1.IAnalysisMarkersParticipant#addProps(org.eclipse.core.resources.IMarker, org.python.pydev.core.IAnalysisPreferences, java.lang.String, org.python.pydev.core.docutils.PySelection, int, org.python.pydev.editor.PyEdit, java.util.List) */ @Override - public void addProps(MarkerAnnotationAndPosition marker, IAnalysisPreferences analysisPreferences, + public void addProps(IMarkerInfoForAnalysis markerInfo, IAnalysisPreferences analysisPreferences, final String line, final PySelection ps, int offset, IPythonNature nature, final IPyEdit edit, List props) throws BadLocationException, CoreException { - IMarker m = marker.markerAnnotation.getMarker(); - Object attribute = m.getAttribute(IMiscConstants.PYLINT_MESSAGE_ID); + Object attribute = markerInfo.getPyLintMessageIdAttribute(); if (attribute == null) { return; } @@ -75,7 +71,7 @@ public void addProps(MarkerAnnotationAndPosition marker, IAnalysisPreferences an messageId, ps.getEndLineOffset(), 0, offset, SharedUiPlugin.getImageCache().get(UIConstants.ASSIST_ANNOTATION), "pylint: disable=" + messageId, null, - null, IPyCompletionProposal.PRIORITY_DEFAULT, edit, line, ps, format, m); + null, IPyCompletionProposal.PRIORITY_DEFAULT, edit, line, ps, format, markerInfo); props.add(proposal); } } diff --git a/plugins/org.python.pydev/src/com/python/pydev/analysis/organizeimports/OrganizeImports.java b/plugins/org.python.pydev/src/com/python/pydev/analysis/organizeimports/OrganizeImports.java index 7035e57f09..84f7751473 100644 --- a/plugins/org.python.pydev/src/com/python/pydev/analysis/organizeimports/OrganizeImports.java +++ b/plugins/org.python.pydev/src/com/python/pydev/analysis/organizeimports/OrganizeImports.java @@ -29,8 +29,8 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; -import org.python.pydev.ast.analysis.IAnalysisPreferences; import org.python.pydev.ast.codecompletion.ProposalsComparator; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.log.Log; import org.python.pydev.editor.PyEdit; @@ -49,7 +49,7 @@ import com.python.pydev.analysis.AnalysisPreferences; import com.python.pydev.analysis.AnalysisUiPlugin; import com.python.pydev.analysis.additionalinfo.builders.AnalysisRunner; -import com.python.pydev.analysis.ctrl_1.UndefinedVariableFixParticipant; +import com.python.pydev.analysis.marker_quick_fixes.UndefinedVariableFixParticipant; /** * Used to present the user a way to add imports for the undefined variables. @@ -120,7 +120,8 @@ public boolean beforePerformArrangeImports(final PySelection ps, final PyEdit ed if (treatedVars.contains(string)) { continue; } - variableFixParticipant.addProps(marker, null, null, ps, start, edit.getPythonNature(), edit, + variableFixParticipant.addProps(marker.asMarkerInfoForAnalysis(), null, null, ps, start, + edit.getPythonNature(), edit, props); if (props.size() > 0) { diff --git a/plugins/org.python.pydev/src/org/python/pydev/editor/codecompletion/PyTemplateProposal.java b/plugins/org.python.pydev/src/org/python/pydev/editor/codecompletion/PyTemplateProposal.java index ad8493499c..c7ef717285 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/editor/codecompletion/PyTemplateProposal.java +++ b/plugins/org.python.pydev/src/org/python/pydev/editor/codecompletion/PyTemplateProposal.java @@ -1,16 +1,23 @@ package org.python.pydev.editor.codecompletion; import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Region; import org.eclipse.jface.text.templates.Template; import org.eclipse.jface.text.templates.TemplateContext; import org.eclipse.jface.text.templates.TemplateProposal; import org.eclipse.swt.graphics.Image; import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; +import com.python.pydev.analysis.refactoring.tdd.TemplateInfo; + public class PyTemplateProposal extends TemplateProposal implements ICompletionProposalHandle { public PyTemplateProposal(Template template, TemplateContext context, IRegion region, Image image, int relevance) { super(template, context, region, image, relevance); } + public TemplateInfo getAsTemplateInfo() { + IRegion region = new Region(getReplaceOffset(), getReplaceEndOffset() - getReplaceOffset()); + return new TemplateInfo(getTemplate(), getContext(), region); + } } diff --git a/plugins/org.python.pydev/src/org/python/pydev/editor/codecompletion/proposals/DefaultCompletionProposalFactory.java b/plugins/org.python.pydev/src/org/python/pydev/editor/codecompletion/proposals/DefaultCompletionProposalFactory.java index 2e989e1b02..fcb299c90b 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/editor/codecompletion/proposals/DefaultCompletionProposalFactory.java +++ b/plugins/org.python.pydev/src/org/python/pydev/editor/codecompletion/proposals/DefaultCompletionProposalFactory.java @@ -2,7 +2,6 @@ import java.util.List; -import org.eclipse.core.resources.IMarker; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.contentassist.IContextInformation; import org.eclipse.jface.text.templates.Template; @@ -10,6 +9,7 @@ import org.eclipse.swt.widgets.Display; import org.python.pydev.ast.refactoring.RefactoringRequest; import org.python.pydev.core.ICompletionRequest; +import org.python.pydev.core.IMarkerInfoForAnalysis; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.IToken; import org.python.pydev.core.ShellId; @@ -56,7 +56,7 @@ public ICompletionProposalHandle createIgnorePyLintCompletionProposalInSameLine( String replacementString, int replacementOffset, int replacementLength, int cursorPosition, IImageHandle image, String displayString, Object contextInformation, String additionalProposalInfo, int priority, IPyEdit edit, String line, PySelection ps, FormatStd format, - IMarker marker) { + IMarkerInfoForAnalysis marker) { return new IgnorePyLintCompletionProposalInSameLine(replacementString, replacementOffset, replacementLength, cursorPosition, image, displayString, (IContextInformation) contextInformation, additionalProposalInfo, priority, edit, line, @@ -68,7 +68,7 @@ public ICompletionProposalHandle createIgnoreFlake8CompletionProposalInSameLine( String replacementString, int replacementOffset, int replacementLength, int cursorPosition, IImageHandle image, String displayString, Object contextInformation, String additionalProposalInfo, int priority, IPyEdit edit, String line, PySelection ps, FormatStd format, - IMarker marker) { + IMarkerInfoForAnalysis marker) { return new IgnoreFlake8CompletionProposalInSameLine(replacementString, replacementOffset, replacementLength, cursorPosition, image, displayString, (IContextInformation) contextInformation, additionalProposalInfo, priority, edit, line, diff --git a/plugins/org.python.pydev/src/org/python/pydev/editor/codefolding/MarkerAnnotationAndPosition.java b/plugins/org.python.pydev/src/org/python/pydev/editor/codefolding/MarkerAnnotationAndPosition.java index d6ecca4fe6..af92ba3b5b 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/editor/codefolding/MarkerAnnotationAndPosition.java +++ b/plugins/org.python.pydev/src/org/python/pydev/editor/codefolding/MarkerAnnotationAndPosition.java @@ -6,14 +6,93 @@ */ package org.python.pydev.editor.codefolding; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.Position; import org.eclipse.ui.texteditor.SimpleMarkerAnnotation; +import org.python.pydev.core.IMarkerInfoForAnalysis; +import org.python.pydev.core.log.Log; +import org.python.pydev.shared_core.IMiscConstants; + +import com.python.pydev.analysis.additionalinfo.builders.AnalysisRunner; /** * This class bundles the marker annotation and a related position. */ public class MarkerAnnotationAndPosition { + public IMarkerInfoForAnalysis asMarkerInfoForAnalysis() { + return new IMarkerInfoForAnalysis() { + + @Override + public Object getPyLintMessageIdAttribute() { + return getAttribute(IMiscConstants.PYLINT_MESSAGE_ID); + } + + private Object getAttribute(String attr) { + IMarker marker = markerAnnotation.getMarker(); + Object attribute; + try { + attribute = marker.getAttribute(attr); + } catch (Exception e) { + Log.log(e); + return null; + } + return attribute; + } + + @Override + public Integer getPyDevAnalisysType() { + IMarker marker = markerAnnotation.getMarker(); + Integer id; + try { + id = (Integer) marker.getAttribute(AnalysisRunner.PYDEV_ANALYSIS_TYPE); + } catch (Exception e) { + Log.log(e); + return null; + } + return id; + } + + @Override + public Object getFlake8MessageId() { + return getAttribute(IMiscConstants.FLAKE8_MESSAGE_ID); + } + + @Override + public Object getMessage() { + return getAttribute(IMarker.MESSAGE); + } + + @Override + public boolean hasPosition() { + return position != null; + } + + @Override + public int getOffset() { + return position.offset; + } + + @Override + public int getLength() { + return position.length; + } + + @Override + public void delete() { + IMarker marker = markerAnnotation.getMarker(); + if (marker != null) { + try { + marker.delete(); + } catch (CoreException e) { + Log.log(e); + } + } + } + }; + } + public final SimpleMarkerAnnotation markerAnnotation; /** * May be null! diff --git a/plugins/org.python.pydev/src/org/python/pydev/editor/correctionassist/IgnoreFlake8CompletionProposalInSameLine.java b/plugins/org.python.pydev/src/org/python/pydev/editor/correctionassist/IgnoreFlake8CompletionProposalInSameLine.java index 0913e16176..55ceb0587b 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/editor/correctionassist/IgnoreFlake8CompletionProposalInSameLine.java +++ b/plugins/org.python.pydev/src/org/python/pydev/editor/correctionassist/IgnoreFlake8CompletionProposalInSameLine.java @@ -1,10 +1,9 @@ package org.python.pydev.editor.correctionassist; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.contentassist.IContextInformation; import org.python.pydev.ast.formatter.PyFormatter; +import org.python.pydev.core.IMarkerInfoForAnalysis; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.docutils.ParsingUtils; import org.python.pydev.core.docutils.PySelection; @@ -20,13 +19,13 @@ public class IgnoreFlake8CompletionProposalInSameLine extends IgnoreCompletionPr private String line; private PySelection ps; private FormatStd format; - private IMarker marker; + private IMarkerInfoForAnalysis marker; public IgnoreFlake8CompletionProposalInSameLine(String replacementString, int replacementOffset, int replacementLength, int cursorPosition, IImageHandle image, String displayString, IContextInformation contextInformation, String additionalProposalInfo, int priority, IPyEdit edit, String line, PySelection ps, FormatStd format, - IMarker marker) { + IMarkerInfoForAnalysis marker) { super(replacementString, replacementOffset, replacementLength, cursorPosition, image, displayString, contextInformation, additionalProposalInfo, priority, edit); this.line = line; //the current line @@ -111,11 +110,7 @@ public void apply(IDocument document) { super.apply(document); if (this.marker != null) { - try { - this.marker.delete(); - } catch (CoreException e) { - Log.log(e); - } + this.marker.delete(); } } diff --git a/plugins/org.python.pydev/src/org/python/pydev/editor/correctionassist/IgnorePyLintCompletionProposalInSameLine.java b/plugins/org.python.pydev/src/org/python/pydev/editor/correctionassist/IgnorePyLintCompletionProposalInSameLine.java index 484d587f51..e706143846 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/editor/correctionassist/IgnorePyLintCompletionProposalInSameLine.java +++ b/plugins/org.python.pydev/src/org/python/pydev/editor/correctionassist/IgnorePyLintCompletionProposalInSameLine.java @@ -1,10 +1,9 @@ package org.python.pydev.editor.correctionassist; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.contentassist.IContextInformation; import org.python.pydev.ast.formatter.PyFormatter; +import org.python.pydev.core.IMarkerInfoForAnalysis; import org.python.pydev.core.IPyEdit; import org.python.pydev.core.docutils.ParsingUtils; import org.python.pydev.core.docutils.PySelection; @@ -20,13 +19,13 @@ public class IgnorePyLintCompletionProposalInSameLine extends IgnoreCompletionPr private String line; private PySelection ps; private FormatStd format; - private IMarker marker; + private IMarkerInfoForAnalysis marker; public IgnorePyLintCompletionProposalInSameLine(String replacementString, int replacementOffset, int replacementLength, int cursorPosition, IImageHandle image, String displayString, IContextInformation contextInformation, String additionalProposalInfo, int priority, IPyEdit edit, String line, PySelection ps, FormatStd format, - IMarker marker) { + IMarkerInfoForAnalysis marker) { super(replacementString, replacementOffset, replacementLength, cursorPosition, image, displayString, contextInformation, additionalProposalInfo, priority, edit); this.line = line; //the current line @@ -111,11 +110,8 @@ public void apply(IDocument document) { super.apply(document); if (this.marker != null) { - try { - this.marker.delete(); - } catch (CoreException e) { - Log.log(e); - } + this.marker.delete(); + } } diff --git a/plugins/org.python.pydev/tests/org/python/pydev/editor/correctionassist/heuristics/AssistSurroundWithTest.java b/plugins/org.python.pydev/tests/org/python/pydev/editor/correctionassist/heuristics/AssistSurroundWithTest.java index d23d6fcfa5..df97020e1b 100644 --- a/plugins/org.python.pydev/tests/org/python/pydev/editor/correctionassist/heuristics/AssistSurroundWithTest.java +++ b/plugins/org.python.pydev/tests/org/python/pydev/editor/correctionassist/heuristics/AssistSurroundWithTest.java @@ -8,31 +8,13 @@ import java.util.List; -import org.eclipse.core.runtime.AssertionFailedException; import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IAutoIndentStrategy; import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IEventConsumer; -import org.eclipse.jface.text.IFindReplaceTarget; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextDoubleClickStrategy; -import org.eclipse.jface.text.ITextHover; -import org.eclipse.jface.text.ITextInputListener; -import org.eclipse.jface.text.ITextListener; -import org.eclipse.jface.text.ITextOperationTarget; -import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.IUndoManager; -import org.eclipse.jface.text.IViewportListener; -import org.eclipse.jface.text.TextPresentation; -import org.eclipse.jface.text.templates.TemplateProposal; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Point; import org.python.pydev.ast.surround_with.AssistSurroundWith; import org.python.pydev.core.TestCaseUtils; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.proposals.CompletionProposalFactory; +import org.python.pydev.editor.codecompletion.PyTemplateProposal; import org.python.pydev.editor.codecompletion.proposals.DefaultCompletionProposalFactory; import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle; @@ -98,14 +80,8 @@ public void testSurround2() throws Exception { } private void apply(ICompletionProposalHandle iCompletionProposalHandle, IDocument doc) { - TemplateProposal p = (TemplateProposal) iCompletionProposalHandle; - try { - p.apply(createViewerWithDoc(doc), ' ', 0, 0); - } catch (AssertionFailedException e) { - // Ignore (we have errors linking with the UI because it's not there and - // TemplateProposal isn't smart enough to work without it, but it can at least - // do the replacement before failing). - } + PyTemplateProposal p = (PyTemplateProposal) iCompletionProposalHandle; + p.getAsTemplateInfo().apply(doc); } public void testSurround3() throws Exception { @@ -192,256 +168,4 @@ public void testSurround() throws Exception { props = assistSurroundWith.getProps(ps, null, null, null, null, offset); assertEquals(0, props.size()); } - - private ITextViewer createViewerWithDoc(IDocument doc) { - // TODO Auto-generated method stub - return new ITextViewer() { - - @Override - public void setVisibleRegion(int offset, int length) { - // TODO Auto-generated method stub - - } - - @Override - public void setUndoManager(IUndoManager undoManager) { - // TODO Auto-generated method stub - - } - - @Override - public void setTopIndex(int index) { - // TODO Auto-generated method stub - - } - - @Override - public void setTextHover(ITextHover textViewerHover, String contentType) { - // TODO Auto-generated method stub - - } - - @Override - public void setTextDoubleClickStrategy(ITextDoubleClickStrategy strategy, String contentType) { - // TODO Auto-generated method stub - - } - - @Override - public void setTextColor(Color color, int offset, int length, boolean controlRedraw) { - // TODO Auto-generated method stub - - } - - @Override - public void setTextColor(Color color) { - // TODO Auto-generated method stub - - } - - @Override - public void setSelectedRange(int offset, int length) { - // TODO Auto-generated method stub - - } - - @Override - public void setIndentPrefixes(String[] indentPrefixes, String contentType) { - // TODO Auto-generated method stub - - } - - @Override - public void setEventConsumer(IEventConsumer consumer) { - // TODO Auto-generated method stub - - } - - @Override - public void setEditable(boolean editable) { - // TODO Auto-generated method stub - - } - - @Override - public void setDocument(IDocument document, int modelRangeOffset, int modelRangeLength) { - // TODO Auto-generated method stub - - } - - @Override - public void setDocument(IDocument document) { - // TODO Auto-generated method stub - - } - - @Override - public void setDefaultPrefixes(String[] defaultPrefixes, String contentType) { - // TODO Auto-generated method stub - - } - - @Override - public void setAutoIndentStrategy(IAutoIndentStrategy strategy, String contentType) { - // TODO Auto-generated method stub - - } - - @Override - public void revealRange(int offset, int length) { - // TODO Auto-generated method stub - - } - - @Override - public void resetVisibleRegion() { - // TODO Auto-generated method stub - - } - - @Override - public void resetPlugins() { - // TODO Auto-generated method stub - - } - - @Override - public void removeViewportListener(IViewportListener listener) { - // TODO Auto-generated method stub - - } - - @Override - public void removeTextListener(ITextListener listener) { - // TODO Auto-generated method stub - - } - - @Override - public void removeTextInputListener(ITextInputListener listener) { - // TODO Auto-generated method stub - - } - - @Override - public boolean overlapsWithVisibleRegion(int offset, int length) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isEditable() { - // TODO Auto-generated method stub - return false; - } - - @Override - public void invalidateTextPresentation() { - // TODO Auto-generated method stub - - } - - @Override - public IRegion getVisibleRegion() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getTopInset() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getTopIndexStartOffset() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getTopIndex() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public StyledText getTextWidget() { - // TODO Auto-generated method stub - return null; - } - - @Override - public ITextOperationTarget getTextOperationTarget() { - // TODO Auto-generated method stub - return null; - } - - @Override - public ISelectionProvider getSelectionProvider() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Point getSelectedRange() { - // TODO Auto-generated method stub - return null; - } - - @Override - public IFindReplaceTarget getFindReplaceTarget() { - // TODO Auto-generated method stub - return null; - } - - @Override - public IDocument getDocument() { - // TODO Auto-generated method stub - return doc; - } - - @Override - public int getBottomIndexEndOffset() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public int getBottomIndex() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void changeTextPresentation(TextPresentation presentation, boolean controlRedraw) { - // TODO Auto-generated method stub - - } - - @Override - public void addViewportListener(IViewportListener listener) { - // TODO Auto-generated method stub - - } - - @Override - public void addTextListener(ITextListener listener) { - // TODO Auto-generated method stub - - } - - @Override - public void addTextInputListener(ITextInputListener listener) { - // TODO Auto-generated method stub - - } - - @Override - public void activatePlugins() { - // TODO Auto-generated method stub - - } - }; - } } diff --git a/plugins/org.python.pydev/tests/org/python/pydev/parser/PyParserEditorIntegrationTest.java b/plugins/org.python.pydev/tests/org/python/pydev/parser/PyParserEditorIntegrationTest.java index c5d05fa12f..6e306e8a96 100644 --- a/plugins/org.python.pydev/tests/org/python/pydev/parser/PyParserEditorIntegrationTest.java +++ b/plugins/org.python.pydev/tests/org/python/pydev/parser/PyParserEditorIntegrationTest.java @@ -6,194 +6,17 @@ */ package org.python.pydev.parser; -import java.io.File; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; -import org.eclipse.ui.IEditorInput; -import org.python.pydev.core.IGrammarVersionProvider; -import org.python.pydev.core.IIndentPrefs; -import org.python.pydev.core.IPyEdit; -import org.python.pydev.core.IPythonNature; -import org.python.pydev.core.MisconfigurationException; -import org.python.pydev.core.parser.IPyParser; -import org.python.pydev.shared_core.editor.IBaseEditor; -import org.python.pydev.shared_core.model.IModelListener; -import org.python.pydev.shared_core.model.ISimpleNode; +import org.python.pydev.ast.codecompletion.revisited.PyEditStub; +import org.python.pydev.ast.codecompletion.revisited.PydevFileEditorInputStub; import org.python.pydev.shared_core.preferences.InMemoryEclipsePreferences; -import org.python.pydev.shared_core.string.ICoreTextSelection; import junit.framework.TestCase; public class PyParserEditorIntegrationTest extends TestCase { - static class PyEditStub implements IPyEdit { - public IDocument doc; - public int parserChanged; - private Map cache = new HashMap(); - private PydevFileEditorInputStub pydevFileEditorInputStub; - - public PyEditStub(IDocument doc, PydevFileEditorInputStub pydevFileEditorInputStub) { - this.doc = doc; - this.pydevFileEditorInputStub = pydevFileEditorInputStub; - } - - @Override - public IEditorInput getEditorInput() { - return pydevFileEditorInputStub; - } - - @Override - public IPythonNature getPythonNature() { - return new PythonNatureStub(); - } - - public void setParser(IPyParser parser) { - throw new RuntimeException("Not implemented"); - } - - @Override - public Object getParser() { - throw new RuntimeException("Not implemented"); - } - - @Override - public void parserChanged(ISimpleNode root, IAdaptable file, IDocument doc, long docModificationStamp) { - this.parserChanged += 1; - } - - @Override - public void parserError(Throwable error, IAdaptable file, IDocument doc) { - throw new RuntimeException("Not implemented"); - } - - @Override - public Map getCache() { - return this.cache; - } - - @Override - public T getAdapter(Class adapter) { - return null; - } - - @Override - public boolean hasSameInput(IBaseEditor edit) { - if (this == edit) { - throw new RuntimeException( - "Cannot compare when it's the same... it should change the document in this case"); - } - if (edit.getEditorInput() == getEditorInput()) { - return true; - } - return false; - } - - @Override - public IDocument getDocument() { - return doc; - } - - public void setDocument(IDocument doc) { - this.doc = doc; - } - - public void setInput(PydevFileEditorInputStub input) { - this.pydevFileEditorInputStub = input; - } - - @Override - public void setStatusLineErrorMessage(String msg) { - throw new RuntimeException("Not implemented"); - } - - @Override - public IGrammarVersionProvider getGrammarVersionProvider() { - return this.getPythonNature(); - } - - @Override - public IIndentPrefs getIndentPrefs() { - throw new RuntimeException("Not implemented"); - } - - @Override - public Object getFormatStd() { - throw new RuntimeException("Not implemented"); - } - - @Override - public void addModelListener(IModelListener modelListener) { - throw new RuntimeException("Not implemented"); - } - - @Override - public void removeModelListener(IModelListener modelListener) { - throw new RuntimeException("Not implemented"); - } - - @Override - public int getGrammarVersion() throws MisconfigurationException { - throw new RuntimeException("Not implemented"); - } - - @Override - public AdditionalGrammarVersionsToCheck getAdditionalGrammarVersions() throws MisconfigurationException { - throw new RuntimeException("Not implemented"); - } - - @Override - public IProject getProject() { - throw new RuntimeException("Not implemented"); - } - - @Override - public Object getAST() { - throw new RuntimeException("Not implemented"); - } - - @Override - public File getEditorFile() { - throw new RuntimeException("Not implemented"); - } - - @Override - public long getAstModificationTimeStamp() { - throw new RuntimeException("Not implemented"); - } - - @Override - public IFile getIFile() { - throw new RuntimeException("Not implemented"); - } - - @Override - public void addOfflineActionListener(String key, Object action, String description, boolean needsEnter) { - throw new RuntimeException("Not implemented"); - } - - @Override - public boolean isCythonFile() { - return false; - } - - @Override - public ICoreTextSelection getTextSelection() { - throw new RuntimeException("Not implemented"); - } - - @Override - public int getPrintMarginColums() { - throw new RuntimeException("Not implemented"); - } - } - public static void main(String[] args) { try { PyParserEditorIntegrationTest test = new PyParserEditorIntegrationTest(); diff --git a/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/AnalysisPreferencesStub.java b/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/AnalysisPreferencesStub.java index f72cb91ae1..2a784bd9a1 100644 --- a/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/AnalysisPreferencesStub.java +++ b/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/AnalysisPreferencesStub.java @@ -115,7 +115,7 @@ public boolean makeCodeAnalysis() { } /** - * @see org.python.pydev.ast.analysis.IAnalysisPreferences#getNamesIgnoredByUnusedVariable() + * @see org.python.pydev.core.IAnalysisPreferences#getNamesIgnoredByUnusedVariable() */ @Override public Set getNamesIgnoredByUnusedVariable() { diff --git a/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/OccurrencesAnalyzerTest.java b/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/OccurrencesAnalyzerTest.java index e8dcefe70d..b36033e862 100644 --- a/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/OccurrencesAnalyzerTest.java +++ b/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/OccurrencesAnalyzerTest.java @@ -9,10 +9,10 @@ */ package com.python.pydev.analysis; -import static org.python.pydev.ast.analysis.IAnalysisPreferences.TYPE_DUPLICATED_SIGNATURE; -import static org.python.pydev.ast.analysis.IAnalysisPreferences.TYPE_UNDEFINED_VARIABLE; -import static org.python.pydev.ast.analysis.IAnalysisPreferences.TYPE_UNUSED_IMPORT; -import static org.python.pydev.ast.analysis.IAnalysisPreferences.TYPE_UNUSED_VARIABLE; +import static org.python.pydev.core.IAnalysisPreferences.TYPE_DUPLICATED_SIGNATURE; +import static org.python.pydev.core.IAnalysisPreferences.TYPE_UNDEFINED_VARIABLE; +import static org.python.pydev.core.IAnalysisPreferences.TYPE_UNUSED_IMPORT; +import static org.python.pydev.core.IAnalysisPreferences.TYPE_UNUSED_VARIABLE; import java.io.File; import java.io.IOException; diff --git a/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/ctrl_1/IgnoreErrorFixParticipantTest.java b/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/ctrl_1/IgnoreErrorFixParticipantTest.java index 44cb18f81f..5d128e60cb 100644 --- a/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/ctrl_1/IgnoreErrorFixParticipantTest.java +++ b/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/ctrl_1/IgnoreErrorFixParticipantTest.java @@ -13,7 +13,7 @@ import java.util.List; import org.eclipse.jface.text.Document; -import org.python.pydev.ast.analysis.IAnalysisPreferences; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.formatter.FormatStd; import org.python.pydev.core.proposals.CompletionProposalFactory; @@ -23,6 +23,7 @@ import com.python.pydev.analysis.AnalysisPreferencesStub; import com.python.pydev.analysis.additionalinfo.AdditionalInfoTestsBase; +import com.python.pydev.analysis.marker_quick_fixes.IgnoreErrorParticipant; public class IgnoreErrorFixParticipantTest extends AdditionalInfoTestsBase { @@ -59,7 +60,7 @@ public void setUp() throws Exception { super.setUp(); format = new FormatStd(); format.spacesBeforeComment = 2; - participant = new IgnoreErrorParticipant(format); + participant = IgnoreErrorParticipant.createForTests(format); prefs = new AnalysisPreferencesStub(); props = new ArrayList(); CompletionProposalFactory.set(new DefaultCompletionProposalFactory()); @@ -82,7 +83,7 @@ public void testFix() throws Exception { ps = new PySelection(new Document(s)); line = s; offset = s.length(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(1, props); assertEquals("UndefinedVariable", props.get(0).getDisplayString()); @@ -102,7 +103,7 @@ public void testFix2() throws Exception { ps = new PySelection(new Document(s)); line = s; offset = s.length(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(1, props); assertEquals("UndefinedVariable", props.get(0).getDisplayString()); @@ -122,7 +123,7 @@ public void testFix3() throws Exception { ps = new PySelection(new Document(s)); line = s; offset = s.length(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(1, props); assertEquals("UndefinedVariable", props.get(0).getDisplayString()); @@ -142,7 +143,7 @@ public void testFix4() throws Exception { ps = new PySelection(new Document(s)); line = s; offset = s.length(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(1, props); assertEquals("UndefinedVariable", props.get(0).getDisplayString()); @@ -162,7 +163,7 @@ public void testFix5() throws Exception { ps = new PySelection(new Document(s)); line = s; offset = s.length(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(1, props); assertEquals("UndefinedVariable", props.get(0).getDisplayString()); diff --git a/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/ctrl_1/UndefinedVariableFixParticipantTest.java b/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/ctrl_1/UndefinedVariableFixParticipantTest.java index 03dd189f1b..40a1c19125 100644 --- a/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/ctrl_1/UndefinedVariableFixParticipantTest.java +++ b/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/ctrl_1/UndefinedVariableFixParticipantTest.java @@ -13,7 +13,7 @@ import java.util.List; import org.eclipse.jface.text.Document; -import org.python.pydev.ast.analysis.IAnalysisPreferences; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal; import org.python.pydev.editor.codefolding.MarkerAnnotationAndPosition; @@ -22,6 +22,7 @@ import com.python.pydev.analysis.AnalysisPreferences; import com.python.pydev.analysis.AnalysisPreferencesStub; import com.python.pydev.analysis.additionalinfo.AdditionalInfoTestsBase; +import com.python.pydev.analysis.marker_quick_fixes.UndefinedVariableFixParticipant; public class UndefinedVariableFixParticipantTest extends AdditionalInfoTestsBase { @@ -74,7 +75,7 @@ public void testFix() throws Exception { ps = new PySelection(new Document(s)); line = s; offset = s.length(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(1, props); assertEquals("Import testlib", props.get(0).getDisplayString()); } @@ -95,7 +96,7 @@ public void testFix2() throws Exception { offset = s.length(); props = new ArrayList(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(2, props); assertContains("Import testlib.unittest", props); assertContains("Import testlib", props); @@ -115,7 +116,7 @@ public void testFix3() throws Exception { offset = s.length(); props = new ArrayList(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(3, props); assertContains("Import testlib.unittest.anothertest", props); assertContains("Import testlib.unittest", props); @@ -136,7 +137,7 @@ public void testFix4() throws Exception { offset = s.length(); props = new ArrayList(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(3, props); assertContains("Import testlib.unittest.anothertest", props); assertContains("Import testlib.unittest", props); @@ -158,7 +159,7 @@ public void testFix5() throws Exception { offset = s.length(); props = new ArrayList(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(1, props); assertContains("Import AnotherTest (testlib.unittest.anothertest)", props); @@ -178,7 +179,7 @@ public void testFix6() throws Exception { offset = s.length(); props = new ArrayList(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(1, props); //appears with __init__ assertContains("Import DTest (relative.rel1.__init__)", props); @@ -204,7 +205,7 @@ public void testFix7() throws Exception { offset = s.length(); props = new ArrayList(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(1, props); //appears with _ assertContains("Import Priv3 (relative.rel1._priv1._priv2._priv3)", props); @@ -230,7 +231,7 @@ public void testFix8() throws Exception { offset = s.length(); props = new ArrayList(); - participant.addProps(marker, prefs, line, ps, offset, nature, null, props); + participant.addProps(marker.asMarkerInfoForAnalysis(), prefs, line, ps, offset, nature, null, props); printProps(1, props); //appears with _ assertContains("Import NotPriv3 (relative.rel1._priv1._priv2.notpriv3)", props); diff --git a/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/organizeimports/OrganizeImportsTest.java b/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/organizeimports/OrganizeImportsTest.java index 3db7fb691e..78dfe78740 100644 --- a/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/organizeimports/OrganizeImportsTest.java +++ b/plugins/org.python.pydev/tests_analysis/com/python/pydev/analysis/organizeimports/OrganizeImportsTest.java @@ -10,7 +10,7 @@ package com.python.pydev.analysis.organizeimports; import org.eclipse.jface.text.Document; -import org.python.pydev.ast.analysis.IAnalysisPreferences; +import org.python.pydev.core.IAnalysisPreferences; import org.python.pydev.editor.codefolding.MarkerAnnotationAndPosition; import com.python.pydev.analysis.additionalinfo.AdditionalInfoTestsBase; diff --git a/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/CodeCompletionTestsBase.java b/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/CodeCompletionTestsBase.java index ee4c273524..1109b532c0 100644 --- a/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/CodeCompletionTestsBase.java +++ b/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/CodeCompletionTestsBase.java @@ -26,6 +26,7 @@ import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; import org.python.pydev.ast.codecompletion.CompletionRequest; import org.python.pydev.ast.codecompletion.IPyCodeCompletion; import org.python.pydev.ast.codecompletion.PyCodeCompletionUtils; @@ -643,6 +644,11 @@ public ICompletionProposalHandle[] requestCompl(String strDoc, String retCompl) return requestCompl(strDoc, new String[] { retCompl }); } + public static ITextViewer createViewerWithDoc(IDocument doc) { + // TODO Auto-generated method stub + return new TextViewerStub(doc); + } + public static void assertContains(List found, String toFind) { for (String str : found) { if (str.equals(toFind)) { diff --git a/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/PyEditStub.java b/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/PyEditStub.java new file mode 100644 index 0000000000..58447091b1 --- /dev/null +++ b/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/PyEditStub.java @@ -0,0 +1,201 @@ +package org.python.pydev.ast.codecompletion.revisited; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.text.IDocument; +import org.eclipse.ui.IEditorInput; +import org.python.pydev.core.IGrammarVersionProvider; +import org.python.pydev.core.IIndentPrefs; +import org.python.pydev.core.IPyEdit; +import org.python.pydev.core.IPythonNature; +import org.python.pydev.core.MisconfigurationException; +import org.python.pydev.core.autoedit.DefaultIndentPrefs; +import org.python.pydev.core.parser.IPyParser; +import org.python.pydev.parser.PyParser; +import org.python.pydev.parser.PyParser.ParserInfo; +import org.python.pydev.parser.PythonNatureStub; +import org.python.pydev.shared_core.editor.IBaseEditor; +import org.python.pydev.shared_core.model.IModelListener; +import org.python.pydev.shared_core.model.ISimpleNode; +import org.python.pydev.shared_core.parsing.BaseParser.ParseOutput; +import org.python.pydev.shared_core.string.ICoreTextSelection; + +public class PyEditStub implements IPyEdit { + public IDocument doc; + public int parserChanged; + private Map cache = new HashMap(); + private IEditorInput pydevFileEditorInputStub; + private IPythonNature nature; + public IFile iFile; + public File file; + + public PyEditStub(IDocument doc, IEditorInput pydevFileEditorInputStub) { + this(doc, pydevFileEditorInputStub, new PythonNatureStub(), null); + } + + public PyEditStub(IDocument doc, IEditorInput pydevFileEditorInputStub, IPythonNature nature, File file) { + this.doc = doc; + this.pydevFileEditorInputStub = pydevFileEditorInputStub; + this.nature = nature; + this.file = file; + } + + @Override + public IEditorInput getEditorInput() { + return pydevFileEditorInputStub; + } + + @Override + public IPythonNature getPythonNature() { + return nature; + } + + public void setParser(IPyParser parser) { + throw new RuntimeException("Not implemented"); + } + + @Override + public Object getParser() { + return null; + } + + @Override + public void parserChanged(ISimpleNode root, IAdaptable file, IDocument doc, long docModificationStamp) { + this.parserChanged += 1; + } + + @Override + public void parserError(Throwable error, IAdaptable file, IDocument doc) { + throw new RuntimeException("Not implemented"); + } + + @Override + public Map getCache() { + return this.cache; + } + + @Override + public T getAdapter(Class adapter) { + return null; + } + + @Override + public boolean hasSameInput(IBaseEditor edit) { + if (this == edit) { + throw new RuntimeException( + "Cannot compare when it's the same... it should change the document in this case"); + } + if (edit.getEditorInput() == getEditorInput()) { + return true; + } + return false; + } + + @Override + public IDocument getDocument() { + return doc; + } + + public void setDocument(IDocument doc) { + this.doc = doc; + } + + public void setInput(PydevFileEditorInputStub input) { + this.pydevFileEditorInputStub = input; + } + + @Override + public void setStatusLineErrorMessage(String msg) { + throw new RuntimeException("Not implemented"); + } + + @Override + public IGrammarVersionProvider getGrammarVersionProvider() { + return this.getPythonNature(); + } + + @Override + public IIndentPrefs getIndentPrefs() { + return DefaultIndentPrefs.get(null); + } + + @Override + public Object getFormatStd() { + throw new RuntimeException("Not implemented"); + } + + @Override + public void addModelListener(IModelListener modelListener) { + throw new RuntimeException("Not implemented"); + } + + @Override + public void removeModelListener(IModelListener modelListener) { + throw new RuntimeException("Not implemented"); + } + + @Override + public int getGrammarVersion() throws MisconfigurationException { + throw new RuntimeException("Not implemented"); + } + + @Override + public AdditionalGrammarVersionsToCheck getAdditionalGrammarVersions() throws MisconfigurationException { + throw new RuntimeException("Not implemented"); + } + + @Override + public IProject getProject() { + return this.nature.getProject(); + } + + @Override + public Object getAST() { + try { + ParseOutput output = PyParser.parseFull(new ParserInfo(doc, nature)); + return output.ast; // It's ok if we have errors, return what we have. + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public File getEditorFile() { + return file; + } + + @Override + public long getAstModificationTimeStamp() { + return 0; + } + + @Override + public IFile getIFile() { + return iFile; + } + + @Override + public void addOfflineActionListener(String key, Object action, String description, boolean needsEnter) { + throw new RuntimeException("Not implemented"); + } + + @Override + public boolean isCythonFile() { + return false; + } + + @Override + public ICoreTextSelection getTextSelection() { + throw new RuntimeException("Not implemented"); + } + + @Override + public int getPrintMarginColums() { + throw new RuntimeException("Not implemented"); + } +} diff --git a/plugins/org.python.pydev/tests/org/python/pydev/parser/PydevFileEditorInputStub.java b/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/PydevFileEditorInputStub.java similarity index 95% rename from plugins/org.python.pydev/tests/org/python/pydev/parser/PydevFileEditorInputStub.java rename to plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/PydevFileEditorInputStub.java index 31eab57f67..84da04cbf2 100644 --- a/plugins/org.python.pydev/tests/org/python/pydev/parser/PydevFileEditorInputStub.java +++ b/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/PydevFileEditorInputStub.java @@ -4,7 +4,7 @@ * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ -package org.python.pydev.parser; +package org.python.pydev.ast.codecompletion.revisited; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.IEditorInput; diff --git a/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/TextViewerStub.java b/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/TextViewerStub.java new file mode 100644 index 0000000000..92653f0ca5 --- /dev/null +++ b/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/TextViewerStub.java @@ -0,0 +1,423 @@ +package org.python.pydev.ast.codecompletion.revisited; + +import org.eclipse.jface.text.IAutoEditStrategy; +import org.eclipse.jface.text.IAutoIndentStrategy; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IEventConsumer; +import org.eclipse.jface.text.IFindReplaceTarget; +import org.eclipse.jface.text.IPainter; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.IRewriteTarget; +import org.eclipse.jface.text.ITextDoubleClickStrategy; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextInputListener; +import org.eclipse.jface.text.ITextListener; +import org.eclipse.jface.text.ITextOperationTarget; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.ITextViewerExtension; +import org.eclipse.jface.text.ITextViewerExtension2; +import org.eclipse.jface.text.IUndoManager; +import org.eclipse.jface.text.IViewportListener; +import org.eclipse.jface.text.TextPresentation; +import org.eclipse.jface.viewers.IPostSelectionProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Control; + +public class TextViewerStub + implements ITextViewer, ITextViewerExtension, ITextViewerExtension2, IPostSelectionProvider { + private final IDocument doc; + + public TextViewerStub(IDocument doc) { + this.doc = doc; + } + + @Override + public void setVisibleRegion(int offset, int length) { + // TODO Auto-generated method stub + + } + + @Override + public void setUndoManager(IUndoManager undoManager) { + // TODO Auto-generated method stub + + } + + @Override + public void setTopIndex(int index) { + // TODO Auto-generated method stub + + } + + @Override + public void setTextHover(ITextHover textViewerHover, String contentType) { + // TODO Auto-generated method stub + + } + + @Override + public void setTextDoubleClickStrategy(ITextDoubleClickStrategy strategy, String contentType) { + // TODO Auto-generated method stub + + } + + @Override + public void setTextColor(Color color, int offset, int length, boolean controlRedraw) { + // TODO Auto-generated method stub + + } + + @Override + public void setTextColor(Color color) { + // TODO Auto-generated method stub + + } + + @Override + public void setSelectedRange(int offset, int length) { + // TODO Auto-generated method stub + + } + + @Override + public void setIndentPrefixes(String[] indentPrefixes, String contentType) { + // TODO Auto-generated method stub + + } + + @Override + public void setEventConsumer(IEventConsumer consumer) { + // TODO Auto-generated method stub + + } + + @Override + public void setEditable(boolean editable) { + // TODO Auto-generated method stub + + } + + @Override + public void setDocument(IDocument document, int modelRangeOffset, int modelRangeLength) { + // TODO Auto-generated method stub + + } + + @Override + public void setDocument(IDocument document) { + // TODO Auto-generated method stub + + } + + @Override + public void setDefaultPrefixes(String[] defaultPrefixes, String contentType) { + // TODO Auto-generated method stub + + } + + @Override + public void setAutoIndentStrategy(IAutoIndentStrategy strategy, String contentType) { + // TODO Auto-generated method stub + + } + + @Override + public void revealRange(int offset, int length) { + // TODO Auto-generated method stub + + } + + @Override + public void resetVisibleRegion() { + // TODO Auto-generated method stub + + } + + @Override + public void resetPlugins() { + // TODO Auto-generated method stub + + } + + @Override + public void removeViewportListener(IViewportListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void removeTextListener(ITextListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void removeTextInputListener(ITextInputListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public boolean overlapsWithVisibleRegion(int offset, int length) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isEditable() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void invalidateTextPresentation() { + // TODO Auto-generated method stub + + } + + @Override + public IRegion getVisibleRegion() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getTopInset() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getTopIndexStartOffset() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getTopIndex() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public StyledText getTextWidget() { + // TODO Auto-generated method stub + return null; + } + + @Override + public ITextOperationTarget getTextOperationTarget() { + // TODO Auto-generated method stub + return null; + } + + @Override + public ISelectionProvider getSelectionProvider() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Point getSelectedRange() { + // TODO Auto-generated method stub + return null; + } + + @Override + public IFindReplaceTarget getFindReplaceTarget() { + // TODO Auto-generated method stub + return null; + } + + @Override + public IDocument getDocument() { + // TODO Auto-generated method stub + return doc; + } + + @Override + public int getBottomIndexEndOffset() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getBottomIndex() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void changeTextPresentation(TextPresentation presentation, boolean controlRedraw) { + // TODO Auto-generated method stub + + } + + @Override + public void addViewportListener(IViewportListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void addTextListener(ITextListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void addTextInputListener(ITextInputListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void activatePlugins() { + // TODO Auto-generated method stub + + } + + @Override + public void invalidateTextPresentation(int offset, int length) { + // TODO Auto-generated method stub + + } + + @Override + public void setTextHover(ITextHover textViewerHover, String contentType, int stateMask) { + // TODO Auto-generated method stub + + } + + @Override + public void removeTextHovers(String contentType) { + // TODO Auto-generated method stub + + } + + @Override + public ITextHover getCurrentTextHover() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Point getHoverEventLocation() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void prependAutoEditStrategy(IAutoEditStrategy strategy, String contentType) { + // TODO Auto-generated method stub + + } + + @Override + public void removeAutoEditStrategy(IAutoEditStrategy strategy, String contentType) { + // TODO Auto-generated method stub + + } + + @Override + public void addPainter(IPainter painter) { + // TODO Auto-generated method stub + + } + + @Override + public void removePainter(IPainter painter) { + // TODO Auto-generated method stub + + } + + @Override + public void addSelectionChangedListener(ISelectionChangedListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public ISelection getSelection() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void setSelection(ISelection selection) { + // TODO Auto-generated method stub + + } + + @Override + public void addPostSelectionChangedListener(ISelectionChangedListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void removePostSelectionChangedListener(ISelectionChangedListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void prependVerifyKeyListener(VerifyKeyListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void appendVerifyKeyListener(VerifyKeyListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void removeVerifyKeyListener(VerifyKeyListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public Control getControl() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setMark(int offset) { + // TODO Auto-generated method stub + + } + + @Override + public int getMark() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void setRedraw(boolean redraw) { + // TODO Auto-generated method stub + + } + + @Override + public IRewriteTarget getRewriteTarget() { + // TODO Auto-generated method stub + return null; + } +} diff --git a/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/javaintegration/AbstractWorkbenchTestCase.java b/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/javaintegration/AbstractWorkbenchTestCase.java index c2ad8fa821..bdc840448e 100644 --- a/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/javaintegration/AbstractWorkbenchTestCase.java +++ b/plugins/org.python.pydev/tests_completions/org/python/pydev/ast/codecompletion/revisited/javaintegration/AbstractWorkbenchTestCase.java @@ -112,7 +112,9 @@ public Boolean call(Tuple, List> arg) { NullProgressMonitor monitor = new NullProgressMonitor(); - createJythonInterpreterManager(monitor); + if (TestDependent.JYTHON_JAR_LOCATION != null) { + createJythonInterpreterManager(monitor); + } createPythonInterpreterManager(monitor); } } @@ -571,7 +573,7 @@ protected void createJunitJar(NullProgressMonitor monitor, IProject project) thr if (!junitJarFile.exists()) { FileUtils.copyFile(TestDependent.TEST_PYDEV_PLUGIN_LOC + - "tests_completions/org/python/pydev/editor/codecompletion/revisited/javaintegration/junit.jar", + "tests_completions/org/python/pydev/ast/codecompletion/revisited/javaintegration/junit.jar", junitJarLocatioon); } project.refreshLocal(IResource.DEPTH_INFINITE, monitor); @@ -587,7 +589,7 @@ protected void createGrinderJar(NullProgressMonitor monitor, IProject project) t if (!grinderJarFile.exists()) { FileUtils.copyFile(TestDependent.TEST_PYDEV_PLUGIN_LOC + - "tests_completions/org/python/pydev/editor/codecompletion/revisited/javaintegration/grinder.jar", + "tests_completions/org/python/pydev/ast/codecompletion/revisited/javaintegration/grinder.jar", grinderJarLocatioon); } project.refreshLocal(IResource.DEPTH_INFINITE, monitor);