package com.bitbakery.plugin.arc.formatting; /* * Copyright (c) Kurt Christensen, 2009 * * Licensed under the Artistic 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.opensource.org/licenses/artistic-license-2.0.php * * 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.. */ import com.intellij.formatting.*; import com.intellij.lang.ASTNode; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiErrorElement; import com.intellij.psi.impl.source.tree.ChameleonElement; import com.intellij.psi.tree.IChameleonElementType; import com.intellij.openapi.util.TextRange; import com.bitbakery.plugin.arc.psi.ArcFile; import com.bitbakery.plugin.arc.psi.ArcElementTypes; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * Formatting block for Arc source code files */ public class ArcBlock implements Block { final protected ASTNode myNode; final protected Alignment myAlignment; final protected Indent myIndent; final protected Wrap myWrap; final protected CodeStyleSettings mySettings; protected List<Block> mySubBlocks = null; public ArcBlock(@NotNull final ASTNode node, @Nullable final Alignment alignment, @NotNull final Indent indent, @Nullable final Wrap wrap, final CodeStyleSettings settings) { myNode = node; myAlignment = alignment; myIndent = indent; myWrap = wrap; mySettings = settings; } @NotNull public ASTNode getNode() { return myNode; } @NotNull public CodeStyleSettings getSettings() { return mySettings; } @NotNull public TextRange getTextRange() { return myNode.getTextRange(); } @NotNull public List<Block> getSubBlocks() { if (mySubBlocks == null) { mySubBlocks = ArcBlockGenerator.generateSubBlocks(myNode, myAlignment, myWrap, mySettings, this); } return mySubBlocks; } @Nullable public Wrap getWrap() { return myWrap; } @Nullable public Indent getIndent() { return myIndent; } @Nullable public Alignment getAlignment() { return myAlignment; } public Spacing getSpacing(Block child1, Block child2) { return ArcSpacingProcessor.getSpacing(child1, child2); } @NotNull public ChildAttributes getChildAttributes(final int newChildIndex) { return getAttributesByParent(); } private ChildAttributes getAttributesByParent() { ASTNode astNode = getNode(); final PsiElement psiParent = astNode.getPsi(); if (psiParent instanceof ArcFile) { return new ChildAttributes(Indent.getNoneIndent(), null); } if (ArcElementTypes.EXPRESSIONS.contains(astNode.getElementType())) { return new ChildAttributes(Indent.getNormalIndent(), null); } return new ChildAttributes(Indent.getNoneIndent(), null); } public boolean isIncomplete() { return isIncomplete(myNode); } /** * @param node Tree node * @return true if node is incomplete */ public boolean isIncomplete(@NotNull final ASTNode node) { if (node.getElementType() instanceof IChameleonElementType) return false; ASTNode lastChild = node.getLastChildNode(); while (lastChild != null && !(lastChild.getElementType() instanceof IChameleonElementType) && (lastChild.getPsi() instanceof PsiWhiteSpace || lastChild.getPsi() instanceof PsiComment)) { lastChild = lastChild.getTreePrev(); } return lastChild != null && !(lastChild instanceof ChameleonElement) && (lastChild.getPsi() instanceof PsiErrorElement || isIncomplete(lastChild)); } public boolean isLeaf() { return myNode.getFirstChildNode() == null; } }