/**
   * On-save operations :
   *
   * <p>* Un-wrapping if needed
   *
   * <p>* Auto section markers normalization
   *
   * <p>* Auto formating when the editor saves the file
   *
   * @param aSourceViewer The editor source viewer
   */
  public void onEditorPerformSave(final ISourceViewer aSourceViewer) {

    final IDocument document = aSourceViewer.getDocument();

    if (pPreferenceStore.getBoolean(IEditorPreferenceConstants.EDITOR_SAVE_RESET_MARKERS)) {
      // Auto section blocks normalization

      RestContentOutlinePage outlinePage = null;

      if (pEditor != null) {
        outlinePage = pEditor.getOutlinePage();
      }

      if (outlinePage != null) {

        // Don't forget to refresh the tree !
        outlinePage.update();

        OutlineUtil.normalizeSectionsMarker(
            pEditor.getOutlinePage().getContentProvider().getRoot());
      }
    }

    // Formatting text _must_ be the last thing to do : it modifies the
    // document content, therefore it may induce unpredictable behavior for
    // next document readers
    if (pPreferenceStore.getBoolean(IEditorPreferenceConstants.EDITOR_SAVE_FORMAT)) {
      // Text format on save

      // Doc informations
      IRegion docRegion = new Region(0, document.getLength());

      // Store current pointer location
      Point currentLocation = aSourceViewer.getSelectedRange();

      // Format the document
      pDocFormatter.format(document, docRegion);

      // Reset point location
      aSourceViewer.setSelectedRange(currentLocation.x, currentLocation.y);
    }

    if (LineWrapUtil.get().isActiveMode(LineWrapMode.SOFT)) {
      // Soft wrap mode : remove all added end-of-line

      pAutoEditLineWrap.unregisterListener();
      pAutoEditLineWrap.removeWrapping();
    }
  }
  /*
   * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)
   */
  @Override
  public ICompletionProposal[] computeQuickAssistProposals(
      IQuickAssistInvocationContext quickAssistContext) {
    ISourceViewer viewer = quickAssistContext.getSourceViewer();
    int documentOffset = quickAssistContext.getOffset();

    int length = viewer != null ? viewer.getSelectedRange().y : -1;
    TextInvocationContext context = new TextInvocationContext(viewer, documentOffset, length);

    IAnnotationModel model = viewer.getAnnotationModel();
    if (model == null) return fgNoSuggestionsProposal;

    List<ICompletionProposal> proposals = computeProposals(context, model);
    if (proposals.isEmpty()) return fgNoSuggestionsProposal;

    return proposals.toArray(new ICompletionProposal[proposals.size()]);
  }
  @Override
  public ICompletionProposal[] computeQuickAssistProposals(
      IQuickAssistInvocationContext quickAssistContext) {
    ISourceViewer viewer = quickAssistContext.getSourceViewer();
    int documentOffset = quickAssistContext.getOffset();

    IEditorPart part = fAssistant.getEditor();

    CompilationUnit cu = DartUI.getWorkingCopyManager().getWorkingCopy(part.getEditorInput());
    IAnnotationModel model = DartUI.getDocumentProvider().getAnnotationModel(part.getEditorInput());

    AssistContext context = null;
    if (cu != null) {
      int length = viewer != null ? viewer.getSelectedRange().y : 0;
      context = new AssistContext(cu, viewer, part, documentOffset, length);
    }

    Annotation[] annotations = fAssistant.getAnnotationsAtOffset();

    fErrorMessage = null;

    ICompletionProposal[] res = null;
    if (model != null && context != null && annotations != null) {
      List<IDartCompletionProposal> proposals = Lists.newArrayList();
      IStatus status =
          collectProposals(
              context, model, annotations, true, !fAssistant.isUpdatedOffset(), proposals);
      res = proposals.toArray(new ICompletionProposal[proposals.size()]);
      if (!status.isOK()) {
        fErrorMessage = status.getMessage();
        DartToolsPlugin.log(status);
      }
    }

    if (res == null || res.length == 0) {
      return new ICompletionProposal[] {
        new ChangeCorrectionProposal(
            CorrectionMessages.NoCorrectionProposal_description, new NullChange(""), 0, null)
      }; //$NON-NLS-1$
    }
    if (res.length > 1) {
      Arrays.sort(res, new CompletionProposalComparator());
    }
    return res;
  }
  public void start() {
    if (getActiveLinkedMode() != null) {
      // for safety; should already be handled in RenameDartElementAction
      fgActiveLinkedMode.startFullDialog();
      return;
    }

    ISourceViewer viewer = fEditor.getViewer();
    IDocument document = viewer.getDocument();
    fOriginalSelection = viewer.getSelectedRange();
    int offset = fOriginalSelection.x;

    try {
      fLinkedPositionGroup = new LinkedPositionGroup();
      prepareElement();
      if (fDartElement == null) {
        return;
      }

      if (viewer instanceof ITextViewerExtension6) {
        IUndoManager undoManager = ((ITextViewerExtension6) viewer).getUndoManager();
        if (undoManager instanceof IUndoManagerExtension) {
          IUndoManagerExtension undoManagerExtension = (IUndoManagerExtension) undoManager;
          IUndoContext undoContext = undoManagerExtension.getUndoContext();
          IOperationHistory operationHistory = OperationHistoryFactory.getOperationHistory();
          fStartingUndoOperation = operationHistory.getUndoOperation(undoContext);
        }
      }

      fOriginalName = nameNode.getName();
      final int pos = nameNode.getOffset();
      final List<ASTNode> sameNodes = Lists.newArrayList();
      nameNode
          .getRoot()
          .accept(
              new RecursiveASTVisitor<Void>() {
                @Override
                public Void visitSimpleIdentifier(SimpleIdentifier node) {
                  Element element = node.getElement();
                  element = getCanonicalElement(element);
                  if (Objects.equal(element, fDartElement)) {
                    sameNodes.add(node);
                  }
                  return super.visitSimpleIdentifier(node);
                }
              });

      // TODO: copied from LinkedNamesAssistProposal#apply(..):
      // sort for iteration order, starting with the node @ offset
      Collections.sort(
          sameNodes,
          new Comparator<ASTNode>() {
            @Override
            public int compare(ASTNode o1, ASTNode o2) {
              return rank(o1) - rank(o2);
            }

            /**
             * Returns the absolute rank of an <code>ASTNode</code>. Nodes preceding <code>pos
             * </code> are ranked last.
             *
             * @param node the node to compute the rank for
             * @return the rank of the node with respect to the invocation offset
             */
            private int rank(ASTNode node) {
              int relativeRank = node.getOffset() + node.getLength() - pos;
              if (relativeRank < 0) {
                return Integer.MAX_VALUE + relativeRank;
              } else {
                return relativeRank;
              }
            }
          });
      for (int i = 0; i < sameNodes.size(); i++) {
        ASTNode elem = sameNodes.get(i);
        LinkedPosition linkedPosition =
            new LinkedPosition(document, elem.getOffset(), elem.getLength(), i);
        if (i == 0) {
          fNamePosition = linkedPosition;
        }
        fLinkedPositionGroup.addPosition(linkedPosition);
      }

      fLinkedModeModel = new LinkedModeModel();
      fLinkedModeModel.addGroup(fLinkedPositionGroup);
      fLinkedModeModel.forceInstall();
      fLinkedModeModel.addLinkingListener(new EditorHighlightingSynchronizer(fEditor));
      fLinkedModeModel.addLinkingListener(new EditorSynchronizer());

      LinkedModeUI ui = new EditorLinkedModeUI(fLinkedModeModel, viewer);
      ui.setExitPosition(viewer, offset, 0, Integer.MAX_VALUE);
      ui.setExitPolicy(new ExitPolicy(document));
      ui.enter();

      viewer.setSelectedRange(
          fOriginalSelection.x,
          fOriginalSelection.y); // by default, full word is selected; restore original selection

      if (viewer instanceof IEditingSupportRegistry) {
        IEditingSupportRegistry registry = (IEditingSupportRegistry) viewer;
        registry.register(fFocusEditingSupport);
      }

      openSecondaryPopup();
      //			startAnimation();
      fgActiveLinkedMode = this;

    } catch (BadLocationException e) {
      DartToolsPlugin.log(e);
    }
  }
    /**
     * (non-Javadoc)
     *
     * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent)
     */
    @SuppressWarnings("fallthrough")
    public void verifyKey(VerifyEvent event) {

      if (!event.doit || getInsertMode() != SMART_INSERT) {
        return;
      }

      ISourceViewer sourceViewer = getSourceViewer();
      IDocument document = sourceViewer.getDocument();

      final Point selection = sourceViewer.getSelectedRange();
      final int offset = selection.x;
      final int length = selection.y;

      switch (event.character) {
        case ']':
          if (!this.fCloseBrackets) {
            return;
          }
          // Fall through

        case ')':
          if (hasCharacterAtOffset(document, offset + length, event.character)) {
            sourceViewer.setSelectedRange(offset + length + 1, 0);
            event.doit = false;
            return;
          }
          break;

        case '(':
          if (hasCharacterToTheRight(document, offset + length, '(')) return;

          // fall through

        case '[':
          if (!this.fCloseBrackets) return;
          if (hasIdentifierToTheRight(document, offset + length)) return;

          // fall through

        case '\'':
          if (event.character == '\'') {
            if (!this.fCloseStrings) return;

            if (hasCharacterAtOffset(document, offset - 1, '\\')) {
              return;
            }

            if (hasCharacterAtOffset(document, offset + length, '\'')) {
              sourceViewer.setSelectedRange(offset + length + 1, 0);
              event.doit = false;
              return;
            }

            if (hasIdentifierToTheLeft(document, offset)
                || hasIdentifierToTheRight(document, offset + length)) {
              return;
            }
          }

          // fall through

        case '"':
          if (event.character == '"') {
            if (!this.fCloseStrings) return;

            if (hasCharacterAtOffset(document, offset - 1, '\\')) {
              return;
            }
            if (hasCharacterAtOffset(document, offset + length, '"')) {
              sourceViewer.setSelectedRange(offset + length + 1, 0);
              event.doit = false;
              return;
            }

            if (hasIdentifierToTheLeft(document, offset)
                || hasIdentifierToTheRight(document, offset + length)) return;
          }

          try {
            //					ITypedRegion partition= TextUtilities.getPartition(document,
            // IJavaPartitions.JAVA_PARTITIONING, offset, true);
            ////					if (! IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()) &&
            // partition.getOffset() != offset)
            //					if (! IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()))
            //						return;
            //
            if (!validateEditorInputState()) {
              return;
            }

            final StringBuffer buffer = new StringBuffer();
            buffer.append(event.character);
            buffer.append(getPeerCharacter(event.character));

            document.replace(offset, length, buffer.toString());

            // move to the right of the inserted element
            sourceViewer.setSelectedRange(offset + 1, 0);

            //
            //					BracketLevel level= new BracketLevel();
            //					fBracketLevelStack.push(level);
            //
            //					LinkedPositionGroup group= new LinkedPositionGroup();
            //					group.addPosition(new LinkedPosition(document, offset + 1, 0,
            // LinkedPositionGroup.NO_STOP));
            //
            //					LinkedModeModel model= new LinkedModeModel();
            //					model.addLinkingListener(this);
            //					model.addGroup(group);
            //					model.forceInstall();
            //
            //					level.fOffset= offset;
            //					level.fLength= 2;
            //
            //					// set up position tracking for our magic peers
            //					if (fBracketLevelStack.size() == 1) {
            //						document.addPositionCategory(CATEGORY);
            //						document.addPositionUpdater(fUpdater);
            //					}
            //					level.fFirstPosition= new Position(offset, 1);
            //					level.fSecondPosition= new Position(offset + 1, 1);
            //					document.addPosition(CATEGORY, level.fFirstPosition);
            //					document.addPosition(CATEGORY, level.fSecondPosition);
            //
            //					level.fUI= new EditorLinkedModeUI(model, sourceViewer);
            //					level.fUI.setSimpleMode(true);
            //					level.fUI.setExitPolicy(new ExitPolicy(closingCharacter,
            // getEscapeCharacter(closingCharacter), fBracketLevelStack));
            //					level.fUI.setExitPosition(sourceViewer, offset + 2, 0, Integer.MAX_VALUE);
            //					level.fUI.setCyclingMode(LinkedModeUI.CYCLE_NEVER);
            //					level.fUI.enter();
            //
            //
            //					IRegion newSelection= level.fUI.getSelectedRegion();
            // sourceViewer.setSelectedRange(newSelection.getOffset(), newSelection.getLength());

            event.doit = false;

          } catch (BadLocationException e) {
            BPELUIPlugin.log(e);
          }
          //					catch (BadPositionCategoryException e) {
          //					BPELUIPlugin.log(e);
          //				}
          break;
      }
    }
  public void start() {
    if (getActiveLinkedMode() != null) {
      // for safety; should already be handled in RenameDartElementAction
      fgActiveLinkedMode.startFullDialog();
      return;
    }

    ISourceViewer viewer = fEditor.getViewer();
    IDocument document = viewer.getDocument();
    fOriginalSelection = viewer.getSelectedRange();
    int offset = fOriginalSelection.x;

    try {
      DartUnit root =
          ASTProvider.getASTProvider().getAST(getCompilationUnit(), ASTProvider.WAIT_YES, null);

      fLinkedPositionGroup = new LinkedPositionGroup();
      DartNode selectedNode = NodeFinder.perform(root, fOriginalSelection.x, fOriginalSelection.y);
      if (!(selectedNode instanceof DartIdentifier)) {
        return; // TODO: show dialog
      }
      DartIdentifier nameNode = (DartIdentifier) selectedNode;

      if (viewer instanceof ITextViewerExtension6) {
        IUndoManager undoManager = ((ITextViewerExtension6) viewer).getUndoManager();
        if (undoManager instanceof IUndoManagerExtension) {
          IUndoManagerExtension undoManagerExtension = (IUndoManagerExtension) undoManager;
          IUndoContext undoContext = undoManagerExtension.getUndoContext();
          IOperationHistory operationHistory = OperationHistoryFactory.getOperationHistory();
          fStartingUndoOperation = operationHistory.getUndoOperation(undoContext);
        }
      }

      fOriginalName = nameNode.getName();
      final int pos = nameNode.getSourceInfo().getOffset();
      DartNode[] sameNodes = LinkedNodeFinder.findByNode(root, nameNode);

      // TODO: copied from LinkedNamesAssistProposal#apply(..):
      // sort for iteration order, starting with the node @ offset
      Arrays.sort(
          sameNodes,
          new Comparator<DartNode>() {
            @Override
            public int compare(DartNode o1, DartNode o2) {
              return rank(o1) - rank(o2);
            }

            /**
             * Returns the absolute rank of an <code>DartNode</code>. Nodes preceding <code>pos
             * </code> are ranked last.
             *
             * @param node the node to compute the rank for
             * @return the rank of the node with respect to the invocation offset
             */
            private int rank(DartNode node) {
              int relativeRank =
                  node.getSourceInfo().getOffset() + node.getSourceInfo().getLength() - pos;
              if (relativeRank < 0) {
                return Integer.MAX_VALUE + relativeRank;
              } else {
                return relativeRank;
              }
            }
          });
      for (int i = 0; i < sameNodes.length; i++) {
        DartNode elem = sameNodes[i];
        LinkedPosition linkedPosition =
            new LinkedPosition(
                document, elem.getSourceInfo().getOffset(), elem.getSourceInfo().getLength(), i);
        if (i == 0) {
          fNamePosition = linkedPosition;
        }
        fLinkedPositionGroup.addPosition(linkedPosition);
      }

      fLinkedModeModel = new LinkedModeModel();
      fLinkedModeModel.addGroup(fLinkedPositionGroup);
      fLinkedModeModel.forceInstall();
      fLinkedModeModel.addLinkingListener(new EditorHighlightingSynchronizer(fEditor));
      fLinkedModeModel.addLinkingListener(new EditorSynchronizer());

      LinkedModeUI ui = new EditorLinkedModeUI(fLinkedModeModel, viewer);
      ui.setExitPosition(viewer, offset, 0, Integer.MAX_VALUE);
      ui.setExitPolicy(new ExitPolicy(document));
      ui.enter();

      viewer.setSelectedRange(
          fOriginalSelection.x,
          fOriginalSelection.y); // by default, full word is selected; restore original selection

      if (viewer instanceof IEditingSupportRegistry) {
        IEditingSupportRegistry registry = (IEditingSupportRegistry) viewer;
        registry.register(fFocusEditingSupport);
      }

      openSecondaryPopup();
      //			startAnimation();
      fgActiveLinkedMode = this;

    } catch (BadLocationException e) {
      DartToolsPlugin.log(e);
    }
  }
