mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
More readable rule language for indent position calculation
This commit is contained in:
+30
-30
@@ -19,12 +19,9 @@ import com.intellij.formatting.Indent;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -33,6 +30,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
* the indentation, it forwards the request to FormatterBasedLineIndentProvider.
|
||||
*/
|
||||
public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineIndentProvider {
|
||||
|
||||
protected enum JavaLikeElement implements SemanticEditorPosition.SyntaxElement {
|
||||
Whitespace,
|
||||
Semicolon,
|
||||
BlockClosingBrace
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getLineIndent(@NotNull Project project, @NotNull Editor editor, int offset) {
|
||||
@@ -54,39 +59,34 @@ public abstract class JavaLikeLangLineIndentProvider extends FormatterBasedLineI
|
||||
@Nullable
|
||||
protected Indent.Type getIndent(@NotNull Editor editor, int offset) {
|
||||
if (offset > 0) {
|
||||
CharSequence docChars = editor.getDocument().getCharsSequence();
|
||||
EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter();
|
||||
HighlighterIterator iterator = highlighter.createIterator(offset - 1);
|
||||
if (isWhitespace(iterator.getTokenType())) {
|
||||
if (containsLineBreaks(iterator, docChars)) {
|
||||
iterator.retreat();
|
||||
if (!iterator.atEnd()) {
|
||||
if (isEndOfCodeBlock(iterator)) return Indent.Type.NONE;
|
||||
}
|
||||
}
|
||||
if (matchesRule(editor, offset - 1,
|
||||
position -> position.isAt(JavaLikeElement.Whitespace) &&
|
||||
position.isAtMultiline()
|
||||
&& position
|
||||
.before()
|
||||
.beforeOptional(JavaLikeElement.Semicolon)
|
||||
.beforeOptional(JavaLikeElement.Whitespace)
|
||||
.isAt(JavaLikeElement.BlockClosingBrace)
|
||||
)) {
|
||||
return Indent.Type.NONE;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract boolean isWhitespace(@NotNull IElementType tokenType);
|
||||
|
||||
private static boolean containsLineBreaks(@NotNull HighlighterIterator iterator, @NotNull CharSequence chars) {
|
||||
return CharArrayUtil.containLineBreaks(chars, iterator.getStart(), iterator.getEnd());
|
||||
}
|
||||
|
||||
protected boolean isEndOfCodeBlock(@NotNull HighlighterIterator iterator) {
|
||||
if (isSemicolon(iterator.getTokenType())) iterator.retreat();
|
||||
if (!iterator.atEnd()) {
|
||||
if (isWhitespace(iterator.getTokenType())) iterator.retreat();
|
||||
if (!iterator.atEnd()) {
|
||||
return isBlockClosingBrace(iterator.getTokenType());
|
||||
|
||||
private boolean matchesRule(@NotNull Editor editor, int offset, @NotNull Rule rule) {
|
||||
SemanticEditorPosition editorPosition = new SemanticEditorPosition((EditorEx)editor, offset) {
|
||||
@Override
|
||||
public SyntaxElement map(@NotNull IElementType elementType) {
|
||||
return mapType(elementType);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return rule.check(editorPosition);
|
||||
}
|
||||
|
||||
protected abstract boolean isSemicolon(@NotNull IElementType tokenType);
|
||||
protected abstract SemanticEditorPosition.SyntaxElement mapType(@NotNull IElementType tokenType);
|
||||
|
||||
protected abstract boolean isBlockClosingBrace(@NotNull IElementType tokenType);
|
||||
private interface Rule {
|
||||
boolean check(SemanticEditorPosition wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl.source.codeStyle;
|
||||
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Rustam Vishnyakov
|
||||
*/
|
||||
public abstract class SemanticEditorPosition {
|
||||
public interface SyntaxElement {}
|
||||
|
||||
private final HighlighterIterator myIterator;
|
||||
private final CharSequence myChars;
|
||||
|
||||
public SemanticEditorPosition(@NotNull EditorEx editor, int offset) {
|
||||
myChars = editor.getDocument().getCharsSequence();
|
||||
myIterator = editor.getHighlighter().createIterator(offset);
|
||||
}
|
||||
|
||||
public SemanticEditorPosition beforeOptional(@NotNull SyntaxElement syntaxElement) {
|
||||
if (!myIterator.atEnd()) {
|
||||
if (syntaxElement.equals(map(myIterator.getTokenType()))) myIterator.retreat();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isAtMultiline() {
|
||||
if (!myIterator.atEnd()) {
|
||||
return CharArrayUtil.containLineBreaks(myChars, myIterator.getStart(), myIterator.getEnd());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public SemanticEditorPosition before() {
|
||||
if (!myIterator.atEnd()) {
|
||||
myIterator.retreat();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isAt(@NotNull SyntaxElement syntaxElement) {
|
||||
return !myIterator.atEnd() && syntaxElement.equals(map(myIterator.getTokenType()));
|
||||
}
|
||||
|
||||
public abstract SyntaxElement map(@NotNull IElementType elementType);
|
||||
}
|
||||
Reference in New Issue
Block a user