Example #1
0
  /**
   * 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;
  }
Example #2
0
 /**
  * This function creates a module and resolves the module name (use this function if only the file
  * is available).
  *
  * @throws MisconfigurationException
  */
 public static IModule createModuleFromDoc(File file, IDocument doc, IPythonNature pythonNature)
     throws MisconfigurationException {
   IModulesManager projModulesManager = pythonNature.getAstManager().getModulesManager();
   String moduleName = null;
   if (file != null) {
     moduleName = projModulesManager.resolveModule(FileUtils.getFileAbsolutePath(file));
   }
   if (moduleName == null) {
     moduleName = MODULE_NAME_WHEN_FILE_IS_UNDEFINED;
   }
   IModule module = createModuleFromDoc(moduleName, file, doc, pythonNature, false);
   return module;
 }
Example #3
0
  /**
   * This method creates a source module from a file.
   *
   * @return
   * @throws IOException
   * @throws MisconfigurationException
   */
  public static AbstractModule createModule(
      String name, File f, IPythonNature nature, boolean checkForPath)
      throws IOException, MisconfigurationException {
    if (PythonPathHelper.isValidFileMod(f.getName())) {
      if (PythonPathHelper.isValidSourceFile(f.getName())) {
        return createModuleFromDoc(
            name, f, FileUtilsFileBuffer.getDocFromFile(f), nature, checkForPath);

      } else { // this should be a compiled extension... we have to get completions from the python
        // shell.
        return new CompiledModule(name, nature.getAstManager().getModulesManager(), nature);
      }
    }

    // if we are here, return null...
    return null;
  }
Example #4
0
  @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;
  }
Example #5
0
  /**
   * @param pythonNatures the natures from were we can get info
   * @param additionalInfo the additional informations
   * @param selectedText the text that should be initially set as a filter
   */
  public static void doSelect(
      List<IPythonNature> pythonNatures,
      List<AbstractAdditionalTokensInfo> additionalInfo,
      String selectedText) {

    SelectionDialog dialog =
        GlobalsDialogFactory.create(getShell(), additionalInfo, selectedText, pythonNatures);

    dialog.open();
    Object[] result = dialog.getResult();
    if (result != null && result.length > 0) {
      for (Object obj : result) {
        IInfo entry;
        if (obj instanceof AdditionalInfoAndIInfo) {
          entry = ((AdditionalInfoAndIInfo) obj).info;
        } else {
          entry = (IInfo) obj;
        }
        List<ItemPointer> pointers = new ArrayList<ItemPointer>();

        CompletionCache completionCache = new CompletionCache();
        for (IPythonNature pythonNature : pythonNatures) {
          // try to find in one of the natures...
          ICodeCompletionASTManager astManager = pythonNature.getAstManager();
          if (astManager == null) {
            continue;
          }
          AnalysisPlugin.getDefinitionFromIInfo(
              pointers, astManager, pythonNature, entry, completionCache);
          if (pointers.size() > 0) {
            new PyOpenAction().run(pointers.get(0));
            break; // don't check the other natures
          }
        }
      }
    }
  }
