private void checkIt( SimpleNode simpleNode, SourceToken token, String rep, String relativeImport, String originalRep) { assertEquals(rep, token.getRepresentation()); assertSame(simpleNode, token.getAst()); assertEquals(relativeImport, token.getAsRelativeImport(MODULE_NAME)); assertEquals(originalRep, token.getOriginalRep()); }
/* (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; }
/** @see org.python.pydev.core.ILocalScope#getLocalTokens(int, int, boolean) */ public IToken[] getLocalTokens(int endLine, int col, boolean onlyArgs) { Set<SourceToken> comps = new HashSet<SourceToken>(); for (Iterator<SimpleNode> iter = this.scope.iterator(); iter.hasNext(); ) { SimpleNode element = iter.next(); stmtType[] body = null; if (element instanceof FunctionDef) { FunctionDef f = (FunctionDef) element; final argumentsType args = f.args; for (int i = 0; i < args.args.length; i++) { String s = NodeUtils.getRepresentationString(args.args[i]); comps.add(new SourceToken(args.args[i], s, "", "", "", IToken.TYPE_PARAM)); } if (args.vararg != null) { String s = NodeUtils.getRepresentationString(args.vararg); comps.add(new SourceToken(args.vararg, s, "", "", "", IToken.TYPE_PARAM)); } if (args.kwarg != null) { String s = NodeUtils.getRepresentationString(args.kwarg); comps.add(new SourceToken(args.kwarg, s, "", "", "", IToken.TYPE_PARAM)); } if (args.kwonlyargs != null) { for (int i = 0; i < args.kwonlyargs.length; i++) { String s = NodeUtils.getRepresentationString(args.kwonlyargs[i]); comps.add(new SourceToken(args.kwonlyargs[i], s, "", "", "", IToken.TYPE_PARAM)); } } if (onlyArgs) { continue; } body = f.body; } else if (element instanceof ClassDef && !iter.hasNext()) { ClassDef classDef = (ClassDef) element; body = classDef.body; } if (body != null) { try { for (int i = 0; i < body.length; i++) { GlobalModelVisitor visitor = new GlobalModelVisitor(GlobalModelVisitor.GLOBAL_TOKENS, "", false, true); stmtType stmt = body[i]; if (stmt == null) { continue; } stmt.accept(visitor); List<IToken> t = visitor.tokens; for (Iterator<IToken> iterator = t.iterator(); iterator.hasNext(); ) { SourceToken tok = (SourceToken) iterator.next(); // if it is found here, it is a local type tok.type = IToken.TYPE_LOCAL; if (tok.getAst().beginLine <= endLine) { comps.add(tok); } } } } catch (Exception e) { Log.log(e); } } } return comps.toArray(new SourceToken[0]); }
/** * adds a message for something that was not used * * @param node the node representing the scope being closed when adding the unused message */ public void addUnusedMessage(SimpleNode node, Found f) { for (GenAndTok g : f) { if (g.generator instanceof SourceToken) { SimpleNode ast = ((SourceToken) g.generator).getAst(); // it can be an unused import if (ast instanceof Import || ast instanceof ImportFrom) { if (AbstractVisitor.isWildImport(ast)) { addMessage(IAnalysisPreferences.TYPE_UNUSED_WILD_IMPORT, g.generator, g.tok); } else if (!(g.generator instanceof ImportPartSourceToken)) { addMessage(IAnalysisPreferences.TYPE_UNUSED_IMPORT, g.generator, g.tok); } continue; // finish it... } } // or unused variable // we have to check if this is a name we should ignore if (startsWithNamesToIgnore(g)) { int type = IAnalysisPreferences.TYPE_UNUSED_VARIABLE; if (g.tok instanceof SourceToken) { SourceToken t = (SourceToken) g.tok; SimpleNode ast = t.getAst(); if (ast instanceof NameTok) { NameTok n = (NameTok) ast; if (n.ctx == NameTok.KwArg || n.ctx == NameTok.VarArg || n.ctx == NameTok.KeywordName) { type = IAnalysisPreferences.TYPE_UNUSED_PARAMETER; } } else if (ast instanceof Name) { Name n = (Name) ast; if (n.ctx == Name.Param || n.ctx == Name.KwOnlyParam) { type = IAnalysisPreferences.TYPE_UNUSED_PARAMETER; } } } boolean addMessage = true; if (type == IAnalysisPreferences.TYPE_UNUSED_PARAMETER) { // just add unused parameters in methods that have some content (not only 'pass' and // 'strings') if (node instanceof FunctionDef) { addMessage = false; FunctionDef def = (FunctionDef) node; for (stmtType b : def.body) { if (b instanceof Pass) { continue; } if (b instanceof Expr) { Expr expr = (Expr) b; if (expr.value instanceof Str) { continue; } } addMessage = true; break; } } } // END if (type == IAnalysisPreferences.TYPE_UNUSED_PARAMETER) if (addMessage) { addMessage(type, g.generator, g.tok); } } } }