use of org.python.pydev.shared_core.code_completion.ICompletionProposalHandle in project Pydev by fabioz.
the class AbstractPyCreateClassOrMethodOrField method createProposal.
protected ICompletionProposalHandle createProposal(PySelection pySelection, String source, Tuple<Integer, String> offsetAndIndent, boolean requireEmptyLines, Pass replacePassStatement) {
int offset;
int len;
String indent = offsetAndIndent.o2;
if (replacePassStatement == null) {
len = 0;
offset = offsetAndIndent.o1;
if (requireEmptyLines) {
int checkLine = pySelection.getLineOfOffset(offset);
int lineOffset = pySelection.getLineOffset(checkLine);
// Make sure we have 2 spaces from the last thing written.
if (lineOffset == offset) {
// it'll be added to the start of the line, so, we have to analyze the previous line to know if we'll need
// to new lines at the start.
checkLine--;
}
if (checkLine >= 0) {
// It'll be added to the current line, so, check the current line and the previous line to know about spaces.
String line = pySelection.getLine(checkLine);
if (line.trim().length() >= 1) {
source = "\n\n" + source;
} else if (checkLine > 1) {
line = pySelection.getLine(checkLine - 1);
if (line.trim().length() > 0) {
source = "\n" + source;
}
}
}
// If we have a '\n', all is OK (all contents after a \n will be indented)
if (!source.startsWith("\n")) {
try {
// Ok, it doesn't start with a \n, that means we have to check the line indentation where it'll
// be added and make sure things are correct (eventually adding a new line or just fixing the indent).
String lineContentsToCursor = pySelection.getLineContentsToCursor(offset);
if (lineContentsToCursor.length() > 0) {
source = "\n" + source;
} else {
source = indent + source;
}
} catch (BadLocationException e) {
source = "\n" + source;
}
}
}
} else {
offset = pySelection.getAbsoluteCursorOffset(replacePassStatement.beginLine - 1, replacePassStatement.beginColumn - 1);
// pass.len
len = 4;
if (requireEmptyLines) {
source = "\n\n" + source;
}
}
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!
TemplateContextType contextType = new TemplateContextType();
// We do want the cursor thought.
contextType.addResolver(new GlobalTemplateVariables.Cursor());
PyDocumentTemplateContext context = PyDocumentTemplateContext.createContext(contextType, ((PyEdit) targetEditor).getPySourceViewer(), 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);
}
}
use of org.python.pydev.shared_core.code_completion.ICompletionProposalHandle in project Pydev by fabioz.
the class TddCodeGenerationQuickFixParticipant method getTddProps.
public List<ICompletionProposalHandle> getTddProps(PySelection ps, IImageCache imageCache, File f, IPythonNature nature, PyEdit edit, int offset, List<ICompletionProposalHandle> ret) {
if (ret == null) {
ret = new ArrayList<ICompletionProposalHandle>();
}
// Additional option: Generate markers for 'self.' accesses
int lineOfOffset = ps.getLineOfOffset(offset);
String lineContents = ps.getLine(lineOfOffset);
// Additional option: Generate methods for function calls
List<TddPossibleMatches> callsAtLine = ps.getTddPossibleMatchesAtLine();
if (callsAtLine.size() > 0) {
// Make sure we don't check the same thing twice.
Map<String, TddPossibleMatches> callsToCheck = new HashMap<String, TddPossibleMatches>();
for (TddPossibleMatches call : callsAtLine) {
String callString = call.initialPart + call.secondPart;
callsToCheck.put(callString, call);
}
CONTINUE_FOR: for (Map.Entry<String, TddPossibleMatches> 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();
ItemPointer[] pointers = null;
PySelection callPs = null;
TddPossibleMatches lastPossibleMatchNotFound = possibleMatch;
for (int i = 0; i < 10; i++) {
// more than 10 attribute accesses in a line? No way!
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<TddPossibleMatches> 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());
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);
if (((pointers != null && pointers.length > 0) || StringUtils.count(possibleMatch.full, '.') <= 1)) {
break;
}
}
if (pointers == null || callPs == null) {
continue CONTINUE_FOR;
}
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();
// +1 for the dot removed too.
absoluteCursorOffset = absoluteCursorOffset - (1 + methodToCreate.length());
PySelection newSelection = new PySelection(callPs.getDoc(), absoluteCursorOffset);
checkCreationBasedOnFoundPointers(edit, callPs, ret, possibleMatch, pointers, methodToCreate, newSelection, nature);
continue CONTINUE_FOR;
}
if (pointers.length >= 1) {
// the __init__ or something at the class level).
if (!checkInitCreation(edit, callPs, pointers, ret)) {
// 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);
}
}
} else if (pointers.length == 0) {
checkMethodCreationAtClass(edit, pyRefactoring, callWithoutParens, callPs, ret, lineContents, possibleMatch, f, nature);
}
} catch (Exception e) {
if (onGetTddPropsError != null) {
onGetTddPropsError.call(e);
}
Log.log(e);
}
}
}
return ret;
}
use of org.python.pydev.shared_core.code_completion.ICompletionProposalHandle in project Pydev by fabioz.
the class TddCodeGenerationQuickFixParticipantTest method testCreate2.
public void testCreate2() throws Exception {
String s = "" + "class MyClass(object):\n" + " pass\n" + "def testName():\n" + " obj = MyClass()\n" + " obj.unimplementedFunction(a.x, 'Some comment in ticket.')\n" + "";
TddCodeGenerationQuickFixParticipant participant = new TddCodeGenerationQuickFixParticipant();
Document doc = new Document(s);
List<ICompletionProposalHandle> props = participant.getTddProps(new PySelection(doc, s.length() - 1), null, null, nature, null, s.length() - 1, null);
TddRefactorCompletionInModule proposal = (TddRefactorCompletionInModule) assertContains("Create unimplementedFunction method at MyClass (__module_not_in_the_pythonpath__)", props.toArray(new ICompletionProposalHandle[0]));
// Todo: check result of apply as string is breaking!
List<String> parametersAfterCall = proposal.getParametersAfterCall();
FastStringBuffer createParametersList = AbstractPyCreateClassOrMethodOrField.createParametersList(parametersAfterCall);
assertEquals("${x}, ${param1}", createParametersList.toString());
}
use of org.python.pydev.shared_core.code_completion.ICompletionProposalHandle in project Pydev by fabioz.
the class TddCodeGenerationQuickFixParticipantTest method testCreateWithTypeAsParam.
public void testCreateWithTypeAsParam() throws Exception {
int usedGrammar = GRAMMAR_TO_USE_FOR_PARSING;
GRAMMAR_TO_USE_FOR_PARSING = PythonNature.LATEST_GRAMMAR_PY3_VERSION;
try {
String s = "" + "class Foo(object):\n" + " pass\n" + "\n" + "def method(foo: Foo = 'A'):\n" + " foo.bar()";
TddCodeGenerationQuickFixParticipant participant = new TddCodeGenerationQuickFixParticipant();
Document doc = new Document(s);
List<ICompletionProposalHandle> props = participant.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__)", props.toArray(new ICompletionProposalHandle[0]));
} finally {
GRAMMAR_TO_USE_FOR_PARSING = usedGrammar;
}
}
use of org.python.pydev.shared_core.code_completion.ICompletionProposalHandle in project Pydev by fabioz.
the class TddCodeGenerationQuickFixParticipantTest method testDontCreate.
public void testDontCreate() throws Exception {
String s = "" + "class MyClass(object):\n" + "\n" + " def unimplementedFunction(self):\n" + " pass\n" + "\n" + "def makeTestObj():\n" + " return MyClass()\n" + "\n" + "def makeTestObj2():\n" + " return makeTestObj()\n" + "\n" + "def testName():\n" + " obj = makeTestObj2()\n" + " obj.unimplementedFunction()\n" + "";
TddCodeGenerationQuickFixParticipant participant = new TddCodeGenerationQuickFixParticipant();
Document doc = new Document(s);
List<ICompletionProposalHandle> props = participant.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__)", props.toArray(new ICompletionProposalHandle[0]));
}
Aggregations