Skip to content

Commit

Permalink
Indentation and alignment on enter after declaration and equal
Browse files Browse the repository at this point in the history
1. Alignment of assignments not working for some reason.
2. Solution is imperfect, because of the last item specifics.
3. Need tests for mid-item enter.

#1674
  • Loading branch information
hurricup committed Apr 26, 2020
1 parent cda00d6 commit 70d55e0
Show file tree
Hide file tree
Showing 59 changed files with 479 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@

import static com.intellij.formatting.WrapType.*;
import static com.intellij.psi.codeStyle.CommonCodeStyleSettings.*;
import static com.perl5.lang.perl.idea.formatter.settings.PerlCodeStyleSettings.OptionalConstructions.ALIGN_IN_STATEMENT;
import static com.perl5.lang.perl.idea.formatter.settings.PerlCodeStyleSettings.OptionalConstructions.ALIGN_LINES;
import static com.perl5.lang.perl.idea.formatter.settings.PerlCodeStyleSettings.OptionalConstructions.*;
import static com.perl5.lang.perl.lexer.PerlTokenSets.ALL_QUOTE_OPENERS;
import static com.perl5.lang.perl.lexer.PerlTokenSets.STATEMENTS;

Expand All @@ -63,6 +62,7 @@ public class PerlFormattingContext implements PerlFormattingTokenSets {
private final Map<Integer, Alignment> myCommentsAlignmentMap = FactoryMap.create(line -> Alignment.createAlignment(true));
private final Map<ASTNode, Alignment> myOperatorsAlignmentsMap = FactoryMap.create(sequence -> Alignment.createAlignment(true));
private final Map<ASTNode, Alignment> myElementsALignmentsMap = FactoryMap.create(sequence -> Alignment.createAlignment(true));
private final Map<ASTNode, Alignment> myAssignmentsElementAlignmentsMap = FactoryMap.create(sequence -> Alignment.createAlignment(true));
private final Map<ASTNode, Map<ASTNode, Alignment>> myStringListAlignmentMap = FactoryMap.create(listNode -> {
Map<Integer, Alignment> generatingMap = FactoryMap.create(key -> Alignment.createAlignment(true));

Expand Down Expand Up @@ -383,7 +383,7 @@ else if ((parentNodeType == ASSIGN_EXPR || parentNodeType == SIGNATURE_ELEMENT)
return getLineBasedAlignment(childNode, myAssignmentsAlignmentsMap);
}
else if (myPerlSettings.ALIGN_CONSECUTIVE_ASSIGNMENTS == ALIGN_IN_STATEMENT) {
return myElementsALignmentsMap.get(parentNode);
return myAssignmentsElementAlignmentsMap.get(parentNodeType == SIGNATURE_ELEMENT ? parentNode.getTreeParent() : parentNode);
}
}
else if (myPerlSettings.ALIGN_ATTRIBUTES && parentNodeType == ATTRIBUTES &&
Expand Down Expand Up @@ -538,13 +538,40 @@ public final ChildAttributes getChildAttributes(@NotNull PerlAstBlock block, int
public Alignment getChildAlignment(@NotNull PerlAstBlock block, int newChildIndex) {
ASTNode node = block.getNode();
IElementType elementType = PsiUtilCore.getElementType(node);
ASTNode parentNode = node == null ? null : node.getTreeParent();

// hack for signature_element wrapping variable_declaration
ASTNode grandParentNode = parentNode == null ? null : parentNode.getTreeParent();
IElementType grandParentElementType = PsiUtilCore.getElementType(grandParentNode);
if (grandParentElementType == SIGNATURE_ELEMENT && PsiUtilCore.getElementType(parentNode) == VARIABLE_DECLARATION_ELEMENT &&
node.getTextRange().equals(grandParentNode.getTextRange())) {
node = grandParentNode;
parentNode = node.getTreeParent();
elementType = grandParentElementType;
}

if (myPerlSettings.ALIGN_CONSECUTIVE_ASSIGNMENTS != NO_ALIGN && elementType == SIGNATURE_ELEMENT) {
IElementType lastChildNodeType = PsiUtilCore.getElementType(node.getLastChildNode());
if (lastChildNodeType == OPERATOR_ASSIGN) {
return null;
}
PsiElement psiElement = node.getPsi();
assert psiElement instanceof PerlSignatureElement;
if (((PerlSignatureElement)psiElement).hasDeclarationElement()) {
if (myPerlSettings.ALIGN_CONSECUTIVE_ASSIGNMENTS == ALIGN_IN_STATEMENT) {
return myAssignmentsElementAlignmentsMap.get(parentNode);
}
else if (myPerlSettings.ALIGN_CONSECUTIVE_ASSIGNMENTS == ALIGN_LINES) {
return getLineBasedAlignment(node, myAssignmentsAlignmentsMap);
}
}
}
if (elementType == SIGNATURE_CONTENT) {
return mySettings.ALIGN_MULTILINE_PARAMETERS ? myElementsALignmentsMap.get(block.getNode()) : null;
}
if (elementType == ATTRIBUTES && myPerlSettings.ALIGN_ATTRIBUTES) {
return myElementsALignmentsMap.get(node);
}

if (PerlFormattingTokenSets.COMMA_LIKE_SEQUENCES.contains(elementType)) {
return null;
}
Expand Down Expand Up @@ -573,11 +600,22 @@ public Boolean isIncomplete(@NotNull PerlAstBlock block) {
if (elementType == ATTRIBUTES) {
return true;
}
if (elementType == SIGNATURE_ELEMENT) {
PsiElement psiElement = blockNode.getPsi();
assert psiElement instanceof PerlSignatureElement;
return !((PerlSignatureElement)psiElement).hasDefaultValueElement();
}
if (COMMA_LIKE_SEQUENCES.contains(elementType)) {
IElementType lastNodeType = PsiUtilCore.getElementType(blockNode.getLastChildNode());
if (lastNodeType == COMMA || lastNodeType == FAT_COMMA) {
return true;
}
if (elementType == SIGNATURE_CONTENT) {
Block lastSubBlock = block.getLastSubBlock();
if (lastSubBlock != null && lastSubBlock.isIncomplete()) {
return true;
}
}
}
else if (STATEMENTS.contains(elementType)) {
PsiElement lastLeaf = PsiTreeUtil.getDeepestLast(blockNode.getPsi());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Objects;

import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.*;
import static com.perl5.lang.perl.lexer.PerlTokenSets.HEREDOC_BODIES_TOKENSET;
Expand Down Expand Up @@ -166,12 +165,25 @@ public Indent getNodeIndent(@NotNull ASTNode node) {

@Nullable
public Indent getChildIndent(@NotNull PerlAstBlock block, int newChildIndex) {
IElementType elementType = block.getElementType();
ASTNode node = block.getNode();
IElementType elementType = PsiUtilCore.getElementType(node);
ASTNode parentNode = node == null ? null : node.getTreeParent();

// hack for signature_element wrapping variable_declaration
ASTNode grandParentNode = parentNode == null ? null : parentNode.getTreeParent();
IElementType grandParentElementType = PsiUtilCore.getElementType(grandParentNode);
if (grandParentElementType == SIGNATURE_ELEMENT && PsiUtilCore.getElementType(parentNode) == VARIABLE_DECLARATION_ELEMENT &&
node.getTextRange().equals(grandParentNode.getTextRange())) {
node = grandParentNode;
elementType = grandParentElementType;
}

if (elementType == ATTRIBUTES) {
return Indent.getContinuationIndent();
}

if (elementType == SIGNATURE_ELEMENT) {
return Indent.getContinuationWithoutFirstIndent();
}
if (SUB_OR_MODIFIER_DEFINITIONS_TOKENSET.contains(elementType) && block.getChildElementType(newChildIndex - 1) == LEFT_PAREN) {
return Indent.getNormalIndent();
}
Expand All @@ -184,10 +196,8 @@ public Indent getChildIndent(@NotNull PerlAstBlock block, int newChildIndex) {
return Indent.getNormalIndent();
}

if (block instanceof PerlSyntheticBlock && block.getSubBlocks().size() == newChildIndex) {
ASTNode parentNode = Objects.requireNonNull(block.getNode());
ASTNode grandParentNode = parentNode.getTreeParent();
return PsiUtilCore.getElementType(grandParentNode) == STATEMENT ? Indent.getNormalIndent() : Indent.getNoneIndent();
if (parentNode != null && block instanceof PerlSyntheticBlock && block.getSubBlocks().size() == newChildIndex) {
return PsiUtilCore.getElementType(parentNode) == STATEMENT ? Indent.getNormalIndent() : Indent.getNoneIndent();
}

List<Block> subBlocks = block.getSubBlocks();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.intellij.formatting.Indent;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand All @@ -41,10 +42,18 @@ default IElementType getElementType() {

@Nullable
default IElementType getChildElementType(int blockIndex) {
if (blockIndex < 0) {
return null;
}
List<Block> subBlocks = getSubBlocks();
if (subBlocks.size() <= blockIndex) {
return null;
}
return ASTBlock.getElementType(subBlocks.get(blockIndex));
}

@Nullable
default Block getLastSubBlock() {
return ContainerUtil.getLastItem(getSubBlocks());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 Alexandr Evstigneev
* Copyright 2015-2020 Alexandr Evstigneev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,7 +19,6 @@
import com.intellij.formatting.*;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.AtomicNullableLazyValue;
import com.intellij.psi.TokenType;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.formatter.common.AbstractBlock;
Expand Down Expand Up @@ -59,12 +58,9 @@ public class PerlFormattingBlock extends AbstractBlock implements PerlElementTyp
private final AtomicNotNullLazyValue<List<Block>> mySubBlocksProvider = AtomicNotNullLazyValue.createValue(
() -> ContainerUtil.immutableList(buildSubBlocks())
);
private final AtomicNullableLazyValue<Alignment> myAlignmentProvider = AtomicNullableLazyValue.createValue(
() -> getContext().getAlignment(myNode)
);

public PerlFormattingBlock(@NotNull ASTNode node, @NotNull PerlFormattingContext context) {
super(context.registerNode(node), context.getWrap(node), null);
super(context.registerNode(node), context.getWrap(node), context.getAlignment(node));
myContext = context;
buildChildren();
myIndent = context.getIndentProcessor().getNodeIndent(node);
Expand All @@ -80,12 +76,6 @@ protected final PerlFormattingContext getContext() {
return myContext;
}

@Nullable
@Override
public final Alignment getAlignment() {
return myAlignmentProvider.getValue();
}

@NotNull
@Override
protected final List<Block> buildChildren() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,12 @@ default PsiElement getDefaultValueElement() {
}
return isDeclarationElement(children[1]) ? null : children[1];
}

default boolean hasDefaultValueElement() {
return getDefaultValueElement() != null;
}

default boolean hasDeclarationElement() {
return getDeclarationElement() != null;
}
}
25 changes: 25 additions & 0 deletions plugin/test/formatter/PerlSubsFormatterEnterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,38 @@
import org.jetbrains.annotations.NotNull;
import org.junit.Test;

import static com.perl5.lang.perl.idea.formatter.settings.PerlCodeStyleSettings.OptionalConstructions.*;

public abstract class PerlSubsFormatterEnterTest extends PerlFormatterTestCase {

@Override
protected final String getBaseDataPath() {
return "testData/formatter/perl/enter/subs";
}

@Test
public void testSignatureElementDefaultValue() {
doTest();
}

@Test
public void testSignatureElementDefaultValueSecond() {
getCustomSettings().ALIGN_CONSECUTIVE_ASSIGNMENTS = NO_ALIGN;
doTest();
}

@Test
public void testSignatureElementDefaultValueSecondAligned() {
getCustomSettings().ALIGN_CONSECUTIVE_ASSIGNMENTS = ALIGN_LINES;
doTest();
}

@Test
public void testSignatureElementDefaultValueSecondAlignedStatement() {
getCustomSettings().ALIGN_CONSECUTIVE_ASSIGNMENTS = ALIGN_IN_STATEMENT;
doTest();
}

@Test
public void testAttributeSecond() {
getCustomSettings().ALIGN_ATTRIBUTES = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sub somesub(
$somevar =<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$somevar =
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sub somesub(
$firstvarlong = 42,
$somevar
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sub somesub(
$firstvarlong = 42,
$somevar
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sub somesub(
$firstvarlong = 42,
$somevar
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sub somesub(
$firstvarlong = 42,
$somevar
<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sub somesub(
$firstvarlong = 42,
$somevar<caret>
) :attribute
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sub somesub(
$firstvarlong = 42,
$somevar
<caret>
) :attribute
{
}
Loading

0 comments on commit 70d55e0

Please sign in to comment.