@Override public Object visitImportFrom(ImportFrom node) throws Exception { String modRep = NodeUtils.getRepresentationString(node.module); if (NodeUtils.isWithin(line, col, node.module)) { // it is a token in the definition of a module int startingCol = node.module.beginColumn; int endingCol = startingCol; while (endingCol < this.col) { endingCol++; } int lastChar = endingCol - startingCol; moduleImported = modRep.substring(0, lastChar); int i = lastChar; while (i < modRep.length()) { if (Character.isJavaIdentifierPart(modRep.charAt(i))) { i++; } else { break; } } moduleImported += modRep.substring(lastChar, i); } else { // it was not the module, so, we have to check for each name alias imported for (aliasType alias : node.names) { // we do not check the 'as' because if it is some 'as', it will be gotten as a global in the // module if (NodeUtils.isWithin(line, col, alias.name)) { moduleImported = modRep + "." + NodeUtils.getRepresentationString(alias.name); } } } return super.visitImportFrom(node); }
@Override public Object visitNameTok(NameTok node) throws Exception { if (node.ctx == NameTok.KeywordName) { if (this.line == node.beginLine) { String rep = NodeUtils.getRepresentationString(node); if (PySelection.isInside(col, node.beginColumn, rep.length())) { foundAsDefinition = true; // if it is found as a definition it is an 'exact' match, so, erase all the others. ILocalScope scope = new LocalScope(this.defsStack); for (Iterator<Definition> it = definitions.iterator(); it.hasNext(); ) { Definition d = it.next(); if (!d.scope.equals(scope)) { it.remove(); } } definitions.clear(); definitionFound = new KeywordParameterDefinition( line, node.beginColumn, rep, node, scope, module.get(), this.call.peek()); definitions.add(definitionFound); throw new StopVisitingException(); } } } return null; }
public void run(IAction action) { FastStringBuffer buf = new FastStringBuffer(); try { PyEdit pyEdit = getPyEdit(); PySelection pySelection = new PySelection(pyEdit); IPythonNature nature = pyEdit.getPythonNature(); File editorFile = pyEdit.getEditorFile(); if (editorFile != null) { if (nature != null) { String mod = nature.resolveModule(editorFile); if (mod != null) { buf.append(mod); } else { // Support for external files (not in PYTHONPATH). buf.append(FullRepIterable.getFirstPart(editorFile.getName())); } } else { buf.append(FullRepIterable.getFirstPart(editorFile.getName())); } } List<stmtType> path = FastParser.parseToKnowGloballyAccessiblePath( pySelection.getDoc(), pySelection.getStartLineIndex()); for (stmtType stmtType : path) { if (buf.length() > 0) { buf.append('.'); } buf.append(NodeUtils.getRepresentationString(stmtType)); } } catch (MisconfigurationException e1) { Log.log(e1); return; } Transfer[] dataTypes = new Transfer[] {TextTransfer.getInstance()}; Object[] data = new Object[] {buf.toString()}; Clipboard clipboard = new Clipboard(EditorUtils.getShell().getDisplay()); try { clipboard.setContents(data, dataTypes); } catch (SWTError e) { if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) { throw e; } MessageDialog.openError( EditorUtils.getShell(), "Error copying to clipboard.", e.getMessage()); } finally { clipboard.dispose(); } }
/** * @param request this is the request for the completion * @param theList OUT - returned completions are added here. (IToken instances) * @param getOnlySupers whether we should only get things from super classes (in this case, we * won't get things from the current class) * @param checkIfInCorrectScope if true, we'll first check if we're in a scope that actually has a * method with 'self' or 'cls' * @return true if we actually tried to get the completions for self or cls. * @throws MisconfigurationException */ @SuppressWarnings("unchecked") public static boolean getSelfOrClsCompletions( CompletionRequest request, List theList, ICompletionState state, boolean getOnlySupers, boolean checkIfInCorrectScope, String lookForRep) throws MisconfigurationException { SimpleNode s = PyParser.reparseDocument( new PyParser.ParserInfo(request.doc, true, request.nature, state.getLine())) .o1; if (s != null) { FindScopeVisitor visitor = new FindScopeVisitor(state.getLine(), 0); try { s.accept(visitor); if (checkIfInCorrectScope) { boolean scopeCorrect = false; FastStack<SimpleNode> scopeStack = visitor.scope.getScopeStack(); for (Iterator<SimpleNode> it = scopeStack.topDownIterator(); scopeCorrect == false && it.hasNext(); ) { SimpleNode node = it.next(); if (node instanceof FunctionDef) { FunctionDef funcDef = (FunctionDef) node; if (funcDef.args != null && funcDef.args.args != null && funcDef.args.args.length > 0) { // ok, we have some arg, let's check for self or cls String rep = NodeUtils.getRepresentationString(funcDef.args.args[0]); if (rep != null && (rep.equals("self") || rep.equals("cls"))) { scopeCorrect = true; } } } } if (!scopeCorrect) { return false; } } if (lookForRep.equals("self")) { state.setLookingFor(ICompletionState.LOOKING_FOR_INSTANCED_VARIABLE); } else { state.setLookingFor(ICompletionState.LOOKING_FOR_CLASSMETHOD_VARIABLE); } getSelfOrClsCompletions(visitor.scope, request, theList, state, getOnlySupers); } catch (Exception e1) { PydevPlugin.log(e1); } return true; } return false; }
/** * @param lastMayBeMethod if true, it gets the path and accepts a method (if it is the last in the * stack) if false, null is returned if a method is found. * @param tempStack is a temporary stack object (which may be cleared) * @return a tuple, where the first element is the path where the entry is located (may return * null). and the second element is a boolen that indicates if the last was actually a method * or not. */ private Tuple<String, Boolean> getPathToRoot( ASTEntry entry, boolean lastMayBeMethod, boolean acceptAny, FastStack<SimpleNode> tempStack) { if (entry.parent == null) { return null; } // just to be sure that it's empty tempStack.clear(); boolean lastIsMethod = false; // if the last 'may be a method', in this case, we have to remember that it will actually be the // first one // to be analyzed. // let's get the stack while (entry.parent != null) { if (entry.parent.node instanceof ClassDef) { tempStack.push(entry.parent.node); } else if (entry.parent.node instanceof FunctionDef) { if (!acceptAny) { if (lastIsMethod) { // already found a method return null; } if (!lastMayBeMethod) { return null; } // ok, the last one may be a method... (in this search, it MUST be the first one...) if (tempStack.size() != 0) { return null; } } // ok, there was a class, so, let's go and set it tempStack.push(entry.parent.node); lastIsMethod = true; } else { return null; } entry = entry.parent; } // now that we have the stack, let's make it into a path... FastStringBuffer buf = new FastStringBuffer(); while (tempStack.size() > 0) { if (buf.length() > 0) { buf.append("."); } buf.append(NodeUtils.getRepresentationString(tempStack.pop())); } return new Tuple<String, Boolean>(buf.toString(), lastIsMethod); }
/** * @param node the declaration node we're interested in (class or function) * @param name the token that represents the name of that declaration */ private void checkDeclaration(SimpleNode node, NameTok name) { String rep = NodeUtils.getRepresentationString(node); if (rep.equals(tokenToFind) && line == name.beginLine && col >= name.beginColumn && col <= name.beginColumn + rep.length()) { foundAsDefinition = true; // if it is found as a definition it is an 'exact' match, so, erase all the others. ILocalScope scope = new LocalScope(this.defsStack); for (Iterator<Definition> it = definitions.iterator(); it.hasNext(); ) { Definition d = it.next(); if (!d.scope.equals(scope)) { it.remove(); } } definitionFound = new Definition(line, name.beginColumn, rep, node, scope, module.get()); definitions.add(definitionFound); } }
/** @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]); }
/** * Called after the creation of any module. Used as a workaround for filling tokens that are in no * way available in the code-completion through the regular inspection. * * <p>The django objects class is the reason why this happens... It's structure for the creation * on a model class follows no real patterns for the creation of the 'objects' attribute in the * class, and thus, we have no real generic way of discovering it (actually, even by looking at * the class definition this is very obscure), so, the solution found is creating the objects by * decorating the module with that info. */ private AbstractModule decorateModule(AbstractModule n, IPythonNature nature) { if (n instanceof SourceModule && "django.db.models.base".equals(n.getName())) { SourceModule sourceModule = (SourceModule) n; SimpleNode ast = sourceModule.getAst(); for (SimpleNode node : ((Module) ast).body) { if (node instanceof ClassDef && "Model".equals(NodeUtils.getRepresentationString(node))) { Object[][] metaclassAttrs = new Object[][] { {"objects", NodeUtils.makeAttribute("django.db.models.manager.Manager()")}, {"DoesNotExist", new Name("Exception", Name.Load, false)}, {"MultipleObjectsReturned", new Name("Exception", Name.Load, false)}, }; ClassDef classDef = (ClassDef) node; stmtType[] newBody = new stmtType[classDef.body.length + metaclassAttrs.length]; System.arraycopy(classDef.body, 0, newBody, metaclassAttrs.length, classDef.body.length); int i = 0; for (Object[] objAndType : metaclassAttrs) { // Note that the line/col is important so that we correctly acknowledge it inside the // "class Model" scope. Name name = new Name((String) objAndType[0], Name.Store, false); name.beginColumn = classDef.beginColumn + 4; name.beginLine = classDef.beginLine + 1; newBody[i] = new Assign(new exprType[] {name}, (exprType) objAndType[1]); newBody[i].beginColumn = classDef.beginColumn + 4; newBody[i].beginLine = classDef.beginLine + 1; i += 1; } classDef.body = newBody; break; } } } return n; }