Search in sources :

Example 46 with RangeMarker

use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.

the class PostprocessReformattingAspect method normalizeAndReorderPostponedActions.

@NotNull
private List<PostponedAction> normalizeAndReorderPostponedActions(@NotNull Set<PostprocessFormattingTask> rangesToProcess, @NotNull Document document) {
    final List<PostprocessFormattingTask> freeFormattingActions = new ArrayList<>();
    final List<ReindentTask> indentActions = new ArrayList<>();
    PostprocessFormattingTask accumulatedTask = null;
    Iterator<PostprocessFormattingTask> iterator = rangesToProcess.iterator();
    while (iterator.hasNext()) {
        final PostprocessFormattingTask currentTask = iterator.next();
        if (accumulatedTask == null) {
            accumulatedTask = currentTask;
            iterator.remove();
        } else if (accumulatedTask.getStartOffset() > currentTask.getEndOffset() || accumulatedTask.getStartOffset() == currentTask.getEndOffset() && !canStickActionsTogether(accumulatedTask, currentTask)) {
            // action can be pushed
            if (accumulatedTask instanceof ReindentTask) {
                indentActions.add((ReindentTask) accumulatedTask);
            } else {
                freeFormattingActions.add(accumulatedTask);
            }
            accumulatedTask = currentTask;
            iterator.remove();
        } else if (accumulatedTask instanceof ReformatTask && currentTask instanceof ReindentTask) {
            // split accumulated reformat range into two
            if (accumulatedTask.getStartOffset() < currentTask.getStartOffset()) {
                final RangeMarker endOfRange = document.createRangeMarker(accumulatedTask.getStartOffset(), currentTask.getStartOffset());
                // add heading reformat part
                rangesToProcess.add(new ReformatTask(endOfRange));
                // and manage heading whitespace because formatter does not edit it in previous action
                iterator = rangesToProcess.iterator();
                //noinspection StatementWithEmptyBody
                while (iterator.next().getRange() != currentTask.getRange()) ;
            }
            final RangeMarker rangeToProcess = document.createRangeMarker(currentTask.getEndOffset(), accumulatedTask.getEndOffset());
            freeFormattingActions.add(new ReformatWithHeadingWhitespaceTask(rangeToProcess));
            accumulatedTask = currentTask;
            iterator.remove();
        } else {
            if (!(accumulatedTask instanceof ReindentTask)) {
                iterator.remove();
                boolean withLeadingWhitespace = accumulatedTask instanceof ReformatWithHeadingWhitespaceTask;
                if (accumulatedTask instanceof ReformatTask && currentTask instanceof ReformatWithHeadingWhitespaceTask && accumulatedTask.getStartOffset() == currentTask.getStartOffset()) {
                    withLeadingWhitespace = true;
                } else if (accumulatedTask instanceof ReformatWithHeadingWhitespaceTask && currentTask instanceof ReformatTask && accumulatedTask.getStartOffset() < currentTask.getStartOffset()) {
                    withLeadingWhitespace = false;
                }
                int newStart = Math.min(accumulatedTask.getStartOffset(), currentTask.getStartOffset());
                int newEnd = Math.max(accumulatedTask.getEndOffset(), currentTask.getEndOffset());
                RangeMarker rangeMarker;
                if (accumulatedTask.getStartOffset() == newStart && accumulatedTask.getEndOffset() == newEnd) {
                    rangeMarker = accumulatedTask.getRange();
                } else if (currentTask.getStartOffset() == newStart && currentTask.getEndOffset() == newEnd) {
                    rangeMarker = currentTask.getRange();
                } else {
                    rangeMarker = document.createRangeMarker(newStart, newEnd);
                }
                if (withLeadingWhitespace) {
                    accumulatedTask = new ReformatWithHeadingWhitespaceTask(rangeMarker);
                } else {
                    accumulatedTask = new ReformatTask(rangeMarker);
                }
            } else if (currentTask instanceof ReindentTask) {
                iterator.remove();
            }
        // TODO[ik]: need to be fixed to correctly process indent inside indent
        }
    }
    if (accumulatedTask != null) {
        if (accumulatedTask instanceof ReindentTask) {
            indentActions.add((ReindentTask) accumulatedTask);
        } else {
            freeFormattingActions.add(accumulatedTask);
        }
    }
    final List<PostponedAction> result = new ArrayList<>();
    Collections.reverse(freeFormattingActions);
    Collections.reverse(indentActions);
    if (!freeFormattingActions.isEmpty()) {
        FormatTextRanges ranges = new FormatTextRanges();
        for (PostprocessFormattingTask action : freeFormattingActions) {
            TextRange range = TextRange.create(action);
            ranges.add(range, action instanceof ReformatWithHeadingWhitespaceTask);
        }
        result.add(new ReformatRangesAction(ranges));
    }
    if (!indentActions.isEmpty()) {
        ReindentRangesAction reindentRangesAction = new ReindentRangesAction();
        for (ReindentTask action : indentActions) {
            reindentRangesAction.add(action.getRange(), action.getOldIndent());
        }
        result.add(reindentRangesAction);
    }
    return result;
}
Also used : RangeMarker(com.intellij.openapi.editor.RangeMarker) FormatTextRanges(com.intellij.formatting.FormatTextRanges) NotNull(org.jetbrains.annotations.NotNull)

