/** * Needed interface for adding the completions on a request * * @throws MisconfigurationException */ @SuppressWarnings("unchecked") public List getCodeCompletionProposals(ITextViewer viewer, CompletionRequest request) throws CoreException, BadLocationException, MisconfigurationException { ArrayList ret = new ArrayList(); request.showTemplates = false; // don't show templates in strings fillWithEpydocFields(viewer, request, ret); if (ret.size() == 0) { // if the size is not 0, it means that this is a place for the '@' stuff, and not for the // 'default' context for a string. ret.addAll( getStringGlobalsFromParticipants( request, CompletionStateFactory.getEmptyCompletionState( request.activationToken, request.nature, new CompletionCache()))); // the code-below does not work well because the module may not have an actual import for the // activation token, // so, it is useless too many times // if(request.activationToken.length() != 0){ // PyCodeCompletion completion = new PyCodeCompletion(); // ret.addAll(completion.getCodeCompletionProposals(viewer, request)); // } } fillWithParams(viewer, request, ret); return ret; }
/** * @return whether we're currently in a valid context for a code-completion request for this * engine. */ private boolean isValidCompletionContext(CompletionRequest request) { // this engine does not work 'correctly' in the default scope on: // - class definitions - after 'class' and before '(' // - method definitions - after 'def' and before '(' PySelection ps = request.getPySelection(); if (ps.isInDeclarationLine() != PySelection.DECLARATION_NONE) { return false; } return true; }
/** * Does a code-completion that will retrieve the all matches for some token in the module * * @throws MisconfigurationException */ private void doTokenCompletion( CompletionRequest request, ICodeCompletionASTManager astManager, List<Object> tokensList, String trimmed, ICompletionState state) throws CompletionRecursionException, MisconfigurationException { if (request.activationToken.endsWith(".")) { request.activationToken = request.activationToken.substring(0, request.activationToken.length() - 1); } final String initialActivationToken = request.activationToken; int parI = request.activationToken.indexOf('('); if (parI != -1) { request.activationToken = request.activationToken.substring(0, parI); } char[] toks = new char[] {'.', ' '}; List<Object> completions = new ArrayList<Object>(); boolean lookInGlobals = true; if (trimmed.equals("self") || FullRepIterable.getFirstPart(trimmed, toks).equals("self")) { lookInGlobals = !getSelfOrClsCompletions(request, tokensList, state, false, true, "self"); } else if (trimmed.equals("cls") || FullRepIterable.getFirstPart(trimmed, toks).equals("cls")) { lookInGlobals = !getSelfOrClsCompletions(request, tokensList, state, false, true, "cls"); } if (lookInGlobals) { state.setActivationToken(initialActivationToken); // Ok, looking for a token in globals. IToken[] comps = astManager.getCompletionsForToken(request.editorFile, request.doc, state); tokensList.addAll(Arrays.asList(comps)); } tokensList.addAll(completions); }
/* (non-Javadoc) * @see org.python.pydev.editor.codecompletion.IPyCodeCompletion#getCodeCompletionProposals(org.eclipse.jface.text.ITextViewer, org.python.pydev.editor.codecompletion.CompletionRequest) */ @SuppressWarnings("unchecked") public List getCodeCompletionProposals(ITextViewer viewer, CompletionRequest request) throws CoreException, BadLocationException, IOException, MisconfigurationException, PythonNatureWithoutProjectException { if (request.getPySelection().getCursorLineContents().trim().startsWith("#")) { // this may happen if the context is still not correctly computed in python return new PyStringCodeCompletion().getCodeCompletionProposals(viewer, request); } if (DebugSettings.DEBUG_CODE_COMPLETION) { Log.toLogFile(this, "Starting getCodeCompletionProposals"); Log.addLogLevel(); Log.toLogFile(this, "Request:" + request); } ArrayList<ICompletionProposal> ret = new ArrayList<ICompletionProposal>(); // let's see if we should do a code-completion in the current scope... if (!isValidCompletionContext(request)) { request.showTemplates = false; return ret; } try { IPythonNature pythonNature = request.nature; checkPythonNature(pythonNature); ICodeCompletionASTManager astManager = pythonNature.getAstManager(); if (astManager == null) { // we're probably still loading it. return ret; } // list of Object[], IToken or ICompletionProposal List<Object> tokensList = new ArrayList<Object>(); lazyStartShell(request); String trimmed = request.activationToken.replace('.', ' ').trim(); ImportInfo importsTipper = getImportsTipperStr(request); int line = request.doc.getLineOfOffset(request.documentOffset); IRegion region = request.doc.getLineInformation(line); ICompletionState state = new CompletionState( line, request.documentOffset - region.getOffset(), null, request.nature, request.qualifier); state.setIsInCalltip(request.isInCalltip); boolean importsTip = false; if (importsTipper.importsTipperStr.length() != 0) { // code completion in imports request.isInCalltip = false; // if found after (, but in an import, it is not a calltip! importsTip = doImportCompletion(request, astManager, tokensList, importsTipper); } else if (trimmed.length() > 0 && request.activationToken.indexOf('.') != -1) { // code completion for a token doTokenCompletion(request, astManager, tokensList, trimmed, state); } else { // go to globals doGlobalsCompletion(request, astManager, tokensList, state); } Map<String, IToken> alreadyChecked = new HashMap<String, IToken>(); String lowerCaseQual = request.qualifier.toLowerCase(); if (lowerCaseQual.length() >= PyCodeCompletionPreferencesPage.getArgumentsDeepAnalysisNChars()) { // this can take some time on the analysis, so, let's let the user choose on how many chars // does he // want to do the analysis... state.pushFindResolveImportMemoryCtx(); try { for (Iterator<Object> it = tokensList.listIterator(); it.hasNext(); ) { Object o = it.next(); if (o instanceof IToken) { it .remove(); // always remove the tokens from the list (they'll be re-added later // once they are filtered) IToken initialToken = (IToken) o; IToken token = initialToken; String strRep = token.getRepresentation(); IToken prev = alreadyChecked.get(strRep); if (prev != null) { if (prev.getArgs().length() != 0) { continue; // we already have a version with args... just keep going } } if (!strRep.toLowerCase().startsWith(lowerCaseQual)) { // just re-add it if we're going to actually use it (depending on the qualifier) continue; } while (token.isImportFrom()) { // we'll only add it here if it is an import from (so, set the flag to false for the // outer add) if (token.getArgs().length() > 0) { // if we already have the args, there's also no reason to do it (that's what we'll // do here) break; } ICompletionState s = state.getCopyForResolveImportWithActTok(token.getRepresentation()); s.checkFindResolveImportMemory(token); IToken token2 = astManager.resolveImport(s, token); if (token2 != null && initialToken != token2) { String args = token2.getArgs(); if (args.length() > 0) { // put it into the map (may override previous if it didn't have args) initialToken.setArgs(args); initialToken.setDocStr(token2.getDocStr()); if (initialToken instanceof SourceToken && token2 instanceof SourceToken) { SourceToken initialSourceToken = (SourceToken) initialToken; SourceToken token2SourceToken = (SourceToken) token2; initialSourceToken.setAst(token2SourceToken.getAst()); } break; } if (token2 == null || (token2.equals(token) && token2.getArgs().equals(token.getArgs()) && token2.getParentPackage().equals(token.getParentPackage()))) { break; } token = token2; } else { break; } } alreadyChecked.put(strRep, initialToken); } } } finally { state.popFindResolveImportMemoryCtx(); } } tokensList.addAll(alreadyChecked.values()); changeItokenToCompletionPropostal(viewer, request, ret, tokensList, importsTip, state); } catch (CompletionRecursionException e) { if (onCompletionRecursionException != null) { onCompletionRecursionException.call(e); } if (DebugSettings.DEBUG_CODE_COMPLETION) { Log.toLogFile(e); } // PydevPlugin.log(e); // ret.add(new CompletionProposal("",request.documentOffset,0,0,null,e.getMessage(), // null,null)); } if (DebugSettings.DEBUG_CODE_COMPLETION) { Log.remLogLevel(); Log.toLogFile(this, "Finished completion. Returned:" + ret.size() + " completions.\r\n"); } return ret; }
private Collection<CtxInsensitiveImportComplProposal> getThem( CompletionRequest request, ICompletionState state, boolean addAutoImport) throws MisconfigurationException { ArrayList<CtxInsensitiveImportComplProposal> completions = new ArrayList<CtxInsensitiveImportComplProposal>(); if (request.isInCalltip) { return completions; } HashSet<String> importedNames = getImportedNames(state); String qual = request.qualifier; if (qual.length() >= CodeCompletionPreferencesPage .getCharsForContextInsensitiveGlobalTokensCompletion()) { // at least n characters // required... String lowerQual = qual.toLowerCase(); String initialModule = request.resolveModule(); List<IInfo> tokensStartingWith = AdditionalProjectInterpreterInfo.getTokensStartingWith( qual, request.nature, AbstractAdditionalInterpreterInfo.TOP_LEVEL); FastStringBuffer realImportRep = new FastStringBuffer(); FastStringBuffer displayString = new FastStringBuffer(); FastStringBuffer tempBuf = new FastStringBuffer(); for (IInfo info : tokensStartingWith) { // there always must be a declaringModuleName String declaringModuleName = info.getDeclaringModuleName(); if (initialModule != null && declaringModuleName != null) { if (initialModule.equals(declaringModuleName)) { continue; } } boolean hasInit = false; if (declaringModuleName.endsWith(".__init__")) { declaringModuleName = declaringModuleName.substring( 0, declaringModuleName.length() - 9); // remove the .__init__ hasInit = true; } String rep = info.getName(); String lowerRep = rep.toLowerCase(); if (!lowerRep.startsWith(lowerQual) || importedNames.contains(rep)) { continue; } if (addAutoImport) { realImportRep.clear(); realImportRep.append("from "); realImportRep.append( AutoImportsPreferencesPage.removeImportsStartingWithUnderIfNeeded( declaringModuleName, tempBuf)); realImportRep.append(" import "); realImportRep.append(rep); } displayString.clear(); displayString.append(rep); displayString.append(" - "); displayString.append(declaringModuleName); if (hasInit) { displayString.append(".__init__"); } CtxInsensitiveImportComplProposal proposal = new CtxInsensitiveImportComplProposal( rep, request.documentOffset - request.qlen, request.qlen, realImportRep.length(), AnalysisPlugin.getImageForAutoImportTypeInfo(info), displayString.toString(), (IContextInformation) null, "", lowerRep.equals(lowerQual) ? IPyCompletionProposal.PRIORITY_LOCALS_1 : IPyCompletionProposal.PRIORITY_GLOBALS, realImportRep.toString()); completions.add(proposal); } } return completions; }