Beispiel #1
0
 private void checkIt(
     SimpleNode simpleNode,
     SourceToken token,
     String rep,
     String relativeImport,
     String originalRep) {
   assertEquals(rep, token.getRepresentation());
   assertSame(simpleNode, token.getAst());
   assertEquals(relativeImport, token.getAsRelativeImport(MODULE_NAME));
   assertEquals(originalRep, token.getOriginalRep());
 }
Beispiel #2
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;
  }
Beispiel #3
0
  /** @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]);
  }
Beispiel #4
0
  /**
   * adds a message for something that was not used
   *
   * @param node the node representing the scope being closed when adding the unused message
   */
  public void addUnusedMessage(SimpleNode node, Found f) {
    for (GenAndTok g : f) {
      if (g.generator instanceof SourceToken) {
        SimpleNode ast = ((SourceToken) g.generator).getAst();

        // it can be an unused import
        if (ast instanceof Import || ast instanceof ImportFrom) {
          if (AbstractVisitor.isWildImport(ast)) {
            addMessage(IAnalysisPreferences.TYPE_UNUSED_WILD_IMPORT, g.generator, g.tok);
          } else if (!(g.generator instanceof ImportPartSourceToken)) {
            addMessage(IAnalysisPreferences.TYPE_UNUSED_IMPORT, g.generator, g.tok);
          }
          continue; // finish it...
        }
      }

      // or unused variable
      // we have to check if this is a name we should ignore
      if (startsWithNamesToIgnore(g)) {
        int type = IAnalysisPreferences.TYPE_UNUSED_VARIABLE;

        if (g.tok instanceof SourceToken) {
          SourceToken t = (SourceToken) g.tok;
          SimpleNode ast = t.getAst();
          if (ast instanceof NameTok) {
            NameTok n = (NameTok) ast;
            if (n.ctx == NameTok.KwArg || n.ctx == NameTok.VarArg || n.ctx == NameTok.KeywordName) {
              type = IAnalysisPreferences.TYPE_UNUSED_PARAMETER;
            }
          } else if (ast instanceof Name) {
            Name n = (Name) ast;
            if (n.ctx == Name.Param || n.ctx == Name.KwOnlyParam) {
              type = IAnalysisPreferences.TYPE_UNUSED_PARAMETER;
            }
          }
        }
        boolean addMessage = true;
        if (type == IAnalysisPreferences.TYPE_UNUSED_PARAMETER) {
          // just add unused parameters in methods that have some content (not only 'pass' and
          // 'strings')

          if (node instanceof FunctionDef) {
            addMessage = false;
            FunctionDef def = (FunctionDef) node;
            for (stmtType b : def.body) {
              if (b instanceof Pass) {
                continue;
              }
              if (b instanceof Expr) {
                Expr expr = (Expr) b;
                if (expr.value instanceof Str) {
                  continue;
                }
              }
              addMessage = true;
              break;
            }
          }
        } // END if (type == IAnalysisPreferences.TYPE_UNUSED_PARAMETER)

        if (addMessage) {
          addMessage(type, g.generator, g.tok);
        }
      }
    }
  }