public boolean beforePerformArrangeImports(PySelection ps, PyEdit edit, IFile f) {
    int oldSelection = ps.getRegion().getOffset();

    IDocumentExtension4 doc = (IDocumentExtension4) ps.getDoc();
    if (edit != null) {
      if (!ensureParsed(edit)) {
        return true;
      }
      // Check that the editor time is actually the same as the document time.
      long docTime = doc.getModificationStamp();

      if (docTime != edit.getAstModificationTimeStamp()) {
        return true;
      }
      ErrorDescription errorDescription = edit.getErrorDescription();
      if (errorDescription != null) {
        return true; // Don't remove unused imports if we have syntax errors.
      }
    }

    try {
      findAndDeleteUnusedImports(ps, edit, doc, f);
    } catch (Exception e) {
      Log.log(e);
    }
    ps.setSelection(oldSelection, oldSelection);
    return true;
  }
  public void run(IAction action) {
    PyEdit pyEdit = getPyEdit();
    PySelection ps = new PySelection(pyEdit);
    if (ps.getSelLength() != 0) {
      return;
    }
    try {
      IDocument doc = ps.getDoc();
      char c = doc.getChar(ps.getAbsoluteCursorOffset() - 1);
      boolean opening = StringUtils.isOpeningPeer(c);
      boolean closing = org.python.pydev.shared_core.string.StringUtils.isClosingPeer(c);

      if (opening || closing) {
        PythonPairMatcher matcher = new PythonPairMatcher();
        IRegion match = matcher.match(doc, ps.getAbsoluteCursorOffset());
        if (match != null) {
          if (closing) {
            pyEdit.setSelection(match.getOffset() + 1, 0);
          } else { // opening
            pyEdit.setSelection(match.getOffset() + match.getLength(), 0);
          }
        }
      }
    } catch (BadLocationException e) {
      return;
    }
  }
Beispiel #3
0
  /**
   * @return the module for the document (may return the ast from the pyedit if it is available).
   */
  public IModule getModule() {
    if (module == null) {
      if (pyEdit != null) {
        SimpleNode ast = pyEdit.getAST();
        if (ast != null) {
          IDocument doc = ps.getDoc();
          long astModificationTimeStamp = pyEdit.getAstModificationTimeStamp();
          if (astModificationTimeStamp != -1
              && astModificationTimeStamp == (((IDocumentExtension4) doc).getModificationStamp())) {
            // Matched time stamp -- so, we can use the ast without fear of being unsynched.
            module = AbstractModule.createModule(ast, file, resolveModule());
          } else {
            // Did not match time stamp!! We'll reparse the document later on to get a synched
            // version.
          }
        }
      }

      if (module == null) {
        try {
          module =
              AbstractModule.createModuleFromDoc(resolveModule(), file, ps.getDoc(), nature, false);
        } catch (MisconfigurationException e) {
          throw new RuntimeException(e);
        }
      }
    }
    return module;
  }
Beispiel #4
0
  /** @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) */
  public void run(IAction action) {
    try {
      if (!canModifyEditor()) {
        return;
      }

      PyEdit pyEdit = getPyEdit();
      PySelection ps = new PySelection(pyEdit);

      try {
        int[] regionsToFormat = null;
        if (ps.getSelLength() > 0) {
          int startLineIndex = ps.getStartLineIndex();
          int endLineIndex = ps.getEndLineIndex();
          regionsToFormat = new int[endLineIndex - startLineIndex + 1];
          for (int i = startLineIndex, j = 0; i <= endLineIndex; i++, j++) {
            regionsToFormat[j] = i;
          }
        } else {
          // For full-formatting, we cannot have a syntax error.
          if (pyEdit.hasSyntaxError(ps.getDoc())) {
            return;
          }
        }

        applyFormatAction(pyEdit, ps, regionsToFormat, true);
      } catch (SyntaxErrorException e) {
        pyEdit.getStatusLineManager().setErrorMessage(e.getMessage());
      }

    } catch (Exception e) {
      beep(e);
    }
  }