示例#7
0
  private void checkResourceFix(String name, String caretLocation, String expectedNewPath)
      throws Exception {
    IProject project = getProject();
    IFile file = getTestDataFile(project, name, FD_RES + "/" + FD_RES_LAYOUT + "/" + name);

    // Determine the offset
    final int offset = getCaretOffset(file, caretLocation);

    String osRoot = project.getLocation().toOSString();
    List<String> errors = new ArrayList<String>();
    String fileRelativePath = file.getProjectRelativePath().toPortableString();
    String filePath = osRoot + File.separator + fileRelativePath;
    // Run AaptParser such that markers are added...
    // When debugging these tests, the project gets a chance to build itself
    // so
    // the real aapt errors are there. But when the test is run directly,
    // aapt has
    // not yet run. I tried waiting for the build (using the code in
    // SampleProjectTest)
    // but this had various adverse effects (exception popups from the
    // Eclipse debugger
    // etc) so instead this test just hardcodes the aapt errors that should
    // be
    // observed on quickfix1.xml.
    assertEquals("Unit test is hardcoded to errors for quickfix1.xml", "quickfix1.xml", name);
    errors.add(
        filePath
            + ":7: error: Error: No resource found that matches the given name"
            + " (at 'text' with value '@string/firststring').");
    errors.add(
        filePath
            + ":7: error: Error: No resource found that matches the given name"
            + " (at 'layout_width' with value '@dimen/testdimen').");
    errors.add(
        filePath
            + ":13: error: Error: No resource found that matches the given name"
            + " (at 'layout' with value '@layout/testlayout').");
    AaptParser.parseOutput(errors, project);

    AaptQuickFix aaptQuickFix = new AaptQuickFix();

    // Open file
    IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
    assertNotNull(page);
    IEditorPart editor = IDE.openEditor(page, file);
    assertTrue(editor instanceof AndroidXmlEditor);
    AndroidXmlEditor layoutEditor = (AndroidXmlEditor) editor;
    final ISourceViewer viewer = layoutEditor.getStructuredSourceViewer();

    // Test marker resolution.
    IMarker[] markers =
        file.findMarkers(AndmoreAndroidConstants.MARKER_AAPT_COMPILE, true, IResource.DEPTH_ZERO);
    for (IMarker marker : markers) {
      int start = marker.getAttribute(IMarker.CHAR_START, 0);
      int end = marker.getAttribute(IMarker.CHAR_END, 0);
      if (offset >= start && offset <= end) {
        // Found the target marker. Now check the marker resolution of
        // it.
        assertTrue(aaptQuickFix.hasResolutions(marker));
        IMarkerResolution[] resolutions = aaptQuickFix.getResolutions(marker);
        assertNotNull(resolutions);
        assertEquals(1, resolutions.length);
        IMarkerResolution resolution = resolutions[0];
        assertNotNull(resolution);
        assertTrue(resolution.getLabel().contains("Create resource"));

        // Not running marker yet -- if we create the files here they
        // already
        // exist when the quick assist code runs. (The quick fix and the
        // quick assist
        // mostly share code for the implementation anyway.)
        // resolution.run(marker);
        break;
      }
    }

    // Next test quick assist.

    IQuickAssistInvocationContext invocationContext =
        new IQuickAssistInvocationContext() {
          @Override
          public int getLength() {
            return 0;
          }

          @Override
          public int getOffset() {
            return offset;
          }

          @Override
          public ISourceViewer getSourceViewer() {
            return viewer;
          }
        };
    ICompletionProposal[] proposals = aaptQuickFix.computeQuickAssistProposals(invocationContext);
    assertNotNull(proposals);
    assertTrue(proposals.length == 1);
    ICompletionProposal proposal = proposals[0];

    assertNotNull(proposal.getAdditionalProposalInfo());
    assertNotNull(proposal.getImage());
    assertTrue(proposal.getDisplayString().contains("Create resource"));

    IDocument document = new Document();
    String fileContent = AndmoreAndroidPlugin.readFile(file);
    document.set(fileContent);

    // Apply quick fix
    proposal.apply(document);

    IPath path = new Path(expectedNewPath);
    IFile newFile = project.getFile(path);
    assertNotNull(path.toPortableString(), newFile);

    // Ensure that the newly created file was opened
    IEditorPart currentFile = AdtUtils.getActiveEditor();
    assertEquals(
        newFile.getProjectRelativePath(),
        ((FileEditorInput) currentFile.getEditorInput()).getFile().getProjectRelativePath());

    // Look up caret offset
    assertTrue(
        currentFile != null ? currentFile.getClass().getName() : "null",
        currentFile instanceof AndroidXmlEditor);
    AndroidXmlEditor newEditor = (AndroidXmlEditor) currentFile;
    ISourceViewer newViewer = newEditor.getStructuredSourceViewer();
    Point selectedRange = newViewer.getSelectedRange();

    String newFileContents = AndmoreAndroidPlugin.readFile(newFile);

    // Insert selection markers -- [ ] for the selection range, ^ for the
    // caret
    String newFileWithCaret = addSelection(newFileContents, selectedRange);
    newFileWithCaret = removeSessionData(newFileWithCaret);

    assertEqualsGolden(name, newFileWithCaret);
  }
  /** @see IPainter#paint(int) */
  public final void paint(final int reason) {
    Point selection = mSourceViewer.getSelectedRange();
    if (selection.y > 0) {
      deactivate(true);
      return;
    }

    SexpNavigator explorer = mEditor.getExplorer();

    boolean backward = true;
    boolean closeToParen = false;
    int offset = selection.x;
    IDocument document = mEditor.getDocument();
    try {
      char previousChar = '\0';
      char nextChar = '\0';

      if (selection.x > 0) previousChar = document.getChar(selection.x - 1);

      if (selection.x > 0
          && SchemeScannerUtilities.isClosingParenthesis(previousChar)
          && SchemeTextUtilities.getPartition(document, selection.x - 1).getType()
              == IDocument.DEFAULT_CONTENT_TYPE) {
        closeToParen = true;
      } else {
        nextChar = document.getChar(selection.x);
        if (selection.x < document.getLength() - 1
            && SchemeScannerUtilities.isOpeningParenthesis(nextChar)
            && SchemeTextUtilities.getPartition(document, selection.x).getType()
                == IDocument.DEFAULT_CONTENT_TYPE) {
          closeToParen = true;
          backward = false;
        }
      }

      if (closeToParen && backward && explorer.backwardSexpression(selection.x)) {
        offset = explorer.getListStart();
        char matchingChar = document.getChar(offset);
        mMismatch =
            SchemeScannerUtilities.getParenthesisType(previousChar)
                != SchemeScannerUtilities.getParenthesisType(matchingChar);
      } else {
        if (closeToParen && !backward && explorer.forwardSexpression(selection.x)) {
          offset = explorer.getSexpEnd() - 1;
          char matchingChar = document.getChar(offset);
          mMismatch =
              SchemeScannerUtilities.getParenthesisType(nextChar)
                  != SchemeScannerUtilities.getParenthesisType(matchingChar);
        } else {
          deactivate(true);
          return;
        }
      }

    } catch (BadLocationException exception) {
      deactivate(true);
      return;
    }

    if (mIsActive) {
      // only if different
      if (offset != mBracketPosition.getOffset()) {
        // remove old highlighting
        handleDrawRequest(null);
        // update position
        mBracketPosition.isDeleted = false;
        mBracketPosition.offset = offset;
        mBracketPosition.length = 1;
        // apply new highlighting
        handleDrawRequest(null);
      }
    } else {
      mIsActive = true;

      mBracketPosition.isDeleted = false;
      mBracketPosition.offset = offset;
      mBracketPosition.length = 1;

      mTextWidget.addPaintListener(this);
      mPositionManager.managePosition(mBracketPosition);
      handleDrawRequest(null);
    }
  }