package com.jetbrains.lang.dart.ide.editor; import com.intellij.formatting.Indent; import com.intellij.lang.Language; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.impl.source.codeStyle.SemanticEditorPosition; import com.intellij.psi.impl.source.codeStyle.lineIndent.IndentCalculator; import com.intellij.psi.impl.source.codeStyle.lineIndent.JavaLikeLangLineIndentProvider; import com.intellij.psi.tree.IElementType; import com.intellij.util.containers.HashMap; import com.jetbrains.lang.dart.DartLanguage; import com.jetbrains.lang.dart.DartTokenTypes; import com.jetbrains.lang.dart.DartTokenTypesSets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import static com.intellij.psi.impl.source.codeStyle.lineIndent.JavaLikeLangLineIndentProvider.JavaLikeElement.*; public class DartLineIndentProvider extends JavaLikeLangLineIndentProvider { static HashMap<IElementType, SemanticEditorPosition.SyntaxElement> SYNTAX_MAP = new HashMap<>(); static { SYNTAX_MAP.put(DartTokenTypesSets.WHITE_SPACE, Whitespace); SYNTAX_MAP.put(DartTokenTypes.SEMICOLON, Semicolon); SYNTAX_MAP.put(DartTokenTypes.LBRACE, BlockOpeningBrace); SYNTAX_MAP.put(DartTokenTypes.RBRACE, BlockClosingBrace); SYNTAX_MAP.put(DartTokenTypes.LBRACKET, ArrayOpeningBracket); SYNTAX_MAP.put(DartTokenTypes.RBRACKET, ArrayClosingBracket); SYNTAX_MAP.put(DartTokenTypes.LPAREN, LeftParenthesis); SYNTAX_MAP.put(DartTokenTypes.RPAREN, RightParenthesis); SYNTAX_MAP.put(DartTokenTypes.COLON, Colon); SYNTAX_MAP.put(DartTokenTypes.CASE, SwitchCase); SYNTAX_MAP.put(DartTokenTypes.DEFAULT, SwitchDefault); SYNTAX_MAP.put(DartTokenTypes.IF, IfKeyword); SYNTAX_MAP.put(DartTokenTypes.ELSE, ElseKeyword); SYNTAX_MAP.put(DartTokenTypes.FOR, ForKeyword); SYNTAX_MAP.put(DartTokenTypes.DO, DoKeyword); SYNTAX_MAP.put(DartTokenTypesSets.MULTI_LINE_COMMENT, BlockComment); SYNTAX_MAP.put(DartTokenTypesSets.MULTI_LINE_COMMENT_END, DocBlockEnd); SYNTAX_MAP.put(DartTokenTypesSets.MULTI_LINE_DOC_COMMENT_START, DocBlockStart); SYNTAX_MAP.put(DartTokenTypes.COMMA, Comma); SYNTAX_MAP.put(DartTokenTypesSets.SINGLE_LINE_COMMENT, LineComment); SYNTAX_MAP.put(DartTokenTypesSets.SINGLE_LINE_DOC_COMMENT, LineComment); } @Nullable @Override protected SemanticEditorPosition.SyntaxElement mapType(@NotNull IElementType tokenType) { return SYNTAX_MAP.get(tokenType); } @Override public boolean isSuitableForLanguage(@NotNull Language language) { return language.is(DartLanguage.INSTANCE); } @Override protected Indent.Type getIndentTypeInBrackets() { return Indent.Type.NORMAL; } @Nullable @Override protected IndentCalculator getIndent(@NotNull Project project, @NotNull Editor editor, @Nullable Language language, int offset) { if (getPosition(editor, offset).matchesRule(position -> position.before().isAt(LeftParenthesis))) { // Need to skip a common logic and force formatter-based line indent provider to work, because // there may be different indents inside parentheses, see https://github.com/dart-lang/dart_style/issues/551 return null; } return super.getIndent(project, editor, language, offset); } }