Beispiel #5
0
  /**
   * @param markOccurrencesRequest
   * @return true if the annotations were removed and added without any problems and false otherwise
   */
  @Override
  protected synchronized Map<Annotation, Position> getAnnotationsToAddAsMap(
      final BaseEditor baseEditor,
      IAnnotationModel annotationModel,
      MarkOccurrencesRequest markOccurrencesRequest,
      IProgressMonitor monitor)
      throws BadLocationException {
    PyEdit pyEdit = (PyEdit) baseEditor;
    PySourceViewer viewer = pyEdit.getPySourceViewer();
    if (viewer == null || monitor.isCanceled()) {
      return null;
    }
    if (viewer.getIsInToggleCompletionStyle() || monitor.isCanceled()) {
      return null;
    }

    PyMarkOccurrencesRequest pyMarkOccurrencesRequest =
        (PyMarkOccurrencesRequest) markOccurrencesRequest;
    Set<ASTEntry> occurrences = pyMarkOccurrencesRequest.getOccurrences();
    if (occurrences == null) {
      if (DEBUG) {
        System.out.println("Occurrences == null");
      }
      return null;
    }

    IDocument doc = pyEdit.getDocument();
    Map<Annotation, Position> toAddAsMap = new HashMap<Annotation, Position>();
    boolean markOccurrencesInStrings = MarkOccurrencesPreferencesPage.useMarkOccurrencesInStrings();

    // get the annotations to add
    for (ASTEntry entry : occurrences) {
      if (!markOccurrencesInStrings) {
        if (entry.node instanceof Name) {
          Name name = (Name) entry.node;
          if (name.ctx == Name.Artificial) {
            continue;
          }
        }
      }

      SimpleNode node = entry.getNameNode();
      IRegion lineInformation = doc.getLineInformation(node.beginLine - 1);

      try {
        Annotation annotation = new Annotation(getOccurrenceAnnotationsType(), false, "occurrence");
        Position position =
            new Position(
                lineInformation.getOffset() + node.beginColumn - 1,
                pyMarkOccurrencesRequest.getInitialName().length());
        toAddAsMap.put(annotation, position);

      } catch (Exception e) {
        Log.log(e);
      }
    }
    return toAddAsMap;
  }
 public static List<IMarker> getMarkersFromCurrentFile(PyEdit edit, int line) {
   return getMarkersFromEditorResource(
       PyMarkerUtils.getResourceForTextEditor(edit),
       edit.getDocument(),
       getExternalFileEditorInput(edit),
       line,
       true,
       edit.getAnnotationModel());
 }
  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();
    }
  }
 /** Requests proposals in the last location of the given editor. */
 protected ICompletionProposal[] requestProposals(String mod1Contents, PyEdit editor) {
   IContentAssistant contentAssistant =
       editor.getEditConfiguration().getContentAssistant(editor.getPySourceViewer());
   SimpleAssistProcessor processor =
       (SimpleAssistProcessor)
           contentAssistant.getContentAssistProcessor(IDocument.DEFAULT_CONTENT_TYPE);
   processor
       .doCycle(); // we want to show the default completions in this case (not the simple ones)
   ICompletionProposal[] props =
       processor.computeCompletionProposals(editor.getPySourceViewer(), mod1Contents.length());
   return props;
 }
Beispiel #9
0
 public void run(IAction action) {
   PyEdit pyEdit = getPyEdit();
   PySelection ps = new PySelection(pyEdit);
   try {
     Tuple<String, Integer> currToken = ps.getCurrToken();
     if (currToken.o1 != null) {
       int len = currToken.o1.length();
       if (len > 0) {
         pyEdit.selectAndReveal(currToken.o2, len);
       }
     }
   } catch (Exception e) {
     PydevPlugin.log(e);
   }
 }