Example 47 with RangeMarker

use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.

the class JavaCompletionUtil method insertTemporary.

public static RangeMarker insertTemporary(final int endOffset, final Document document, final String temporary) {
    final CharSequence chars = document.getCharsSequence();
    final int length = chars.length();
    final RangeMarker toDelete;
    if (endOffset < length && Character.isJavaIdentifierPart(chars.charAt(endOffset))) {
        document.insertString(endOffset, temporary);
        toDelete = document.createRangeMarker(endOffset, endOffset + 1);
    } else if (endOffset >= length) {
        toDelete = document.createRangeMarker(length, length);
    } else {
        toDelete = document.createRangeMarker(endOffset, endOffset);
    }
    toDelete.setGreedyToLeft(true);
    toDelete.setGreedyToRight(true);
    return toDelete;
}
Also used : RangeMarker(com.intellij.openapi.editor.RangeMarker) ElementClassHint(com.intellij.psi.scope.ElementClassHint) NameHint(com.intellij.psi.scope.NameHint)

Example 48 with RangeMarker

use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.

the class JavaQualifiedNameProvider method insertQualifiedName.

public void insertQualifiedName(String fqn, final PsiElement element, final Editor editor, final Project project) {
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
    Document document = editor.getDocument();
    final PsiFile file = documentManager.getPsiFile(document);
    final int offset = editor.getCaretModel().getOffset();
    PsiElement elementAtCaret = file.findElementAt(offset);
    fqn = fqn.replace('#', '.');
    String toInsert;
    String suffix = "";
    if (!(element instanceof PsiMember)) {
        toInsert = fqn;
    } else if (elementAtCaret != null && (element instanceof PsiMethod || element instanceof PsiField) && PsiUtil.isInsideJavadocComment(elementAtCaret)) {
        // use fqn#methodName(ParamType)
        PsiMember member = (PsiMember) element;
        PsiClass aClass = member.getContainingClass();
        String className = aClass == null ? "" : aClass.getQualifiedName();
        toInsert = className == null ? "" : className;
        if (toInsert.length() != 0)
            toInsert += "#";
        toInsert += member.getName();
        if (member instanceof PsiMethod) {
            toInsert += getParameterString((PsiMethod) member, true);
        }
    } else if (elementAtCaret == null || PsiTreeUtil.getNonStrictParentOfType(elementAtCaret, PsiLiteralExpression.class, PsiComment.class) != null || PsiTreeUtil.getNonStrictParentOfType(elementAtCaret, PsiJavaFile.class) == null) {
        toInsert = fqn;
    } else {
        PsiMember targetElement = (PsiMember) element;
        toInsert = targetElement.getName();
        if (targetElement instanceof PsiMethod) {
            if (!fqn.contains("(")) {
                suffix = "()";
            }
            if (((PsiMethod) targetElement).isConstructor()) {
                targetElement = targetElement.getContainingClass();
                fqn = StringUtil.getPackageName(fqn);
            }
        } else if (targetElement instanceof PsiClass) {
            if (isAfterNew(file, elementAtCaret)) {
                // pasting reference to default constructor of the class after new
                suffix = "()";
            } else if (toInsert != null && toInsert.length() != 0 && Character.isJavaIdentifierPart(toInsert.charAt(toInsert.length() - 1)) && Character.isJavaIdentifierPart(elementAtCaret.getText().charAt(0))) {
                //separate identifiers with space
                suffix = " ";
            }
        }
        final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
        final PsiExpression expression;
        try {
            expression = factory.createExpressionFromText(toInsert + suffix, elementAtCaret);
            final PsiReferenceExpression referenceExpression = expression instanceof PsiMethodCallExpression ? ((PsiMethodCallExpression) expression).getMethodExpression() : expression instanceof PsiReferenceExpression ? (PsiReferenceExpression) expression : null;
            if (referenceExpression == null || !referenceExpression.isValid()) {
                toInsert = fqn;
            } else if (!isReferencedTo(referenceExpression, targetElement)) {
                try {
                    referenceExpression.bindToElement(targetElement);
                } catch (IncorrectOperationException e) {
                // failed to bind
                }
                if (!referenceExpression.isValid() || !isReferencedTo(referenceExpression, targetElement)) {
                    toInsert = fqn;
                }
            }
        } catch (IncorrectOperationException ignored) {
        }
    }
    if (toInsert == null)
        toInsert = "";
    document.insertString(offset, toInsert + suffix);
    documentManager.commitAllDocuments();
    int endOffset = offset + toInsert.length() + suffix.length();
    RangeMarker rangeMarker = document.createRangeMarker(endOffset, endOffset);
    elementAtCaret = file.findElementAt(offset);
    if (elementAtCaret != null && elementAtCaret.isValid()) {
        try {
            shortenReference(elementAtCaret);
        } catch (IncorrectOperationException e) {
            LOG.error(e);
        }
    }
    CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(file);
    try {
        CodeStyleManager.getInstance(project).adjustLineIndent(file, offset);
    } catch (IncorrectOperationException e) {
        LOG.error(e);
    }
    int caretOffset = rangeMarker.getEndOffset();
    if (element instanceof PsiMethod && ((PsiMethod) element).getParameterList().getParametersCount() != 0 && StringUtil.endsWithChar(suffix, ')')) {
        caretOffset--;
    }
    editor.getCaretModel().moveToOffset(caretOffset);
}
Also used : RangeMarker(com.intellij.openapi.editor.RangeMarker) Document(com.intellij.openapi.editor.Document) IncorrectOperationException(com.intellij.util.IncorrectOperationException)

