Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More formatter fixes #1850

Merged
merged 6 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions cli/lff/src/test/java/org/lflang/cli/LffCliTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,35 @@ reactor Filter(period: int = 0, b: double[] = {0, 0}) {
// baz
state grid2: SnakeGrid = {= SnakeGrid::new(grid_side, &snake) =}
}
"""),
List.of(
"""
target Cpp

reactor ContextManager<Req, Resp, Ctx> {


\s
}

reactor MACService {
mul_cm = new ContextManager<loooooooooooooooooooooooooooooong, looooooooooooooong, loooooooooooooong>()
}

""",
"""
target Cpp

reactor ContextManager<Req, Resp, Ctx> {
}

reactor MACService {
mul_cm = new ContextManager<
loooooooooooooooooooooooooooooong,
looooooooooooooong,
loooooooooooooong
>()
}
"""));

LffTestFixture lffTester = new LffTestFixture();
Expand Down
54 changes: 38 additions & 16 deletions core/src/main/java/org/lflang/ast/MalleableString.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ public MalleableString indent() {
* whole of this.
* @param indentation The number of spaces used per level of indentation.
* @param singleLineCommentPrefix The prefix that marks the start of a single-line comment.
* @return Whether the best representation changed.
*/
public abstract void findBestRepresentation(
public abstract boolean findBestRepresentation(
Supplier<RenderResult> providedRender,
ToLongFunction<RenderResult> badness,
int width,
Expand Down Expand Up @@ -348,40 +349,59 @@ private List<String> getLinesOfInterest(
}

@Override
public void findBestRepresentation(
public boolean findBestRepresentation(
Supplier<RenderResult> providedRender,
ToLongFunction<RenderResult> badness,
int width,
int indentation,
String singleLineCommentPrefix) {
this.width = width;
keepCommentsOnSameLine = true;
optimizeChildren(providedRender, badness, width, indentation, singleLineCommentPrefix);
// Multiple calls to optimizeChildren may be required because as parts of the textual
// representation are updated, the optimal representation of other parts may change.
// For example, if the text is wider than 100 characters, the line may only need to be
// broken in one place, but it will be broken in multiple places a second optimization pass
// is not made. This is a heuristic in the sense that two passes are not guaranteed to result
// in a fixed point, but since a subsequent call to the formatter will get the same AST and
// therefore have the same starting point, the formatter as a whole should still be
// idempotent.
var everChanged = false;
var changed =
optimizeChildren(providedRender, badness, width, indentation, singleLineCommentPrefix);
everChanged = changed;
if (changed)
changed =
optimizeChildren(providedRender, badness, width, indentation, singleLineCommentPrefix);
if (components.stream()
.noneMatch(
it ->
it.render(indentation, singleLineCommentPrefix, false, null)
.unplacedComments
.findAny()
.isPresent())) return;
.isPresent())) return changed;
long badnessTrue = badness.applyAsLong(providedRender.get());
keepCommentsOnSameLine = false;
optimizeChildren(providedRender, badness, width, indentation, singleLineCommentPrefix);
changed =
optimizeChildren(providedRender, badness, width, indentation, singleLineCommentPrefix);
everChanged |= changed;
long badnessFalse = badness.applyAsLong(providedRender.get());
keepCommentsOnSameLine = badnessTrue < badnessFalse;
optimizeChildren(providedRender, badness, width, indentation, singleLineCommentPrefix);
optimizeChildren(providedRender, badness, width, indentation, singleLineCommentPrefix);
if (changed)
changed =
optimizeChildren(providedRender, badness, width, indentation, singleLineCommentPrefix);
if (changed)
optimizeChildren(providedRender, badness, width, indentation, singleLineCommentPrefix);
petervdonovan marked this conversation as resolved.
Show resolved Hide resolved
return everChanged;
}

private void optimizeChildren(
private boolean optimizeChildren(
Supplier<RenderResult> providedRender,
ToLongFunction<RenderResult> badness,
int width,
int indentation,
String singleLineCommentPrefix) {
components
.reverse()
.forEach(
return components.reverse().stream()
.anyMatch(
it ->
it.findBestRepresentation(
providedRender, badness, width, indentation, singleLineCommentPrefix));
Expand Down Expand Up @@ -409,14 +429,14 @@ public MalleableString indent() {
}

@Override
public void findBestRepresentation(
public boolean findBestRepresentation(
Supplier<RenderResult> providedRender,
ToLongFunction<RenderResult> badness,
int width,
int indentation,
String singleLineCommentPrefix) {
this.width = width;
nested.findBestRepresentation(
return nested.findBestRepresentation(
providedRender, badness, width - indentation, indentation, singleLineCommentPrefix);
}

Expand Down Expand Up @@ -462,12 +482,13 @@ public String toString() {
}

@Override
public void findBestRepresentation(
public boolean findBestRepresentation(
Supplier<RenderResult> providedRender,
ToLongFunction<RenderResult> badness,
int width,
int indentation,
String singleLineCommentPrefix) {
var initialChosenPossibility = getChosenPossibility();
bestPossibility =
Collections.min(
getPossibilities(),
Expand All @@ -479,9 +500,10 @@ public void findBestRepresentation(
return Math.toIntExact(badnessA - badnessB);
});
if (bestPossibility instanceof MalleableString ms) {
ms.findBestRepresentation(
providedRender, badness, width, indentation, singleLineCommentPrefix);
if (ms.findBestRepresentation(
providedRender, badness, width, indentation, singleLineCommentPrefix)) return true;
}
return getChosenPossibility() != initialChosenPossibility;
}

/** Return the best representation of this. */
Expand Down
13 changes: 6 additions & 7 deletions core/src/main/java/org/lflang/formatting2/LFFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.xtext.formatting2.FormatterRequest;
import org.eclipse.xtext.formatting2.IFormatter2;
import org.eclipse.xtext.formatting2.regionaccess.ITextReplacement;
Expand All @@ -24,13 +25,11 @@ public class LFFormatter implements IFormatter2 {
@Override
public List<ITextReplacement> format(FormatterRequest request) {
// TODO: Use a CancelIndicator that actually cancels?
if (!request.getTextRegionAccess().getResource().getErrors().isEmpty()
|| !validator
.validate(
request.getTextRegionAccess().getResource(),
CheckMode.ALL,
CancelIndicator.NullImpl)
.isEmpty()) {
if (validator
.validate(
request.getTextRegionAccess().getResource(), CheckMode.ALL, CancelIndicator.NullImpl)
.stream()
.anyMatch(it -> it.isSyntaxError() && it.getSeverity() == Severity.ERROR)) {
return List.of();
}
ITextSegment documentRegion = request.getTextRegionAccess().regionForDocument();
Expand Down
3 changes: 1 addition & 2 deletions test/C/src/federated/DistributedLogicalActionUpstreamLong.lf
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ federated reactor {
passThroughs7.out,
passThroughs8.out,
passThroughs9.out,
passThroughs10.out
->
passThroughs10.out ->
passThroughs1.in,
passThroughs2.in,
passThroughs3.in,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ federated reactor {
passThroughs7.out,
passThroughs8.out,
passThroughs9.out,
passThroughs10.out
->
passThroughs10.out ->
passThroughs1.in,
passThroughs2.in,
passThroughs3.in,
Expand Down
3 changes: 1 addition & 2 deletions test/C/src/modal_models/BanksModalStateReset.lf
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ main reactor {
reset2.mode_switch,
reset2.count0,
reset2.count1,
reset2.count2
-> test.events
reset2.count2 -> test.events

// Trigger mode change (separately because of #1278)
reaction(stepper) -> reset1.next {=
Expand Down
3 changes: 1 addition & 2 deletions test/C/src/modal_models/ModalActions.lf
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ main reactor {
modal.action1_sched,
modal.action1_exec,
modal.action2_sched,
modal.action2_exec
-> test.events
modal.action2_exec -> test.events

reaction(stepper) -> modal.next {= lf_set(modal.next, true); =} // Trigger mode change
}
3 changes: 1 addition & 2 deletions test/C/src/modal_models/ModalStartupShutdown.lf
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ main reactor {
modal.shutdown4,
modal.startup5,
modal.reset5,
modal.shutdown5
-> test.events
modal.shutdown5 -> test.events

reaction(stepper) -> modal.next {= lf_set(modal.next, true); =} // Trigger mode change
}
3 changes: 1 addition & 2 deletions test/Python/src/modal_models/BanksModalStateReset.lf
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ main reactor {
reset2.mode_switch,
reset2.count0,
reset2.count1,
reset2.count2
-> test.events
reset2.count2 -> test.events

# Trigger mode change (separately because of #1278)
reaction(stepper) -> reset1.next {=
Expand Down
3 changes: 1 addition & 2 deletions test/Python/src/modal_models/ModalActions.lf
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ main reactor {
modal.action1_sched,
modal.action1_exec,
modal.action2_sched,
modal.action2_exec
-> test.events
modal.action2_exec -> test.events

reaction(stepper) -> modal.next {= modal.next.set(True) =} # Trigger mode change
}
3 changes: 1 addition & 2 deletions test/Python/src/modal_models/ModalStartupShutdown.lf
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ main reactor {
modal.shutdown4,
modal.startup5,
modal.reset5,
modal.shutdown5
-> test.events
modal.shutdown5 -> test.events

reaction(stepper) -> modal.next {= modal.next.set(True) =} # Trigger mode change
}
4 changes: 1 addition & 3 deletions test/TypeScript/src/DeadlineHandledAbove.lf
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ reactor Deadline(threshold: time = 100 msec) {

reaction(x) -> deadline_violation {=
util.requestErrorStop("ERROR: Deadline violation was not detected!")
=} deadline(
threshold
) {=
=} deadline(threshold) {=
console.log("Deadline violation detected.");
deadline_violation = true;
=}
Expand Down
4 changes: 1 addition & 3 deletions test/TypeScript/src/SimpleDeadline.lf
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ reactor Deadline(threshold: time = 100 msec) {

reaction(x) -> deadlineViolation {=
util.requestErrorStop("ERROR: Deadline violation was not detected!")
=} deadline(
threshold
) {=
=} deadline(threshold) {=
console.log("Deadline violation detected.");
deadlineViolation = true;
=}
Expand Down