Beispiel #10
0
  /**
   * This method applies the code-formatting to the document in the PySelection
   *
   * @param pyEdit used to restore the selection
   * @param ps the selection used (contains the document that'll be changed)
   * @param regionsToFormat if null or empty, the whole document will be formatted, otherwise, only
   *     the passed ranges will be formatted.
   * @throws SyntaxErrorException
   */
  public void applyFormatAction(
      PyEdit pyEdit, PySelection ps, int[] regionsToFormat, boolean throwSyntaxError)
      throws BadLocationException, SyntaxErrorException {
    final IFormatter participant = getFormatter();
    final IDocument doc = ps.getDoc();
    final SelectionKeeper selectionKeeper = new SelectionKeeper(ps);

    DocumentRewriteSession session = null;
    try {

      if (regionsToFormat == null || regionsToFormat.length == 0) {
        if (doc instanceof IDocumentExtension4) {
          IDocumentExtension4 ext = (IDocumentExtension4) doc;
          session = ext.startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL);
        }
        participant.formatAll(doc, pyEdit, null, true, throwSyntaxError);

      } else {
        if (doc instanceof IDocumentExtension4) {
          IDocumentExtension4 ext = (IDocumentExtension4) doc;
          session = ext.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL);
        }
        participant.formatSelection(doc, regionsToFormat, pyEdit, ps);
      }

    } finally {
      if (session != null) {
        ((IDocumentExtension4) doc).stopRewriteSession(session);
      }
    }

    selectionKeeper.restoreSelection(pyEdit.getSelectionProvider(), doc);
  }
  public RemoveCoverageMarkersListener(IDocument document, PyEdit edit, IFile file) {
    this.doc = document;
    this.edit = edit;
    this.file = file;

    document.addDocumentListener(this);
    edit.addPyeditListener(this);
  }
Beispiel #12
0
  /** @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) */
  public void run(IAction action) {
    try {
      if (!canModifyEditor()) {
        return;
      }

      PyEdit pyEdit = getPyEdit();
      PySelection ps = new PySelection(pyEdit);

      try {
        applyFormatAction(pyEdit, ps, false, true);
      } catch (SyntaxErrorException e) {
        pyEdit.getStatusLineManager().setErrorMessage(e.getMessage());
      }

    } catch (Exception e) {
      beep(e);
    }
  }
 /** This is the apply that should actually be called! */
 public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
   IDocument document = viewer.getDocument();
   if (viewer instanceof PySourceViewer) {
     PySourceViewer pySourceViewer = (PySourceViewer) viewer;
     PyEdit pyEdit = pySourceViewer.getEdit();
     this.indentString = pyEdit.getIndentPrefs().getIndentationString();
   } else {
     // happens on compare editor
     this.indentString = new DefaultIndentPrefs().getIndentationString();
   }
   // If the completion is applied with shift pressed, do a local import. Note that the user is
   // only actually
   // able to do that if the popup menu is focused (i.e.: request completion and do a tab to focus
   // it, instead
   // of having the focus on the editor and just pressing up/down).
   if ((stateMask & SWT.SHIFT) != 0) {
     this.setAddLocalImport(true);
   }
   apply(document, trigger, stateMask, offset);
 }
Beispiel #14
0
  public RefactoringInfo(PyEdit edit, ITextSelection selection) throws MisconfigurationException {
    IEditorInput input = edit.getEditorInput();
    this.indentPrefs = edit.getIndentPrefs();
    IPythonNature localNature = edit.getPythonNature();

    if (input instanceof IFileEditorInput) {
      IFileEditorInput editorInput = (IFileEditorInput) input;
      this.sourceFile = editorInput.getFile();
      this.realFile = sourceFile != null ? sourceFile.getLocation().toFile() : null;
    } else {
      this.realFile = edit.getEditorFile();
    }

    if (localNature == null) {
      Tuple<IPythonNature, String> infoForFile = PydevPlugin.getInfoForFile(this.realFile);
      if (infoForFile != null && infoForFile.o1 != null) {
        localNature = infoForFile.o1;
      }
    }
    this.nature = localNature;

    this.doc = edit.getDocument();

    this.project = edit.getProject();
    versionProvider = this.nature;
    initInfo(selection);
  }