Example #6
0
  /* (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;
  }
Example #7
0
  /**
   * This method returns the module that corresponds to the path passed as a parameter.
   *
   * @param name the name of the module we're looking for (e.g.: mod1.mod2)
   * @param dontSearchInit is used in a negative form because initially it was isLookingForRelative,
   *     but it actually defines if we should look in __init__ modules too, so, the name matches the
   *     old signature.
   *     <p>NOTE: isLookingForRelative description was: when looking for relative imports, we don't
   *     check for __init__
   * @return the module represented by this name
   */
  protected IModule getModule(
      boolean acceptCompiledModule, String name, IPythonNature nature, boolean dontSearchInit) {
    if (temporaryModules != null) {
      synchronized (lockTemporaryModules) {
        if (temporaryModules != null) {
          // who knows, maybe it became null at that point.
          FastStack<IModule> stack = temporaryModules.get(name);
          if (stack != null && stack.size() > 0) {
            if (DEBUG_TEMPORARY_MODULES) {
              System.out.println("Returning temporary module: " + name);
            }
            return stack.peek();
          }
        }
      }
    }
    AbstractModule n = null;
    ModulesKey keyForCacheAccess = new ModulesKey(null, null);

    if (!dontSearchInit) {
      if (n == null) {
        keyForCacheAccess.name = new StringBuffer(name).append(".__init__").toString();
        n = cache.getObj(keyForCacheAccess, this);
        if (n != null) {
          name += ".__init__";
        }
      }
    }
    if (n == null) {
      keyForCacheAccess.name = name;
      n = cache.getObj(keyForCacheAccess, this);
    }

    if (n instanceof SourceModule) {
      // ok, module exists, let's check if it is synched with the filesystem version...
      SourceModule s = (SourceModule) n;
      if (!s.isSynched()) {
        // change it for an empty and proceed as usual.
        n = (AbstractModule) addModule(createModulesKey(s.getName(), s.getFile()));
      }
    }

    if (n instanceof EmptyModule) {
      EmptyModule e = (EmptyModule) n;

      boolean found = false;

      if (!found && e.f != null) {

        if (!e.f.exists()) {
          // if the file does not exist anymore, just remove it.
          keyForCacheAccess.name = name;
          keyForCacheAccess.file = e.f;
          doRemoveSingleModule(keyForCacheAccess);
          n = null;

        } else {
          // file exists
          n = checkOverride(name, nature, n);

          if (n instanceof EmptyModule) {
            // ok, handle case where the file is actually from a zip file...
            if (e instanceof EmptyModuleForZip) {
              EmptyModuleForZip emptyModuleForZip = (EmptyModuleForZip) e;

              if (emptyModuleForZip.pathInZip.endsWith(".class") || !emptyModuleForZip.isFile) {
                // handle java class... (if it's a class or a folder in a jar)
                n = JythonModulesManagerUtils.createModuleFromJar(emptyModuleForZip);
                n = decorateModule(n, nature);

              } else if (FileTypesPreferencesPage.isValidDll(emptyModuleForZip.pathInZip)) {
                // .pyd
                n = new CompiledModule(name, IToken.TYPE_BUILTIN, nature.getAstManager());
                n = decorateModule(n, nature);

              } else if (PythonPathHelper.isValidSourceFile(emptyModuleForZip.pathInZip)) {
                // handle python file from zip... we have to create it getting the contents from the
                // zip file
                try {
                  IDocument doc =
                      REF.getDocFromZip(emptyModuleForZip.f, emptyModuleForZip.pathInZip);
                  // NOTE: The nature (and so the grammar to be used) must be defined by this
                  // modules
                  // manager (and not by the initial caller)!!
                  n =
                      AbstractModule.createModuleFromDoc(
                          name, emptyModuleForZip.f, doc, this.getNature(), -1, false);
                  SourceModule zipModule = (SourceModule) n;
                  zipModule.zipFilePath = emptyModuleForZip.pathInZip;
                  n = decorateModule(n, nature);
                } catch (Exception exc1) {
                  PydevPlugin.log(exc1);
                  n = null;
                }
              }

            } else {
              // regular case... just go on and create it.
              try {
                // NOTE: The nature (and so the grammar to be used) must be defined by this modules
                // manager (and not by the initial caller)!!
                n = AbstractModule.createModule(name, e.f, this.getNature(), -1);
                n = decorateModule(n, nature);
              } catch (IOException exc) {
                keyForCacheAccess.name = name;
                keyForCacheAccess.file = e.f;
                doRemoveSingleModule(keyForCacheAccess);
                n = null;
              } catch (MisconfigurationException exc) {
                PydevPlugin.log(exc);
                n = null;
              }
            }
          }
        }

      } else { // ok, it does not have a file associated, so, we treat it as a builtin (this can
               // happen in java jars)
        n = checkOverride(name, nature, n);
        if (n instanceof EmptyModule) {
          if (acceptCompiledModule) {
            n = new CompiledModule(name, IToken.TYPE_BUILTIN, nature.getAstManager());
            n = decorateModule(n, nature);
          } else {
            return null;
          }
        }
      }

      if (n != null) {
        doAddSingleModule(createModulesKey(name, e.f), n);
      } else {
        System.err.println("The module " + name + " could not be found nor created!");
      }
    }

    if (n instanceof EmptyModule) {
      throw new RuntimeException("Should not be an empty module anymore!");
    }
    if (n instanceof SourceModule) {
      SourceModule sourceModule = (SourceModule) n;
      // now, here's a catch... it may be a bootstrap module...
      if (sourceModule.isBootstrapModule()) {
        // if it's a bootstrap module, we must replace it for the related compiled module.
        n = new CompiledModule(name, IToken.TYPE_BUILTIN, nature.getAstManager());
        n = decorateModule(n, nature);
      }
    }

    return n;
  }
