Skip to content

Commit

Permalink
feat(language): limit node declaration line length
Browse files Browse the repository at this point in the history
Avoid problems with text editors when opening large generated models
saved in the .refinery format.
  • Loading branch information
kris7t committed Dec 29, 2024
1 parent d2ec467 commit db28de9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@
import org.eclipse.xtext.formatting2.AbstractJavaFormatter;
import org.eclipse.xtext.formatting2.IFormattableDocument;
import org.eclipse.xtext.formatting2.IHiddenRegionFormatter;
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion;
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegionsFinder;
import org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import tools.refinery.language.model.problem.*;

@SuppressWarnings("UnstableApiUsage")
public class ProblemFormatter extends AbstractJavaFormatter {
public static final int MAX_LENGTH = 80;
public static final int TAB_SIZE = 4;

@Override
public void format(Object child, IFormattableDocument document) {
if (child instanceof AnnotatedElement annotatedElement) {
Expand Down Expand Up @@ -176,11 +180,42 @@ protected void format(Atom atom, IFormattableDocument doc) {
protected void format(NodeDeclaration nodeDeclaration, IFormattableDocument doc) {
surroundNewLines(doc, nodeDeclaration, this::singleNewLine);
var region = regionFor(nodeDeclaration);
doc.append(region.keyword("declare"), this::oneSpace);
doc.append(region.feature(ProblemPackage.Literals.NODE_DECLARATION__KIND), this::oneSpace);
formatList(region, ",", doc);
doc.prepend(region.keyword("."), this::noSpace);
for (var node : nodeDeclaration.getNodes()) {
var declare = region.keyword("declare");
int indentation = declare == null ? 0 : declare.getLength() + 1;
doc.append(declare, this::oneSpace);
var start = region.feature(ProblemPackage.Literals.NODE_DECLARATION__KIND);
doc.append(start, this::oneSpace);
if (start == null) {
start = declare;
} else {
indentation += start.getLength() + 1;
}
var end = region.keyword(".");
if (!nodeDeclaration.getNodes().isEmpty()) {
// This is a syntax error, but we should avoid clash between this and the space before even if we're
// asked to format an invalid document.
doc.prepend(end, this::noSpace);
}
doc.interior(start, end, IHiddenRegionFormatter::indent);
var commaIterator = region.keywords(",").iterator();
var nodeIterator = nodeDeclaration.getNodes().iterator();
ISemanticRegion lastComma = null;
while (nodeIterator.hasNext()) {
var node = nodeIterator.next();
var nodeRegion = regionForEObject(node);
// Add 1 for the space after the previous comma and add 1 for the comma or dot after.
int totalLength = 1 + nodeRegion.getLength() + 1;
int newOffset = indentation + totalLength;
boolean breakLineBefore = newOffset >= MAX_LENGTH;
if (breakLineBefore) {
doc.append(lastComma, this::newLine);
indentation = TAB_SIZE + totalLength;
} else {
doc.append(lastComma, this::oneSpace);
indentation = newOffset;
}
lastComma = commaIterator.hasNext() ? commaIterator.next() : null;
doc.prepend(lastComma, this::noSpace);
doc.format(node);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,8 @@ void nodeAnnotationTest() {
#pred Example(@optional string a, @optional int b).
atom @Example foo, @Example() @Example("foo", 3) @Example(b = 2, a = "bar") bar.
atom @Example foo,
@Example() @Example("foo", 3) @Example(b = 2, a = "bar") bar.
""");
}

Expand Down

0 comments on commit db28de9

Please sign in to comment.