Example 49 with RangeMarker

use of com.intellij.openapi.editor.RangeMarker in project intellij-community by JetBrains.

the class SliceBackwardTest method doTest.

private void doTest() throws Exception {
    configureByFile("/codeInsight/slice/backward/" + getTestName(false) + ".java");
    Map<String, RangeMarker> sliceUsageName2Offset = SliceTestUtil.extractSliceOffsetsFromDocument(getEditor().getDocument());
    PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
    PsiElement element = new SliceHandler(true).getExpressionAtCaret(getEditor(), getFile());
    assertNotNull(element);
    SliceTestUtil.calcRealOffsets(element, sliceUsageName2Offset, myFlownOffsets);
    Collection<HighlightInfo> errors = highlightErrors();
    assertEmpty(errors);
    SliceAnalysisParams params = new SliceAnalysisParams();
    params.scope = new AnalysisScope(getProject());
    params.dataFlowToThis = true;
    SliceUsage usage = LanguageSlicing.getProvider(element).createRootUsage(element, params);
    SliceTestUtil.checkUsages(usage, myFlownOffsets);
}
Also used : AnalysisScope(com.intellij.analysis.AnalysisScope) HighlightInfo(com.intellij.codeInsight.daemon.impl.HighlightInfo) RangeMarker(com.intellij.openapi.editor.RangeMarker) PsiElement(com.intellij.psi.PsiElement)

Example 50 with RangeMarker

use of com.intellij.openapi.editor.RangeMarker in project android by JetBrains.

the class AndroidAddStringResourceAction method createJavaResourceReference.

