From c68a5b2fd7cffe17d2a896513a5dd266880e226c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 13 Sep 2023 15:44:10 +0200 Subject: [PATCH 01/22] Add bracket list expression --- .../main/java/org/lflang/LinguaFranca.xtext | 8 ++++++++ core/src/main/java/org/lflang/Target.java | 5 +++++ .../src/main/java/org/lflang/ast/IsEqual.java | 8 ++++++++ core/src/main/java/org/lflang/ast/ToLf.java | 10 ++++++++++ core/src/main/java/org/lflang/ast/ToText.java | 6 ++++++ .../lflang/generator/LfExpressionVisitor.java | 19 +++++++++++++++++++ .../org/lflang/generator/TargetTypes.java | 11 +++++++++++ .../org/lflang/validation/LFValidator.java | 10 ++++++++++ 8 files changed, 77 insertions(+) diff --git a/core/src/main/java/org/lflang/LinguaFranca.xtext b/core/src/main/java/org/lflang/LinguaFranca.xtext index b00456ce07..593b06317e 100644 --- a/core/src/main/java/org/lflang/LinguaFranca.xtext +++ b/core/src/main/java/org/lflang/LinguaFranca.xtext @@ -320,6 +320,7 @@ Expression: | ParameterReference | {CodeExpr} code=Code | BracedListExpression + | BracketListExpression ; // A list of expressions within braces. @@ -328,6 +329,13 @@ BracedListExpression: '{' {BracedListExpression} (items+=Expression (',' items+=Expression)*)? ','? '}' ; +// A list of expressions within square brackets. +// In Python and TS, this is a list literal. In Rust this could be an array but Rust +// array expressions are relatively rare so probably not worth supporting. +BracketListExpression: + '[' {BracketListExpression} (items+=Expression (',' items+=Expression)*)? ','? ']' +; + ParameterReference: parameter=[Parameter] ; diff --git a/core/src/main/java/org/lflang/Target.java b/core/src/main/java/org/lflang/Target.java index 096788484e..8dc820f826 100644 --- a/core/src/main/java/org/lflang/Target.java +++ b/core/src/main/java/org/lflang/Target.java @@ -524,6 +524,11 @@ public boolean allowsBracedListExpressions() { return this == C || this == CCPP || this == CPP; } + /** Allow expressions of the form {@code [a, b, c]}. */ + public boolean allowsBracketListExpressions() { + return this == Python || this == TS || this == Rust; + } + /** Return a string that demarcates the beginning of a single-line comment. */ public String getSingleLineCommentPrefix() { return this.equals(Target.Python) ? "#" : "//"; diff --git a/core/src/main/java/org/lflang/ast/IsEqual.java b/core/src/main/java/org/lflang/ast/IsEqual.java index af06923d35..9ac2a0a389 100644 --- a/core/src/main/java/org/lflang/ast/IsEqual.java +++ b/core/src/main/java/org/lflang/ast/IsEqual.java @@ -16,6 +16,7 @@ import org.lflang.lf.AttrParm; import org.lflang.lf.Attribute; import org.lflang.lf.BracedListExpression; +import org.lflang.lf.BracketListExpression; import org.lflang.lf.BuiltinTriggerRef; import org.lflang.lf.Code; import org.lflang.lf.CodeExpr; @@ -465,6 +466,13 @@ public Boolean caseBracedListExpression(BracedListExpression object) { .conclusion; } + @Override + public Boolean caseBracketListExpression(BracketListExpression object) { + return new ComparisonMachine<>(object, BracketListExpression.class) + .listsEquivalent(BracketListExpression::getItems) + .conclusion; + } + @Override public Boolean caseParameterReference(ParameterReference object) { return new ComparisonMachine<>(object, ParameterReference.class) diff --git a/core/src/main/java/org/lflang/ast/ToLf.java b/core/src/main/java/org/lflang/ast/ToLf.java index b91ea5499c..149b9211a3 100644 --- a/core/src/main/java/org/lflang/ast/ToLf.java +++ b/core/src/main/java/org/lflang/ast/ToLf.java @@ -30,6 +30,7 @@ import org.lflang.lf.AttrParm; import org.lflang.lf.Attribute; import org.lflang.lf.BracedListExpression; +import org.lflang.lf.BracketListExpression; import org.lflang.lf.BuiltinTriggerRef; import org.lflang.lf.Code; import org.lflang.lf.CodeExpr; @@ -873,6 +874,15 @@ public MalleableString caseBracedListExpression(BracedListExpression object) { return bracedListExpression(object.getItems()); } + + @Override + public MalleableString caseBracketListExpression(BracketListExpression object) { + if (object.getItems().isEmpty()) { + return MalleableString.anyOf("[]"); + } + return list(", ", "[", "]", false, false, true, object.getItems()); + } + /** * Represent a braced list expression. Do not invoke on expressions that may have comments * attached. diff --git a/core/src/main/java/org/lflang/ast/ToText.java b/core/src/main/java/org/lflang/ast/ToText.java index 6845fde4e7..515eb29fe5 100644 --- a/core/src/main/java/org/lflang/ast/ToText.java +++ b/core/src/main/java/org/lflang/ast/ToText.java @@ -6,6 +6,7 @@ import org.eclipse.xtext.nodemodel.util.NodeModelUtils; import org.lflang.lf.ArraySpec; import org.lflang.lf.BracedListExpression; +import org.lflang.lf.BracketListExpression; import org.lflang.lf.Code; import org.lflang.lf.CodeExpr; import org.lflang.lf.Host; @@ -80,6 +81,11 @@ public String caseBracedListExpression(BracedListExpression object) { return new ToLf().caseBracedListExpression(object).toString(); } + @Override + public String caseBracketListExpression(BracketListExpression object) { + return new ToLf().caseBracketListExpression(object).toString(); + } + @Override public String caseHost(Host host) { return new ToLf().caseHost(host).toString(); diff --git a/core/src/main/java/org/lflang/generator/LfExpressionVisitor.java b/core/src/main/java/org/lflang/generator/LfExpressionVisitor.java index 15f0e8ddad..e5b669b6f2 100644 --- a/core/src/main/java/org/lflang/generator/LfExpressionVisitor.java +++ b/core/src/main/java/org/lflang/generator/LfExpressionVisitor.java @@ -25,6 +25,7 @@ package org.lflang.generator; import org.lflang.lf.BracedListExpression; +import org.lflang.lf.BracketListExpression; import org.lflang.lf.Code; import org.lflang.lf.CodeExpr; import org.lflang.lf.Expression; @@ -43,6 +44,7 @@ public interface LfExpressionVisitor { R visitLiteral(Literal expr, P param); R visitBracedListExpr(BracedListExpression expr, P param); + R visitBracketListExpr(BracketListExpression expr, P param); R visitTimeLiteral(Time expr, P param); @@ -66,6 +68,8 @@ static R dispatch( return visitor.visitLiteral((Literal) e, arg); } else if (e instanceof BracedListExpression) { return visitor.visitBracedListExpr((BracedListExpression) e, arg); + } else if (e instanceof BracketListExpression) { + return visitor.visitBracketListExpr((BracketListExpression) e, arg); } else if (e instanceof Time) { return visitor.visitTimeLiteral((Time) e, arg); } else if (e instanceof CodeExpr) { @@ -106,6 +110,11 @@ public R visitCodeExpr(CodeExpr expr, P param) { public R visitParameterRef(ParameterReference expr, P param) { return visitExpression(expr, param); } + + @Override + public R visitBracketListExpr(BracketListExpression expr, P param) { + return visitExpression(expr, param); + } } /** @@ -147,6 +156,16 @@ public Expression visitParameterRef(ParameterReference expr, P param) { return clone; } + @Override + public Expression visitBracketListExpr(BracketListExpression expr, P param) { + BracketListExpression clone = LfFactory.eINSTANCE.createBracketListExpression(); + for (Expression item : expr.getItems()) { + clone.getItems().add(dispatch(item, param, this)); + } + return clone; + + } + @Override public Expression visitCodeExpr(CodeExpr expr, P param) { CodeExpr codeExpr = LfFactory.eINSTANCE.createCodeExpr(); diff --git a/core/src/main/java/org/lflang/generator/TargetTypes.java b/core/src/main/java/org/lflang/generator/TargetTypes.java index 968a641ed3..65552edc59 100644 --- a/core/src/main/java/org/lflang/generator/TargetTypes.java +++ b/core/src/main/java/org/lflang/generator/TargetTypes.java @@ -8,6 +8,7 @@ import org.lflang.ast.ASTUtils; import org.lflang.lf.Action; import org.lflang.lf.BracedListExpression; +import org.lflang.lf.BracketListExpression; import org.lflang.lf.CodeExpr; import org.lflang.lf.Expression; import org.lflang.lf.Initializer; @@ -60,6 +61,14 @@ default String getTargetBracedListExpr(BracedListExpression expr, InferredType t .collect(Collectors.joining(",", "{", "}")); } + /** Translate the bracket list expression into target language syntax. */ + default String getTargetBracketListExpr(BracketListExpression expr, InferredType typeOrNull) { + InferredType t = typeOrNull == null ? InferredType.undefined() : typeOrNull; + return expr.getItems().stream() + .map(e -> getTargetExpr(e, t)) + .collect(Collectors.joining(", ", "[", "]")); + } + /** Return an "unknown" type which is used as a default when a type cannot be inferred. */ String getTargetUndefinedType(); @@ -224,6 +233,8 @@ default String getTargetExpr(Expression expr, InferredType type) { return ASTUtils.toText(((CodeExpr) expr).getCode()); } else if (expr instanceof BracedListExpression) { return getTargetBracedListExpr((BracedListExpression) expr, type); + } else if (expr instanceof BracketListExpression) { + return getTargetBracketListExpr((BracketListExpression) expr, type); } else { throw new IllegalStateException("Invalid value " + expr); } diff --git a/core/src/main/java/org/lflang/validation/LFValidator.java b/core/src/main/java/org/lflang/validation/LFValidator.java index 7dcf00d107..755d28a42b 100644 --- a/core/src/main/java/org/lflang/validation/LFValidator.java +++ b/core/src/main/java/org/lflang/validation/LFValidator.java @@ -72,6 +72,7 @@ import org.lflang.lf.Assignment; import org.lflang.lf.Attribute; import org.lflang.lf.BracedListExpression; +import org.lflang.lf.BracketListExpression; import org.lflang.lf.BuiltinTrigger; import org.lflang.lf.BuiltinTriggerRef; import org.lflang.lf.Connection; @@ -193,6 +194,15 @@ public void checkBracedExpression(BracedListExpression expr) { } } + @Check(CheckType.FAST) + public void checkBracketExpression(BracketListExpression expr) { + if (!target.allowsBracketListExpressions()) { + var message = + "Bracketed expression lists are not a valid expression for the " + target + " target."; + error(message, Literals.BRACKET_LIST_EXPRESSION.eContainmentFeature()); + } + } + @Check(CheckType.FAST) public void checkAssignment(Assignment assignment) { From 2bb8212be4411485d2c0891636ff71acdf898a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 13 Sep 2023 15:46:41 +0200 Subject: [PATCH 02/22] Update tests --- .../src/modal_models/util/TraceTesting.lf | 4 +-- test/Rust/src/ArrayAsParameter.lf | 36 +++++++++++++++++++ test/TypeScript/src/ArrayAsParameter.lf | 4 +-- test/TypeScript/src/MovingAverage.lf | 2 +- 4 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 test/Rust/src/ArrayAsParameter.lf diff --git a/test/Python/src/modal_models/util/TraceTesting.lf b/test/Python/src/modal_models/util/TraceTesting.lf index 0d5053b844..4bad50cd26 100644 --- a/test/Python/src/modal_models/util/TraceTesting.lf +++ b/test/Python/src/modal_models/util/TraceTesting.lf @@ -1,12 +1,12 @@ /** Utility reactor to record and test execution traces. */ target Python -reactor TraceTesting(events_size=0, trace = {= [] =}, training=False) { +reactor TraceTesting(events_size=0, trace = [], training=False) { input[events_size] events state last_reaction_time = 0 state trace_idx = 0 - state recorded_events = {= [] =} + state recorded_events = [] state recorded_events_next = 0 reaction(startup) {= diff --git a/test/Rust/src/ArrayAsParameter.lf b/test/Rust/src/ArrayAsParameter.lf new file mode 100644 index 0000000000..2692512273 --- /dev/null +++ b/test/Rust/src/ArrayAsParameter.lf @@ -0,0 +1,36 @@ +// Source has an array as a parameter, the elements of which it passes to Print. +target Rust + +reactor Source(sequence: {= [i32; 3] =} = [0, 1, 2]) { + output out: i32 + state count: usize = 0 + state seq = sequence + logical action next + + reaction(startup, next) -> out, next {= + ctx.set(out, self.seq[self.count]); + self.count += 1; + if self.count < self.seq.len() { + ctx.schedule(next, Asap); + } + =} +} + +reactor Print { + input x: i32 + state count: usize = 0 + + reaction(x) {= + let expected = [2, 3, 4]; + let x = ctx.get(x).unwrap(); + println!("Received: {}.", x); + assert_eq!(x, expected[self.count]); + self.count += 1; + =} +} + +main reactor ArrayAsParameter { + s = new Source(sequence = [2, 3, 4]) + p = new Print() + s.out -> p.x +} diff --git a/test/TypeScript/src/ArrayAsParameter.lf b/test/TypeScript/src/ArrayAsParameter.lf index ef9ba9f414..10ef7a5c32 100644 --- a/test/TypeScript/src/ArrayAsParameter.lf +++ b/test/TypeScript/src/ArrayAsParameter.lf @@ -1,7 +1,7 @@ // Source has an array as a parameter, the elements of which it passes to Print. target TypeScript -reactor Source(sequence: {= Array =} = {= [0, 1, 2] =}) { +reactor Source(sequence: Array = [0, 1, 2]) { output out: number state count: number = 0 logical action next @@ -29,7 +29,7 @@ reactor Print { } main reactor ArrayAsParameter { - s = new Source(sequence = {= [1, 2, 3, 4] =}) + s = new Source(sequence = [1, 2, 3, 4]) p = new Print() s.out -> p.x } diff --git a/test/TypeScript/src/MovingAverage.lf b/test/TypeScript/src/MovingAverage.lf index f99e436ab7..dfe550f612 100644 --- a/test/TypeScript/src/MovingAverage.lf +++ b/test/TypeScript/src/MovingAverage.lf @@ -17,7 +17,7 @@ reactor Source { } reactor MovingAverageImpl { - state delay_line: {= Array =} = {= [0.0, 0.0, 0.0] =} + state delay_line: Array = [0.0, 0.0, 0.0] state index: number = 0 input x: number output out: number From 82dd4d64fd50038f0a414a333e3e8632dd4de8c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 13 Sep 2023 16:32:57 +0200 Subject: [PATCH 03/22] Format --- test/Python/src/modal_models/util/TraceTesting.lf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Python/src/modal_models/util/TraceTesting.lf b/test/Python/src/modal_models/util/TraceTesting.lf index 4bad50cd26..027b1ccb19 100644 --- a/test/Python/src/modal_models/util/TraceTesting.lf +++ b/test/Python/src/modal_models/util/TraceTesting.lf @@ -1,7 +1,7 @@ /** Utility reactor to record and test execution traces. */ target Python -reactor TraceTesting(events_size=0, trace = [], training=False) { +reactor TraceTesting(events_size=0, trace=[], training=False) { input[events_size] events state last_reaction_time = 0 From e9f3bade4f8e5c9e72b6e8ddd7f329ece28ab081 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Thu, 14 Sep 2023 17:03:29 -0700 Subject: [PATCH 04/22] Build epoch against fork --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6d7edf2145..25c12ebf0e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,8 @@ jobs: files: core/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml,cli/base/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml,cli/lfc/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml,cli/lfd/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml,cli/lff/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml epoch: - uses: lf-lang/epoch/.github/workflows/build.yml@main + uses: lf-lang/epoch/.github/workflows/build.yml@build-against-fork with: lingua-franca-ref: ${{ github.head_ref || github.ref_name }} + lingua-franca-repo: ${{ github.repository }} upload-artifacts: false From 91b219b4fa42a2e51c3f384157cf80328467d363 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Thu, 14 Sep 2023 18:24:29 -0700 Subject: [PATCH 05/22] Pass in URL instead of repo name --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 25c12ebf0e..32e34c9ffb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,5 +35,5 @@ jobs: uses: lf-lang/epoch/.github/workflows/build.yml@build-against-fork with: lingua-franca-ref: ${{ github.head_ref || github.ref_name }} - lingua-franca-repo: ${{ github.repository }} + lingua-franca-repo: ${{ github.event.pull_request.head.repo.full_name }} upload-artifacts: false From 63ddf066a7821fbd2272d02aca7ad0661f85b601 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Thu, 14 Sep 2023 19:24:44 -0700 Subject: [PATCH 06/22] Apply formatter --- core/src/main/java/org/lflang/ast/ToLf.java | 1 - .../src/main/java/org/lflang/generator/LfExpressionVisitor.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/main/java/org/lflang/ast/ToLf.java b/core/src/main/java/org/lflang/ast/ToLf.java index 149b9211a3..dd8096a5e3 100644 --- a/core/src/main/java/org/lflang/ast/ToLf.java +++ b/core/src/main/java/org/lflang/ast/ToLf.java @@ -874,7 +874,6 @@ public MalleableString caseBracedListExpression(BracedListExpression object) { return bracedListExpression(object.getItems()); } - @Override public MalleableString caseBracketListExpression(BracketListExpression object) { if (object.getItems().isEmpty()) { diff --git a/core/src/main/java/org/lflang/generator/LfExpressionVisitor.java b/core/src/main/java/org/lflang/generator/LfExpressionVisitor.java index e5b669b6f2..c50f805209 100644 --- a/core/src/main/java/org/lflang/generator/LfExpressionVisitor.java +++ b/core/src/main/java/org/lflang/generator/LfExpressionVisitor.java @@ -44,6 +44,7 @@ public interface LfExpressionVisitor { R visitLiteral(Literal expr, P param); R visitBracedListExpr(BracedListExpression expr, P param); + R visitBracketListExpr(BracketListExpression expr, P param); R visitTimeLiteral(Time expr, P param); @@ -163,7 +164,6 @@ public Expression visitBracketListExpr(BracketListExpression expr, P param) { clone.getItems().add(dispatch(item, param, this)); } return clone; - } @Override From da30b7925e7358e622755a2e0516191f42b12894 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Thu, 14 Sep 2023 22:04:35 -0700 Subject: [PATCH 07/22] Update .github/workflows/build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 32e34c9ffb..da1990ca3f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,7 @@ jobs: files: core/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml,cli/base/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml,cli/lfc/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml,cli/lfd/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml,cli/lff/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml epoch: - uses: lf-lang/epoch/.github/workflows/build.yml@build-against-fork + uses: lf-lang/epoch/.github/workflows/build.yml@main with: lingua-franca-ref: ${{ github.head_ref || github.ref_name }} lingua-franca-repo: ${{ github.event.pull_request.head.repo.full_name }} From 7b5f0a9ce82a4b5eb5261dd66f5f72d308f0a00e Mon Sep 17 00:00:00 2001 From: Christian Menard Date: Fri, 22 Sep 2023 11:49:53 +0200 Subject: [PATCH 08/22] add lsp dependency on de.cau.cs.kieler.klighd.incremental This should stabilize the diagram generation in VS Code. See https://github.com/lf-lang/vscode-lingua-franca/issues/103 and this comment: https://github.com/lf-lang/vscode-lingua-franca/issues/103#issuecomment-1731023470 --- lsp/build.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lsp/build.gradle b/lsp/build.gradle index 772f618db1..65215162b7 100644 --- a/lsp/build.gradle +++ b/lsp/build.gradle @@ -10,6 +10,13 @@ dependencies { exclude group: 'org.eclipse.platform', module: 'org.eclipse.swt.*' exclude group: 'org.eclipse.platform', module: 'org.eclipse.swt' } + + // This dependency ensures correct animations and bookkeeping during updates + // See https://github.com/lf-lang/vscode-lingua-franca/issues/103#issuecomment-1731023470 + implementation ("de.cau.cs.kieler.klighd:de.cau.cs.kieler.klighd.incremental:$klighdVersion") { + exclude group: 'org.eclipse.platform', module: 'org.eclipse.swt.*' + exclude group: 'org.eclipse.platform', module: 'org.eclipse.swt' + } } application { From d61d3e650334afdd4526c44ebccbbda5a87fa427 Mon Sep 17 00:00:00 2001 From: Christian Menard Date: Fri, 22 Sep 2023 16:43:51 +0200 Subject: [PATCH 09/22] add synthesis option to control if reactors are expanded by default --- .../lflang/diagram/synthesis/LinguaFrancaSynthesis.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/lflang/diagram/synthesis/LinguaFrancaSynthesis.java b/core/src/main/java/org/lflang/diagram/synthesis/LinguaFrancaSynthesis.java index b51822c9a5..0c6c88d8d5 100644 --- a/core/src/main/java/org/lflang/diagram/synthesis/LinguaFrancaSynthesis.java +++ b/core/src/main/java/org/lflang/diagram/synthesis/LinguaFrancaSynthesis.java @@ -257,6 +257,9 @@ public class LinguaFrancaSynthesis extends AbstractDiagramSynthesis { SynthesisOption.createRangeOption("Reactor Parameter/Variable Columns", 1, 10, 1) .setCategory(APPEARANCE); + public static final SynthesisOption DEFAULT_EXPAND_ALL = + SynthesisOption.createCheckOption("Expand reactors by default", false); + public static final SynthesisOption FIXED_PORT_SIDE = SynthesisOption.createCheckOption("Fixed Port Sides", true).setCategory(LAYOUT); public static final SynthesisOption SPACING = @@ -273,6 +276,7 @@ public class LinguaFrancaSynthesis extends AbstractDiagramSynthesis { public List getDisplayedSynthesisOptions() { return List.of( SHOW_ALL_REACTORS, + DEFAULT_EXPAND_ALL, MemorizingExpandCollapseAction.MEMORIZE_EXPANSION_STATES, CYCLE_DETECTION, APPEARANCE, @@ -1019,18 +1023,16 @@ private Collection transformReactorNetwork( TriggerInstance reset = null; // Transform instances - int index = 0; for (ReactorInstance child : reactorInstance.children) { Boolean expansionState = MemorizingExpandCollapseAction.getExpansionState(child); Collection rNodes = createReactorNode( child, - expansionState != null ? expansionState : false, + expansionState != null ? expansionState : getBooleanValue(DEFAULT_EXPAND_ALL), inputPorts, outputPorts, allReactorNodes); nodes.addAll(rNodes); - index++; } // Create timers From b7ee795dffb8222756fa88dddc89b7e4f5b7322c Mon Sep 17 00:00:00 2001 From: Christian Menard Date: Fri, 22 Sep 2023 17:06:32 +0200 Subject: [PATCH 10/22] Removed "Reaction level" diagram synthesis option Fixes https://github.com/lf-lang/lingua-franca/issues/2017 --- .../synthesis/LinguaFrancaSynthesis.java | 3 --- .../styles/LinguaFrancaShapeExtensions.java | 18 ------------------ 2 files changed, 21 deletions(-) diff --git a/core/src/main/java/org/lflang/diagram/synthesis/LinguaFrancaSynthesis.java b/core/src/main/java/org/lflang/diagram/synthesis/LinguaFrancaSynthesis.java index b51822c9a5..1c992557b6 100644 --- a/core/src/main/java/org/lflang/diagram/synthesis/LinguaFrancaSynthesis.java +++ b/core/src/main/java/org/lflang/diagram/synthesis/LinguaFrancaSynthesis.java @@ -237,8 +237,6 @@ public class LinguaFrancaSynthesis extends AbstractDiagramSynthesis { SynthesisOption.createCheckOption("Multiport Widths", false).setCategory(APPEARANCE); public static final SynthesisOption SHOW_REACTION_CODE = SynthesisOption.createCheckOption("Reaction Code", false).setCategory(APPEARANCE); - public static final SynthesisOption SHOW_REACTION_LEVEL = - SynthesisOption.createCheckOption("Reaction Level", false).setCategory(APPEARANCE); public static final SynthesisOption SHOW_REACTION_ORDER_EDGES = SynthesisOption.createCheckOption("Reaction Order Edges", false).setCategory(APPEARANCE); public static final SynthesisOption SHOW_REACTOR_HOST = @@ -287,7 +285,6 @@ public List getDisplayedSynthesisOptions() { SHOW_PORT_NAMES, SHOW_MULTIPORT_WIDTH, SHOW_REACTION_CODE, - SHOW_REACTION_LEVEL, SHOW_REACTION_ORDER_EDGES, SHOW_REACTOR_HOST, SHOW_INSTANCE_NAMES, diff --git a/core/src/main/java/org/lflang/diagram/synthesis/styles/LinguaFrancaShapeExtensions.java b/core/src/main/java/org/lflang/diagram/synthesis/styles/LinguaFrancaShapeExtensions.java index b8ee69fa1c..88d15db4f6 100644 --- a/core/src/main/java/org/lflang/diagram/synthesis/styles/LinguaFrancaShapeExtensions.java +++ b/core/src/main/java/org/lflang/diagram/synthesis/styles/LinguaFrancaShapeExtensions.java @@ -72,7 +72,6 @@ import org.eclipse.elk.graph.properties.Property; import org.eclipse.xtext.xbase.lib.Extension; import org.eclipse.xtext.xbase.lib.Functions.Function1; -import org.eclipse.xtext.xbase.lib.IterableExtensions; import org.eclipse.xtext.xbase.lib.Pair; import org.eclipse.xtext.xbase.lib.StringExtensions; import org.lflang.ast.ASTUtils; @@ -424,23 +423,6 @@ public KPolygon addReactionFigure(KNode node, ReactionInstance reaction) { DiagramSyntheses.suppressSelectability(textToAdd); } - // optional reaction level - if (getBooleanValue(LinguaFrancaSynthesis.SHOW_REACTION_LEVEL)) { - // Force calculation of levels for reactions. This calculation - // will only be done once. Note that if this fails due to a causality loop, - // then some reactions will have level -1. - try { - String levels = IterableExtensions.join(reaction.getLevels(), ", "); - KText levelsText = - _kContainerRenderingExtensions.addText(contentContainer, ("level: " + levels)); - _kRenderingExtensions.setFontBold(levelsText, false); - _linguaFrancaStyleExtensions.noSelectionStyle(levelsText); - DiagramSyntheses.suppressSelectability(levelsText); - } catch (Exception ex) { - // If the graph has cycles, the above fails. Continue without showing levels. - } - } - // optional code content boolean hasCode = getBooleanValue(LinguaFrancaSynthesis.SHOW_REACTION_CODE) From 52180e2e1e04d02b920c633930c3f5da469de41a Mon Sep 17 00:00:00 2001 From: Christian Menard Date: Fri, 22 Sep 2023 17:11:38 +0200 Subject: [PATCH 11/22] Avoid null pointer exception in diagrams with bodyless reactions --- .../diagram/synthesis/styles/LinguaFrancaShapeExtensions.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/org/lflang/diagram/synthesis/styles/LinguaFrancaShapeExtensions.java b/core/src/main/java/org/lflang/diagram/synthesis/styles/LinguaFrancaShapeExtensions.java index b8ee69fa1c..893d7df47b 100644 --- a/core/src/main/java/org/lflang/diagram/synthesis/styles/LinguaFrancaShapeExtensions.java +++ b/core/src/main/java/org/lflang/diagram/synthesis/styles/LinguaFrancaShapeExtensions.java @@ -444,6 +444,7 @@ public KPolygon addReactionFigure(KNode node, ReactionInstance reaction) { // optional code content boolean hasCode = getBooleanValue(LinguaFrancaSynthesis.SHOW_REACTION_CODE) + && reaction.getDefinition().getCode() != null && !StringExtensions.isNullOrEmpty(reaction.getDefinition().getCode().getBody()); if (hasCode) { KText hasCodeText = From 18d83214feeb03d96f79d607261fcbee7fb9d00e Mon Sep 17 00:00:00 2001 From: Christian Menard Date: Fri, 22 Sep 2023 17:57:56 +0200 Subject: [PATCH 12/22] Removed stray print statement --- core/src/main/java/org/lflang/AttributeUtils.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/src/main/java/org/lflang/AttributeUtils.java b/core/src/main/java/org/lflang/AttributeUtils.java index 7e7b445d9c..147a4b6d0d 100644 --- a/core/src/main/java/org/lflang/AttributeUtils.java +++ b/core/src/main/java/org/lflang/AttributeUtils.java @@ -110,9 +110,6 @@ public static Attribute findAttributeByName(EObject node, String name) { */ public static List findAttributesByName(EObject node, String name) { List attrs = getAttributes(node); - if (!attrs.isEmpty()) { - System.out.println("Fun"); - } return attrs.stream() .filter( it -> From 9edab375febce6a03a2d11b90c32d889990e42c1 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Fri, 22 Sep 2023 16:14:11 -0700 Subject: [PATCH 13/22] Fix ArrayAsParameter.lf --- test/Python/src/ArrayAsParameter.lf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Python/src/ArrayAsParameter.lf b/test/Python/src/ArrayAsParameter.lf index b794008a7c..58b4cb50e3 100644 --- a/test/Python/src/ArrayAsParameter.lf +++ b/test/Python/src/ArrayAsParameter.lf @@ -1,7 +1,7 @@ # Source has an array as a parameter, the elements of which it passes to Print. target Python -reactor Source(sequence(0, 1, 2)) { +reactor Source(sequence = [0, 1, 2]) { output out state count = 0 logical action next @@ -36,7 +36,7 @@ reactor Print { } main reactor ArrayAsParameter { - s = new Source(sequence(1, 2, 3, 4)) + s = new Source(sequence = [1, 2, 3, 4]) p = new Print() s.out -> p._in } From c71e923906a578b5e069b14e21ee7f9b3d3b45a5 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Sat, 23 Sep 2023 16:39:59 -0700 Subject: [PATCH 14/22] Update action.yml --- .github/actions/prepare-build-env/action.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/actions/prepare-build-env/action.yml b/.github/actions/prepare-build-env/action.yml index 682be37dbb..933bfce680 100644 --- a/.github/actions/prepare-build-env/action.yml +++ b/.github/actions/prepare-build-env/action.yml @@ -11,3 +11,10 @@ runs: uses: gradle/gradle-build-action@v2.8.0 with: cache-read-only: false + - name: Download Gradle Wrapper and print version + run: | + # Retry 3 times before the steps actually fails + (echo "==== Gradle Wrapper Download Attempt: 1 ====" && ./gradlew --version) || \ + (echo "==== Gradle Wrapper Download Attempt: 2 ====" && ./gradlew --version) || \ + (echo "==== Gradle Wrapper Download Attempt: 3 ====" && ./gradlew --version) || \ + (echo "==== Gradle Wrapper Download Failed ====" && exit 1) From 43d6360489d4440672bf2699da72c4a67e747a00 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Sat, 23 Sep 2023 16:46:27 -0700 Subject: [PATCH 15/22] Yaml is not a programming language --- .github/actions/prepare-build-env/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/prepare-build-env/action.yml b/.github/actions/prepare-build-env/action.yml index 933bfce680..b512736020 100644 --- a/.github/actions/prepare-build-env/action.yml +++ b/.github/actions/prepare-build-env/action.yml @@ -11,8 +11,8 @@ runs: uses: gradle/gradle-build-action@v2.8.0 with: cache-read-only: false - - name: Download Gradle Wrapper and print version - run: | + - name: Download Gradle Wrapper and print version + run: | # Retry 3 times before the steps actually fails (echo "==== Gradle Wrapper Download Attempt: 1 ====" && ./gradlew --version) || \ (echo "==== Gradle Wrapper Download Attempt: 2 ====" && ./gradlew --version) || \ From 02e754899c1fda83429f76f230c251ee40cf9cba Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Sat, 23 Sep 2023 16:51:07 -0700 Subject: [PATCH 16/22] Update action.yml --- .github/actions/prepare-build-env/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/prepare-build-env/action.yml b/.github/actions/prepare-build-env/action.yml index b512736020..a626eabd19 100644 --- a/.github/actions/prepare-build-env/action.yml +++ b/.github/actions/prepare-build-env/action.yml @@ -18,3 +18,4 @@ runs: (echo "==== Gradle Wrapper Download Attempt: 2 ====" && ./gradlew --version) || \ (echo "==== Gradle Wrapper Download Attempt: 3 ====" && ./gradlew --version) || \ (echo "==== Gradle Wrapper Download Failed ====" && exit 1) + shell: bash From 3ab626924bc8e286677e75d26b4752825218ecf1 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Sat, 23 Sep 2023 17:24:12 -0700 Subject: [PATCH 17/22] Add input to specify working dir --- .github/actions/prepare-build-env/action.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/actions/prepare-build-env/action.yml b/.github/actions/prepare-build-env/action.yml index a626eabd19..b8104c370b 100644 --- a/.github/actions/prepare-build-env/action.yml +++ b/.github/actions/prepare-build-env/action.yml @@ -1,5 +1,11 @@ name: Set up build environment description: Set up Java and Gradle (including caching). + +inputs: + lingua-franca-dir: + description: 'Path to the lingua-franca directory' + required: false + runs: using: "composite" steps: @@ -12,6 +18,7 @@ runs: with: cache-read-only: false - name: Download Gradle Wrapper and print version + working-directory: ${{ inputs.lingua-franca-dir }} run: | # Retry 3 times before the steps actually fails (echo "==== Gradle Wrapper Download Attempt: 1 ====" && ./gradlew --version) || \ From afb1718bc83008df757ea45d9b93b0b8c0fc5dea Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Sat, 23 Sep 2023 17:28:28 -0700 Subject: [PATCH 18/22] Update action.yml --- .github/actions/prepare-build-env/action.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/actions/prepare-build-env/action.yml b/.github/actions/prepare-build-env/action.yml index b8104c370b..2c9da78679 100644 --- a/.github/actions/prepare-build-env/action.yml +++ b/.github/actions/prepare-build-env/action.yml @@ -17,12 +17,12 @@ runs: uses: gradle/gradle-build-action@v2.8.0 with: cache-read-only: false - - name: Download Gradle Wrapper and print version + - name: Download Gradle and print version working-directory: ${{ inputs.lingua-franca-dir }} run: | # Retry 3 times before the steps actually fails - (echo "==== Gradle Wrapper Download Attempt: 1 ====" && ./gradlew --version) || \ - (echo "==== Gradle Wrapper Download Attempt: 2 ====" && ./gradlew --version) || \ - (echo "==== Gradle Wrapper Download Attempt: 3 ====" && ./gradlew --version) || \ - (echo "==== Gradle Wrapper Download Failed ====" && exit 1) + (echo "==== Gradle Download Attempt: 1 ====" && ./gradlew --version) || \ + (echo "==== Gradle Download Attempt: 2 ====" && ./gradlew --version) || \ + (echo "==== Gradle Download Attempt: 3 ====" && ./gradlew --version) || \ + (echo "==== Gradle Download Failed ====" && exit 1) shell: bash From 50e33f0b96a2c61c1cb180cba8e40c7160bc59bf Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Sat, 23 Sep 2023 23:12:54 -0700 Subject: [PATCH 19/22] Bump Gradle from 8.1.1 to 8.3 --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2c3425d49e..93ac3e13b9 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=e111cb9948407e26351227dabce49822fb88c37ee72f1d1582a69c68af2e702f -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionSha256Sum=591855b517fc635b9e04de1d05d5e76ada3f89f5fc76f87978d1b245b4f69225 +distributionUrl=https://services.gradle.org/distributions/gradle-8.3-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 05bb01869676e1d0b1701e1e66a556d8fd39eea8 Mon Sep 17 00:00:00 2001 From: Christian Menard Date: Mon, 25 Sep 2023 09:47:19 +0200 Subject: [PATCH 20/22] Sleep between attempts --- .github/actions/prepare-build-env/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/prepare-build-env/action.yml b/.github/actions/prepare-build-env/action.yml index 2c9da78679..7584d5cd27 100644 --- a/.github/actions/prepare-build-env/action.yml +++ b/.github/actions/prepare-build-env/action.yml @@ -22,7 +22,7 @@ runs: run: | # Retry 3 times before the steps actually fails (echo "==== Gradle Download Attempt: 1 ====" && ./gradlew --version) || \ - (echo "==== Gradle Download Attempt: 2 ====" && ./gradlew --version) || \ - (echo "==== Gradle Download Attempt: 3 ====" && ./gradlew --version) || \ + (sleep 30 && echo "==== Gradle Download Attempt: 2 ====" && ./gradlew --version) || \ + (sleep 30 && echo "==== Gradle Download Attempt: 3 ====" && ./gradlew --version) || \ (echo "==== Gradle Download Failed ====" && exit 1) shell: bash From da00390c33e77483fa1b3ff4b43d218dfcba9463 Mon Sep 17 00:00:00 2001 From: Christian Menard Date: Mon, 25 Sep 2023 10:04:44 +0200 Subject: [PATCH 21/22] bump gradle plugin versions --- buildSrc/build.gradle | 2 +- buildSrc/gradle.properties | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 7c2d942ef8..3a0866f164 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -18,5 +18,5 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" implementation "com.diffplug.spotless:spotless-plugin-gradle:$spotlessVersion" - implementation "gradle.plugin.com.github.johnrengelman:shadow:$shadowJarVersion" + implementation "com.github.johnrengelman:shadow:$shadowJarVersion" } diff --git a/buildSrc/gradle.properties b/buildSrc/gradle.properties index a8cd2581d4..a6e3b64311 100644 --- a/buildSrc/gradle.properties +++ b/buildSrc/gradle.properties @@ -1,6 +1,6 @@ [versions] -spotlessVersion=6.11.0 +spotlessVersion=6.21.0 spotlessLibVersion=2.30.0 -kotlinVersion=1.6.21 -shadowJarVersion=7.1.2 -spotbugsPluginVersion=5.1.3 \ No newline at end of file +kotlinVersion=1.9.0 +shadowJarVersion=8.1.1 +spotbugsPluginVersion=5.1.3 From 470e8ee553d4a97cf6b44d0e653f41d887cea6ba Mon Sep 17 00:00:00 2001 From: Christian Menard Date: Mon, 25 Sep 2023 14:11:50 +0200 Subject: [PATCH 22/22] Fixed error reporting bug introduced in #2006 --- .../testFixtures/java/org/lflang/tests/LFTest.java | 14 ++++++++++---- .../java/org/lflang/tests/TestBase.java | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/core/src/testFixtures/java/org/lflang/tests/LFTest.java b/core/src/testFixtures/java/org/lflang/tests/LFTest.java index e99fee4b54..1fa4184237 100644 --- a/core/src/testFixtures/java/org/lflang/tests/LFTest.java +++ b/core/src/testFixtures/java/org/lflang/tests/LFTest.java @@ -39,6 +39,12 @@ public class LFTest implements Comparable { /** String builder for collecting issues encountered during test execution. */ private final StringBuilder issues = new StringBuilder(); + /** Reference to System.out for restoring the default output. */ + private static final PrintStream out = System.out; + + /** Reference to System.err for restoring the default output. */ + private static final PrintStream err = System.err; + private long executionTimeNanoseconds; /** @@ -71,11 +77,11 @@ public void redirectOutputs() { } /** End output redirection. */ - public void restoreOutputs() { + public static void restoreOutputs() { System.out.flush(); System.err.flush(); - System.setOut(System.out); - System.setErr(System.err); + System.setOut(out); + System.setErr(err); } /** @@ -130,7 +136,7 @@ public boolean hasPassed() { return result == Result.TEST_PASS; } - /** Compile a string that contains all collected errors and return it. */ + /** Print a report of all the collected errors. */ public void reportErrors() { if (this.hasFailed()) { System.out.println( diff --git a/core/src/testFixtures/java/org/lflang/tests/TestBase.java b/core/src/testFixtures/java/org/lflang/tests/TestBase.java index ee0d72ff02..04a699068c 100644 --- a/core/src/testFixtures/java/org/lflang/tests/TestBase.java +++ b/core/src/testFixtures/java/org/lflang/tests/TestBase.java @@ -328,7 +328,7 @@ private static void checkAndReportFailures(Set tests) { var passed = tests.stream().filter(LFTest::hasPassed).toList(); var s = new StringBuffer(); s.append(THIN_LINE); - s.append("Passing: ").append(passed.size()).append("/").append(tests.size()).append("%n"); + s.append(String.format("Passing: %d/%d%n", passed.size(), tests.size())); s.append(THIN_LINE); passed.forEach( test ->