From 029f825201694b30a16156a0d352dd1cba20d6c0 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 16 May 2023 19:43:46 -0700 Subject: [PATCH 01/11] "fix" naming collision in fed-gen files. This is not really a fix because we still have the problem that we consider reactor classes to have distinct names using a **case-sensitive** comparison, but we want to generate files corresponding to the reactor classes that will be compared **case-insensitively** on macOS. However, it does make our generated code "less wrong." --- org.lflang/src/org/lflang/federated/generator/FedEmitter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/federated/generator/FedEmitter.java b/org.lflang/src/org/lflang/federated/generator/FedEmitter.java index 9ae5c9d2cc..9cbffdbae2 100644 --- a/org.lflang/src/org/lflang/federated/generator/FedEmitter.java +++ b/org.lflang/src/org/lflang/federated/generator/FedEmitter.java @@ -52,7 +52,7 @@ Map generateFederate( + fileConfig.getSrcPath()); Path lfFilePath = fileConfig.getSrcPath().resolve( - fedName + ".lf"); + "__" + fedName + ".lf"); String federateCode = String.join( "\n", From c11dd2e9d5759cf9f780c1c4549aef0dfd09be4e Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 16 May 2023 20:05:43 -0700 Subject: [PATCH 02/11] Check for case-insensitive name collisions. --- org.lflang/src/org/lflang/ModelInfo.java | 38 +++++++++++++++++------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/org.lflang/src/org/lflang/ModelInfo.java b/org.lflang/src/org/lflang/ModelInfo.java index 45e9995045..c447d381ac 100644 --- a/org.lflang/src/org/lflang/ModelInfo.java +++ b/org.lflang/src/org/lflang/ModelInfo.java @@ -11,15 +11,15 @@ this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************/ @@ -28,6 +28,7 @@ import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toIterable; +import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; @@ -81,7 +82,7 @@ public class ModelInfo { * interval. */ public Set overflowingDeadlines; - + /** * The set of STP offsets that use a too-large constant to specify their time * interval. @@ -137,6 +138,23 @@ public void update(Model model, ErrorReporter reporter) { if (target == Target.C) { this.collectOverflowingNodes(); } + + checkCaseInsensitiveNameCollisions(model, reporter); + } + + public void checkCaseInsensitiveNameCollisions(Model model, ErrorReporter reporter) { + var reactorNames = new HashSet<>(); + var bad = new ArrayList<>(); + for (var reactor : model.getReactors()) { + var lowerName = reactor.getName().toLowerCase(); + if (reactorNames.contains(lowerName)) bad.add(lowerName); + reactorNames.add(lowerName); + } + for (var badName : bad) { + model.getReactors().stream().filter(it -> it.getName() + .toLowerCase().equals(badName)) + .forEach(it -> reporter.reportError(it, "Multiple reactors have the same name up to case differences.")); + } } public Set> topologyCycles() { @@ -223,7 +241,7 @@ private boolean detectOverflow(Set visited, Parameter current) { // Check for overflow in the referenced parameter. overflow = detectOverflow(visited, ((ParameterReference)expr).getParameter()) || overflow; } else { - // The right-hand side of the assignment is a + // The right-hand side of the assignment is a // constant; check whether it is too large. if (isTooLarge(ASTUtils.getLiteralTimeValue(expr))) { this.overflowingAssignments.add(assignment); From 4f85c270b64e0fa4634add3f92860def23100f54 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 16 May 2023 20:23:02 -0700 Subject: [PATCH 03/11] Refactor a bit. The file name of the fed-gen file should be specified in one place (DRY). --- .../src/org/lflang/federated/generator/FedEmitter.java | 9 ++++++--- .../src/org/lflang/federated/generator/FedGenerator.java | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/org.lflang/src/org/lflang/federated/generator/FedEmitter.java b/org.lflang/src/org/lflang/federated/generator/FedEmitter.java index 9cbffdbae2..ee44002306 100644 --- a/org.lflang/src/org/lflang/federated/generator/FedEmitter.java +++ b/org.lflang/src/org/lflang/federated/generator/FedEmitter.java @@ -51,9 +51,6 @@ Map generateFederate( + " in directory " + fileConfig.getSrcPath()); - Path lfFilePath = fileConfig.getSrcPath().resolve( - "__" + fedName + ".lf"); - String federateCode = String.join( "\n", new FedTargetEmitter().generateTarget(context, numOfFederates, federate, fileConfig, errorReporter, rtiConfig), @@ -67,6 +64,7 @@ Map generateFederate( ) ); Map codeMapMap = new HashMap<>(); + var lfFilePath = lfFilePath(fileConfig, federate); try (var srcWriter = Files.newBufferedWriter(lfFilePath)) { var codeMap = CodeMap.fromGeneratedCode(federateCode); codeMapMap.put(lfFilePath, codeMap); @@ -74,4 +72,9 @@ Map generateFederate( } return codeMapMap; } + + public static Path lfFilePath(FedFileConfig fileConfig, FederateInstance federate) { + return fileConfig.getSrcPath().resolve( + "__" + federate.name + ".lf"); + } } diff --git a/org.lflang/src/org/lflang/federated/generator/FedGenerator.java b/org.lflang/src/org/lflang/federated/generator/FedGenerator.java index cd9c2e95d0..dddae562f7 100644 --- a/org.lflang/src/org/lflang/federated/generator/FedGenerator.java +++ b/org.lflang/src/org/lflang/federated/generator/FedGenerator.java @@ -286,7 +286,7 @@ private Map compileFederates( final int id = i; compileThreadPool.execute(() -> { Resource res = rs.getResource(URI.createFileURI( - fileConfig.getSrcPath().resolve(fed.name + ".lf").toAbsolutePath().toString() + FedEmitter.lfFilePath(fileConfig, fed).toAbsolutePath().toString() ), true); FileConfig subFileConfig = LFGenerator.createFileConfig(res, fileConfig.getSrcGenPath(), true); ErrorReporter subContextErrorReporter = new LineAdjustingErrorReporter(threadSafeErrorReporter, lf2lfCodeMapMap); From 0cbbacd36c424b21bca42b5711396fb9367d26a5 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 16 May 2023 21:13:03 -0700 Subject: [PATCH 04/11] Fix NPE in getting name of reactor. --- org.lflang/src/org/lflang/ModelInfo.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/org.lflang/src/org/lflang/ModelInfo.java b/org.lflang/src/org/lflang/ModelInfo.java index c447d381ac..22caf4a0dc 100644 --- a/org.lflang/src/org/lflang/ModelInfo.java +++ b/org.lflang/src/org/lflang/ModelInfo.java @@ -28,6 +28,7 @@ import static org.eclipse.xtext.xbase.lib.IterableExtensions.filter; import static org.eclipse.xtext.xbase.lib.IteratorExtensions.toIterable; +import java.nio.file.Path; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashSet; @@ -47,6 +48,7 @@ import org.lflang.lf.ParameterReference; import org.lflang.lf.Reactor; import org.lflang.lf.STP; +import org.lflang.util.FileUtil; /** @@ -146,17 +148,21 @@ public void checkCaseInsensitiveNameCollisions(Model model, ErrorReporter report var reactorNames = new HashSet<>(); var bad = new ArrayList<>(); for (var reactor : model.getReactors()) { - var lowerName = reactor.getName().toLowerCase(); + var lowerName = getName(reactor).toLowerCase(); if (reactorNames.contains(lowerName)) bad.add(lowerName); reactorNames.add(lowerName); } for (var badName : bad) { - model.getReactors().stream().filter(it -> it.getName() - .toLowerCase().equals(badName)) + model.getReactors().stream() + .filter(it -> getName(it).toLowerCase().equals(badName)) .forEach(it -> reporter.reportError(it, "Multiple reactors have the same name up to case differences.")); } } + private String getName(Reactor r) { + return r.getName() == null ? r.getName() : FileUtil.nameWithoutExtension(Path.of(model.eResource().getURI().toFileString())); + } + public Set> topologyCycles() { return this.topologyCycles; } From e1652694045e73f49c4d70d24003fb97846e4e7d Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 16 May 2023 21:25:27 -0700 Subject: [PATCH 05/11] Update unit test. --- .../src/org/lflang/tests/compiler/TargetConfigTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang.tests/src/org/lflang/tests/compiler/TargetConfigTests.java b/org.lflang.tests/src/org/lflang/tests/compiler/TargetConfigTests.java index 593e302d25..12b86996cb 100644 --- a/org.lflang.tests/src/org/lflang/tests/compiler/TargetConfigTests.java +++ b/org.lflang.tests/src/org/lflang/tests/compiler/TargetConfigTests.java @@ -94,7 +94,7 @@ public void testFederation() throws Exception { generator.doGenerate(resource, fileAccess, context); String lfSrc = Files.readAllLines( - ((FedFileConfig)context.getFileConfig()).getSrcPath().resolve("a.lf") + ((FedFileConfig)context.getFileConfig()).getSrcPath().resolve("__a.lf") ).stream().reduce("\n", String::concat); Model federate = parser.parse(lfSrc); assertHasTargetProperty(federate, "tracing"); From 47eb5c8ab58bce0e971f86c8c77d8d4541239a04 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 16 May 2023 21:28:15 -0700 Subject: [PATCH 06/11] Fix logical error. --- org.lflang/src/org/lflang/ModelInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/ModelInfo.java b/org.lflang/src/org/lflang/ModelInfo.java index 22caf4a0dc..fbe5c2047c 100644 --- a/org.lflang/src/org/lflang/ModelInfo.java +++ b/org.lflang/src/org/lflang/ModelInfo.java @@ -160,7 +160,7 @@ public void checkCaseInsensitiveNameCollisions(Model model, ErrorReporter report } private String getName(Reactor r) { - return r.getName() == null ? r.getName() : FileUtil.nameWithoutExtension(Path.of(model.eResource().getURI().toFileString())); + return r.getName() != null ? r.getName() : FileUtil.nameWithoutExtension(Path.of(model.eResource().getURI().toFileString())); } public Set> topologyCycles() { From 05827f1119a9e2b9ab9f6eb42ea80e9b0f5a1473 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 16 May 2023 23:28:14 -0700 Subject: [PATCH 07/11] Attempt to pass failing TS docker tests. --- org.lflang/src/org/lflang/generator/DockerGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/DockerGenerator.java b/org.lflang/src/org/lflang/generator/DockerGenerator.java index 902d664631..851ee6c0be 100644 --- a/org.lflang/src/org/lflang/generator/DockerGenerator.java +++ b/org.lflang/src/org/lflang/generator/DockerGenerator.java @@ -43,7 +43,7 @@ public DockerData generateDockerData() { var dockerFilePath = context.getFileConfig().getSrcGenPath().resolve("Dockerfile"); var dockerFileContent = generateDockerFileContent(); - return new DockerData(name, dockerFilePath, dockerFileContent); + return new DockerData(name.replace("_", ""), dockerFilePath, dockerFileContent); } public static DockerGenerator dockerGeneratorFactory(LFGeneratorContext context) { From 3c52f30f82c2863a47eb980ea799b7fd0c7abef2 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 17 May 2023 11:02:16 -0700 Subject: [PATCH 08/11] Bugfix. The problem here is that we use the uniqueID of the federate both before and after we transform it into separate programs. After we transform it, the name of the instance depends on the name of the main reactor, which might be different (indeed, it must be different in order for us to eliminate the possibility of name collisions with other parts of the program). So this is a bit of a hack, but I'm not sure what else to do. --- org.lflang/src/org/lflang/generator/ReactorInstance.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/org.lflang/src/org/lflang/generator/ReactorInstance.java b/org.lflang/src/org/lflang/generator/ReactorInstance.java index eb5163ade6..92d7d9ea3d 100644 --- a/org.lflang/src/org/lflang/generator/ReactorInstance.java +++ b/org.lflang/src/org/lflang/generator/ReactorInstance.java @@ -323,7 +323,8 @@ public String getName() { @Override public String uniqueID() { if (this.isMainOrFederated()) { - return super.uniqueID() + "_main"; + if (reactorDefinition.isFederated()) return "__" + super.uniqueID() + "_main"; + return super.uniqueID() + "_main"; } return super.uniqueID(); } From 2551a52142474be7a1c04183f4485b3e43595482 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 17 May 2023 15:08:11 -0700 Subject: [PATCH 09/11] Address federated test failures. It is bad that in order to make this change it is necessary to edit code in several places. But it isn't clear how to fix this because different parts of the code operate on the program at different stages in the compilation process, either before or after it has been split into many programs. --- .../federated/generator/FederateInstance.java | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/org.lflang/src/org/lflang/federated/generator/FederateInstance.java b/org.lflang/src/org/lflang/federated/generator/FederateInstance.java index 7ca5a19bca..6dd7dc1de2 100644 --- a/org.lflang/src/org/lflang/federated/generator/FederateInstance.java +++ b/org.lflang/src/org/lflang/federated/generator/FederateInstance.java @@ -97,8 +97,8 @@ public class FederateInstance { // why does this not extend ReactorInstance? * @param errorReporter The error reporter */ public FederateInstance( - Instantiation instantiation, - int id, + Instantiation instantiation, + int id, int bankIndex, TargetConfig targetConfig, ErrorReporter errorReporter) { @@ -107,9 +107,9 @@ public FederateInstance( this.bankIndex = bankIndex; this.errorReporter = errorReporter; this.targetConfig = targetConfig; - + if (instantiation != null) { - this.name = instantiation.getName(); + this.name = "__" + instantiation.getName(); // If the instantiation is in a bank, then we have to append // the bank index to the name. if (instantiation.getWidthSpec() != null) { @@ -120,18 +120,18 @@ public FederateInstance( ///////////////////////////////////////////// //// Public Fields - + /** * The position within a bank of reactors for this federate. * This is 0 if the instantiation is not a bank of reactors. */ public int bankIndex = 0; - + /** * A list of outputs that can be triggered directly or indirectly by physical actions. */ public Set outputsConnectedToPhysicalActions = new LinkedHashSet<>(); - + /** * The host, if specified using the 'at' keyword. */ @@ -150,7 +150,7 @@ public Instantiation getInstantiation() { * A list of individual connections between federates */ public Set connections = new HashSet<>(); - + /** * Map from the federates that this federate receives messages from * to the delays on connections from that federate. The delay set @@ -158,17 +158,17 @@ public Instantiation getInstantiation() { * from the federate instance that has no delay. */ public Map> dependsOn = new LinkedHashMap<>(); - + /** * The directory, if specified using the 'at' keyword. */ public String dir = null; - + /** * The port, if specified using the 'at' keyword. */ public int port = 0; - + /** * Map from the federates that this federate sends messages to * to the delays on connections to that federate. The delay set @@ -176,12 +176,12 @@ public Instantiation getInstantiation() { * from the federate instance that has no delay. */ public Map> sendsTo = new LinkedHashMap<>(); - + /** * The user, if specified using the 'at' keyword. */ public String user = null; - + /** * The integer ID of this federate. */ @@ -194,7 +194,7 @@ public Instantiation getInstantiation() { * this instance if the instantiation is of a bank of reactors. */ public String name = "Unnamed"; - + /** * List of networkMessage actions. Each of these handles a message * received from another federate over the network. The ID of @@ -202,7 +202,7 @@ public Instantiation getInstantiation() { * The sending federate needs to specify this ID. */ public List networkMessageActions = new ArrayList<>(); - + /** * A set of federates with which this federate has an inbound connection * There will only be one physical connection even if federate A has defined multiple @@ -211,7 +211,7 @@ public Instantiation getInstantiation() { * to help the receiver distinguish different events. */ public Set inboundP2PConnections = new LinkedHashSet<>(); - + /** * A list of federate with which this federate has an outbound physical connection. * There will only be one physical connection even if federate A has defined multiple @@ -220,29 +220,29 @@ public Instantiation getInstantiation() { * scheduling the appropriate action. */ public Set outboundP2PConnections = new LinkedHashSet<>(); - + /** * A list of triggers for network input control reactions. This is used to trigger * all the input network control reactions that might be nested in a hierarchy. */ public List networkInputControlReactionsTriggers = new ArrayList<>(); - + /** * The trigger that triggers the output control reaction of this * federate. - * + * * The network output control reactions send a PORT_ABSENT message for a network output port, * if it is absent at the current tag, to notify all downstream federates that no value will * be present on the given network port, allowing input control reactions on those federates * to stop blocking. */ public Variable networkOutputControlReactionsTrigger = null; - + /** * Indicates whether the federate is remote or local */ public boolean isRemote = false; - + /** * List of generated network reactions (network receivers, * network input control reactions, network senders, and network output control @@ -389,16 +389,16 @@ private boolean contains(Action action) { } } } - - return false; + + return false; } - /** + /** * Return true if the specified reaction should be included in the code generated for this * federate at the top-level. This means that if the reaction is triggered by or * sends data to a port of a contained reactor, then that reaction * is in the federate. Otherwise, return false. - * + * * NOTE: This method assumes that it will not be called with reaction arguments * that are within other federates. It should only be called on reactions that are * either at the top level or within this federate. For this reason, for any reaction @@ -411,7 +411,7 @@ private boolean contains(Reaction reaction) { assert reactor != null; if (!reactor.getReactions().contains(reaction)) return false; - + if (networkReactions.contains(reaction)) { // Reaction is a network reaction that belongs to this federate return true; @@ -421,15 +421,15 @@ private boolean contains(Reaction reaction) { if (reactionBankIndex >= 0 && this.bankIndex >= 0 && reactionBankIndex != this.bankIndex) { return false; } - + // If this has been called before, then the result of the // following check is cached. if (excludeReactions != null) { return !excludeReactions.contains(reaction); } - + indexExcludedTopLevelReactions(reactor); - + return !excludeReactions.contains(reaction); } @@ -462,17 +462,17 @@ private boolean contains(Timer timer) { return false; } - /** + /** * Return true if the specified reactor instance or any parent * reactor instance is contained by this federate. * If the specified instance is the top-level reactor, return true * (the top-level reactor belongs to all federates). * If this federate instance is a singleton, then return true if the * instance is non null. - * + * * NOTE: If the instance is bank within the top level, then this * returns true even though only one of the bank members is in the federate. - * + * * @param instance The reactor instance. * @return True if this federate contains the reactor instance */ @@ -496,7 +496,7 @@ public boolean contains(ReactorInstance instance) { * federatedReactor) that don't belong to this federate * instance. This index is put in the excludeReactions * class variable. - * + * * @param federatedReactor The top-level federated reactor */ private void indexExcludedTopLevelReactions(Reactor federatedReactor) { @@ -537,7 +537,7 @@ private void indexExcludedTopLevelReactions(Reactor federatedReactor) { } } } - + /** * Return true if all members of 'varRefs' belong to this federate. * @@ -564,7 +564,7 @@ private boolean containsAllVarRefs(Iterable varRefs) { } return inFederate; } - + /** * Find output ports that are connected to a physical action trigger upstream * in the same reactor. Return a list of such outputs paired with the minimum delay @@ -596,7 +596,7 @@ public List getZeroDelayImmediateUpstreamFederates() { .filter(e -> e.getValue().contains(null)) .map(Map.Entry::getKey).toList(); } - + @Override public String toString() { return "Federate " + id + ": " @@ -605,21 +605,21 @@ public String toString() { ///////////////////////////////////////////// //// Private Fields - + /** * Cached result of analysis of which reactions to exclude from main. */ private Set excludeReactions = null; - + /** * An error reporter */ private final ErrorReporter errorReporter; - + /** * Find the nearest (shortest) path to a physical action trigger from this * 'reaction' in terms of minimum delay. - * + * * @param reaction The reaction to start with * @return The minimum delay found to the nearest physical action and * TimeValue.MAX_VALUE otherwise @@ -646,7 +646,7 @@ public TimeValue findNearestPhysicalActionTrigger(ReactionInstance reaction) { } } } - + } else if (trigger.getDefinition() instanceof Output) { // Outputs of contained reactions PortInstance outputInstance = (PortInstance) trigger; @@ -660,7 +660,7 @@ public TimeValue findNearestPhysicalActionTrigger(ReactionInstance reaction) { } return minDelay; } - + // TODO: Put this function into a utils file instead private List convertToEmptyListIfNull(List list) { return list == null ? new ArrayList<>() : list; From 13e9b291c9336779482f9fcf9fa50d59d690f199 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 17 May 2023 16:40:14 -0700 Subject: [PATCH 10/11] Do not doubly mark as federated. This is hacky. The problem is that the generated code does not have a federated reactor, but we do an AST transformation so that we can pretend that it is (I do not want to know why). So we end up running the code generator on a federated program, even though it is supposed to result on code for a single federate. So if the federate had its name prefixed once in the main run of the code generator, its name will be prefixed again in the nested run of the code generator. --- .../src/org/lflang/federated/generator/FedEmitter.java | 3 +-- .../org/lflang/federated/generator/FederateInstance.java | 7 +------ org.lflang/src/org/lflang/generator/ReactorInstance.java | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/org.lflang/src/org/lflang/federated/generator/FedEmitter.java b/org.lflang/src/org/lflang/federated/generator/FedEmitter.java index ee44002306..2c9f32aad8 100644 --- a/org.lflang/src/org/lflang/federated/generator/FedEmitter.java +++ b/org.lflang/src/org/lflang/federated/generator/FedEmitter.java @@ -74,7 +74,6 @@ Map generateFederate( } public static Path lfFilePath(FedFileConfig fileConfig, FederateInstance federate) { - return fileConfig.getSrcPath().resolve( - "__" + federate.name + ".lf"); + return fileConfig.getSrcPath().resolve(federate.name + ".lf"); } } diff --git a/org.lflang/src/org/lflang/federated/generator/FederateInstance.java b/org.lflang/src/org/lflang/federated/generator/FederateInstance.java index 6dd7dc1de2..835ecca4dd 100644 --- a/org.lflang/src/org/lflang/federated/generator/FederateInstance.java +++ b/org.lflang/src/org/lflang/federated/generator/FederateInstance.java @@ -25,7 +25,6 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY package org.lflang.federated.generator; -import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedHashMap; @@ -40,17 +39,13 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import org.lflang.ASTUtils; import org.lflang.ErrorReporter; -import org.lflang.FileConfig; -import org.lflang.Target; import org.lflang.TargetConfig; import org.lflang.TimeValue; import org.lflang.federated.serialization.SupportedSerializers; import org.lflang.generator.ActionInstance; -import org.lflang.generator.GeneratorUtils; import org.lflang.generator.PortInstance; import org.lflang.generator.ReactionInstance; import org.lflang.generator.ReactorInstance; -import org.lflang.generator.SubContext; import org.lflang.generator.TriggerInstance; import org.lflang.lf.Action; import org.lflang.lf.ActionOrigin; @@ -109,12 +104,12 @@ public FederateInstance( this.targetConfig = targetConfig; if (instantiation != null) { - this.name = "__" + instantiation.getName(); // If the instantiation is in a bank, then we have to append // the bank index to the name. if (instantiation.getWidthSpec() != null) { this.name = instantiation.getName() + "__" + bankIndex; } + name = "federate__" + name; } } diff --git a/org.lflang/src/org/lflang/generator/ReactorInstance.java b/org.lflang/src/org/lflang/generator/ReactorInstance.java index 92d7d9ea3d..20f9718aea 100644 --- a/org.lflang/src/org/lflang/generator/ReactorInstance.java +++ b/org.lflang/src/org/lflang/generator/ReactorInstance.java @@ -323,7 +323,7 @@ public String getName() { @Override public String uniqueID() { if (this.isMainOrFederated()) { - if (reactorDefinition.isFederated()) return "__" + super.uniqueID() + "_main"; + if (reactorDefinition.isFederated() && !super.uniqueID().startsWith("federate__")) return "federate__" + super.uniqueID() + "_main"; return super.uniqueID() + "_main"; } return super.uniqueID(); From d4968e8800258ea19b0377b4e80683a91369f02e Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Wed, 17 May 2023 16:53:35 -0700 Subject: [PATCH 11/11] More bugfixes. --- .../src/org/lflang/tests/compiler/TargetConfigTests.java | 2 +- .../src/org/lflang/federated/generator/FederateInstance.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/org.lflang.tests/src/org/lflang/tests/compiler/TargetConfigTests.java b/org.lflang.tests/src/org/lflang/tests/compiler/TargetConfigTests.java index 12b86996cb..eede6a6831 100644 --- a/org.lflang.tests/src/org/lflang/tests/compiler/TargetConfigTests.java +++ b/org.lflang.tests/src/org/lflang/tests/compiler/TargetConfigTests.java @@ -94,7 +94,7 @@ public void testFederation() throws Exception { generator.doGenerate(resource, fileAccess, context); String lfSrc = Files.readAllLines( - ((FedFileConfig)context.getFileConfig()).getSrcPath().resolve("__a.lf") + ((FedFileConfig)context.getFileConfig()).getSrcPath().resolve("federate__a.lf") ).stream().reduce("\n", String::concat); Model federate = parser.parse(lfSrc); assertHasTargetProperty(federate, "tracing"); diff --git a/org.lflang/src/org/lflang/federated/generator/FederateInstance.java b/org.lflang/src/org/lflang/federated/generator/FederateInstance.java index 835ecca4dd..cdd64f03b2 100644 --- a/org.lflang/src/org/lflang/federated/generator/FederateInstance.java +++ b/org.lflang/src/org/lflang/federated/generator/FederateInstance.java @@ -107,9 +107,10 @@ public FederateInstance( // If the instantiation is in a bank, then we have to append // the bank index to the name. if (instantiation.getWidthSpec() != null) { - this.name = instantiation.getName() + "__" + bankIndex; + this.name = "federate__" + instantiation.getName() + "__" + bankIndex; + } else { + this.name = "federate__" + instantiation.getName(); } - name = "federate__" + name; } }