diff --git a/org.lflang/src/org/lflang/generator/GeneratorBase.java b/org.lflang/src/org/lflang/generator/GeneratorBase.java index 34f6e41e48..b71ae991a9 100644 --- a/org.lflang/src/org/lflang/generator/GeneratorBase.java +++ b/org.lflang/src/org/lflang/generator/GeneratorBase.java @@ -354,10 +354,15 @@ public void doGenerate(Resource resource, LFGeneratorContext context) { .map(it -> GeneratorUtils.getLFResource(it, fileConfig.getSrcGenBasePath(), context, errorReporter)) .collect(Collectors.toList()) ); - GeneratorUtils.accommodatePhysicalActionsIfPresent(allResources, getTarget(), targetConfig, errorReporter); + GeneratorUtils.accommodatePhysicalActionsIfPresent( + allResources, + getTarget().setsKeepAliveOptionAutomatically(), + targetConfig, + errorReporter + ); // FIXME: Should the GeneratorBase pull in `files` from imported // resources? - + // Reroute connections that have delays associated with them via // generated delay reactors. transformDelays(); diff --git a/org.lflang/src/org/lflang/generator/GeneratorUtils.java b/org.lflang/src/org/lflang/generator/GeneratorUtils.java index 70caa9708b..f5cf198fb6 100644 --- a/org.lflang/src/org/lflang/generator/GeneratorUtils.java +++ b/org.lflang/src/org/lflang/generator/GeneratorUtils.java @@ -30,6 +30,7 @@ import org.lflang.lf.Action; import org.lflang.lf.ActionOrigin; import org.lflang.lf.Import; +import org.lflang.lf.Instantiation; import org.lflang.lf.KeyValuePair; import org.lflang.lf.KeyValuePairs; import org.lflang.lf.Model; @@ -55,17 +56,7 @@ private GeneratorUtils() { * Return the target declaration found in the given resource. */ public static TargetDecl findTarget(Resource resource) { - TargetDecl targetDecl = null; - for (TargetDecl t : findAll(resource, TargetDecl.class)) { // getAllContents should never return null. - if (targetDecl != null) { - throw new InvalidSourceException("There is more than one target!"); // FIXME: check this in validator - } - targetDecl = t; - } - if (targetDecl == null) { - throw new InvalidSourceException("No target found!"); - } - return targetDecl; + return findAll(resource, TargetDecl.class).iterator().next(); } /** @@ -130,30 +121,31 @@ public static void setTargetConfig( */ public static void accommodatePhysicalActionsIfPresent( List resources, - Target target, + boolean setsKeepAliveOptionAutomatically, TargetConfig targetConfig, ErrorReporter errorReporter ) { - if (!target.setsKeepAliveOptionAutomatically()) { + if (!setsKeepAliveOptionAutomatically) { return; } for (Resource resource : resources) { for (Action action : findAll(resource, Action.class)) { - if (action.getOrigin() == ActionOrigin.PHYSICAL) { + if (action.getOrigin() == ActionOrigin.PHYSICAL && // Check if the user has explicitly set keepalive to false - if (!targetConfig.setByUser.contains(TargetProperty.KEEPALIVE) && !targetConfig.keepalive) { - // If not, set it to true - targetConfig.keepalive = true; - errorReporter.reportWarning( - action, - String.format( - "Setting %s to true because of the physical action %s.", - TargetProperty.KEEPALIVE.getDisplayName(), - action.getName() - ) - ); - return; - } + !targetConfig.setByUser.contains(TargetProperty.KEEPALIVE) && + !targetConfig.keepalive + ) { + // If not, set it to true + targetConfig.keepalive = true; + errorReporter.reportWarning( + action, + String.format( + "Setting %s to true because of the physical action %s.", + TargetProperty.KEEPALIVE.getDisplayName(), + action.getName() + ) + ); + return; } } } @@ -306,14 +298,13 @@ public static LFResource getLFResource( List pairs = config.getPairs(); TargetProperty.set(targetConfig, pairs != null ? pairs : List.of(), errorReporter); } - FileConfig fc; try { - fc = new FileConfig(resource, srcGenBasePath, context.useHierarchicalBin()); + FileConfig fc = new FileConfig(resource, srcGenBasePath, context.useHierarchicalBin()); + return new LFResource(resource, fc, targetConfig); } catch (IOException e) { throw new RuntimeException("Failed to instantiate an imported resource because an I/O error " + "occurred."); } - return new LFResource(resource, fc, targetConfig); } /** @@ -341,4 +332,29 @@ public static void refreshProject(Resource resource, Mode compilerMode) { public static boolean isHostWindows() { return System.getProperty("os.name").toLowerCase().contains("win"); } + + /** + * Check whether code can be generated; report any problems + * and inform the context accordingly. + * @return Whether it is possible to generate code. + */ + public static boolean canGenerate( + Boolean errorsOccurred, + Instantiation mainDef, + ErrorReporter errorReporter, + LFGeneratorContext context + ) { + // stop if there are any errors found in the program by doGenerate() in GeneratorBase + if (errorsOccurred) { + context.finish(GeneratorResult.FAILED); + return false; + } + // abort if there is no main reactor + if (mainDef == null) { + errorReporter.reportWarning("WARNING: The given Lingua Franca program does not define a main reactor. Therefore, no code was generated."); + context.finish(GeneratorResult.NOTHING); + return false; + } + return true; + } } diff --git a/org.lflang/src/org/lflang/generator/GeneratorUtils.kt b/org.lflang/src/org/lflang/generator/GeneratorUtils.kt index 1a1cfb9f68..e124080f82 100644 --- a/org.lflang/src/org/lflang/generator/GeneratorUtils.kt +++ b/org.lflang/src/org/lflang/generator/GeneratorUtils.kt @@ -8,7 +8,6 @@ import org.lflang.toUnixString import org.lflang.toTextTokenBased import org.lflang.lf.Instantiation - /** A transparent type alias to document when a string contains target code. */ typealias TargetCode = String @@ -43,28 +42,3 @@ fun EObject.locationInfo(): LocationInfo { lfText = toTextTokenBased() ?: "" ) } - -/** - * Check whether code can be generated; report any problems - * and inform the context accordingly. - * @return Whether it is possible to generate code. - */ -fun canGenerate( - errorsOccurred: Boolean, - mainDef: Instantiation?, - errorReporter: ErrorReporter, - context: LFGeneratorContext -): Boolean { - // stop if there are any errors found in the program by doGenerate() in GeneratorBase - if (errorsOccurred) { - context.finish(GeneratorResult.FAILED) - return false - } - // abort if there is no main reactor - if (mainDef == null) { - errorReporter.reportWarning("WARNING: The given Lingua Franca program does not define a main reactor. Therefore, no code was generated.") - context.finish(GeneratorResult.NOTHING) - return false - } - return true -} diff --git a/org.lflang/src/org/lflang/generator/c/CGenerator.xtend b/org.lflang/src/org/lflang/generator/c/CGenerator.xtend index c67557701d..c7eecbd350 100644 --- a/org.lflang/src/org/lflang/generator/c/CGenerator.xtend +++ b/org.lflang/src/org/lflang/generator/c/CGenerator.xtend @@ -334,12 +334,6 @@ class CGenerator extends GeneratorBase { //////////////////////////////////////////// //// Public methods - - override printInfo(LFGeneratorContext.Mode mode) { - super.printInfo(mode) - println('******** generated binaries: ' + fileConfig.binPath) - } - /** * Set C-specific default target configurations if needed. */ @@ -385,6 +379,7 @@ class CGenerator extends GeneratorBase { '''Using the threaded C runtime to allow for asynchronous handling of« » physical action «action.name».''' ); + return; } } } @@ -435,9 +430,10 @@ class CGenerator extends GeneratorBase { * whether it is a standalone context */ override void doGenerate(Resource resource, LFGeneratorContext context) { - - // The following generates code needed by all the reactors. super.doGenerate(resource, context) + + if (!GeneratorUtils.canGenerate(errorsOccurred, mainDef, errorReporter, context)) return; + accommodatePhysicalActionsIfPresent() setCSpecificDefaults(context) generatePreamble() @@ -936,6 +932,7 @@ class CGenerator extends GeneratorBase { GeneratorResult.Status.COMPILED, fileConfig.name, fileConfig, null ); } + println("Compiled binary is in " + fileConfig.binPath); } else { context.finish(GeneratorResult.GENERATED_NO_EXECUTABLE.apply(null)); } diff --git a/org.lflang/src/org/lflang/generator/cpp/CppGenerator.kt b/org.lflang/src/org/lflang/generator/cpp/CppGenerator.kt index b446c5d6c9..093d2c9ef1 100644 --- a/org.lflang/src/org/lflang/generator/cpp/CppGenerator.kt +++ b/org.lflang/src/org/lflang/generator/cpp/CppGenerator.kt @@ -39,7 +39,7 @@ import org.lflang.generator.GeneratorResult import org.lflang.generator.IntegratedBuilder import org.lflang.generator.LFGeneratorContext import org.lflang.generator.TargetTypes -import org.lflang.generator.canGenerate +import org.lflang.generator.GeneratorUtils.canGenerate import org.lflang.isGeneric import org.lflang.lf.Action import org.lflang.lf.VarRef diff --git a/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt b/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt index 283e5fa1a4..008bbc217b 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt @@ -28,7 +28,7 @@ import org.eclipse.emf.ecore.resource.Resource import org.lflang.ErrorReporter import org.lflang.Target import org.lflang.TargetProperty.BuildType -import org.lflang.generator.canGenerate +import org.lflang.generator.GeneratorUtils.canGenerate import org.lflang.generator.CodeMap import org.lflang.generator.GeneratorBase import org.lflang.generator.GeneratorResult diff --git a/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt b/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt index df510f29cd..7a2aa05d20 100644 --- a/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt +++ b/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt @@ -45,7 +45,7 @@ import org.lflang.generator.PrependOperator import org.lflang.generator.SubContext import org.lflang.generator.TargetTypes import org.lflang.generator.ValueGenerator -import org.lflang.generator.canGenerate +import org.lflang.generator.GeneratorUtils.canGenerate import org.lflang.inferredType import org.lflang.lf.Action import org.lflang.lf.Delay