Skip to content

Commit

Permalink
Moved AssistAssign to non-ui plugin.
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioz committed Sep 22, 2024
1 parent 2c083f4 commit df32b13
Show file tree
Hide file tree
Showing 25 changed files with 407 additions and 370 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,12 @@

import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IEditorActionDelegate;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.texteditor.ITextEditor;
import org.python.pydev.ast.refactoring.RefactoringInfo;
import org.python.pydev.core.IPyEdit;
import org.python.pydev.core.log.Log;
import org.python.pydev.shared_core.SharedCorePlugin;
import org.python.pydev.shared_core.code_completion.ICompletionProposalHandle;
import org.python.pydev.shared_ui.EditorUtils;

public abstract class AbstractPyCreateAction extends Action implements IEditorActionDelegate {
public abstract class AbstractPyCreateAction {

public static final int LOCATION_STRATEGY_BEFORE_CURRENT = 0; //before the current method (in the same level)
public static final int LOCATION_STRATEGY_END = 1; //end of file or end of class
Expand All @@ -36,52 +25,6 @@ public void setActiveEditor(IAction action, IPyEdit edit) {
this.targetEditor = edit;
}

@Override
public void setActiveEditor(IAction action, IEditorPart targetEditor) {
if (targetEditor instanceof ITextEditor) {
if (targetEditor instanceof IPyEdit) {
this.targetEditor = (IPyEdit) targetEditor;
} else {
this.targetEditor = null;
Log.log(new RuntimeException("Editor not a PyEdit."));
}
}
}

@Override
public void selectionChanged(IAction action, ISelection selection) {
}

/*
* (non-Javadoc)
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
*/
@Override
public void run(IAction action) {
if (targetEditor == null) {
Status status = SharedCorePlugin.makeStatus(IStatus.ERROR, "Unable to do refactoring.", null);
ErrorDialog.openError(EditorUtils.getShell(), "Unable to do refactoring.",
"Target editor is null (not PyEdit).", status);
return;
}

try {
RefactoringInfo refactoringInfo = new RefactoringInfo(targetEditor);
execute(refactoringInfo, LOCATION_STRATEGY_BEFORE_CURRENT);
} catch (Throwable e) {
Log.log(e);
Throwable initial = e;
while (e.getCause() != null) {
e = e.getCause();
}
//get the root cause
Status status = SharedCorePlugin.makeStatus(IStatus.ERROR, "Error making refactoring", initial);
ErrorDialog.openError(EditorUtils.getShell(), "Error making refactoring", e.getMessage(), status);
}
}

public abstract void execute(RefactoringInfo refactoringInfo, int locationStrategyBeforeCurrent);

public abstract ICompletionProposalHandle createProposal(RefactoringInfo refactoringInfo, String actTok,
int locationStrategy, List<String> parametersAfterCall);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,102 +9,34 @@
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
import org.eclipse.jface.text.templates.GlobalTemplateVariables;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.python.pydev.ast.adapters.IClassDefAdapter;
import org.python.pydev.ast.adapters.ModuleAdapter;
import org.python.pydev.ast.adapters.offsetstrategy.BeginOffset;
import org.python.pydev.ast.adapters.offsetstrategy.EndOffset;
import org.python.pydev.ast.adapters.offsetstrategy.IOffsetStrategy;
import org.python.pydev.ast.refactoring.RefactoringInfo;
import org.python.pydev.ast.assist_assign.AssistAssign;
import org.python.pydev.core.docutils.PySelection;
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.editor.PyEdit;
import org.python.pydev.editor.correctionassist.heuristics.AssistAssign;
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;
import org.python.pydev.shared_ui.EditorUtils;

public abstract class AbstractPyCreateClassOrMethodOrField extends AbstractPyCreateAction {

public abstract String getCreationStr();

@Override
public void execute(RefactoringInfo refactoringInfo, int locationStrategy) {
try {
String creationStr = this.getCreationStr();
final String asTitle = StringUtils.getWithFirstUpper(creationStr);

PySelection pySelection = refactoringInfo.getPySelection();
Tuple<String, Integer> currToken = pySelection.getCurrToken();
String actTok = currToken.o1;
List<String> parametersAfterCall = null;
if (actTok.length() == 0) {
InputDialog dialog = new InputDialog(EditorUtils.getShell(), asTitle + " name",
"Please enter the name of the " + asTitle + " to be created.", "", new IInputValidator() {

@Override
public String isValid(String newText) {
if (newText.length() == 0) {
return "The " + asTitle + " name may not be empty";
}
if (StringUtils.containsWhitespace(newText)) {
return "The " + asTitle + " name may not contain whitespaces.";
}
return null;
}
});
if (dialog.open() != InputDialog.OK) {
return;
}
actTok = dialog.getValue();
} else {
parametersAfterCall = pySelection.getParametersAfterCall(currToken.o2 + actTok.length());

}

execute(refactoringInfo, actTok, parametersAfterCall, locationStrategy);
} catch (BadLocationException e) {
Log.log(e);
}
}

/**
* When executed it'll create a proposal and apply it.
*/
/*default*/void execute(RefactoringInfo refactoringInfo, String actTok, List<String> parametersAfterCall,
int locationStrategy) {
try {
ICompletionProposalHandle proposal = createProposal(refactoringInfo, actTok, locationStrategy,
parametersAfterCall);
if (proposal != null) {
if (proposal instanceof ICompletionProposalExtension2) {
ICompletionProposalExtension2 extension2 = (ICompletionProposalExtension2) proposal;
extension2.apply(((PyEdit) targetEditor).getPySourceViewer(), '\n', 0, 0);
} else {
proposal.apply(refactoringInfo.getDocument());
}
}

} catch (Exception e) {
Log.log(e);
}
}
protected abstract String getDefaultActTok();

protected ICompletionProposalHandle createProposal(PySelection pySelection, String source,
Tuple<Integer, String> offsetAndIndent) {
Expand Down Expand Up @@ -176,10 +108,8 @@ protected ICompletionProposalHandle createProposal(PySelection pySelection, Stri
//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!
TemplateContextType contextType = new TemplateContextType();
contextType.addResolver(new GlobalTemplateVariables.Cursor()); //We do want the cursor thought.
PyDocumentTemplateContext context = PyDocumentTemplateContext.createContext(contextType,
targetEditor, region, indent);
PyDocumentTemplateContext context = PyDocumentTemplateContext.createContextWithCursor(targetEditor, region,
indent);

Template template = new Template("Create " + creationStr, "Create " + creationStr, "", source, true);
ICompletionProposalHandle templateProposal = CompletionProposalFactory.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@

public class NullPyCreateAction extends AbstractPyCreateAction {

@Override
public void execute(RefactoringInfo refactoringInfo, int locationStrategyBeforeCurrent) {

}

@Override
public ICompletionProposalHandle createProposal(RefactoringInfo refactoringInfo, String actTok,
int locationStrategy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public String getCreationStr() {
return "class";
}

@Override
protected String getDefaultActTok() {
return "MyClass";
}

/**
* Returns a proposal that can be used to generate the code.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ public String getCreationStr() {
return "method";
}

@Override
protected String getDefaultActTok() {
if (createAs == FIELD) {
return "my_field";
}
if (createAs == CONSTANT) {
return "my_constant";
}
return "my_method";
}

/**
* Returns a proposal that can be used to generate the code.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.python.pydev.refactoring.tdd;

import java.util.List;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
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.shared_core.code_completion.ICompletionProposalHandle;
import org.python.pydev.shared_core.structure.Tuple;

public class ExecutePyCreate {

public static void execute(AbstractPyCreateClassOrMethodOrField action, RefactoringInfo refactoringInfo,
int locationStrategy) {
try {
PySelection pySelection = refactoringInfo.getPySelection();
Tuple<String, Integer> currToken = pySelection.getCurrToken();
String actTok = currToken.o1;
List<String> parametersAfterCall = null;
if (actTok.length() == 0) {
actTok = action.getDefaultActTok();
// String creationStr = this.getCreationStr();
// final String asTitle = StringUtils.getWithFirstUpper(creationStr);
// InputDialog dialog = new InputDialog(EditorUtils.getShell(), asTitle + " name",
// "Please enter the name of the " + asTitle + " to be created.", "", new IInputValidator() {
//
// @Override
// public String isValid(String newText) {
// if (newText.length() == 0) {
// return "The " + asTitle + " name may not be empty";
// }
// if (StringUtils.containsWhitespace(newText)) {
// return "The " + asTitle + " name may not contain whitespaces.";
// }
// return null;
// }
// });
// if (dialog.open() != InputDialog.OK) {
// return;
// }
// actTok = dialog.getValue();
} else {
parametersAfterCall = pySelection.getParametersAfterCall(currToken.o2 + actTok.length());

}

execute(action, refactoringInfo, actTok, parametersAfterCall, locationStrategy);
} catch (BadLocationException e) {
Log.log(e);
}
}

/**
* When executed it'll create a proposal and apply it.
*/
public static void execute(AbstractPyCreateClassOrMethodOrField action, RefactoringInfo refactoringInfo,
String actTok, List<String> parametersAfterCall,
int locationStrategy) {
try {
ICompletionProposalHandle proposal = action.createProposal(refactoringInfo, actTok, locationStrategy,
parametersAfterCall);
if (proposal != null) {
if (proposal instanceof ICompletionProposalExtension2) {
ICompletionProposalExtension2 extension2 = (ICompletionProposalExtension2) proposal;
extension2.apply(null, '\n', 0, 0);
} else {
proposal.apply(refactoringInfo.getDocument());
}
}

} catch (Exception e) {
Log.log(e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void testPyCreateClassInSameModule() throws Exception {
ICoreTextSelection selection = new CoreTextSelection(document, 0, 0);
RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER);

pyCreateClass.execute(info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);
ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);

assertContentsEqual("" +
"class MyClass(${object}):\n" +
Expand Down Expand Up @@ -95,7 +95,7 @@ public void testPyCreateClassInSameModule4() throws Exception {
ICoreTextSelection selection = new CoreTextSelection(document, document.getLength() - 5, 0);
RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER);

pyCreateClass.execute(info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);
ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);

assertContentsEqual("" +
"#=============\n" +
Expand Down Expand Up @@ -132,7 +132,7 @@ public void testPyCreateClassInSameModule5() throws Exception {
ICoreTextSelection selection = new CoreTextSelection(document, document.getLength() - 5, 0);
RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER);

pyCreateClass.execute(info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);
ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);

assertContentsEqual("" +
"a = 10\n" +
Expand Down Expand Up @@ -168,7 +168,7 @@ public void testPyCreateClassInSameModule6() throws Exception {
ICoreTextSelection selection = new CoreTextSelection(document, document.getLength() - 5, 0);
RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER);

pyCreateClass.execute(info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);
ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);

assertContentsEqual("" +
"a = 10\n" +
Expand Down Expand Up @@ -196,7 +196,7 @@ public void testPyCreateClassWithParameters() throws Exception {
ICoreTextSelection selection = new CoreTextSelection(document, 0, 0);
RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER);

pyCreateClass.execute(info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);
ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);

assertContentsEqual("" +
"class MyClass(${object}):\n" +
Expand All @@ -219,7 +219,7 @@ public void testPyCreateClassWithParameters2() throws Exception {
ICoreTextSelection selection = new CoreTextSelection(document, 0, 0);
RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER);

pyCreateClass.execute(info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);
ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);

assertContentsEqual("" +
"class MyClass(${object}):\n" +
Expand Down Expand Up @@ -248,7 +248,7 @@ public void testPyCreateClassInSameModule2() throws Exception {
ICoreTextSelection selection = new CoreTextSelection(document, source.length() - 4, 0);
RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER);

pyCreateClass.execute(info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);
ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);

assertContentsEqual("" +
"import foo\n" +
Expand Down Expand Up @@ -280,7 +280,7 @@ public void testPyCreateClassInSameModule3() throws Exception {
ICoreTextSelection selection = new CoreTextSelection(document, source.length() - 4, 0);
RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER);

pyCreateClass.execute(info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);
ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_BEFORE_CURRENT);

assertContentsEqual("" +
"import foo\n" +
Expand Down Expand Up @@ -317,7 +317,7 @@ public void testPyCreateClassEndOfFile() throws Exception {
ICoreTextSelection selection = new CoreTextSelection(document, source.length() - 4, 0);
RefactoringInfo info = new RefactoringInfo(document, selection, PY_27_ONLY_GRAMMAR_VERSION_PROVIDER);

pyCreateClass.execute(info, PyCreateClass.LOCATION_STRATEGY_END);
ExecutePyCreate.execute(pyCreateClass, info, PyCreateClass.LOCATION_STRATEGY_END);

assertContentsEqual("" +
"import foo\n" +
Expand Down
Loading

0 comments on commit df32b13

Please sign in to comment.