Beispiel #15
0
  /**
   * Gets the command to send to the console (either the selected text or a runfile with the
   * editor).
   */
  private static String getCommandToSend(PyEdit edit, PySelection selection) {
    String cmd = null;
    String code = selection.getTextSelection().getText();

    if (code.length() != 0) {
      cmd = code + "\n";
    } else {
      // no code available: do a runfile in the current context
      File editorFile = edit.getEditorFile();

      if (editorFile != null) {
        cmd = PythonSnippetUtils.getRunfileCommand(editorFile);
      }
    }
    return cmd;
  }
Beispiel #16
0
  /**
   * This method applies the code-formatting to the document in the PySelection
   *
   * @param pyEdit used to restore the selection
   * @param ps the selection used (contains the document that'll be changed)
   * @param forceFormatAll whether the full formatting (and not the selection formatting) should be
   *     applied.
   * @param throwSyntaxError
   * @throws SyntaxErrorException
   */
  public void applyFormatAction(
      PyEdit pyEdit, PySelection ps, boolean forceFormatAll, boolean throwSyntaxError)
      throws BadLocationException, SyntaxErrorException {
    final IFormatter participant = getFormatter();
    final IDocument doc = ps.getDoc();
    final ITextSelection selection = ps.getTextSelection();
    final int startLine = ps.getStartLineIndex();
    final SelectionKeeper selectionKeeper = new SelectionKeeper(ps);

    if (selection.getLength() == 0 || forceFormatAll) {
      participant.formatAll(doc, pyEdit, true, throwSyntaxError);
    } else {
      participant.formatSelection(doc, startLine, ps.getEndLineIndex(), pyEdit, ps);
    }

    selectionKeeper.restoreSelection(pyEdit.getSelectionProvider(), doc);
  }
  private ArrayList<IDefinition> findDefinitions(
      IPythonNature nature, PyEdit edit, int start, IDocument doc) {
    CompletionCache completionCache = new CompletionCache();
    ArrayList<IDefinition> selected = new ArrayList<IDefinition>();

    RefactoringRequest request =
        new RefactoringRequest(
            edit.getEditorFile(),
            new PySelection(doc, new TextSelection(doc, start, 0)),
            new NullProgressMonitor(),
            nature,
            edit);

    try {
      PyRefactoringFindDefinition.findActualDefinition(request, completionCache, selected);
    } catch (CompletionRecursionException | BadLocationException e1) {
      Log.log(e1);
    }
    return selected;
  }
  private void findAndDeleteUnusedImports(
      PySelection ps, PyEdit edit, IDocumentExtension4 doc, IFile f) throws Exception {
    Iterator<MarkerAnnotationAndPosition> it;
    if (edit != null) {
      it = edit.getPySourceViewer().getMarkerIterator();
    } else {

      IMarker markers[] =
          f.findMarkers(IMiscConstants.PYDEV_ANALYSIS_PROBLEM_MARKER, true, IResource.DEPTH_ZERO);
      MarkerAnnotationAndPosition maap[] = new MarkerAnnotationAndPosition[markers.length];
      int ix = 0;
      for (IMarker m : markers) {
        int start = (Integer) m.getAttribute(IMarker.CHAR_START);
        int end = (Integer) m.getAttribute(IMarker.CHAR_END);
        maap[ix++] =
            new MarkerAnnotationAndPosition(
                new MarkerAnnotation(m), new Position(start, end - start));
      }
      it = Arrays.asList(maap).iterator();
    }
    ArrayList<MarkerAnnotationAndPosition> unusedImportsMarkers = getUnusedImports(it);
    sortInReverseDocumentOrder(unusedImportsMarkers);
    deleteImports(doc, ps, unusedImportsMarkers);
  }
  /**
   * Performs the action with a given PySelection
   *
   * @param ps Given PySelection
   * @return boolean The success or failure of the action
   */
  public int perform(PySelection ps) {
    // What we'll be replacing the selected text with
    FastStringBuffer strbuf = new FastStringBuffer();

    try {
      // discover 1st line that starts the block comment
      int i;
      int startLineIndex = getStartIndex(ps);
      int endLineIndex = getEndIndex(ps);
      if (startLineIndex == -1 || endLineIndex == -1) {
        if (startLineIndex == -1 && endLineIndex == -1) {
          return -1;
        } else if (startLineIndex == -1) {
          startLineIndex = endLineIndex;
        } else {
          endLineIndex = startLineIndex;
        }
      }

      // For each line, uncomment it
      for (i = startLineIndex; i <= endLineIndex; i++) {
        boolean addDelim = true;
        String spacesBefore = "";
        String line = ps.getLine(i);
        int lineLen = line.length();
        for (int j = 0; j < lineLen; j++) {
          char c = line.charAt(j);
          if (c == '#') {
            // ok, it starts with # (so, remove the whitespaces before it)
            if (j > 0) {
              spacesBefore = line.substring(0, j);
            }
            line = line.substring(j);
            break;
          } else {
            if (!Character.isWhitespace(c)) {
              break;
            }
          }
        }
        if (line.startsWith("#")) {
          line = line.substring(1);
        }

        // get the chars used in block-comments
        AbstractBlockCommentAction[] acts =
            new AbstractBlockCommentAction[] {
              new PyAddSingleBlockComment(), new PyAddBlockComment()
            };
        HashSet<Character> chars = new HashSet<Character>();
        for (int j = 0; j < acts.length; j++) {
          AbstractBlockCommentAction action = acts[j];
          chars.add(action.getColsAndChar().o2);
        }

        if (line.length() > 0) {
          boolean removedChar = false;
          char lastChar = '\0';
          for (int j = 0; j < line.length(); j++) {
            lastChar = line.charAt(j);
            if (!chars.contains(lastChar)) {
              break;
            } else {
              removedChar = true;
              line = line.substring(1);
              j--;
            }
          }
          if (line.length() == 0 && removedChar) {
            addDelim = false;
          }
          if (removedChar && lastChar == ' ') {
            line = line.substring(1);
          }
        }

        if (addDelim) {
          strbuf.append(spacesBefore);
          strbuf.append(line);
          String lineDelimiter = ps.getDoc().getLineDelimiter(i);
          if (lineDelimiter != null) {
            strbuf.append(lineDelimiter);
          }
        }
      }

      // Ok, at this point things should be correct, but make sure than on uncomment,
      // the code goes to a proper indent position (remove spaces we may have added when creating a
      // block).
      String string = strbuf.toString();
      List<String> lines = StringUtils.splitInLines(string);
      Tuple<Integer, String> posAndLine = new Tuple<Integer, String>(-1, "");
      for (String line : lines) {
        int firstCharPosition = PySelection.getFirstCharPosition(line);
        if (firstCharPosition < posAndLine.o1 || posAndLine.o1 < 0) {
          posAndLine.o1 = firstCharPosition;
          posAndLine.o2 = line;
        }
      }
      if (posAndLine.o1 > 0) {
        final String sub = posAndLine.o2.substring(0, posAndLine.o1);
        if (sub.endsWith(
            " ")) { // If it ends with a tab, we won't change anything (only spaces are removed --
                    // which we may have introduced)
          boolean allEqual = true;
          for (String line : lines) {
            if (!line.startsWith(sub)) {
              allEqual = false;
              break;
            }
          }
          if (allEqual) {
            if (sub.startsWith("\t")) {
              // Tabs based indent: remove any ending spaces (and at this point we know a string
              // ends with a space)
              int j;
              for (j = sub.length() - 1; j >= 0; j--) {
                char c = sub.charAt(j);
                if (c != ' ') {
                  j++;
                  break;
                }
              }
              String newSub = sub.substring(0, j);
              strbuf.clear();
              for (String line : lines) {
                strbuf.append(newSub);
                strbuf.append(line.substring(sub.length()));
              }

            } else {
              IIndentPrefs indentPrefs;
              if (targetEditor instanceof PyEdit) {
                PyEdit pyEdit = (PyEdit) targetEditor;
                indentPrefs = pyEdit.getIndentPrefs();
              } else {
                indentPrefs = DefaultIndentPrefs.get();
              }

              String indentationString = indentPrefs.getIndentationString();

              int subLen = sub.length();
              int indentLen = indentationString.length();
              int mod = subLen % indentLen;
              if (mod != 0) {
                String substring = sub.substring(subLen - mod, subLen);
                boolean onlyWhitespaces = true;
                for (int k = 0; k < substring.length(); k++) {
                  if (substring.charAt(k) != ' ') {
                    onlyWhitespaces = false;
                    break;
                  }
                }
                if (onlyWhitespaces) {
                  String newSub = sub.substring(0, subLen - mod);
                  strbuf.clear();
                  for (String line : lines) {
                    strbuf.append(newSub);
                    strbuf.append(line.substring(sub.length()));
                  }
                }
              }
            }
          }
        }
      }

      // Replace the text with the modified information
      int startLineOffset = ps.getLineOffset(startLineIndex);
      int endLineOffset = ps.getEndLineOffset(endLineIndex);
      String endLineDelimiter = ps.getDoc().getLineDelimiter(endLineIndex);
      if (endLineDelimiter != null) {
        endLineOffset += endLineDelimiter.length();
      }
      String str = strbuf.toString();
      ps.getDoc().replace(startLineOffset, endLineOffset - startLineOffset, str);
      return startLineOffset + str.length();
    } catch (Exception e) {
      beep(e);
    }

    // In event of problems, return false
    return -1;
  }
