From ccec4f9f7fe75498996aa4d729ec0fd84a272f03 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 24 Jan 2022 20:54:24 -0800 Subject: [PATCH 1/4] LFC: Disable generated code validation by default. --- org.lflang.lfc/src/org/lflang/lfc/Main.java | 3 ++- .../src/org/lflang/generator/Validator.java | 27 ++++++++++++++++--- .../org/lflang/generator/cpp/CppGenerator.kt | 2 +- .../generator/python/PythonGenerator.xtend | 2 +- .../lflang/generator/rust/RustGenerator.kt | 2 +- .../org/lflang/generator/ts/TSGenerator.kt | 4 +-- .../org/lflang/generator/ts/TSValidator.kt | 7 ++--- 7 files changed, 34 insertions(+), 13 deletions(-) diff --git a/org.lflang.lfc/src/org/lflang/lfc/Main.java b/org.lflang.lfc/src/org/lflang/lfc/Main.java index 51be01ce84..36f495abd4 100644 --- a/org.lflang.lfc/src/org/lflang/lfc/Main.java +++ b/org.lflang.lfc/src/org/lflang/lfc/Main.java @@ -106,6 +106,7 @@ enum CLIOption { COMPILER(null, "target-compiler", true, false, "Target compiler to invoke.", true), CLEAN("c", "clean", false, false, "Clean before building.", true), HELP("h", "help", false, false, "Display this information.", true), + LINT("l", "lint", true, false, "Enable or disable linting of generated code.", true), NO_COMPILE("n", "no-compile", false, false, "Do not invoke target compiler.", true), FEDERATED("f", "federated", false, false, "Treat main reactor as federated.", false), THREADS("t", "threads", true, false, "Specify the default number of threads.", true), @@ -120,7 +121,7 @@ enum CLIOption { public final Option option; /** - * Whether or not to pass this option to the code generator. + * Whether to pass this option to the code generator. */ public final boolean passOn; diff --git a/org.lflang/src/org/lflang/generator/Validator.java b/org.lflang/src/org/lflang/generator/Validator.java index 5951172825..c64ebf2c8a 100644 --- a/org.lflang/src/org/lflang/generator/Validator.java +++ b/org.lflang/src/org/lflang/generator/Validator.java @@ -3,6 +3,7 @@ import org.eclipse.xtext.util.CancelIndicator; import org.lflang.ErrorReporter; +import org.lflang.TargetConfig.Mode; import org.lflang.util.LFCommand; import java.nio.file.Path; import java.util.ArrayList; @@ -50,13 +51,13 @@ protected Validator(ErrorReporter errorReporter, Map codeMaps) { /** * Validate this Validator's group of generated files. - * @param cancelIndicator The cancel indicator for the - * current operation. + * @param context The context of the current build. */ - public final void doValidate(CancelIndicator cancelIndicator) throws ExecutionException, InterruptedException { + public final void doValidate(LFGeneratorContext context) throws ExecutionException, InterruptedException { + if (!validationEnabled(context)) return; final List>> tasks = getValidationStrategies().stream().map( it -> (Callable>) () -> { - it.second.run(cancelIndicator, true); + it.second.run(context.getCancelIndicator(), true); return it; } ).collect(Collectors.toList()); @@ -66,6 +67,24 @@ public final void doValidate(CancelIndicator cancelIndicator) throws ExecutionEx } } + /** + * Return whether generated code validation is enabled for this build. + * @param context The context of the current build. + */ + private boolean validationEnabled(LFGeneratorContext context) { + String lint = context.getArgs().getProperty("lint", context.getMode() == Mode.STANDALONE ? "false" : "true"); + if (lint.equalsIgnoreCase("true")) return true; + else if (lint.equalsIgnoreCase("false")) return false; + else { + errorReporter.reportWarning(String.format( + "Unrecognized value for \"lint\" property: \"%s\". Acceptable values are \"true\" and \"false\". " + + "Assuming default value of \"false\".", + lint + )); + return false; + } + } + /** * Invoke all the given tasks. * @param tasks Any set of tasks. diff --git a/org.lflang/src/org/lflang/generator/cpp/CppGenerator.kt b/org.lflang/src/org/lflang/generator/cpp/CppGenerator.kt index b4ae8fa572..7230446cdb 100644 --- a/org.lflang/src/org/lflang/generator/cpp/CppGenerator.kt +++ b/org.lflang/src/org/lflang/generator/cpp/CppGenerator.kt @@ -83,7 +83,7 @@ class CppGenerator( // We must compile in order to install the dependencies. Future validations will be faster. doCompile(context, codeMaps) } else if (runCmake(context).first == 0) { - CppValidator(cppFileConfig, errorReporter, codeMaps).doValidate(context.cancelIndicator) + CppValidator(cppFileConfig, errorReporter, codeMaps).doValidate(context) context.finish(GeneratorResult.GENERATED_NO_EXECUTABLE.apply(codeMaps)) } else { context.unsuccessfulFinish() diff --git a/org.lflang/src/org/lflang/generator/python/PythonGenerator.xtend b/org.lflang/src/org/lflang/generator/python/PythonGenerator.xtend index ba928c9a36..8175e0f733 100644 --- a/org.lflang/src/org/lflang/generator/python/PythonGenerator.xtend +++ b/org.lflang/src/org/lflang/generator/python/PythonGenerator.xtend @@ -1299,7 +1299,7 @@ class PythonGenerator extends CGenerator { 100 * federateCount / federates.size() ) // If there are no federates, compile and install the generated code - new PythonValidator(fileConfig, errorReporter, codeMaps, protoNames).doValidate(context.cancelIndicator) + new PythonValidator(fileConfig, errorReporter, codeMaps, protoNames).doValidate(context) if (!errorsOccurred() && context.mode != Mode.LSP_MEDIUM) { compilingFederatesContext.reportProgress( String.format("Validation complete. Compiling and installing %d/%d Python modules...", federateCount, federates.size()), diff --git a/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt b/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt index 69cf164104..20e51bbd5a 100644 --- a/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt +++ b/org.lflang/src/org/lflang/generator/rust/RustGenerator.kt @@ -86,7 +86,7 @@ class RustGenerator( ) val exec = fileConfig.binPath.toAbsolutePath().resolve(gen.executableName) Files.deleteIfExists(exec) // cleanup, cargo doesn't do it - if (context.mode == TargetConfig.Mode.LSP_MEDIUM) RustValidator(fileConfig, errorReporter, codeMaps).doValidate(context.cancelIndicator) + if (context.mode == TargetConfig.Mode.LSP_MEDIUM) RustValidator(fileConfig, errorReporter, codeMaps).doValidate(context) else invokeRustCompiler(context, gen.executableName, codeMaps) } } diff --git a/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt b/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt index 7c3669a909..90b5ff0ece 100644 --- a/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt +++ b/org.lflang/src/org/lflang/generator/ts/TSGenerator.kt @@ -389,10 +389,10 @@ class TSGenerator( */ private fun passesChecks(validator: TSValidator, parsingContext: LFGeneratorContext): Boolean { parsingContext.reportProgress("Linting generated code...", 0) - validator.doLint(parsingContext.cancelIndicator) + validator.doLint(parsingContext) if (errorsOccurred()) return false parsingContext.reportProgress("Validating generated code...", 25) - validator.doValidate(parsingContext.cancelIndicator) + validator.doValidate(parsingContext) return !errorsOccurred() } diff --git a/org.lflang/src/org/lflang/generator/ts/TSValidator.kt b/org.lflang/src/org/lflang/generator/ts/TSValidator.kt index e217c9d975..2b80ec39e2 100644 --- a/org.lflang/src/org/lflang/generator/ts/TSValidator.kt +++ b/org.lflang/src/org/lflang/generator/ts/TSValidator.kt @@ -9,6 +9,7 @@ import org.lflang.ErrorReporter import org.lflang.generator.CodeMap import org.lflang.generator.DiagnosticReporting import org.lflang.generator.HumanReadableReportingStrategy +import org.lflang.generator.LFGeneratorContext import org.lflang.generator.Position import org.lflang.generator.ValidationStrategy import org.lflang.generator.Validator @@ -152,9 +153,9 @@ class TSValidator( /** * Run a relatively fast linter on the generated code. - * @param cancelIndicator The indicator of whether this build process is cancelled. + * @param context The context of the current build. */ - fun doLint(cancelIndicator: CancelIndicator) { - TSLinter(fileConfig, errorReporter, codeMaps).doValidate(cancelIndicator) + fun doLint(context: LFGeneratorContext) { + TSLinter(fileConfig, errorReporter, codeMaps).doValidate(context) } } From 48d95663efdf11c8125623427058c3995e6a94cc Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 24 Jan 2022 21:18:28 -0800 Subject: [PATCH 2/4] LFC: Never disable type checks for TypeScript. --- .../src/org/lflang/generator/Validator.java | 18 ++++++++++++++---- .../src/org/lflang/generator/ts/TSValidator.kt | 3 +++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/Validator.java b/org.lflang/src/org/lflang/generator/Validator.java index c64ebf2c8a..969dac71d2 100644 --- a/org.lflang/src/org/lflang/generator/Validator.java +++ b/org.lflang/src/org/lflang/generator/Validator.java @@ -72,19 +72,29 @@ public final void doValidate(LFGeneratorContext context) throws ExecutionExcepti * @param context The context of the current build. */ private boolean validationEnabled(LFGeneratorContext context) { - String lint = context.getArgs().getProperty("lint", context.getMode() == Mode.STANDALONE ? "false" : "true"); + boolean defaultValue = validationEnabledByDefault(context); + String lint = context.getArgs().getProperty("lint", defaultValue ? "true" : "false"); if (lint.equalsIgnoreCase("true")) return true; else if (lint.equalsIgnoreCase("false")) return false; else { errorReporter.reportWarning(String.format( "Unrecognized value for \"lint\" property: \"%s\". Acceptable values are \"true\" and \"false\". " - + "Assuming default value of \"false\".", - lint + + "Assuming default value of \"%s\".", + lint, defaultValue ? "true" : "false" )); - return false; + return defaultValue; } } + /** + * Return whether validation of generated code is enabled by default. + * @param context The context of the current build. + * @return Whether validation of generated code is enabled by default. + */ + protected boolean validationEnabledByDefault(LFGeneratorContext context) { + return context.getMode() != Mode.STANDALONE; + } + /** * Invoke all the given tasks. * @param tasks Any set of tasks. diff --git a/org.lflang/src/org/lflang/generator/ts/TSValidator.kt b/org.lflang/src/org/lflang/generator/ts/TSValidator.kt index 2b80ec39e2..0f361d2286 100644 --- a/org.lflang/src/org/lflang/generator/ts/TSValidator.kt +++ b/org.lflang/src/org/lflang/generator/ts/TSValidator.kt @@ -158,4 +158,7 @@ class TSValidator( fun doLint(context: LFGeneratorContext) { TSLinter(fileConfig, errorReporter, codeMaps).doValidate(context) } + + // If this is not true, then the user might as well be writing JavaScript. + override fun validationEnabledByDefault(context: LFGeneratorContext?): Boolean = true } From d1cc5ed9ab0150b766d1fa8e8ab4cd1d8dba02b7 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 24 Jan 2022 21:28:35 -0800 Subject: [PATCH 3/4] LFC: --lint is just a flag (no argument). --- org.lflang.lfc/src/org/lflang/lfc/Main.java | 2 +- org.lflang/src/org/lflang/generator/Validator.java | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/org.lflang.lfc/src/org/lflang/lfc/Main.java b/org.lflang.lfc/src/org/lflang/lfc/Main.java index 36f495abd4..9ef9674c93 100644 --- a/org.lflang.lfc/src/org/lflang/lfc/Main.java +++ b/org.lflang.lfc/src/org/lflang/lfc/Main.java @@ -106,7 +106,7 @@ enum CLIOption { COMPILER(null, "target-compiler", true, false, "Target compiler to invoke.", true), CLEAN("c", "clean", false, false, "Clean before building.", true), HELP("h", "help", false, false, "Display this information.", true), - LINT("l", "lint", true, false, "Enable or disable linting of generated code.", true), + LINT("l", "lint", false, false, "Enable or disable linting of generated code.", true), NO_COMPILE("n", "no-compile", false, false, "Do not invoke target compiler.", true), FEDERATED("f", "federated", false, false, "Treat main reactor as federated.", false), THREADS("t", "threads", true, false, "Specify the default number of threads.", true), diff --git a/org.lflang/src/org/lflang/generator/Validator.java b/org.lflang/src/org/lflang/generator/Validator.java index 969dac71d2..6106b13559 100644 --- a/org.lflang/src/org/lflang/generator/Validator.java +++ b/org.lflang/src/org/lflang/generator/Validator.java @@ -72,18 +72,7 @@ public final void doValidate(LFGeneratorContext context) throws ExecutionExcepti * @param context The context of the current build. */ private boolean validationEnabled(LFGeneratorContext context) { - boolean defaultValue = validationEnabledByDefault(context); - String lint = context.getArgs().getProperty("lint", defaultValue ? "true" : "false"); - if (lint.equalsIgnoreCase("true")) return true; - else if (lint.equalsIgnoreCase("false")) return false; - else { - errorReporter.reportWarning(String.format( - "Unrecognized value for \"lint\" property: \"%s\". Acceptable values are \"true\" and \"false\". " - + "Assuming default value of \"%s\".", - lint, defaultValue ? "true" : "false" - )); - return defaultValue; - } + return context.getArgs().containsKey("lint") || validationEnabledByDefault(context); } /** From 577911973b896a19710e0f81e3875d2126ef460e Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 24 Jan 2022 21:53:09 -0800 Subject: [PATCH 4/4] Tests: Add tautological check that option is listed in enum. --- .github/scripts/test-lfc.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/scripts/test-lfc.sh b/.github/scripts/test-lfc.sh index 447629d02b..c5132e1cd0 100755 --- a/.github/scripts/test-lfc.sh +++ b/.github/scripts/test-lfc.sh @@ -47,6 +47,10 @@ bin/lfc --federated --rti rti test/C/src/Minimal.lf # -h,--help Display this information. bin/lfc --help +# -l, --lint Enable linting during build. +bin/lfc -l test/Python/src/Minimal.lf +bin/lfc --lint test/Python/src/Minimal.lf + # -n,--no-compile Do not invoke target compiler. bin/lfc -n test/C/src/Minimal.lf bin/lfc --no-compile test/C/src/Minimal.lf