org.openrewrite.hcl.format.AttributeSpaceVisitor Maven / Gradle / Ivy
Show all versions of rewrite-hcl Show documentation
/*
* Copyright 2020 the original author or authors.
*
* 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
*
* https://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 org.openrewrite.hcl.format;
import org.openrewrite.Tree;
import org.openrewrite.hcl.HclIsoVisitor;
import org.openrewrite.hcl.style.SpacesStyle;
import org.openrewrite.hcl.tree.BodyContent;
import org.openrewrite.hcl.tree.Expression;
import org.openrewrite.hcl.tree.Hcl;
import org.openrewrite.hcl.tree.HclLeftPadded;
import org.openrewrite.internal.StringUtils;
import org.openrewrite.internal.lang.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AttributeSpaceVisitor
extends HclIsoVisitor
{
@Nullable
private final Tree stopAfter;
private final SpacesStyle style;
public AttributeSpaceVisitor(SpacesStyle style) {
this(style, null);
}
public AttributeSpaceVisitor(SpacesStyle style, @Nullable Tree stopAfter) {
this.style = style;
this.stopAfter = stopAfter;
}
@Override
public Hcl.Attribute visitAttribute(Hcl.Attribute attribute, P p) {
Hcl.Attribute a = super.visitAttribute(attribute, p);
Hcl parent = getCursor().getParentTreeCursor().getValue();
if (parent instanceof Hcl.Block || parent instanceof Hcl.ObjectValue) {
List siblingAttributes = getSiblingAttributes(parent);
if (attribute.getType().equals(Hcl.Attribute.Type.Assignment)) {
HclLeftPadded type = a.getPadding().getType();
if (Boolean.TRUE.equals(style.getBodyContent().getColumnarAlignment())) {
List groupAttributes = attributesInGroup(siblingAttributes, attribute);
int rightMostColumnOfAttributeKey = 0;
for (final Hcl.Attribute sibling : groupAttributes) {
rightMostColumnOfAttributeKey = Math.max(rightMostColumnOfAttributeKey, endColumn(sibling));
}
rightMostColumnOfAttributeKey = Math.max(rightMostColumnOfAttributeKey, endColumn(a));
int indent = rightMostColumnOfAttributeKey - endColumn(a) + 1;
a = a.getPadding().withType(type.withBefore(type.getBefore().withWhitespace(
StringUtils.repeat(" ", indent))));
} else if (Boolean.FALSE.equals(style.getBodyContent().getColumnarAlignment())) {
a = a.getPadding().withType(type.withBefore(type.getBefore().withWhitespace(" ")));
}
}
}
return a;
}
private List getSiblingAttributes(final Hcl parent) {
List allAttributes = new ArrayList<>();
if (parent instanceof Hcl.Block) {
for (final BodyContent bc : ((Hcl.Block) parent).getBody()) {
if (bc instanceof Hcl.Attribute) {
allAttributes.add((Hcl.Attribute) bc);
}
}
}else {
for (final Expression expr : ((Hcl.ObjectValue) parent).getAttributes()) {
if (expr instanceof Hcl.Attribute) {
allAttributes.add((Hcl.Attribute) expr);
}
}
}
return allAttributes;
}
// find group of attributes (attributes with no extra newlines) containing given attribute
private List attributesInGroup(List siblings, Hcl.Attribute attribute) {
boolean isAttributeMultiline = attribute.getValue().print(getCursor()).split("\r\n|\r|\n").length > 2;
if (isAttributeMultiline) {
return Collections.singletonList(attribute);
}
List groupAttributes = new ArrayList<>();
boolean groupFound = false;
Hcl.Attribute perviousSibling = null;
for (Hcl.Attribute sibling : siblings) {
if (sibling.getType().equals(Hcl.Attribute.Type.Assignment)) {
boolean siblingPrefixHasNewLines = sibling.getPrefix().getWhitespace().split("\r\n|\r|\n").length > 2;
boolean siblingIsMultiline = sibling.getValue().print(getCursor()).split("\r\n|\r|\n").length > 2;
boolean previousSiblingIsMultiline = perviousSibling != null && perviousSibling.getValue().print(getCursor()).split("\r\n|\r|\n").length > 2;
boolean newGroup = siblingPrefixHasNewLines || previousSiblingIsMultiline || siblingIsMultiline;
if (newGroup) {
if (groupFound) {
break;
}
groupAttributes.clear();
}
if (sibling.getId() == attribute.getId()) {
groupFound = true;
}
groupAttributes.add(sibling);
perviousSibling = sibling;
}
}
return groupAttributes;
}
private int endColumn(Hcl.Attribute attribute) {
return (attribute.getPrefix().getIndent() + attribute.getName().print(getCursor())).length();
}
@Nullable
@Override
public Hcl postVisit(Hcl tree, P p) {
if (stopAfter != null && stopAfter.isScope(tree)) {
getCursor().putMessageOnFirstEnclosing(Hcl.ConfigFile.class, "stop", true);
}
return super.postVisit(tree, p);
}
@Nullable
@Override
public Hcl visit(@Nullable Tree tree, P p) {
if (getCursor().getNearestMessage("stop") != null) {
return (Hcl) tree;
}
return super.visit(tree, p);
}
}