@Override public int isInGlobalTokens( String tok, IPythonNature nature, boolean searchSameLevelMods, boolean ifHasGetAttributeConsiderInTokens, ICompletionCache completionCache) throws CompletionRecursionException { // it's worth checking it if it is not dotted... (much faster as it's in a map already) if (tok.indexOf(".") == -1) { if (isInDirectGlobalTokens(tok, completionCache)) { return IModule.FOUND_TOKEN; } } String[] headAndTail = FullRepIterable.headAndTail(tok); String head = headAndTail[1]; String generateTokensFor = headAndTail[0]; Map<String, IToken> cachedTokens = getCachedCompletions(tok, nature, searchSameLevelMods, completionCache, generateTokensFor); if (cachedTokens.containsKey(head)) { return IModule.FOUND_TOKEN; } if (ifHasGetAttributeConsiderInTokens) { IToken token = cachedTokens.get("__getattribute__"); if (token == null || isTokenFromBuiltins(token)) { token = cachedTokens.get("__getattr__"); } if (token != null && !isTokenFromBuiltins(token)) { return IModule.FOUND_BECAUSE_OF_GETATTR; } // Try to determine if the user specified it has a @DynamicAttrs. String[] parentsHeadAndTail = FullRepIterable.headAndTail(generateTokensFor); cachedTokens = getCachedCompletions( tok, nature, searchSameLevelMods, completionCache, parentsHeadAndTail[0]); IToken parentToken = cachedTokens.get(parentsHeadAndTail[1]); if (parentToken != null) { String docString = parentToken.getDocStr(); if (docString != null) { if (docString.indexOf("@DynamicAttrs") != -1) { // class that has things dynamically defined. return IModule.FOUND_BECAUSE_OF_GETATTR; } } } } // if not found until now, it is not defined return IModule.NOT_FOUND; }
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(); } }
private IInfo addAssignTargets( ASTEntry entry, String moduleName, int doOn, String path, boolean lastIsMethod) { String rep = NodeUtils.getFullRepresentationString(entry.node); if (lastIsMethod) { List<String> parts = StringUtils.dotSplit(rep); if (parts.size() >= 2) { // at least 2 parts are required if (parts.get(0).equals("self")) { rep = parts.get(1); // no intern construct (locked in the loop that calls this method) AttrInfo info = new AttrInfo( ObjectsPool.internUnsynched(rep), moduleName, ObjectsPool.internUnsynched(path), false); add(info, doOn); return info; } } } else { // no intern construct (locked in the loop that calls this method) AttrInfo info = new AttrInfo( ObjectsPool.internUnsynched(FullRepIterable.getFirstPart(rep)), moduleName, ObjectsPool.internUnsynched(path), false); add(info, doOn); return info; } return null; }
/** * Checks if some token is actually undefined and changes its representation if needed * * @return a tuple indicating if it really is undefined and the representation that should be * used. */ protected Tuple<Boolean, String> isActuallyUndefined(IToken token, String rep) { String tokenRepresentation = token.getRepresentation(); if (tokenRepresentation != null) { String firstPart = FullRepIterable.getFirstPart(tokenRepresentation); if (this.prefs.getTokensAlwaysInGlobals().contains(firstPart)) { return new Tuple<Boolean, String>( false, firstPart); // ok firstPart in not really undefined... } } boolean isActuallyUndefined = true; if (rep == null) { rep = tokenRepresentation; } int i; if ((i = rep.indexOf('.')) != -1) { rep = rep.substring(0, i); } String builtinType = NodeUtils.getBuiltinType(rep); if (builtinType != null) { isActuallyUndefined = false; // this is a builtin, so, it is defined after all } return new Tuple<Boolean, String>(isActuallyUndefined, rep); }
/** * @param input * @return a tuple with the part name to be used and a boolean indicating if the maximum level has * been reached for this path. */ private Tuple<String, Boolean> getPartNameInLevel( int level, IPath path, String initHandling, String djangoModulesHandling, IEditorInput input) { String classStr = input.getClass().toString(); if (classStr.endsWith("RemoteFileStoreEditorInput") && classStr.indexOf("com.aptana") != -1) { return new Tuple<String, Boolean>(input.getName(), true); } String[] segments = path.segments(); if (segments.length == 0) { return new Tuple<String, Boolean>("", true); } if (segments.length == 1) { return new Tuple<String, Boolean>(segments[1], true); } String lastSegment = segments[segments.length - 1]; boolean handled = isDjangoHandledModule(djangoModulesHandling, input, lastSegment); if (handled && djangoModulesHandling == PyTitlePreferencesPage.TITLE_EDITOR_DJANGO_MODULES_SHOW_PARENT_AND_DECORATE) { String[] dest = new String[segments.length - 1]; System.arraycopy(segments, 0, dest, 0, dest.length); segments = dest; } else if (initHandling != PyTitlePreferencesPage.TITLE_EDITOR_INIT_HANDLING_IN_TITLE) { if (lastSegment.startsWith("__init__.")) { // remove the __init__. String[] dest = new String[segments.length - 1]; System.arraycopy(segments, 0, dest, 0, dest.length); segments = dest; } } int startAt = segments.length - level; if (startAt < 0) { startAt = 0; } int endAt = segments.length - 1; String modulePart = StringUtils.join(".", segments, startAt, endAt); String name = segments[segments.length - 1]; if (!PyTitlePreferencesPage.getTitleShowExtension()) { String initial = name; name = FullRepIterable.getFirstPart(name); if (name.length() == 0) { name = initial; } } if (modulePart.length() > 0) { return new Tuple<String, Boolean>(name + " (" + modulePart + ")", startAt == 0); } else { return new Tuple<String, Boolean>(name, startAt == 0); } }
public String toString() { FastStringBuffer buf = new FastStringBuffer(); buf.append( FullRepIterable.getLastPart( super .toString())); // something as org.eclipse.ui.internal.WorkingSet@2813 will become // WorkingSet@2813 buf.append(" ("); buf.append(this.getActualObject().toString()); buf.append(")"); return buf.toString(); }
/** @return whether we should add an unused import message to the module being analyzed */ public boolean shouldAddUnusedImportMessage() { if (moduleName == null) { return true; } String onlyModName = FullRepIterable.headAndTail(moduleName, true)[1]; Set<String> patternsToBeIgnored = this.prefs.getModuleNamePatternsToBeIgnored(); for (String pattern : patternsToBeIgnored) { if (onlyModName.matches(pattern)) { 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); }
/** * This method should traverse the pythonpath passed and return a structure with the info that * could be collected about the files that are related to python modules. */ public ModulesFoundStructure getModulesFoundStructure(IProgressMonitor monitor) { if (monitor == null) { monitor = new NullProgressMonitor(); } List<String> pythonpathList = getPythonpath(); ModulesFoundStructure ret = new ModulesFoundStructure(); for (Iterator<String> iter = pythonpathList.iterator(); iter.hasNext(); ) { String element = iter.next(); if (monitor.isCanceled()) { break; } // the slow part is getting the files... not much we can do (I think). File root = new File(element); PyFileListing below = getModulesBelow(root, monitor); if (below != null) { Iterator<PyFileInfo> e1 = below.getFoundPyFileInfos().iterator(); while (e1.hasNext()) { PyFileInfo pyFileInfo = e1.next(); File file = pyFileInfo.getFile(); String scannedModuleName = pyFileInfo.getModuleName(); String modName; if (scannedModuleName.length() != 0) { modName = new StringBuffer(scannedModuleName) .append('.') .append(stripExtension(file.getName())) .toString(); } else { modName = stripExtension(file.getName()); } if (isValidModuleLastPart(FullRepIterable.getLastPart(modName))) { ret.regularModules.put(file, modName); } } } else { // ok, it was null, so, maybe this is not a folder, but zip file with java classes... ModulesFoundStructure.ZipContents zipContents = getFromZip(root, monitor); if (zipContents != null) { ret.zipContents.add(zipContents); } } } return ret; }
/** * This method passes through all the java packages and calls the filter callback passed on each * package found. * * <p>If true is returned on the callback, the children of each package (classes) will also be * visited, otherwise, they'll be skipped. */ private void filterJavaPackages(IFilter filter) { IClasspathEntry[] rawClasspath; try { rawClasspath = this.javaProject.getRawClasspath(); FastStringBuffer buffer = new FastStringBuffer(); for (IClasspathEntry entry : rawClasspath) { int entryKind = entry.getEntryKind(); IClasspathEntry resolvedClasspathEntry = JavaCore.getResolvedClasspathEntry(entry); if (entryKind != IClasspathEntry.CPE_CONTAINER) { // ignore if it's in the system classpath... IPackageFragmentRoot[] roots = javaProject.findPackageFragmentRoots(resolvedClasspathEntry); // get the package roots for (IPackageFragmentRoot root : roots) { IJavaElement[] children = root.getChildren(); // get the actual packages for (IJavaElement child : children) { IPackageFragment childPackage = (IPackageFragment) child; String elementName = childPackage.getElementName(); // and if the java package is 'accepted' if (filter.accept(elementName, root, childPackage)) { buffer.clear(); buffer.append(elementName); int packageNameLen = buffer.length(); if (packageNameLen > 0) { buffer.append('.'); packageNameLen++; } // traverse its classes for (IJavaElement class_ : childPackage.getChildren()) { buffer.append(FullRepIterable.getFirstPart(class_.getElementName())); filter.accept(buffer.toString(), root, class_); buffer.setCount( packageNameLen); // leave only the package part for the next append } } } } } } } catch (Exception e) { throw new RuntimeException(e); } }
private IInfo addAssignTargets( ASTEntry entry, String moduleName, int doOn, String path, boolean lastIsMethod) { String rep = NodeUtils.getFullRepresentationString(entry.node); if (lastIsMethod) { List<String> parts = StringUtils.dotSplit(rep); if (parts.size() >= 2) { // at least 2 parts are required if (parts.get(0).equals("self")) { rep = parts.get(1); return addAttribute(rep, moduleName, doOn, path); } } } else { return addAttribute(FullRepIterable.getFirstPart(rep), moduleName, doOn, path); } return null; }
/** * Get the completions based on the arguments received * * @param state this is the state used for the completion * @param localScope this is the scope we're currently on (may be null) */ public static Collection<AbstractToken> getCompletionsForTokenWithUndefinedType( CompletionState state, LocalScope localScope) { AbstractToken[] localTokens = localScope.getLocalTokens(-1, -1, false); // only to get the // args String activationToken = state.getActivationToken(); String firstPart = FullRepIterable.getFirstPart(activationToken); for (AbstractToken token : localTokens) { if (token.getRepresentation().equals(firstPart)) { Collection<AbstractToken> interfaceForLocal = localScope.getInterfaceForLocal(state.getActivationToken()); Collection<AbstractToken> argsCompletionFromParticipants = getCompletionsForTokenWithUndefinedTypeFromParticipants( state, localScope, interfaceForLocal); return argsCompletionFromParticipants; } } return getCompletionsForTokenWithUndefinedTypeFromParticipants(state, localScope, null); }
/** * Get the completions based on the arguments received * * @param state this is the state used for the completion * @param localScope this is the scope we're currently on (may be null) */ public static Collection<AbstractToken> getCompletionsForMethodParameter( CompletionState state, LocalScope localScope) { AbstractToken[] args = localScope.getLocalTokens(-1, -1, true); // only to get the args String activationToken = state.getActivationToken(); String firstPart = FullRepIterable.getFirstPart(activationToken); for (AbstractToken token : args) { if (token.getRepresentation().equals(firstPart)) { Collection<AbstractToken> interfaceForLocal = localScope.getInterfaceForLocal(state.getActivationToken()); Collection<AbstractToken> argsCompletionFromParticipants = getCompletionsForMethodParameterFromParticipants(state, localScope, interfaceForLocal); for (AbstractToken t : interfaceForLocal) { if (!t.getRepresentation().equals(state.getQualifier())) { argsCompletionFromParticipants.add(t); } } return argsCompletionFromParticipants; } } return new ArrayList<AbstractToken>(); }
@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; }
public static void buildKeysForZipContents( PyPublicTreeMap<ModulesKey, ModulesKey> keys, ZipContents zipContents) { for (String filePathInZip : zipContents.foundFileZipPaths) { String modName = StringUtils.stripExtension(filePathInZip).replace('/', '.'); if (DEBUG_ZIP) { System.out.println("Found in zip:" + modName); } ModulesKey k = new ModulesKeyForZip(modName, zipContents.zipFile, filePathInZip, true); keys.put(k, k); if (zipContents.zipContentsType == ZipContents.ZIP_CONTENTS_TYPE_JAR) { // folder modules are only created for jars (because for python files, the __init__.py is // required). for (String s : new FullRepIterable( FullRepIterable.getWithoutLastPart( modName))) { // the one without the last part was already added k = new ModulesKeyForZip(s, zipContents.zipFile, s.replace('.', '/'), false); keys.put(k, k); } } } }
/** * @param findInfo * @see * org.python.pydev.editor.codecompletion.revisited.modules.AbstractModule#findDefinition(java.lang.String, * int, int) */ public Definition[] findDefinition( ICompletionState state, int line, int col, IPythonNature nature) throws Exception { String token = state.getActivationToken(); if (TRACE_COMPILED_MODULES) { System.out.println("CompiledModule.findDefinition:" + token); } Definition[] found = this.definitionsFoundCache.getObj(token); if (found != null) { if (TRACE_COMPILED_MODULES) { System.out.println("CompiledModule.findDefinition: found in cache."); } return found; } AbstractShell shell = AbstractShell.getServerShell(nature, AbstractShell.COMPLETION_SHELL); synchronized (shell) { Tuple<String[], int[]> def = shell.getLineCol( this.name, token, nature .getAstManager() .getModulesManager() .getCompletePythonPath( nature.getProjectInterpreter(), nature.getRelatedInterpreterManager())); // default if (def == null) { if (TRACE_COMPILED_MODULES) { System.out.println("CompiledModule.findDefinition:" + token + " = empty"); } this.definitionsFoundCache.add(token, EMPTY_DEFINITION); return EMPTY_DEFINITION; } String fPath = def.o1[0]; if (fPath.equals("None")) { if (TRACE_COMPILED_MODULES) { System.out.println("CompiledModule.findDefinition:" + token + " = None"); } Definition[] definition = new Definition[] {new Definition(def.o2[0], def.o2[1], token, null, null, this)}; this.definitionsFoundCache.add(token, definition); return definition; } File f = new File(fPath); String foundModName = nature.resolveModule(f); String foundAs = def.o1[1]; IModule mod; if (foundModName == null) { // this can happen in a case where we have a definition that's found from a compiled file // which actually // maps to a file that's outside of the pythonpath known by Pydev. String n = FullRepIterable.getFirstPart(f.getName()); mod = AbstractModule.createModule(n, f, nature, true); } else { mod = nature.getAstManager().getModule(foundModName, nature, true); } if (TRACE_COMPILED_MODULES) { System.out.println("CompiledModule.findDefinition: found at:" + mod.getName()); } int foundLine = def.o2[0]; if (foundLine == 0 && foundAs != null && foundAs.length() > 0 && mod != null && state.canStillCheckFindSourceFromCompiled(mod, foundAs)) { // TODO: The nature (and so the grammar to be used) must be defined by the file we'll parse // (so, we need to know the system modules manager that actually created it to know the // actual nature) IModule sourceMod = AbstractModule.createModuleFromDoc( mod.getName(), f, new Document(REF.getFileContents(f)), nature, true); if (sourceMod instanceof SourceModule) { Definition[] definitions = (Definition[]) sourceMod.findDefinition(state.getCopyWithActTok(foundAs), -1, -1, nature); if (definitions.length > 0) { this.definitionsFoundCache.add(token, definitions); return definitions; } } } if (mod == null) { mod = this; } int foundCol = def.o2[1]; if (foundCol < 0) { foundCol = 0; } if (TRACE_COMPILED_MODULES) { System.out.println("CompiledModule.findDefinition: found compiled at:" + mod.getName()); } Definition[] definitions = new Definition[] {new Definition(foundLine + 1, foundCol + 1, token, null, null, mod)}; this.definitionsFoundCache.add(token, definitions); return definitions; } }
@Override public void addProps( MarkerAnnotationAndPosition markerAnnotation, IAnalysisPreferences analysisPreferences, String line, PySelection ps, int offset, IPythonNature nature, PyEdit edit, List<ICompletionProposal> props) throws BadLocationException, CoreException { if (nature == null) { return; } ICodeCompletionASTManager astManager = nature.getAstManager(); if (astManager == null) { return; } if (markerAnnotation.position == null) { return; } IMarker marker = markerAnnotation.markerAnnotation.getMarker(); Integer id = (Integer) marker.getAttribute(AnalysisRunner.PYDEV_ANALYSIS_TYPE); int start = markerAnnotation.position.offset; int end = start + markerAnnotation.position.length; ps.setSelection(start, end); String markerContents; try { markerContents = ps.getSelectedText(); } catch (Exception e1) { return; // Selection may be wrong. } IDocument doc = ps.getDoc(); List<String> parametersAfterCall = ps.getParametersAfterCall(end); switch (id) { case IAnalysisPreferences.TYPE_UNDEFINED_VARIABLE: addCreateClassOption(ps, edit, props, markerContents, parametersAfterCall); addCreateMethodOption(ps, edit, props, markerContents, parametersAfterCall); break; case IAnalysisPreferences.TYPE_UNDEFINED_IMPORT_VARIABLE: // Say we had something as: // import sys // sys.Bar // in which case 'Bar' is undefined // in this situation, the activationTokenAndQual would be "sys." and "Bar" // and we want to get the definition for "sys" String[] activationTokenAndQual = ps.getActivationTokenAndQual(true); if (activationTokenAndQual[0].endsWith(".")) { ArrayList<IDefinition> selected = findDefinitions(nature, edit, start - 2, doc); for (IDefinition iDefinition : selected) { IModule module = iDefinition.getModule(); if (module.getFile() != null) { Definition definition = (Definition) iDefinition; File file = module.getFile(); if (definition.ast == null) { // if we have no ast in the definition, it means the module itself was found (global // scope) // Add option to create class at the given module! addCreateClassOption(ps, edit, props, markerContents, parametersAfterCall, file); addCreateMethodOption(ps, edit, props, markerContents, parametersAfterCall, file); } else if (definition.ast instanceof ClassDef) { ClassDef classDef = (ClassDef) definition.ast; // Ok, we should create a field or method in this case (accessing a classmethod or // staticmethod) PyCreateMethodOrField pyCreateMethod = new PyCreateMethodOrField(); String className = NodeUtils.getNameFromNameTok(classDef.name); pyCreateMethod.setCreateInClass(className); pyCreateMethod.setCreateAs(PyCreateMethodOrField.CLASSMETHOD); addCreateClassmethodOption( ps, edit, props, markerContents, parametersAfterCall, pyCreateMethod, file, className); } } } } break; case IAnalysisPreferences.TYPE_UNRESOLVED_IMPORT: // This case is the following: from other_module4 import Foo // with 'Foo' being undefined. // So, we have to suggest creating a Foo class/method in other_module4 PyImportsHandling importsHandling = new PyImportsHandling(ps.getDoc(), false); int offsetLine = ps.getLineOfOffset(start); String selectedText = ps.getSelectedText(); Tuple<IModule, String> found = null; String foundFromImportStr = null; boolean isImportFrom = false; OUT: for (ImportHandle handle : importsHandling) { if (handle.startFoundLine == offsetLine || handle.endFoundLine == offsetLine || (handle.startFoundLine < offsetLine && handle.endFoundLine > offsetLine)) { List<ImportHandleInfo> importInfo = handle.getImportInfo(); for (ImportHandleInfo importHandleInfo : importInfo) { String fromImportStr = importHandleInfo.getFromImportStr(); List<String> importedStr = importHandleInfo.getImportedStr(); for (String imported : importedStr) { if (selectedText.equals(imported)) { if (fromImportStr != null) { foundFromImportStr = fromImportStr + "." + imported; isImportFrom = true; } else { // if fromImportStr == null, it's not a from xxx import yyy (i.e.: simple // import) foundFromImportStr = imported; } try { String currentModule = nature.resolveModule(edit.getEditorFile()); ICompletionState state = CompletionStateFactory.getEmptyCompletionState( nature, new CompletionCache()); found = nature .getAstManager() .findModule( foundFromImportStr, currentModule, state, new SourceModule( currentModule, edit.getEditorFile(), edit.getAST(), null)); } catch (Exception e) { Log.log(e); } break OUT; } } } break OUT; } } boolean addOptionToCreateClassOrMethod = isImportFrom; if (found != null && found.o1 != null) { // Ok, we found a module, now, it may be that we still have to create some intermediary // modules // or just create a class or method at the end. if (found.o1 instanceof SourceModule) { // if all was found, there's nothing left to create. if (found.o2 != null && found.o2.length() > 0) { SourceModule sourceModule = (SourceModule) found.o1; File file = sourceModule.getFile(); if (found.o2.indexOf('.') != -1) { // We have to create some intermediary structure. if (!addOptionToCreateClassOrMethod) { // Cannot create class or method from the info (only the module structure). if (sourceModule.getName().endsWith(".__init__")) { File f = getFileStructure(file.getParentFile(), found.o2); addCreateModuleOption(ps, edit, props, markerContents, f); } } else { // Ok, the leaf may be a class or method. if (sourceModule.getName().endsWith(".__init__")) { String moduleName = FullRepIterable.getWithoutLastPart(sourceModule.getName()); String withoutLastPart = FullRepIterable.getWithoutLastPart(found.o2); moduleName += "." + withoutLastPart; String classOrMethodName = FullRepIterable.getLastPart(found.o2); File f = getFileStructure(file.getParentFile(), withoutLastPart); addCreateClassInNewModuleOption( ps, edit, props, classOrMethodName, moduleName, parametersAfterCall, f); addCreateMethodInNewModuleOption( ps, edit, props, classOrMethodName, moduleName, parametersAfterCall, f); } } } else { // Ok, it's all there, we just have to create the leaf. if (!addOptionToCreateClassOrMethod || sourceModule.getName().endsWith(".__init__")) { // Cannot create class or method from the info (only the module structure). if (sourceModule.getName().endsWith(".__init__")) { File f = new File( file.getParent(), found.o2 + FileTypesPreferencesPage.getDefaultDottedPythonExtension()); addCreateModuleOption(ps, edit, props, markerContents, f); } } else { // Ok, the leaf may be a class or method. addCreateClassOption(ps, edit, props, markerContents, parametersAfterCall, file); addCreateMethodOption(ps, edit, props, markerContents, parametersAfterCall, file); } } } } } else if (foundFromImportStr != null) { // We couldn't find anything there, so, we have to create the modules structure as needed // and // maybe create a class or module at the end (but only if it's an import from). // Ok, it's all there, we just have to create the leaf. // Discover the source folder where we should create the structure. File editorFile = edit.getEditorFile(); String onlyProjectPythonPathStr = nature.getPythonPathNature().getOnlyProjectPythonPathStr(false); List<String> split = StringUtils.splitAndRemoveEmptyTrimmed(onlyProjectPythonPathStr, '|'); for (int i = 0; i < split.size(); i++) { String fullPath = FileUtils.getFileAbsolutePath(split.get(i)); fullPath = PythonPathHelper.getDefaultPathStr(fullPath); split.set(i, fullPath); } HashSet<String> projectSourcePath = new HashSet<String>(split); if (projectSourcePath.size() == 0) { return; // No source folder for editor... this shouldn't happen (code analysis wouldn't // even run on it). } String fullPath = FileUtils.getFileAbsolutePath(editorFile); fullPath = PythonPathHelper.getDefaultPathStr(fullPath); String foundSourceFolderFullPath = null; if (projectSourcePath.size() == 1) { foundSourceFolderFullPath = projectSourcePath.iterator().next(); } else { for (String string : projectSourcePath) { if (fullPath.startsWith(string)) { // Use this as the source folder foundSourceFolderFullPath = string; break; } } } if (foundSourceFolderFullPath != null) { if (!addOptionToCreateClassOrMethod) { // Cannot create class or method from the info (only the module structure). File f = getFileStructure(new File(foundSourceFolderFullPath), foundFromImportStr); addCreateModuleOption(ps, edit, props, foundFromImportStr, f); } else { // Ok, the leaf may be a class or method. String moduleName = FullRepIterable.getWithoutLastPart(foundFromImportStr); File file = getFileStructure(new File(foundSourceFolderFullPath), moduleName); String lastPart = FullRepIterable.getLastPart(foundFromImportStr); addCreateClassInNewModuleOption( ps, edit, props, lastPart, moduleName, parametersAfterCall, file); addCreateMethodInNewModuleOption( ps, edit, props, lastPart, moduleName, parametersAfterCall, file); } } } break; } }
/** * Change the pythonpath (used for both: system and project) * * @param project: may be null * @param defaultSelectedInterpreter: may be null */ public void changePythonPath( String pythonpath, final IProject project, IProgressMonitor monitor) { pythonPathHelper.setPythonPath(pythonpath); ModulesFoundStructure modulesFound = pythonPathHelper.getModulesFoundStructure(monitor); // now, on to actually filling the module keys ModulesKeyTreeMap<ModulesKey, ModulesKey> keys = new ModulesKeyTreeMap<ModulesKey, ModulesKey>(); int j = 0; FastStringBuffer buffer = new FastStringBuffer(); // now, create in memory modules for all the loaded files (empty modules). for (Iterator<Map.Entry<File, String>> iterator = modulesFound.regularModules.entrySet().iterator(); iterator.hasNext() && monitor.isCanceled() == false; j++) { Map.Entry<File, String> entry = iterator.next(); File f = entry.getKey(); String m = entry.getValue(); if (j % 15 == 0) { // no need to report all the time (that's pretty fast now) buffer.clear(); monitor.setTaskName(buffer.append("Module resolved: ").append(m).toString()); monitor.worked(1); } if (m != null) { // we don't load them at this time. ModulesKey modulesKey = new ModulesKey(m, f); // no conflict (easy) if (!keys.containsKey(modulesKey)) { keys.put(modulesKey, modulesKey); } else { // we have a conflict, so, let's resolve which one to keep (the old one or this one) if (PythonPathHelper.isValidSourceFile(f.getName())) { // source files have priority over other modules (dlls) -- if both are source, there is // no real way to resolve // this priority, so, let's just add it over. keys.put(modulesKey, modulesKey); } } } } for (ZipContents zipContents : modulesFound.zipContents) { if (monitor.isCanceled()) { break; } for (String filePathInZip : zipContents.foundFileZipPaths) { String modName = StringUtils.stripExtension(filePathInZip).replace('/', '.'); if (DEBUG_ZIP) { System.out.println("Found in zip:" + modName); } ModulesKey k = new ModulesKeyForZip(modName, zipContents.zipFile, filePathInZip, true); keys.put(k, k); if (zipContents.zipContentsType == ZipContents.ZIP_CONTENTS_TYPE_JAR) { // folder modules are only created for jars (because for python files, the __init__.py is // required). for (String s : new FullRepIterable( FullRepIterable.getWithoutLastPart( modName))) { // the one without the last part was already added k = new ModulesKeyForZip(s, zipContents.zipFile, s.replace('.', '/'), false); keys.put(k, k); } } } } onChangePythonpath(keys); // assign to instance variable this.setModules(keys); }
@Override public String getPackageFolderName() { return FullRepIterable.getParentModule(this.name); }
public Collection<IToken> getInterfaceForLocal( String activationToken, boolean addAttributeAccess, boolean addLocalsFromHasAttr) { Set<SourceToken> comps = new HashSet<SourceToken>(); Iterator<SimpleNode> it = this.scope.topDownIterator(); if (!it.hasNext()) { return new ArrayList<IToken>(); } SimpleNode element = it.next(); String dottedActTok = activationToken + '.'; // ok, that's the scope we have to analyze SequencialASTIteratorVisitor visitor = SequencialASTIteratorVisitor.create(element); ArrayList<Class> classes = new ArrayList<Class>(2); if (addAttributeAccess) { classes.add(Attribute.class); } if (addLocalsFromHasAttr) { classes.add(Call.class); } Iterator<ASTEntry> iterator = visitor.getIterator(classes.toArray(new Class[classes.size()])); while (iterator.hasNext()) { ASTEntry entry = iterator.next(); if (entry.node instanceof Attribute) { String rep = NodeUtils.getFullRepresentationString(entry.node); if (rep.startsWith(dottedActTok)) { rep = rep.substring(dottedActTok.length()); if (NodeUtils.isValidNameRepresentation( rep)) { // that'd be something that can happen when trying to recreate the parsing comps.add( new SourceToken( entry.node, FullRepIterable.getFirstPart(rep), "", "", "", IToken.TYPE_OBJECT_FOUND_INTERFACE)); } } } else if (entry.node instanceof Call) { Call call = (Call) entry.node; if ("hasattr".equals(NodeUtils.getFullRepresentationString(call.func)) && call.args != null && call.args.length == 2) { String rep = NodeUtils.getFullRepresentationString(call.args[0]); if (rep.equals(activationToken)) { exprType node = call.args[1]; if (node instanceof Str) { Str str = (Str) node; String attrName = str.s; if (NodeUtils.isValidNameRepresentation(attrName)) { comps.add( new SourceToken( node, attrName, "", "", "", IToken.TYPE_OBJECT_FOUND_INTERFACE)); } } } } } } return new ArrayList<IToken>(comps); }
/** @see {@link ILocalScope#getPossibleClassesForActivationToken(String)} */ public List<String> getPossibleClassesForActivationToken(String actTok) { ArrayList<String> ret = new ArrayList<String>(); Iterator<SimpleNode> it = this.scope.topDownIterator(); if (!it.hasNext()) { return ret; } SimpleNode element = it.next(); // ok, that's the scope we have to analyze // Search for docstrings. String typeForParameter = NodeUtils.getTypeForParameterFromDocstring(actTok, element); if (typeForParameter != null) { ret.add(typeForParameter); } // Search for assert isinstance(). SequencialASTIteratorVisitor visitor = SequencialASTIteratorVisitor.create(element); Iterator<ASTEntry> iterator = visitor.getIterator(); ArrayList<Object> lst = new ArrayList<Object>(); Name nameDefinition = null; while (iterator.hasNext()) { ASTEntry entry = iterator.next(); if (entry.node.specialsAfter != null) { lst.addAll(entry.node.specialsAfter); } if (entry.node.specialsBefore != null) { lst.addAll(entry.node.specialsBefore); } if (!(entry.node instanceof Assert)) { if (entry.node instanceof Str) { lst.add(entry.node); } if (entry.node instanceof Name) { Name name = (Name) entry.node; if (name.ctx == Name.Load) { if (actTok.equals(name.id)) { nameDefinition = name; } } } continue; } Assert ass = (Assert) entry.node; if (ass.test instanceof Call) { Call call = (Call) ass.test; String rep = NodeUtils.getFullRepresentationString(call.func); if (rep == null) { continue; } Integer classIndex = ISINSTANCE_POSSIBILITIES.get(FullRepIterable.getLastPart(rep).toLowerCase()); if (classIndex != null) { if (call.args != null && (call.args.length >= Math.max(classIndex, 1))) { // in all cases, the instance is the 1st parameter. String foundActTok = NodeUtils.getFullRepresentationString(call.args[0]); if (foundActTok != null && foundActTok.equals(actTok)) { if (classIndex > 0) { exprType type = call.args[classIndex - 1]; if (type instanceof Tuple) { // case: isinstance(obj, (Class1,Class2)) Tuple tuple = (Tuple) type; for (exprType expr : tuple.elts) { addRepresentationIfPossible(ret, expr); } } else { // case: isinstance(obj, Class) addRepresentationIfPossible(ret, type); } } else { // zope case Interface.implementedBy(obj) -> Interface added ret.add(FullRepIterable.getWithoutLastPart(rep)); } } } } } } if (nameDefinition != null) { int s = lst.size(); for (int i = 0; i < s; i++) { Object object = lst.get(i); if (object instanceof commentType) { commentType commentType = (commentType) object; // according to http://sphinx-doc.org/ext/autodoc.html#directive-autoattribute, // to be a valid comment must be before the definition or in the same line. if (Math.abs(commentType.beginLine - nameDefinition.beginLine) <= 2) { if (commentType.id != null) { String trim = commentType.id.trim(); if (trim.startsWith("#")) { trim = trim.substring(1).trim(); } if (trim.startsWith(":")) { String type = NodeUtils.getTypeForParameterFromDocstring(actTok, trim.substring(1)); if (type != null) { ret.add(type); } } else if (trim.startsWith("@")) { String type = NodeUtils.getTypeForParameterFromDocstring(actTok, trim); if (type != null) { ret.add(type); } } } } } else if (object instanceof Str) { Str str = (Str) object; if (Math.abs(str.beginLine - nameDefinition.beginLine) <= 2) { if (str.s != null) { String trim = str.s.trim(); if (trim.startsWith("#")) { trim = trim.substring(1).trim(); } if (trim.startsWith(":")) { String type = NodeUtils.getTypeForParameterFromDocstring(actTok, trim.substring(1)); if (type != null) { ret.add(type); } } else if (trim.startsWith("@")) { String type = NodeUtils.getTypeForParameterFromDocstring(actTok, trim); if (type != null) { ret.add(type); } } } } } } } return ret; }
public static void convertToICompletions( String text, String actTok, int offset, Object fromServer, List<ICompletionProposal> ret) { if (fromServer instanceof Object[]) { Object[] objects = (Object[]) fromServer; fromServer = Arrays.asList(objects); } if (fromServer instanceof List) { int length = actTok.lastIndexOf('.'); if (length == -1) { length = actTok.length(); } else { length = actTok.length() - length - 1; } List comps = (List) fromServer; for (Object o : comps) { if (o instanceof Object[]) { // name, doc, args, type Object[] comp = (Object[]) o; String name = (String) comp[0]; String docStr = (String) comp[1]; int type = extractInt(comp[3]); String args = AbstractPyCodeCompletion.getArgs( (String) comp[2], type, ICompletionState.LOOKING_FOR_INSTANCED_VARIABLE); String nameAndArgs = name + args; int priority = IPyCompletionProposal.PRIORITY_DEFAULT; if (type == IToken.TYPE_LOCAL) { priority = IPyCompletionProposal.PRIORITY_LOCALS; } else if (type == IToken.TYPE_PARAM) { priority = IPyCompletionProposal.PRIORITY_LOCALS_1; } // ret.add(new PyCompletionProposal(name, // offset-length, length, name.length(), // PyCodeCompletionImages.getImageForType(type), name, null, // docStr, priority)); int cursorPos = name.length(); if (args.length() > 1) { cursorPos += 1; } int replacementOffset = offset - length; PyCalltipsContextInformation pyContextInformation = null; if (args.length() > 2) { pyContextInformation = new PyCalltipsContextInformation( args, replacementOffset + name.length() + 1); // just after the parenthesis } else { // Support for IPython completions (non standard names) // i.e.: %completions, cd ... if (name.length() > 0) { // magic ipython stuff (starting with %) if (name.charAt(0) == '%') { replacementOffset -= 1; } else if (name.charAt(0) == '/') { // Should be something as cd c:/temp/foo (and name is /temp/foo) char[] chars = text.toCharArray(); for (int i = 0; i < chars.length; i++) { char c = chars[i]; if (c == name.charAt(0)) { String sub = text.substring(i, text.length()); if (name.startsWith(sub)) { replacementOffset -= (sub.length() - FullRepIterable.getLastPart(actTok).length()); break; } } } } } } ret.add( new PyLinkedModeCompletionProposal( nameAndArgs, replacementOffset, length, cursorPos, PyCodeCompletionImages.getImageForType(type), nameAndArgs, pyContextInformation, docStr, priority, PyCompletionProposal.ON_APPLY_DEFAULT, args, false)); } } } }
/** * DAMN... when I started thinking this up, it seemed much better... (and easier) * * @param module - this is the full path of the module. Only for directories or py,pyd,dll,pyo * files. * @return a String with the module that the file or folder should represent. E.g.: compiler.ast */ public String resolveModule( String fullPath, final boolean requireFileToExist, List<String> pythonPathCopy) { fullPath = REF.getFileAbsolutePath(fullPath); fullPath = getDefaultPathStr(fullPath); String fullPathWithoutExtension; if (isValidSourceFile(fullPath) || FileTypesPreferencesPage.isValidDll(fullPath)) { fullPathWithoutExtension = FullRepIterable.headAndTail(fullPath)[0]; } else { fullPathWithoutExtension = fullPath; } final File moduleFile = new File(fullPath); if (requireFileToExist && !moduleFile.exists()) { return null; } boolean isFile = moduleFile.isFile(); // go through our pythonpath and check the beginning for (String pathEntry : pythonPathCopy) { String element = getDefaultPathStr(pathEntry); if (fullPath.startsWith(element)) { int len = element.length(); String s = fullPath.substring(len); String sWithoutExtension = fullPathWithoutExtension.substring(len); if (s.startsWith("/")) { s = s.substring(1); } if (sWithoutExtension.startsWith("/")) { sWithoutExtension = sWithoutExtension.substring(1); } if (!isValidModuleLastPart(sWithoutExtension)) { continue; } s = s.replaceAll("/", "."); if (s.indexOf(".") != -1) { File root = new File(element); if (root.exists() == false) { continue; } final List<String> temp = StringUtils.dotSplit(s); String[] modulesParts = temp.toArray(new String[temp.size()]); // this means that more than 1 module is specified, so, in order to get it, // we have to go and see if all the folders to that module have __init__.py in it... if (modulesParts.length > 1 && isFile) { String[] t = new String[modulesParts.length - 1]; for (int i = 0; i < modulesParts.length - 1; i++) { t[i] = modulesParts[i]; } t[t.length - 1] = t[t.length - 1] + "." + modulesParts[modulesParts.length - 1]; modulesParts = t; } // here, in modulesParts, we have something like // ["compiler", "ast.py"] - if file // ["pywin","debugger"] - if folder // // root starts with the pythonpath folder that starts with the same // chars as the full path passed in. boolean isValid = true; for (int i = 0; i < modulesParts.length && root != null; i++) { root = new File(REF.getFileAbsolutePath(root) + "/" + modulesParts[i]); // check if file is in root... if (isValidFileMod(modulesParts[i])) { if (root.exists() && root.isFile()) { break; } } else { // this part is a folder part... check if it is a valid module (has init). if (isFileOrFolderWithInit(root) == false) { isValid = false; break; } // go on and check the next part. } } if (isValid) { if (isFile) { s = stripExtension(s); } else if (moduleFile.exists() == false) { // ok, it does not exist, so isFile will not work, let's just check if it is // a valid module (ends with .py or .pyw) and if it is, strip the extension if (isValidFileMod(s)) { s = stripExtension(s); } } return s; } } else { // simple part, we don't have to go into subfolders to check validity... if (!isFile && moduleFile.isDirectory() && isFileOrFolderWithInit(moduleFile) == false) { return null; } return s; } } } // ok, it was not found in any existing way, so, if we don't require the file to exist, let's // just do some simpler search and get the // first match (if any)... this is useful if the file we are looking for has just been deleted if (!requireFileToExist) { // we have to remove the last part (.py, .pyc, .pyw) for (String element : pythonPathCopy) { element = getDefaultPathStr(element); if (fullPathWithoutExtension.startsWith(element)) { String s = fullPathWithoutExtension.substring(element.length()); if (s.startsWith("/")) { s = s.substring(1); } if (!isValidModuleLastPart(s)) { continue; } s = s.replaceAll("/", "."); return s; } } } return null; }