Skip to content

Commit

Permalink
Merge pull request #1000 from lf-lang/c-do-not-generate-without-main
Browse files Browse the repository at this point in the history
[C] do not generate code without main reactor
  • Loading branch information
lhstrh authored Mar 9, 2022
2 parents fcc7733 + aebac86 commit 9e5e5a1
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 69 deletions.
9 changes: 7 additions & 2 deletions org.lflang/src/org/lflang/generator/GeneratorBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -356,10 +356,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();
Expand Down
76 changes: 46 additions & 30 deletions org.lflang/src/org/lflang/generator/GeneratorUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
}

/**
Expand Down Expand Up @@ -130,30 +121,31 @@ public static void setTargetConfig(
*/
public static void accommodatePhysicalActionsIfPresent(
List<Resource> 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;
}
}
}
Expand Down Expand Up @@ -306,14 +298,13 @@ public static LFResource getLFResource(
List<KeyValuePair> 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);
}

/**
Expand Down Expand Up @@ -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;
}
}
26 changes: 0 additions & 26 deletions org.lflang/src/org/lflang/generator/GeneratorUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
}
13 changes: 5 additions & 8 deletions org.lflang/src/org/lflang/generator/c/CGenerator.xtend
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -385,6 +379,7 @@ class CGenerator extends GeneratorBase {
'''Using the threaded C runtime to allow for asynchronous handling of«
» physical action «action.name».'''
);
return;
}
}
}
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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));
}
Expand Down
2 changes: 1 addition & 1 deletion org.lflang/src/org/lflang/generator/cpp/CppGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import org.lflang.generator.IntegratedBuilder
import org.lflang.generator.LFGeneratorContext
import org.lflang.generator.LFGeneratorContext.Mode
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
Expand Down
2 changes: 1 addition & 1 deletion org.lflang/src/org/lflang/generator/rust/RustGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion org.lflang/src/org/lflang/generator/ts/TSGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 9e5e5a1

Please sign in to comment.