From 32d35778943db44376f1342d9e85c7ea14a06acb Mon Sep 17 00:00:00 2001 From: Johannes Mey <johannes.mey@tu-dresden.de> Date: Thu, 18 Nov 2021 01:46:02 +0100 Subject: [PATCH] initial version of auto formatter --- .../jastadd/tooling/aspect/AspectBlock.java | 112 ++++++++++++++++++ .../aspect/AspectFormattingModelBuilder.java | 29 +++++ src/main/resources/META-INF/plugin.xml | 2 + 3 files changed, 143 insertions(+) create mode 100644 src/main/java/org/jastadd/tooling/aspect/AspectBlock.java create mode 100644 src/main/java/org/jastadd/tooling/aspect/AspectFormattingModelBuilder.java diff --git a/src/main/java/org/jastadd/tooling/aspect/AspectBlock.java b/src/main/java/org/jastadd/tooling/aspect/AspectBlock.java new file mode 100644 index 0000000..694bcc4 --- /dev/null +++ b/src/main/java/org/jastadd/tooling/aspect/AspectBlock.java @@ -0,0 +1,112 @@ +package org.jastadd.tooling.aspect; + + +import com.intellij.formatting.*; +import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.TokenType; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.formatter.common.AbstractBlock; +import com.intellij.psi.formatter.common.InjectedLanguageBlockBuilder; +import com.intellij.psi.formatter.java.LeafBlock; +import org.jastadd.tooling.aspect.psi.JastAddAspectAspectBody; +import org.jastadd.tooling.aspect.psi.JastAddAspectAspectBodyDeclaration; +import org.jastadd.tooling.aspect.psi.JastAddAspectBlock; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class AspectBlock extends AbstractBlock { + + private final SpacingBuilder spacingBuilder; + private final InjectedLanguageBlockBuilder myInjectedBlockBuilder; + + protected AspectBlock(@NotNull ASTNode node, @Nullable Wrap wrap, @Nullable Alignment alignment, + SpacingBuilder spacingBuilder) { + super(node, wrap, alignment); + this.spacingBuilder = spacingBuilder; + + myInjectedBlockBuilder = new JavaBlockInjectedBlockBuilder(); + } + + @Override + protected List<Block> buildChildren() { + List<Block> blocks = new ArrayList<>(); + if (myNode.getPsi() instanceof JastAddAspectBlock) { + myInjectedBlockBuilder.addInjectedBlocks(blocks, myNode, Wrap.createWrap(WrapType.NONE, false), null, Indent.getIndent(Indent.Type.NONE, false, true)); + } else { + ASTNode child = myNode.getFirstChildNode(); + while (child != null) { + if (child.getElementType() != TokenType.WHITE_SPACE) { + Block block = new AspectBlock(child, Wrap.createWrap(WrapType.NORMAL, false), null, spacingBuilder); + blocks.add(block); + } + child = child.getTreeNext(); + } + } + return blocks; + } + + @Override + public Indent getIndent() { + + if (myNode.getPsi() instanceof JastAddAspectAspectBodyDeclaration) { + return Indent.getNormalIndent(); + } else if (myNode.getPsi() instanceof JastAddAspectAspectBody) { + return Indent.getAbsoluteNoneIndent(); + } else { + return Indent.getNoneIndent(); + } + } + + @Nullable + @Override + public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) { + return spacingBuilder.getSpacing(this, child1, child2); + } + + @Override + public boolean isLeaf() { + return myNode.getFirstChildNode() == null; + } + + private static class AroundBlockBlock extends LeafBlock { + private final TextRange myRange; + + AroundBlockBlock(ASTNode node, Wrap wrap, Alignment alignment, Indent indent, TextRange range) { + super(node, wrap, alignment, indent); + myRange = range; + } + + @NotNull + @Override + public TextRange getTextRange() { + return myRange; + } + } + + private static class JavaBlockInjectedBlockBuilder extends InjectedLanguageBlockBuilder { + @Override + public CodeStyleSettings getSettings() { + return CodeStyleSettings.getDefaults(); + } + + @Override + public boolean canProcessFragment(String text, ASTNode injectionHost) { + return true; + } + + @Override + public Block createBlockBeforeInjection(ASTNode node, Wrap wrap, Alignment alignment, Indent indent, TextRange range) { + return new AroundBlockBlock(node, wrap, alignment, indent, range); + } + + @Override + public Block createBlockAfterInjection(ASTNode node, Wrap wrap, Alignment alignment, Indent indent, TextRange range) { + return new AroundBlockBlock(node, wrap, alignment, Indent.getNoneIndent(), range); + } + } + +} diff --git a/src/main/java/org/jastadd/tooling/aspect/AspectFormattingModelBuilder.java b/src/main/java/org/jastadd/tooling/aspect/AspectFormattingModelBuilder.java new file mode 100644 index 0000000..fa469ff --- /dev/null +++ b/src/main/java/org/jastadd/tooling/aspect/AspectFormattingModelBuilder.java @@ -0,0 +1,29 @@ +package org.jastadd.tooling.aspect; + +import com.intellij.formatting.*; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import org.jastadd.tooling.aspect.psi.AspectTypes; +import org.jetbrains.annotations.NotNull; + +public class AspectFormattingModelBuilder implements FormattingModelBuilder { + + private static SpacingBuilder createSpaceBuilder(CodeStyleSettings settings) { + return new SpacingBuilder(settings, Aspect.INSTANCE) + .before(AspectTypes.ASPECT).none() + .after(AspectTypes.ASPECT).spaces(1) + .after(AspectTypes.LBRACE).none(); + } + + @Override + public @NotNull FormattingModel createModel(@NotNull FormattingContext formattingContext) { + final CodeStyleSettings codeStyleSettings = formattingContext.getCodeStyleSettings(); + return FormattingModelProvider + .createFormattingModelForPsiFile(formattingContext.getContainingFile(), + new AspectBlock(formattingContext.getNode(), + Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment(), + createSpaceBuilder(codeStyleSettings)), + codeStyleSettings); + } + +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 5b1ae81..2cb82c0 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -79,6 +79,8 @@ <annotator language="JAVA" implementationClass="org.jastadd.tooling.java.JavaMethodHighlighter"/> <colorSettingsPage implementation="org.jastadd.tooling.java.JavaColorSettingsPage"/> + + <lang.formatter language="JastAddAspect" implementationClass="org.jastadd.tooling.aspect.AspectFormattingModelBuilder"/> </extensions> <actions> -- GitLab