/** * Generates the cached tokens in the needed structure for a 'fast' search given a token * representation (creates a map with the name of the token --> token). */ private Map<String, IToken> internalGenerateCachedTokens( IPythonNature nature, ICompletionCache completionCache, String activationToken, boolean searchSameLevelMods) throws CompletionRecursionException { Map<String, IToken> cachedTokens = new HashMap<String, IToken>(); // if still not found, we have to get all the tokens, including regular and wild imports ICompletionState state = CompletionStateFactory.getEmptyCompletionState(nature, completionCache); ICodeCompletionASTManager astManager = nature.getAstManager(); state.setActivationToken(activationToken); // we don't want to gather builtins in this case. state.setBuiltinsGotten(true); IToken[] globalTokens = astManager.getCompletionsForModule(this, state, searchSameLevelMods); for (IToken token : globalTokens) { String rep = token.getRepresentation(); IToken t = cachedTokens.get(rep); if (t != null) { // only override tokens if it's a getattr that's not defined in the builtin module if (rep.equals("__getattribute__") || rep.equals("__getattr__")) { if (!isTokenFromBuiltins(token)) { cachedTokens.put(rep, token); } } } else { cachedTokens.put(rep, token); } } return cachedTokens; }
/** * Does a code-completion that will retrieve the globals in the module * * @throws MisconfigurationException */ private void doGlobalsCompletion( CompletionRequest request, ICodeCompletionASTManager astManager, List<Object> tokensList, ICompletionState state) throws CompletionRecursionException, MisconfigurationException { state.setActivationToken(request.activationToken); if (DebugSettings.DEBUG_CODE_COMPLETION) { Log.toLogFile(this, "astManager.getCompletionsForToken"); Log.addLogLevel(); } IToken[] comps = astManager.getCompletionsForToken(request.editorFile, request.doc, state); if (DebugSettings.DEBUG_CODE_COMPLETION) { Log.remLogLevel(); Log.toLogFile(this, "END astManager.getCompletionsForToken"); } tokensList.addAll(Arrays.asList(comps)); tokensList.addAll(getGlobalsFromParticipants(request, state)); }
/** * 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); }
@Override public boolean isInGlobalTokens( String tok, IPythonNature nature, ICompletionCache completionCache) { // we have to override because there is no way to check if it is in some import from some other // place if it has dots on the tok... if (tok.indexOf('.') == -1) { return isInDirectGlobalTokens(tok, completionCache); } else { ICompletionState state = CompletionStateFactory.getEmptyCompletionState(nature, completionCache); String[] headAndTail = FullRepIterable.headAndTail(tok); state.setActivationToken(headAndTail[0]); String head = headAndTail[1]; IToken[] globalTokens = getGlobalTokens(state, nature.getAstManager()); for (IToken token : globalTokens) { if (token.getRepresentation().equals(head)) { return true; } } } return false; }
/** * Get self completions when you already have a scope * * @throws MisconfigurationException */ @SuppressWarnings("unchecked") public static void getSelfOrClsCompletions( ILocalScope scope, CompletionRequest request, List theList, ICompletionState state, boolean getOnlySupers) throws BadLocationException, MisconfigurationException { for (Iterator<SimpleNode> it = scope.iterator(); it.hasNext(); ) { SimpleNode node = it.next(); if (node instanceof ClassDef) { ClassDef d = (ClassDef) node; if (getOnlySupers) { List gottenComps = new ArrayList(); for (int i = 0; i < d.bases.length; i++) { if (d.bases[i] instanceof Name) { Name n = (Name) d.bases[i]; state.setActivationToken(n.id); IToken[] completions; try { completions = request .nature .getAstManager() .getCompletionsForToken(request.editorFile, request.doc, state); gottenComps.addAll(Arrays.asList(completions)); } catch (CompletionRecursionException e) { // ok... } } } theList.addAll(gottenComps); } else { // ok, get the completions for the class, only thing we have to take care now is that we // may // not have only 'self' for completion, but something like self.foo. // so, let's analyze our activation token to see what should we do. String trimmed = request.activationToken.replace('.', ' ').trim(); String[] actTokStrs = trimmed.split(" "); if (actTokStrs.length == 0 || (!actTokStrs[0].equals("self") && !actTokStrs[0].equals("cls"))) { throw new AssertionError( "We need to have at least one token (self or cls) for doing completions in the class."); } if (actTokStrs.length == 1) { // ok, it's just really self, let's get on to get the completions state.setActivationToken(NodeUtils.getNameFromNameTok((NameTok) d.name)); try { theList.addAll( Arrays.asList( request .nature .getAstManager() .getCompletionsForToken(request.editorFile, request.doc, state))); } catch (CompletionRecursionException e) { // ok } } else { // it's not only self, so, first we have to get the definition of the token // the first one is self, so, just discard it, and go on, token by token to know what is // the last // one we are completing (e.g.: self.foo.bar) int line = request.doc.getLineOfOffset(request.documentOffset); IRegion region = request.doc.getLineInformationOfOffset(request.documentOffset); int col = request.documentOffset - region.getOffset(); // ok, try our best shot at getting the module name of the current buffer used in the // request. String modName = ""; File requestFile = request.editorFile; if (request.editorFile != null) { String resolveModule = request.nature.resolveModule(requestFile); if (resolveModule != null) { modName = resolveModule; } } IModule module = AbstractModule.createModuleFromDoc( modName, requestFile, request.doc, request.nature, line); AbstractASTManager astMan = ((AbstractASTManager) request.nature.getAstManager()); theList.addAll( new AssignAnalysis() .getAssignCompletions( astMan, module, new CompletionState( line, col, request.activationToken, request.nature, request.qualifier)) .completions); } } } } }