private static void createJavaResourceReference(final Module module, final Editor editor, final PsiFile file, final PsiElement element, final String aPackage, final String resName, final ResourceType resType) {
    final boolean extendsContext = getContainingInheritorOf(element, CLASS_CONTEXT) != null;
    final boolean extendsFragment = getContainingInheritorOf(element, CLASS_FRAGMENT) != null || getContainingInheritorOf(element, CLASS_V4_FRAGMENT) != null;
    final String rJavaFieldName = AndroidResourceUtil.getRJavaFieldName(resName);
    final String field = aPackage + ".R." + resType + '.' + rJavaFieldName;
    final String methodName = getGetterNameForResourceType(resType, element);
    assert methodName != null;
    final TemplateImpl template;
    final boolean inStaticContext = RefactoringUtil.isInStaticContext(element, null);
    final Project project = module.getProject();
    if ((extendsContext || extendsFragment) && !inStaticContext) {
        if (ResourceType.STRING == resType) {
            if (useGetStringMethodForStringRes(element)) {
                template = new TemplateImpl("", methodName + '(' + field + ')', "");
            } else {
                template = new TemplateImpl("", field, "");
            }
        } else {
            template = new TemplateImpl("", "$resources$." + methodName + "(" + field + ")", "");
            MacroCallNode node = new MacroCallNode(new MyVarOfTypeExpression("getResources()"));
            node.addParameter(new ConstantNode(CLASS_RESOURCES));
            template.addVariable("resources", node, new ConstantNode(""), true);
        }
    } else {
        boolean addContextVariable = true;
        if (ResourceType.STRING == resType) {
            if (useGetStringMethodForStringRes(element)) {
                template = new TemplateImpl("", "$context$." + methodName + '(' + field + ')', "");
            } else {
                template = new TemplateImpl("", field, "");
                addContextVariable = false;
            }
        } else {
            template = new TemplateImpl("", "$context$.getResources()." + methodName + "(" + field + ")", "");
        }
        if (addContextVariable) {
            final boolean extendsView = getContainingInheritorOf(element, VIEW_CLASS_NAME) != null;
            MacroCallNode node = new MacroCallNode(extendsView && !inStaticContext ? new MyVarOfTypeExpression("getContext()") : new VariableOfTypeMacro());
            node.addParameter(new ConstantNode(CLASS_CONTEXT));
            template.addVariable("context", node, new ConstantNode(""), true);
        }
    }
    final int offset = element.getTextOffset();
    editor.getCaretModel().moveToOffset(offset);
    final TextRange elementRange = element.getTextRange();
    editor.getDocument().deleteString(elementRange.getStartOffset(), elementRange.getEndOffset());
    final RangeMarker marker = editor.getDocument().createRangeMarker(offset, offset);
    marker.setGreedyToLeft(true);
    marker.setGreedyToRight(true);
    //noinspection ConstantConditions
    TemplateManager.getInstance(project).startTemplate(editor, template, false, null, new TemplateEditingAdapter() {

        @Override
        public void waitingForInput(Template template) {
            JavaCodeStyleManager.getInstance(project).shortenClassReferences(file, marker.getStartOffset(), marker.getEndOffset());
        }

        @Override
        public void beforeTemplateFinished(TemplateState state, Template template) {
            JavaCodeStyleManager.getInstance(project).shortenClassReferences(file, marker.getStartOffset(), marker.getEndOffset());
        }
    });
}
Also used : VariableOfTypeMacro(com.intellij.codeInsight.template.macro.VariableOfTypeMacro) TextRange(com.intellij.openapi.util.TextRange) RangeMarker(com.intellij.openapi.editor.RangeMarker) Project(com.intellij.openapi.project.Project)

Aggregations

RangeMarker (com.intellij.openapi.editor.RangeMarker)111 Document (com.intellij.openapi.editor.Document)33 TextRange (com.intellij.openapi.util.TextRange)20 Project (com.intellij.openapi.project.Project)19 PsiFile (com.intellij.psi.PsiFile)14 PsiElement (com.intellij.psi.PsiElement)13 IncorrectOperationException (com.intellij.util.IncorrectOperationException)13 Editor (com.intellij.openapi.editor.Editor)11 Nullable (org.jetbrains.annotations.Nullable)11 NotNull (org.jetbrains.annotations.NotNull)10 Template (com.intellij.codeInsight.template.Template)8 TemplateBuilderImpl (com.intellij.codeInsight.template.TemplateBuilderImpl)7 TemplateEditingAdapter (com.intellij.codeInsight.template.TemplateEditingAdapter)6 PsiDocumentManager (com.intellij.psi.PsiDocumentManager)6 RangeHighlighterEx (com.intellij.openapi.editor.ex.RangeHighlighterEx)5 THashMap (gnu.trove.THashMap)5 GutterMark (com.intellij.codeInsight.daemon.GutterMark)4 HighlightSeverity (com.intellij.lang.annotation.HighlightSeverity)4 ApplicationManager (com.intellij.openapi.application.ApplicationManager)4 RelativePoint (com.intellij.ui.awt.RelativePoint)4