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/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 index 6b4da4c134..afb6bd1e76 100644 --- 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 @@ -1,21 +1,21 @@ package com.python.pydev.analysis.refactoring.tdd; import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.Region; +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; -import org.python.pydev.core.templates.PyDocumentTemplateContext; public class TemplateInfo { public Template fTemplate; - public PyDocumentTemplateContext fContext; - public Region fRegion; + public TemplateContext fContext; + public IRegion fRegion; - public TemplateInfo(Template template, PyDocumentTemplateContext context, Region region) { + public TemplateInfo(Template template, TemplateContext context, IRegion region) { this.fTemplate = template; this.fContext = context; this.fRegion = region; @@ -32,7 +32,7 @@ public TemplateInfo(Template template, PyDocumentTemplateContext context, Region protected final int getReplaceOffset() { int start; if (fContext instanceof DocumentTemplateContext) { - DocumentTemplateContext docContext = fContext; + DocumentTemplateContext docContext = (DocumentTemplateContext) fContext; start = docContext.getStart(); } else { start = fRegion.getOffset(); @@ -51,7 +51,7 @@ protected final int getReplaceOffset() { protected final int getReplaceEndOffset() { int end; if (fContext instanceof DocumentTemplateContext) { - DocumentTemplateContext docContext = fContext; + DocumentTemplateContext docContext = (DocumentTemplateContext) fContext; end = docContext.getEnd(); } else { end = fRegion.getOffset() + fRegion.getLength(); 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 050fc53a91..ef7159d19c 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 @@ -153,7 +153,6 @@ def m1(self): String label = "Create m2 method at Foo"; check(s, expected, label); - } private void check(String s, String expected, String label) throws MisconfigurationException { 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 index 066ddb2d32..8957aa86c0 100644 --- 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 @@ -6,15 +6,17 @@ */ 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.CodeCompletionTestsBase; import org.python.pydev.ast.codecompletion.revisited.PyEditStub; import org.python.pydev.ast.codecompletion.revisited.PydevFileEditorInputStub; import org.python.pydev.ast.codecompletion.revisited.modules.CompiledModule; @@ -27,11 +29,15 @@ 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 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; @@ -40,7 +46,7 @@ * @author Fabio * */ -public class TddCodeGenerationQuickFixParticipantWithMarkersTest extends CodeCompletionTestsBase { +public class TddCodeGenerationQuickFixParticipantWithMarkersTest extends AnalysisTestsBase { public static void main(String[] args) { @@ -125,6 +131,39 @@ def m1(self): 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 + """; + String expected = """ + """; + String stringForRegion = "some_module"; + String expectedLabel = "Create NewClass class"; + int markerType = IAnalysisPreferences.TYPE_UNRESOLVED_IMPORT; + + check(initial, expected, stringForRegion, expectedLabel, markerType); + } + public void testCreateMethod() throws Exception { String initial = """ print i @@ -135,13 +174,24 @@ class Foo(object): def m1(self): self.m2 """; - System.out.println(initial); String expected = """ - """; - String stringForRegion = "self.m2"; + 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 = IAnalysisPreferences.TYPE_UNDEFINED_VARIABLE; + int markerType = -1; // No marker check(initial, expected, stringForRegion, expectedLabel, markerType); } @@ -153,20 +203,72 @@ private void check(String initial, String expected, String stringForRegion, Stri Document doc = new Document(initial); - TddQuickFixFromMarkersParticipant participant = new TddQuickFixFromMarkersParticipant(); - int offset = initial.length(); - PySelection ps = new PySelection(doc, offset); 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(); + PydevFileEditorInputStub editorInputStub = new PydevFileEditorInputStub(); + IPyEdit edit = new PyEditStub(doc, editorInputStub, nature); + + File file = new File(TestDependent.TEST_PYSRC_TESTING_LOC + "extendable/check_analysis_and_tdd.py"); + + 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); + } + + 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 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(); - List props = new ArrayList<>(); PydevFileEditorInputStub editorInputStub = new PydevFileEditorInputStub(); IPyEdit edit = new PyEditStub(doc, editorInputStub, nature); + + File file = new File(TestDependent.TEST_PYSRC_TESTING_LOC + "extendable/check_analysis_and_tdd.py"); + + 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(); 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/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/tests/org/python/pydev/editor/correctionassist/heuristics/AssistSurroundWithTest.java b/plugins/org.python.pydev/tests/org/python/pydev/editor/correctionassist/heuristics/AssistSurroundWithTest.java index d4c9ec3419..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,15 +8,13 @@ import java.util.List; -import org.eclipse.core.runtime.AssertionFailedException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.templates.TemplateProposal; -import org.python.pydev.ast.codecompletion.revisited.CodeCompletionTestsBase; 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; @@ -82,14 +80,8 @@ public void testSurround2() throws Exception { } private void apply(ICompletionProposalHandle iCompletionProposalHandle, IDocument doc) { - TemplateProposal p = (TemplateProposal) iCompletionProposalHandle; - try { - p.apply(CodeCompletionTestsBase.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 {