From 6b8a881e8e7b70fa408f6e04361e844879d77b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 26 Sep 2021 16:52:13 +0200 Subject: [PATCH 01/21] Add end position to LfIssue --- org.lflang.lfc/src/org/lflang/lfc/Main.java | 9 +++++---- org.lflang.lfc/src/org/lflang/lfc/ReportingUtil.kt | 2 ++ .../src/org/lflang/lfc/StandaloneErrorReporter.java | 2 +- .../src/org/lflang/lfc/StandaloneIssueAcceptor.java | 2 ++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/org.lflang.lfc/src/org/lflang/lfc/Main.java b/org.lflang.lfc/src/org/lflang/lfc/Main.java index 8b5c2ae3ba..1e954e9c61 100644 --- a/org.lflang.lfc/src/org/lflang/lfc/Main.java +++ b/org.lflang.lfc/src/org/lflang/lfc/Main.java @@ -521,11 +521,12 @@ private Resource getValidatedResource(Path path) { for (Issue issue : issues) { URI uri = issue.getUriToProblem(); // Issues may also relate to imported resources. try { - issueCollector.accept(new LfIssue(issue.getMessage(), - issue.getSeverity(), issue.getLineNumber(), - issue.getColumn(), issue.getLength(), FileConfig.toPath(uri))); + issueCollector.accept(new LfIssue(issue.getMessage(), issue.getSeverity(), + issue.getLineNumber(), issue.getColumn(), + issue.getLineNumberEnd(), issue.getColumnEnd(), + issue.getLength(), FileConfig.toPath(uri))); } catch (IOException e) { - reporter.printError("Unable to convert '" + uri + "' to path."); + reporter.printError("Unable to convert '" + uri + "' to path." + e); } } return resource; diff --git a/org.lflang.lfc/src/org/lflang/lfc/ReportingUtil.kt b/org.lflang.lfc/src/org/lflang/lfc/ReportingUtil.kt index dca98b5bd6..3ec30e0249 100644 --- a/org.lflang.lfc/src/org/lflang/lfc/ReportingUtil.kt +++ b/org.lflang.lfc/src/org/lflang/lfc/ReportingUtil.kt @@ -83,6 +83,8 @@ data class LfIssue( val severity: Severity, val line: Int?, val column: Int?, + val endLine: Int?, + val endColumn: Int?, val length: Int?, val file: Path? ) : Comparable { diff --git a/org.lflang.lfc/src/org/lflang/lfc/StandaloneErrorReporter.java b/org.lflang.lfc/src/org/lflang/lfc/StandaloneErrorReporter.java index 9f67e5efc4..96a75bb89d 100644 --- a/org.lflang.lfc/src/org/lflang/lfc/StandaloneErrorReporter.java +++ b/org.lflang.lfc/src/org/lflang/lfc/StandaloneErrorReporter.java @@ -51,7 +51,7 @@ private String reportWithNode(String message, Severity severity, EObject obj) { } private String reportSimpleFileCtx(String message, Severity severity, Integer line, Path path) { - LfIssue issue = new LfIssue(message, severity, line, null, null, path); + LfIssue issue = new LfIssue(message, severity, line, 1, line, 1, 0, path); issueAcceptor.accept(issue); // Return a string that can be inserted into the generated code. return message; diff --git a/org.lflang.lfc/src/org/lflang/lfc/StandaloneIssueAcceptor.java b/org.lflang.lfc/src/org/lflang/lfc/StandaloneIssueAcceptor.java index 2ac587e338..aed51b59f7 100644 --- a/org.lflang.lfc/src/org/lflang/lfc/StandaloneIssueAcceptor.java +++ b/org.lflang.lfc/src/org/lflang/lfc/StandaloneIssueAcceptor.java @@ -48,6 +48,8 @@ void accept(Severity severity, String message, EObject object, EStructuralFeatur severity, diagnostic.getLine(), diagnostic.getColumn(), + diagnostic.getLineEnd(), + diagnostic.getColumnEnd(), diagnostic.getLength(), getPath(object) ); From 2505e2c2ea6e8c7c4bfc0320e059fce496247fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 26 Sep 2021 17:57:07 +0200 Subject: [PATCH 02/21] Add tests for standalone error messages --- org.lflang.lfc/build.gradle | 21 +++ .../org/lflang/lfc/LFStandaloneModule.java | 7 +- org.lflang.lfc/src/org/lflang/lfc/Main.java | 120 +++++++++++------- .../src/org/lflang/lfc/ReportingUtil.kt | 10 +- .../lflang/lfc/tests/LfIssueReportingTest.kt | 93 ++++++++++++++ .../org/lflang/lfc/tests/multilineWarning.lf | 5 + .../lflang/lfc/tests/multilineWarning.stderr | 5 + .../org/lflang/lfc/tests/simpleWarning.lf | 5 + .../org/lflang/lfc/tests/simpleWarning.stderr | 16 +++ .../lflang/tests/standalone/simpleWarning.lf | 0 .../tests/standalone/simpleWarning.stderr | 0 11 files changed, 231 insertions(+), 51 deletions(-) create mode 100644 org.lflang.lfc/test/kotlin/org/lflang/lfc/tests/LfIssueReportingTest.kt create mode 100644 org.lflang.lfc/test/resources/org/lflang/lfc/tests/multilineWarning.lf create mode 100644 org.lflang.lfc/test/resources/org/lflang/lfc/tests/multilineWarning.stderr create mode 100644 org.lflang.lfc/test/resources/org/lflang/lfc/tests/simpleWarning.lf create mode 100644 org.lflang.lfc/test/resources/org/lflang/lfc/tests/simpleWarning.stderr create mode 100644 org.lflang.tests/src/org/lflang/tests/standalone/simpleWarning.lf create mode 100644 org.lflang.tests/src/org/lflang/tests/standalone/simpleWarning.stderr diff --git a/org.lflang.lfc/build.gradle b/org.lflang.lfc/build.gradle index f96d08da49..ad4b8b1a36 100644 --- a/org.lflang.lfc/build.gradle +++ b/org.lflang.lfc/build.gradle @@ -1,7 +1,28 @@ + +sourceSets { + test { + java.srcDirs = [] + kotlin.srcDirs = ['test/kotlin'] + resources.srcDir('test/resources') + resources.include '**/*' + } +} + +compileTestKotlin { + destinationDir = compileTestJava.destinationDir + kotlinOptions { + jvmTarget = "1.8" + } +} + + + dependencies { implementation project(':org.lflang') implementation "org.eclipse.xtext:org.eclipse.xtext.ide:${xtextVersion}" implementation "org.eclipse.xtext:org.eclipse.xtext.xbase.ide:${xtextVersion}" + + testImplementation "junit:junit:4.12" } apply plugin: 'application' diff --git a/org.lflang.lfc/src/org/lflang/lfc/LFStandaloneModule.java b/org.lflang.lfc/src/org/lflang/lfc/LFStandaloneModule.java index 01215fef69..291c28eaf2 100644 --- a/org.lflang.lfc/src/org/lflang/lfc/LFStandaloneModule.java +++ b/org.lflang.lfc/src/org/lflang/lfc/LFStandaloneModule.java @@ -26,15 +26,14 @@ * generated by Xtext 2.23.0 */ -package org.lflang; +package org.lflang.lfc; import java.util.Objects; import org.eclipse.xtext.validation.ValidationMessageAcceptor; -import org.lflang.lfc.ReportingBackend; -import org.lflang.lfc.StandaloneErrorReporter; -import org.lflang.lfc.StandaloneIssueAcceptor; +import org.lflang.ErrorReporter; +import org.lflang.LFRuntimeModule; import com.google.inject.Binder; import com.google.inject.Module; diff --git a/org.lflang.lfc/src/org/lflang/lfc/Main.java b/org.lflang.lfc/src/org/lflang/lfc/Main.java index 1e954e9c61..b74af4d7bb 100644 --- a/org.lflang.lfc/src/org/lflang/lfc/Main.java +++ b/org.lflang.lfc/src/org/lflang/lfc/Main.java @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2021, TU Dresden. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * 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 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 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /** * Stand-alone version of the Lingua Franca compiler (lfc). */ @@ -35,11 +59,11 @@ import org.eclipse.xtext.validation.CheckMode; import org.eclipse.xtext.validation.IResourceValidator; import org.eclipse.xtext.validation.Issue; + import org.lflang.ASTUtils; import org.lflang.ErrorReporter; import org.lflang.FileConfig; import org.lflang.LFRuntimeModule; -import org.lflang.LFStandaloneModule; import org.lflang.LFStandaloneSetup; import org.lflang.generator.StandaloneContext; @@ -59,9 +83,9 @@ public class Main { * The location of the class file of this class inside of the jar. */ private static String MAIN_PATH_IN_JAR = String.join("/", - new String[] {"!", "org", "lflang", "lfc", "Main.class"}); + new String[] {"!", "org", "lflang", "org/lflang/lfc", "Main.class"}); + - /** * Object for interpreting command line arguments. */ @@ -87,13 +111,13 @@ public class Main { */ @Inject private Provider resourceSetProvider; - + /** * Injected resource validator. */ @Inject private IResourceValidator validator; - + /** * Injected code generator. */ @@ -140,20 +164,20 @@ enum CLIOption { OUTPUT_PATH("o", "output-path", true, false, "Specify the root output directory.", false), RUNTIME_VERSION(null, "runtime-version", true, false, "Specify the version of the runtime library used for compiling LF programs.", true), EXTERNAL_RUNTIME_PATH(null, "external-runtime-path", true, false, "Specify an external runtime library to be used by the compiled binary.", true); - + /** * The corresponding Apache CLI Option object. */ public final Option option; - + /** * Whether or not to pass this option to the code generator. */ public final boolean passOn; - + /** * Construct a new CLIOption. - * + * * @param opt The short option name. E.g.: "f" denotes a flag * "-f". * @param longOpt The long option name. E.g.: "foo" denotes a flag @@ -171,10 +195,10 @@ enum CLIOption { option.setRequired(isReq); this.passOn = passOn; } - + /** * Create an Apache Commons CLI Options object and add all the options. - * + * * @return Options object that includes all the options in this enum. */ public static Options getOptions() { @@ -182,11 +206,11 @@ public static Options getOptions() { Arrays.asList(CLIOption.values()).forEach(o -> opts.addOption(o.option)); return opts; } - + /** * Return a list of options that are to be passed on to the code * generator. - * + * * @return List of options that must be passed on to the code gen stage. */ public static List