Example #8
0
  /**
   * @return the function name for this breakpoint.
   *     <p>A return of "None" signals that we couldn't discover the function name (so, we should
   *     try to match things in the whole file, and not only in the given context, as we don't know
   *     which context it is)
   */
  public String getFunctionName() {
    String fileStr = getFile();
    File file = fileStr != null ? new File(fileStr) : null;
    if (file == null || !file.exists()) {
      return "None";
    }

    if (file.lastModified() == lastModifiedTimeCached) {
      return functionName;
    }

    try {
      IPythonNature nature = getPythonNature();
      if (nature == null) {
        lastModifiedTimeCached = 0;
        return "None";
      }
      ICodeCompletionASTManager astManager = nature.getAstManager();
      if (astManager == null) {
        lastModifiedTimeCached = 0;
        return "None";
      }
      // Only mark it as found if we were able to get the python nature (otherwise, this could
      // change later
      // if requesting during a setup)
      if (nature.startRequests()) { // start requests, as we'll ask for resolve and get module.
        SourceModule sourceModule = null;
        try {
          String modName = nature.resolveModule(fileStr);
          if (modName != null) {
            // when all is set up, this is the most likely path we're going to use
            // so, we shouldn't have delays when the module is changed, as it's already
            // ok for use.
            IModule module = astManager.getModule(modName, nature, true);
            if (module instanceof SourceModule) {
              sourceModule = (SourceModule) module;
            }
          }
        } finally {
          nature.endRequests();
        }
        lastModifiedTimeCached = file.lastModified();

        if (sourceModule == null) {
          // the text for the breakpoint requires the function name, and it may be requested before
          // the ast manager is actually restored (so, modName is None, and we have little
          // alternative
          // but making a parse to get the function name)
          IDocument doc = getDocument();
          sourceModule = AbstractModule.createModuleFromDoc("", null, doc, nature, true);
        }

        int lineToUse = getLineNumber() - 1;

        if (sourceModule == null || sourceModule.getAst() == null || lineToUse < 0) {
          functionName = "None";
          return functionName;
        }

        SimpleNode ast = sourceModule.getAst();

        functionName = NodeUtils.getContextName(lineToUse, ast);
        if (functionName == null) {
          functionName = ""; // global context
        }
        return functionName;
      }
      // If it was found, it would've already returned. So, match anything as we couldn't determine
      // it.
      functionName = "None";

    } catch (Exception e) {
      // Some error happened determining it. Match anything.
      Log.log(
          "Error determining breakpoint context. Breakpoint at: "
              + file
              + " will match any context.",
          e);
      functionName = "None";
    }
    return functionName;
  }
  @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;
    }
  }
Example #10
0
  /**
   * @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;
    }
  }