Beispiel #20
0
 /**
  * If the file is passed, we also set the document automatically
  *
  * @param file the file correspondent to this request
  * @throws MisconfigurationException
  */
 public RefactoringRequest(PyEdit pyEdit, PySelection ps) throws MisconfigurationException {
   this(pyEdit.getEditorFile(), ps, null, pyEdit.getPythonNature(), pyEdit);
 }
  @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;
    }
  }
 public void onDispose(PyEdit edit, IProgressMonitor monitor) {
   IEditorInput input = edit.getEditorInput();
   // remove the markers if we want problems only in the active editor.
   removeMarkersFromInput(input);
 }
Beispiel #23
0
 public RefactoringInfo(PyEdit edit) throws MisconfigurationException {
   this(edit, (ITextSelection) edit.getSelectionProvider().getSelection());
 };
  private boolean ensureParsed(PyEdit edit) {
    // Ok, we have a little problem here: we have to ensure not that only a regular ast parse took
    // place, but
    // that the analysis of the related document is updated (so that the markers are in-place).
    // To do that, we ask for a reparse asking to analyze the results in that same thread (without
    // scheduling it).
    //
    // Maybe better would be having some extension that allowed to call the analysis of the document
    // directly
    // (so we don't have to rely on markers in place?)
    final PyParser parser = edit.getParser();
    final boolean[] notified = new boolean[] {false};
    final Object sentinel = new Object();

    parser.addPostParseListener(
        new IPostParserListener() {

          @Override
          public void participantsNotified(Object... argsToReparse) {
            synchronized (OrganizeImportsFixesUnused.this) {
              parser.removePostParseListener(this);
              if (argsToReparse.length == 2 && argsToReparse[1] == sentinel) {
                notified[0] = true;
                OrganizeImportsFixesUnused.this.notify();
              }
            }
          }
        });

    long initial = System.currentTimeMillis();
    while ((System.currentTimeMillis() - initial) < 5000) {

      if (parser.forceReparse(
          new Tuple<String, Boolean>(
              IMiscConstants.ANALYSIS_PARSER_OBSERVER_FORCE_IN_THIS_THREAD, true),
          sentinel)) {
        // ok, we were able to schedule it with our parameters, let's wait for its completion...
        synchronized (this) {
          try {
            wait(5000);
          } catch (InterruptedException e) {
          }
        }
        break;
      } else {
        synchronized (this) {
          try {
            wait(200);
          } catch (InterruptedException e) {
          }
        }
      }
    }

    // Commented out: in the worse case, we already waited 5 seconds, if because of a racing
    // condition we couldn't decide
    // that it worked, let's just keep on going hoping that the markers are in place...
    // if (!notified[0]) {
    //    return false;
    // }
    return true;
  }