From 49316b707441686469a583ce48e62ec4c89b33cd Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 30 Jan 2024 15:11:32 +0530 Subject: [PATCH 01/55] Improve diagnostic rendering for simple cases --- cli/ballerina-cli/build.gradle | 1 + .../io/ballerina/cli/task/CompileTask.java | 5 ++ .../cli/tool/AnnotateDiagnostics.java | 89 +++++++++++++++++++ .../cli/tool/DiagnosticAnnotation.java | 60 +++++++++++++ .../src/main/java/module-info.java | 1 + .../projects/internal/PackageDiagnostic.java | 10 ++- 6 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java create mode 100644 cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java diff --git a/cli/ballerina-cli/build.gradle b/cli/ballerina-cli/build.gradle index 90b35005a054..90d7a04f2c53 100644 --- a/cli/ballerina-cli/build.gradle +++ b/cli/ballerina-cli/build.gradle @@ -34,6 +34,7 @@ configurations { dependencies { + implementation project(':ballerina-parser') implementation project(':ballerina-lang') implementation project(':ballerina-runtime') implementation project(':ballerina-tools-api') diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index ba0bd8f7aeba..5c12e12318ef 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -18,6 +18,7 @@ package io.ballerina.cli.task; +import io.ballerina.cli.tool.AnnotateDiagnostics; import io.ballerina.cli.utils.BuildTime; import io.ballerina.projects.CodeGeneratorResult; import io.ballerina.projects.CodeModifierResult; @@ -234,6 +235,10 @@ public void execute(Project project) { if (d.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) { hasErrors = true; } + if (d.diagnosticInfo().code() == null || !d.diagnosticInfo().code().equals( + ProjectDiagnosticErrorCode.BUILT_WITH_OLDER_SL_UPDATE_DISTRIBUTION.diagnosticId())) { + err.println(AnnotateDiagnostics.renderDiagnostic(d)); + } } if (hasErrors) { throw createLauncherException("compilation contains errors"); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java new file mode 100644 index 000000000000..d7ddbc7292d7 --- /dev/null +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java @@ -0,0 +1,89 @@ +package io.ballerina.cli.tool; + +import io.ballerina.compiler.syntax.tree.ModulePartNode; +import io.ballerina.compiler.syntax.tree.NonTerminalNode; +import io.ballerina.compiler.syntax.tree.SyntaxKind; +import io.ballerina.compiler.syntax.tree.SyntaxTree; +import io.ballerina.tools.diagnostics.Diagnostic; +import io.ballerina.projects.internal.PackageDiagnostic; +import io.ballerina.tools.diagnostics.Location; +import io.ballerina.tools.text.TextDocument; +import io.ballerina.tools.text.TextDocuments; +import io.ballerina.tools.text.TextRange; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; + +public class AnnotateDiagnostics { + + private static final Set STATEMENT_NODES = Set.of( + SyntaxKind.ASSIGNMENT_STATEMENT, + SyntaxKind.CALL_STATEMENT, + SyntaxKind.LOCAL_VAR_DECL, + SyntaxKind.RETURN_STATEMENT); + + public static String renderDiagnostic(Diagnostic diagnostic) { + + if (diagnostic instanceof PackageDiagnostic packageDiagnostic) { + DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( + packageDiagnostic.diagnosticFilePath(), packageDiagnostic.location()); + return diagnosticAnnotation + "\n" + diagnostic; + } + + return diagnostic.toString(); + } + + private static String getDiagnosticLineFromText(Path diagnosticFilePath, Location location) { + String text = getSourceText(diagnosticFilePath); + int lineNumber = location.lineRange().startLine().line(); + String[] lines = text.split("\n"); + String line = lines[lineNumber]; + int start = location.textRange().startOffset(); + int end = location.textRange().endOffset(); + return line; + } + + private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnosticFilePath, Location location) { + String text = getSourceText(diagnosticFilePath); + TextDocument textDocument = TextDocuments.from(text); + SyntaxTree syntaxTree = SyntaxTree.from(textDocument, diagnosticFilePath.toString()); + boolean isMultiline = location.lineRange().startLine().line() != location.lineRange().endLine().line(); + int start = location.textRange().startOffset(); + int end = location.textRange().endOffset(); + int startLine = location.lineRange().startLine().line() + 1; + NonTerminalNode diagnosticNode = ((ModulePartNode) syntaxTree.rootNode()).findNode( + TextRange.from(start, end - start), true); + NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode); + + return new DiagnosticAnnotation( + statementNode.toString(), + diagnosticNode.textRangeWithMinutiae().startOffset() - + statementNode.textRangeWithMinutiae().startOffset(), + diagnosticNode.textRangeWithMinutiae().endOffset() - + diagnosticNode.textRangeWithMinutiae().startOffset(), + isMultiline, startLine); + } + + private static NonTerminalNode climbUpToStatementNode(NonTerminalNode node) { + if (node.parent() == null) { + return node; + } + if (STATEMENT_NODES.contains(node.parent().kind())) { + return node.parent(); + } + return climbUpToStatementNode(node.parent()); + } + + private static String getSourceText(Path sourceFilePath) { + try { + return new String(Files.readAllBytes(sourceFilePath), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} + diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java new file mode 100644 index 000000000000..b9db65d17e0f --- /dev/null +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java @@ -0,0 +1,60 @@ +package io.ballerina.cli.tool; + +public class DiagnosticAnnotation { + + private final String line; + private final int start; + private final int length; + private final boolean isMultiline; + private final int startLine; + + public DiagnosticAnnotation(String line, int start, int length, boolean isMultiline, int startLine) { + this.line = line; + this.start = start; + this.length = length; + this.isMultiline = isMultiline; + this.startLine = startLine; + } + + public String toString() { + String line_ = line; +// remove leading and trailing newline + if (line_.startsWith("\n")) { + line_ = line_.substring(1); + } + if (line_.endsWith("\n")) { + line_ = line_.substring(0, line_.length() - 1); + } + if (!isMultiline) { + int n_digits = (int) Math.log10(startLine) + 1; + String padding = " ".repeat(n_digits + 1); + return padding + "| " + "\n" + + String.format("%" + n_digits + "d ", startLine) + "| " + line_ + "\n" + + padding + "| " + getCaretLine(start, length) + "\n"; + } + + // Multiline case + String[] lines = line.split("\n"); + int n_digits_end = (int) Math.log10(startLine + lines.length - 1) + 1; + String padding = " ".repeat(n_digits_end + 1); + + if (lines.length == 2) { + return padding + "| " + "\n" + + String.format("%" + n_digits_end + "d ", startLine) + "| " + lines[0] + "\n" + + String.format("%" + n_digits_end + "d ", startLine + 1) + "| " + lines[1] + "\n" + + padding + "| " + "\n"; + } + return padding + "| " + "\n" + + String.format("%" + n_digits_end + "d ", startLine) + "| " + lines[0] + "\n" + + ":" + " ".repeat(n_digits_end) + "| " + "\n" + + ":" + " ".repeat(n_digits_end) + "| " + "\n" + + String.format("%" + n_digits_end + "d ", startLine + lines.length - 1) + "| " + + lines[lines.length - 1] + "\n" + + padding + "| " + "\n"; + + } + + private static String getCaretLine(int offset, int length) { + return " ".repeat(offset) + "^".repeat(length); + } +} diff --git a/cli/ballerina-cli/src/main/java/module-info.java b/cli/ballerina-cli/src/main/java/module-info.java index 5a4dc307a549..48866e6f76d6 100644 --- a/cli/ballerina-cli/src/main/java/module-info.java +++ b/cli/ballerina-cli/src/main/java/module-info.java @@ -8,6 +8,7 @@ requires io.ballerina.runtime; requires io.ballerina.lang; + requires io.ballerina.parser; requires io.ballerina.tools.api; requires io.ballerina.testerina.runtime; requires io.ballerina.testerina.core; diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java index ec1502a9bb37..00a4049ecc1f 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java @@ -27,9 +27,7 @@ import io.ballerina.tools.diagnostics.DiagnosticInfo; import io.ballerina.tools.diagnostics.DiagnosticProperty; import io.ballerina.tools.diagnostics.Location; -import io.ballerina.tools.text.LinePosition; -import io.ballerina.tools.text.LineRange; -import io.ballerina.tools.text.TextRange; +import io.ballerina.tools.text.*; import java.io.File; import java.nio.file.Files; @@ -51,6 +49,7 @@ public class PackageDiagnostic extends Diagnostic { protected Location location; protected Project project; protected ModuleDescriptor moduleDescriptor; + protected Path diagnosticFilePath; public PackageDiagnostic(DiagnosticInfo diagnosticInfo, Location location) { this.diagnostic = DiagnosticFactory.createDiagnostic(diagnosticInfo, location); @@ -93,6 +92,11 @@ public PackageDiagnostic(Diagnostic diagnostic, ModuleDescriptor moduleDescripto this.project = project; this.moduleDescriptor = moduleDescriptor; this.location = new DiagnosticLocation(filePath, this.diagnostic.location()); + this.diagnosticFilePath = Paths.get(filePath); + } + + public Path diagnosticFilePath() { + return diagnosticFilePath; } @Override From 0e214c38fb265223a7df8765dd1bf2137f0731b2 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Wed, 31 Jan 2024 13:19:23 +0530 Subject: [PATCH 02/55] Handling tab chars in user code --- .../cli/tool/AnnotateDiagnostics.java | 42 +++++++++---------- .../cli/tool/DiagnosticAnnotation.java | 35 +++++++++++++--- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java index d7ddbc7292d7..4dbbc728be15 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java @@ -30,21 +30,12 @@ public static String renderDiagnostic(Diagnostic diagnostic) { if (diagnostic instanceof PackageDiagnostic packageDiagnostic) { DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( packageDiagnostic.diagnosticFilePath(), packageDiagnostic.location()); - return diagnosticAnnotation + "\n" + diagnostic; + return diagnostic + "\n" + diagnosticAnnotation; } return diagnostic.toString(); } - private static String getDiagnosticLineFromText(Path diagnosticFilePath, Location location) { - String text = getSourceText(diagnosticFilePath); - int lineNumber = location.lineRange().startLine().line(); - String[] lines = text.split("\n"); - String line = lines[lineNumber]; - int start = location.textRange().startOffset(); - int end = location.textRange().endOffset(); - return line; - } private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnosticFilePath, Location location) { String text = getSourceText(diagnosticFilePath); @@ -53,28 +44,35 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnost boolean isMultiline = location.lineRange().startLine().line() != location.lineRange().endLine().line(); int start = location.textRange().startOffset(); int end = location.textRange().endOffset(); - int startLine = location.lineRange().startLine().line() + 1; + int startLine = location.lineRange().startLine().line(); + int endLine = location.lineRange().endLine().line(); NonTerminalNode diagnosticNode = ((ModulePartNode) syntaxTree.rootNode()).findNode( TextRange.from(start, end - start), true); - NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode); + NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode, startLine, endLine); return new DiagnosticAnnotation( statementNode.toString(), - diagnosticNode.textRangeWithMinutiae().startOffset() - - statementNode.textRangeWithMinutiae().startOffset(), - diagnosticNode.textRangeWithMinutiae().endOffset() - - diagnosticNode.textRangeWithMinutiae().startOffset(), - isMultiline, startLine); + + diagnosticNode.textRange().startOffset() - statementNode.textRangeWithMinutiae().startOffset(), + diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), + isMultiline, startLine + 1); } - private static NonTerminalNode climbUpToStatementNode(NonTerminalNode node) { - if (node.parent() == null) { + private static NonTerminalNode climbUpToStatementNode(NonTerminalNode node, int start, int end) { + NonTerminalNode parent = node.parent(); + + if (parent == null) { return node; } - if (STATEMENT_NODES.contains(node.parent().kind())) { - return node.parent(); + + if (parent.lineRange().startLine().line() < start || parent.lineRange().endLine().line() > end) { + return node; + } + + if (STATEMENT_NODES.contains(parent.kind())) { + return parent; } - return climbUpToStatementNode(node.parent()); + return climbUpToStatementNode(parent, start, end); } private static String getSourceText(Path sourceFilePath) { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java index b9db65d17e0f..1348479b3d9f 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java @@ -9,8 +9,8 @@ public class DiagnosticAnnotation { private final int startLine; public DiagnosticAnnotation(String line, int start, int length, boolean isMultiline, int startLine) { - this.line = line; - this.start = start; + this.start = start + 3 * countTabChars(line, start); + this.line = replaceTabs(line, start); this.length = length; this.isMultiline = isMultiline; this.startLine = startLine; @@ -18,9 +18,9 @@ public DiagnosticAnnotation(String line, int start, int length, boolean isMultil public String toString() { String line_ = line; -// remove leading and trailing newline +// replace leading and trailing newlines if (line_.startsWith("\n")) { - line_ = line_.substring(1); + line_ = " " + line_.substring(1); } if (line_.endsWith("\n")) { line_ = line_.substring(0, line_.length() - 1); @@ -46,8 +46,8 @@ public String toString() { } return padding + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLine) + "| " + lines[0] + "\n" - + ":" + " ".repeat(n_digits_end) + "| " + "\n" - + ":" + " ".repeat(n_digits_end) + "| " + "\n" + + " :" + " ".repeat(n_digits_end - 1) + "| " + "\n" + + " :" + " ".repeat(n_digits_end - 1) + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLine + lines.length - 1) + "| " + lines[lines.length - 1] + "\n" + padding + "| " + "\n"; @@ -57,4 +57,27 @@ public String toString() { private static String getCaretLine(int offset, int length) { return " ".repeat(offset) + "^".repeat(length); } + + private static int countTabChars(String line, int end) { + int count = 0; + for (int i = 0; i < end; i++) { + if (line.charAt(i) == '\t') { + count++; + } + } + return count; + } + + + private static String replaceTabs(String line, int end) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < end; i++) { + if (line.charAt(i) == '\t') { + sb.append(" "); + } else { + sb.append(line.charAt(i)); + } + } + return sb + line.substring(end); + } } From 61bc9fc01b3a213cb20ef78d104a21dcf45e7ffd Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Thu, 1 Feb 2024 13:12:19 +0530 Subject: [PATCH 03/55] Add caret underline for multi lined diagnostics --- .../cli/tool/AnnotateDiagnostics.java | 11 +++- .../cli/tool/DiagnosticAnnotation.java | 51 +++++++++++++------ .../projects/internal/PackageDiagnostic.java | 5 ++ 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java index 4dbbc728be15..35c0d5afe2cb 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java @@ -50,12 +50,21 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnost TextRange.from(start, end - start), true); NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode, startLine, endLine); + if (isMultiline) { + return new DiagnosticAnnotation( + statementNode.toString(), + diagnosticNode.textRange().startOffset() - statementNode.textRangeWithMinutiae().startOffset(), + diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), + diagnosticNode.lineRange().endLine().offset(), + startLine + 1); + } + return new DiagnosticAnnotation( statementNode.toString(), diagnosticNode.textRange().startOffset() - statementNode.textRangeWithMinutiae().startOffset(), diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), - isMultiline, startLine + 1); + startLine + 1); } private static NonTerminalNode climbUpToStatementNode(NonTerminalNode node, int start, int end) { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java index 1348479b3d9f..f689cde1cec1 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java @@ -6,14 +6,29 @@ public class DiagnosticAnnotation { private final int start; private final int length; private final boolean isMultiline; - private final int startLine; + private final int endOffset; + private final int startLineNumber; - public DiagnosticAnnotation(String line, int start, int length, boolean isMultiline, int startLine) { + + public static final String RESET = "\033[0m"; + public static final String RED = "\033[0;31m"; + + public DiagnosticAnnotation(String line, int start, int length, int startLineNumber) { + this.start = start + 3 * countTabChars(line, start); + this.line = replaceTabs(line, start); + this.length = length; + this.endOffset = 0; + this.isMultiline = false; + this.startLineNumber = startLineNumber; + } + + public DiagnosticAnnotation(String line, int start, int length, int endOffset, int startLineNumber) { this.start = start + 3 * countTabChars(line, start); this.line = replaceTabs(line, start); this.length = length; - this.isMultiline = isMultiline; - this.startLine = startLine; + this.endOffset = endOffset; + this.isMultiline = true; + this.startLineNumber = startLineNumber; } public String toString() { @@ -26,36 +41,42 @@ public String toString() { line_ = line_.substring(0, line_.length() - 1); } if (!isMultiline) { - int n_digits = (int) Math.log10(startLine) + 1; + int n_digits = (int) Math.log10(startLineNumber) + 1; String padding = " ".repeat(n_digits + 1); return padding + "| " + "\n" - + String.format("%" + n_digits + "d ", startLine) + "| " + line_ + "\n" + + String.format("%" + n_digits + "d ", startLineNumber) + "| " + line_ + "\n" + padding + "| " + getCaretLine(start, length) + "\n"; } // Multiline case - String[] lines = line.split("\n"); - int n_digits_end = (int) Math.log10(startLine + lines.length - 1) + 1; + String[] lines = line_.split("\n"); + int max_length_line = Math.max(lines[0].length(), lines[lines.length - 1].length()); + int n_digits_end = (int) Math.log10(startLineNumber + lines.length - 1) + 1; String padding = " ".repeat(n_digits_end + 1); + String paddingWithColon = " :" + " ".repeat(n_digits_end - 1); if (lines.length == 2) { return padding + "| " + "\n" - + String.format("%" + n_digits_end + "d ", startLine) + "| " + lines[0] + "\n" - + String.format("%" + n_digits_end + "d ", startLine + 1) + "| " + lines[1] + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + lines[0] + "\n" + + padding + "| " + getCaretLine(start, lines[0].length() - start) + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + lines[1] + "\n" + + padding + "| " + getCaretLine(0, endOffset) + "\n" + padding + "| " + "\n"; } return padding + "| " + "\n" - + String.format("%" + n_digits_end + "d ", startLine) + "| " + lines[0] + "\n" - + " :" + " ".repeat(n_digits_end - 1) + "| " + "\n" - + " :" + " ".repeat(n_digits_end - 1) + "| " + "\n" - + String.format("%" + n_digits_end + "d ", startLine + lines.length - 1) + "| " + + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + lines[0] + "\n" + + paddingWithColon + "| " + getCaretLine(start, lines[0].length() - start) + "\n" + + paddingWithColon + "| " + " ".repeat(max_length_line / 2) + "." + "\n" + + paddingWithColon + "| " + " ".repeat(max_length_line / 2) + "." + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber + lines.length - 1) + "| " + lines[lines.length - 1] + "\n" + + padding + "| " + getCaretLine(0, endOffset) + "\n" + padding + "| " + "\n"; } private static String getCaretLine(int offset, int length) { - return " ".repeat(offset) + "^".repeat(length); + return " ".repeat(offset) + RED + "^".repeat(length) + RESET; } private static int countTabChars(String line, int end) { diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java index 00a4049ecc1f..e2c0fd511b84 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java @@ -28,6 +28,7 @@ import io.ballerina.tools.diagnostics.DiagnosticProperty; import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.*; +import org.wso2.ballerinalang.compiler.diagnostic.BLangDiagnostic; import java.io.File; import java.nio.file.Files; @@ -99,6 +100,10 @@ public Path diagnosticFilePath() { return diagnosticFilePath; } + public boolean isSemanticDiagnostic() { + return this.diagnostic instanceof BLangDiagnostic; + } + @Override public Location location() { return this.location; From affe957777d31ba0c7416d2de8fc52079a7b9f3e Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 2 Feb 2024 14:35:18 +0530 Subject: [PATCH 04/55] Filter duplicate diagnostics --- .../src/main/java/io/ballerina/cli/task/CompileTask.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index 5c12e12318ef..edc39aa52212 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -49,6 +49,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.HashSet; import static io.ballerina.cli.launcher.LauncherUtils.createLauncherException; import static io.ballerina.projects.util.ProjectConstants.DOT; @@ -231,13 +232,17 @@ public void execute(Project project) { // Add tool resolution diagnostics to diagnostics diagnostics.addAll(project.currentPackage().getBuildToolResolution().getDiagnosticList()); boolean hasErrors = false; + // HashSet to keep track of the diagnostics to avoid duplicate diagnostics + HashSet diagnosticSet = new HashSet<>(); for (Diagnostic d : diagnostics) { if (d.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) { hasErrors = true; } if (d.diagnosticInfo().code() == null || !d.diagnosticInfo().code().equals( ProjectDiagnosticErrorCode.BUILT_WITH_OLDER_SL_UPDATE_DISTRIBUTION.diagnosticId())) { - err.println(AnnotateDiagnostics.renderDiagnostic(d)); + if (diagnosticSet.add(d.toString())) { + err.println(AnnotateDiagnostics.renderDiagnostic(d)); + } } } if (hasErrors) { From 5585a3bbb60e333ec0509542c95ee8a90cb426b5 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 9 Feb 2024 10:10:30 +0530 Subject: [PATCH 05/55] Change tree traversal approach --- .../cli/tool/AnnotateDiagnostics.java | 45 ++++++++++++++----- .../cli/tool/DiagnosticAnnotation.java | 7 ++- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java index 35c0d5afe2cb..76791f5da076 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java @@ -1,9 +1,6 @@ package io.ballerina.cli.tool; -import io.ballerina.compiler.syntax.tree.ModulePartNode; -import io.ballerina.compiler.syntax.tree.NonTerminalNode; -import io.ballerina.compiler.syntax.tree.SyntaxKind; -import io.ballerina.compiler.syntax.tree.SyntaxTree; +import io.ballerina.compiler.syntax.tree.*; import io.ballerina.tools.diagnostics.Diagnostic; import io.ballerina.projects.internal.PackageDiagnostic; import io.ballerina.tools.diagnostics.Location; @@ -15,6 +12,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Set; public class AnnotateDiagnostics { @@ -36,7 +34,6 @@ public static String renderDiagnostic(Diagnostic diagnostic) { return diagnostic.toString(); } - private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnosticFilePath, Location location) { String text = getSourceText(diagnosticFilePath); TextDocument textDocument = TextDocuments.from(text); @@ -49,10 +46,11 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnost NonTerminalNode diagnosticNode = ((ModulePartNode) syntaxTree.rootNode()).findNode( TextRange.from(start, end - start), true); NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode, startLine, endLine); + ArrayList siblings = getSiblingsOnSameRange(statementNode, startLine, endLine); if (isMultiline) { return new DiagnosticAnnotation( - statementNode.toString(), + nodeListToString(siblings), diagnosticNode.textRange().startOffset() - statementNode.textRangeWithMinutiae().startOffset(), diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), diagnosticNode.lineRange().endLine().offset(), @@ -60,9 +58,8 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnost } return new DiagnosticAnnotation( - statementNode.toString(), - - diagnosticNode.textRange().startOffset() - statementNode.textRangeWithMinutiae().startOffset(), + nodeListToString(siblings), + diagnosticNode.textRange().startOffset() - siblings.get(0).textRangeWithMinutiae().startOffset(), diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), startLine + 1); } @@ -78,12 +75,36 @@ private static NonTerminalNode climbUpToStatementNode(NonTerminalNode node, int return node; } - if (STATEMENT_NODES.contains(parent.kind())) { - return parent; - } +// if (STATEMENT_NODES.contains(parent.kind())) { +// return parent; +// } return climbUpToStatementNode(parent, start, end); } + private static ArrayList getSiblingsOnSameRange(NonTerminalNode node, int start, int end) { + NonTerminalNode parent = node.parent(); + ArrayList siblings = new ArrayList<>(); + if (parent == null) { + siblings.add(node); + return siblings; + } + ChildNodeList childNodeList = parent.children(); + for (Node child : childNodeList) { + if (child.lineRange().startLine().line() >= start && child.lineRange().endLine().line() <= end) { + siblings.add(child); + } + } + return siblings; + } + + private static String nodeListToString(ArrayList nodeList) { + StringBuilder sb = new StringBuilder(); + for (Node node : nodeList) { + sb.append(node.toString()); + } + return sb.toString(); + } + private static String getSourceText(Path sourceFilePath) { try { return new String(Files.readAllBytes(sourceFilePath), StandardCharsets.UTF_8); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java index f689cde1cec1..f4607f74a71a 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java @@ -55,12 +55,15 @@ public String toString() { String padding = " ".repeat(n_digits_end + 1); String paddingWithColon = " :" + " ".repeat(n_digits_end - 1); + int tabsInLastLine = countTabChars(lines[lines.length - 1], this.endOffset); + lines[lines.length - 1] = replaceTabs(lines[lines.length - 1], this.endOffset); + if (lines.length == 2) { return padding + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + lines[0] + "\n" + padding + "| " + getCaretLine(start, lines[0].length() - start) + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + lines[1] + "\n" - + padding + "| " + getCaretLine(0, endOffset) + "\n" + + padding + "| " + getCaretLine(0, endOffset + 3 * tabsInLastLine) + "\n" + padding + "| " + "\n"; } return padding + "| " + "\n" @@ -70,7 +73,7 @@ public String toString() { + paddingWithColon + "| " + " ".repeat(max_length_line / 2) + "." + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber + lines.length - 1) + "| " + lines[lines.length - 1] + "\n" - + padding + "| " + getCaretLine(0, endOffset) + "\n" + + padding + "| " + getCaretLine(0, endOffset + 3 * tabsInLastLine) + "\n" + padding + "| " + "\n"; } From 639978752c86650cbce115bcfefb48949f7d83e6 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 9 Feb 2024 15:31:47 +0530 Subject: [PATCH 06/55] Move classes to shell-cli to access jansi --- .../shell/cli}/AnnotateDiagnostics.java | 10 +- .../shell/cli}/DiagnosticAnnotation.java | 2 +- .../io/ballerina/cli/task/CompileTask.java | 5 +- .../cli/tool/AnnotateDiagnostics2.java | 120 ++++++++++++++++++ .../cli/tool/DiagnosticAnnotation2.java | 107 ++++++++++++++++ .../src/main/java/module-info.java | 2 +- 6 files changed, 241 insertions(+), 5 deletions(-) rename {cli/ballerina-cli/src/main/java/io/ballerina/cli/tool => ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli}/AnnotateDiagnostics.java (94%) rename {cli/ballerina-cli/src/main/java/io/ballerina/cli/tool => ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli}/DiagnosticAnnotation.java (99%) create mode 100644 cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics2.java create mode 100644 cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation2.java diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java similarity index 94% rename from cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java rename to ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java index 76791f5da076..ef8d2874e3e5 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java @@ -1,12 +1,13 @@ -package io.ballerina.cli.tool; +package io.ballerina.shell.cli; import io.ballerina.compiler.syntax.tree.*; -import io.ballerina.tools.diagnostics.Diagnostic; import io.ballerina.projects.internal.PackageDiagnostic; +import io.ballerina.tools.diagnostics.Diagnostic; import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.TextDocument; import io.ballerina.tools.text.TextDocuments; import io.ballerina.tools.text.TextRange; +import org.jline.terminal.TerminalBuilder; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -47,6 +48,11 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnost TextRange.from(start, end - start), true); NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode, startLine, endLine); ArrayList siblings = getSiblingsOnSameRange(statementNode, startLine, endLine); + try (var terminal = TerminalBuilder.terminal()) { + System.out.println(terminal.getWidth()); + } catch (IOException e) { + throw new RuntimeException(e); + } if (isMultiline) { return new DiagnosticAnnotation( diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java similarity index 99% rename from cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java rename to ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java index f4607f74a71a..67fe8f27fc3b 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java @@ -1,4 +1,4 @@ -package io.ballerina.cli.tool; +package io.ballerina.shell.cli; public class DiagnosticAnnotation { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index edc39aa52212..6694f88b4e62 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -18,7 +18,10 @@ package io.ballerina.cli.task; -import io.ballerina.cli.tool.AnnotateDiagnostics; +//import io.ballerina.cli.tool.AnnotateDiagnostics2; + + +import io.ballerina.shell.cli.AnnotateDiagnostics; import io.ballerina.cli.utils.BuildTime; import io.ballerina.projects.CodeGeneratorResult; import io.ballerina.projects.CodeModifierResult; diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics2.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics2.java new file mode 100644 index 000000000000..9084990f5d20 --- /dev/null +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics2.java @@ -0,0 +1,120 @@ +package io.ballerina.cli.tool; + + +import io.ballerina.compiler.syntax.tree.*; +import io.ballerina.tools.diagnostics.Diagnostic; +import io.ballerina.projects.internal.PackageDiagnostic; +import io.ballerina.tools.diagnostics.Location; +import io.ballerina.tools.text.TextDocument; +import io.ballerina.tools.text.TextDocuments; +import io.ballerina.tools.text.TextRange; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Set; + +public class AnnotateDiagnostics2 { + + private static final Set STATEMENT_NODES = Set.of( + SyntaxKind.ASSIGNMENT_STATEMENT, + SyntaxKind.CALL_STATEMENT, + SyntaxKind.LOCAL_VAR_DECL, + SyntaxKind.RETURN_STATEMENT); + + + public static String renderDiagnostic(Diagnostic diagnostic) { + + if (diagnostic instanceof PackageDiagnostic packageDiagnostic) { + DiagnosticAnnotation2 diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( + packageDiagnostic.diagnosticFilePath(), packageDiagnostic.location()); + return diagnostic + "\n" + diagnosticAnnotation; + } + + return diagnostic.toString(); + } + + + private static DiagnosticAnnotation2 getDiagnosticLineFromSyntaxAPI(Path diagnosticFilePath, Location location) { + String text = getSourceText(diagnosticFilePath); + TextDocument textDocument = TextDocuments.from(text); + SyntaxTree syntaxTree = SyntaxTree.from(textDocument, diagnosticFilePath.toString()); + boolean isMultiline = location.lineRange().startLine().line() != location.lineRange().endLine().line(); + int start = location.textRange().startOffset(); + int end = location.textRange().endOffset(); + int startLine = location.lineRange().startLine().line(); + int endLine = location.lineRange().endLine().line(); + NonTerminalNode diagnosticNode = ((ModulePartNode) syntaxTree.rootNode()).findNode( + TextRange.from(start, end - start), true); + NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode, startLine, endLine); + ArrayList siblings = getSiblingsOnSameRange(statementNode, startLine, endLine); + + if (isMultiline) { + return new DiagnosticAnnotation2( + nodeListToString(siblings), + diagnosticNode.textRange().startOffset() - statementNode.textRangeWithMinutiae().startOffset(), + diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), + diagnosticNode.lineRange().endLine().offset(), + startLine + 1); + } + + return new DiagnosticAnnotation2( + nodeListToString(siblings), + diagnosticNode.textRange().startOffset() - siblings.get(0).textRangeWithMinutiae().startOffset(), + diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), + startLine + 1); + } + + private static NonTerminalNode climbUpToStatementNode(NonTerminalNode node, int start, int end) { + NonTerminalNode parent = node.parent(); + + if (parent == null) { + return node; + } + + if (parent.lineRange().startLine().line() < start || parent.lineRange().endLine().line() > end) { + return node; + } + +// if (STATEMENT_NODES.contains(parent.kind())) { +// return parent; +// } + return climbUpToStatementNode(parent, start, end); + } + + private static ArrayList getSiblingsOnSameRange(NonTerminalNode node, int start, int end) { + NonTerminalNode parent = node.parent(); + ArrayList siblings = new ArrayList<>(); + if (parent == null) { + siblings.add(node); + return siblings; + } + ChildNodeList childNodeList = parent.children(); + for (Node child : childNodeList) { + if (child.lineRange().startLine().line() >= start && child.lineRange().endLine().line() <= end) { + siblings.add(child); + } + } + return siblings; + } + + private static String nodeListToString(ArrayList nodeList) { + StringBuilder sb = new StringBuilder(); + for (Node node : nodeList) { + sb.append(node.toString()); + } + return sb.toString(); + } + + private static String getSourceText(Path sourceFilePath) { + try { + return new String(Files.readAllBytes(sourceFilePath), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + +} + diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation2.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation2.java new file mode 100644 index 000000000000..f19a695d6d31 --- /dev/null +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation2.java @@ -0,0 +1,107 @@ +package io.ballerina.cli.tool; + +public class DiagnosticAnnotation2 { + + private final String line; + private final int start; + private final int length; + private final boolean isMultiline; + private final int endOffset; + private final int startLineNumber; + + + public static final String RESET = "\033[0m"; + public static final String RED = "\033[0;31m"; + + public DiagnosticAnnotation2(String line, int start, int length, int startLineNumber) { + this.start = start + 3 * countTabChars(line, start); + this.line = replaceTabs(line, start); + this.length = length; + this.endOffset = 0; + this.isMultiline = false; + this.startLineNumber = startLineNumber; + } + + public DiagnosticAnnotation2(String line, int start, int length, int endOffset, int startLineNumber) { + this.start = start + 3 * countTabChars(line, start); + this.line = replaceTabs(line, start); + this.length = length; + this.endOffset = endOffset; + this.isMultiline = true; + this.startLineNumber = startLineNumber; + } + + public String toString() { + String line_ = line; +// replace leading and trailing newlines + if (line_.startsWith("\n")) { + line_ = " " + line_.substring(1); + } + if (line_.endsWith("\n")) { + line_ = line_.substring(0, line_.length() - 1); + } + if (!isMultiline) { + int n_digits = (int) Math.log10(startLineNumber) + 1; + String padding = " ".repeat(n_digits + 1); + return padding + "| " + "\n" + + String.format("%" + n_digits + "d ", startLineNumber) + "| " + line_ + "\n" + + padding + "| " + getCaretLine(start, length) + "\n"; + } + + // Multiline case + String[] lines = line_.split("\n"); + int max_length_line = Math.max(lines[0].length(), lines[lines.length - 1].length()); + int n_digits_end = (int) Math.log10(startLineNumber + lines.length - 1) + 1; + String padding = " ".repeat(n_digits_end + 1); + String paddingWithColon = " :" + " ".repeat(n_digits_end - 1); + + int tabsInLastLine = countTabChars(lines[lines.length - 1], this.endOffset); + lines[lines.length - 1] = replaceTabs(lines[lines.length - 1], this.endOffset); + + if (lines.length == 2) { + return padding + "| " + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + lines[0] + "\n" + + padding + "| " + getCaretLine(start, lines[0].length() - start) + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + lines[1] + "\n" + + padding + "| " + getCaretLine(0, endOffset + 3 * tabsInLastLine) + "\n" + + padding + "| " + "\n"; + } + return padding + "| " + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + lines[0] + "\n" + + paddingWithColon + "| " + getCaretLine(start, lines[0].length() - start) + "\n" + + paddingWithColon + "| " + " ".repeat(max_length_line / 2) + "." + "\n" + + paddingWithColon + "| " + " ".repeat(max_length_line / 2) + "." + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber + lines.length - 1) + "| " + + lines[lines.length - 1] + "\n" + + padding + "| " + getCaretLine(0, endOffset + 3 * tabsInLastLine) + "\n" + + padding + "| " + "\n"; + + } + + private static String getCaretLine(int offset, int length) { + return " ".repeat(offset) + RED + "^".repeat(length) + RESET; + } + + private static int countTabChars(String line, int end) { + int count = 0; + for (int i = 0; i < end; i++) { + if (line.charAt(i) == '\t') { + count++; + } + } + return count; + } + + + private static String replaceTabs(String line, int end) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < end; i++) { + if (line.charAt(i) == '\t') { + sb.append(" "); + } else { + sb.append(line.charAt(i)); + } + } + return sb + line.substring(end); + } +} diff --git a/compiler/ballerina-lang/src/main/java/module-info.java b/compiler/ballerina-lang/src/main/java/module-info.java index b76856e09d11..4865bd4d49bf 100644 --- a/compiler/ballerina-lang/src/main/java/module-info.java +++ b/compiler/ballerina-lang/src/main/java/module-info.java @@ -77,7 +77,7 @@ exports io.ballerina.projects.plugins.codeaction; exports io.ballerina.projects.internal.model; // TODO Remove this exports exports io.ballerina.projects.internal.environment; // TODO Remove these exports - exports io.ballerina.projects.internal to io.ballerina.cli; + exports io.ballerina.projects.internal to io.ballerina.cli, io.ballerina.shell.cli; exports io.ballerina.projects.internal.bala; exports io.ballerina.projects.internal.configschema to org.ballerinalang.config.schema.generator, io.ballerina.language.server.core; From a43a4ff99b65cc9080a3b056b72c6020722cab66 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Mon, 12 Feb 2024 13:31:49 +0530 Subject: [PATCH 07/55] Truncate singleline diagnostics by terminal width --- .../shell/cli/AnnotateDiagnostics.java | 29 +++++++++++------- .../shell/cli/DiagnosticAnnotation.java | 30 ++++++++++++++++--- .../io/ballerina/cli/task/CompileTask.java | 3 +- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java index ef8d2874e3e5..347da43c1926 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java @@ -8,6 +8,8 @@ import io.ballerina.tools.text.TextDocuments; import io.ballerina.tools.text.TextRange; import org.jline.terminal.TerminalBuilder; +import org.jline.utils.AttributedStringBuilder; +import org.jline.utils.AttributedStyle; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -24,18 +26,19 @@ public class AnnotateDiagnostics { SyntaxKind.LOCAL_VAR_DECL, SyntaxKind.RETURN_STATEMENT); - public static String renderDiagnostic(Diagnostic diagnostic) { + public static String renderDiagnostic(Diagnostic diagnostic, int terminalWidth) { if (diagnostic instanceof PackageDiagnostic packageDiagnostic) { DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( - packageDiagnostic.diagnosticFilePath(), packageDiagnostic.location()); + packageDiagnostic.diagnosticFilePath(), packageDiagnostic.location(), terminalWidth); return diagnostic + "\n" + diagnosticAnnotation; } return diagnostic.toString(); } - private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnosticFilePath, Location location) { + private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnosticFilePath, Location location, + int terminalWidth) { String text = getSourceText(diagnosticFilePath); TextDocument textDocument = TextDocuments.from(text); SyntaxTree syntaxTree = SyntaxTree.from(textDocument, diagnosticFilePath.toString()); @@ -48,26 +51,30 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnost TextRange.from(start, end - start), true); NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode, startLine, endLine); ArrayList siblings = getSiblingsOnSameRange(statementNode, startLine, endLine); - try (var terminal = TerminalBuilder.terminal()) { - System.out.println(terminal.getWidth()); - } catch (IOException e) { - throw new RuntimeException(e); - } - if (isMultiline) { return new DiagnosticAnnotation( nodeListToString(siblings), diagnosticNode.textRange().startOffset() - statementNode.textRangeWithMinutiae().startOffset(), diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), diagnosticNode.lineRange().endLine().offset(), - startLine + 1); + startLine + 1, + terminalWidth); } return new DiagnosticAnnotation( nodeListToString(siblings), diagnosticNode.textRange().startOffset() - siblings.get(0).textRangeWithMinutiae().startOffset(), diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), - startLine + 1); + startLine + 1, + terminalWidth); + } + + public static int getTerminalWidth() { + try (var terminal = TerminalBuilder.terminal()) { + return terminal.getWidth(); + } catch (IOException e) { + throw new RuntimeException(e); + } } private static NonTerminalNode climbUpToStatementNode(NonTerminalNode node, int start, int end) { diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java index 67fe8f27fc3b..03e6c0413b32 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java @@ -8,27 +8,30 @@ public class DiagnosticAnnotation { private final boolean isMultiline; private final int endOffset; private final int startLineNumber; + private final int terminalWidth; public static final String RESET = "\033[0m"; public static final String RED = "\033[0;31m"; - public DiagnosticAnnotation(String line, int start, int length, int startLineNumber) { + public DiagnosticAnnotation(String line, int start, int length, int startLineNumber, int terminalWidth) { this.start = start + 3 * countTabChars(line, start); this.line = replaceTabs(line, start); this.length = length; this.endOffset = 0; this.isMultiline = false; this.startLineNumber = startLineNumber; + this.terminalWidth = terminalWidth; } - public DiagnosticAnnotation(String line, int start, int length, int endOffset, int startLineNumber) { + public DiagnosticAnnotation(String line, int start, int length, int endOffset, int startLineNumber, int terminalWidth) { this.start = start + 3 * countTabChars(line, start); this.line = replaceTabs(line, start); this.length = length; this.endOffset = endOffset; this.isMultiline = true; this.startLineNumber = startLineNumber; + this.terminalWidth = terminalWidth; } public String toString() { @@ -43,9 +46,12 @@ public String toString() { if (!isMultiline) { int n_digits = (int) Math.log10(startLineNumber) + 1; String padding = " ".repeat(n_digits + 1); + int maxLength = terminalWidth - n_digits - 3; + TruncateResult result = truncate(line_, maxLength, start, length); return padding + "| " + "\n" - + String.format("%" + n_digits + "d ", startLineNumber) + "| " + line_ + "\n" - + padding + "| " + getCaretLine(start, length) + "\n"; + + String.format("%" + n_digits + "d ", startLineNumber) + "| " + result.line + "\n" + + padding + "| " + getCaretLine(result.diagnosticStart, length) + "\n"; + } // Multiline case @@ -92,6 +98,19 @@ private static int countTabChars(String line, int end) { return count; } + private static TruncateResult truncate(String line, int maxLength, int diagnosticStart, int diagnosticLength) { + if (line.length() < maxLength) { + return new TruncateResult(line, diagnosticStart); + } + if (diagnosticStart + diagnosticLength < maxLength) { + return new TruncateResult(line.substring(0, maxLength - 3) + "...", diagnosticStart); + } + int diagnosticMid = diagnosticStart + diagnosticLength / 2; + int stepsToMoveWindow = diagnosticMid - maxLength / 2; + return new TruncateResult("..." + line.substring(stepsToMoveWindow, stepsToMoveWindow + maxLength - 6) + + "...", diagnosticStart - stepsToMoveWindow + 3); + + } private static String replaceTabs(String line, int end) { StringBuilder sb = new StringBuilder(); @@ -104,4 +123,7 @@ private static String replaceTabs(String line, int end) { } return sb + line.substring(end); } + + private record TruncateResult(String line, int diagnosticStart) { + } } diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index 6694f88b4e62..3a75b85f35b9 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -237,6 +237,7 @@ public void execute(Project project) { boolean hasErrors = false; // HashSet to keep track of the diagnostics to avoid duplicate diagnostics HashSet diagnosticSet = new HashSet<>(); + int terminalWidth = AnnotateDiagnostics.getTerminalWidth(); for (Diagnostic d : diagnostics) { if (d.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) { hasErrors = true; @@ -244,7 +245,7 @@ public void execute(Project project) { if (d.diagnosticInfo().code() == null || !d.diagnosticInfo().code().equals( ProjectDiagnosticErrorCode.BUILT_WITH_OLDER_SL_UPDATE_DISTRIBUTION.diagnosticId())) { if (diagnosticSet.add(d.toString())) { - err.println(AnnotateDiagnostics.renderDiagnostic(d)); + err.println(AnnotateDiagnostics.renderDiagnostic(d, terminalWidth)); } } } From f5477c065b2f872332206e6f5e5a17fe3432aa81 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Mon, 12 Feb 2024 16:22:46 +0530 Subject: [PATCH 08/55] Change tree traversal to direct line access --- .../shell/cli/AnnotateDiagnostics.java | 33 ++++----- .../shell/cli/DiagnosticAnnotation.java | 68 ++++++++++--------- 2 files changed, 52 insertions(+), 49 deletions(-) diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java index 347da43c1926..b50f5f6a8ea2 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java @@ -47,24 +47,25 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnost int end = location.textRange().endOffset(); int startLine = location.lineRange().startLine().line(); int endLine = location.lineRange().endLine().line(); - NonTerminalNode diagnosticNode = ((ModulePartNode) syntaxTree.rootNode()).findNode( - TextRange.from(start, end - start), true); - NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode, startLine, endLine); - ArrayList siblings = getSiblingsOnSameRange(statementNode, startLine, endLine); +// NonTerminalNode diagnosticNode = ((ModulePartNode) syntaxTree.rootNode()).findNode( +// TextRange.from(start, end - start), true); +// NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode, startLine, endLine); +// ArrayList siblings = getSiblingsOnSameRange(statementNode, startLine, endLine); + if (isMultiline) { return new DiagnosticAnnotation( - nodeListToString(siblings), - diagnosticNode.textRange().startOffset() - statementNode.textRangeWithMinutiae().startOffset(), - diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), - diagnosticNode.lineRange().endLine().offset(), + getLines(textDocument, startLine, endLine), + location.lineRange().startLine().offset(), + textDocument.line(startLine).length() - location.lineRange().startLine().offset(), + location.lineRange().endLine().offset(), startLine + 1, terminalWidth); } return new DiagnosticAnnotation( - nodeListToString(siblings), - diagnosticNode.textRange().startOffset() - siblings.get(0).textRangeWithMinutiae().startOffset(), - diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), + getLines(textDocument, startLine, endLine), + location.lineRange().startLine().offset(), + location.lineRange().endLine().offset() - location.lineRange().startLine().offset(), startLine + 1, terminalWidth); } @@ -110,12 +111,12 @@ private static ArrayList getSiblingsOnSameRange(NonTerminalNode node, int return siblings; } - private static String nodeListToString(ArrayList nodeList) { - StringBuilder sb = new StringBuilder(); - for (Node node : nodeList) { - sb.append(node.toString()); + private static ArrayList getLines(TextDocument textDocument, int start, int end) { + ArrayList lines = new ArrayList<>(); + for (int i = start; i <= end; i++) { + lines.add(textDocument.line(i).text()); } - return sb.toString(); + return lines; } private static String getSourceText(Path sourceFilePath) { diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java index 03e6c0413b32..2f3ee755aa45 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java @@ -1,8 +1,10 @@ package io.ballerina.shell.cli; +import java.util.ArrayList; + public class DiagnosticAnnotation { - private final String line; + private final ArrayList lines; private final int start; private final int length; private final boolean isMultiline; @@ -14,9 +16,10 @@ public class DiagnosticAnnotation { public static final String RESET = "\033[0m"; public static final String RED = "\033[0;31m"; - public DiagnosticAnnotation(String line, int start, int length, int startLineNumber, int terminalWidth) { - this.start = start + 3 * countTabChars(line, start); - this.line = replaceTabs(line, start); + public DiagnosticAnnotation(ArrayList lines, int start, int length, int startLineNumber, int terminalWidth) { + this.start = start + 3 * countTabChars(lines.get(0), start); + lines.set(0, replaceTabs(lines.get(0), start)); + this.lines = lines; this.length = length; this.endOffset = 0; this.isMultiline = false; @@ -24,9 +27,10 @@ public DiagnosticAnnotation(String line, int start, int length, int startLineNum this.terminalWidth = terminalWidth; } - public DiagnosticAnnotation(String line, int start, int length, int endOffset, int startLineNumber, int terminalWidth) { - this.start = start + 3 * countTabChars(line, start); - this.line = replaceTabs(line, start); + public DiagnosticAnnotation(ArrayList lines, int start, int length, int endOffset, int startLineNumber, int terminalWidth) { + this.start = start + 3 * countTabChars(lines.get(0), start); + lines.set(0, replaceTabs(lines.get(0), start)); + this.lines = lines; this.length = length; this.endOffset = endOffset; this.isMultiline = true; @@ -35,50 +39,48 @@ public DiagnosticAnnotation(String line, int start, int length, int endOffset, i } public String toString() { - String line_ = line; -// replace leading and trailing newlines - if (line_.startsWith("\n")) { - line_ = " " + line_.substring(1); - } - if (line_.endsWith("\n")) { - line_ = line_.substring(0, line_.length() - 1); - } if (!isMultiline) { int n_digits = (int) Math.log10(startLineNumber) + 1; String padding = " ".repeat(n_digits + 1); int maxLength = terminalWidth - n_digits - 3; - TruncateResult result = truncate(line_, maxLength, start, length); + TruncateResult result = truncate(lines.get(0), maxLength, start, length); return padding + "| " + "\n" + String.format("%" + n_digits + "d ", startLineNumber) + "| " + result.line + "\n" + padding + "| " + getCaretLine(result.diagnosticStart, length) + "\n"; } - // Multiline case - String[] lines = line_.split("\n"); - int max_length_line = Math.max(lines[0].length(), lines[lines.length - 1].length()); - int n_digits_end = (int) Math.log10(startLineNumber + lines.length - 1) + 1; + + int max_length_line = Math.max(lines.get(0).length(), lines.get(lines.size() - 1).length()); + int n_digits_end = (int) Math.log10(startLineNumber + lines.size() - 1) + 1; String padding = " ".repeat(n_digits_end + 1); String paddingWithColon = " :" + " ".repeat(n_digits_end - 1); - int tabsInLastLine = countTabChars(lines[lines.length - 1], this.endOffset); - lines[lines.length - 1] = replaceTabs(lines[lines.length - 1], this.endOffset); + int tabsInLastLine = countTabChars(lines.get(lines.size() - 1), this.endOffset); + lines.set(lines.size() - 1, replaceTabs(lines.get(lines.size() - 1), this.endOffset)); + int maxLength = terminalWidth - n_digits_end - 3; + TruncateResult result1 = truncate(lines.get(0), maxLength, start, length); + int res1DiagnosticLen = result1.line().length() - result1.diagnosticStart; + TruncateResult result2 = truncate(lines.get(lines.size() - 1), maxLength, 0, + endOffset + 3 * tabsInLastLine); + int res2DiagnosticLen = result2.line().length() - result2.diagnosticStart; - if (lines.length == 2) { + if (lines.size() == 2) { return padding + "| " + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + lines[0] + "\n" - + padding + "| " + getCaretLine(start, lines[0].length() - start) + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + lines[1] + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" + + padding + "| " + getCaretLine(result1.diagnosticStart, res1DiagnosticLen) + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + result2.line + "\n" + padding + "| " + getCaretLine(0, endOffset + 3 * tabsInLastLine) + "\n" + padding + "| " + "\n"; } + String padding2 = " ".repeat(Math.min(terminalWidth, max_length_line) / 2); return padding + "| " + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + lines[0] + "\n" - + paddingWithColon + "| " + getCaretLine(start, lines[0].length() - start) + "\n" - + paddingWithColon + "| " + " ".repeat(max_length_line / 2) + "." + "\n" - + paddingWithColon + "| " + " ".repeat(max_length_line / 2) + "." + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber + lines.length - 1) + "| " - + lines[lines.length - 1] + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" + + paddingWithColon + "| " + getCaretLine(result1.diagnosticStart, res1DiagnosticLen) + "\n" + + paddingWithColon + "| " + padding2 + ":" + "\n" + + paddingWithColon + "| " + padding2 + ":" + "\n" + + String.format("%" + n_digits_end + "d ", startLineNumber + lines.size() - 1) + "| " + + result2.line + "\n" + padding + "| " + getCaretLine(0, endOffset + 3 * tabsInLastLine) + "\n" + padding + "| " + "\n"; @@ -107,7 +109,7 @@ private static TruncateResult truncate(String line, int maxLength, int diagnosti } int diagnosticMid = diagnosticStart + diagnosticLength / 2; int stepsToMoveWindow = diagnosticMid - maxLength / 2; - return new TruncateResult("..." + line.substring(stepsToMoveWindow, stepsToMoveWindow + maxLength - 6) + return new TruncateResult("..." + line.substring(stepsToMoveWindow, maxLength - 6) + "...", diagnosticStart - stepsToMoveWindow + 3); } From c79a1c806e8ca23d46359db7fb15ef790340d87e Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 13 Feb 2024 13:36:08 +0530 Subject: [PATCH 09/55] Handle extreme terminal window sizes --- .../shell/cli/DiagnosticAnnotation.java | 31 ++++++++++--------- .../projects/internal/PackageDiagnostic.java | 4 --- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java index 2f3ee755aa45..199036f12a6e 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java @@ -46,7 +46,7 @@ public String toString() { TruncateResult result = truncate(lines.get(0), maxLength, start, length); return padding + "| " + "\n" + String.format("%" + n_digits + "d ", startLineNumber) + "| " + result.line + "\n" - + padding + "| " + getCaretLine(result.diagnosticStart, length) + "\n"; + + padding + "| " + getCaretLine(result.diagnosticStart, result.diagnosticLength) + "\n"; } @@ -60,28 +60,26 @@ public String toString() { lines.set(lines.size() - 1, replaceTabs(lines.get(lines.size() - 1), this.endOffset)); int maxLength = terminalWidth - n_digits_end - 3; TruncateResult result1 = truncate(lines.get(0), maxLength, start, length); - int res1DiagnosticLen = result1.line().length() - result1.diagnosticStart; TruncateResult result2 = truncate(lines.get(lines.size() - 1), maxLength, 0, endOffset + 3 * tabsInLastLine); - int res2DiagnosticLen = result2.line().length() - result2.diagnosticStart; if (lines.size() == 2) { return padding + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" - + padding + "| " + getCaretLine(result1.diagnosticStart, res1DiagnosticLen) + "\n" + + padding + "| " + getCaretLine(result1.diagnosticStart, result1.diagnosticLength) + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + result2.line + "\n" - + padding + "| " + getCaretLine(0, endOffset + 3 * tabsInLastLine) + "\n" + + padding + "| " + getCaretLine(0, result2.diagnosticLength) + "\n" + padding + "| " + "\n"; } String padding2 = " ".repeat(Math.min(terminalWidth, max_length_line) / 2); return padding + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" - + paddingWithColon + "| " + getCaretLine(result1.diagnosticStart, res1DiagnosticLen) + "\n" + + paddingWithColon + "| " + getCaretLine(result1.diagnosticStart, result1.diagnosticLength) + "\n" + paddingWithColon + "| " + padding2 + ":" + "\n" + paddingWithColon + "| " + padding2 + ":" + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber + lines.size() - 1) + "| " + result2.line + "\n" - + padding + "| " + getCaretLine(0, endOffset + 3 * tabsInLastLine) + "\n" + + padding + "| " + getCaretLine(0, result2.diagnosticLength) + "\n" + padding + "| " + "\n"; } @@ -101,16 +99,19 @@ private static int countTabChars(String line, int end) { } private static TruncateResult truncate(String line, int maxLength, int diagnosticStart, int diagnosticLength) { - if (line.length() < maxLength) { - return new TruncateResult(line, diagnosticStart); + if (line.length() < maxLength - 3) { + return new TruncateResult(line, diagnosticStart, diagnosticLength); } - if (diagnosticStart + diagnosticLength < maxLength) { - return new TruncateResult(line.substring(0, maxLength - 3) + "...", diagnosticStart); + if (diagnosticStart + diagnosticLength < maxLength - 3) { + return new TruncateResult(line.substring(0, maxLength - 3) + "...", diagnosticStart, diagnosticLength); } int diagnosticMid = diagnosticStart + diagnosticLength / 2; - int stepsToMoveWindow = diagnosticMid - maxLength / 2; - return new TruncateResult("..." + line.substring(stepsToMoveWindow, maxLength - 6) - + "...", diagnosticStart - stepsToMoveWindow + 3); + int stepsToMoveWindow = Math.max(0, diagnosticMid - maxLength / 2); + int border = Math.min(line.length() - 1, stepsToMoveWindow + maxLength - 6); + int newDiagnosticStart = Math.max(0, diagnosticStart - stepsToMoveWindow + 3); + int newDiagnosticLength = Math.min(diagnosticLength, maxLength - newDiagnosticStart - 3); + return new TruncateResult("..." + line.substring(stepsToMoveWindow, Math.max(stepsToMoveWindow, border)) + + "...", newDiagnosticStart, Math.max(0, newDiagnosticLength)); } @@ -126,6 +127,6 @@ private static String replaceTabs(String line, int end) { return sb + line.substring(end); } - private record TruncateResult(String line, int diagnosticStart) { + private record TruncateResult(String line, int diagnosticStart, int diagnosticLength) { } } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java index e2c0fd511b84..b8e34ec2468b 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java @@ -100,10 +100,6 @@ public Path diagnosticFilePath() { return diagnosticFilePath; } - public boolean isSemanticDiagnostic() { - return this.diagnostic instanceof BLangDiagnostic; - } - @Override public Location location() { return this.location; From 662b8df4e53e8c220cbd8ffc70aa47fb063b387d Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Thu, 15 Feb 2024 11:56:10 +0530 Subject: [PATCH 10/55] Use existing syntaxtree, handle bal build projects --- .../shell/cli/AnnotateDiagnostics.java | 91 +++++++++++++++++-- .../io/ballerina/cli/task/CompileTask.java | 25 ++++- .../projects/internal/PackageDiagnostic.java | 11 +-- 3 files changed, 108 insertions(+), 19 deletions(-) diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java index b50f5f6a8ea2..6d57992e7243 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java @@ -1,6 +1,7 @@ package io.ballerina.shell.cli; import io.ballerina.compiler.syntax.tree.*; +import io.ballerina.projects.Document; import io.ballerina.projects.internal.PackageDiagnostic; import io.ballerina.tools.diagnostics.Diagnostic; import io.ballerina.tools.diagnostics.Location; @@ -16,6 +17,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.HashSet; import java.util.Set; public class AnnotateDiagnostics { @@ -26,22 +28,26 @@ public class AnnotateDiagnostics { SyntaxKind.LOCAL_VAR_DECL, SyntaxKind.RETURN_STATEMENT); - public static String renderDiagnostic(Diagnostic diagnostic, int terminalWidth) { + public static String renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth) { - if (diagnostic instanceof PackageDiagnostic packageDiagnostic) { - DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( - packageDiagnostic.diagnosticFilePath(), packageDiagnostic.location(), terminalWidth); - return diagnostic + "\n" + diagnosticAnnotation; + String diagnosticCode = diagnostic.diagnosticInfo().code(); + if (diagnosticCode.startsWith("BCE")) { + int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); + if (diagnosticCodeNumber < 1000) { + return diagnostic + getSyntaxDiagnosticAnnotation( + document, diagnostic.location(), terminalWidth); + } } + DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( + document, diagnostic.location(), terminalWidth); + return diagnostic + "\n" + diagnosticAnnotation; - return diagnostic.toString(); +// return diagnostic.toString(); } - private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnosticFilePath, Location location, + private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document document, Location location, int terminalWidth) { - String text = getSourceText(diagnosticFilePath); - TextDocument textDocument = TextDocuments.from(text); - SyntaxTree syntaxTree = SyntaxTree.from(textDocument, diagnosticFilePath.toString()); + TextDocument textDocument = document.textDocument(); boolean isMultiline = location.lineRange().startLine().line() != location.lineRange().endLine().line(); int start = location.textRange().startOffset(); int end = location.textRange().endOffset(); @@ -70,6 +76,21 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Path diagnost terminalWidth); } + private static String getSyntaxDiagnosticAnnotation(Document document, Location location, int terminalWidth) { + SyntaxTree syntaxTree = document.syntaxTree(); + if (location.textRange().startOffset() == location.textRange().endOffset()) { + Token searchStartToken = + ((ModulePartNode) syntaxTree.rootNode()).findToken(location.textRange().startOffset()); + if (isSyntaxErrorToken(searchStartToken, location.textRange().startOffset())) { + return searchStartToken.toString(); + } + HashSet visited = new HashSet<>(); + return findSyntaxDiagnosticToken(searchStartToken.parent(), + location.textRange().startOffset(), visited).node().toString(); + } + return ""; + } + public static int getTerminalWidth() { try (var terminal = TerminalBuilder.terminal()) { return terminal.getWidth(); @@ -78,6 +99,53 @@ public static int getTerminalWidth() { } } + private static SyntaxErrorSearchResult findSyntaxDiagnosticToken(Node curr, int position, + HashSet visited) { + if (curr instanceof Token token && isSyntaxErrorToken(curr, position)) { + return new SyntaxErrorSearchResult(token, true); + } + + if (curr instanceof NonTerminalNode nonTerminalNode) { + if (isNotWithinRange(nonTerminalNode.textRange(), position)) { + return findSyntaxDiagnosticToken(curr.parent(), position, visited); + } + + for (Node child : nonTerminalNode.children()) { + if (visited.contains(child.hashCode())) { + continue; + } + if (child instanceof NonTerminalNode && isNotWithinRange(child.textRange(), position)) { + visited.add(child.hashCode()); + continue; + } + SyntaxErrorSearchResult result = findSyntaxDiagnosticToken(child, position, visited); + if (result.found()) { + return result; + } + } + + visited.add(nonTerminalNode.hashCode()); + + return findSyntaxDiagnosticToken(curr.parent(), position, visited); + + } + + return new SyntaxErrorSearchResult(curr, false); + + } + + private static boolean isNotWithinRange(TextRange textRange, int position) { + return textRange.startOffset() > position || textRange.endOffset() < position; + } + + private static boolean isSyntaxErrorToken(Node node, int position) { + if (node instanceof Token token) { + return token.textRange().startOffset() == position && token.textRange().endOffset() == position; + } + + return false; + } + private static NonTerminalNode climbUpToStatementNode(NonTerminalNode node, int start, int end) { NonTerminalNode parent = node.parent(); @@ -127,5 +195,8 @@ private static String getSourceText(Path sourceFilePath) { } } + private record SyntaxErrorSearchResult(Node node, boolean found) { + + } } diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index 3a75b85f35b9..e2ef0dd5ef46 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -21,6 +21,7 @@ //import io.ballerina.cli.tool.AnnotateDiagnostics2; +import io.ballerina.projects.*; import io.ballerina.shell.cli.AnnotateDiagnostics; import io.ballerina.cli.utils.BuildTime; import io.ballerina.projects.CodeGeneratorResult; @@ -237,7 +238,17 @@ public void execute(Project project) { boolean hasErrors = false; // HashSet to keep track of the diagnostics to avoid duplicate diagnostics HashSet diagnosticSet = new HashSet<>(); + // HashMap for documents based on filename + HashMap documentMap = new HashMap<>(); int terminalWidth = AnnotateDiagnostics.getTerminalWidth(); + + project.currentPackage().moduleIds().forEach(moduleId -> { + project.currentPackage().module(moduleId).documentIds().forEach(documentId -> { + Document document = project.currentPackage().module(moduleId).document(documentId); + documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); + }); + }); + for (Diagnostic d : diagnostics) { if (d.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) { hasErrors = true; @@ -245,7 +256,12 @@ public void execute(Project project) { if (d.diagnosticInfo().code() == null || !d.diagnosticInfo().code().equals( ProjectDiagnosticErrorCode.BUILT_WITH_OLDER_SL_UPDATE_DISTRIBUTION.diagnosticId())) { if (diagnosticSet.add(d.toString())) { - err.println(AnnotateDiagnostics.renderDiagnostic(d, terminalWidth)); + Document document = documentMap.get(d.location().lineRange().fileName()); + if (document != null) { + err.println(AnnotateDiagnostics.renderDiagnostic(d, document, terminalWidth)); + } else { + err.println(d.toString()); + } } } } @@ -258,6 +274,13 @@ public void execute(Project project) { } } + private String getDocumentPath(ModuleName moduleName, String documentName) { + if (moduleName.isDefaultModuleName()) { + return documentName; + } + return "modules" + "/" + moduleName.moduleNamePart() + "/" + documentName; + } + private boolean isPackCmdForATemplatePkg(Project project) { return compileForBalPack && project.currentPackage().manifest().template(); } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java index b8e34ec2468b..ec1502a9bb37 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageDiagnostic.java @@ -27,8 +27,9 @@ import io.ballerina.tools.diagnostics.DiagnosticInfo; import io.ballerina.tools.diagnostics.DiagnosticProperty; import io.ballerina.tools.diagnostics.Location; -import io.ballerina.tools.text.*; -import org.wso2.ballerinalang.compiler.diagnostic.BLangDiagnostic; +import io.ballerina.tools.text.LinePosition; +import io.ballerina.tools.text.LineRange; +import io.ballerina.tools.text.TextRange; import java.io.File; import java.nio.file.Files; @@ -50,7 +51,6 @@ public class PackageDiagnostic extends Diagnostic { protected Location location; protected Project project; protected ModuleDescriptor moduleDescriptor; - protected Path diagnosticFilePath; public PackageDiagnostic(DiagnosticInfo diagnosticInfo, Location location) { this.diagnostic = DiagnosticFactory.createDiagnostic(diagnosticInfo, location); @@ -93,11 +93,6 @@ public PackageDiagnostic(Diagnostic diagnostic, ModuleDescriptor moduleDescripto this.project = project; this.moduleDescriptor = moduleDescriptor; this.location = new DiagnosticLocation(filePath, this.diagnostic.location()); - this.diagnosticFilePath = Paths.get(filePath); - } - - public Path diagnosticFilePath() { - return diagnosticFilePath; } @Override From bd778678d0a4633e52ef5fc3d2c8bec6687a3435 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 16 Feb 2024 11:46:42 +0530 Subject: [PATCH 11/55] Bump jline version to access jansi from within it --- .../shell/cli/AnnotateDiagnostics.java | 30 ++++- .../shell/cli/DiagnosticAnnotation.java | 34 +++-- .../io/ballerina/cli/task/CompileTask.java | 15 ++- .../cli/tool/AnnotateDiagnostics2.java | 120 ------------------ .../cli/tool/DiagnosticAnnotation2.java | 107 ---------------- .../src/main/java/module-info.java | 1 + gradle.properties | 2 +- 7 files changed, 60 insertions(+), 249 deletions(-) delete mode 100644 cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics2.java delete mode 100644 cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation2.java diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java index 6d57992e7243..0030df42a625 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java @@ -4,6 +4,7 @@ import io.ballerina.projects.Document; import io.ballerina.projects.internal.PackageDiagnostic; import io.ballerina.tools.diagnostics.Diagnostic; +import io.ballerina.tools.diagnostics.DiagnosticSeverity; import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.TextDocument; import io.ballerina.tools.text.TextDocuments; @@ -17,9 +18,12 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.Set; +import static io.ballerina.shell.cli.DiagnosticAnnotation.SEVERITY_COLORS; + public class AnnotateDiagnostics { private static final Set STATEMENT_NODES = Set.of( @@ -34,19 +38,31 @@ public static String renderDiagnostic(Diagnostic diagnostic, Document document, if (diagnosticCode.startsWith("BCE")) { int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); if (diagnosticCodeNumber < 1000) { - return diagnostic + getSyntaxDiagnosticAnnotation( + return diagnosticToString(diagnostic) + getSyntaxDiagnosticAnnotation( document, diagnostic.location(), terminalWidth); } } DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( - document, diagnostic.location(), terminalWidth); - return diagnostic + "\n" + diagnosticAnnotation; + document, diagnostic.location(), diagnostic.diagnosticInfo().severity(), terminalWidth); + return diagnosticToString(diagnostic) + "\n" + diagnosticAnnotation; // return diagnostic.toString(); } + public static String renderDiagnostic(Diagnostic diagnostic) { + return diagnosticToString(diagnostic); + } + + private static String diagnosticToString(Diagnostic diagnostic) { + DiagnosticSeverity severity = diagnostic.diagnosticInfo().severity(); + int severityLength = severity.toString().length(); + return "@|" + SEVERITY_COLORS.get(severity) + " " + severity + "|@" + + diagnostic.toString().substring(severityLength); + + } + private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document document, Location location, - int terminalWidth) { + DiagnosticSeverity severity, int terminalWidth) { TextDocument textDocument = document.textDocument(); boolean isMultiline = location.lineRange().startLine().line() != location.lineRange().endLine().line(); int start = location.textRange().startOffset(); @@ -65,6 +81,7 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document docu textDocument.line(startLine).length() - location.lineRange().startLine().offset(), location.lineRange().endLine().offset(), startLine + 1, + severity, terminalWidth); } @@ -73,6 +90,7 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document docu location.lineRange().startLine().offset(), location.lineRange().endLine().offset() - location.lineRange().startLine().offset(), startLine + 1, + severity, terminalWidth); } @@ -106,7 +124,7 @@ private static SyntaxErrorSearchResult findSyntaxDiagnosticToken(Node curr, int } if (curr instanceof NonTerminalNode nonTerminalNode) { - if (isNotWithinRange(nonTerminalNode.textRange(), position)) { + if (isNotWithinRange(nonTerminalNode.textRangeWithMinutiae(), position)) { return findSyntaxDiagnosticToken(curr.parent(), position, visited); } @@ -114,7 +132,7 @@ private static SyntaxErrorSearchResult findSyntaxDiagnosticToken(Node curr, int if (visited.contains(child.hashCode())) { continue; } - if (child instanceof NonTerminalNode && isNotWithinRange(child.textRange(), position)) { + if (child instanceof NonTerminalNode && isNotWithinRange(child.textRangeWithMinutiae(), position)) { visited.add(child.hashCode()); continue; } diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java index 199036f12a6e..3e8b2e697c39 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java @@ -1,6 +1,9 @@ package io.ballerina.shell.cli; +import io.ballerina.tools.diagnostics.DiagnosticSeverity; + import java.util.ArrayList; +import java.util.HashMap; public class DiagnosticAnnotation { @@ -11,12 +14,18 @@ public class DiagnosticAnnotation { private final int endOffset; private final int startLineNumber; private final int terminalWidth; + private final DiagnosticSeverity severity; - public static final String RESET = "\033[0m"; - public static final String RED = "\033[0;31m"; + public static final HashMap SEVERITY_COLORS = new HashMap<>() {{ + put(DiagnosticSeverity.INTERNAL, "blue"); + put(DiagnosticSeverity.HINT, "blue"); + put(DiagnosticSeverity.INFO, "blue"); + put(DiagnosticSeverity.WARNING, "yellow"); + put(DiagnosticSeverity.ERROR, "red"); + }}; - public DiagnosticAnnotation(ArrayList lines, int start, int length, int startLineNumber, int terminalWidth) { + public DiagnosticAnnotation(ArrayList lines, int start, int length, int startLineNumber, DiagnosticSeverity severity, int terminalWidth) { this.start = start + 3 * countTabChars(lines.get(0), start); lines.set(0, replaceTabs(lines.get(0), start)); this.lines = lines; @@ -24,10 +33,11 @@ public DiagnosticAnnotation(ArrayList lines, int start, int length, int this.endOffset = 0; this.isMultiline = false; this.startLineNumber = startLineNumber; + this.severity = severity; this.terminalWidth = terminalWidth; } - public DiagnosticAnnotation(ArrayList lines, int start, int length, int endOffset, int startLineNumber, int terminalWidth) { + public DiagnosticAnnotation(ArrayList lines, int start, int length, int endOffset, int startLineNumber, DiagnosticSeverity severity, int terminalWidth) { this.start = start + 3 * countTabChars(lines.get(0), start); lines.set(0, replaceTabs(lines.get(0), start)); this.lines = lines; @@ -35,6 +45,7 @@ public DiagnosticAnnotation(ArrayList lines, int start, int length, int this.endOffset = endOffset; this.isMultiline = true; this.startLineNumber = startLineNumber; + this.severity = severity; this.terminalWidth = terminalWidth; } @@ -46,11 +57,10 @@ public String toString() { TruncateResult result = truncate(lines.get(0), maxLength, start, length); return padding + "| " + "\n" + String.format("%" + n_digits + "d ", startLineNumber) + "| " + result.line + "\n" - + padding + "| " + getCaretLine(result.diagnosticStart, result.diagnosticLength) + "\n"; + + padding + "| " + getCaretLine(result.diagnosticStart, result.diagnosticLength, this.severity) + "\n"; } - int max_length_line = Math.max(lines.get(0).length(), lines.get(lines.size() - 1).length()); int n_digits_end = (int) Math.log10(startLineNumber + lines.size() - 1) + 1; String padding = " ".repeat(n_digits_end + 1); @@ -66,26 +76,26 @@ public String toString() { if (lines.size() == 2) { return padding + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" - + padding + "| " + getCaretLine(result1.diagnosticStart, result1.diagnosticLength) + "\n" + + padding + "| " + getCaretLine(result1.diagnosticStart, result1.diagnosticLength, this.severity) + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + result2.line + "\n" - + padding + "| " + getCaretLine(0, result2.diagnosticLength) + "\n" + + padding + "| " + getCaretLine(0, result2.diagnosticLength, this.severity) + "\n" + padding + "| " + "\n"; } String padding2 = " ".repeat(Math.min(terminalWidth, max_length_line) / 2); return padding + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" - + paddingWithColon + "| " + getCaretLine(result1.diagnosticStart, result1.diagnosticLength) + "\n" + + paddingWithColon + "| " + getCaretLine(result1.diagnosticStart, result1.diagnosticLength, this.severity) + "\n" + paddingWithColon + "| " + padding2 + ":" + "\n" + paddingWithColon + "| " + padding2 + ":" + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber + lines.size() - 1) + "| " + result2.line + "\n" - + padding + "| " + getCaretLine(0, result2.diagnosticLength) + "\n" + + padding + "| " + getCaretLine(0, result2.diagnosticLength, this.severity) + "\n" + padding + "| " + "\n"; } - private static String getCaretLine(int offset, int length) { - return " ".repeat(offset) + RED + "^".repeat(length) + RESET; + private static String getCaretLine(int offset, int length, DiagnosticSeverity severity) { + return " ".repeat(offset) + "@|" + SEVERITY_COLORS.get(severity) + " " + "^".repeat(length) + "|@"; } private static int countTabChars(String line, int end) { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index e2ef0dd5ef46..9d776c8ec9e3 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -47,6 +47,8 @@ import org.ballerinalang.central.client.CentralClientConstants; import org.wso2.ballerinalang.util.RepoUtils; + +import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; @@ -59,6 +61,11 @@ import static io.ballerina.projects.util.ProjectConstants.DOT; import static io.ballerina.projects.util.ProjectConstants.TOOL_DIAGNOSTIC_CODE_PREFIX; +import org.jline.terminal.TerminalBuilder; +import org.jline.jansi.AnsiConsole; +import static org.jline.jansi.Ansi.ansi; + + /** * Task for compiling a package. * @@ -240,7 +247,7 @@ public void execute(Project project) { HashSet diagnosticSet = new HashSet<>(); // HashMap for documents based on filename HashMap documentMap = new HashMap<>(); - int terminalWidth = AnnotateDiagnostics.getTerminalWidth(); + int terminalWidth = AnsiConsole.getTerminalWidth(); project.currentPackage().moduleIds().forEach(moduleId -> { project.currentPackage().module(moduleId).documentIds().forEach(documentId -> { @@ -249,6 +256,7 @@ public void execute(Project project) { }); }); + AnsiConsole.systemInstall(); for (Diagnostic d : diagnostics) { if (d.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) { hasErrors = true; @@ -258,13 +266,14 @@ public void execute(Project project) { if (diagnosticSet.add(d.toString())) { Document document = documentMap.get(d.location().lineRange().fileName()); if (document != null) { - err.println(AnnotateDiagnostics.renderDiagnostic(d, document, terminalWidth)); + err.println(ansi().render(AnnotateDiagnostics.renderDiagnostic(d, document, terminalWidth))); } else { - err.println(d.toString()); + err.println(ansi().render(AnnotateDiagnostics.renderDiagnostic(d))); } } } } + AnsiConsole.systemUninstall(); if (hasErrors) { throw createLauncherException("compilation contains errors"); } diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics2.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics2.java deleted file mode 100644 index 9084990f5d20..000000000000 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/AnnotateDiagnostics2.java +++ /dev/null @@ -1,120 +0,0 @@ -package io.ballerina.cli.tool; - - -import io.ballerina.compiler.syntax.tree.*; -import io.ballerina.tools.diagnostics.Diagnostic; -import io.ballerina.projects.internal.PackageDiagnostic; -import io.ballerina.tools.diagnostics.Location; -import io.ballerina.tools.text.TextDocument; -import io.ballerina.tools.text.TextDocuments; -import io.ballerina.tools.text.TextRange; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Set; - -public class AnnotateDiagnostics2 { - - private static final Set STATEMENT_NODES = Set.of( - SyntaxKind.ASSIGNMENT_STATEMENT, - SyntaxKind.CALL_STATEMENT, - SyntaxKind.LOCAL_VAR_DECL, - SyntaxKind.RETURN_STATEMENT); - - - public static String renderDiagnostic(Diagnostic diagnostic) { - - if (diagnostic instanceof PackageDiagnostic packageDiagnostic) { - DiagnosticAnnotation2 diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( - packageDiagnostic.diagnosticFilePath(), packageDiagnostic.location()); - return diagnostic + "\n" + diagnosticAnnotation; - } - - return diagnostic.toString(); - } - - - private static DiagnosticAnnotation2 getDiagnosticLineFromSyntaxAPI(Path diagnosticFilePath, Location location) { - String text = getSourceText(diagnosticFilePath); - TextDocument textDocument = TextDocuments.from(text); - SyntaxTree syntaxTree = SyntaxTree.from(textDocument, diagnosticFilePath.toString()); - boolean isMultiline = location.lineRange().startLine().line() != location.lineRange().endLine().line(); - int start = location.textRange().startOffset(); - int end = location.textRange().endOffset(); - int startLine = location.lineRange().startLine().line(); - int endLine = location.lineRange().endLine().line(); - NonTerminalNode diagnosticNode = ((ModulePartNode) syntaxTree.rootNode()).findNode( - TextRange.from(start, end - start), true); - NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode, startLine, endLine); - ArrayList siblings = getSiblingsOnSameRange(statementNode, startLine, endLine); - - if (isMultiline) { - return new DiagnosticAnnotation2( - nodeListToString(siblings), - diagnosticNode.textRange().startOffset() - statementNode.textRangeWithMinutiae().startOffset(), - diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), - diagnosticNode.lineRange().endLine().offset(), - startLine + 1); - } - - return new DiagnosticAnnotation2( - nodeListToString(siblings), - diagnosticNode.textRange().startOffset() - siblings.get(0).textRangeWithMinutiae().startOffset(), - diagnosticNode.textRange().endOffset() - diagnosticNode.textRange().startOffset(), - startLine + 1); - } - - private static NonTerminalNode climbUpToStatementNode(NonTerminalNode node, int start, int end) { - NonTerminalNode parent = node.parent(); - - if (parent == null) { - return node; - } - - if (parent.lineRange().startLine().line() < start || parent.lineRange().endLine().line() > end) { - return node; - } - -// if (STATEMENT_NODES.contains(parent.kind())) { -// return parent; -// } - return climbUpToStatementNode(parent, start, end); - } - - private static ArrayList getSiblingsOnSameRange(NonTerminalNode node, int start, int end) { - NonTerminalNode parent = node.parent(); - ArrayList siblings = new ArrayList<>(); - if (parent == null) { - siblings.add(node); - return siblings; - } - ChildNodeList childNodeList = parent.children(); - for (Node child : childNodeList) { - if (child.lineRange().startLine().line() >= start && child.lineRange().endLine().line() <= end) { - siblings.add(child); - } - } - return siblings; - } - - private static String nodeListToString(ArrayList nodeList) { - StringBuilder sb = new StringBuilder(); - for (Node node : nodeList) { - sb.append(node.toString()); - } - return sb.toString(); - } - - private static String getSourceText(Path sourceFilePath) { - try { - return new String(Files.readAllBytes(sourceFilePath), StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - -} - diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation2.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation2.java deleted file mode 100644 index f19a695d6d31..000000000000 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/tool/DiagnosticAnnotation2.java +++ /dev/null @@ -1,107 +0,0 @@ -package io.ballerina.cli.tool; - -public class DiagnosticAnnotation2 { - - private final String line; - private final int start; - private final int length; - private final boolean isMultiline; - private final int endOffset; - private final int startLineNumber; - - - public static final String RESET = "\033[0m"; - public static final String RED = "\033[0;31m"; - - public DiagnosticAnnotation2(String line, int start, int length, int startLineNumber) { - this.start = start + 3 * countTabChars(line, start); - this.line = replaceTabs(line, start); - this.length = length; - this.endOffset = 0; - this.isMultiline = false; - this.startLineNumber = startLineNumber; - } - - public DiagnosticAnnotation2(String line, int start, int length, int endOffset, int startLineNumber) { - this.start = start + 3 * countTabChars(line, start); - this.line = replaceTabs(line, start); - this.length = length; - this.endOffset = endOffset; - this.isMultiline = true; - this.startLineNumber = startLineNumber; - } - - public String toString() { - String line_ = line; -// replace leading and trailing newlines - if (line_.startsWith("\n")) { - line_ = " " + line_.substring(1); - } - if (line_.endsWith("\n")) { - line_ = line_.substring(0, line_.length() - 1); - } - if (!isMultiline) { - int n_digits = (int) Math.log10(startLineNumber) + 1; - String padding = " ".repeat(n_digits + 1); - return padding + "| " + "\n" - + String.format("%" + n_digits + "d ", startLineNumber) + "| " + line_ + "\n" - + padding + "| " + getCaretLine(start, length) + "\n"; - } - - // Multiline case - String[] lines = line_.split("\n"); - int max_length_line = Math.max(lines[0].length(), lines[lines.length - 1].length()); - int n_digits_end = (int) Math.log10(startLineNumber + lines.length - 1) + 1; - String padding = " ".repeat(n_digits_end + 1); - String paddingWithColon = " :" + " ".repeat(n_digits_end - 1); - - int tabsInLastLine = countTabChars(lines[lines.length - 1], this.endOffset); - lines[lines.length - 1] = replaceTabs(lines[lines.length - 1], this.endOffset); - - if (lines.length == 2) { - return padding + "| " + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + lines[0] + "\n" - + padding + "| " + getCaretLine(start, lines[0].length() - start) + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + lines[1] + "\n" - + padding + "| " + getCaretLine(0, endOffset + 3 * tabsInLastLine) + "\n" - + padding + "| " + "\n"; - } - return padding + "| " + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + lines[0] + "\n" - + paddingWithColon + "| " + getCaretLine(start, lines[0].length() - start) + "\n" - + paddingWithColon + "| " + " ".repeat(max_length_line / 2) + "." + "\n" - + paddingWithColon + "| " + " ".repeat(max_length_line / 2) + "." + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber + lines.length - 1) + "| " - + lines[lines.length - 1] + "\n" - + padding + "| " + getCaretLine(0, endOffset + 3 * tabsInLastLine) + "\n" - + padding + "| " + "\n"; - - } - - private static String getCaretLine(int offset, int length) { - return " ".repeat(offset) + RED + "^".repeat(length) + RESET; - } - - private static int countTabChars(String line, int end) { - int count = 0; - for (int i = 0; i < end; i++) { - if (line.charAt(i) == '\t') { - count++; - } - } - return count; - } - - - private static String replaceTabs(String line, int end) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < end; i++) { - if (line.charAt(i) == '\t') { - sb.append(" "); - } else { - sb.append(line.charAt(i)); - } - } - return sb + line.substring(end); - } -} diff --git a/cli/ballerina-cli/src/main/java/module-info.java b/cli/ballerina-cli/src/main/java/module-info.java index 48866e6f76d6..147447bea71a 100644 --- a/cli/ballerina-cli/src/main/java/module-info.java +++ b/cli/ballerina-cli/src/main/java/module-info.java @@ -25,4 +25,5 @@ requires io.ballerina.identifier; requires org.objectweb.asm; requires org.apache.commons.io; + requires maven.resolver; } diff --git a/gradle.properties b/gradle.properties index eed4c3e7bb45..c2657a1d8e74 100644 --- a/gradle.properties +++ b/gradle.properties @@ -92,7 +92,7 @@ jetbrainsKotlinStdlibVersion=1.6.0 jetbrainsKotlinStdlibCommonVersion=1.6.0 junitVersion=4.13.2 jknackHandlebarsVersion=4.0.6 -jlineVersion=3.23.0 +jlineVersion=3.25.1 jvnetMimepullVersion=1.9.11 kaitaiGradlePluginVersion=0.1.1 kaitaiStructRuntimeVersion=0.9 From ac7c15f38c36292523b104388659fae1b1c511c3 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Wed, 21 Feb 2024 11:50:37 +0530 Subject: [PATCH 12/55] Pass missing tokens through diagnosticproperties --- .../shell/cli/AnnotateDiagnostics.java | 114 +++++++++++++----- .../shell/cli/DiagnosticAnnotation.java | 33 +++-- .../diagnostics/StringDiagnosticProperty.java | 38 ++++++ .../diagnostics/SyntaxDiagnostic.java | 14 ++- .../internal/parser/SyntaxErrors.java | 2 +- .../src/main/java/module-info.java | 1 + 6 files changed, 159 insertions(+), 43 deletions(-) create mode 100644 compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java index 0030df42a625..85bb0aba6a93 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java @@ -1,13 +1,17 @@ package io.ballerina.shell.cli; +import io.ballerina.compiler.internal.diagnostics.StringDiagnosticProperty; +import io.ballerina.compiler.internal.diagnostics.SyntaxDiagnostic; import io.ballerina.compiler.syntax.tree.*; import io.ballerina.projects.Document; import io.ballerina.projects.internal.PackageDiagnostic; import io.ballerina.tools.diagnostics.Diagnostic; +import io.ballerina.tools.diagnostics.DiagnosticProperty; import io.ballerina.tools.diagnostics.DiagnosticSeverity; import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.TextDocument; import io.ballerina.tools.text.TextDocuments; +import io.ballerina.tools.text.TextLine; import io.ballerina.tools.text.TextRange; import org.jline.terminal.TerminalBuilder; import org.jline.utils.AttributedStringBuilder; @@ -38,15 +42,15 @@ public static String renderDiagnostic(Diagnostic diagnostic, Document document, if (diagnosticCode.startsWith("BCE")) { int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); if (diagnosticCodeNumber < 1000) { - return diagnosticToString(diagnostic) + getSyntaxDiagnosticAnnotation( - document, diagnostic.location(), terminalWidth); + PackageDiagnostic packageDiagnostic = (PackageDiagnostic) diagnostic; + return diagnosticToString(diagnostic) + "\n" + getSyntaxDiagnosticAnnotation( + document, packageDiagnostic, diagnosticCodeNumber, terminalWidth); } } DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( document, diagnostic.location(), diagnostic.diagnosticInfo().severity(), terminalWidth); return diagnosticToString(diagnostic) + "\n" + diagnosticAnnotation; -// return diagnostic.toString(); } public static String renderDiagnostic(Diagnostic diagnostic) { @@ -64,49 +68,103 @@ private static String diagnosticToString(Diagnostic diagnostic) { private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document document, Location location, DiagnosticSeverity severity, int terminalWidth) { TextDocument textDocument = document.textDocument(); - boolean isMultiline = location.lineRange().startLine().line() != location.lineRange().endLine().line(); - int start = location.textRange().startOffset(); - int end = location.textRange().endOffset(); + int startOffset = location.lineRange().startLine().offset(); + int endOffset = location.lineRange().endLine().offset(); int startLine = location.lineRange().startLine().line(); int endLine = location.lineRange().endLine().line(); -// NonTerminalNode diagnosticNode = ((ModulePartNode) syntaxTree.rootNode()).findNode( -// TextRange.from(start, end - start), true); -// NonTerminalNode statementNode = climbUpToStatementNode(diagnosticNode, startLine, endLine); -// ArrayList siblings = getSiblingsOnSameRange(statementNode, startLine, endLine); - if (isMultiline) { + if (startLine != endLine) { return new DiagnosticAnnotation( getLines(textDocument, startLine, endLine), - location.lineRange().startLine().offset(), - textDocument.line(startLine).length() - location.lineRange().startLine().offset(), - location.lineRange().endLine().offset(), + startOffset, + textDocument.line(startLine).length() - startOffset, + endOffset, startLine + 1, severity, + DiagnosticAnnotation.DiagnosticAnnotationType.REGULAR, terminalWidth); } - + int length = endOffset - startOffset; return new DiagnosticAnnotation( getLines(textDocument, startLine, endLine), - location.lineRange().startLine().offset(), - location.lineRange().endLine().offset() - location.lineRange().startLine().offset(), + startOffset, + length == 0 ? 1 : length, startLine + 1, severity, + DiagnosticAnnotation.DiagnosticAnnotationType.REGULAR, terminalWidth); } - private static String getSyntaxDiagnosticAnnotation(Document document, Location location, int terminalWidth) { - SyntaxTree syntaxTree = document.syntaxTree(); - if (location.textRange().startOffset() == location.textRange().endOffset()) { - Token searchStartToken = - ((ModulePartNode) syntaxTree.rootNode()).findToken(location.textRange().startOffset()); - if (isSyntaxErrorToken(searchStartToken, location.textRange().startOffset())) { - return searchStartToken.toString(); + private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document document, + PackageDiagnostic packageDiagnostic, + int diagnosticCode, int terminalWidth) { + TextDocument textDocument = document.textDocument(); + Location location = packageDiagnostic.location(); + int startLine = location.lineRange().startLine().line(); + int startOffset = location.lineRange().startLine().offset(); + int padding = 0; + int endLine = location.lineRange().endLine().line(); + int endOffset = location.lineRange().endLine().offset(); + // missing tokens and keywords + if (diagnosticCode < 400) { + StringDiagnosticProperty strProperty = (StringDiagnosticProperty) packageDiagnostic.properties().get(0); + String lineString = textDocument.line(startLine).text(); + String missingTokenString = "@|red " + strProperty.value() + "|@"; + if (startOffset < lineString.length() && lineString.charAt(startOffset) != ' ') { + missingTokenString = missingTokenString + " "; + } + if (startOffset > 0 && lineString.charAt(startOffset - 1) != ' ') { + missingTokenString = " " + missingTokenString; + padding++; + } + + String lineWithMissingToken = lineString.substring(0, startOffset) + missingTokenString + + lineString.substring(startOffset); + ArrayList lines = new ArrayList<>(); + lines.add(lineWithMissingToken); + return new DiagnosticAnnotation( + lines, + padding + startOffset, + strProperty.value().length(), + startLine + 1, + DiagnosticSeverity.ERROR, + DiagnosticAnnotation.DiagnosticAnnotationType.MISSING, + terminalWidth); + } + // Invalid Token + if (diagnosticCode == 600) { + ArrayList lines = getLines(textDocument, startLine, endLine); + if (lines.size() > 1) { + String annotatedLine1 = lines.get(0).substring(0, startOffset) + "@|red " + + lines.get(0).substring(startOffset) + "|@"; + String annotatedLine2 = "@|red " + lines.get(lines.size() - 1).substring(0, endOffset) + "|@" + + lines.get(lines.size() - 1).substring(endOffset); + lines.set(0, annotatedLine1); + lines.set(lines.size() - 1, annotatedLine2); + return new DiagnosticAnnotation( + lines, + startOffset, + textDocument.line(startLine).length() - location.lineRange().startLine().offset(), + endOffset, + startLine + 1, + DiagnosticSeverity.ERROR, + DiagnosticAnnotation.DiagnosticAnnotationType.INVALID, + terminalWidth); } - HashSet visited = new HashSet<>(); - return findSyntaxDiagnosticToken(searchStartToken.parent(), - location.textRange().startOffset(), visited).node().toString(); + String line = lines.get(0); + String annotatedLine = line.substring(0, startOffset) + "@|red " + + line.substring(startOffset, endOffset) + "|@" + line.substring(endOffset); + lines.set(0, annotatedLine); + return new DiagnosticAnnotation( + lines, + startOffset, + endOffset - startOffset, + startLine + 1, + DiagnosticSeverity.ERROR, + DiagnosticAnnotation.DiagnosticAnnotationType.INVALID, + terminalWidth); } - return ""; + return getDiagnosticLineFromSyntaxAPI(document, location, DiagnosticSeverity.ERROR, terminalWidth); } public static int getTerminalWidth() { diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java index 3e8b2e697c39..5c42abd49391 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java @@ -15,6 +15,7 @@ public class DiagnosticAnnotation { private final int startLineNumber; private final int terminalWidth; private final DiagnosticSeverity severity; + private final DiagnosticAnnotationType type; public static final HashMap SEVERITY_COLORS = new HashMap<>() {{ @@ -25,7 +26,13 @@ public class DiagnosticAnnotation { put(DiagnosticSeverity.ERROR, "red"); }}; - public DiagnosticAnnotation(ArrayList lines, int start, int length, int startLineNumber, DiagnosticSeverity severity, int terminalWidth) { + public enum DiagnosticAnnotationType { + REGULAR, + MISSING, + INVALID + } + + public DiagnosticAnnotation(ArrayList lines, int start, int length, int startLineNumber, DiagnosticSeverity severity, DiagnosticAnnotationType type, int terminalWidth) { this.start = start + 3 * countTabChars(lines.get(0), start); lines.set(0, replaceTabs(lines.get(0), start)); this.lines = lines; @@ -34,10 +41,11 @@ public DiagnosticAnnotation(ArrayList lines, int start, int length, int this.isMultiline = false; this.startLineNumber = startLineNumber; this.severity = severity; + this.type = type; this.terminalWidth = terminalWidth; } - public DiagnosticAnnotation(ArrayList lines, int start, int length, int endOffset, int startLineNumber, DiagnosticSeverity severity, int terminalWidth) { + public DiagnosticAnnotation(ArrayList lines, int start, int length, int endOffset, int startLineNumber, DiagnosticSeverity severity,DiagnosticAnnotationType type ,int terminalWidth) { this.start = start + 3 * countTabChars(lines.get(0), start); lines.set(0, replaceTabs(lines.get(0), start)); this.lines = lines; @@ -46,6 +54,7 @@ public DiagnosticAnnotation(ArrayList lines, int start, int length, int this.isMultiline = true; this.startLineNumber = startLineNumber; this.severity = severity; + this.type = type; this.terminalWidth = terminalWidth; } @@ -57,7 +66,7 @@ public String toString() { TruncateResult result = truncate(lines.get(0), maxLength, start, length); return padding + "| " + "\n" + String.format("%" + n_digits + "d ", startLineNumber) + "| " + result.line + "\n" - + padding + "| " + getCaretLine(result.diagnosticStart, result.diagnosticLength, this.severity) + "\n"; + + padding + "| " + getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type) + "\n"; } @@ -76,26 +85,32 @@ public String toString() { if (lines.size() == 2) { return padding + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" - + padding + "| " + getCaretLine(result1.diagnosticStart, result1.diagnosticLength, this.severity) + "\n" + + padding + "| " + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + result2.line + "\n" - + padding + "| " + getCaretLine(0, result2.diagnosticLength, this.severity) + "\n" + + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type) + "\n" + padding + "| " + "\n"; } String padding2 = " ".repeat(Math.min(terminalWidth, max_length_line) / 2); return padding + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" - + paddingWithColon + "| " + getCaretLine(result1.diagnosticStart, result1.diagnosticLength, this.severity) + "\n" + + paddingWithColon + "| " + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + "\n" + paddingWithColon + "| " + padding2 + ":" + "\n" + paddingWithColon + "| " + padding2 + ":" + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber + lines.size() - 1) + "| " + result2.line + "\n" - + padding + "| " + getCaretLine(0, result2.diagnosticLength, this.severity) + "\n" + + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type) + "\n" + padding + "| " + "\n"; } - private static String getCaretLine(int offset, int length, DiagnosticSeverity severity) { - return " ".repeat(offset) + "@|" + SEVERITY_COLORS.get(severity) + " " + "^".repeat(length) + "|@"; + private static String getUnderline(int offset, int length, DiagnosticSeverity severity, DiagnosticAnnotationType type) { + String symbol = "^"; + if (type == DiagnosticAnnotationType.MISSING) { + symbol = "+"; + } else if (type == DiagnosticAnnotationType.INVALID) { + symbol = "-"; + } + return " ".repeat(offset) + "@|" + SEVERITY_COLORS.get(severity) + " " + symbol.repeat(length) + "|@"; } private static int countTabChars(String line, int end) { diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java new file mode 100644 index 000000000000..92367f498eb1 --- /dev/null +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java @@ -0,0 +1,38 @@ +package io.ballerina.compiler.internal.diagnostics; + +import io.ballerina.tools.diagnostics.DiagnosticProperty; +import io.ballerina.tools.diagnostics.DiagnosticPropertyKind; + +import java.util.Arrays; + +public class StringDiagnosticProperty implements DiagnosticProperty { + private final DiagnosticPropertyKind kind; + private final String value; + + public StringDiagnosticProperty(String value) { + this.kind = DiagnosticPropertyKind.STRING; + this.value = value; + } + @Override + public DiagnosticPropertyKind kind() { + return kind; + } + + @Override + public String value() { + return value; + } + + @Override + public int hashCode() { + return Arrays.hashCode(new int[]{kind.hashCode(), value.hashCode()}); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof StringDiagnosticProperty prop) { + return this.value.equals(prop.value) && this.kind.equals(prop.kind); + } + return false; + } +} diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/SyntaxDiagnostic.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/SyntaxDiagnostic.java index 1ae9489efe9b..fcd1b7160337 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/SyntaxDiagnostic.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/SyntaxDiagnostic.java @@ -19,11 +19,9 @@ import io.ballerina.compiler.internal.parser.tree.STNodeDiagnostic; import io.ballerina.compiler.syntax.tree.NodeLocation; -import io.ballerina.tools.diagnostics.Diagnostic; -import io.ballerina.tools.diagnostics.DiagnosticCode; -import io.ballerina.tools.diagnostics.DiagnosticInfo; -import io.ballerina.tools.diagnostics.DiagnosticProperty; +import io.ballerina.tools.diagnostics.*; +import java.util.ArrayList; import java.util.List; /** @@ -74,7 +72,13 @@ public String message() { @Override public List> properties() { - return null; + Object[] args = this.nodeDiagnostic.args(); + List> diagArgs = new ArrayList<>(); + for (Object arg : args) { + DiagnosticProperty dArg = new StringDiagnosticProperty((String) arg); + diagArgs.add(dArg); + } + return diagArgs; } @Override diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/parser/SyntaxErrors.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/parser/SyntaxErrors.java index 16bea2db962f..18d85fd1da15 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/parser/SyntaxErrors.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/parser/SyntaxErrors.java @@ -93,7 +93,7 @@ public static STToken createMissingRegExpTokenWithDiagnostics(SyntaxKind expecte public static STToken createMissingTokenWithDiagnostics(SyntaxKind expectedKind, DiagnosticCode diagnosticCode) { List diagnosticList = new ArrayList<>(); - diagnosticList.add(createDiagnostic(diagnosticCode)); + diagnosticList.add(createDiagnostic(diagnosticCode, expectedKind.stringValue())); return STNodeFactory.createMissingToken(expectedKind, diagnosticList); } diff --git a/compiler/ballerina-parser/src/main/java/module-info.java b/compiler/ballerina-parser/src/main/java/module-info.java index 2d0455b39c5f..8b4751616496 100644 --- a/compiler/ballerina-parser/src/main/java/module-info.java +++ b/compiler/ballerina-parser/src/main/java/module-info.java @@ -2,4 +2,5 @@ requires io.ballerina.tools.api; exports io.ballerina.compiler.syntax.tree; exports io.ballerina.compiler.internal.parser.tree to io.ballerina.lang; + exports io.ballerina.compiler.internal.diagnostics; } From 05373ed68524c7e7e09c9277b4044a4e81645cd5 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Wed, 21 Feb 2024 13:55:10 +0530 Subject: [PATCH 13/55] Clean up --- .../shell/cli/AnnotateDiagnostics.java | 111 ------------------ .../shell/cli/DiagnosticAnnotation.java | 22 ++-- .../io/ballerina/cli/task/CompileTask.java | 9 +- 3 files changed, 18 insertions(+), 124 deletions(-) diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java index 85bb0aba6a93..da14ede9f2d3 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java @@ -1,41 +1,21 @@ package io.ballerina.shell.cli; import io.ballerina.compiler.internal.diagnostics.StringDiagnosticProperty; -import io.ballerina.compiler.internal.diagnostics.SyntaxDiagnostic; -import io.ballerina.compiler.syntax.tree.*; import io.ballerina.projects.Document; import io.ballerina.projects.internal.PackageDiagnostic; import io.ballerina.tools.diagnostics.Diagnostic; -import io.ballerina.tools.diagnostics.DiagnosticProperty; import io.ballerina.tools.diagnostics.DiagnosticSeverity; import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.TextDocument; -import io.ballerina.tools.text.TextDocuments; -import io.ballerina.tools.text.TextLine; -import io.ballerina.tools.text.TextRange; import org.jline.terminal.TerminalBuilder; -import org.jline.utils.AttributedStringBuilder; -import org.jline.utils.AttributedStyle; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; import static io.ballerina.shell.cli.DiagnosticAnnotation.SEVERITY_COLORS; public class AnnotateDiagnostics { - private static final Set STATEMENT_NODES = Set.of( - SyntaxKind.ASSIGNMENT_STATEMENT, - SyntaxKind.CALL_STATEMENT, - SyntaxKind.LOCAL_VAR_DECL, - SyntaxKind.RETURN_STATEMENT); - public static String renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth) { String diagnosticCode = diagnostic.diagnosticInfo().code(); @@ -175,86 +155,6 @@ public static int getTerminalWidth() { } } - private static SyntaxErrorSearchResult findSyntaxDiagnosticToken(Node curr, int position, - HashSet visited) { - if (curr instanceof Token token && isSyntaxErrorToken(curr, position)) { - return new SyntaxErrorSearchResult(token, true); - } - - if (curr instanceof NonTerminalNode nonTerminalNode) { - if (isNotWithinRange(nonTerminalNode.textRangeWithMinutiae(), position)) { - return findSyntaxDiagnosticToken(curr.parent(), position, visited); - } - - for (Node child : nonTerminalNode.children()) { - if (visited.contains(child.hashCode())) { - continue; - } - if (child instanceof NonTerminalNode && isNotWithinRange(child.textRangeWithMinutiae(), position)) { - visited.add(child.hashCode()); - continue; - } - SyntaxErrorSearchResult result = findSyntaxDiagnosticToken(child, position, visited); - if (result.found()) { - return result; - } - } - - visited.add(nonTerminalNode.hashCode()); - - return findSyntaxDiagnosticToken(curr.parent(), position, visited); - - } - - return new SyntaxErrorSearchResult(curr, false); - - } - - private static boolean isNotWithinRange(TextRange textRange, int position) { - return textRange.startOffset() > position || textRange.endOffset() < position; - } - - private static boolean isSyntaxErrorToken(Node node, int position) { - if (node instanceof Token token) { - return token.textRange().startOffset() == position && token.textRange().endOffset() == position; - } - - return false; - } - - private static NonTerminalNode climbUpToStatementNode(NonTerminalNode node, int start, int end) { - NonTerminalNode parent = node.parent(); - - if (parent == null) { - return node; - } - - if (parent.lineRange().startLine().line() < start || parent.lineRange().endLine().line() > end) { - return node; - } - -// if (STATEMENT_NODES.contains(parent.kind())) { -// return parent; -// } - return climbUpToStatementNode(parent, start, end); - } - - private static ArrayList getSiblingsOnSameRange(NonTerminalNode node, int start, int end) { - NonTerminalNode parent = node.parent(); - ArrayList siblings = new ArrayList<>(); - if (parent == null) { - siblings.add(node); - return siblings; - } - ChildNodeList childNodeList = parent.children(); - for (Node child : childNodeList) { - if (child.lineRange().startLine().line() >= start && child.lineRange().endLine().line() <= end) { - siblings.add(child); - } - } - return siblings; - } - private static ArrayList getLines(TextDocument textDocument, int start, int end) { ArrayList lines = new ArrayList<>(); for (int i = start; i <= end; i++) { @@ -263,16 +163,5 @@ private static ArrayList getLines(TextDocument textDocument, int start, return lines; } - private static String getSourceText(Path sourceFilePath) { - try { - return new String(Files.readAllBytes(sourceFilePath), StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private record SyntaxErrorSearchResult(Node node, boolean found) { - - } } diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java index 5c42abd49391..080c5b443a02 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java +++ b/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java @@ -17,7 +17,6 @@ public class DiagnosticAnnotation { private final DiagnosticSeverity severity; private final DiagnosticAnnotationType type; - public static final HashMap SEVERITY_COLORS = new HashMap<>() {{ put(DiagnosticSeverity.INTERNAL, "blue"); put(DiagnosticSeverity.HINT, "blue"); @@ -32,7 +31,8 @@ public enum DiagnosticAnnotationType { INVALID } - public DiagnosticAnnotation(ArrayList lines, int start, int length, int startLineNumber, DiagnosticSeverity severity, DiagnosticAnnotationType type, int terminalWidth) { + public DiagnosticAnnotation(ArrayList lines, int start, int length, int startLineNumber, + DiagnosticSeverity severity, DiagnosticAnnotationType type, int terminalWidth) { this.start = start + 3 * countTabChars(lines.get(0), start); lines.set(0, replaceTabs(lines.get(0), start)); this.lines = lines; @@ -45,7 +45,8 @@ public DiagnosticAnnotation(ArrayList lines, int start, int length, int this.terminalWidth = terminalWidth; } - public DiagnosticAnnotation(ArrayList lines, int start, int length, int endOffset, int startLineNumber, DiagnosticSeverity severity,DiagnosticAnnotationType type ,int terminalWidth) { + public DiagnosticAnnotation(ArrayList lines, int start, int length, int endOffset, int startLineNumber, + DiagnosticSeverity severity, DiagnosticAnnotationType type, int terminalWidth) { this.start = start + 3 * countTabChars(lines.get(0), start); lines.set(0, replaceTabs(lines.get(0), start)); this.lines = lines; @@ -66,7 +67,8 @@ public String toString() { TruncateResult result = truncate(lines.get(0), maxLength, start, length); return padding + "| " + "\n" + String.format("%" + n_digits + "d ", startLineNumber) + "| " + result.line + "\n" - + padding + "| " + getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type) + "\n"; + + padding + "| " + + getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type) + "\n"; } @@ -85,7 +87,8 @@ public String toString() { if (lines.size() == 2) { return padding + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" - + padding + "| " + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + "\n" + + padding + "| " + + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + result2.line + "\n" + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type) + "\n" + padding + "| " + "\n"; @@ -93,7 +96,8 @@ public String toString() { String padding2 = " ".repeat(Math.min(terminalWidth, max_length_line) / 2); return padding + "| " + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" - + paddingWithColon + "| " + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + "\n" + + paddingWithColon + "| " + + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + "\n" + paddingWithColon + "| " + padding2 + ":" + "\n" + paddingWithColon + "| " + padding2 + ":" + "\n" + String.format("%" + n_digits_end + "d ", startLineNumber + lines.size() - 1) + "| " @@ -103,12 +107,13 @@ public String toString() { } - private static String getUnderline(int offset, int length, DiagnosticSeverity severity, DiagnosticAnnotationType type) { + private static String getUnderline(int offset, int length, DiagnosticSeverity severity, + DiagnosticAnnotationType type) { String symbol = "^"; if (type == DiagnosticAnnotationType.MISSING) { symbol = "+"; } else if (type == DiagnosticAnnotationType.INVALID) { - symbol = "-"; + symbol = "^"; } return " ".repeat(offset) + "@|" + SEVERITY_COLORS.get(severity) + " " + symbol.repeat(length) + "|@"; } @@ -153,5 +158,6 @@ private static String replaceTabs(String line, int end) { } private record TruncateResult(String line, int diagnosticStart, int diagnosticLength) { + } } diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index 9d776c8ec9e3..8c844663bb02 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -20,7 +20,6 @@ //import io.ballerina.cli.tool.AnnotateDiagnostics2; - import io.ballerina.projects.*; import io.ballerina.shell.cli.AnnotateDiagnostics; import io.ballerina.cli.utils.BuildTime; @@ -47,7 +46,6 @@ import org.ballerinalang.central.client.CentralClientConstants; import org.wso2.ballerinalang.util.RepoUtils; - import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; @@ -61,10 +59,9 @@ import static io.ballerina.projects.util.ProjectConstants.DOT; import static io.ballerina.projects.util.ProjectConstants.TOOL_DIAGNOSTIC_CODE_PREFIX; -import org.jline.terminal.TerminalBuilder; import org.jline.jansi.AnsiConsole; -import static org.jline.jansi.Ansi.ansi; +import static org.jline.jansi.Ansi.ansi; /** * Task for compiling a package. @@ -72,6 +69,7 @@ * @since 2.0.0 */ public class CompileTask implements Task { + private final transient PrintStream out; private final transient PrintStream err; private final boolean compileForBalPack; @@ -266,7 +264,8 @@ public void execute(Project project) { if (diagnosticSet.add(d.toString())) { Document document = documentMap.get(d.location().lineRange().fileName()); if (document != null) { - err.println(ansi().render(AnnotateDiagnostics.renderDiagnostic(d, document, terminalWidth))); + err.println( + ansi().render(AnnotateDiagnostics.renderDiagnostic(d, document, terminalWidth))); } else { err.println(ansi().render(AnnotateDiagnostics.renderDiagnostic(d))); } From 837a200fe495c47c7534f85feedc90fece80cfc7 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 27 Feb 2024 11:53:36 +0530 Subject: [PATCH 14/55] Move back to ballerina-cli, show error code --- .../io/ballerina/cli/task/CompileTask.java | 40 ++++++++----------- .../cli/utils}/AnnotateDiagnostics.java | 13 +++--- .../cli/utils}/DiagnosticAnnotation.java | 2 +- 3 files changed, 24 insertions(+), 31 deletions(-) rename {ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli => cli/ballerina-cli/src/main/java/io/ballerina/cli/utils}/AnnotateDiagnostics.java (94%) rename {ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli => cli/ballerina-cli/src/main/java/io/ballerina/cli/utils}/DiagnosticAnnotation.java (99%) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index 8c844663bb02..1742c5a4e777 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -18,10 +18,8 @@ package io.ballerina.cli.task; -//import io.ballerina.cli.tool.AnnotateDiagnostics2; - import io.ballerina.projects.*; -import io.ballerina.shell.cli.AnnotateDiagnostics; +import io.ballerina.cli.utils.AnnotateDiagnostics; import io.ballerina.cli.utils.BuildTime; import io.ballerina.projects.CodeGeneratorResult; import io.ballerina.projects.CodeModifierResult; @@ -46,7 +44,6 @@ import org.ballerinalang.central.client.CentralClientConstants; import org.wso2.ballerinalang.util.RepoUtils; -import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; @@ -229,18 +226,6 @@ public void execute(Project project) { BuildTime.getInstance().codeGenDuration = System.currentTimeMillis() - start; } - // Report package compilation and backend diagnostics - diagnostics.addAll(jBallerinaBackend.diagnosticResult().diagnostics(false)); - diagnostics.forEach(d -> { - if (d.diagnosticInfo().code() == null || (!d.diagnosticInfo().code().equals( - ProjectDiagnosticErrorCode.BUILT_WITH_OLDER_SL_UPDATE_DISTRIBUTION.diagnosticId()) && - !d.diagnosticInfo().code().startsWith(TOOL_DIAGNOSTIC_CODE_PREFIX))) { - err.println(d); - } - }); - // Add tool resolution diagnostics to diagnostics - diagnostics.addAll(project.currentPackage().getBuildToolResolution().getDiagnosticList()); - boolean hasErrors = false; // HashSet to keep track of the diagnostics to avoid duplicate diagnostics HashSet diagnosticSet = new HashSet<>(); // HashMap for documents based on filename @@ -253,14 +238,13 @@ public void execute(Project project) { documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); }); }); - AnsiConsole.systemInstall(); - for (Diagnostic d : diagnostics) { - if (d.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) { - hasErrors = true; - } - if (d.diagnosticInfo().code() == null || !d.diagnosticInfo().code().equals( - ProjectDiagnosticErrorCode.BUILT_WITH_OLDER_SL_UPDATE_DISTRIBUTION.diagnosticId())) { + // Report package compilation and backend diagnostics + diagnostics.addAll(jBallerinaBackend.diagnosticResult().diagnostics(false)); + diagnostics.forEach(d -> { + if (d.diagnosticInfo().code() == null || (!d.diagnosticInfo().code().equals( + ProjectDiagnosticErrorCode.BUILT_WITH_OLDER_SL_UPDATE_DISTRIBUTION.diagnosticId()) && + !d.diagnosticInfo().code().startsWith(TOOL_DIAGNOSTIC_CODE_PREFIX))) { if (diagnosticSet.add(d.toString())) { Document document = documentMap.get(d.location().lineRange().fileName()); if (document != null) { @@ -271,8 +255,16 @@ public void execute(Project project) { } } } - } + }); AnsiConsole.systemUninstall(); + // Add tool resolution diagnostics to diagnostics + diagnostics.addAll(project.currentPackage().getBuildToolResolution().getDiagnosticList()); + boolean hasErrors = false; + for (Diagnostic d : diagnostics) { + if (d.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) { + hasErrors = true; + } + } if (hasErrors) { throw createLauncherException("compilation contains errors"); } diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java similarity index 94% rename from ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java rename to cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java index da14ede9f2d3..27103d5fb7d5 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java @@ -1,4 +1,4 @@ -package io.ballerina.shell.cli; +package io.ballerina.cli.utils; import io.ballerina.compiler.internal.diagnostics.StringDiagnosticProperty; import io.ballerina.projects.Document; @@ -12,8 +12,7 @@ import java.io.IOException; import java.util.ArrayList; -import static io.ballerina.shell.cli.DiagnosticAnnotation.SEVERITY_COLORS; - +import static io.ballerina.cli.utils.DiagnosticAnnotation.SEVERITY_COLORS; public class AnnotateDiagnostics { public static String renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth) { @@ -39,10 +38,12 @@ public static String renderDiagnostic(Diagnostic diagnostic) { private static String diagnosticToString(Diagnostic diagnostic) { DiagnosticSeverity severity = diagnostic.diagnosticInfo().severity(); - int severityLength = severity.toString().length(); - return "@|" + SEVERITY_COLORS.get(severity) + " " + severity + "|@" - + diagnostic.toString().substring(severityLength); + String severityString = severity.toString(); + String color = SEVERITY_COLORS.get(severity); + String message = diagnostic.toString().substring(severityString.length()); + String code = diagnostic.diagnosticInfo().code(); + return String.format("@|%s %s|@%s (%s)", color, severityString, message, code); } private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document document, Location location, diff --git a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java similarity index 99% rename from ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java rename to cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java index 080c5b443a02..c40b302005cc 100644 --- a/ballerina-shell/modules/shell-cli/src/main/java/io/ballerina/shell/cli/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java @@ -1,4 +1,4 @@ -package io.ballerina.shell.cli; +package io.ballerina.cli.utils; import io.ballerina.tools.diagnostics.DiagnosticSeverity; From 5cf94005b001fcb04083f28d31841ca97c96ab47 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 27 Feb 2024 13:55:50 +0530 Subject: [PATCH 15/55] Annotate errors in module tests --- .../main/java/io/ballerina/cli/task/CompileTask.java | 4 ++++ .../io/ballerina/cli/utils/AnnotateDiagnostics.java | 11 +---------- cli/ballerina-cli/src/main/java/module-info.java | 1 - 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index 1742c5a4e777..73b3730f421e 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -237,6 +237,10 @@ public void execute(Project project) { Document document = project.currentPackage().module(moduleId).document(documentId); documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); }); + project.currentPackage().module(moduleId).testDocumentIds().forEach(documentId -> { + Document document = project.currentPackage().module(moduleId).document(documentId); + documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); + }); }); AnsiConsole.systemInstall(); // Report package compilation and backend diagnostics diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java index 27103d5fb7d5..0b7e272111a6 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java @@ -7,12 +7,11 @@ import io.ballerina.tools.diagnostics.DiagnosticSeverity; import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.TextDocument; -import org.jline.terminal.TerminalBuilder; -import java.io.IOException; import java.util.ArrayList; import static io.ballerina.cli.utils.DiagnosticAnnotation.SEVERITY_COLORS; + public class AnnotateDiagnostics { public static String renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth) { @@ -148,14 +147,6 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum return getDiagnosticLineFromSyntaxAPI(document, location, DiagnosticSeverity.ERROR, terminalWidth); } - public static int getTerminalWidth() { - try (var terminal = TerminalBuilder.terminal()) { - return terminal.getWidth(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - private static ArrayList getLines(TextDocument textDocument, int start, int end) { ArrayList lines = new ArrayList<>(); for (int i = start; i <= end; i++) { diff --git a/cli/ballerina-cli/src/main/java/module-info.java b/cli/ballerina-cli/src/main/java/module-info.java index 147447bea71a..48866e6f76d6 100644 --- a/cli/ballerina-cli/src/main/java/module-info.java +++ b/cli/ballerina-cli/src/main/java/module-info.java @@ -25,5 +25,4 @@ requires io.ballerina.identifier; requires org.objectweb.asm; requires org.apache.commons.io; - requires maven.resolver; } From 5b43f9cc096f0eff541b489a992717394422a578 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 27 Feb 2024 14:22:54 +0530 Subject: [PATCH 16/55] Fix padding before colon when single digit --- .../io/ballerina/cli/utils/DiagnosticAnnotation.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java index c40b302005cc..eb8435fc7399 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java @@ -74,9 +74,15 @@ public String toString() { int max_length_line = Math.max(lines.get(0).length(), lines.get(lines.size() - 1).length()); int n_digits_end = (int) Math.log10(startLineNumber + lines.size() - 1) + 1; - String padding = " ".repeat(n_digits_end + 1); - String paddingWithColon = " :" + " ".repeat(n_digits_end - 1); - + String padding; + String paddingWithColon; + if (n_digits_end == 1) { + padding = " ".repeat(n_digits_end + 1); + paddingWithColon = ":" + " ".repeat(n_digits_end); + } else { + padding = " ".repeat(n_digits_end + 1); + paddingWithColon = " :" + " ".repeat(n_digits_end - 1); + } int tabsInLastLine = countTabChars(lines.get(lines.size() - 1), this.endOffset); lines.set(lines.size() - 1, replaceTabs(lines.get(lines.size() - 1), this.endOffset)); int maxLength = terminalWidth - n_digits_end - 3; From ea57515b3587e39611ef8650e48e7861a90877d9 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Wed, 28 Feb 2024 11:23:36 +0530 Subject: [PATCH 17/55] Add license header and class comment --- .../cli/utils/AnnotateDiagnostics.java | 21 +++++++++++++++++++ .../cli/utils/DiagnosticAnnotation.java | 21 +++++++++++++++++++ .../diagnostics/StringDiagnosticProperty.java | 21 +++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java index 0b7e272111a6..6ac21c292082 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java @@ -1,3 +1,19 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + package io.ballerina.cli.utils; import io.ballerina.compiler.internal.diagnostics.StringDiagnosticProperty; @@ -12,6 +28,11 @@ import static io.ballerina.cli.utils.DiagnosticAnnotation.SEVERITY_COLORS; +/** + * This class is used to generate diagnostic annotations from diagnostics. + * + * @since 2201.9.0 + */ public class AnnotateDiagnostics { public static String renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth) { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java index eb8435fc7399..7127a685652f 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java @@ -1,3 +1,19 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + package io.ballerina.cli.utils; import io.ballerina.tools.diagnostics.DiagnosticSeverity; @@ -5,6 +21,11 @@ import java.util.ArrayList; import java.util.HashMap; +/** + * Represents a diagnostic annotation that is used to annotate the source code with diagnostics. + * + * @since 2201.9.0 + */ public class DiagnosticAnnotation { private final ArrayList lines; diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java index 92367f498eb1..7cb1e2a8ea9a 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java @@ -1,3 +1,19 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + package io.ballerina.compiler.internal.diagnostics; import io.ballerina.tools.diagnostics.DiagnosticProperty; @@ -5,6 +21,11 @@ import java.util.Arrays; +/** + * Represents a string diagnostic property. + * + * @since 2201.9.0 + */ public class StringDiagnosticProperty implements DiagnosticProperty { private final DiagnosticPropertyKind kind; private final String value; From 3d3a6f0b7aa075ffbf50888a59ed3a734a347ccd Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Wed, 28 Feb 2024 15:29:53 +0530 Subject: [PATCH 18/55] Fix checkstyle fail and add review suggestions --- .../io/ballerina/cli/task/CompileTask.java | 35 ++-- .../cli/utils/AnnotateDiagnostics.java | 105 ++++++----- .../cli/utils/DiagnosticAnnotation.java | 165 +++++++++--------- .../diagnostics/StringDiagnosticProperty.java | 34 ++-- .../diagnostics/SyntaxDiagnostic.java | 6 +- 5 files changed, 183 insertions(+), 162 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index 73b3730f421e..d014c8efef6b 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -18,13 +18,14 @@ package io.ballerina.cli.task; -import io.ballerina.projects.*; -import io.ballerina.cli.utils.AnnotateDiagnostics; import io.ballerina.cli.utils.BuildTime; import io.ballerina.projects.CodeGeneratorResult; import io.ballerina.projects.CodeModifierResult; +import io.ballerina.projects.Document; import io.ballerina.projects.JBallerinaBackend; import io.ballerina.projects.JvmTarget; +import io.ballerina.projects.ModuleName; +import io.ballerina.projects.Package; import io.ballerina.projects.PackageCompilation; import io.ballerina.projects.PackageManifest; import io.ballerina.projects.PackageResolution; @@ -42,22 +43,23 @@ import io.ballerina.tools.diagnostics.DiagnosticInfo; import io.ballerina.tools.diagnostics.DiagnosticSeverity; import org.ballerinalang.central.client.CentralClientConstants; +import org.jline.jansi.AnsiConsole; import org.wso2.ballerinalang.util.RepoUtils; import java.io.PrintStream; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.HashSet; import static io.ballerina.cli.launcher.LauncherUtils.createLauncherException; +import static io.ballerina.cli.utils.AnnotateDiagnostics.renderDiagnostic; import static io.ballerina.projects.util.ProjectConstants.DOT; import static io.ballerina.projects.util.ProjectConstants.TOOL_DIAGNOSTIC_CODE_PREFIX; - -import org.jline.jansi.AnsiConsole; - import static org.jline.jansi.Ansi.ansi; /** @@ -227,18 +229,19 @@ public void execute(Project project) { } // HashSet to keep track of the diagnostics to avoid duplicate diagnostics - HashSet diagnosticSet = new HashSet<>(); + Set diagnosticSet = new HashSet<>(); // HashMap for documents based on filename - HashMap documentMap = new HashMap<>(); + Map documentMap = new HashMap<>(); int terminalWidth = AnsiConsole.getTerminalWidth(); - project.currentPackage().moduleIds().forEach(moduleId -> { - project.currentPackage().module(moduleId).documentIds().forEach(documentId -> { - Document document = project.currentPackage().module(moduleId).document(documentId); + Package currentPackage = project.currentPackage(); + currentPackage.moduleIds().forEach(moduleId -> { + currentPackage.module(moduleId).documentIds().forEach(documentId -> { + Document document = currentPackage.module(moduleId).document(documentId); documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); }); - project.currentPackage().module(moduleId).testDocumentIds().forEach(documentId -> { - Document document = project.currentPackage().module(moduleId).document(documentId); + currentPackage.module(moduleId).testDocumentIds().forEach(documentId -> { + Document document = currentPackage.module(moduleId).document(documentId); documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); }); }); @@ -253,9 +256,9 @@ public void execute(Project project) { Document document = documentMap.get(d.location().lineRange().fileName()); if (document != null) { err.println( - ansi().render(AnnotateDiagnostics.renderDiagnostic(d, document, terminalWidth))); + ansi().render(renderDiagnostic(d, document, terminalWidth))); } else { - err.println(ansi().render(AnnotateDiagnostics.renderDiagnostic(d))); + err.println(ansi().render(renderDiagnostic(d))); } } } @@ -282,7 +285,7 @@ private String getDocumentPath(ModuleName moduleName, String documentName) { if (moduleName.isDefaultModuleName()) { return documentName; } - return "modules" + "/" + moduleName.moduleNamePart() + "/" + documentName; + return Paths.get("modules", moduleName.moduleNamePart(), documentName).toString(); } private boolean isPackCmdForATemplatePkg(Project project) { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java index 6ac21c292082..25c545565fde 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java @@ -1,18 +1,20 @@ -// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. -// -// WSO2 LLC. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package io.ballerina.cli.utils; @@ -25,8 +27,11 @@ import io.ballerina.tools.text.TextDocument; import java.util.ArrayList; +import java.util.List; +import static io.ballerina.cli.utils.DiagnosticAnnotation.NEW_LINE; import static io.ballerina.cli.utils.DiagnosticAnnotation.SEVERITY_COLORS; +import static io.ballerina.cli.utils.DiagnosticAnnotation.getColoredString; /** * This class is used to generate diagnostic annotations from diagnostics. @@ -35,20 +40,25 @@ */ public class AnnotateDiagnostics { + private static final String COMPILER_ERROR_PREFIX = "BCE"; + private static final int SYNTAX_ERROR_CODE_THRESHOLD = 1000; + private static final int MISSING_TOKEN_KEYWORD_CODE_THRESHOLD = 400; + private static final int INVALID_TOKEN_CODE = 600; + public static String renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth) { String diagnosticCode = diagnostic.diagnosticInfo().code(); - if (diagnosticCode.startsWith("BCE")) { + if (diagnostic instanceof PackageDiagnostic && diagnosticCode.startsWith(COMPILER_ERROR_PREFIX)) { int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); - if (diagnosticCodeNumber < 1000) { + if (diagnosticCodeNumber < SYNTAX_ERROR_CODE_THRESHOLD) { PackageDiagnostic packageDiagnostic = (PackageDiagnostic) diagnostic; - return diagnosticToString(diagnostic) + "\n" + getSyntaxDiagnosticAnnotation( + return diagnosticToString(diagnostic) + NEW_LINE + getSyntaxDiagnosticAnnotation( document, packageDiagnostic, diagnosticCodeNumber, terminalWidth); } } DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( document, diagnostic.location(), diagnostic.diagnosticInfo().severity(), terminalWidth); - return diagnosticToString(diagnostic) + "\n" + diagnosticAnnotation; + return diagnosticToString(diagnostic) + NEW_LINE + diagnosticAnnotation; } @@ -62,8 +72,9 @@ private static String diagnosticToString(Diagnostic diagnostic) { String color = SEVERITY_COLORS.get(severity); String message = diagnostic.toString().substring(severityString.length()); String code = diagnostic.diagnosticInfo().code(); + String formatString = getColoredString("%s", color) + "%s (%s)"; - return String.format("@|%s %s|@%s (%s)", color, severityString, message, code); + return String.format(formatString, severityString, message, code); } private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document document, Location location, @@ -73,23 +84,15 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document docu int endOffset = location.lineRange().endLine().offset(); int startLine = location.lineRange().startLine().line(); int endLine = location.lineRange().endLine().line(); + boolean isMultiline = startLine != endLine; + int length = isMultiline ? textDocument.line(startLine).length() - startOffset : endOffset - startOffset; - if (startLine != endLine) { - return new DiagnosticAnnotation( - getLines(textDocument, startLine, endLine), - startOffset, - textDocument.line(startLine).length() - startOffset, - endOffset, - startLine + 1, - severity, - DiagnosticAnnotation.DiagnosticAnnotationType.REGULAR, - terminalWidth); - } - int length = endOffset - startOffset; return new DiagnosticAnnotation( getLines(textDocument, startLine, endLine), startOffset, length == 0 ? 1 : length, + isMultiline, + endOffset, startLine + 1, severity, DiagnosticAnnotation.DiagnosticAnnotationType.REGULAR, @@ -106,11 +109,12 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum int padding = 0; int endLine = location.lineRange().endLine().line(); int endOffset = location.lineRange().endLine().offset(); - // missing tokens and keywords - if (diagnosticCode < 400) { + String color = SEVERITY_COLORS.get(DiagnosticSeverity.ERROR); + + if (diagnosticCode < MISSING_TOKEN_KEYWORD_CODE_THRESHOLD) { StringDiagnosticProperty strProperty = (StringDiagnosticProperty) packageDiagnostic.properties().get(0); String lineString = textDocument.line(startLine).text(); - String missingTokenString = "@|red " + strProperty.value() + "|@"; + String missingTokenString = getColoredString(strProperty.value(), color); if (startOffset < lineString.length() && lineString.charAt(startOffset) != ' ') { missingTokenString = missingTokenString + " "; } @@ -121,31 +125,35 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum String lineWithMissingToken = lineString.substring(0, startOffset) + missingTokenString + lineString.substring(startOffset); - ArrayList lines = new ArrayList<>(); + List lines = new ArrayList<>(); lines.add(lineWithMissingToken); return new DiagnosticAnnotation( lines, padding + startOffset, strProperty.value().length(), + false, + 0, startLine + 1, DiagnosticSeverity.ERROR, DiagnosticAnnotation.DiagnosticAnnotationType.MISSING, terminalWidth); } - // Invalid Token - if (diagnosticCode == 600) { - ArrayList lines = getLines(textDocument, startLine, endLine); + + if (diagnosticCode == INVALID_TOKEN_CODE) { + List lines = getLines(textDocument, startLine, endLine); if (lines.size() > 1) { - String annotatedLine1 = lines.get(0).substring(0, startOffset) + "@|red " + - lines.get(0).substring(startOffset) + "|@"; - String annotatedLine2 = "@|red " + lines.get(lines.size() - 1).substring(0, endOffset) + "|@" + - lines.get(lines.size() - 1).substring(endOffset); + String annotatedLine1 = lines.get(0).substring(0, startOffset) + + getColoredString(lines.get(0).substring(startOffset), color); + String annotatedLine2 = + getColoredString(lines.get(lines.size() - 1).substring(0, endOffset), color) + + lines.get(lines.size() - 1).substring(endOffset); lines.set(0, annotatedLine1); lines.set(lines.size() - 1, annotatedLine2); return new DiagnosticAnnotation( lines, startOffset, textDocument.line(startLine).length() - location.lineRange().startLine().offset(), + true, endOffset, startLine + 1, DiagnosticSeverity.ERROR, @@ -153,13 +161,15 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum terminalWidth); } String line = lines.get(0); - String annotatedLine = line.substring(0, startOffset) + "@|red " + - line.substring(startOffset, endOffset) + "|@" + line.substring(endOffset); + String annotatedLine = line.substring(0, startOffset) + + getColoredString(line.substring(startOffset, endOffset), color) + line.substring(endOffset); lines.set(0, annotatedLine); return new DiagnosticAnnotation( lines, startOffset, endOffset - startOffset, + false, + 0, startLine + 1, DiagnosticSeverity.ERROR, DiagnosticAnnotation.DiagnosticAnnotationType.INVALID, @@ -168,8 +178,8 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum return getDiagnosticLineFromSyntaxAPI(document, location, DiagnosticSeverity.ERROR, terminalWidth); } - private static ArrayList getLines(TextDocument textDocument, int start, int end) { - ArrayList lines = new ArrayList<>(); + private static List getLines(TextDocument textDocument, int start, int end) { + List lines = new ArrayList<>(); for (int i = start; i <= end; i++) { lines.add(textDocument.line(i).text()); } @@ -177,4 +187,3 @@ private static ArrayList getLines(TextDocument textDocument, int start, } } - diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java index 7127a685652f..28c8237b6944 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java @@ -1,25 +1,27 @@ -// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. -// -// WSO2 LLC. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package io.ballerina.cli.utils; import io.ballerina.tools.diagnostics.DiagnosticSeverity; -import java.util.ArrayList; -import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Represents a diagnostic annotation that is used to annotate the source code with diagnostics. @@ -28,23 +30,16 @@ */ public class DiagnosticAnnotation { - private final ArrayList lines; - private final int start; - private final int length; - private final boolean isMultiline; - private final int endOffset; - private final int startLineNumber; - private final int terminalWidth; - private final DiagnosticSeverity severity; - private final DiagnosticAnnotationType type; + public static final String NEW_LINE = System.lineSeparator(); + public static final String JANSI_ANNOTATOR = "@|"; + public static final String JANSI_RESET = "|@"; + public static final Map SEVERITY_COLORS; - public static final HashMap SEVERITY_COLORS = new HashMap<>() {{ - put(DiagnosticSeverity.INTERNAL, "blue"); - put(DiagnosticSeverity.HINT, "blue"); - put(DiagnosticSeverity.INFO, "blue"); - put(DiagnosticSeverity.WARNING, "yellow"); - put(DiagnosticSeverity.ERROR, "red"); - }}; + static { + SEVERITY_COLORS = + Map.of(DiagnosticSeverity.INTERNAL, "blue", DiagnosticSeverity.HINT, "blue", DiagnosticSeverity.INFO, + "blue", DiagnosticSeverity.WARNING, "yellow", DiagnosticSeverity.ERROR, "red"); + } public enum DiagnosticAnnotationType { REGULAR, @@ -52,28 +47,25 @@ public enum DiagnosticAnnotationType { INVALID } - public DiagnosticAnnotation(ArrayList lines, int start, int length, int startLineNumber, - DiagnosticSeverity severity, DiagnosticAnnotationType type, int terminalWidth) { - this.start = start + 3 * countTabChars(lines.get(0), start); - lines.set(0, replaceTabs(lines.get(0), start)); - this.lines = lines; - this.length = length; - this.endOffset = 0; - this.isMultiline = false; - this.startLineNumber = startLineNumber; - this.severity = severity; - this.type = type; - this.terminalWidth = terminalWidth; - } + private final List lines; + private final int start; + private final int length; + private final boolean isMultiline; + private final int endOffset; + private final int startLineNumber; + private final int terminalWidth; + private final DiagnosticSeverity severity; + private final DiagnosticAnnotationType type; - public DiagnosticAnnotation(ArrayList lines, int start, int length, int endOffset, int startLineNumber, - DiagnosticSeverity severity, DiagnosticAnnotationType type, int terminalWidth) { + public DiagnosticAnnotation(List lines, int start, int length, boolean isMultiline, int endOffset, + int startLineNumber, DiagnosticSeverity severity, DiagnosticAnnotationType type, + int terminalWidth) { this.start = start + 3 * countTabChars(lines.get(0), start); lines.set(0, replaceTabs(lines.get(0), start)); this.lines = lines; this.length = length; this.endOffset = endOffset; - this.isMultiline = true; + this.isMultiline = isMultiline; this.startLineNumber = startLineNumber; this.severity = severity; this.type = type; @@ -82,56 +74,60 @@ public DiagnosticAnnotation(ArrayList lines, int start, int length, int public String toString() { if (!isMultiline) { - int n_digits = (int) Math.log10(startLineNumber) + 1; - String padding = " ".repeat(n_digits + 1); - int maxLength = terminalWidth - n_digits - 3; + int digitsNum = (int) Math.log10(startLineNumber) + 1; + String padding = " ".repeat(digitsNum + 1); + int maxLength = terminalWidth - digitsNum - 3; TruncateResult result = truncate(lines.get(0), maxLength, start, length); - return padding + "| " + "\n" - + String.format("%" + n_digits + "d ", startLineNumber) + "| " + result.line + "\n" + return padding + "| " + NEW_LINE + + String.format("%" + digitsNum + "d ", startLineNumber) + "| " + result.line + NEW_LINE + padding + "| " + - getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type) + "\n"; + getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type) + NEW_LINE; } - int max_length_line = Math.max(lines.get(0).length(), lines.get(lines.size() - 1).length()); - int n_digits_end = (int) Math.log10(startLineNumber + lines.size() - 1) + 1; + int maxLineLength = Math.max(lines.get(0).length(), lines.get(lines.size() - 1).length()); + int endDigitsNum = (int) Math.log10(startLineNumber + lines.size() - 1) + 1; String padding; String paddingWithColon; - if (n_digits_end == 1) { - padding = " ".repeat(n_digits_end + 1); - paddingWithColon = ":" + " ".repeat(n_digits_end); + if (endDigitsNum == 1) { + padding = " ".repeat(endDigitsNum + 1); + paddingWithColon = ":" + " ".repeat(endDigitsNum); } else { - padding = " ".repeat(n_digits_end + 1); - paddingWithColon = " :" + " ".repeat(n_digits_end - 1); + padding = " ".repeat(endDigitsNum + 1); + paddingWithColon = " :" + " ".repeat(endDigitsNum - 1); } int tabsInLastLine = countTabChars(lines.get(lines.size() - 1), this.endOffset); lines.set(lines.size() - 1, replaceTabs(lines.get(lines.size() - 1), this.endOffset)); - int maxLength = terminalWidth - n_digits_end - 3; + int maxLength = terminalWidth - endDigitsNum - 3; TruncateResult result1 = truncate(lines.get(0), maxLength, start, length); TruncateResult result2 = truncate(lines.get(lines.size() - 1), maxLength, 0, endOffset + 3 * tabsInLastLine); if (lines.size() == 2) { - return padding + "| " + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" + return padding + "| " + NEW_LINE + + String.format("%" + endDigitsNum + "d ", startLineNumber) + "| " + result1.line + NEW_LINE + padding + "| " + - getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber + 1) + "| " + result2.line + "\n" - + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type) + "\n" - + padding + "| " + "\n"; + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + NEW_LINE + + String.format("%" + endDigitsNum + "d ", startLineNumber + 1) + "| " + result2.line + NEW_LINE + + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type) + NEW_LINE + + padding + "| " + NEW_LINE; } - String padding2 = " ".repeat(Math.min(terminalWidth, max_length_line) / 2); - return padding + "| " + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber) + "| " + result1.line + "\n" + String padding2 = " ".repeat(Math.min(terminalWidth, maxLineLength) / 2); + return padding + "| " + NEW_LINE + + String.format("%" + endDigitsNum + "d ", startLineNumber) + "| " + result1.line + NEW_LINE + paddingWithColon + "| " + - getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + "\n" - + paddingWithColon + "| " + padding2 + ":" + "\n" - + paddingWithColon + "| " + padding2 + ":" + "\n" - + String.format("%" + n_digits_end + "d ", startLineNumber + lines.size() - 1) + "| " - + result2.line + "\n" - + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type) + "\n" - + padding + "| " + "\n"; + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + NEW_LINE + + paddingWithColon + "| " + padding2 + ":" + NEW_LINE + + paddingWithColon + "| " + padding2 + ":" + NEW_LINE + + String.format("%" + endDigitsNum + "d ", startLineNumber + lines.size() - 1) + "| " + + result2.line + NEW_LINE + + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type) + NEW_LINE + + padding + "| " + NEW_LINE; + + } + public static String getColoredString(String message, String color) { + return JANSI_ANNOTATOR + color + " " + message + JANSI_RESET; } private static String getUnderline(int offset, int length, DiagnosticSeverity severity, @@ -139,10 +135,8 @@ private static String getUnderline(int offset, int length, DiagnosticSeverity se String symbol = "^"; if (type == DiagnosticAnnotationType.MISSING) { symbol = "+"; - } else if (type == DiagnosticAnnotationType.INVALID) { - symbol = "^"; } - return " ".repeat(offset) + "@|" + SEVERITY_COLORS.get(severity) + " " + symbol.repeat(length) + "|@"; + return " ".repeat(offset) + getColoredString(symbol.repeat(length), SEVERITY_COLORS.get(severity)); } private static int countTabChars(String line, int end) { @@ -184,6 +178,13 @@ private static String replaceTabs(String line, int end) { return sb + line.substring(end); } + /** + * Represents a result of truncating a line. + * + * @param line The truncated line + * @param diagnosticStart The start of the diagnostic in the truncated line + * @param diagnosticLength The length of the diagnostic in the truncated line + */ private record TruncateResult(String line, int diagnosticStart, int diagnosticLength) { } diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java index 7cb1e2a8ea9a..1ec0727a85b0 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java @@ -1,18 +1,20 @@ -// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. -// -// WSO2 LLC. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package io.ballerina.compiler.internal.diagnostics; @@ -27,6 +29,7 @@ * @since 2201.9.0 */ public class StringDiagnosticProperty implements DiagnosticProperty { + private final DiagnosticPropertyKind kind; private final String value; @@ -34,6 +37,7 @@ public StringDiagnosticProperty(String value) { this.kind = DiagnosticPropertyKind.STRING; this.value = value; } + @Override public DiagnosticPropertyKind kind() { return kind; diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/SyntaxDiagnostic.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/SyntaxDiagnostic.java index fcd1b7160337..ac75ed6bf8e8 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/SyntaxDiagnostic.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/SyntaxDiagnostic.java @@ -19,7 +19,10 @@ import io.ballerina.compiler.internal.parser.tree.STNodeDiagnostic; import io.ballerina.compiler.syntax.tree.NodeLocation; -import io.ballerina.tools.diagnostics.*; +import io.ballerina.tools.diagnostics.Diagnostic; +import io.ballerina.tools.diagnostics.DiagnosticCode; +import io.ballerina.tools.diagnostics.DiagnosticInfo; +import io.ballerina.tools.diagnostics.DiagnosticProperty; import java.util.ArrayList; import java.util.List; @@ -30,6 +33,7 @@ * @since 2.0.0 */ public class SyntaxDiagnostic extends Diagnostic { + private final STNodeDiagnostic nodeDiagnostic; private final NodeLocation location; private DiagnosticInfo diagnosticInfo; From ec2b32896cc458bfdc2f345f441a49dc065bece0 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Sun, 3 Mar 2024 11:58:34 +0530 Subject: [PATCH 19/55] Update jline version for test compatibility jline 3.25.1 which is the latest at time of writing, breaks most of our test cases related ballerina shell. After testing around it seems that this is caused by the dumbterminal. Even though tests failed the bal shell command seems to work as usual. There is no mention of this issue on jline's issues and I was not able to reproduce it in a sample java project. The version bump I needed to access jansi from within jline happened in jline 3.25.0, therefore instead of 3.25.1 I changed it back to 3.25.0 until we find a way to change our test cases or jline's future updates. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index c2657a1d8e74..ee34c9b80df3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -92,7 +92,7 @@ jetbrainsKotlinStdlibVersion=1.6.0 jetbrainsKotlinStdlibCommonVersion=1.6.0 junitVersion=4.13.2 jknackHandlebarsVersion=4.0.6 -jlineVersion=3.25.1 +jlineVersion=3.25.0 jvnetMimepullVersion=1.9.11 kaitaiGradlePluginVersion=0.1.1 kaitaiStructRuntimeVersion=0.9 From 163df5f45130c472d5f0bd9a7f922ba07219870a Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Sun, 3 Mar 2024 15:59:08 +0530 Subject: [PATCH 20/55] Move usage of jansi to AnnotateDiagnostics class --- .../io/ballerina/cli/task/CompileTask.java | 13 ++++--------- .../cli/utils/AnnotateDiagnostics.java | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index d014c8efef6b..37e99c453362 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -18,6 +18,7 @@ package io.ballerina.cli.task; +import io.ballerina.cli.utils.AnnotateDiagnostics; import io.ballerina.cli.utils.BuildTime; import io.ballerina.projects.CodeGeneratorResult; import io.ballerina.projects.CodeModifierResult; @@ -43,7 +44,6 @@ import io.ballerina.tools.diagnostics.DiagnosticInfo; import io.ballerina.tools.diagnostics.DiagnosticSeverity; import org.ballerinalang.central.client.CentralClientConstants; -import org.jline.jansi.AnsiConsole; import org.wso2.ballerinalang.util.RepoUtils; import java.io.PrintStream; @@ -57,10 +57,8 @@ import java.util.Set; import static io.ballerina.cli.launcher.LauncherUtils.createLauncherException; -import static io.ballerina.cli.utils.AnnotateDiagnostics.renderDiagnostic; import static io.ballerina.projects.util.ProjectConstants.DOT; import static io.ballerina.projects.util.ProjectConstants.TOOL_DIAGNOSTIC_CODE_PREFIX; -import static org.jline.jansi.Ansi.ansi; /** * Task for compiling a package. @@ -232,7 +230,7 @@ public void execute(Project project) { Set diagnosticSet = new HashSet<>(); // HashMap for documents based on filename Map documentMap = new HashMap<>(); - int terminalWidth = AnsiConsole.getTerminalWidth(); + int terminalWidth = AnnotateDiagnostics.getTerminalWidth(); Package currentPackage = project.currentPackage(); currentPackage.moduleIds().forEach(moduleId -> { @@ -245,7 +243,6 @@ public void execute(Project project) { documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); }); }); - AnsiConsole.systemInstall(); // Report package compilation and backend diagnostics diagnostics.addAll(jBallerinaBackend.diagnosticResult().diagnostics(false)); diagnostics.forEach(d -> { @@ -255,15 +252,13 @@ public void execute(Project project) { if (diagnosticSet.add(d.toString())) { Document document = documentMap.get(d.location().lineRange().fileName()); if (document != null) { - err.println( - ansi().render(renderDiagnostic(d, document, terminalWidth))); + err.println(AnnotateDiagnostics.renderDiagnostic(d, document, terminalWidth)); } else { - err.println(ansi().render(renderDiagnostic(d))); + err.println(AnnotateDiagnostics.renderDiagnostic(d)); } } } }); - AnsiConsole.systemUninstall(); // Add tool resolution diagnostics to diagnostics diagnostics.addAll(project.currentPackage().getBuildToolResolution().getDiagnosticList()); boolean hasErrors = false; diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java index 25c545565fde..9984f804190f 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java @@ -25,6 +25,8 @@ import io.ballerina.tools.diagnostics.DiagnosticSeverity; import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.TextDocument; +import org.jline.jansi.Ansi; +import org.jline.jansi.AnsiConsole; import java.util.ArrayList; import java.util.List; @@ -45,25 +47,29 @@ public class AnnotateDiagnostics { private static final int MISSING_TOKEN_KEYWORD_CODE_THRESHOLD = 400; private static final int INVALID_TOKEN_CODE = 600; - public static String renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth) { + public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth) { String diagnosticCode = diagnostic.diagnosticInfo().code(); if (diagnostic instanceof PackageDiagnostic && diagnosticCode.startsWith(COMPILER_ERROR_PREFIX)) { int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); if (diagnosticCodeNumber < SYNTAX_ERROR_CODE_THRESHOLD) { PackageDiagnostic packageDiagnostic = (PackageDiagnostic) diagnostic; - return diagnosticToString(diagnostic) + NEW_LINE + getSyntaxDiagnosticAnnotation( - document, packageDiagnostic, diagnosticCodeNumber, terminalWidth); + return Ansi.ansi().render(diagnosticToString(diagnostic) + NEW_LINE + getSyntaxDiagnosticAnnotation( + document, packageDiagnostic, diagnosticCodeNumber, terminalWidth)); } } DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( document, diagnostic.location(), diagnostic.diagnosticInfo().severity(), terminalWidth); - return diagnosticToString(diagnostic) + NEW_LINE + diagnosticAnnotation; + return Ansi.ansi().render(diagnosticToString(diagnostic) + NEW_LINE + diagnosticAnnotation); } - public static String renderDiagnostic(Diagnostic diagnostic) { - return diagnosticToString(diagnostic); + public static int getTerminalWidth() { + return AnsiConsole.getTerminalWidth(); + } + + public static Ansi renderDiagnostic(Diagnostic diagnostic) { + return Ansi.ansi().render(diagnosticToString(diagnostic)); } private static String diagnosticToString(Diagnostic diagnostic) { From e3dfaafea013a83b755f647714c3dd9de8a75cc9 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Sun, 3 Mar 2024 20:25:19 +0530 Subject: [PATCH 21/55] Add option to disable color for tests --- .../io/ballerina/cli/task/CompileTask.java | 6 ++- .../cli/utils/AnnotateDiagnostics.java | 46 +++++++++++-------- .../cli/utils/DiagnosticAnnotation.java | 38 +++++++++------ .../command-outputs/unix/run-bal.txt | 8 +++- .../command-outputs/windows/run-bal.txt | 8 +++- 5 files changed, 65 insertions(+), 41 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index 37e99c453362..cec7de2aa6d0 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -231,6 +231,7 @@ public void execute(Project project) { // HashMap for documents based on filename Map documentMap = new HashMap<>(); int terminalWidth = AnnotateDiagnostics.getTerminalWidth(); + boolean colorEnabled = terminalWidth != 0; Package currentPackage = project.currentPackage(); currentPackage.moduleIds().forEach(moduleId -> { @@ -252,9 +253,10 @@ public void execute(Project project) { if (diagnosticSet.add(d.toString())) { Document document = documentMap.get(d.location().lineRange().fileName()); if (document != null) { - err.println(AnnotateDiagnostics.renderDiagnostic(d, document, terminalWidth)); + err.println(AnnotateDiagnostics.renderDiagnostic(d, document, + terminalWidth == 0 ? 999 : terminalWidth, colorEnabled)); } else { - err.println(AnnotateDiagnostics.renderDiagnostic(d)); + err.println(AnnotateDiagnostics.renderDiagnostic(d, colorEnabled)); } } } diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java index 9984f804190f..918197cb6722 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java @@ -47,20 +47,22 @@ public class AnnotateDiagnostics { private static final int MISSING_TOKEN_KEYWORD_CODE_THRESHOLD = 400; private static final int INVALID_TOKEN_CODE = 600; - public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth) { + public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth, + boolean colorEnabled) { String diagnosticCode = diagnostic.diagnosticInfo().code(); if (diagnostic instanceof PackageDiagnostic && diagnosticCode.startsWith(COMPILER_ERROR_PREFIX)) { int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); if (diagnosticCodeNumber < SYNTAX_ERROR_CODE_THRESHOLD) { PackageDiagnostic packageDiagnostic = (PackageDiagnostic) diagnostic; - return Ansi.ansi().render(diagnosticToString(diagnostic) + NEW_LINE + getSyntaxDiagnosticAnnotation( - document, packageDiagnostic, diagnosticCodeNumber, terminalWidth)); + return Ansi.ansi() + .render(diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + getSyntaxDiagnosticAnnotation( + document, packageDiagnostic, diagnosticCodeNumber, terminalWidth, colorEnabled)); } } DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( - document, diagnostic.location(), diagnostic.diagnosticInfo().severity(), terminalWidth); - return Ansi.ansi().render(diagnosticToString(diagnostic) + NEW_LINE + diagnosticAnnotation); + document, diagnostic.location(), diagnostic.diagnosticInfo().severity(), terminalWidth, colorEnabled); + return Ansi.ansi().render(diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + diagnosticAnnotation); } @@ -68,23 +70,24 @@ public static int getTerminalWidth() { return AnsiConsole.getTerminalWidth(); } - public static Ansi renderDiagnostic(Diagnostic diagnostic) { - return Ansi.ansi().render(diagnosticToString(diagnostic)); + public static Ansi renderDiagnostic(Diagnostic diagnostic, boolean colorEnabled) { + return Ansi.ansi().render(diagnosticToString(diagnostic, colorEnabled)); } - private static String diagnosticToString(Diagnostic diagnostic) { + private static String diagnosticToString(Diagnostic diagnostic, boolean colorEnabled) { DiagnosticSeverity severity = diagnostic.diagnosticInfo().severity(); String severityString = severity.toString(); String color = SEVERITY_COLORS.get(severity); String message = diagnostic.toString().substring(severityString.length()); String code = diagnostic.diagnosticInfo().code(); - String formatString = getColoredString("%s", color) + "%s (%s)"; + String formatString = getColoredString("%s", color, colorEnabled) + "%s (%s)"; return String.format(formatString, severityString, message, code); } private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document document, Location location, - DiagnosticSeverity severity, int terminalWidth) { + DiagnosticSeverity severity, int terminalWidth, + boolean colorEnabled) { TextDocument textDocument = document.textDocument(); int startOffset = location.lineRange().startLine().offset(); int endOffset = location.lineRange().endLine().offset(); @@ -102,12 +105,13 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document docu startLine + 1, severity, DiagnosticAnnotation.DiagnosticAnnotationType.REGULAR, - terminalWidth); + terminalWidth, colorEnabled); } private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document document, PackageDiagnostic packageDiagnostic, - int diagnosticCode, int terminalWidth) { + int diagnosticCode, int terminalWidth, + boolean colorEnabled) { TextDocument textDocument = document.textDocument(); Location location = packageDiagnostic.location(); int startLine = location.lineRange().startLine().line(); @@ -120,7 +124,7 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum if (diagnosticCode < MISSING_TOKEN_KEYWORD_CODE_THRESHOLD) { StringDiagnosticProperty strProperty = (StringDiagnosticProperty) packageDiagnostic.properties().get(0); String lineString = textDocument.line(startLine).text(); - String missingTokenString = getColoredString(strProperty.value(), color); + String missingTokenString = getColoredString(strProperty.value(), color, colorEnabled); if (startOffset < lineString.length() && lineString.charAt(startOffset) != ' ') { missingTokenString = missingTokenString + " "; } @@ -142,16 +146,16 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum startLine + 1, DiagnosticSeverity.ERROR, DiagnosticAnnotation.DiagnosticAnnotationType.MISSING, - terminalWidth); + terminalWidth, colorEnabled); } if (diagnosticCode == INVALID_TOKEN_CODE) { List lines = getLines(textDocument, startLine, endLine); if (lines.size() > 1) { String annotatedLine1 = lines.get(0).substring(0, startOffset) + - getColoredString(lines.get(0).substring(startOffset), color); + getColoredString(lines.get(0).substring(startOffset), color, colorEnabled); String annotatedLine2 = - getColoredString(lines.get(lines.size() - 1).substring(0, endOffset), color) + + getColoredString(lines.get(lines.size() - 1).substring(0, endOffset), color, colorEnabled) + lines.get(lines.size() - 1).substring(endOffset); lines.set(0, annotatedLine1); lines.set(lines.size() - 1, annotatedLine2); @@ -164,11 +168,12 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum startLine + 1, DiagnosticSeverity.ERROR, DiagnosticAnnotation.DiagnosticAnnotationType.INVALID, - terminalWidth); + terminalWidth, colorEnabled); } String line = lines.get(0); String annotatedLine = line.substring(0, startOffset) + - getColoredString(line.substring(startOffset, endOffset), color) + line.substring(endOffset); + getColoredString(line.substring(startOffset, endOffset), color, colorEnabled) + + line.substring(endOffset); lines.set(0, annotatedLine); return new DiagnosticAnnotation( lines, @@ -179,9 +184,10 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum startLine + 1, DiagnosticSeverity.ERROR, DiagnosticAnnotation.DiagnosticAnnotationType.INVALID, - terminalWidth); + terminalWidth, colorEnabled); } - return getDiagnosticLineFromSyntaxAPI(document, location, DiagnosticSeverity.ERROR, terminalWidth); + return getDiagnosticLineFromSyntaxAPI(document, location, DiagnosticSeverity.ERROR, terminalWidth, + colorEnabled); } private static List getLines(TextDocument textDocument, int start, int end) { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java index 28c8237b6944..79d13702209a 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java @@ -56,10 +56,11 @@ public enum DiagnosticAnnotationType { private final int terminalWidth; private final DiagnosticSeverity severity; private final DiagnosticAnnotationType type; + private final boolean colorEnabled; public DiagnosticAnnotation(List lines, int start, int length, boolean isMultiline, int endOffset, int startLineNumber, DiagnosticSeverity severity, DiagnosticAnnotationType type, - int terminalWidth) { + int terminalWidth, boolean colorEnabled) { this.start = start + 3 * countTabChars(lines.get(0), start); lines.set(0, replaceTabs(lines.get(0), start)); this.lines = lines; @@ -70,6 +71,7 @@ public DiagnosticAnnotation(List lines, int start, int length, boolean i this.severity = severity; this.type = type; this.terminalWidth = terminalWidth; + this.colorEnabled = colorEnabled; } public String toString() { @@ -78,10 +80,11 @@ public String toString() { String padding = " ".repeat(digitsNum + 1); int maxLength = terminalWidth - digitsNum - 3; TruncateResult result = truncate(lines.get(0), maxLength, start, length); - return padding + "| " + NEW_LINE + return padding + "|" + NEW_LINE + String.format("%" + digitsNum + "d ", startLineNumber) + "| " + result.line + NEW_LINE + padding + "| " + - getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type) + NEW_LINE; + getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type, + colorEnabled) + NEW_LINE; } @@ -104,39 +107,44 @@ public String toString() { endOffset + 3 * tabsInLastLine); if (lines.size() == 2) { - return padding + "| " + NEW_LINE + return padding + "|" + NEW_LINE + String.format("%" + endDigitsNum + "d ", startLineNumber) + "| " + result1.line + NEW_LINE + padding + "| " + - getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + NEW_LINE + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type, + colorEnabled) + NEW_LINE + String.format("%" + endDigitsNum + "d ", startLineNumber + 1) + "| " + result2.line + NEW_LINE - + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type) + NEW_LINE - + padding + "| " + NEW_LINE; + + padding + "| " + + getUnderline(0, result2.diagnosticLength, this.severity, this.type, colorEnabled) + NEW_LINE + + padding + "|" + NEW_LINE; } String padding2 = " ".repeat(Math.min(terminalWidth, maxLineLength) / 2); - return padding + "| " + NEW_LINE + return padding + "|" + NEW_LINE + String.format("%" + endDigitsNum + "d ", startLineNumber) + "| " + result1.line + NEW_LINE + paddingWithColon + "| " + - getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type) + NEW_LINE + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type, + colorEnabled) + NEW_LINE + paddingWithColon + "| " + padding2 + ":" + NEW_LINE + paddingWithColon + "| " + padding2 + ":" + NEW_LINE + String.format("%" + endDigitsNum + "d ", startLineNumber + lines.size() - 1) + "| " + result2.line + NEW_LINE - + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type) + NEW_LINE - + padding + "| " + NEW_LINE; + + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type, colorEnabled) + + NEW_LINE + + padding + "|" + NEW_LINE; } - public static String getColoredString(String message, String color) { - return JANSI_ANNOTATOR + color + " " + message + JANSI_RESET; + public static String getColoredString(String message, String color, boolean colorEnabled) { + return colorEnabled ? JANSI_ANNOTATOR + color + " " + message + JANSI_RESET : message; } private static String getUnderline(int offset, int length, DiagnosticSeverity severity, - DiagnosticAnnotationType type) { + DiagnosticAnnotationType type, boolean colorEnabled) { String symbol = "^"; if (type == DiagnosticAnnotationType.MISSING) { symbol = "+"; } - return " ".repeat(offset) + getColoredString(symbol.repeat(length), SEVERITY_COLORS.get(severity)); + return " ".repeat(offset) + + getColoredString(symbol.repeat(length), SEVERITY_COLORS.get(severity), colorEnabled); } private static int countTabChars(String line, int end) { diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/run-bal.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/run-bal.txt index 7418db727411..7298e53ca9ca 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/run-bal.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/run-bal.txt @@ -1,7 +1,11 @@ Compiling source file_create.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files -WARNING [file_create.bal:(6:4,6:58)] unused variable 'isSuccess' +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) +WARNING [file_create.bal:(6:4,6:58)] unused variable 'isSuccess' (BCE20403) + | +6 | boolean|error isSuccess = createNewFileInternal(file); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running executable diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/run-bal.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/run-bal.txt index 7418db727411..7298e53ca9ca 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/run-bal.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/run-bal.txt @@ -1,7 +1,11 @@ Compiling source file_create.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files -WARNING [file_create.bal:(6:4,6:58)] unused variable 'isSuccess' +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) +WARNING [file_create.bal:(6:4,6:58)] unused variable 'isSuccess' (BCE20403) + | +6 | boolean|error isSuccess = createNewFileInternal(file); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running executable From 8eb0560c889cee1d7bd7b679faf7c94fa2cb8f14 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Mon, 4 Mar 2024 11:18:48 +0530 Subject: [PATCH 22/55] Update ballerina-cli tests for new diagnostics --- .../java/io/ballerina/cli/utils/AnnotateDiagnostics.java | 3 ++- .../unix/build-bal-with-absolute-jar-path.txt | 2 +- .../test-resources/command-outputs/unix/build-bar-bal.txt | 2 +- .../test-resources/command-outputs/unix/build-foo-bal.txt | 2 +- .../unix/build-hello-world-bal-with-build-options.txt | 2 +- .../command-outputs/unix/build-hello-world-bal.txt | 2 +- .../unix/build-project-with-empty-ballerina-toml.txt | 1 + .../command-outputs/unix/build-syntax-err-bal.txt | 8 ++++++-- .../command-outputs/unix/build-syntax-err-package.txt | 6 +++++- .../command-outputs/unix/dump-build-time-standalone.txt | 2 +- .../windows/build-bal-with-absolute-jar-path.txt | 2 +- .../command-outputs/windows/build-bar-bal.txt | 2 +- .../command-outputs/windows/build-foo-bal.txt | 2 +- .../windows/build-hello-world-bal-with-build-options.txt | 2 +- .../command-outputs/windows/build-hello-world-bal.txt | 2 +- .../windows/build-project-with-empty-ballerina-toml.txt | 1 + .../command-outputs/windows/build-syntax-err-bal.txt | 8 ++++++-- .../command-outputs/windows/build-syntax-err-package.txt | 6 +++++- .../windows/dump-build-time-standalone.txt | 2 +- 19 files changed, 38 insertions(+), 19 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java index 918197cb6722..919e14174641 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java @@ -80,7 +80,8 @@ private static String diagnosticToString(Diagnostic diagnostic, boolean colorEna String color = SEVERITY_COLORS.get(severity); String message = diagnostic.toString().substring(severityString.length()); String code = diagnostic.diagnosticInfo().code(); - String formatString = getColoredString("%s", color, colorEnabled) + "%s (%s)"; + boolean isMultiline = diagnostic.message().contains("\n"); + String formatString = getColoredString("%s", color, colorEnabled) + "%s" + (isMultiline ? "\n(%s)" : " (%s)"); return String.format(formatString, severityString, message, code); } diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-bal-with-absolute-jar-path.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-bal-with-absolute-jar-path.txt index 10f97cb46a11..2c2de9e12b96 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-bal-with-absolute-jar-path.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-bal-with-absolute-jar-path.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-bar-bal.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-bar-bal.txt index 55fbccbf4a4a..4e90569f1e79 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-bar-bal.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-bar-bal.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable bar.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-foo-bal.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-foo-bal.txt index 076d9df06c38..243a73fc432e 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-foo-bal.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-foo-bal.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable foo.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-hello-world-bal-with-build-options.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-hello-world-bal-with-build-options.txt index bf62e658690d..99fdcb2cdb49 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-hello-world-bal-with-build-options.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-hello-world-bal-with-build-options.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable hello_world.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-hello-world-bal.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-hello-world-bal.txt index bf62e658690d..99fdcb2cdb49 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-hello-world-bal.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-hello-world-bal.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable hello_world.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-with-empty-ballerina-toml.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-with-empty-ballerina-toml.txt index ed846965f54f..b91445c7aa0b 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-with-empty-ballerina-toml.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-with-empty-ballerina-toml.txt @@ -5,6 +5,7 @@ WARNING [Ballerina.toml:(1:1,1:1)] missing table '[package]' in 'Ballerina.toml' org = "john" name = "validProjectWithEmptyBallerinaToml" version = "0.1.0" +(BCE5001) Generating executable target/bin/validProjectWithEmptyBallerinaToml.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-syntax-err-bal.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-syntax-err-bal.txt index 242b9d8033e4..f0098abf2f41 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-syntax-err-bal.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-syntax-err-bal.txt @@ -1,4 +1,8 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files -ERROR [hello_world.bal:(2:3,2:4)] invalid token ';' +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) +ERROR [hello_world.bal:(2:3,2:4)] invalid token ';' (BCE0600) + | +2 | };; + | ^ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-syntax-err-package.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-syntax-err-package.txt index 748e446c1e67..a69eff61ff8b 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-syntax-err-package.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-syntax-err-package.txt @@ -1,3 +1,7 @@ Compiling source foo/winery:0.1.0 -ERROR [hello_world.bal:(2:3,2:4)] invalid token ';' +ERROR [hello_world.bal:(2:3,2:4)] invalid token ';' (BCE0600) + | +2 | };; + | ^ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/dump-build-time-standalone.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/dump-build-time-standalone.txt index 2c5b1c6c542c..8d71bbfcda15 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/dump-build-time-standalone.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/dump-build-time-standalone.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable hello_world.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-bal-with-absolute-jar-path.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-bal-with-absolute-jar-path.txt index 10f97cb46a11..2c2de9e12b96 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-bal-with-absolute-jar-path.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-bal-with-absolute-jar-path.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-bar-bal.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-bar-bal.txt index 55fbccbf4a4a..4e90569f1e79 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-bar-bal.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-bar-bal.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable bar.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-foo-bal.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-foo-bal.txt index 076d9df06c38..243a73fc432e 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-foo-bal.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-foo-bal.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable foo.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-hello-world-bal-with-build-options.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-hello-world-bal-with-build-options.txt index bf62e658690d..99fdcb2cdb49 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-hello-world-bal-with-build-options.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-hello-world-bal-with-build-options.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable hello_world.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-hello-world-bal.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-hello-world-bal.txt index bf62e658690d..99fdcb2cdb49 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-hello-world-bal.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-hello-world-bal.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable hello_world.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-with-empty-ballerina-toml.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-with-empty-ballerina-toml.txt index 944bda503633..2eb7ac0fbc21 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-with-empty-ballerina-toml.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-with-empty-ballerina-toml.txt @@ -5,6 +5,7 @@ WARNING [Ballerina.toml:(1:1,1:1)] missing table '[package]' in 'Ballerina.toml' org = "john" name = "validProjectWithEmptyBallerinaToml" version = "0.1.0" +(BCE5001) Generating executable target\bin\validProjectWithEmptyBallerinaToml.jar diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-syntax-err-bal.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-syntax-err-bal.txt index 242b9d8033e4..f0098abf2f41 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-syntax-err-bal.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-syntax-err-bal.txt @@ -1,4 +1,8 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files -ERROR [hello_world.bal:(2:3,2:4)] invalid token ';' +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) +ERROR [hello_world.bal:(2:3,2:4)] invalid token ';' (BCE0600) + | +2 | };; + | ^ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-syntax-err-package.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-syntax-err-package.txt index 748e446c1e67..a69eff61ff8b 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-syntax-err-package.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-syntax-err-package.txt @@ -1,3 +1,7 @@ Compiling source foo/winery:0.1.0 -ERROR [hello_world.bal:(2:3,2:4)] invalid token ';' +ERROR [hello_world.bal:(2:3,2:4)] invalid token ';' (BCE0600) + | +2 | };; + | ^ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/dump-build-time-standalone.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/dump-build-time-standalone.txt index 2c5b1c6c542c..8d71bbfcda15 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/dump-build-time-standalone.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/dump-build-time-standalone.txt @@ -1,6 +1,6 @@ Compiling source hello_world.bal -WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files +WARNING [:(1:1,1:1)] Skipped adding the generated source file with prefix "dummyfunc". Source file generation is not supported with standalone bal files (BCE5401) Generating executable hello_world.jar From c6d4865c1b9f8a3dfaa32a1b2625d40a395d3b04 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 5 Mar 2024 09:23:56 +0530 Subject: [PATCH 23/55] Fix to pass jballerina-integration-test --- .../java/io/ballerina/cli/utils/AnnotateDiagnostics.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java index 919e14174641..50204efab8bf 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java @@ -26,8 +26,9 @@ import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.TextDocument; import org.jline.jansi.Ansi; -import org.jline.jansi.AnsiConsole; +import org.jline.terminal.TerminalBuilder; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -67,7 +68,11 @@ public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, in } public static int getTerminalWidth() { - return AnsiConsole.getTerminalWidth(); + try { + return TerminalBuilder.builder().dumb(true).build().getWidth(); + } catch (IOException e) { + return 999; + } } public static Ansi renderDiagnostic(Diagnostic diagnostic, boolean colorEnabled) { From 710f66d40c5ff07a7350e77f4b97ecd0898e51c3 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 5 Mar 2024 13:04:40 +0530 Subject: [PATCH 24/55] Update testerina-tests for new diagnostics --- .../cli/utils/AnnotateDiagnostics.java | 10 +- .../BasicCasesTest-testAnnotationAccess.txt | 6 +- ...sicCasesTest-testAssertBehavioralTypes.txt | 18 +- .../BasicCasesTest-testAssertDiffError.txt | 18 +- ...sicCasesTest-testAssertStructuralTypes.txt | 18 +- ...sicCasesTest-testAssertionErrorMessage.txt | 18 +- ...iderTest-testArrayDataProviderWithFail.txt | 12 +- ...viderTest-testArrayDataRerunFailedTest.txt | 12 +- ...DataProviderTest-testCodeFragmentKeys0.txt | 12 +- ...DataProviderTest-testCodeFragmentKeys1.txt | 12 +- ...DataProviderTest-testCodeFragmentKeys2.txt | 12 +- ...DataProviderTest-testCodeFragmentKeys3.txt | 12 +- ...DataProviderTest-testCodeFragmentKeys4.txt | 12 +- ...DataProviderTest-testCodeFragmentKeys5.txt | 12 +- ...DataProviderTest-testCodeFragmentKeys6.txt | 12 +- ...Test-testCodeFragmentKeysWithWildCard0.txt | 12 +- ...Test-testCodeFragmentKeysWithWildCard1.txt | 12 +- ...Test-testCodeFragmentKeysWithWildCard2.txt | 12 +- ...Test-testCodeFragmentKeysWithWildCard3.txt | 12 +- ...Test-testCodeFragmentKeysWithWildCard4.txt | 12 +- ...Test-testCodeFragmentKeysWithWildCard5.txt | 12 +- ...Test-testCodeFragmentKeysWithWildCard6.txt | 12 +- ...iderTest-testDataProviderSingleFailure.txt | 12 +- ...iderTest-testDataProviderWithMixedType.txt | 12 +- ...aProviderTest-testMapValueDataProvider.txt | 12 +- ...iderTest-testMultiModuleSingleTestExec.txt | 12 +- .../DataProviderTest-testRerunFailedTest.txt | 12 +- ...DataProviderTest-testValidDataProvider.txt | 12 +- ...ProviderTest-testValidDataProviderCase.txt | 12 +- ...-testValidDataProviderWithAfterFailing.txt | 12 +- ...idDataProviderWithBeforeAfterFunctions.txt | 12 +- ...testValidDataProviderWithBeforeFailing.txt | 12 +- ...iderTest-testValidDataProviderWithFail.txt | 12 +- .../DataProviderTest-testWithSpecialKeys.txt | 12 +- .../GroupingTest-testWhenAfterGroupsFails.txt | 6 +- ...ProviderTestCase-testEmptyDataProvider.txt | 6 +- ...oviderTestCase-testInvalidDataProvider.txt | 6 +- ...viderTestCase-testInvalidDataProvider2.txt | 18 +- ...gacyMockingFunctionInNonExistingModule.txt | 9 + ...gacyMockingFunctionInSingleFileProject.txt | 4 + ...cyMockingFunctionWithIncompatibleTypes.txt | 9 + ...e-testLegacyMockingNonExistingFunction.txt | 9 + ...LegacyMockingWithEmptyAnnotationRecord.txt | 4 + ...stLegacyMockingWithoutAnnotationRecord.txt | 4 + ...testMockingFunctionInNonExistingModule.txt | 9 + ...testMockingFunctionInSingleFileProject.txt | 4 + ...estCase-testMockingNonExistingFunction.txt | 4 + ...e-testMockingWithEmptyAnnotationRecord.txt | 4 + ...ase-testMockingWithoutAnnotationRecord.txt | 4 + ...tionsTestCase-testMissingAfterFunction.txt | 6 +- ...ionsTestCase-testMissingBeforeFunction.txt | 6 +- ...sTestCase-testMissingDependsOnFunction.txt | 6 +- .../unix/MockTest-testObjectMocking.txt | 12 +- ...kTest-testObjectMocking_NegativeCases1.txt | 12 +- ...kTest-testObjectMocking_NegativeCases2.txt | 12 +- ...kTest-testObjectMocking_NegativeCases3.txt | 12 +- ...kTest-testObjectMocking_NegativeCases4.txt | 12 +- ...kTest-testObjectMocking_NegativeCases5.txt | 12 +- ...kTest-testObjectMocking_NegativeCases6.txt | 12 +- ...kTest-testObjectMocking_NegativeCases7.txt | 12 +- ...stsTestCase-testSkipWhenAfterEachFails.txt | 6 +- ...ipTestsTestCase-testSkipWhenAfterFails.txt | 6 +- ...tsTestCase-testSkipWhenBeforeEachFails.txt | 6 +- ...pTestsTestCase-testSkipWhenBeforeFails.txt | 6 +- ...TestCase-testSkipWhenBeforeGroupsFails.txt | 6 +- ...sTestCase-testSkipWhenBeforeSuiteFails.txt | 6 +- ...ase-testSkipWhenDependsOnFunctionFails.txt | 6 +- ...tTest-testWarningForCoverageFormatFlag.txt | 6 +- ...stReportTest-testWarningForReportTools.txt | 6 +- .../BasicCasesTest-testAnnotationAccess.txt | 6 +- ...sicCasesTest-testAssertBehavioralTypes.txt | 18 +- .../BasicCasesTest-testAssertDiffError.txt | 18 +- ...sicCasesTest-testAssertStructuralTypes.txt | 18 +- ...sicCasesTest-testAssertionErrorMessage.txt | 18 +- ...iderTest-testArrayDataProviderWithFail.txt | 12 +- ...viderTest-testArrayDataRerunFailedTest.txt | 12 +- ...DataProviderTest-testCodeFragmentKeys2.txt | 12 +- ...DataProviderTest-testCodeFragmentKeys3.txt | 12 +- ...DataProviderTest-testCodeFragmentKeys5.txt | 11 +- ...Test-testCodeFragmentKeysWithWildCard0.txt | 11 +- ...Test-testCodeFragmentKeysWithWildCard1.txt | 11 +- ...Test-testCodeFragmentKeysWithWildCard2.txt | 11 +- ...Test-testCodeFragmentKeysWithWildCard3.txt | 11 +- ...Test-testCodeFragmentKeysWithWildCard4.txt | 12 +- ...Test-testCodeFragmentKeysWithWildCard5.txt | 12 +- ...Test-testCodeFragmentKeysWithWildCard6.txt | 12 +- ...iderTest-testDataProviderSingleFailure.txt | 12 +- ...iderTest-testDataProviderWithMixedType.txt | 12 +- ...aProviderTest-testMapValueDataProvider.txt | 12 +- ...iderTest-testMultiModuleSingleTestExec.txt | 12 +- .../DataProviderTest-testRerunFailedTest.txt | 12 +- ...DataProviderTest-testValidDataProvider.txt | 12 +- ...ProviderTest-testValidDataProviderCase.txt | 12 +- ...-testValidDataProviderWithAfterFailing.txt | 12 +- ...idDataProviderWithBeforeAfterFunctions.txt | 12 +- ...testValidDataProviderWithBeforeFailing.txt | 12 +- ...iderTest-testValidDataProviderWithFail.txt | 12 +- .../DataProviderTest-testWithSpecialKeys.txt | 12 +- .../GroupingTest-testWhenAfterGroupsFails.txt | 6 +- ...ProviderTestCase-testEmptyDataProvider.txt | 8 +- ...oviderTestCase-testInvalidDataProvider.txt | 6 +- ...viderTestCase-testInvalidDataProvider2.txt | 18 +- ...gacyMockingFunctionInNonExistingModule.txt | 9 + ...gacyMockingFunctionInSingleFileProject.txt | 4 + ...cyMockingFunctionWithIncompatibleTypes.txt | 9 + ...e-testLegacyMockingNonExistingFunction.txt | 9 + ...LegacyMockingWithEmptyAnnotationRecord.txt | 4 + ...stLegacyMockingWithoutAnnotationRecord.txt | 4 + ...testMockingFunctionInNonExistingModule.txt | 9 + ...testMockingFunctionInSingleFileProject.txt | 4 + ...estCase-testMockingNonExistingFunction.txt | 4 + ...e-testMockingWithEmptyAnnotationRecord.txt | 4 + ...ase-testMockingWithoutAnnotationRecord.txt | 4 + ...tionsTestCase-testMissingAfterFunction.txt | 8 +- ...ionsTestCase-testMissingBeforeFunction.txt | 8 +- ...sTestCase-testMissingDependsOnFunction.txt | 8 +- .../windows/MockTest-testObjectMocking.txt | 234 +++++++++--------- ...kTest-testObjectMocking_NegativeCases1.txt | 12 +- ...kTest-testObjectMocking_NegativeCases2.txt | 12 +- ...kTest-testObjectMocking_NegativeCases3.txt | 12 +- ...kTest-testObjectMocking_NegativeCases4.txt | 12 +- ...kTest-testObjectMocking_NegativeCases5.txt | 12 +- ...kTest-testObjectMocking_NegativeCases6.txt | 12 +- ...kTest-testObjectMocking_NegativeCases7.txt | 12 +- ...stsTestCase-testSkipWhenAfterEachFails.txt | 6 +- ...ipTestsTestCase-testSkipWhenAfterFails.txt | 6 +- ...tsTestCase-testSkipWhenBeforeEachFails.txt | 6 +- ...pTestsTestCase-testSkipWhenBeforeFails.txt | 6 +- ...TestCase-testSkipWhenBeforeGroupsFails.txt | 6 +- ...sTestCase-testSkipWhenBeforeSuiteFails.txt | 6 +- ...ase-testSkipWhenDependsOnFunctionFails.txt | 6 +- ...tTest-testWarningForCoverageFormatFlag.txt | 6 +- ...stReportTest-testWarningForReportTools.txt | 6 +- 133 files changed, 1234 insertions(+), 317 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java index 50204efab8bf..8a8fa34f171d 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java @@ -52,7 +52,8 @@ public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, in boolean colorEnabled) { String diagnosticCode = diagnostic.diagnosticInfo().code(); - if (diagnostic instanceof PackageDiagnostic && diagnosticCode.startsWith(COMPILER_ERROR_PREFIX)) { + if (diagnostic instanceof PackageDiagnostic && diagnosticCode != null && + diagnosticCode.startsWith(COMPILER_ERROR_PREFIX)) { int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); if (diagnosticCodeNumber < SYNTAX_ERROR_CODE_THRESHOLD) { PackageDiagnostic packageDiagnostic = (PackageDiagnostic) diagnostic; @@ -85,10 +86,11 @@ private static String diagnosticToString(Diagnostic diagnostic, boolean colorEna String color = SEVERITY_COLORS.get(severity); String message = diagnostic.toString().substring(severityString.length()); String code = diagnostic.diagnosticInfo().code(); - boolean isMultiline = diagnostic.message().contains("\n"); - String formatString = getColoredString("%s", color, colorEnabled) + "%s" + (isMultiline ? "\n(%s)" : " (%s)"); + boolean isMultiline = diagnostic.message().contains(NEW_LINE); + String formatString = getColoredString("%s", color, colorEnabled) + "%s" + + (code != null ? (isMultiline ? NEW_LINE + "(%s)" : " (%s)") : ""); - return String.format(formatString, severityString, message, code); + return String.format(formatString, severityString, message, code != null ? code : ""); } private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document document, Location location, diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAnnotationAccess.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAnnotationAccess.txt index 02c08213122d..4ef4fde9bff1 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAnnotationAccess.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAnnotationAccess.txt @@ -1,6 +1,10 @@ Compiling source intg_tests/annotation_access:0.0.0 -HINT [tests/main_test.bal:(73:5,73:5)] concurrent calls will not be made to this method since the service is not an 'isolated' service +HINT [tests/main_test.bal:(73:5,73:5)] concurrent calls will not be made to this method since the service is not an 'isolated' service (BCH2004) + | +73 | remote function xyz() { + | ^ + ballerina: Oh no, something really went wrong. Bad. Sad. We appreciate it if you can report the code that broke Ballerina in diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertBehavioralTypes.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertBehavioralTypes.txt index a3dcd6542fd6..b87c8673ad6b 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertBehavioralTypes.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertBehavioralTypes.txt @@ -1,8 +1,20 @@ Compiling source intg_tests/assertions:0.0.0 -WARNING [tests/assert-test-behavioral-types.bal:(22:5,22:29)] undocumented field 'name' -WARNING [tests/assert-test-behavioral-types.bal:(23:5,23:24)] undocumented field 'age' -WARNING [tests/assert-test-behavioral-types.bal:(24:5,24:32)] undocumented field 'parent' +WARNING [tests/assert-test-behavioral-types.bal:(22:5,22:29)] undocumented field 'name' (BCE20004) + | +22 | public string name = ""; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [tests/assert-test-behavioral-types.bal:(23:5,23:24)] undocumented field 'age' (BCE20004) + | +23 | public int age = 0; + | ^^^^^^^^^^^^^^^^^^^ + +WARNING [tests/assert-test-behavioral-types.bal:(24:5,24:32)] undocumented field 'parent' (BCE20004) + | +24 | public Person? parent = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertDiffError.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertDiffError.txt index 0fcb0d60b75a..ee89582e0934 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertDiffError.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertDiffError.txt @@ -1,8 +1,20 @@ Compiling source intg_tests/assertions:0.0.0 -WARNING [tests/assertions-diff-error-messages.bal:(22:5,22:29)] undocumented field 'name' -WARNING [tests/assertions-diff-error-messages.bal:(23:5,23:24)] undocumented field 'age' -WARNING [tests/assertions-diff-error-messages.bal:(24:5,24:32)] undocumented field 'parent' +WARNING [tests/assertions-diff-error-messages.bal:(22:5,22:29)] undocumented field 'name' (BCE20004) + | +22 | public string name = ""; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [tests/assertions-diff-error-messages.bal:(23:5,23:24)] undocumented field 'age' (BCE20004) + | +23 | public int age = 0; + | ^^^^^^^^^^^^^^^^^^^ + +WARNING [tests/assertions-diff-error-messages.bal:(24:5,24:32)] undocumented field 'parent' (BCE20004) + | +24 | public Person? parent = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertStructuralTypes.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertStructuralTypes.txt index f59d2f7c166a..956c40b9ef85 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertStructuralTypes.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertStructuralTypes.txt @@ -1,8 +1,20 @@ Compiling source intg_tests/assertions:0.0.0 -WARNING [tests/assert-test-structural-types.bal:(22:5,22:21)] undocumented field 'id' -WARNING [tests/assert-test-structural-types.bal:(23:5,23:17)] undocumented field 'name' -WARNING [tests/assert-test-structural-types.bal:(24:5,24:18)] undocumented field 'salary' +WARNING [tests/assert-test-structural-types.bal:(22:5,22:21)] undocumented field 'id' (BCE20004) + | +22 | readonly int id; + | ^^^^^^^^^^^^^^^^ + +WARNING [tests/assert-test-structural-types.bal:(23:5,23:17)] undocumented field 'name' (BCE20004) + | +23 | string name; + | ^^^^^^^^^^^^ + +WARNING [tests/assert-test-structural-types.bal:(24:5,24:18)] undocumented field 'salary' (BCE20004) + | +24 | float salary; + | ^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertionErrorMessage.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertionErrorMessage.txt index 753c7d8f0ee6..bd84674ed373 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertionErrorMessage.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/BasicCasesTest-testAssertionErrorMessage.txt @@ -1,8 +1,20 @@ Compiling source intg_tests/assertions:0.0.0 -WARNING [tests/assertions-error-messages.bal:(22:5,22:29)] undocumented field 'name' -WARNING [tests/assertions-error-messages.bal:(23:5,23:24)] undocumented field 'age' -WARNING [tests/assertions-error-messages.bal:(24:5,24:32)] undocumented field 'parent' +WARNING [tests/assertions-error-messages.bal:(22:5,22:29)] undocumented field 'name' (BCE20004) + | +22 | public string name = ""; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [tests/assertions-error-messages.bal:(23:5,23:24)] undocumented field 'age' (BCE20004) + | +23 | public int age = 0; + | ^^^^^^^^^^^^^^^^^^^ + +WARNING [tests/assertions-error-messages.bal:(24:5,24:32)] undocumented field 'parent' (BCE20004) + | +24 | public Person? parent = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testArrayDataProviderWithFail.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testArrayDataProviderWithFail.txt index 177fa1d3e46e..3d03621893e4 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testArrayDataProviderWithFail.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testArrayDataProviderWithFail.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testArrayDataRerunFailedTest.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testArrayDataRerunFailedTest.txt index 62de71b0190f..e70563bca2bb 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testArrayDataRerunFailedTest.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testArrayDataRerunFailedTest.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys0.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys0.txt index 9b035dfe4df4..816d5e26120f 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys0.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys0.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys1.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys1.txt index 8c1f43d82d81..fa9f75198c97 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys1.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys1.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys2.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys2.txt index eb05990fbbec..0543c335188b 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys2.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys2.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys3.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys3.txt index 6b4ff813f0de..50282f7c5875 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys3.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys3.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys4.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys4.txt index 4fc7adcb9550..35d802bc7d8d 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys4.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys4.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys5.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys5.txt index 862b310dad79..62596538312b 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys5.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys5.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys6.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys6.txt index d2f21152b6d0..f87475fa8370 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys6.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeys6.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt index 9b035dfe4df4..816d5e26120f 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt index 8c1f43d82d81..fa9f75198c97 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt index eb05990fbbec..0543c335188b 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt index 6b4ff813f0de..50282f7c5875 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard4.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard4.txt index 4fc7adcb9550..35d802bc7d8d 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard4.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard4.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard5.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard5.txt index 862b310dad79..62596538312b 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard5.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard5.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard6.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard6.txt index d2f21152b6d0..f87475fa8370 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard6.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testCodeFragmentKeysWithWildCard6.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testDataProviderSingleFailure.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testDataProviderSingleFailure.txt index d62f56be1247..e87dfc583495 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testDataProviderSingleFailure.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testDataProviderSingleFailure.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testDataProviderWithMixedType.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testDataProviderWithMixedType.txt index 00c8194d9eb5..ef0ea94734a6 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testDataProviderWithMixedType.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testDataProviderWithMixedType.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testMapValueDataProvider.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testMapValueDataProvider.txt index c38947ff799c..25f294a5d2b7 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testMapValueDataProvider.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testMapValueDataProvider.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testMultiModuleSingleTestExec.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testMultiModuleSingleTestExec.txt index 6a8d9414dffe..675cdae0f9ee 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testMultiModuleSingleTestExec.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testMultiModuleSingleTestExec.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testRerunFailedTest.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testRerunFailedTest.txt index c7cc860df0bb..5cf32b5d9e18 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testRerunFailedTest.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testRerunFailedTest.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProvider.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProvider.txt index f6605f0a17ac..e7fa9ca3e556 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProvider.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProvider.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderCase.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderCase.txt index 939dee9ded10..3d9b46e2bd04 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderCase.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderCase.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithAfterFailing.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithAfterFailing.txt index 08cc2ccfe028..c8e8b7d4dc63 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithAfterFailing.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithAfterFailing.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithBeforeAfterFunctions.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithBeforeAfterFunctions.txt index 855b559c3d3e..9a7059f90c3e 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithBeforeAfterFunctions.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithBeforeAfterFunctions.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithBeforeFailing.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithBeforeFailing.txt index 20664b5932b5..bd70ce68ff40 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithBeforeFailing.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithBeforeFailing.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithFail.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithFail.txt index 53d541178839..9cfa047ea720 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithFail.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testValidDataProviderWithFail.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testWithSpecialKeys.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testWithSpecialKeys.txt index 3a19cdfe1337..fdd0da4f6bc0 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testWithSpecialKeys.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/DataProviderTest-testWithSpecialKeys.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests/new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests/new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/GroupingTest-testWhenAfterGroupsFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/GroupingTest-testWhenAfterGroupsFails.txt index 226cf4ea32af..91eb916ee41a 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/GroupingTest-testWhenAfterGroupsFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/GroupingTest-testWhenAfterGroupsFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source failed-after-groups-test.bal -WARNING [failed-after-groups-test.bal:(37:5,37:17)] unused variable 'b' +WARNING [failed-after-groups-test.bal:(37:5,37:17)] unused variable 'b' (BCE20403) + | +37 | int b = 2/0; + | ^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testEmptyDataProvider.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testEmptyDataProvider.txt index 0c0ac9e5321a..906ce0a1098d 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testEmptyDataProvider.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testEmptyDataProvider.txt @@ -2,5 +2,9 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source empty-data-provider-test.bal -ERROR [empty-data-provider-test.bal:(14:19,14:28)] incompatible types: expected 'function () returns (ballerina/test:0.0.0:DataProviderReturnType)?', found 'function () returns (int[])' +ERROR [empty-data-provider-test.bal:(14:19,14:28)] incompatible types: expected 'function () returns (ballerina/test:0.0.0:DataProviderReturnType)?', found 'function () returns (int[])' (BCE2066) + | +14 | dataProvider: provider2 + | ^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testInvalidDataProvider.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testInvalidDataProvider.txt index d3a8749e72fe..4dfa9a60ae12 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testInvalidDataProvider.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testInvalidDataProvider.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source invalid-data-provider-test.bal -WARNING [invalid-data-provider-test.bal:(25:5,25:58)] unused variable 'resultErr' +WARNING [invalid-data-provider-test.bal:(25:5,25:58)] unused variable 'resultErr' (BCE20403) + | +25 | int|error resultErr = trap result.cloneWithType(int); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testInvalidDataProvider2.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testInvalidDataProvider2.txt index c80c73073bb0..fd147229e42b 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testInvalidDataProvider2.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidDataProviderTestCase-testInvalidDataProvider2.txt @@ -2,9 +2,21 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source invalid-data-provider-test2.bal -WARNING [invalid-data-provider-test2.bal:(25:5,25:53)] unused variable 'fErr' -WARNING [invalid-data-provider-test2.bal:(26:5,26:53)] unused variable 'sErr' -WARNING [invalid-data-provider-test2.bal:(27:5,27:58)] unused variable 'resultErr' +WARNING [invalid-data-provider-test2.bal:(25:5,25:53)] unused variable 'fErr' (BCE20403) + | +25 | int|error fErr = trap fValue.cloneWithType(int); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [invalid-data-provider-test2.bal:(26:5,26:53)] unused variable 'sErr' (BCE20403) + | +26 | int|error sErr = trap sValue.cloneWithType(int); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [invalid-data-provider-test2.bal:(27:5,27:58)] unused variable 'resultErr' (BCE20403) + | +27 | int|error resultErr = trap result.cloneWithType(int); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt index a3c34b85eb58..082cdf2424b1 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt @@ -1,4 +1,13 @@ Compiling source intg_tests/non_existent_module_mock:0.1.0 ERROR [tests/test.bal:(3:1,6:2)] could not find specified module 'intg_tests/module1:0.1.0' + | +3 | @test:Mock { +: | ^^^^^^^^^^^^ +: | : +: | : +6 | } + | ^ + | + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInSingleFileProject.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInSingleFileProject.txt index 00aa19d721a0..c69f652d5818 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInSingleFileProject.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInSingleFileProject.txt @@ -3,4 +3,8 @@ warning: ignoring --includes flag since code coverage is not enabled Compiling source function-legacy-mock.bal ERROR [function-legacy-mock.bal:(8:1,8:38)] function mocking is not supported with standalone Ballerina files + | +8 | @test:Mock { functionName: "intAdd" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt index f4a01e5ecba0..5483cdd45e13 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt @@ -1,4 +1,13 @@ Compiling source intg_tests/incompatible_type_mock:0.1.0 ERROR [tests/test.bal:(6:1,8:2)] incompatible types: expected isolated function () returns (string) but found isolated function () returns (int) + | +6 | function getMockClient() returns int { +: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +: | : +: | : +8 | } + | ^ + | + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt index 327839ef5180..56b54aca5336 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt @@ -1,4 +1,13 @@ Compiling source intg_tests/non_existent_function_mock:0.1.0 ERROR [tests/test.bal:(3:1,5:2)] could not find function 'createJdbcClient' in module 'intg_tests/non_existent_function_mock:0.1.0' + | +3 | @test:Mock { +: | ^^^^^^^^^^^^ +: | : +: | : +5 | } + | ^ + | + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingWithEmptyAnnotationRecord.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingWithEmptyAnnotationRecord.txt index 100d89c93610..a2196d1c87ac 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingWithEmptyAnnotationRecord.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingWithEmptyAnnotationRecord.txt @@ -1,4 +1,8 @@ Compiling source intg_tests/empty_annot_rec_function_mock:0.1.0 ERROR [tests/test.bal:(3:1,3:14)] function name cannot be empty + | +3 | @test:Mock {} + | ^^^^^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingWithoutAnnotationRecord.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingWithoutAnnotationRecord.txt index 3afce0b0f7d5..dc5115c7699d 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingWithoutAnnotationRecord.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingWithoutAnnotationRecord.txt @@ -1,4 +1,8 @@ Compiling source intg_tests/recordless_annot_function_mock:0.1.0 ERROR [tests/test.bal:(3:1,3:11)] missing required 'functionName' field + | +3 | @test:Mock + | ^^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt index a3c34b85eb58..082cdf2424b1 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt @@ -1,4 +1,13 @@ Compiling source intg_tests/non_existent_module_mock:0.1.0 ERROR [tests/test.bal:(3:1,6:2)] could not find specified module 'intg_tests/module1:0.1.0' + | +3 | @test:Mock { +: | ^^^^^^^^^^^^ +: | : +: | : +6 | } + | ^ + | + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInSingleFileProject.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInSingleFileProject.txt index b07583365de3..ead4c3aaa0b4 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInSingleFileProject.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInSingleFileProject.txt @@ -3,4 +3,8 @@ warning: ignoring --includes flag since code coverage is not enabled Compiling source function-mock.bal ERROR [function-mock.bal:(12:1,12:38)] function mocking is not supported with standalone Ballerina files + | +12 | @test:Mock { functionName: "intAdd" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingNonExistingFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingNonExistingFunction.txt index 6e8c9fa30bf2..7a7bddbfefee 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingNonExistingFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingNonExistingFunction.txt @@ -1,4 +1,8 @@ Compiling source intg_tests/non_existent_function_mock:0.1.0 ERROR [tests/test.bal:(3:1,3:38)] could not find function 'intAdd' in module 'intg_tests/non_existent_function_mock:0.1.0' + | +3 | @test:Mock { functionName: "intAdd" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingWithEmptyAnnotationRecord.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingWithEmptyAnnotationRecord.txt index 100d89c93610..a2196d1c87ac 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingWithEmptyAnnotationRecord.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingWithEmptyAnnotationRecord.txt @@ -1,4 +1,8 @@ Compiling source intg_tests/empty_annot_rec_function_mock:0.1.0 ERROR [tests/test.bal:(3:1,3:14)] function name cannot be empty + | +3 | @test:Mock {} + | ^^^^^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingWithoutAnnotationRecord.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingWithoutAnnotationRecord.txt index 3afce0b0f7d5..dc5115c7699d 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingWithoutAnnotationRecord.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingWithoutAnnotationRecord.txt @@ -1,4 +1,8 @@ Compiling source intg_tests/recordless_annot_function_mock:0.1.0 ERROR [tests/test.bal:(3:1,3:11)] missing required 'functionName' field + | +3 | @test:Mock + | ^^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingAfterFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingAfterFunction.txt index 464421053c58..a6f0eddbd0bb 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingAfterFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingAfterFunction.txt @@ -2,5 +2,9 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source after-func-negative.bal -ERROR [after-func-negative.bal:(22:12,22:29)] undefined symbol 'afterFuncNonExist' +ERROR [after-func-negative.bal:(22:12,22:29)] undefined symbol 'afterFuncNonExist' (BCE2010) + | +22 | after: afterFuncNonExist + | ^^^^^^^^^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingBeforeFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingBeforeFunction.txt index fb6158642878..cc3992ab5eff 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingBeforeFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingBeforeFunction.txt @@ -2,5 +2,9 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source before-func-negative.bal -ERROR [before-func-negative.bal:(22:13,22:31)] undefined symbol 'beforeFuncNonExist' +ERROR [before-func-negative.bal:(22:13,22:31)] undefined symbol 'beforeFuncNonExist' (BCE2010) + | +22 | before: beforeFuncNonExist + | ^^^^^^^^^^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingDependsOnFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingDependsOnFunction.txt index 3f4da62dcc4c..0ea72c1ffb68 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingDependsOnFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MissingFunctionsTestCase-testMissingDependsOnFunction.txt @@ -2,5 +2,9 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source depends-on-negative.bal -ERROR [depends-on-negative.bal:(22:17,22:28)] undefined symbol 'nonExisting' +ERROR [depends-on-negative.bal:(22:17,22:28)] undefined symbol 'nonExisting' (BCE2010) + | +22 | dependsOn: [nonExisting] + | ^^^^^^^^^^^ + error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking.txt index 9963be3a446b..caaae019983f 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases1.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases1.txt index b3e2198b0cb7..92e606037a4a 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases1.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases1.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases2.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases2.txt index f291d70eb35a..8b969c6c541a 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases2.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases2.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases3.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases3.txt index a369bbedc170..4a4eb857f560 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases3.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases3.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases4.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases4.txt index 844d5d413b09..084e4d51d184 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases4.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases4.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases5.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases5.txt index d8ac4b000730..3ca6ca899c71 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases5.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases5.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases6.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases6.txt index 9b7effbf3202..b2fd79f44844 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases6.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases6.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases7.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases7.txt index 8b89ee8e229e..c6e52eea48e3 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases7.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/MockTest-testObjectMocking_NegativeCases7.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules/TestHttpClient/main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenAfterEachFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenAfterEachFails.txt index 594604459e03..d13a959c6229 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenAfterEachFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenAfterEachFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-afterEach-fails.bal -WARNING [skip-when-afterEach-fails.bal:(30:5,30:18)] unused variable 'i' +WARNING [skip-when-afterEach-fails.bal:(30:5,30:18)] unused variable 'i' (BCE20403) + | +30 | int i = 12/0; + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenAfterFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenAfterFails.txt index 5ca3d5a1e622..971f80e9c500 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenAfterFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenAfterFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-after-fails.bal -WARNING [skip-when-after-fails.bal:(30:5,30:18)] unused variable 'i' +WARNING [skip-when-after-fails.bal:(30:5,30:18)] unused variable 'i' (BCE20403) + | +30 | int i = 12/0; + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeEachFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeEachFails.txt index 9d03588b1210..9b4cf01de3f1 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeEachFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeEachFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-beforeEach-fails.bal -WARNING [skip-when-beforeEach-fails.bal:(25:5,25:18)] unused variable 'i' +WARNING [skip-when-beforeEach-fails.bal:(25:5,25:18)] unused variable 'i' (BCE20403) + | +25 | int i = 12/0; + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeFails.txt index 1853e4767f2e..4f0524525b62 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-before-fails.bal -WARNING [skip-when-before-fails.bal:(28:5,28:18)] unused variable 'i' +WARNING [skip-when-before-fails.bal:(28:5,28:18)] unused variable 'i' (BCE20403) + | +28 | int i = 12/0; + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeGroupsFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeGroupsFails.txt index f37fe856dcef..80e90e1fba94 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeGroupsFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeGroupsFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-beforeGroups-fails.bal -WARNING [skip-when-beforeGroups-fails.bal:(32:5,32:17)] unused variable 'b' +WARNING [skip-when-beforeGroups-fails.bal:(32:5,32:17)] unused variable 'b' (BCE20403) + | +32 | int b = 2/0; + | ^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeSuiteFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeSuiteFails.txt index b0b198468ef8..8000f39ef738 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeSuiteFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenBeforeSuiteFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-beforeSuite-fails.bal -WARNING [skip-when-beforeSuite-fails.bal:(24:5,24:18)] unused variable 'i' +WARNING [skip-when-beforeSuite-fails.bal:(24:5,24:18)] unused variable 'i' (BCE20403) + | +24 | int i = 12/0; // This will throw an exception and fail the function + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenDependsOnFunctionFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenDependsOnFunctionFails.txt index 4686fd83e79f..7f50ab977259 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenDependsOnFunctionFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/SkipTestsTestCase-testSkipWhenDependsOnFunctionFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source dependson-skip-test.bal -WARNING [dependson-skip-test.bal:(34:5,34:18)] unused variable 'i' +WARNING [dependson-skip-test.bal:(34:5,34:18)] unused variable 'i' (BCE20403) + | +34 | int i = 12/0; + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/TestReportTest-testWarningForCoverageFormatFlag.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/TestReportTest-testWarningForCoverageFormatFlag.txt index 99cc6a5014a2..67836b2483da 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/TestReportTest-testWarningForCoverageFormatFlag.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/TestReportTest-testWarningForCoverageFormatFlag.txt @@ -1,7 +1,11 @@ warning: ignoring --coverage-format flag since code coverage is not enabled Compiling source testerina_report/foo:0.0.0 -WARNING [main.bal:(36:5,36:19)] unused variable 'b' +WARNING [main.bal:(36:5,36:19)] unused variable 'b' (BCE20403) + | +36 | int b = a + 1; + | ^^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/TestReportTest-testWarningForReportTools.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/TestReportTest-testWarningForReportTools.txt index 40b924d70612..4517bd3011cd 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/TestReportTest-testWarningForReportTools.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/TestReportTest-testWarningForReportTools.txt @@ -1,6 +1,10 @@ Compiling source testerina_report/foo:0.0.0 -WARNING [main.bal:(36:5,36:19)] unused variable 'b' +WARNING [main.bal:(36:5,36:19)] unused variable 'b' (BCE20403) + | +36 | int b = a + 1; + | ^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAnnotationAccess.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAnnotationAccess.txt index 8d4059d02d49..0fcfb1c25cf6 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAnnotationAccess.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAnnotationAccess.txt @@ -1,6 +1,10 @@ Compiling source intg_tests/annotation_access:0.0.0 -HINT [tests\main_test.bal:(73:5,73:5)] concurrent calls will not be made to this method since the service is not an 'isolated' service +HINT [tests\main_test.bal:(73:5,73:5)] concurrent calls will not be made to this method since the service is not an 'isolated' service (BCH2004) + | +73 | remote function xyz() { + | ^ + ballerina: Oh no, something really went wrong. Bad. Sad. We appreciate it if you can report the code that broke Ballerina in diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertBehavioralTypes.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertBehavioralTypes.txt index 59dd1b2eb189..f8ff1c48fa1e 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertBehavioralTypes.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertBehavioralTypes.txt @@ -1,8 +1,20 @@ Compiling source intg_tests/assertions:0.0.0 -WARNING [tests\assert-test-behavioral-types.bal:(22:5,22:29)] undocumented field 'name' -WARNING [tests\assert-test-behavioral-types.bal:(23:5,23:24)] undocumented field 'age' -WARNING [tests\assert-test-behavioral-types.bal:(24:5,24:32)] undocumented field 'parent' +WARNING [tests\assert-test-behavioral-types.bal:(22:5,22:29)] undocumented field 'name' (BCE20004) + | +22 | public string name = ""; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [tests\assert-test-behavioral-types.bal:(23:5,23:24)] undocumented field 'age' (BCE20004) + | +23 | public int age = 0; + | ^^^^^^^^^^^^^^^^^^^ + +WARNING [tests\assert-test-behavioral-types.bal:(24:5,24:32)] undocumented field 'parent' (BCE20004) + | +24 | public Person? parent = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertDiffError.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertDiffError.txt index d29c46fb8b2f..ac32eb886c7a 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertDiffError.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertDiffError.txt @@ -1,8 +1,20 @@ Compiling source intg_tests/assertions:0.0.0 -WARNING [tests\assertions-diff-error-messages.bal:(22:5,22:29)] undocumented field 'name' -WARNING [tests\assertions-diff-error-messages.bal:(23:5,23:24)] undocumented field 'age' -WARNING [tests\assertions-diff-error-messages.bal:(24:5,24:32)] undocumented field 'parent' +WARNING [tests\assertions-diff-error-messages.bal:(22:5,22:29)] undocumented field 'name' (BCE20004) + | +22 | public string name = ""; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [tests\assertions-diff-error-messages.bal:(23:5,23:24)] undocumented field 'age' (BCE20004) + | +23 | public int age = 0; + | ^^^^^^^^^^^^^^^^^^^ + +WARNING [tests\assertions-diff-error-messages.bal:(24:5,24:32)] undocumented field 'parent' (BCE20004) + | +24 | public Person? parent = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertStructuralTypes.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertStructuralTypes.txt index 9b6a9337584d..d2e3f32b6bf7 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertStructuralTypes.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertStructuralTypes.txt @@ -1,8 +1,20 @@ Compiling source intg_tests/assertions:0.0.0 -WARNING [tests\assert-test-structural-types.bal:(22:5,22:21)] undocumented field 'id' -WARNING [tests\assert-test-structural-types.bal:(23:5,23:17)] undocumented field 'name' -WARNING [tests\assert-test-structural-types.bal:(24:5,24:18)] undocumented field 'salary' +WARNING [tests\assert-test-structural-types.bal:(22:5,22:21)] undocumented field 'id' (BCE20004) + | +22 | readonly int id; + | ^^^^^^^^^^^^^^^^ + +WARNING [tests\assert-test-structural-types.bal:(23:5,23:17)] undocumented field 'name' (BCE20004) + | +23 | string name; + | ^^^^^^^^^^^^ + +WARNING [tests\assert-test-structural-types.bal:(24:5,24:18)] undocumented field 'salary' (BCE20004) + | +24 | float salary; + | ^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertionErrorMessage.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertionErrorMessage.txt index 3fc5195f45c8..b24ce0643bbd 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertionErrorMessage.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/BasicCasesTest-testAssertionErrorMessage.txt @@ -1,8 +1,20 @@ Compiling source intg_tests/assertions:0.0.0 -WARNING [tests\assertions-error-messages.bal:(22:5,22:29)] undocumented field 'name' -WARNING [tests\assertions-error-messages.bal:(23:5,23:24)] undocumented field 'age' -WARNING [tests\assertions-error-messages.bal:(24:5,24:32)] undocumented field 'parent' +WARNING [tests\assertions-error-messages.bal:(22:5,22:29)] undocumented field 'name' (BCE20004) + | +22 | public string name = ""; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [tests\assertions-error-messages.bal:(23:5,23:24)] undocumented field 'age' (BCE20004) + | +23 | public int age = 0; + | ^^^^^^^^^^^^^^^^^^^ + +WARNING [tests\assertions-error-messages.bal:(24:5,24:32)] undocumented field 'parent' (BCE20004) + | +24 | public Person? parent = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testArrayDataProviderWithFail.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testArrayDataProviderWithFail.txt index dc4868b06f38..23ddf9693114 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testArrayDataProviderWithFail.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testArrayDataProviderWithFail.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testArrayDataRerunFailedTest.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testArrayDataRerunFailedTest.txt index 20df320a02c2..b3e97cf070e0 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testArrayDataRerunFailedTest.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testArrayDataRerunFailedTest.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys2.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys2.txt index 846fbfc0eab9..96a3c3e74344 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys2.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys2.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys3.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys3.txt index 8df54d7c847a..4038469bf3af 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys3.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys3.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys5.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys5.txt index ce01863d1b3e..a3f72c9275a3 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys5.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys5.txt @@ -1,7 +1,14 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt index 36e950726ca0..1e7bc6503126 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt @@ -1,7 +1,14 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt index 39b96e58df95..06b6df186bfb 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt @@ -1,7 +1,14 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt index 846fbfc0eab9..47c7b7d170d1 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt @@ -1,7 +1,14 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt index 8df54d7c847a..abde52e71614 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt @@ -1,7 +1,14 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard4.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard4.txt index a9da367d8d27..ffb95dc8a9af 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard4.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard4.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard5.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard5.txt index ce01863d1b3e..2ef6192270ee 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard5.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard5.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard6.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard6.txt index 59daf1e51894..661f925e4884 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard6.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard6.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testDataProviderSingleFailure.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testDataProviderSingleFailure.txt index 9af0622d91df..eb7bf4b9c621 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testDataProviderSingleFailure.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testDataProviderSingleFailure.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testDataProviderWithMixedType.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testDataProviderWithMixedType.txt index 63796d312b20..6fce7c4b7819 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testDataProviderWithMixedType.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testDataProviderWithMixedType.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testMapValueDataProvider.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testMapValueDataProvider.txt index db70ccdddf8d..f2b1d8457ed9 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testMapValueDataProvider.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testMapValueDataProvider.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testMultiModuleSingleTestExec.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testMultiModuleSingleTestExec.txt index 81d65f58a0a3..56a4b87f020f 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testMultiModuleSingleTestExec.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testMultiModuleSingleTestExec.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testRerunFailedTest.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testRerunFailedTest.txt index 56ec02fefcd6..b53f23311bc1 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testRerunFailedTest.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testRerunFailedTest.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProvider.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProvider.txt index 6be496f855a4..9fbbffcd73cb 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProvider.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProvider.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderCase.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderCase.txt index 24d228d4e228..3624de81b1af 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderCase.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderCase.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithAfterFailing.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithAfterFailing.txt index ec7dfbb075fd..bd6c2cdae5dc 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithAfterFailing.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithAfterFailing.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithBeforeAfterFunctions.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithBeforeAfterFunctions.txt index 7b00744184aa..f3049edb4888 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithBeforeAfterFunctions.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithBeforeAfterFunctions.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithBeforeFailing.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithBeforeFailing.txt index 577e8d2d8eda..d8f009e00abf 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithBeforeFailing.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithBeforeFailing.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithFail.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithFail.txt index 05de187b5b78..5b3a29d59fb5 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithFail.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testValidDataProviderWithFail.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testWithSpecialKeys.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testWithSpecialKeys.txt index 4b115af65bcd..5db2ce2dfbb3 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testWithSpecialKeys.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testWithSpecialKeys.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/GroupingTest-testWhenAfterGroupsFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/GroupingTest-testWhenAfterGroupsFails.txt index 810d17422460..da28452c8b95 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/GroupingTest-testWhenAfterGroupsFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/GroupingTest-testWhenAfterGroupsFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source failed-after-groups-test.bal -WARNING [failed-after-groups-test.bal:(37:5,37:17)] unused variable 'b' +WARNING [failed-after-groups-test.bal:(37:5,37:17)] unused variable 'b' (BCE20403) + | +37 | int b = 2/0; + | ^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testEmptyDataProvider.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testEmptyDataProvider.txt index 56612731e9f7..c0b77ef50351 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testEmptyDataProvider.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testEmptyDataProvider.txt @@ -2,5 +2,9 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source empty-data-provider-test.bal -ERROR [empty-data-provider-test.bal:(14:19,14:28)] incompatible types: expected 'function () returns (ballerina/test:0.0.0:DataProviderReturnType)?', found 'function () returns (int[])' -error: compilation contains errors \ No newline at end of file +ERROR [empty-data-provider-test.bal:(14:19,14:28)] incompatible types: expected 'function () returns (ballerina/test:0.0.0:DataProviderReturnType)?', found 'function () returns (int[])' (BCE2066) + | +14 | dataProvider: provider2 + | ^^^^^^^^^ + +error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testInvalidDataProvider.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testInvalidDataProvider.txt index 8298a3d541b0..3f755057565e 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testInvalidDataProvider.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testInvalidDataProvider.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source invalid-data-provider-test.bal -WARNING [invalid-data-provider-test.bal:(25:5,25:58)] unused variable 'resultErr' +WARNING [invalid-data-provider-test.bal:(25:5,25:58)] unused variable 'resultErr' (BCE20403) + | +25 | int|error resultErr = trap result.cloneWithType(int); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testInvalidDataProvider2.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testInvalidDataProvider2.txt index ddae8eaf4b04..20ef8a3913d6 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testInvalidDataProvider2.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidDataProviderTestCase-testInvalidDataProvider2.txt @@ -2,9 +2,21 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source invalid-data-provider-test2.bal -WARNING [invalid-data-provider-test2.bal:(25:5,25:53)] unused variable 'fErr' -WARNING [invalid-data-provider-test2.bal:(26:5,26:53)] unused variable 'sErr' -WARNING [invalid-data-provider-test2.bal:(27:5,27:58)] unused variable 'resultErr' +WARNING [invalid-data-provider-test2.bal:(25:5,25:53)] unused variable 'fErr' (BCE20403) + | +25 | int|error fErr = trap fValue.cloneWithType(int); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [invalid-data-provider-test2.bal:(26:5,26:53)] unused variable 'sErr' (BCE20403) + | +26 | int|error sErr = trap sValue.cloneWithType(int); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [invalid-data-provider-test2.bal:(27:5,27:58)] unused variable 'resultErr' (BCE20403) + | +27 | int|error resultErr = trap result.cloneWithType(int); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt index c037b79b9f0d..47311091ea75 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt @@ -1,4 +1,13 @@ Compiling source intg_tests/non_existent_module_mock:0.1.0 ERROR [tests\test.bal:(3:1,6:2)] could not find specified module 'intg_tests/module1:0.1.0' + | +3 | @test:Mock { +: | ^^^^^^^^^^^^ +: | : +: | : +6 | } + | ^ + | + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInSingleFileProject.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInSingleFileProject.txt index e9b3b3bd2ccc..fbbae2d0ee8c 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInSingleFileProject.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInSingleFileProject.txt @@ -3,4 +3,8 @@ warning: ignoring --includes flag since code coverage is not enabled Compiling source function-legacy-mock.bal ERROR [function-legacy-mock.bal:(8:1,8:38)] function mocking is not supported with standalone Ballerina files + | +8 | @test:Mock { functionName: "intAdd" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt index 537c1fa15bfe..48ead55f1150 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt @@ -1,4 +1,13 @@ Compiling source intg_tests/incompatible_type_mock:0.1.0 ERROR [tests\test.bal:(6:1,8:2)] incompatible types: expected isolated function () returns (string) but found isolated function () returns (int) + | +6 | function getMockClient() returns int { +: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +: | : +: | : +8 | } + | ^ + | + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt index 1b90b3e50c80..fc8aa1226ab8 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt @@ -1,4 +1,13 @@ Compiling source intg_tests/non_existent_function_mock:0.1.0 ERROR [tests\test.bal:(3:1,5:2)] could not find function 'createJdbcClient' in module 'intg_tests/non_existent_function_mock:0.1.0' + | +3 | @test:Mock { +: | ^^^^^^^^^^^^ +: | : +: | : +5 | } + | ^ + | + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingWithEmptyAnnotationRecord.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingWithEmptyAnnotationRecord.txt index 498299af288d..15dee64e1dc7 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingWithEmptyAnnotationRecord.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingWithEmptyAnnotationRecord.txt @@ -1,4 +1,8 @@ Compiling source intg_tests/empty_annot_rec_function_mock:0.1.0 ERROR [tests\test.bal:(3:1,3:14)] function name cannot be empty + | +3 | @test:Mock {} + | ^^^^^^^^^^^^^ + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingWithoutAnnotationRecord.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingWithoutAnnotationRecord.txt index 17ad4fff2996..2609ed9c4440 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingWithoutAnnotationRecord.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingWithoutAnnotationRecord.txt @@ -1,4 +1,8 @@ Compiling source intg_tests/recordless_annot_function_mock:0.1.0 ERROR [tests\test.bal:(3:1,3:11)] missing required 'functionName' field + | +3 | @test:Mock + | ^^^^^^^^^^ + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt index c037b79b9f0d..47311091ea75 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt @@ -1,4 +1,13 @@ Compiling source intg_tests/non_existent_module_mock:0.1.0 ERROR [tests\test.bal:(3:1,6:2)] could not find specified module 'intg_tests/module1:0.1.0' + | +3 | @test:Mock { +: | ^^^^^^^^^^^^ +: | : +: | : +6 | } + | ^ + | + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInSingleFileProject.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInSingleFileProject.txt index 5f65b32f2d6f..54a818f73c5a 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInSingleFileProject.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInSingleFileProject.txt @@ -3,4 +3,8 @@ warning: ignoring --includes flag since code coverage is not enabled Compiling source function-mock.bal ERROR [function-mock.bal:(12:1,12:38)] function mocking is not supported with standalone Ballerina files + | +12 | @test:Mock { functionName: "intAdd" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingNonExistingFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingNonExistingFunction.txt index 3bb26045a8a0..60d6a53d74b4 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingNonExistingFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingNonExistingFunction.txt @@ -1,4 +1,8 @@ Compiling source intg_tests/non_existent_function_mock:0.1.0 ERROR [tests\test.bal:(3:1,3:38)] could not find function 'intAdd' in module 'intg_tests/non_existent_function_mock:0.1.0' + | +3 | @test:Mock { functionName: "intAdd" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingWithEmptyAnnotationRecord.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingWithEmptyAnnotationRecord.txt index 498299af288d..15dee64e1dc7 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingWithEmptyAnnotationRecord.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingWithEmptyAnnotationRecord.txt @@ -1,4 +1,8 @@ Compiling source intg_tests/empty_annot_rec_function_mock:0.1.0 ERROR [tests\test.bal:(3:1,3:14)] function name cannot be empty + | +3 | @test:Mock {} + | ^^^^^^^^^^^^^ + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingWithoutAnnotationRecord.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingWithoutAnnotationRecord.txt index 17ad4fff2996..2609ed9c4440 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingWithoutAnnotationRecord.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingWithoutAnnotationRecord.txt @@ -1,4 +1,8 @@ Compiling source intg_tests/recordless_annot_function_mock:0.1.0 ERROR [tests\test.bal:(3:1,3:11)] missing required 'functionName' field + | +3 | @test:Mock + | ^^^^^^^^^^ + error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingAfterFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingAfterFunction.txt index 0d82ae4f677f..45f400b55340 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingAfterFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingAfterFunction.txt @@ -2,5 +2,9 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source after-func-negative.bal -ERROR [after-func-negative.bal:(22:12,22:29)] undefined symbol 'afterFuncNonExist' -error: compilation contains errors \ No newline at end of file +ERROR [after-func-negative.bal:(22:12,22:29)] undefined symbol 'afterFuncNonExist' (BCE2010) + | +22 | after: afterFuncNonExist + | ^^^^^^^^^^^^^^^^^ + +error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingBeforeFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingBeforeFunction.txt index d357e7acaa57..5466561952cb 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingBeforeFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingBeforeFunction.txt @@ -2,5 +2,9 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source before-func-negative.bal -ERROR [before-func-negative.bal:(22:13,22:31)] undefined symbol 'beforeFuncNonExist' -error: compilation contains errors \ No newline at end of file +ERROR [before-func-negative.bal:(22:13,22:31)] undefined symbol 'beforeFuncNonExist' (BCE2010) + | +22 | before: beforeFuncNonExist + | ^^^^^^^^^^^^^^^^^^ + +error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingDependsOnFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingDependsOnFunction.txt index af5514ab7a62..e5f0e38616ac 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingDependsOnFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MissingFunctionsTestCase-testMissingDependsOnFunction.txt @@ -2,5 +2,9 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source depends-on-negative.bal -ERROR [depends-on-negative.bal:(22:17,22:28)] undefined symbol 'nonExisting' -error: compilation contains errors \ No newline at end of file +ERROR [depends-on-negative.bal:(22:17,22:28)] undefined symbol 'nonExisting' (BCE2010) + | +22 | dependsOn: [nonExisting] + | ^^^^^^^^^^^ + +error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking.txt index 2ef5c8d90973..c0062400c0f5 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking.txt @@ -1,113 +1,121 @@ -Compiling source - intg_tests/object_mocking:0.0.0 -WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' - -Running Tests with Coverage - - object_mocking - - testDefaultIncompatibleArgs has failed. - - - testDefaultInvalidMemberReturnValue has failed. - - - testDefaultMockInvalidFieldName has failed. - - - testDefaultMockInvalidReturnValue has failed. - - - testDefaultMockWrongAction has failed. - - - testDefaultTooManyArgs has failed. - - - testMockInvalidStream has failed. - - [pass] testDependentlyTypedFunctions_testDouble - [pass] testDependentlyTypedFunctions_thenReturn - [pass] testMockMemberVariable - [pass] testMockStreamSuccess - [pass] testProvideAReturnSequence - [pass] testProvideAReturnValue - [pass] testProvideAReturnValueBasedOnInput - [pass] testProvideErrorReturnValue - [pass] testUserDefinedMockObject - - [fail] testDefaultIncompatibleArgs: - - error {ballerina/test:0}FunctionSignatureMismatchError ("incorrect type of argument provided at position '1' to mock the function 'get()'") - callableName: validateArgumentsExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 535 - callableName: withArguments moduleName: ballerina.test.0.MemberFunctionStub fileName: mock.bal lineNumber: 160 - callableName: testDefaultIncompatibleArgs moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 56 - callableName: testDefaultIncompatibleArgs$lambda3$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 7 - - - [fail] testDefaultInvalidMemberReturnValue: - - error {ballerina/test:0}InvalidMemberFieldError ("return value provided does not match the type of 'url'") - callableName: thenReturnExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 562 - callableName: thenReturn moduleName: ballerina.test.0.MemberVariableStub fileName: mock.bal lineNumber: 373 - callableName: testDefaultInvalidMemberReturnValue moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 74 - callableName: testDefaultInvalidMemberReturnValue$lambda5$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 9 - - - [fail] testDefaultMockInvalidFieldName: - - error {ballerina/test:0}InvalidMemberFieldError ("invalid field name 'invalidField' provided") - callableName: validateFieldNameExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 526 - callableName: getMember moduleName: ballerina.test.0.MockObject fileName: mock.bal lineNumber: 123 - callableName: testDefaultMockInvalidFieldName moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 65 - callableName: testDefaultMockInvalidFieldName$lambda4$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 8 - - - [fail] testDefaultMockInvalidReturnValue: - - error {ballerina/test:0}FunctionSignatureMismatchError ("return value provided does not match the return type of function 'get()'") - callableName: thenReturnExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 562 - callableName: thenReturn moduleName: ballerina.test.0.MemberFunctionStub fileName: mock.bal lineNumber: 176 - callableName: testDefaultMockInvalidReturnValue moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 35 - callableName: testDefaultMockInvalidReturnValue$lambda0$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 4 - - - [fail] testDefaultMockWrongAction: - - error {ballerina/test:0}FunctionSignatureMismatchError ("return value provided does not match the return type of function 'get()'") - callableName: thenReturnExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 562 - callableName: doNothing moduleName: ballerina.test.0.MemberFunctionStub fileName: mock.bal lineNumber: 208 - callableName: testDefaultMockWrongAction moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 42 - callableName: testDefaultMockWrongAction$lambda1$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 5 - - - [fail] testDefaultTooManyArgs: - - error {ballerina/test:0}FunctionSignatureMismatchError ("too many argument provided to mock the function 'get()'") - callableName: validateArgumentsExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 535 - callableName: withArguments moduleName: ballerina.test.0.MemberFunctionStub fileName: mock.bal lineNumber: 160 - callableName: testDefaultTooManyArgs moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 49 - callableName: testDefaultTooManyArgs$lambda2$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 6 - - - [fail] testMockInvalidStream: - - error {ballerina/test:0}FunctionSignatureMismatchError ("return value provided does not match the return type of function 'get_stream()'") - callableName: thenReturnExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 562 - callableName: thenReturn moduleName: ballerina.test.0.MemberFunctionStub fileName: mock.bal lineNumber: 176 - callableName: testMockInvalidStream moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 81 - callableName: testMockInvalidStream$lambda6$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 10 - - - - 9 passing - 7 failing - 0 skipped - - Test execution time :*****s - -Generating Test Report - object-mocking-tests\target\report\test_results.json - -error: there are test failures +Compiling source + intg_tests/object_mocking:0.0.0 +WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Running Tests with Coverage + + object_mocking + + testDefaultIncompatibleArgs has failed. + + + testDefaultInvalidMemberReturnValue has failed. + + + testDefaultMockInvalidFieldName has failed. + + + testDefaultMockInvalidReturnValue has failed. + + + testDefaultMockWrongAction has failed. + + + testDefaultTooManyArgs has failed. + + + testMockInvalidStream has failed. + + [pass] testDependentlyTypedFunctions_testDouble + [pass] testDependentlyTypedFunctions_thenReturn + [pass] testMockMemberVariable + [pass] testMockStreamSuccess + [pass] testProvideAReturnSequence + [pass] testProvideAReturnValue + [pass] testProvideAReturnValueBasedOnInput + [pass] testProvideErrorReturnValue + [pass] testUserDefinedMockObject + + [fail] testDefaultIncompatibleArgs: + + error {ballerina/test:0}FunctionSignatureMismatchError ("incorrect type of argument provided at position '1' to mock the function 'get()'") + callableName: validateArgumentsExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 535 + callableName: withArguments moduleName: ballerina.test.0.MemberFunctionStub fileName: mock.bal lineNumber: 160 + callableName: testDefaultIncompatibleArgs moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 56 + callableName: testDefaultIncompatibleArgs$lambda3$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 7 + + + [fail] testDefaultInvalidMemberReturnValue: + + error {ballerina/test:0}InvalidMemberFieldError ("return value provided does not match the type of 'url'") + callableName: thenReturnExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 562 + callableName: thenReturn moduleName: ballerina.test.0.MemberVariableStub fileName: mock.bal lineNumber: 373 + callableName: testDefaultInvalidMemberReturnValue moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 74 + callableName: testDefaultInvalidMemberReturnValue$lambda5$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 9 + + + [fail] testDefaultMockInvalidFieldName: + + error {ballerina/test:0}InvalidMemberFieldError ("invalid field name 'invalidField' provided") + callableName: validateFieldNameExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 526 + callableName: getMember moduleName: ballerina.test.0.MockObject fileName: mock.bal lineNumber: 123 + callableName: testDefaultMockInvalidFieldName moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 65 + callableName: testDefaultMockInvalidFieldName$lambda4$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 8 + + + [fail] testDefaultMockInvalidReturnValue: + + error {ballerina/test:0}FunctionSignatureMismatchError ("return value provided does not match the return type of function 'get()'") + callableName: thenReturnExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 562 + callableName: thenReturn moduleName: ballerina.test.0.MemberFunctionStub fileName: mock.bal lineNumber: 176 + callableName: testDefaultMockInvalidReturnValue moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 35 + callableName: testDefaultMockInvalidReturnValue$lambda0$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 4 + + + [fail] testDefaultMockWrongAction: + + error {ballerina/test:0}FunctionSignatureMismatchError ("return value provided does not match the return type of function 'get()'") + callableName: thenReturnExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 562 + callableName: doNothing moduleName: ballerina.test.0.MemberFunctionStub fileName: mock.bal lineNumber: 208 + callableName: testDefaultMockWrongAction moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 42 + callableName: testDefaultMockWrongAction$lambda1$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 5 + + + [fail] testDefaultTooManyArgs: + + error {ballerina/test:0}FunctionSignatureMismatchError ("too many argument provided to mock the function 'get()'") + callableName: validateArgumentsExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 535 + callableName: withArguments moduleName: ballerina.test.0.MemberFunctionStub fileName: mock.bal lineNumber: 160 + callableName: testDefaultTooManyArgs moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 49 + callableName: testDefaultTooManyArgs$lambda2$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 6 + + + [fail] testMockInvalidStream: + + error {ballerina/test:0}FunctionSignatureMismatchError ("return value provided does not match the return type of function 'get_stream()'") + callableName: thenReturnExt moduleName: ballerina.test.0 fileName: mock.bal lineNumber: 562 + callableName: thenReturn moduleName: ballerina.test.0.MemberFunctionStub fileName: mock.bal lineNumber: 176 + callableName: testMockInvalidStream moduleName: intg_tests.object_mocking$test.0.tests.main_error_test fileName: tests/main_error_test.bal lineNumber: 81 + callableName: testMockInvalidStream$lambda6$ moduleName: intg_tests.object_mocking$test.0.tests.test_execute-generated_*****lineNumber: 10 + + + + 9 passing + 7 failing + 0 skipped + + Test execution time :*****s + +Generating Test Report + object-mocking-tests\target\report\test_results.json + +error: there are test failures diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases1.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases1.txt index 2f361383543c..c6a0c77262ea 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases1.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases1.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases2.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases2.txt index 8c27559b230d..59b344b1cbee 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases2.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases2.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases3.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases3.txt index 3b88e7e05b1a..49652b41ca3b 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases3.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases3.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases4.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases4.txt index ae9387d341ee..035e917cda53 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases4.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases4.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases5.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases5.txt index ca5934c3ad51..e33d6358c7ed 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases5.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases5.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases6.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases6.txt index 1b34b1af98c1..3b3cb2d1995f 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases6.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases6.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases7.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases7.txt index 50fa436dc175..b5f10e968a9a 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases7.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/MockTest-testObjectMocking_NegativeCases7.txt @@ -1,7 +1,15 @@ Compiling source intg_tests/object_mocking:0.0.0 -WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value -WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' +WARNING [modules\TestHttpClient\main.bal:(64:45,64:82)] this function should explicitly return a value (BCE20350) + | +64 | public isolated function next() returns record {|AttributeDAO value;|}|Error? { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(53:5,53:47)] unused variable 'closeErr' (BCE20403) + | +53 | error? closeErr = attributeStream.close(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running Tests with Coverage diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenAfterEachFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenAfterEachFails.txt index 0c8de27d3b27..9bacccc66c54 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenAfterEachFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenAfterEachFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-afterEach-fails.bal -WARNING [skip-when-afterEach-fails.bal:(30:5,30:18)] unused variable 'i' +WARNING [skip-when-afterEach-fails.bal:(30:5,30:18)] unused variable 'i' (BCE20403) + | +30 | int i = 12/0; + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenAfterFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenAfterFails.txt index 0e6d69a2410f..d2c833dd2a35 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenAfterFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenAfterFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-after-fails.bal -WARNING [skip-when-after-fails.bal:(30:5,30:18)] unused variable 'i' +WARNING [skip-when-after-fails.bal:(30:5,30:18)] unused variable 'i' (BCE20403) + | +30 | int i = 12/0; + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeEachFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeEachFails.txt index 83a329911803..6bb364aeca42 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeEachFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeEachFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-beforeEach-fails.bal -WARNING [skip-when-beforeEach-fails.bal:(25:5,25:18)] unused variable 'i' +WARNING [skip-when-beforeEach-fails.bal:(25:5,25:18)] unused variable 'i' (BCE20403) + | +25 | int i = 12/0; + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeFails.txt index 910433425ba8..8eaf184ff4a7 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-before-fails.bal -WARNING [skip-when-before-fails.bal:(28:5,28:18)] unused variable 'i' +WARNING [skip-when-before-fails.bal:(28:5,28:18)] unused variable 'i' (BCE20403) + | +28 | int i = 12/0; + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeGroupsFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeGroupsFails.txt index a107eab26887..74e2eb715348 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeGroupsFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeGroupsFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-beforeGroups-fails.bal -WARNING [skip-when-beforeGroups-fails.bal:(32:5,32:17)] unused variable 'b' +WARNING [skip-when-beforeGroups-fails.bal:(32:5,32:17)] unused variable 'b' (BCE20403) + | +32 | int b = 2/0; + | ^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeSuiteFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeSuiteFails.txt index c29b4a9c4f02..b962eef8987b 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeSuiteFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenBeforeSuiteFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source skip-when-beforeSuite-fails.bal -WARNING [skip-when-beforeSuite-fails.bal:(24:5,24:18)] unused variable 'i' +WARNING [skip-when-beforeSuite-fails.bal:(24:5,24:18)] unused variable 'i' (BCE20403) + | +24 | int i = 12/0; // This will throw an exception and fail the function + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenDependsOnFunctionFails.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenDependsOnFunctionFails.txt index 68b479077884..e5f2c73ae059 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenDependsOnFunctionFails.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/SkipTestsTestCase-testSkipWhenDependsOnFunctionFails.txt @@ -2,7 +2,11 @@ Code coverage is not yet supported with single bal files. Ignoring the flag and warning: ignoring --includes flag since code coverage is not enabled Compiling source dependson-skip-test.bal -WARNING [dependson-skip-test.bal:(34:5,34:18)] unused variable 'i' +WARNING [dependson-skip-test.bal:(34:5,34:18)] unused variable 'i' (BCE20403) + | +34 | int i = 12/0; + | ^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/TestReportTest-testWarningForCoverageFormatFlag.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/TestReportTest-testWarningForCoverageFormatFlag.txt index fc1daee66f65..503e56ad5a92 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/TestReportTest-testWarningForCoverageFormatFlag.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/TestReportTest-testWarningForCoverageFormatFlag.txt @@ -1,7 +1,11 @@ warning: ignoring --coverage-format flag since code coverage is not enabled Compiling source testerina_report/foo:0.0.0 -WARNING [main.bal:(36:5,36:19)] unused variable 'b' +WARNING [main.bal:(36:5,36:19)] unused variable 'b' (BCE20403) + | +36 | int b = a + 1; + | ^^^^^^^^^^^^^^ + Running Tests diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/TestReportTest-testWarningForReportTools.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/TestReportTest-testWarningForReportTools.txt index 2a632515749e..2620b592690c 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/TestReportTest-testWarningForReportTools.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/TestReportTest-testWarningForReportTools.txt @@ -1,6 +1,10 @@ Compiling source testerina_report/foo:0.0.0 -WARNING [main.bal:(36:5,36:19)] unused variable 'b' +WARNING [main.bal:(36:5,36:19)] unused variable 'b' (BCE20403) + | +36 | int b = a + 1; + | ^^^^^^^^^^^^^^ + Running Tests with Coverage From 151f957e8b4cc1c571234117e96cadcdd03ade0d Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 8 Mar 2024 14:52:25 +0530 Subject: [PATCH 25/55] Add tests for AnnotateDiagnostics --- .../AnnotateDiagnostics.java | 36 +- .../DiagnosticAnnotation.java | 2 +- .../io/ballerina/cli/task/CompileTask.java | 23 +- .../src/main/java/module-info.java | 1 + .../diagnostics/AnnotateDiagnosticsTest.java | 157 +++++ .../bal-error/long-line-expected0.txt | 4 + .../bal-error/long-line-expected1.txt | 4 + .../bal-error/long-line-expected2.txt | 4 + .../bal-error/long-line-expected3.txt | 4 + .../bal-error/long-line-expected4.txt | 4 + .../bal-error/long-line-expected5.txt | 4 + .../bal-error/long-line.bal | 4 + .../bal-error/multi-line-expected.txt | 275 ++++++++ .../bal-error/multi-line.bal | 589 ++++++++++++++++++ .../invalid-token-expected.txt | 4 + .../bal-invalid-error/invalid-token.bal | 8 + .../missing-function-keyword-expected.txt | 4 + .../missing-function-keyword.bal | 5 + .../semicolon-missing-expected.txt | 4 + .../bal-missing-error/semicolon-missing.bal | 6 + .../bal-project-error/project1/.gitignore | 4 + .../bal-project-error/project1/Ballerina.toml | 8 + .../bal-project-error/project1/main.bal | 14 + .../project1/modules/helpers/helpers.bal | 10 + .../modules/helpers/tests/lib_test.bal | 34 + .../project1/modules/util/docalc.bal | 3 + .../project1/modules/util/person.bal | 4 + .../project1/modules/util/tests/lib_test.bal | 34 + .../project1/modules/util/util.bal | 14 + .../bal-project-error/project2/.gitignore | 4 + .../bal-project-error/project2/Ballerina.toml | 8 + .../bal-project-error/project2/main.bal | 18 + .../project2/modules/mymath/mymath.bal | 13 + .../unix/project1-expected.txt | 35 ++ .../unix/project2-expected.txt | 15 + .../windows/project1-expected.txt | 35 ++ .../windows/project2-expected.txt | 15 + .../src/test/resources/testng.xml | 5 + 38 files changed, 1389 insertions(+), 26 deletions(-) rename cli/ballerina-cli/src/main/java/io/ballerina/cli/{utils => diagnostics}/AnnotateDiagnostics.java (86%) rename cli/ballerina-cli/src/main/java/io/ballerina/cli/{utils => diagnostics}/DiagnosticAnnotation.java (99%) create mode 100644 cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected0.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected1.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected2.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/.gitignore create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/Ballerina.toml create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/main.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/helpers.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/tests/lib_test.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/docalc.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/person.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/tests/lib_test.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/util.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/.gitignore create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/Ballerina.toml create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/modules/mymath/mymath.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project1-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project1-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected.txt diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java similarity index 86% rename from cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java rename to cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index 8a8fa34f171d..71bff10e0782 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -16,10 +16,12 @@ * under the License. */ -package io.ballerina.cli.utils; +package io.ballerina.cli.diagnostics; import io.ballerina.compiler.internal.diagnostics.StringDiagnosticProperty; import io.ballerina.projects.Document; +import io.ballerina.projects.ModuleName; +import io.ballerina.projects.Package; import io.ballerina.projects.internal.PackageDiagnostic; import io.ballerina.tools.diagnostics.Diagnostic; import io.ballerina.tools.diagnostics.DiagnosticSeverity; @@ -29,12 +31,15 @@ import org.jline.terminal.TerminalBuilder; import java.io.IOException; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; -import static io.ballerina.cli.utils.DiagnosticAnnotation.NEW_LINE; -import static io.ballerina.cli.utils.DiagnosticAnnotation.SEVERITY_COLORS; -import static io.ballerina.cli.utils.DiagnosticAnnotation.getColoredString; +import static io.ballerina.cli.diagnostics.DiagnosticAnnotation.NEW_LINE; +import static io.ballerina.cli.diagnostics.DiagnosticAnnotation.SEVERITY_COLORS; +import static io.ballerina.cli.diagnostics.DiagnosticAnnotation.getColoredString; /** * This class is used to generate diagnostic annotations from diagnostics. @@ -80,6 +85,29 @@ public static Ansi renderDiagnostic(Diagnostic diagnostic, boolean colorEnabled) return Ansi.ansi().render(diagnosticToString(diagnostic, colorEnabled)); } + public static Map getDocumentMap(Package currentPackage) { + Map documentMap = new HashMap<>(); + currentPackage.moduleIds().forEach(moduleId -> { + currentPackage.module(moduleId).documentIds().forEach(documentId -> { + Document document = currentPackage.module(moduleId).document(documentId); + documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); + }); + currentPackage.module(moduleId).testDocumentIds().forEach(documentId -> { + Document document = currentPackage.module(moduleId).document(documentId); + documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); + }); + }); + + return documentMap; + } + + private static String getDocumentPath(ModuleName moduleName, String documentName) { + if (moduleName.isDefaultModuleName()) { + return documentName; + } + return Paths.get("modules", moduleName.moduleNamePart(), documentName).toString(); + } + private static String diagnosticToString(Diagnostic diagnostic, boolean colorEnabled) { DiagnosticSeverity severity = diagnostic.diagnosticInfo().severity(); String severityString = severity.toString(); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java similarity index 99% rename from cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java rename to cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index 79d13702209a..ec9cb53a4af9 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -16,7 +16,7 @@ * under the License. */ -package io.ballerina.cli.utils; +package io.ballerina.cli.diagnostics; import io.ballerina.tools.diagnostics.DiagnosticSeverity; diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index cec7de2aa6d0..e7331c0aa105 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -18,7 +18,7 @@ package io.ballerina.cli.task; -import io.ballerina.cli.utils.AnnotateDiagnostics; +import io.ballerina.cli.diagnostics.AnnotateDiagnostics; import io.ballerina.cli.utils.BuildTime; import io.ballerina.projects.CodeGeneratorResult; import io.ballerina.projects.CodeModifierResult; @@ -228,22 +228,10 @@ public void execute(Project project) { // HashSet to keep track of the diagnostics to avoid duplicate diagnostics Set diagnosticSet = new HashSet<>(); - // HashMap for documents based on filename - Map documentMap = new HashMap<>(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(project.currentPackage()); int terminalWidth = AnnotateDiagnostics.getTerminalWidth(); boolean colorEnabled = terminalWidth != 0; - Package currentPackage = project.currentPackage(); - currentPackage.moduleIds().forEach(moduleId -> { - currentPackage.module(moduleId).documentIds().forEach(documentId -> { - Document document = currentPackage.module(moduleId).document(documentId); - documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); - }); - currentPackage.module(moduleId).testDocumentIds().forEach(documentId -> { - Document document = currentPackage.module(moduleId).document(documentId); - documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); - }); - }); // Report package compilation and backend diagnostics diagnostics.addAll(jBallerinaBackend.diagnosticResult().diagnostics(false)); diagnostics.forEach(d -> { @@ -278,13 +266,6 @@ public void execute(Project project) { } } - private String getDocumentPath(ModuleName moduleName, String documentName) { - if (moduleName.isDefaultModuleName()) { - return documentName; - } - return Paths.get("modules", moduleName.moduleNamePart(), documentName).toString(); - } - private boolean isPackCmdForATemplatePkg(Project project) { return compileForBalPack && project.currentPackage().manifest().template(); } diff --git a/cli/ballerina-cli/src/main/java/module-info.java b/cli/ballerina-cli/src/main/java/module-info.java index 48866e6f76d6..215e5b2ba5c3 100644 --- a/cli/ballerina-cli/src/main/java/module-info.java +++ b/cli/ballerina-cli/src/main/java/module-info.java @@ -5,6 +5,7 @@ exports io.ballerina.cli.launcher; exports io.ballerina.cli.utils; exports io.ballerina.cli.cmd; + exports io.ballerina.cli.diagnostics; requires io.ballerina.runtime; requires io.ballerina.lang; diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java new file mode 100644 index 000000000000..65720bf7158b --- /dev/null +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -0,0 +1,157 @@ +package io.ballerina.cli.diagnostics; + +import io.ballerina.projects.Document; +import io.ballerina.tools.diagnostics.Diagnostic; +import io.ballerina.tools.diagnostics.DiagnosticSeverity; +import org.ballerinalang.test.BCompileUtil; +import org.ballerinalang.test.CompileResult; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; +import java.util.Objects; + +import static io.ballerina.cli.utils.OsUtils.isWindows; + +public class AnnotateDiagnosticsTest { + + private Path testResources; + + @BeforeClass + public void setup() throws URISyntaxException { + URI testResourcesURI = Objects.requireNonNull( + getClass().getClassLoader().getResource("test-resources")).toURI(); + this.testResources = Paths.get(testResourcesURI).resolve("diagnostics-test-files"); + } + + @Test + public void testMissingTokenAnnotation() throws IOException { + CompileResult result = BCompileUtil.compile( + "test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing.bal"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + String expectedOutput = Files.readString(testResources.resolve("bal-missing-error") + .resolve("semicolon-missing-expected.txt")); + Assert.assertTrue(diagnostics.length > 0); + Diagnostic diagnostic = diagnostics[0]; + Document document = documentMap.get(diagnostic.location().lineRange().fileName()); + String output = AnnotateDiagnostics.renderDiagnostic(diagnostic, document, 999, false).toString(); + Assert.assertEquals(output, expectedOutput); + } + + @Test + public void testMissingFunctionKeywordAnnotation() throws IOException { + CompileResult result = BCompileUtil.compile( + "test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + String expectedOutput = Files.readString(testResources.resolve("bal-missing-error") + .resolve("missing-function-keyword-expected.txt")); + Assert.assertEquals(diagnostics.length, 1); + Diagnostic diagnostic = diagnostics[0]; + Document document = documentMap.get(diagnostic.location().lineRange().fileName()); + String output = AnnotateDiagnostics.renderDiagnostic(diagnostic, document, 999, false).toString(); + Assert.assertEquals(output, expectedOutput); + } + + @Test + void testInvalidTokenAnnotation() throws IOException { + CompileResult result = BCompileUtil.compile( + "test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + String expectedOutput = Files.readString(testResources.resolve("bal-invalid-error") + .resolve("invalid-token-expected.txt")); + Assert.assertEquals(diagnostics.length, 1); + Diagnostic diagnostic = diagnostics[0]; + Document document = documentMap.get(diagnostic.location().lineRange().fileName()); + String output = AnnotateDiagnostics.renderDiagnostic(diagnostic, document, 999, false).toString(); + Assert.assertEquals(output, expectedOutput); + } + + @Test + void testLongLineAnnotation() throws IOException { + int[] terminalWidth = {999, 200, 150, 100, 50, 40}; + CompileResult result = BCompileUtil.compile( + "test-resources/diagnostics-test-files/bal-error/long-line.bal"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + Assert.assertEquals(diagnostics.length, 1); + Diagnostic diagnostic = diagnostics[0]; + Document document = documentMap.get(diagnostic.location().lineRange().fileName()); + for (int i = 0; i < terminalWidth.length; i++) { + String output = + AnnotateDiagnostics.renderDiagnostic(diagnostic, document, terminalWidth[i], false).toString(); + String expectedOutput = + Files.readString(testResources.resolve("bal-error").resolve("long-line-expected" + i + ".txt")); + Assert.assertEquals(output, expectedOutput); + } + } + + @Test + void testProjectErrorAnnotation() throws IOException { + CompileResult result = BCompileUtil.compile( + "test-resources/diagnostics-test-files/bal-project-error/project1"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + String output = getAnnotatedDiagnostics(diagnostics, documentMap); + String expectedOutput = getExpectedOutput(testResources.resolve("bal-project-error"), "project1-expected.txt"); + Assert.assertEquals(output, expectedOutput); + + } + + @Test + void testProjectWarningAnnotation() throws IOException { + CompileResult result = + BCompileUtil.compileWithoutInitInvocation( + "test-resources/diagnostics-test-files/bal-project-error/project2"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + StringBuilder output = new StringBuilder(); + for (Diagnostic diagnostic : diagnostics) { + if (diagnostic.diagnosticInfo().severity() != DiagnosticSeverity.WARNING) { + continue; + } + Document document = documentMap.get(diagnostic.location().lineRange().fileName()); + output.append(AnnotateDiagnostics.renderDiagnostic(diagnostic, document, 999, false).toString()); + output.append(System.lineSeparator()); + } + String expectedOutput = getExpectedOutput(testResources.resolve("bal-project-error"), "project2-expected.txt"); + Assert.assertEquals(output.toString(), expectedOutput); + } + + @Test + void testMultiLineAnnotations() throws IOException { + CompileResult result = BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/multi-line.bal"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + String output = getAnnotatedDiagnostics(diagnostics, documentMap); + String expectedOutput = Files.readString(testResources.resolve("bal-error").resolve("multi-line-expected.txt")); + Assert.assertEquals(output, expectedOutput); + } + + private static String getAnnotatedDiagnostics(Diagnostic[] diagnostics, Map documentMap) { + StringBuilder output = new StringBuilder(); + for (Diagnostic diagnostic : diagnostics) { + Document document = documentMap.get(diagnostic.location().lineRange().fileName()); + output.append(AnnotateDiagnostics.renderDiagnostic(diagnostic, document, 999, false).toString()); + output.append(System.lineSeparator()); + } + return output.toString(); + } + + private static String getExpectedOutput(Path path, String fileName) throws IOException { + if (isWindows()) { + return Files.readString(path.resolve("windows").resolve(fileName)).replaceAll("\r", ""); + } else { + return Files.readString(path.resolve("unix").resolve(fileName)); + } + } +} \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected0.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected0.txt new file mode 100644 index 000000000000..8749b8366e50 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected0.txt @@ -0,0 +1,4 @@ +ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) + | +3 | io:println(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected1.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected1.txt new file mode 100644 index 000000000000..1b2d0bd7dbbc --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected1.txt @@ -0,0 +1,4 @@ +ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) + | +3 | io:println(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 3... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected2.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected2.txt new file mode 100644 index 000000000000..02b160f60537 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected2.txt @@ -0,0 +1,4 @@ +ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) + | +3 | io:println(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 2... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt new file mode 100644 index 000000000000..0138d36c0fd1 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt @@ -0,0 +1,4 @@ +ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) + | +3 | ... + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + ... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt new file mode 100644 index 000000000000..4bff64a76b1a --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt @@ -0,0 +1,4 @@ +ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) + | +3 | ...+ 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + ... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt new file mode 100644 index 000000000000..de23c4c4cac7 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt @@ -0,0 +1,4 @@ +ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) + | +3 | ... 3, 4 + 5 + 6 + 7 + 8 + 9 + "1... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line.bal new file mode 100644 index 000000000000..846c270858ac --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line.bal @@ -0,0 +1,4 @@ +import ballerina/io; +public function main() { + io:println(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40); +} \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt new file mode 100644 index 000000000000..2c8db40fc12b --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt @@ -0,0 +1,275 @@ +ERROR [multi-line.bal:(63:38,63:45)] incompatible types: expected 'Person', found 'Teacher' (BCE2066) + | +63 | Person[] outputPersonList = from Teacher person in personList + | ^^^^^^^ + +ERROR [multi-line.bal:(66:30,66:45)] undeclared field 'lastName' in record 'Teacher' (BCE2119) + | +66 | lastName: person.lastName, + | ^^^^^^^^^^^^^^^ + +ERROR [multi-line.bal:(67:25,67:35)] undeclared field 'age' in record 'Teacher' (BCE2119) + | +67 | age: person.age + | ^^^^^^^^^^ + +ERROR [multi-line.bal:(82:18,82:21)] unknown type 'XYZ' (BCE2069) + | +82 | from XYZ person in personList + | ^^^ + +ERROR [multi-line.bal:(102:20,102:28)] undefined field 'lastName' in record 'Teacher' (BCE2023) + | +102 | lastName: person.lastName + | ^^^^^^^^ + +ERROR [multi-line.bal:(115:32,115:34)] incompatible types: 'int' is not an iterable collection (BCE2800) + | +115 | from var person in 10 + | ^^ + +ERROR [multi-line.bal:(116:19,116:21)] incompatible types: expected 'boolean', found 'int' (BCE2066) + | +116 | where 20 + | ^^ + +ERROR [multi-line.bal:(117:20,117:22)] incompatible types: expected 'Person', found 'int' (BCE2066) + | +117 | select 30; + | ^^ + +ERROR [multi-line.bal:(131:10,134:4)] missing non-defaultable required record field 'lastName' (BCE2520) + | +131 | select { + : | ^ + : | : + : | : +134 | }; + | ^^^^^^^^^ + | + +ERROR [multi-line.bal:(152:13,152:25)] incompatible types: expected 'float', found 'int' (BCE2066) + | +152 | score:invalidScore + | ^^^^^^^^^^^^ + +ERROR [multi-line.bal:(167:22,167:38)] undefined function 'calculateScore' (BCE2011) + | +167 | let float avgScore=calculateScore() + | ^^^^^^^^^^^^^^^^ + +ERROR [multi-line.bal:(204:8,204:34)] invalid record binding pattern; unknown field 'fname' in record type 'Student' (BCE2576) + | +204 | from var {fname,lastName,score} in studentList + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [multi-line.bal:(206:15,206:20)] undefined symbol 'fname' (BCE2010) + | +206 | firstName: fname, + | ^^^^^ + +ERROR [multi-line.bal:(221:10,221:17)] incompatible types: expected 'Student', found '(string|float)' (BCE2066) + | +221 | select student; + | ^^^^^^^ + +ERROR [multi-line.bal:(240:13,240:18)] incompatible types: expected 'Address', found 'map' (BCE2066) + | +240 | address: addr1 + | ^^^^^ + +ERROR [multi-line.bal:(265:13,265:27)] incompatible types: expected 'FullName[]', found '()' (BCE2066) + | +265 | return outputNameList; + | ^^^^^^^^^^^^^^ + +ERROR [multi-line.bal:(277:24,277:34)] incompatible types: expected 'string', found 'int' (BCE2066) + | +277 | select person.age; + | ^^^^^^^^^^ + +ERROR [multi-line.bal:(291:24,294:18)] a type compatible with mapping constructor expressions not found in type 'string' (BCE2508) + | +291 | select { + : | ^ + : | : + : | : +294 | }; + | ^^^^^^^^^^^^^^^^^ + | + +ERROR [multi-line.bal:(350:36,350:41)] redeclared symbol 'fname' (BCE2008) + | +350 | Employee[] records = from var {fname, lname, age} in entities select {fname, lname, age}; + | ^^^^^ + +ERROR [multi-line.bal:(363:21,363:24)] redeclared symbol 'age' (BCE2008) + | +363 | let int age = 35 + | ^^^ + +ERROR [multi-line.bal:(380:44,380:47)] redeclared symbol 'age' (BCE2008) + | +380 | from var {firstName, lastName, age} in personList + | ^^^ + +ERROR [multi-line.bal:(400:11,400:14)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) + | +400 | table ids = from var x in t select x.id; + | ^^^ + +ERROR [multi-line.bal:(400:22,400:49)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) + | +400 | table ids = from var x in t select x.id; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [multi-line.bal:(410:11,410:14)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) + | +410 | table ids = from var {id} in t select id; + | ^^^ + +ERROR [multi-line.bal:(410:22,410:50)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) + | +410 | table ids = from var {id} in t select id; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [multi-line.bal:(415:29,415:30)] incompatible types: 'int' is not an iterable collection (BCE2800) + | +415 | int[] w = from var a in x + | ^ + +ERROR [multi-line.bal:(420:12,420:64)] incompatible types: expected 'error?', found 'stream' (BCE2066) + | +420 | return stream from string num in clientStream select {a: 1}; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [multi-line.bal:(425:22,425:29)] invalid record binding pattern with type 'anydata' (BCE2607) + | +425 | var x = map from var {k} in keyValsMap + | ^^^^^^^ + +ERROR [multi-line.bal:(426:25,426:26)] undefined symbol 'k' (BCE2010) + | +426 | select k; + | ^ + +ERROR [multi-line.bal:(431:22,431:29)] invalid record binding pattern with type 'any' (BCE2607) + | +431 | var x = map from var {k} in keyValsMap + | ^^^^^^^ + +ERROR [multi-line.bal:(432:25,432:26)] undefined symbol 'k' (BCE2010) + | +432 | select k; + | ^ + +ERROR [multi-line.bal:(450:28,450:30)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) + | +450 | var result = table key(id) from var user in users + | ^^ + +ERROR [multi-line.bal:(455:24,455:26)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) + | +455 | result = table key(id) from var user in userList + | ^^ + +ERROR [multi-line.bal:(468:28,468:30)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) + | +468 | var result = table key(id, firstName) from var user in users + | ^^ + +ERROR [multi-line.bal:(468:32,468:41)] field name 'firstName' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) + | +468 | var result = table key(id, firstName) from var user in users + | ^^^^^^^^^ + +ERROR [multi-line.bal:(473:24,473:26)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) + | +473 | result = table key(id, firstName) from var user in userList + | ^^ + +ERROR [multi-line.bal:(473:28,473:37)] field name 'firstName' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) + | +473 | result = table key(id, firstName) from var user in userList + | ^^^^^^^^^ + +ERROR [multi-line.bal:(489:14,489:17)] incompatible types: expected 'ScoreEventType', found 'int' (BCE2066) + | +489 | _ = from int ev in events + | ^^^ + +ERROR [multi-line.bal:(493:1,493:14)] unknown type 'UndefinedType' (BCE2069) + | +493 | UndefinedType[] undefinedTypeList = []; + | ^^^^^^^^^^^^^ + +ERROR [multi-line.bal:(504:14,504:27)] unknown type 'UndefinedType' (BCE2069) + | +504 | join UndefinedType item in undefinedTypeList + | ^^^^^^^^^^^^^ + +ERROR [multi-line.bal:(513:29,513:31)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) + | +513 | var result1 = table key(id) from var user in users + | ^^ + +ERROR [multi-line.bal:(515:47,515:48)] incompatible types: expected 'error?', found 'int' (BCE2066) + | +515 | select {user} on conflict 1; + | ^ + +ERROR [multi-line.bal:(517:29,517:31)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) + | +517 | var result2 = table key(id) from var user in users + | ^^ + +ERROR [multi-line.bal:(519:47,519:50)] incompatible types: expected 'error?', found '(error|int)' (BCE2066) + | +519 | select {user} on conflict msg; + | ^^^ + +ERROR [multi-line.bal:(524:16,524:17)] incompatible types: expected 'int', found 'string' (BCE2066) + | +524 | select s); + | ^ + +ERROR [multi-line.bal:(529:20,529:28)] incompatible types: expected 'int', found 'string' (BCE2066) + | +529 | select s.trim()); + | ^^^^^^^^ + +WARNING [multi-line.bal:(543:15,543:26)] invalid usage of the 'check' expression operator: no expression type is equivalent to error type (BCE20404) + | +543 | check returnNil(); + | ^^^^^^^^^^^ + +WARNING [multi-line.bal:(552:15,552:26)] invalid usage of the 'check' expression operator: no expression type is equivalent to error type (BCE20404) + | +552 | check returnNil(); + | ^^^^^^^^^^^ + +ERROR [multi-line.bal:(573:13,577:28)] incompatible types: expected 'int', found 'string[]' (BCE2066) + | +573 | from var person in + : | ^^^^^^^^^^^^^^^^^^ + : | : + : | : +577 | select person.firstName; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + +ERROR [multi-line.bal:(583:12,583:28)] incompatible types: expected 'PersonA', found 'string' (BCE2066) + | +583 | select person.firstName; + | ^^^^^^^^^^^^^^^^ + +ERROR [multi-line.bal:(585:28,588:28)] incompatible types: expected 'PersonA', found 'string[]' (BCE2066) + | +585 | PersonA outputPerson = from var person in personList + : | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + : | : + : | : +588 | select person.firstName; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line.bal new file mode 100644 index 000000000000..f779a62fd1e4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line.bal @@ -0,0 +1,589 @@ +// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +// +// WSO2 Inc. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +type Person record {| + string firstName; + string lastName; + int age; +|}; + +type Teacher record {| + string firstName; +|}; + +type Department record {| + string name; +|}; + +type Student record{| + string firstName; + string lastName; + float score; +|}; + +type FullName record{| + string firstName; + string lastName; +|}; + +type Person1 record {| + string firstName; + string lastName; + string deptAccess; + Address address; +|}; + +type Address record{| + string city; + string country; +|}; + + +function testFromClauseWithInvalidType() returns Person[]{ + + Person p1 = {firstName: "Alex", lastName: "George", age: 23}; + Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; + Person p3 = {firstName: "John", lastName: "David", age: 33}; + + Person[] personList = [p1, p2, p3]; + + Person[] outputPersonList = from Teacher person in personList + select { + firstName: person.firstName, + lastName: person.lastName, + age: person.age + }; + + return outputPersonList; +} + +function testFromClauseWithUnDefinedType() returns Person[]{ + + Person p1 = {firstName: "Alex", lastName: "George", age: 23}; + Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; + Person p3 = {firstName: "John", lastName: "David", age: 33}; + + Person[] personList = [p1, p2, p3]; + + Person[] outputPersonList = + from XYZ person in personList + select { + firstName: person.firstName, + lastName: person.lastName, + age: person.age + }; + + return outputPersonList; +} + +function testSelectTypeMismatch() { + Person[] personList = [ + {firstName: "Alex", lastName: "George", age: 23}, + {firstName: "Ranjan", lastName: "Fonseka", age: 30} + ]; + + Teacher[] outputPersonList = + from Person person in personList + select { + firstName: person.firstName, + lastName: person.lastName + }; +} + +function testQueryWithInvalidExpressions() returns Person[]{ + + Person p1 = {firstName: "Alex", lastName: "George", age: 23}; + Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; + Person p3 = {firstName: "John", lastName: "David", age: 33}; + + Person[] personList = [p1, p2, p3]; + + Person[] outputPersonList = + from var person in 10 + where 20 + select 30; + + return outputPersonList; +} + +function testMissingRequiredRecordField() returns Student[]{ + + Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; + Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; + + Student[] studentList = [s1, s2]; + + Student[] outputStudentList= + from var student in studentList + select { + firstName: student.firstName, + score:student.score + }; + + return outputStudentList; +} + +function testInvalidFieldValueInSelect() returns Student[]{ + + Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; + Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; + + Student[] studentList = [s1, s2]; + + Student[] outputStudentList= + from var student in studentList + let int invalidScore=90 + select { + firstName: student.firstName, + lastName:student.lastName, + score:invalidScore + }; + + return outputStudentList; +} + +function testUndefinedFunctionInLet() returns Student[]{ + + Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; + Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; + + Student[] studentList = [s1, s2]; + + Student[] outputStudentList= + from var student in studentList + let float avgScore=calculateScore() + select { + firstName: student.firstName, + lastName:student.lastName, + score:avgScore + }; + + return outputStudentList; +} + +function testDuplicateKeyInSelect() returns Student[]{ + + Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; + Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; + + Student[] studentList = [s1, s2]; + + Student[] outputStudentList= + from var student in studentList + select { + firstName: student.firstName, + lastName:student.lastName, + score:student.score, + lastName:student.lastName + }; + + return outputStudentList; +} + +function testInvalidRecordBindingPattern() returns Student[]{ + + Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; + Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; + + Student[] studentList = [s1, s2]; + + Student[] outputStudentList= + from var {fname,lastName,score} in studentList + select { + firstName: fname, + lastName: lastName, + score: score + }; + + return outputStudentList; +} + +function testIncompatibleTypesInFrom() returns Student[]{ + + Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; + Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; + + Student[] outputStudentList= + from var student in s1 + select student; + + return outputStudentList; +} + +function testMapAssignmetToRecordTypesWithRequiredFields() returns Person1[]{ + + Person1 p1 = {firstName: "Alex", lastName: "George", deptAccess: "XYZ", address:{city:"NY", country:"America"}}; + Person1 p2 = {firstName: "Ranjan", lastName: "Fonseka", deptAccess: "XYZ", address:{city:"NY", country:"America"}}; + + Person1[] personList = [p1, p2]; + map addr1 = {city:"Manchester",country:"UK"}; + + Person1[] outputPersonList= + from var person in personList + select { + firstName: person.firstName, + lastName: person.lastName, + deptAccess: person.deptAccess, + address: addr1 + }; + + return outputPersonList; +} + +function testReassignValueInLet() returns FullName[]{ + + Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; + Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; + + Student[] studentList = [s1, s2]; + FullName[] nameList = []; + + var outputNameList = + from var student in studentList + let float twiceScore = (student.score * 2.0) + do { + twiceScore = 1000; + if(twiceScore < 50.00){ + FullName fullname = {firstName:student.firstName,lastName:student.lastName}; + nameList.push(fullname); + } + }; + + return outputNameList; +} + +function testQueryExprForString() returns string { + Person p1 = {firstName: "Alex", lastName: "George", age: 23}; + Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; + Person p3 = {firstName: "John", lastName: "David", age: 33}; + + Person[] personList = [p1, p2, p3]; + + string outputNameString = + from var person in personList + select person.age; + + return outputNameString; +} + +function testQueryExprForString2() returns string { + Person p1 = {firstName: "Alex", lastName: "George", age: 23}; + Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; + Person p3 = {firstName: "John", lastName: "David", age: 33}; + + Person[] personList = [p1, p2, p3]; + + string outputNameString = + from var person in personList + select { + firstName: person.firstName, + lastName: person.lastName + }; + + return outputNameString; +} + +function testQueryExprWithAmbigousTypeForXML() { + xml book1 = xml ` + Sherlock Holmes + Sir Arthur Conan Doyle + `; + + xml book2 = xml ` + The Da Vinci Code + Dan Brown + `; + + xml book = book1 + book2; + + xml|xml[] books = from var x in book/ + select x; + +} + +function testQueryExprWithAmbigousTypeForString() { + Person p1 = {firstName: "Alex", lastName: "George", age: 23}; + Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; + Person p3 = {firstName: "John", lastName: "David", age: 33}; + + Person[] personList = [p1, p2, p3]; + + string|string[] outputNameString = + from var person in personList + select person.firstName; +} + +type EmployeeEntity record { + int id; + string fname; + string lname; + int age; +}; + +type Employee record {| + string fname; + string lname; + int age; +|}; + +function testVariableShadowingWithQueryExpressions() { + string fname = ""; + EmployeeEntity[] entities = [ + {id: 1232, fname: "Sameera", lname: "Jayasoma", age: 30}, + {id: 1232, fname: "Asanthi", lname: "Kulasinghe", age: 30}, + {id: 1232, fname: "Khiana", lname: "Jayasoma", age: 2} + ]; + + Employee[] records = from var {fname, lname, age} in entities select {fname, lname, age}; +} + +public function testMethodParamWithLet(int age) { + + Person p1 = {firstName: "Alex", lastName: "George", age: 23}; + Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; + Person p3 = {firstName: "John", lastName: "David", age: 33}; + + Person[] personList = [p1, p2, p3]; + + Person[] outputPersonList = + from var person in personList + let int age = 35 + select { + firstName: person.firstName, + lastName: person.lastName, + age: age + }; +} + +public function testMethodParamInQuery(int age) { + + Person p1 = {firstName: "Alex", lastName: "George", age: 23}; + Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; + Person p3 = {firstName: "John", lastName: "David", age: 33}; + + Person[] personList = [p1, p2, p3]; + + Person[] outputPersonList = + from var {firstName, lastName, age} in personList + select { + firstName: firstName, + lastName: lastName, + age: age + }; +} + +type TableRecord record { + readonly string name; + int id; +}; + +function testTableWithNonMappingType() { + + table key(name) t = table [ + {name: "Amy", id: 1234}, + {name: "John", id: 4567} + ]; + + table ids = from var x in t select x.id; +} + +function testTableWithNonMappingTypeWithBindingPatterns() { + + table key(name) t = table [ + {name: "Amy", id: 1234}, + {name: "John", id: 4567} + ]; + + table ids = from var {id} in t select id; +} + +public function testInvalidInputType() { + int x = 1; + int[] w = from var a in x + select 1; +} + +function testIncompatibleSelectType(stream clientStream) returns error? { + return stream from string num in clientStream select {a: 1}; +} + +function testMapBindingPatternsAnydataType() { + map keyValsMap = {foo:"sss", bar:"ffff"}; + var x = map from var {k} in keyValsMap + select k; +} + +function testMapBindingPatternsAnyType() { + map keyValsMap = {foo:"sss", bar:"ffff"}; + var x = map from var {k} in keyValsMap + select k; +} + +type User record { + readonly int id; + readonly string firstName; + string lastName; + int age; +}; + +function testInvalidTypeInSelectWithQueryConstructingTable() { + User u1 = {id: 1, firstName: "John", lastName: "Doe", age: 25}; + User u2 = {id: 2, firstName: "Anne", lastName: "Frank", age: 30}; + + table key(id) users = table []; + users.add(u1); + users.add(u2); + + var result = table key(id) from var user in users + where user.age > 21 && user.age < 60 + select {user}; + + User[] userList = [u1, u2]; + result = table key(id) from var user in userList + where user.age > 21 && user.age < 60 + select {user}; +} + +function testInvalidTypeInSelectWithQueryConstructingTable2() { + User u1 = {id: 1, firstName: "John", lastName: "Doe", age: 25}; + User u2 = {id: 2, firstName: "Anne", lastName: "Frank", age: 30}; + + table key(id) users = table []; + users.add(u1); + users.add(u2); + + var result = table key(id, firstName) from var user in users + where user.age > 21 && user.age < 60 + select {user}; + + User[] userList = [u1, u2]; + result = table key(id, firstName) from var user in userList + where user.age > 21 && user.age < 60 + select {user}; +} + +type ScoreEvent readonly & record {| + string email; + string problemId; + float score; +|}; + +type ScoreEventType ScoreEvent; + +function testInvalidTypeInFromClause() { + ScoreEventType[] events = []; + + _ = from int ev in events + select ev; +} + +UndefinedType[] undefinedTypeList = []; + +public function testVariableOfUndefinedTypeUsedInFromClause() { + int[] _ = from var item in undefinedTypeList + select 1; +} + +int[] customerList = []; + +public function testVariableOfUndefinedTypeUsedInJoin() { + int[] _ = from var customer in customerList + join UndefinedType item in undefinedTypeList + on 1 equals 1 + select 1; +} + +function testInvalidTypeInOnConflictClauseWithQueryConstructingTable() { + User[] users = []; + error|int msg = error("Error"); + + var result1 = table key(id) from var user in users + where user.age > 21 && user.age < 60 + select {user} on conflict 1; + + var result2 = table key(id) from var user in users + where user.age > 21 && user.age < 60 + select {user} on conflict msg; +} + +function testQueryUsedAsFuncArg() { + int len = getLength(from string s in ["A", "B"] + select s); + + string[][] ar = []; + int[][] newAr = from var c in ar + select foo(from var s in c + select s.trim()); +} + +function getLength(int[] arr) returns int { + return arr.length(); +} + +function foo(int[] s) returns int[] { + return s; +} + +function testInvalidCheckExpressionInQueryAction() returns string|error { + from int _ in [1, 3, 5] + do { + check returnNil(); + return "string 1"; + }; + return "string 2"; +} + +function testInvalidCheckExpressionInQueryAction2() returns error? { + from int _ in [1, 3, 5] + do { + check returnNil(); + return; + }; + return; +} + +function returnNil() { +} + +type PersonA record {| + string firstName; + string lastName; + int age; +|}; + +type Persons PersonA[]; + +function testInvalidContextuallyExpectedTypes() { + + PersonA[] personList = []; + int outputPersonList = + from var person in + personList + let int newAge = 20 + where person.age == 33 + select person.firstName; + + Persons outputPersons = + from var person in personList + let int newAge = 20 + where person.age == 33 + select person.firstName; + + PersonA outputPerson = from var person in personList + let int newAge = 20 + where person.age == 33 + select person.firstName; +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token-expected.txt new file mode 100644 index 000000000000..bf0ea0f5c216 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token-expected.txt @@ -0,0 +1,4 @@ +ERROR [invalid-token.bal:(5:16,5:17)] invalid token '=' (BCE0600) + | +5 | int b = 20;= + | ^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal new file mode 100644 index 000000000000..a221f8ef4547 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal @@ -0,0 +1,8 @@ +import ballerina/io; + +public function main() { + int a = 10; + int b = 20;= + int c = a + b; + io:println("Sum of a and b is: ", c); +} \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword-expected.txt new file mode 100644 index 000000000000..0a4d82464fe8 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword-expected.txt @@ -0,0 +1,4 @@ +ERROR [missing-function-keyword.bal:(3:8,3:8)] missing function keyword (BCE0248) + | +3 | public function main() { + | ++++++++ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal new file mode 100644 index 000000000000..8785b9cfe03e --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal @@ -0,0 +1,5 @@ +import ballerina/io; + +public main() { + io:println("Hello Worl"); +} \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing-expected.txt new file mode 100644 index 000000000000..5d0b0099b069 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing-expected.txt @@ -0,0 +1,4 @@ +ERROR [semicolon-missing.bal:(5:1,5:1)] missing semicolon token (BCE0002) + | +5 | ; return; + | + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing.bal new file mode 100644 index 000000000000..41c88fa2d9b7 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing.bal @@ -0,0 +1,6 @@ +public function main(string... str) { + + // Following line is invalid. + int b + return; +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/.gitignore b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/.gitignore new file mode 100644 index 000000000000..99b13f3d09ca --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/.gitignore @@ -0,0 +1,4 @@ +target +generated +Config.toml +Dependencies.toml \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/Ballerina.toml new file mode 100644 index 000000000000..56d23377fe8b --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +org = "radith" +name = "project1" +version = "0.1.0" +distribution = "2201.8.4" + +[build-options] +observabilityIncluded = true diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/main.bal new file mode 100644 index 000000000000..dfa0eee0a93e --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/main.bal @@ -0,0 +1,14 @@ +import ballerina/io; +import asfasdf/adsfadsf; +import project1.util; + +public function main() { + int a = 1; + string b = string `Hello ${a}`; + io:println("Hello, World!"); + io::println(util:hello(b)); + +} +test() { + return; +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/helpers.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/helpers.bal new file mode 100644 index 000000000000..a0ae0e237068 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/helpers.bal @@ -0,0 +1,10 @@ +# Returns the string `Hello` with the input string name. +# +# + name - name as a string +# + return - "Hello, " with the input string name +public function hello2(string name) returns string { + if !(name is "") { + return "Hello, " + name; + } + return "Hello, World!"; + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/tests/lib_test.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/tests/lib_test.bal new file mode 100644 index 000000000000..4767fcad4d9e --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/tests/lib_test.bal @@ -0,0 +1,34 @@ +import ballerina/io; +import ballerina/test; + +// Before Suite Function + +@test:BeforeSuite +function beforeSuiteFunc() { + io:println("I'm the before suite function!"); +} + +// Test function + +@test:Config {} +function testFunction() { + string name = "John"; + string welcomeMsg = hello2(name); + test:assertEquals("Hello, John", welcomeMsg); +} + +// Negative Test function + +@test:Config {} +function negativeTestFunction() { + name = ""; + string welcomeMsg = hello2(name); + test:assertEquals("Hello, World!", welcomeMsg); +} + +// After Suite Function + +@test:AfterSuite +function afterSuiteFunc() { + io:println("I'm the after suite function!"); +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/docalc.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/docalc.bal new file mode 100644 index 000000000000..cf7fa60e95e8 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/docalc.bal @@ -0,0 +1,3 @@ +public function doACalc() returns int{ + return 1 10; +} \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/person.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/person.bal new file mode 100644 index 000000000000..43d3f4a583a7 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/person.bal @@ -0,0 +1,4 @@ +type Person record {| + string name; + int age; +|}; \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/tests/lib_test.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/tests/lib_test.bal new file mode 100644 index 000000000000..31ce10dfbb64 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/tests/lib_test.bal @@ -0,0 +1,34 @@ +import ballerina/io; +import ballerina/test; + +// Before Suite Function + +@test:BeforeSuite +function beforeSuiteFunc() { + io:println("I'm the before suite function!"); +} + +// Test function + +@test:Config {} +function testFunction() { + string name = "John"; + string welcomeMsg = hello(name); + test:assertEquals("Hello, John", welcomeMsg); +} + +// Negative Test function + +@test:Config {} +function negativeTestFunction() { + string name = ""; + string welcomeMsg = hello(name); + test:assertEquals("Hello, World!", welcomeMsg); +} + +// After Suite Function + +@test:AfterSuite +function afterSuiteFunc() { + io:println("I'm the after suite function!"); +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/util.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/util.bal new file mode 100644 index 000000000000..512727034b46 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/util.bal @@ -0,0 +1,14 @@ +import project1.helpers; + +# Returns the string `Hello` with the input string name. +# +# + name - name as a string +# + return - "Hello, " with the input string name +public function hello(string name) returns string { + if !(name is "") { + Person person = {name: name, age: 10}; + return string `Hello, ${person.name}! You are ${person.age.toString()} years old. ${doACalc().toString()}`; + } + + return "Hello, World!" + helpers:hello2("John"); +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/.gitignore b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/.gitignore new file mode 100644 index 000000000000..3749d15ac361 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/.gitignore @@ -0,0 +1,4 @@ +target +generated +Config.toml +Dependencies.toml diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/Ballerina.toml new file mode 100644 index 000000000000..4d24c5ab04b9 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/Ballerina.toml @@ -0,0 +1,8 @@ +[package] +org = "radith" +name = "project2" +version = "0.1.0" +distribution = "2201.8.4" + +[build-options] +observabilityIncluded = true diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal new file mode 100644 index 000000000000..df53f83e373c --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal @@ -0,0 +1,18 @@ +import ballerina/http; +import project2.mymath; + +service / on new http:Listener(9090) { + + resource function get greeting() returns string { + return "Hello, World!"; + } + + resource function get add(int a, int b) returns int { + return mymath:add(a, b); + } + + resource function get subtract(int a, int b) returns int { + return mymath:subtract(a, b); + } + +} \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/modules/mymath/mymath.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/modules/mymath/mymath.bal new file mode 100644 index 000000000000..069b39e64736 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/modules/mymath/mymath.bal @@ -0,0 +1,13 @@ +public function add(int a, int b) returns int { + return a + b; +} + +# Description. +# +# + a - parameter description +# + a - parameter description +# + c - parameter description +# + return - return value description +public function subtract(int a, int b) returns int { + return a - b; +} \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project1-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project1-expected.txt new file mode 100644 index 000000000000..1d4222bd1da6 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project1-expected.txt @@ -0,0 +1,35 @@ +ERROR [modules/helpers/helpers.bal:(10:1,10:1)] missing close brace token (BCE0007) + | +10 | } + | + + +ERROR [modules/helpers/tests/lib_test.bal:(24:5,24:9)] undefined symbol 'name' (BCE2010) + | +24 | name = ""; + | ^^^^ + +ERROR [modules/helpers/tests/lib_test.bal:(25:32,25:36)] undefined symbol 'name' (BCE2010) + | +25 | string welcomeMsg = hello2(name); + | ^^^^ + +ERROR [modules/util/docalc.bal:(2:14,2:14)] missing binary operator (BCE0012) + | +2 | return 1 + 10; + | + + +ERROR [main.bal:(2:1,2:25)] cannot resolve module 'asfasdf/adsfadsf' (BCE2003) + | +2 | import asfasdf/adsfadsf; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [main.bal:(9:7,9:8)] invalid token ':' (BCE0600) + | +9 | io::println(util:hello(b)); + | ^ + +ERROR [main.bal:(12:1,12:1)] missing function keyword (BCE0248) + | +12 | function test() { + | ++++++++ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected.txt new file mode 100644 index 000000000000..d758dde0171e --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected.txt @@ -0,0 +1,15 @@ +WARNING [modules/mymath/mymath.bal:(8:5,8:6)] parameter 'a' already documented (BCE20003) + | +8 | # + a - parameter description + | ^ + +WARNING [modules/mymath/mymath.bal:(9:5,9:6)] no such documentable parameter 'c' (BCE20002) + | +9 | # + c - parameter description + | ^ + +WARNING [modules/mymath/mymath.bal:(11:33,11:38)] undocumented parameter 'b' (BCE20001) + | +11 | public function subtract(int a, int b) returns int { + | ^^^^^ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project1-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project1-expected.txt new file mode 100644 index 000000000000..b2f95dc00a80 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project1-expected.txt @@ -0,0 +1,35 @@ +ERROR [modules\helpers\helpers.bal:(10:1,10:1)] missing close brace token (BCE0007) + | +10 | } + | + + +ERROR [modules\helpers\tests\lib_test.bal:(24:5,24:9)] undefined symbol 'name' (BCE2010) + | +24 | name = ""; + | ^^^^ + +ERROR [modules\helpers\tests\lib_test.bal:(25:32,25:36)] undefined symbol 'name' (BCE2010) + | +25 | string welcomeMsg = hello2(name); + | ^^^^ + +ERROR [modules\util\docalc.bal:(2:14,2:14)] missing binary operator (BCE0012) + | +2 | return 1 + 10; + | + + +ERROR [main.bal:(2:1,2:25)] cannot resolve module 'asfasdf/adsfadsf' (BCE2003) + | +2 | import asfasdf/adsfadsf; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [main.bal:(9:7,9:8)] invalid token ':' (BCE0600) + | +9 | io::println(util:hello(b)); + | ^ + +ERROR [main.bal:(12:1,12:1)] missing function keyword (BCE0248) + | +12 | function test() { + | ++++++++ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected.txt new file mode 100644 index 000000000000..826f7c83906c --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected.txt @@ -0,0 +1,15 @@ +WARNING [modules\mymath\mymath.bal:(8:5,8:6)] parameter 'a' already documented (BCE20003) + | +8 | # + a - parameter description + | ^ + +WARNING [modules\mymath\mymath.bal:(9:5,9:6)] no such documentable parameter 'c' (BCE20002) + | +9 | # + c - parameter description + | ^ + +WARNING [modules\mymath\mymath.bal:(11:33,11:38)] undocumented parameter 'b' (BCE20001) + | +11 | public function subtract(int a, int b) returns int { + | ^^^^^ + diff --git a/cli/ballerina-cli/src/test/resources/testng.xml b/cli/ballerina-cli/src/test/resources/testng.xml index 2b477f334530..043a6a745c33 100644 --- a/cli/ballerina-cli/src/test/resources/testng.xml +++ b/cli/ballerina-cli/src/test/resources/testng.xml @@ -47,4 +47,9 @@ under the License. + + + + + From b061f95972c3c4aa1ac25bb9d43be6b544c792b5 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 8 Mar 2024 14:58:17 +0530 Subject: [PATCH 26/55] Remove unused imports --- .../src/main/java/io/ballerina/cli/task/CompileTask.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index e7331c0aa105..15ed4566f450 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -25,8 +25,6 @@ import io.ballerina.projects.Document; import io.ballerina.projects.JBallerinaBackend; import io.ballerina.projects.JvmTarget; -import io.ballerina.projects.ModuleName; -import io.ballerina.projects.Package; import io.ballerina.projects.PackageCompilation; import io.ballerina.projects.PackageManifest; import io.ballerina.projects.PackageResolution; @@ -47,9 +45,7 @@ import org.wso2.ballerinalang.util.RepoUtils; import java.io.PrintStream; -import java.nio.file.Paths; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; From 0f865324dace9948828769a4e13862ab6003f0d8 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 8 Mar 2024 15:03:19 +0530 Subject: [PATCH 27/55] Add newline --- .../io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index 65720bf7158b..07962beec229 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -154,4 +154,4 @@ private static String getExpectedOutput(Path path, String fileName) throws IOExc return Files.readString(path.resolve("unix").resolve(fileName)); } } -} \ No newline at end of file +} From 4fc62c65d5c614a124f30f000d9fe7f221159384 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Sat, 9 Mar 2024 17:23:09 +0530 Subject: [PATCH 28/55] Fix testerina windows test --- .../cli/diagnostics/AnnotateDiagnostics.java | 3 +- ...DataProviderTest-testCodeFragmentKeys0.txt | 62 +++++++++++-------- ...DataProviderTest-testCodeFragmentKeys1.txt | 62 +++++++++++-------- ...DataProviderTest-testCodeFragmentKeys4.txt | 62 +++++++++++-------- ...DataProviderTest-testCodeFragmentKeys5.txt | 1 + ...DataProviderTest-testCodeFragmentKeys6.txt | 62 +++++++++++-------- ...Test-testCodeFragmentKeysWithWildCard0.txt | 1 + ...Test-testCodeFragmentKeysWithWildCard1.txt | 1 + ...Test-testCodeFragmentKeysWithWildCard2.txt | 1 + ...Test-testCodeFragmentKeysWithWildCard3.txt | 1 + 10 files changed, 147 insertions(+), 109 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index 71bff10e0782..51a93cb368f4 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -94,7 +94,8 @@ public static Map getDocumentMap(Package currentPackage) { }); currentPackage.module(moduleId).testDocumentIds().forEach(documentId -> { Document document = currentPackage.module(moduleId).document(documentId); - documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); + documentMap.put(getDocumentPath(document.module().moduleName(), document.name().replace("/", "\\")), + document); }); }); diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys0.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys0.txt index 36e950726ca0..428e94b2a7ea 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys0.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys0.txt @@ -1,27 +1,35 @@ -Compiling source - intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' - -Running Tests with Coverage - - dataproviders - [pass] testFunction3#`'"\a"" - - - 1 passing - 0 failing - 0 skipped - - Test execution time :*****s - - dataproviders.module1 - - - No tests found - - Test execution time :*****s - -Generating Test Report - data-providers\target\report\test_results.json - +Compiling source + intg_tests/dataproviders:0.0.0 +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + + +Running Tests with Coverage + + dataproviders + [pass] testFunction3#`'"\a"" + + + 1 passing + 0 failing + 0 skipped + + Test execution time :*****s + + dataproviders.module1 + + + No tests found + + Test execution time :*****s + +Generating Test Report + data-providers\target\report\test_results.json + diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys1.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys1.txt index 39b96e58df95..adfdb2c74734 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys1.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys1.txt @@ -1,27 +1,35 @@ -Compiling source - intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' - -Running Tests with Coverage - - dataproviders - [pass] testFunction3#"\u{D7FF}"" " - - - 1 passing - 0 failing - 0 skipped - - Test execution time :*****s - - dataproviders.module1 - - - No tests found - - Test execution time :*****s - -Generating Test Report - data-providers\target\report\test_results.json - +Compiling source + intg_tests/dataproviders:0.0.0 +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + + +Running Tests with Coverage + + dataproviders + [pass] testFunction3#"\u{D7FF}"" " + + + 1 passing + 0 failing + 0 skipped + + Test execution time :*****s + + dataproviders.module1 + + + No tests found + + Test execution time :*****s + +Generating Test Report + data-providers\target\report\test_results.json + diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys4.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys4.txt index a9da367d8d27..b2c4558842b9 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys4.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys4.txt @@ -1,27 +1,35 @@ -Compiling source - intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' - -Running Tests with Coverage - - dataproviders - [pass] testFunction3#(1 - - - 1 passing - 0 failing - 0 skipped - - Test execution time :*****s - - dataproviders.module1 - - - No tests found - - Test execution time :*****s - -Generating Test Report - data-providers\target\report\test_results.json - +Compiling source + intg_tests/dataproviders:0.0.0 +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + + +Running Tests with Coverage + + dataproviders + [pass] testFunction3#(1 + + + 1 passing + 0 failing + 0 skipped + + Test execution time :*****s + + dataproviders.module1 + + + No tests found + + Test execution time :*****s + +Generating Test Report + data-providers\target\report\test_results.json + diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys5.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys5.txt index a3f72c9275a3..2ef6192270ee 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys5.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys5.txt @@ -10,6 +10,7 @@ WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' ( 153 | int a = 9/0; | ^^^^^^^^^^^^ + Running Tests with Coverage dataproviders diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys6.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys6.txt index 59daf1e51894..45f8aedac945 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys6.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeys6.txt @@ -1,27 +1,35 @@ -Compiling source - intg_tests/dataproviders:0.0.0 -WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' -WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' - -Running Tests with Coverage - - dataproviders - [pass] testFunction3#map v = { "x": 1 }; - - - 1 passing - 0 failing - 0 skipped - - Test execution time :*****s - - dataproviders.module1 - - - No tests found - - Test execution time :*****s - -Generating Test Report - data-providers\target\report\test_results.json - +Compiling source + intg_tests/dataproviders:0.0.0 +WARNING [tests\new-data-provider-tests.bal:(121:9,121:21)] unused variable 'a' (BCE20403) + | +121 | int a = 9/0; + | ^^^^^^^^^^^^ + +WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' (BCE20403) + | +153 | int a = 9/0; + | ^^^^^^^^^^^^ + + +Running Tests with Coverage + + dataproviders + [pass] testFunction3#map v = { "x": 1 }; + + + 1 passing + 0 failing + 0 skipped + + Test execution time :*****s + + dataproviders.module1 + + + No tests found + + Test execution time :*****s + +Generating Test Report + data-providers\target\report\test_results.json + diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt index 1e7bc6503126..7e4bc6cadcae 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard0.txt @@ -10,6 +10,7 @@ WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' ( 153 | int a = 9/0; | ^^^^^^^^^^^^ + Running Tests with Coverage dataproviders diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt index 06b6df186bfb..c5e790b08558 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard1.txt @@ -10,6 +10,7 @@ WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' ( 153 | int a = 9/0; | ^^^^^^^^^^^^ + Running Tests with Coverage dataproviders diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt index 47c7b7d170d1..96a3c3e74344 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard2.txt @@ -10,6 +10,7 @@ WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' ( 153 | int a = 9/0; | ^^^^^^^^^^^^ + Running Tests with Coverage dataproviders diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt index abde52e71614..4038469bf3af 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/DataProviderTest-testCodeFragmentKeysWithWildCard3.txt @@ -10,6 +10,7 @@ WARNING [tests\new-data-provider-tests.bal:(153:9,153:21)] unused variable 'a' ( 153 | int a = 9/0; | ^^^^^^^^^^^^ + Running Tests with Coverage dataproviders From bb5bc5ef30f4428406da2024cfb7481436df341c Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Sun, 10 Mar 2024 13:22:02 +0530 Subject: [PATCH 29/55] Handle forward slashes in document names --- .../io/ballerina/cli/diagnostics/AnnotateDiagnostics.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index 51a93cb368f4..96456eb99b42 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -40,6 +40,7 @@ import static io.ballerina.cli.diagnostics.DiagnosticAnnotation.NEW_LINE; import static io.ballerina.cli.diagnostics.DiagnosticAnnotation.SEVERITY_COLORS; import static io.ballerina.cli.diagnostics.DiagnosticAnnotation.getColoredString; +import static io.ballerina.cli.utils.OsUtils.isWindows; /** * This class is used to generate diagnostic annotations from diagnostics. @@ -94,7 +95,7 @@ public static Map getDocumentMap(Package currentPackage) { }); currentPackage.module(moduleId).testDocumentIds().forEach(documentId -> { Document document = currentPackage.module(moduleId).document(documentId); - documentMap.put(getDocumentPath(document.module().moduleName(), document.name().replace("/", "\\")), + documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); }); }); @@ -103,10 +104,11 @@ public static Map getDocumentMap(Package currentPackage) { } private static String getDocumentPath(ModuleName moduleName, String documentName) { + String documentNameFixed = isWindows() ? documentName.replace("/", "\\") : documentName; if (moduleName.isDefaultModuleName()) { - return documentName; + return documentNameFixed; } - return Paths.get("modules", moduleName.moduleNamePart(), documentName).toString(); + return Paths.get("modules", moduleName.moduleNamePart(), documentNameFixed).toString(); } private static String diagnosticToString(Diagnostic diagnostic, boolean colorEnabled) { From b3ac8abd9173c67130eb0a112314bb6323d6d893 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Mon, 11 Mar 2024 10:50:06 +0530 Subject: [PATCH 30/55] Add more tests to improve codecov score --- .../diagnostics/AnnotateDiagnosticsTest.java | 51 ++++++++++++++++--- .../bal-error/tabs-expected.txt | 40 +++++++++++++++ .../diagnostics-test-files/bal-error/tabs.bal | 35 +++++++++++++ .../bal-error/two-line-error-expected.txt | 16 ++++++ .../bal-error/two-line-error.bal | 33 ++++++++++++ .../missing-multiple-keywords-expected.txt | 40 +++++++++++++++ .../missing-multiple-keywords.bal | 35 +++++++++++++ 7 files changed, 242 insertions(+), 8 deletions(-) create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index 07962beec229..1b8242468c54 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -31,7 +31,7 @@ public void setup() throws URISyntaxException { this.testResources = Paths.get(testResourcesURI).resolve("diagnostics-test-files"); } - @Test + @Test(description = "Test annotations when the source file contains missing tokens") public void testMissingTokenAnnotation() throws IOException { CompileResult result = BCompileUtil.compile( "test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing.bal"); @@ -46,7 +46,7 @@ public void testMissingTokenAnnotation() throws IOException { Assert.assertEquals(output, expectedOutput); } - @Test + @Test(description = "Test annotations when the source file contains a missing function keyword") public void testMissingFunctionKeywordAnnotation() throws IOException { CompileResult result = BCompileUtil.compile( "test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal"); @@ -61,7 +61,20 @@ public void testMissingFunctionKeywordAnnotation() throws IOException { Assert.assertEquals(output, expectedOutput); } - @Test + @Test(description = "Test annotations when the source file contains a missing keywords") + public void testMissingMultipleKeywordsAnnotation() throws IOException { + CompileResult result = BCompileUtil.compile( + "test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + String expectedOutput = Files.readString(testResources.resolve("bal-missing-error") + .resolve("missing-multiple-keywords-expected.txt")); + Assert.assertTrue(diagnostics.length > 0); + String output = getAnnotatedDiagnostics(diagnostics, documentMap); + Assert.assertEquals(output, expectedOutput); + } + + @Test(description = "Test annotations when the source file contains invalid tokens") void testInvalidTokenAnnotation() throws IOException { CompileResult result = BCompileUtil.compile( "test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal"); @@ -76,7 +89,7 @@ void testInvalidTokenAnnotation() throws IOException { Assert.assertEquals(output, expectedOutput); } - @Test + @Test(description = "Test annotations when erroneous line is longer than the terminal width. Tests truncation") void testLongLineAnnotation() throws IOException { int[] terminalWidth = {999, 200, 150, 100, 50, 40}; CompileResult result = BCompileUtil.compile( @@ -95,7 +108,7 @@ void testLongLineAnnotation() throws IOException { } } - @Test + @Test(description = "Test annotations when a ballerina project contains errors in multiple files") void testProjectErrorAnnotation() throws IOException { CompileResult result = BCompileUtil.compile( "test-resources/diagnostics-test-files/bal-project-error/project1"); @@ -107,7 +120,7 @@ void testProjectErrorAnnotation() throws IOException { } - @Test + @Test(description = "Test warning annotations in a ballerina project") void testProjectWarningAnnotation() throws IOException { CompileResult result = BCompileUtil.compileWithoutInitInvocation( @@ -127,8 +140,20 @@ void testProjectWarningAnnotation() throws IOException { Assert.assertEquals(output.toString(), expectedOutput); } - @Test - void testMultiLineAnnotations() throws IOException { + @Test(description = "Test annotations spanning two lines in the source file") + void testTwoLinedAnnotations() throws IOException { + CompileResult result = + BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/two-line-error.bal"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + String output = getAnnotatedDiagnostics(diagnostics, documentMap); + String expectedOutput = + Files.readString(testResources.resolve("bal-error").resolve("two-line-error-expected.txt")); + Assert.assertEquals(output, expectedOutput); + } + + @Test(description = "Test annotations when the source file contains diagnostics spanning multiple lines") + void testMultiLinedAnnotations() throws IOException { CompileResult result = BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/multi-line.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); @@ -137,6 +162,16 @@ void testMultiLineAnnotations() throws IOException { Assert.assertEquals(output, expectedOutput); } + @Test(description = "Test annotations when the source file contains tabs instead of spaces") + void testAnnotationsWithTabs() throws IOException { + CompileResult result = BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/tabs.bal"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + String output = getAnnotatedDiagnostics(diagnostics, documentMap); + String expectedOutput = Files.readString(testResources.resolve("bal-error").resolve("tabs-expected.txt")); + Assert.assertEquals(output, expectedOutput); + } + private static String getAnnotatedDiagnostics(Diagnostic[] diagnostics, Map documentMap) { StringBuilder output = new StringBuilder(); for (Diagnostic diagnostic : diagnostics) { diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs-expected.txt new file mode 100644 index 000000000000..6fe97e266d07 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs-expected.txt @@ -0,0 +1,40 @@ +ERROR [tabs.bal:(7:8,7:8)] missing function keyword (BCE0248) + | +7 | public function add(int a, int b) returns int { + | ++++++++ + +ERROR [tabs.bal:(10:9,10:9)] missing if keyword (BCE0262) + | +10 | } else if (b < 0) { + | ++ + +ERROR [tabs.bal:(16:8,16:8)] missing function keyword (BCE0248) + | +16 | public function sub(int a, int b) returns int { + | ++++++++ + +ERROR [tabs.bal:(26:41,26:41)] missing select keyword (BCE0231) + | +26 | int[] numsTimes10 = from var i in nums select i * 10; + | ++++++ + +ERROR [tabs.bal:(27:21,27:21)] missing from keyword (BCE0260) + | +27 | int[] numsTimes2 = from var i in nums select i * 2; + | ++++ + +ERROR [tabs.bal:(28:32,28:32)] missing in keyword (BCE0261) + | +28 | int[] numsTimes3 = from var i in nums select i * 3; + | ++ + +ERROR [tabs.bal:(29:42,29:42)] missing order keyword (BCE0266) + | +29 | int[] numsReversed = from int i in nums order by i descending select i; + | +++++ + +ERROR [tabs.bal:(30:49,30:49)] missing by keyword (BCE0267) + | +30 | int[] numsReversed_ = from int i in nums order by i descending select i; + | ++ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal new file mode 100644 index 000000000000..524e33fa68ef --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal @@ -0,0 +1,35 @@ +import ballerina/io; + +public function main() { + +} + +public add(int a, int b) returns int { + if (a < 0) { + return 0; + } else (b < 0) { + return 0; + } + return a + b; +} + +public sub(int a, int b) returns int { + int count = 0; + while true { + count = count + 1; + } + return a - b; +} + +public function query() { + int[] nums = [1, 2, 3, 4]; + int[] numsTimes10 = from var i in nums i * 10; + int[] numsTimes2 = var i in nums select i * 2; + int[] numsTimes3 = from var i nums select i * 3; + int[] numsReversed = from int i in nums by i descending select i; + int[] numsReversed_ = from int i in nums order i descending select i; + +} + + + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error-expected.txt new file mode 100644 index 000000000000..1713d78bc1f9 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error-expected.txt @@ -0,0 +1,16 @@ +ERROR [two-line-error.bal:(4:33,5:10)] operator '+' not defined for 'int' and 'float' (BCE2070) + | +4 | io:println("Hello, World!", 1 + 2 + | ^^^^^ +5 | + 3.4, true, "Hello, World!"); + | ^^^^^^^^^ + | + +ERROR [two-line-error.bal:(19:41,20:29)] too many arguments in call to 'exponentiate()' (BCE2524) + | +19 | io:println("Hello, World!", 1 + 2 + exponentiate(2, 3 + | ^^^^^^^^^^^^^^^^^ +20 | , true, "Hello, World!")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal new file mode 100644 index 000000000000..5fedad5633b7 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal @@ -0,0 +1,33 @@ +import ballerina/io; + +public function main() { + io:println("Hello, World!", 1 + 2 + + 3.4, true, "Hello, World!"); + // + // + // + // + // + // + // + // + // + // + // + // + + io:println("Hello, World!", 1 + 2 + exponentiate(2, 3 + , true, "Hello, World!")); +} + +public function exponentiate(int base, int exponent) returns int { + if (exponent == 0) { + return 1; + } + if (exponent % 2 == 0) { + int halfResult = exponentiate(base, exponent / 2); + return halfResult * halfResult; + } + return base * exponentiate(base, exponent - 1); +} + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords-expected.txt new file mode 100644 index 000000000000..b6ca69127c7a --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords-expected.txt @@ -0,0 +1,40 @@ +ERROR [missing-multiple-keywords.bal:(7:8,7:8)] missing function keyword (BCE0248) + | +7 | public function add(int a, int b) returns int { + | ++++++++ + +ERROR [missing-multiple-keywords.bal:(10:12,10:12)] missing if keyword (BCE0262) + | +10 | } else if (b < 0) { + | ++ + +ERROR [missing-multiple-keywords.bal:(16:8,16:8)] missing function keyword (BCE0248) + | +16 | public function sub(int a, int b) returns int { + | ++++++++ + +ERROR [missing-multiple-keywords.bal:(26:44,26:44)] missing select keyword (BCE0231) + | +26 | int[] numsTimes10 = from var i in nums select i * 10; + | ++++++ + +ERROR [missing-multiple-keywords.bal:(27:24,27:24)] missing from keyword (BCE0260) + | +27 | int[] numsTimes2 = from var i in nums select i * 2; + | ++++ + +ERROR [missing-multiple-keywords.bal:(28:35,28:35)] missing in keyword (BCE0261) + | +28 | int[] numsTimes3 = from var i in nums select i * 3; + | ++ + +ERROR [missing-multiple-keywords.bal:(29:45,29:45)] missing order keyword (BCE0266) + | +29 | int[] numsReversed = from int i in nums order by i descending select i; + | +++++ + +ERROR [missing-multiple-keywords.bal:(30:52,30:52)] missing by keyword (BCE0267) + | +30 | int[] numsReversed_ = from int i in nums order by i descending select i; + | ++ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal new file mode 100644 index 000000000000..cd2db968c051 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal @@ -0,0 +1,35 @@ +import ballerina/io; + +public function main() { + +} + +public add(int a, int b) returns int { + if (a < 0) { + return 0; + } else (b < 0) { + return 0; + } + return a + b; +} + +public sub(int a, int b) returns int { + int count = 0; + while true { + count = count + 1; + } + return a - b; +} + +public function query() { + int[] nums = [1, 2, 3, 4]; + int[] numsTimes10 = from var i in nums i * 10; + int[] numsTimes2 = var i in nums select i * 2; + int[] numsTimes3 = from var i nums select i * 3; + int[] numsReversed = from int i in nums by i descending select i; + int[] numsReversed_ = from int i in nums order i descending select i; + +} + + + From 95f0cd24e73812b32a864e508fdc3694d0ec8e90 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 12 Mar 2024 11:06:10 +0530 Subject: [PATCH 31/55] Add tests for DiagnosticAnnotation --- .../cli/diagnostics/DiagnosticAnnotation.java | 4 +- .../diagnostics/AnnotateDiagnosticsTest.java | 18 +++++++ .../diagnostics/DiagnosticAnnotationTest.java | 52 +++++++++++++++++++ .../src/test/resources/testng.xml | 1 + 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index ec9cb53a4af9..57b584591234 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -157,7 +157,7 @@ private static int countTabChars(String line, int end) { return count; } - private static TruncateResult truncate(String line, int maxLength, int diagnosticStart, int diagnosticLength) { + protected static TruncateResult truncate(String line, int maxLength, int diagnosticStart, int diagnosticLength) { if (line.length() < maxLength - 3) { return new TruncateResult(line, diagnosticStart, diagnosticLength); } @@ -193,7 +193,7 @@ private static String replaceTabs(String line, int end) { * @param diagnosticStart The start of the diagnostic in the truncated line * @param diagnosticLength The length of the diagnostic in the truncated line */ - private record TruncateResult(String line, int diagnosticStart, int diagnosticLength) { + protected record TruncateResult(String line, int diagnosticStart, int diagnosticLength) { } } diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index 1b8242468c54..6b9c99f1f343 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -172,6 +172,24 @@ void testAnnotationsWithTabs() throws IOException { Assert.assertEquals(output, expectedOutput); } +// @Test +// public void testGetTerminalWidthIOException() throws IOException { +// // Mock the TerminalBuilder +// TerminalBuilder terminalBuilder = mock(TerminalBuilder.class); +// when(terminalBuilder.dumb(true)).thenReturn(terminalBuilder); +// when(terminalBuilder.build()).thenReturn(terminalBuilder); +// when(terminalBuilder.getWidth()).thenThrow(new IOException()); +// +// // Inject the mock TerminalBuilder into your class +// AnnotateDiagnostics.setTerminalBuilder(terminalBuilder); +// +// // Call the method you want to test +// int result = AnnotateDiagnostics.getTerminalWidth(); +// +// // Assert that the result is the expected value (999 in this case) +// Assert.assertEquals(999, result); +// } + private static String getAnnotatedDiagnostics(Diagnostic[] diagnostics, Map documentMap) { StringBuilder output = new StringBuilder(); for (Diagnostic diagnostic : diagnostics) { diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java new file mode 100644 index 000000000000..93472257363f --- /dev/null +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java @@ -0,0 +1,52 @@ +package io.ballerina.cli.diagnostics; + +import io.ballerina.tools.diagnostics.DiagnosticSeverity; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.HashMap; +import java.util.Map; + +public class DiagnosticAnnotationTest { + + @Test + public void testColorAnnotations() { + String errorColor = DiagnosticAnnotation.SEVERITY_COLORS.get(DiagnosticSeverity.ERROR); + String warningColor = DiagnosticAnnotation.SEVERITY_COLORS.get(DiagnosticSeverity.WARNING); + String hintColor = DiagnosticAnnotation.SEVERITY_COLORS.get(DiagnosticSeverity.HINT); + String message = "Hello World!"; + + String error_message = DiagnosticAnnotation.getColoredString(message, errorColor, true); + String expected = + DiagnosticAnnotation.JANSI_ANNOTATOR + "red" + " " + message + DiagnosticAnnotation.JANSI_RESET; + Assert.assertEquals(error_message, expected); + + String warning_message = DiagnosticAnnotation.getColoredString(message, warningColor, true); + expected = DiagnosticAnnotation.JANSI_ANNOTATOR + "yellow" + " " + message + DiagnosticAnnotation.JANSI_RESET; + Assert.assertEquals(warning_message, expected); + + String hint_message = DiagnosticAnnotation.getColoredString(message, hintColor, true); + expected = DiagnosticAnnotation.JANSI_ANNOTATOR + "blue" + " " + message + DiagnosticAnnotation.JANSI_RESET; + Assert.assertEquals(hint_message, expected); + } + + @Test + public void testTruncation() { + String message = "This is a long message that needs to be truncated"; + int importantPartStart = 15; + int importantPartLength = 8; + Map truncatedLines = new HashMap<>(); + truncatedLines.put(30, "This is a long message that..."); + truncatedLines.put(25, "... a long message tha..."); + truncatedLines.put(20, "... long message ..."); + + int[] lengths = {30, 25, 20}; + for (int length : lengths) { + DiagnosticAnnotation.TruncateResult truncatedMessage = + DiagnosticAnnotation.truncate(message, length, importantPartStart, importantPartLength); + String expected = truncatedLines.get(length); + Assert.assertEquals(truncatedMessage.line(), expected); + } + } + +} diff --git a/cli/ballerina-cli/src/test/resources/testng.xml b/cli/ballerina-cli/src/test/resources/testng.xml index 043a6a745c33..ed77ca662b4a 100644 --- a/cli/ballerina-cli/src/test/resources/testng.xml +++ b/cli/ballerina-cli/src/test/resources/testng.xml @@ -50,6 +50,7 @@ under the License. + From 4c4d8fb2d4bbfde2a46cbc559b7c9002381c0fd8 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 12 Mar 2024 13:56:42 +0530 Subject: [PATCH 32/55] Improve truncate function --- .../cli/diagnostics/DiagnosticAnnotation.java | 13 ++++++---- .../diagnostics/DiagnosticAnnotationTest.java | 26 +++++++++++-------- .../bal-error/long-line-expected3.txt | 4 +-- .../bal-error/long-line-expected4.txt | 4 +-- .../bal-error/long-line-expected5.txt | 4 +-- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index 57b584591234..43823c2f97aa 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -161,16 +161,19 @@ protected static TruncateResult truncate(String line, int maxLength, int diagnos if (line.length() < maxLength - 3) { return new TruncateResult(line, diagnosticStart, diagnosticLength); } - if (diagnosticStart + diagnosticLength < maxLength - 3) { + if (diagnosticStart + diagnosticLength <= maxLength - 3) { return new TruncateResult(line.substring(0, maxLength - 3) + "...", diagnosticStart, diagnosticLength); } int diagnosticMid = diagnosticStart + diagnosticLength / 2; int stepsToMoveWindow = Math.max(0, diagnosticMid - maxLength / 2); - int border = Math.min(line.length() - 1, stepsToMoveWindow + maxLength - 6); - int newDiagnosticStart = Math.max(0, diagnosticStart - stepsToMoveWindow + 3); + int border = Math.min(line.length() - 1, stepsToMoveWindow + maxLength - 3); + int newDiagnosticStart = Math.max(3, diagnosticStart - stepsToMoveWindow); int newDiagnosticLength = Math.min(diagnosticLength, maxLength - newDiagnosticStart - 3); - return new TruncateResult("..." + line.substring(stepsToMoveWindow, Math.max(stepsToMoveWindow, border)) - + "...", newDiagnosticStart, Math.max(0, newDiagnosticLength)); + int stringStart = Math.min(stepsToMoveWindow + 3, border); + int stringEnd = border; + + String truncatedLine = "..." + line.substring(stringStart, stringEnd) + "..."; + return new TruncateResult(truncatedLine, newDiagnosticStart, Math.max(0, newDiagnosticLength)); } diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java index 93472257363f..ccc331a318e4 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java @@ -16,31 +16,35 @@ public void testColorAnnotations() { String hintColor = DiagnosticAnnotation.SEVERITY_COLORS.get(DiagnosticSeverity.HINT); String message = "Hello World!"; - String error_message = DiagnosticAnnotation.getColoredString(message, errorColor, true); + String errorMessage = DiagnosticAnnotation.getColoredString(message, errorColor, true); String expected = DiagnosticAnnotation.JANSI_ANNOTATOR + "red" + " " + message + DiagnosticAnnotation.JANSI_RESET; - Assert.assertEquals(error_message, expected); + Assert.assertEquals(errorMessage, expected); - String warning_message = DiagnosticAnnotation.getColoredString(message, warningColor, true); + String warningMessage = DiagnosticAnnotation.getColoredString(message, warningColor, true); expected = DiagnosticAnnotation.JANSI_ANNOTATOR + "yellow" + " " + message + DiagnosticAnnotation.JANSI_RESET; - Assert.assertEquals(warning_message, expected); + Assert.assertEquals(warningMessage, expected); - String hint_message = DiagnosticAnnotation.getColoredString(message, hintColor, true); + String hintMessage = DiagnosticAnnotation.getColoredString(message, hintColor, true); expected = DiagnosticAnnotation.JANSI_ANNOTATOR + "blue" + " " + message + DiagnosticAnnotation.JANSI_RESET; - Assert.assertEquals(hint_message, expected); + Assert.assertEquals(hintMessage, expected); } @Test public void testTruncation() { String message = "This is a long message that needs to be truncated"; int importantPartStart = 15; - int importantPartLength = 8; + int importantPartLength = 7; Map truncatedLines = new HashMap<>(); truncatedLines.put(30, "This is a long message that..."); - truncatedLines.put(25, "... a long message tha..."); - truncatedLines.put(20, "... long message ..."); - - int[] lengths = {30, 25, 20}; + truncatedLines.put(25, "This is a long message..."); + truncatedLines.put(20, "...ong message th..."); + truncatedLines.put(13, "...message..."); + truncatedLines.put(10, "...essa..."); + truncatedLines.put(5, "......"); + truncatedLines.put(0, "......"); + + int[] lengths = {30, 25, 20, 13, 10, 5, 0}; for (int length : lengths) { DiagnosticAnnotation.TruncateResult truncatedMessage = DiagnosticAnnotation.truncate(message, length, importantPartStart, importantPartLength); diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt index 0138d36c0fd1..4dff567c0997 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt @@ -1,4 +1,4 @@ ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) | -3 | ... + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + ... - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +3 | ...3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 ... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt index 4bff64a76b1a..df3ceb4659a8 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt @@ -1,4 +1,4 @@ ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) | -3 | ...+ 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + ... - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +3 | ... + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 ... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt index de23c4c4cac7..9f54212981eb 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt @@ -1,4 +1,4 @@ ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) | -3 | ... 3, 4 + 5 + 6 + 7 + 8 + 9 + "1... - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +3 | ... 4 + 5 + 6 + 7 + 8 + 9 + "10" ... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 89ab5b87353a4e60f800277e10221be2004aad89 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Wed, 20 Mar 2024 15:08:30 +0530 Subject: [PATCH 33/55] Add a workaround for tests not running --- cli/ballerina-cli/src/test/resources/testng.xml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cli/ballerina-cli/src/test/resources/testng.xml b/cli/ballerina-cli/src/test/resources/testng.xml index ed77ca662b4a..171999230815 100644 --- a/cli/ballerina-cli/src/test/resources/testng.xml +++ b/cli/ballerina-cli/src/test/resources/testng.xml @@ -20,6 +20,11 @@ under the License. + + + + + @@ -47,10 +52,4 @@ under the License. - - - - - - From 36a762e9be34125af6e5ac7fee389d1f202bfa86 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Thu, 21 Mar 2024 08:16:39 +0530 Subject: [PATCH 34/55] Fix cannot resolve module error --- .../cli/diagnostics/DiagnosticAnnotation.java | 7 ++-- .../diagnostics/AnnotateDiagnosticsTest.java | 19 ++++----- .../bal-error/long-line-expected0.txt | 6 +-- .../bal-error/long-line-expected1.txt | 6 +-- .../bal-error/long-line-expected2.txt | 6 +-- .../bal-error/long-line-expected3.txt | 4 +- .../bal-error/long-line-expected4.txt | 4 +- .../bal-error/long-line-expected5.txt | 4 +- .../bal-error/long-line.bal | 9 +++-- .../bal-error/multi-line-expected.txt | 4 -- .../bal-error/tabs-expected.txt | 36 ++++++++--------- .../diagnostics-test-files/bal-error/tabs.bal | 2 - .../bal-error/two-line-error-expected.txt | 20 +++++----- .../bal-error/two-line-error.bal | 10 ++--- .../invalid-token-expected.txt | 4 +- .../bal-invalid-error/invalid-token.bal | 3 -- .../missing-function-keyword-expected.txt | 4 +- .../missing-function-keyword.bal | 4 +- .../missing-multiple-keywords-expected.txt | 36 ++++++++--------- .../missing-multiple-keywords.bal | 2 - .../bal-project-error/project1/main.bal | 1 - .../modules/helpers/tests/lib_test.bal | 15 ------- .../unix/project1-expected.txt | 40 ++++++++++++++----- .../windows/project1-expected.txt | 40 ++++++++++++++----- 24 files changed, 148 insertions(+), 138 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index 43823c2f97aa..a028012b4ee1 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -114,8 +114,8 @@ public String toString() { colorEnabled) + NEW_LINE + String.format("%" + endDigitsNum + "d ", startLineNumber + 1) + "| " + result2.line + NEW_LINE + padding + "| " + - getUnderline(0, result2.diagnosticLength, this.severity, this.type, colorEnabled) + NEW_LINE - + padding + "|" + NEW_LINE; + getUnderline(0, result2.diagnosticLength, this.severity, this.type, colorEnabled) + NEW_LINE; + } String padding2 = " ".repeat(Math.min(terminalWidth, maxLineLength) / 2); return padding + "|" + NEW_LINE @@ -128,8 +128,7 @@ public String toString() { + String.format("%" + endDigitsNum + "d ", startLineNumber + lines.size() - 1) + "| " + result2.line + NEW_LINE + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type, colorEnabled) + - NEW_LINE - + padding + "|" + NEW_LINE; + NEW_LINE; } diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index 6b9c99f1f343..3331a9c441f6 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -33,7 +33,7 @@ public void setup() throws URISyntaxException { @Test(description = "Test annotations when the source file contains missing tokens") public void testMissingTokenAnnotation() throws IOException { - CompileResult result = BCompileUtil.compile( + CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); @@ -48,7 +48,7 @@ public void testMissingTokenAnnotation() throws IOException { @Test(description = "Test annotations when the source file contains a missing function keyword") public void testMissingFunctionKeywordAnnotation() throws IOException { - CompileResult result = BCompileUtil.compile( + CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); @@ -63,7 +63,7 @@ public void testMissingFunctionKeywordAnnotation() throws IOException { @Test(description = "Test annotations when the source file contains a missing keywords") public void testMissingMultipleKeywordsAnnotation() throws IOException { - CompileResult result = BCompileUtil.compile( + CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); @@ -76,7 +76,7 @@ public void testMissingMultipleKeywordsAnnotation() throws IOException { @Test(description = "Test annotations when the source file contains invalid tokens") void testInvalidTokenAnnotation() throws IOException { - CompileResult result = BCompileUtil.compile( + CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); @@ -92,7 +92,7 @@ void testInvalidTokenAnnotation() throws IOException { @Test(description = "Test annotations when erroneous line is longer than the terminal width. Tests truncation") void testLongLineAnnotation() throws IOException { int[] terminalWidth = {999, 200, 150, 100, 50, 40}; - CompileResult result = BCompileUtil.compile( + CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-error/long-line.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); @@ -110,7 +110,7 @@ void testLongLineAnnotation() throws IOException { @Test(description = "Test annotations when a ballerina project contains errors in multiple files") void testProjectErrorAnnotation() throws IOException { - CompileResult result = BCompileUtil.compile( + CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-project-error/project1"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); @@ -143,7 +143,7 @@ void testProjectWarningAnnotation() throws IOException { @Test(description = "Test annotations spanning two lines in the source file") void testTwoLinedAnnotations() throws IOException { CompileResult result = - BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/two-line-error.bal"); + BCompileUtil.compileOffline("test-resources/diagnostics-test-files/bal-error/two-line-error.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String output = getAnnotatedDiagnostics(diagnostics, documentMap); @@ -154,7 +154,8 @@ void testTwoLinedAnnotations() throws IOException { @Test(description = "Test annotations when the source file contains diagnostics spanning multiple lines") void testMultiLinedAnnotations() throws IOException { - CompileResult result = BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/multi-line.bal"); + CompileResult result = + BCompileUtil.compileOffline("test-resources/diagnostics-test-files/bal-error/multi-line.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String output = getAnnotatedDiagnostics(diagnostics, documentMap); @@ -164,7 +165,7 @@ void testMultiLinedAnnotations() throws IOException { @Test(description = "Test annotations when the source file contains tabs instead of spaces") void testAnnotationsWithTabs() throws IOException { - CompileResult result = BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/tabs.bal"); + CompileResult result = BCompileUtil.compileOffline("test-resources/diagnostics-test-files/bal-error/tabs.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String output = getAnnotatedDiagnostics(diagnostics, documentMap); diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected0.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected0.txt index 8749b8366e50..fc86cac7ab73 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected0.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected0.txt @@ -1,4 +1,4 @@ -ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) +ERROR [long-line.bal:(2:68,2:96)] operator '+' not defined for 'int' and 'string' (BCE2070) | -3 | io:println(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2 | int c = add(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected1.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected1.txt index 1b2d0bd7dbbc..04b453524ec9 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected1.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected1.txt @@ -1,4 +1,4 @@ -ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) +ERROR [long-line.bal:(2:68,2:96)] operator '+' not defined for 'int' and 'string' (BCE2070) | -3 | io:println(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 3... - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2 | int c = add(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + ... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected2.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected2.txt index 02b160f60537..019f9056d240 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected2.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected2.txt @@ -1,4 +1,4 @@ -ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) +ERROR [long-line.bal:(2:68,2:96)] operator '+' not defined for 'int' and 'string' (BCE2070) | -3 | io:println(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 2... - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2 | int c = add(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + ... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt index 4dff567c0997..ef3e6da93c8a 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt @@ -1,4 +1,4 @@ -ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) +ERROR [long-line.bal:(2:68,2:96)] operator '+' not defined for 'int' and 'string' (BCE2070) | -3 | ...3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 ... +2 | ...3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 ... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt index df3ceb4659a8..5102e1201f15 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt @@ -1,4 +1,4 @@ -ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) +ERROR [long-line.bal:(2:68,2:96)] operator '+' not defined for 'int' and 'string' (BCE2070) | -3 | ... + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 ... +2 | ... + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 ... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt index 9f54212981eb..dc38889bc550 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt @@ -1,4 +1,4 @@ -ERROR [long-line.bal:(3:67,3:95)] operator '+' not defined for 'int' and 'string' (BCE2070) +ERROR [long-line.bal:(2:68,2:96)] operator '+' not defined for 'int' and 'string' (BCE2070) | -3 | ... 4 + 5 + 6 + 7 + 8 + 9 + "10" ... +2 | ... 4 + 5 + 6 + 7 + 8 + 9 + "10" ... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line.bal index 846c270858ac..f78a12df4500 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line.bal @@ -1,4 +1,7 @@ -import ballerina/io; public function main() { - io:println(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40); -} \ No newline at end of file + int c = add(1 + 2 + 3 + 1 + 2 + 3 + 1 + 2 + 3 + 2 + 1 + 2 + 3, 4 + 5 + 6 + 7 + 8 + 9 + "10" + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40); +} + +public function add(int a, int b) returns int { + return a + b; +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt index 2c8db40fc12b..8df8e8343c03 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt @@ -46,7 +46,6 @@ ERROR [multi-line.bal:(131:10,134:4)] missing non-defaultable required record fi : | : 134 | }; | ^^^^^^^^^ - | ERROR [multi-line.bal:(152:13,152:25)] incompatible types: expected 'float', found 'int' (BCE2066) | @@ -96,7 +95,6 @@ ERROR [multi-line.bal:(291:24,294:18)] a type compatible with mapping constructo : | : 294 | }; | ^^^^^^^^^^^^^^^^^ - | ERROR [multi-line.bal:(350:36,350:41)] redeclared symbol 'fname' (BCE2008) | @@ -256,7 +254,6 @@ ERROR [multi-line.bal:(573:13,577:28)] incompatible types: expected 'int', found : | : 577 | select person.firstName; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | ERROR [multi-line.bal:(583:12,583:28)] incompatible types: expected 'PersonA', found 'string' (BCE2066) | @@ -271,5 +268,4 @@ ERROR [multi-line.bal:(585:28,588:28)] incompatible types: expected 'PersonA', f : | : 588 | select person.firstName; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs-expected.txt index 6fe97e266d07..9f17c933f336 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs-expected.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs-expected.txt @@ -1,40 +1,40 @@ -ERROR [tabs.bal:(7:8,7:8)] missing function keyword (BCE0248) +ERROR [tabs.bal:(5:8,5:8)] missing function keyword (BCE0248) | -7 | public function add(int a, int b) returns int { +5 | public function add(int a, int b) returns int { | ++++++++ -ERROR [tabs.bal:(10:9,10:9)] missing if keyword (BCE0262) - | -10 | } else if (b < 0) { - | ++ +ERROR [tabs.bal:(8:9,8:9)] missing if keyword (BCE0262) + | +8 | } else if (b < 0) { + | ++ -ERROR [tabs.bal:(16:8,16:8)] missing function keyword (BCE0248) +ERROR [tabs.bal:(14:8,14:8)] missing function keyword (BCE0248) | -16 | public function sub(int a, int b) returns int { +14 | public function sub(int a, int b) returns int { | ++++++++ -ERROR [tabs.bal:(26:41,26:41)] missing select keyword (BCE0231) +ERROR [tabs.bal:(24:41,24:41)] missing select keyword (BCE0231) | -26 | int[] numsTimes10 = from var i in nums select i * 10; +24 | int[] numsTimes10 = from var i in nums select i * 10; | ++++++ -ERROR [tabs.bal:(27:21,27:21)] missing from keyword (BCE0260) +ERROR [tabs.bal:(25:21,25:21)] missing from keyword (BCE0260) | -27 | int[] numsTimes2 = from var i in nums select i * 2; +25 | int[] numsTimes2 = from var i in nums select i * 2; | ++++ -ERROR [tabs.bal:(28:32,28:32)] missing in keyword (BCE0261) +ERROR [tabs.bal:(26:32,26:32)] missing in keyword (BCE0261) | -28 | int[] numsTimes3 = from var i in nums select i * 3; +26 | int[] numsTimes3 = from var i in nums select i * 3; | ++ -ERROR [tabs.bal:(29:42,29:42)] missing order keyword (BCE0266) +ERROR [tabs.bal:(27:42,27:42)] missing order keyword (BCE0266) | -29 | int[] numsReversed = from int i in nums order by i descending select i; +27 | int[] numsReversed = from int i in nums order by i descending select i; | +++++ -ERROR [tabs.bal:(30:49,30:49)] missing by keyword (BCE0267) +ERROR [tabs.bal:(28:49,28:49)] missing by keyword (BCE0267) | -30 | int[] numsReversed_ = from int i in nums order by i descending select i; +28 | int[] numsReversed_ = from int i in nums order by i descending select i; | ++ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal index 524e33fa68ef..2ffba9f96ab2 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal @@ -1,5 +1,3 @@ -import ballerina/io; - public function main() { } diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error-expected.txt index 1713d78bc1f9..1772be7a93d2 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error-expected.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error-expected.txt @@ -1,16 +1,14 @@ -ERROR [two-line-error.bal:(4:33,5:10)] operator '+' not defined for 'int' and 'float' (BCE2070) - | -4 | io:println("Hello, World!", 1 + 2 - | ^^^^^ -5 | + 3.4, true, "Hello, World!"); - | ^^^^^^^^^ +ERROR [two-line-error.bal:(2:45,3:18)] operator '+' not defined for 'int' and 'string' (BCE2070) | +2 | int a = exponentiate(1 + 2 + 3 + 4 + 5, 3 + 4 + 5 + + | ^^^^^^^^^^^ +3 | "Hello world" + 6 + 7 + 8 + 9 + 10); + | ^^^^^^^^^^^^^^^^^ -ERROR [two-line-error.bal:(19:41,20:29)] too many arguments in call to 'exponentiate()' (BCE2524) +ERROR [two-line-error.bal:(17:13,18:29)] too many arguments in call to 'exponentiate()' (BCE2524) | -19 | io:println("Hello, World!", 1 + 2 + exponentiate(2, 3 - | ^^^^^^^^^^^^^^^^^ -20 | , true, "Hello, World!")); +17 | int d = exponentiate(2, 3 + | ^^^^^^^^^^^^^^^^^ +18 | , true, "Hello, World!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal index 5fedad5633b7..4002f43cf0d0 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal @@ -1,8 +1,6 @@ -import ballerina/io; - public function main() { - io:println("Hello, World!", 1 + 2 - + 3.4, true, "Hello, World!"); + int a = exponentiate(1 + 2 + 3 + 4 + 5, 3 + 4 + 5 + + "Hello world" + 6 + 7 + 8 + 9 + 10); // // // @@ -16,8 +14,8 @@ public function main() { // // - io:println("Hello, World!", 1 + 2 + exponentiate(2, 3 - , true, "Hello, World!")); + int d = exponentiate(2, 3 + , true, "Hello, World!"); } public function exponentiate(int base, int exponent) returns int { diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token-expected.txt index bf0ea0f5c216..82fad03e8d93 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token-expected.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token-expected.txt @@ -1,4 +1,4 @@ -ERROR [invalid-token.bal:(5:16,5:17)] invalid token '=' (BCE0600) +ERROR [invalid-token.bal:(3:16,3:17)] invalid token '=' (BCE0600) | -5 | int b = 20;= +3 | int b = 20;= | ^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal index a221f8ef4547..3d5fd438d34b 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal @@ -1,8 +1,5 @@ -import ballerina/io; - public function main() { int a = 10; int b = 20;= int c = a + b; - io:println("Sum of a and b is: ", c); } \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword-expected.txt index 0a4d82464fe8..1bae3ce48fcd 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword-expected.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword-expected.txt @@ -1,4 +1,4 @@ -ERROR [missing-function-keyword.bal:(3:8,3:8)] missing function keyword (BCE0248) +ERROR [missing-function-keyword.bal:(1:8,1:8)] missing function keyword (BCE0248) | -3 | public function main() { +1 | public function main() { | ++++++++ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal index 8785b9cfe03e..36e8bc8e77ee 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal @@ -1,5 +1,3 @@ -import ballerina/io; - public main() { - io:println("Hello Worl"); + string a = "Hello Worl"; } \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords-expected.txt index b6ca69127c7a..d138573c4534 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords-expected.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords-expected.txt @@ -1,40 +1,40 @@ -ERROR [missing-multiple-keywords.bal:(7:8,7:8)] missing function keyword (BCE0248) +ERROR [missing-multiple-keywords.bal:(5:8,5:8)] missing function keyword (BCE0248) | -7 | public function add(int a, int b) returns int { +5 | public function add(int a, int b) returns int { | ++++++++ -ERROR [missing-multiple-keywords.bal:(10:12,10:12)] missing if keyword (BCE0262) - | -10 | } else if (b < 0) { - | ++ +ERROR [missing-multiple-keywords.bal:(8:12,8:12)] missing if keyword (BCE0262) + | +8 | } else if (b < 0) { + | ++ -ERROR [missing-multiple-keywords.bal:(16:8,16:8)] missing function keyword (BCE0248) +ERROR [missing-multiple-keywords.bal:(14:8,14:8)] missing function keyword (BCE0248) | -16 | public function sub(int a, int b) returns int { +14 | public function sub(int a, int b) returns int { | ++++++++ -ERROR [missing-multiple-keywords.bal:(26:44,26:44)] missing select keyword (BCE0231) +ERROR [missing-multiple-keywords.bal:(24:44,24:44)] missing select keyword (BCE0231) | -26 | int[] numsTimes10 = from var i in nums select i * 10; +24 | int[] numsTimes10 = from var i in nums select i * 10; | ++++++ -ERROR [missing-multiple-keywords.bal:(27:24,27:24)] missing from keyword (BCE0260) +ERROR [missing-multiple-keywords.bal:(25:24,25:24)] missing from keyword (BCE0260) | -27 | int[] numsTimes2 = from var i in nums select i * 2; +25 | int[] numsTimes2 = from var i in nums select i * 2; | ++++ -ERROR [missing-multiple-keywords.bal:(28:35,28:35)] missing in keyword (BCE0261) +ERROR [missing-multiple-keywords.bal:(26:35,26:35)] missing in keyword (BCE0261) | -28 | int[] numsTimes3 = from var i in nums select i * 3; +26 | int[] numsTimes3 = from var i in nums select i * 3; | ++ -ERROR [missing-multiple-keywords.bal:(29:45,29:45)] missing order keyword (BCE0266) +ERROR [missing-multiple-keywords.bal:(27:45,27:45)] missing order keyword (BCE0266) | -29 | int[] numsReversed = from int i in nums order by i descending select i; +27 | int[] numsReversed = from int i in nums order by i descending select i; | +++++ -ERROR [missing-multiple-keywords.bal:(30:52,30:52)] missing by keyword (BCE0267) +ERROR [missing-multiple-keywords.bal:(28:52,28:52)] missing by keyword (BCE0267) | -30 | int[] numsReversed_ = from int i in nums order by i descending select i; +28 | int[] numsReversed_ = from int i in nums order by i descending select i; | ++ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal index cd2db968c051..0c063b057540 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal @@ -1,5 +1,3 @@ -import ballerina/io; - public function main() { } diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/main.bal index dfa0eee0a93e..f385f6590e92 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/main.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/main.bal @@ -1,4 +1,3 @@ -import ballerina/io; import asfasdf/adsfadsf; import project1.util; diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/tests/lib_test.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/tests/lib_test.bal index 4767fcad4d9e..1c84bf966436 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/tests/lib_test.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/tests/lib_test.bal @@ -1,13 +1,5 @@ -import ballerina/io; import ballerina/test; -// Before Suite Function - -@test:BeforeSuite -function beforeSuiteFunc() { - io:println("I'm the before suite function!"); -} - // Test function @test:Config {} @@ -25,10 +17,3 @@ function negativeTestFunction() { string welcomeMsg = hello2(name); test:assertEquals("Hello, World!", welcomeMsg); } - -// After Suite Function - -@test:AfterSuite -function afterSuiteFunc() { - io:println("I'm the after suite function!"); -} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project1-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project1-expected.txt index 1d4222bd1da6..567568cf8090 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project1-expected.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project1-expected.txt @@ -3,14 +3,14 @@ ERROR [modules/helpers/helpers.bal:(10:1,10:1)] missing close brace token (BCE00 10 | } | + -ERROR [modules/helpers/tests/lib_test.bal:(24:5,24:9)] undefined symbol 'name' (BCE2010) +ERROR [modules/helpers/tests/lib_test.bal:(16:5,16:9)] undefined symbol 'name' (BCE2010) | -24 | name = ""; +16 | name = ""; | ^^^^ -ERROR [modules/helpers/tests/lib_test.bal:(25:32,25:36)] undefined symbol 'name' (BCE2010) +ERROR [modules/helpers/tests/lib_test.bal:(17:32,17:36)] undefined symbol 'name' (BCE2010) | -25 | string welcomeMsg = hello2(name); +17 | string welcomeMsg = hello2(name); | ^^^^ ERROR [modules/util/docalc.bal:(2:14,2:14)] missing binary operator (BCE0012) @@ -18,18 +18,38 @@ ERROR [modules/util/docalc.bal:(2:14,2:14)] missing binary operator (BCE0012) 2 | return 1 + 10; | + -ERROR [main.bal:(2:1,2:25)] cannot resolve module 'asfasdf/adsfadsf' (BCE2003) +ERROR [main.bal:(1:1,1:25)] cannot resolve module 'asfasdf/adsfadsf' (BCE2003) | -2 | import asfasdf/adsfadsf; +1 | import asfasdf/adsfadsf; | ^^^^^^^^^^^^^^^^^^^^^^^^ -ERROR [main.bal:(9:7,9:8)] invalid token ':' (BCE0600) +ERROR [main.bal:(7:5,7:32)] undefined function 'println' (BCE2011) | -9 | io::println(util:hello(b)); +7 | io:println("Hello, World!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [main.bal:(7:5,7:32)] undefined module 'io' (BCE2000) + | +7 | io:println("Hello, World!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [main.bal:(8:5,8:31)] undefined function 'println' (BCE2011) + | +8 | io::println(util:hello(b)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [main.bal:(8:5,8:31)] undefined module 'io' (BCE2000) + | +8 | io::println(util:hello(b)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [main.bal:(8:7,8:8)] invalid token ':' (BCE0600) + | +8 | io::println(util:hello(b)); | ^ -ERROR [main.bal:(12:1,12:1)] missing function keyword (BCE0248) +ERROR [main.bal:(11:1,11:1)] missing function keyword (BCE0248) | -12 | function test() { +11 | function test() { | ++++++++ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project1-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project1-expected.txt index b2f95dc00a80..096cdad565d8 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project1-expected.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project1-expected.txt @@ -3,14 +3,14 @@ ERROR [modules\helpers\helpers.bal:(10:1,10:1)] missing close brace token (BCE00 10 | } | + -ERROR [modules\helpers\tests\lib_test.bal:(24:5,24:9)] undefined symbol 'name' (BCE2010) +ERROR [modules\helpers\tests\lib_test.bal:(16:5,16:9)] undefined symbol 'name' (BCE2010) | -24 | name = ""; +16 | name = ""; | ^^^^ -ERROR [modules\helpers\tests\lib_test.bal:(25:32,25:36)] undefined symbol 'name' (BCE2010) +ERROR [modules\helpers\tests\lib_test.bal:(17:32,17:36)] undefined symbol 'name' (BCE2010) | -25 | string welcomeMsg = hello2(name); +17 | string welcomeMsg = hello2(name); | ^^^^ ERROR [modules\util\docalc.bal:(2:14,2:14)] missing binary operator (BCE0012) @@ -18,18 +18,38 @@ ERROR [modules\util\docalc.bal:(2:14,2:14)] missing binary operator (BCE0012) 2 | return 1 + 10; | + -ERROR [main.bal:(2:1,2:25)] cannot resolve module 'asfasdf/adsfadsf' (BCE2003) +ERROR [main.bal:(1:1,1:25)] cannot resolve module 'asfasdf/adsfadsf' (BCE2003) | -2 | import asfasdf/adsfadsf; +1 | import asfasdf/adsfadsf; | ^^^^^^^^^^^^^^^^^^^^^^^^ -ERROR [main.bal:(9:7,9:8)] invalid token ':' (BCE0600) +ERROR [main.bal:(7:5,7:32)] undefined function 'println' (BCE2011) | -9 | io::println(util:hello(b)); +7 | io:println("Hello, World!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [main.bal:(7:5,7:32)] undefined module 'io' (BCE2000) + | +7 | io:println("Hello, World!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [main.bal:(8:5,8:31)] undefined function 'println' (BCE2011) + | +8 | io::println(util:hello(b)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [main.bal:(8:5,8:31)] undefined module 'io' (BCE2000) + | +8 | io::println(util:hello(b)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ERROR [main.bal:(8:7,8:8)] invalid token ':' (BCE0600) + | +8 | io::println(util:hello(b)); | ^ -ERROR [main.bal:(12:1,12:1)] missing function keyword (BCE0248) +ERROR [main.bal:(11:1,11:1)] missing function keyword (BCE0248) | -12 | function test() { +11 | function test() { | ++++++++ From 0fc64f034dbb84a39ab44ec6d5de7cc82215450f Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Thu, 21 Mar 2024 11:44:36 +0530 Subject: [PATCH 35/55] Change back to regular compile method --- .../ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index 3331a9c441f6..47493e320288 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -143,7 +143,7 @@ void testProjectWarningAnnotation() throws IOException { @Test(description = "Test annotations spanning two lines in the source file") void testTwoLinedAnnotations() throws IOException { CompileResult result = - BCompileUtil.compileOffline("test-resources/diagnostics-test-files/bal-error/two-line-error.bal"); + BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/two-line-error.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String output = getAnnotatedDiagnostics(diagnostics, documentMap); @@ -155,7 +155,7 @@ void testTwoLinedAnnotations() throws IOException { @Test(description = "Test annotations when the source file contains diagnostics spanning multiple lines") void testMultiLinedAnnotations() throws IOException { CompileResult result = - BCompileUtil.compileOffline("test-resources/diagnostics-test-files/bal-error/multi-line.bal"); + BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/multi-line.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String output = getAnnotatedDiagnostics(diagnostics, documentMap); @@ -165,7 +165,7 @@ void testMultiLinedAnnotations() throws IOException { @Test(description = "Test annotations when the source file contains tabs instead of spaces") void testAnnotationsWithTabs() throws IOException { - CompileResult result = BCompileUtil.compileOffline("test-resources/diagnostics-test-files/bal-error/tabs.bal"); + CompileResult result = BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/tabs.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String output = getAnnotatedDiagnostics(diagnostics, documentMap); From 03d4b3188ee0bafbbc651520385d5434ac5a231c Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Thu, 21 Mar 2024 12:25:37 +0530 Subject: [PATCH 36/55] Update tests --- .../project1/modules/util/tests/lib_test.bal | 16 ---------------- ...tLegacyMockingFunctionInNonExistingModule.txt | 1 - ...egacyMockingFunctionWithIncompatibleTypes.txt | 1 - ...Case-testLegacyMockingNonExistingFunction.txt | 1 - ...se-testMockingFunctionInNonExistingModule.txt | 1 - ...tLegacyMockingFunctionInNonExistingModule.txt | 1 - ...egacyMockingFunctionWithIncompatibleTypes.txt | 1 - ...Case-testLegacyMockingNonExistingFunction.txt | 1 - ...se-testMockingFunctionInNonExistingModule.txt | 1 - 9 files changed, 24 deletions(-) diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/tests/lib_test.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/tests/lib_test.bal index 31ce10dfbb64..aaa2a2c5bb76 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/tests/lib_test.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/tests/lib_test.bal @@ -1,15 +1,5 @@ -import ballerina/io; import ballerina/test; -// Before Suite Function - -@test:BeforeSuite -function beforeSuiteFunc() { - io:println("I'm the before suite function!"); -} - -// Test function - @test:Config {} function testFunction() { string name = "John"; @@ -26,9 +16,3 @@ function negativeTestFunction() { test:assertEquals("Hello, World!", welcomeMsg); } -// After Suite Function - -@test:AfterSuite -function afterSuiteFunc() { - io:println("I'm the after suite function!"); -} diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt index 082cdf2424b1..aadc06b9a3e6 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt @@ -8,6 +8,5 @@ ERROR [tests/test.bal:(3:1,6:2)] could not find specified module 'intg_tests/mod : | : 6 | } | ^ - | error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt index 5483cdd45e13..434540575a3d 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt @@ -8,6 +8,5 @@ ERROR [tests/test.bal:(6:1,8:2)] incompatible types: expected isolated function : | : 8 | } | ^ - | error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt index 56b54aca5336..3d1c088b0ab8 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt @@ -8,6 +8,5 @@ ERROR [tests/test.bal:(3:1,5:2)] could not find function 'createJdbcClient' in m : | : 5 | } | ^ - | error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt index 082cdf2424b1..aadc06b9a3e6 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/unix/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt @@ -8,6 +8,5 @@ ERROR [tests/test.bal:(3:1,6:2)] could not find specified module 'intg_tests/mod : | : 6 | } | ^ - | error: compilation contains errors \ No newline at end of file diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt index 47311091ea75..e5e81e50f2f5 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionInNonExistingModule.txt @@ -8,6 +8,5 @@ ERROR [tests\test.bal:(3:1,6:2)] could not find specified module 'intg_tests/mod : | : 6 | } | ^ - | error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt index 48ead55f1150..5696bd3b734c 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingFunctionWithIncompatibleTypes.txt @@ -8,6 +8,5 @@ ERROR [tests\test.bal:(6:1,8:2)] incompatible types: expected isolated function : | : 8 | } | ^ - | error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt index fc8aa1226ab8..6bdf21c0ef13 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testLegacyMockingNonExistingFunction.txt @@ -8,6 +8,5 @@ ERROR [tests\test.bal:(3:1,5:2)] could not find function 'createJdbcClient' in m : | : 5 | } | ^ - | error: compilation contains errors diff --git a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt index 47311091ea75..e5e81e50f2f5 100644 --- a/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt +++ b/tests/testerina-integration-test/src/test/resources/command-outputs/windows/InvalidFunctionMockingTestCase-testMockingFunctionInNonExistingModule.txt @@ -8,6 +8,5 @@ ERROR [tests\test.bal:(3:1,6:2)] could not find specified module 'intg_tests/mod : | : 6 | } | ^ - | error: compilation contains errors From 3a9a08031c4d94617192d52cf70c56478bb3da0b Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 22 Mar 2024 10:37:11 +0530 Subject: [PATCH 37/55] Optimize logic and add more tests --- .../cli/diagnostics/AnnotateDiagnostics.java | 19 --------- .../diagnostics/AnnotateDiagnosticsTest.java | 30 ++++++------- .../missing-non-terminal-expected.txt | 42 +++++++++++++++++++ .../missing-non-terminal.bal | 21 ++++++++++ 4 files changed, 76 insertions(+), 36 deletions(-) create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal-expected.txt create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal.bal diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index 96456eb99b42..e61b0c2cc04d 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -190,25 +190,6 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum if (diagnosticCode == INVALID_TOKEN_CODE) { List lines = getLines(textDocument, startLine, endLine); - if (lines.size() > 1) { - String annotatedLine1 = lines.get(0).substring(0, startOffset) + - getColoredString(lines.get(0).substring(startOffset), color, colorEnabled); - String annotatedLine2 = - getColoredString(lines.get(lines.size() - 1).substring(0, endOffset), color, colorEnabled) + - lines.get(lines.size() - 1).substring(endOffset); - lines.set(0, annotatedLine1); - lines.set(lines.size() - 1, annotatedLine2); - return new DiagnosticAnnotation( - lines, - startOffset, - textDocument.line(startLine).length() - location.lineRange().startLine().offset(), - true, - endOffset, - startLine + 1, - DiagnosticSeverity.ERROR, - DiagnosticAnnotation.DiagnosticAnnotationType.INVALID, - terminalWidth, colorEnabled); - } String line = lines.get(0); String annotatedLine = line.substring(0, startOffset) + getColoredString(line.substring(startOffset, endOffset), color, colorEnabled) + diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index 47493e320288..2bcd437b737c 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -173,23 +173,19 @@ void testAnnotationsWithTabs() throws IOException { Assert.assertEquals(output, expectedOutput); } -// @Test -// public void testGetTerminalWidthIOException() throws IOException { -// // Mock the TerminalBuilder -// TerminalBuilder terminalBuilder = mock(TerminalBuilder.class); -// when(terminalBuilder.dumb(true)).thenReturn(terminalBuilder); -// when(terminalBuilder.build()).thenReturn(terminalBuilder); -// when(terminalBuilder.getWidth()).thenThrow(new IOException()); -// -// // Inject the mock TerminalBuilder into your class -// AnnotateDiagnostics.setTerminalBuilder(terminalBuilder); -// -// // Call the method you want to test -// int result = AnnotateDiagnostics.getTerminalWidth(); -// -// // Assert that the result is the expected value (999 in this case) -// Assert.assertEquals(999, result); -// } + @Test(description = "Test non terminal node missing annotations") + void testNonTerminalNodeMissingAnnotation() throws IOException { + CompileResult result = BCompileUtil.compileWithoutInitInvocation( + "test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal.bal"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + String expectedOutput = Files.readString(testResources.resolve("bal-missing-error") + .resolve("missing-non-terminal-expected.txt")); + Assert.assertEquals(diagnostics.length, 8); + String output = getAnnotatedDiagnostics(diagnostics, documentMap); + Assert.assertEquals(output, expectedOutput); + } + private static String getAnnotatedDiagnostics(Diagnostic[] diagnostics, Map documentMap) { StringBuilder output = new StringBuilder(); diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal-expected.txt new file mode 100644 index 000000000000..8a52f45ecd20 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal-expected.txt @@ -0,0 +1,42 @@ +ERROR [missing-non-terminal.bal:(1:12,1:13)] missing enum member (BCE0507) + | +1 | enum Color { + | ^ + +ERROR [missing-non-terminal.bal:(5:9,5:9)] missing identifier (BCE0400) + | +5 | int = 5; + | ^ + +ERROR [missing-non-terminal.bal:(6:12,6:12)] missing identifier (BCE0400) + | +6 | string = "Hello"; + | ^ + +ERROR [missing-non-terminal.bal:(9:9,10:13)] missing select clause (BCE0503) + | + 9 | where i % 2 + | ^^^^^^^^^^^ +10 | == 0 + | ^^^^^^^^^^^^ + +ERROR [missing-non-terminal.bal:(15:17,15:17)] missing function name (BCE0500) + | +15 | public function (int num1, int num2) returns int { + | ^ + +ERROR [missing-non-terminal.bal:(19:31,19:35)] unknown type 'num2' (BCE2069) + | +19 | public function mul(int num1, num2 ) returns int { + | ^^^^ + +ERROR [missing-non-terminal.bal:(19:36,19:36)] missing identifier (BCE0400) + | +19 | public function mul(int num1, num2 ) returns int { + | ^ + +ERROR [missing-non-terminal.bal:(20:19,20:23)] undefined symbol 'num2' (BCE2010) + | +20 | return num1 * num2; + | ^^^^ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal.bal new file mode 100644 index 000000000000..a84e5f10e0ce --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal.bal @@ -0,0 +1,21 @@ +enum Color { +} + +public function main() { + int = 5; + string = "Hello"; + int[] nums = [1, 2, 3, 4]; + int[] evenNums = from int i in nums + where i % 2 + == 0 + ; + +} + +public function (int num1, int num2) returns int { + return num1 + num2; +} + +public function mul(int num1, num2 ) returns int { + return num1 * num2; +} From 8d5cfb142b4e509d36f5796813287ca0352641bf Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 22 Mar 2024 15:34:35 +0530 Subject: [PATCH 38/55] Add newlines and more tests --- .../diagnostics/AnnotateDiagnosticsTest.java | 25 ++++++++++++++++++- .../diagnostics-test-files/bal-error/tabs.bal | 3 --- .../bal-error/two-line-error.bal | 1 - .../bal-invalid-error/invalid-token.bal | 2 +- .../missing-function-keyword.bal | 2 +- .../missing-multiple-keywords.bal | 3 --- .../missing-token-padding-expected.txt | 4 +++ .../project1/modules/helpers/helpers.bal | 1 - .../project1/modules/util/docalc.bal | 2 +- .../project1/modules/util/person.bal | 2 +- .../bal-project-error/project2/main.bal | 2 +- .../project2/modules/mymath/mymath.bal | 2 +- 12 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-token-padding-expected.txt diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index 2bcd437b737c..26918f298687 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -1,6 +1,7 @@ package io.ballerina.cli.diagnostics; import io.ballerina.projects.Document; +import io.ballerina.projects.DocumentConfig; import io.ballerina.tools.diagnostics.Diagnostic; import io.ballerina.tools.diagnostics.DiagnosticSeverity; import org.ballerinalang.test.BCompileUtil; @@ -175,7 +176,7 @@ void testAnnotationsWithTabs() throws IOException { @Test(description = "Test non terminal node missing annotations") void testNonTerminalNodeMissingAnnotation() throws IOException { - CompileResult result = BCompileUtil.compileWithoutInitInvocation( + CompileResult result = BCompileUtil.compile( "test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); @@ -186,6 +187,28 @@ void testNonTerminalNodeMissingAnnotation() throws IOException { Assert.assertEquals(output, expectedOutput); } + @Test(description = "Test missing token annotation padding") + void testMissingTokenAnnotationPadding() throws IOException { + CompileResult result = BCompileUtil.compile( + "test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal"); + Diagnostic[] diagnostics = result.getDiagnostics(); + Assert.assertEquals(diagnostics.length, 1); + + Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + Document document = documentMap.get(diagnostics[0].location().lineRange().fileName()); + int index = diagnostics[0].location().textRange().startOffset(); + + String documentString = " " + document.textDocument().toString().substring(0, index - 1) + + document.textDocument().toString().substring(index); + DocumentConfig documentConfig = DocumentConfig.from(document.documentId(), documentString, document.name()); + Document updatedDocument = Document.from(documentConfig, document.module()); + + String output = AnnotateDiagnostics.renderDiagnostic(diagnostics[0], updatedDocument, 999, false).toString(); + String expectedOutput = Files.readString(testResources.resolve("bal-missing-error") + .resolve("missing-token-padding-expected.txt")); + + Assert.assertEquals(output, expectedOutput); + } private static String getAnnotatedDiagnostics(Diagnostic[] diagnostics, Map documentMap) { StringBuilder output = new StringBuilder(); diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal index 2ffba9f96ab2..e4884bbc44e9 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/tabs.bal @@ -28,6 +28,3 @@ public function query() { int[] numsReversed_ = from int i in nums order i descending select i; } - - - diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal index 4002f43cf0d0..f58d3a804568 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/two-line-error.bal @@ -28,4 +28,3 @@ public function exponentiate(int base, int exponent) returns int { } return base * exponentiate(base, exponent - 1); } - diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal index 3d5fd438d34b..eea1f7760dd2 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal @@ -2,4 +2,4 @@ public function main() { int a = 10; int b = 20;= int c = a + b; -} \ No newline at end of file +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal index 36e8bc8e77ee..1cadff02edc8 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal @@ -1,3 +1,3 @@ public main() { string a = "Hello Worl"; -} \ No newline at end of file +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal index 0c063b057540..10079d424a10 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal @@ -28,6 +28,3 @@ public function query() { int[] numsReversed_ = from int i in nums order i descending select i; } - - - diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-token-padding-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-token-padding-expected.txt new file mode 100644 index 000000000000..24c2958842d1 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-missing-error/missing-token-padding-expected.txt @@ -0,0 +1,4 @@ +ERROR [missing-function-keyword.bal:(1:8,1:8)] missing function keyword (BCE0248) + | +1 | public function main() { + | ++++++++ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/helpers.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/helpers.bal index a0ae0e237068..1ed502e81e0d 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/helpers.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/helpers/helpers.bal @@ -7,4 +7,3 @@ public function hello2(string name) returns string { return "Hello, " + name; } return "Hello, World!"; - diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/docalc.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/docalc.bal index cf7fa60e95e8..c07ca82dc7d4 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/docalc.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/docalc.bal @@ -1,3 +1,3 @@ public function doACalc() returns int{ return 1 10; -} \ No newline at end of file +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/person.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/person.bal index 43d3f4a583a7..54569d530622 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/person.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/modules/util/person.bal @@ -1,4 +1,4 @@ type Person record {| string name; int age; -|}; \ No newline at end of file +|}; diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal index df53f83e373c..d9dc0ea4799d 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal @@ -15,4 +15,4 @@ service / on new http:Listener(9090) { return mymath:subtract(a, b); } -} \ No newline at end of file +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/modules/mymath/mymath.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/modules/mymath/mymath.bal index 069b39e64736..fbbbe6507c9a 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/modules/mymath/mymath.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/modules/mymath/mymath.bal @@ -10,4 +10,4 @@ public function add(int a, int b) returns int { # + return - return value description public function subtract(int a, int b) returns int { return a - b; -} \ No newline at end of file +} From 32e2373804c6b700c9dc9818e1362cc360518e78 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Thu, 28 Mar 2024 14:53:50 +0530 Subject: [PATCH 39/55] Address code review comments --- .../cli/diagnostics/AnnotateDiagnostics.java | 162 +++++++++++------- .../cli/diagnostics/DiagnosticAnnotation.java | 16 +- .../io/ballerina/cli/task/CompileTask.java | 2 +- .../bal-project-error/project1/.gitignore | 2 +- 4 files changed, 104 insertions(+), 78 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index e61b0c2cc04d..156cfce86375 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -20,6 +20,7 @@ import io.ballerina.compiler.internal.diagnostics.StringDiagnosticProperty; import io.ballerina.projects.Document; +import io.ballerina.projects.DocumentId; import io.ballerina.projects.ModuleName; import io.ballerina.projects.Package; import io.ballerina.projects.internal.PackageDiagnostic; @@ -36,6 +37,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; import static io.ballerina.cli.diagnostics.DiagnosticAnnotation.NEW_LINE; import static io.ballerina.cli.diagnostics.DiagnosticAnnotation.SEVERITY_COLORS; @@ -53,16 +55,17 @@ public class AnnotateDiagnostics { private static final int SYNTAX_ERROR_CODE_THRESHOLD = 1000; private static final int MISSING_TOKEN_KEYWORD_CODE_THRESHOLD = 400; private static final int INVALID_TOKEN_CODE = 600; + private static final int NO_TRUNCATE_WIDTH = 999; public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth, boolean colorEnabled) { String diagnosticCode = diagnostic.diagnosticInfo().code(); - if (diagnostic instanceof PackageDiagnostic && diagnosticCode != null && + terminalWidth = terminalWidth == 0 ? NO_TRUNCATE_WIDTH : terminalWidth; + if (diagnostic instanceof PackageDiagnostic packageDiagnostic && diagnosticCode != null && diagnosticCode.startsWith(COMPILER_ERROR_PREFIX)) { int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); if (diagnosticCodeNumber < SYNTAX_ERROR_CODE_THRESHOLD) { - PackageDiagnostic packageDiagnostic = (PackageDiagnostic) diagnostic; return Ansi.ansi() .render(diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + getSyntaxDiagnosticAnnotation( document, packageDiagnostic, diagnosticCodeNumber, terminalWidth, colorEnabled)); @@ -78,7 +81,7 @@ public static int getTerminalWidth() { try { return TerminalBuilder.builder().dumb(true).build().getWidth(); } catch (IOException e) { - return 999; + return NO_TRUNCATE_WIDTH; } } @@ -89,15 +92,12 @@ public static Ansi renderDiagnostic(Diagnostic diagnostic, boolean colorEnabled) public static Map getDocumentMap(Package currentPackage) { Map documentMap = new HashMap<>(); currentPackage.moduleIds().forEach(moduleId -> { - currentPackage.module(moduleId).documentIds().forEach(documentId -> { + Consumer consumer = documentId -> { Document document = currentPackage.module(moduleId).document(documentId); documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); - }); - currentPackage.module(moduleId).testDocumentIds().forEach(documentId -> { - Document document = currentPackage.module(moduleId).document(documentId); - documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), - document); - }); + }; + currentPackage.module(moduleId).documentIds().forEach(consumer); + currentPackage.module(moduleId).testDocumentIds().forEach(consumer); }); return documentMap; @@ -128,20 +128,18 @@ private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document docu DiagnosticSeverity severity, int terminalWidth, boolean colorEnabled) { TextDocument textDocument = document.textDocument(); - int startOffset = location.lineRange().startLine().offset(); - int endOffset = location.lineRange().endLine().offset(); - int startLine = location.lineRange().startLine().line(); - int endLine = location.lineRange().endLine().line(); - boolean isMultiline = startLine != endLine; - int length = isMultiline ? textDocument.line(startLine).length() - startOffset : endOffset - startOffset; + LocationDetails locationDetails = getLocationDetails(location); + boolean isMultiline = locationDetails.startLine != locationDetails.endLine; + int length = isMultiline ? textDocument.line(locationDetails.startLine).length() - locationDetails.startOffset : + locationDetails.endOffset - locationDetails.startOffset; return new DiagnosticAnnotation( - getLines(textDocument, startLine, endLine), - startOffset, + getLines(textDocument, locationDetails.startLine, locationDetails.endLine), + locationDetails.startOffset, length == 0 ? 1 : length, isMultiline, - endOffset, - startLine + 1, + locationDetails.endOffset, + locationDetails.startLine + 1, severity, DiagnosticAnnotation.DiagnosticAnnotationType.REGULAR, terminalWidth, colorEnabled); @@ -153,63 +151,77 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum boolean colorEnabled) { TextDocument textDocument = document.textDocument(); Location location = packageDiagnostic.location(); - int startLine = location.lineRange().startLine().line(); - int startOffset = location.lineRange().startLine().offset(); + LocationDetails locationDetails = getLocationDetails(location); int padding = 0; - int endLine = location.lineRange().endLine().line(); - int endOffset = location.lineRange().endLine().offset(); String color = SEVERITY_COLORS.get(DiagnosticSeverity.ERROR); if (diagnosticCode < MISSING_TOKEN_KEYWORD_CODE_THRESHOLD) { - StringDiagnosticProperty strProperty = (StringDiagnosticProperty) packageDiagnostic.properties().get(0); - String lineString = textDocument.line(startLine).text(); - String missingTokenString = getColoredString(strProperty.value(), color, colorEnabled); - if (startOffset < lineString.length() && lineString.charAt(startOffset) != ' ') { - missingTokenString = missingTokenString + " "; - } - if (startOffset > 0 && lineString.charAt(startOffset - 1) != ' ') { - missingTokenString = " " + missingTokenString; - padding++; - } - - String lineWithMissingToken = lineString.substring(0, startOffset) + missingTokenString + - lineString.substring(startOffset); - List lines = new ArrayList<>(); - lines.add(lineWithMissingToken); - return new DiagnosticAnnotation( - lines, - padding + startOffset, - strProperty.value().length(), - false, - 0, - startLine + 1, - DiagnosticSeverity.ERROR, - DiagnosticAnnotation.DiagnosticAnnotationType.MISSING, - terminalWidth, colorEnabled); + return getMissingTokenAnnotation(packageDiagnostic, textDocument, locationDetails, color, colorEnabled, + terminalWidth, padding); } if (diagnosticCode == INVALID_TOKEN_CODE) { - List lines = getLines(textDocument, startLine, endLine); - String line = lines.get(0); - String annotatedLine = line.substring(0, startOffset) + - getColoredString(line.substring(startOffset, endOffset), color, colorEnabled) + - line.substring(endOffset); - lines.set(0, annotatedLine); - return new DiagnosticAnnotation( - lines, - startOffset, - endOffset - startOffset, - false, - 0, - startLine + 1, - DiagnosticSeverity.ERROR, - DiagnosticAnnotation.DiagnosticAnnotationType.INVALID, - terminalWidth, colorEnabled); + return getInvalidTokenAnnotation(textDocument, locationDetails, color, colorEnabled, terminalWidth); } return getDiagnosticLineFromSyntaxAPI(document, location, DiagnosticSeverity.ERROR, terminalWidth, colorEnabled); } + private static DiagnosticAnnotation getMissingTokenAnnotation(PackageDiagnostic packageDiagnostic, + TextDocument textDocument, + LocationDetails locationDetails, String color, + boolean colorEnabled, int terminalWidth, + int padding) { + StringDiagnosticProperty strProperty = (StringDiagnosticProperty) packageDiagnostic.properties().get(0); + String lineString = textDocument.line(locationDetails.startLine).text(); + String missingTokenString = getColoredString(strProperty.value(), color, colorEnabled); + if (locationDetails.startOffset < lineString.length() && + lineString.charAt(locationDetails.startOffset) != ' ') { + missingTokenString = missingTokenString + " "; + } + if (locationDetails.startOffset > 0 && lineString.charAt(locationDetails.startOffset - 1) != ' ') { + missingTokenString = " " + missingTokenString; + padding++; + } + + String lineWithMissingToken = lineString.substring(0, locationDetails.startOffset) + missingTokenString + + lineString.substring(locationDetails.startOffset); + List lines = new ArrayList<>(); + lines.add(lineWithMissingToken); + return new DiagnosticAnnotation( + lines, + padding + locationDetails.startOffset, + strProperty.value().length(), + false, + 0, + locationDetails.startLine + 1, + DiagnosticSeverity.ERROR, + DiagnosticAnnotation.DiagnosticAnnotationType.MISSING, + terminalWidth, colorEnabled); + } + + private static DiagnosticAnnotation getInvalidTokenAnnotation(TextDocument textDocument, + LocationDetails locationDetails, String color, + boolean colorEnabled, int terminalWidth) { + List lines = getLines(textDocument, locationDetails.startLine, locationDetails.endLine); + String line = lines.get(0); + String annotatedLine = line.substring(0, locationDetails.startOffset) + + getColoredString(line.substring(locationDetails.startOffset, locationDetails.endOffset), color, + colorEnabled) + + line.substring(locationDetails.endOffset); + lines.set(0, annotatedLine); + return new DiagnosticAnnotation( + lines, + locationDetails.startOffset, + locationDetails.endOffset - locationDetails.startOffset, + false, + 0, + locationDetails.startLine + 1, + DiagnosticSeverity.ERROR, + DiagnosticAnnotation.DiagnosticAnnotationType.INVALID, + terminalWidth, colorEnabled); + } + private static List getLines(TextDocument textDocument, int start, int end) { List lines = new ArrayList<>(); for (int i = start; i <= end; i++) { @@ -218,4 +230,24 @@ private static List getLines(TextDocument textDocument, int start, int e return lines; } + private static LocationDetails getLocationDetails(Location location) { + int startLine = location.lineRange().startLine().line(); + int startOffset = location.lineRange().startLine().offset(); + int endLine = location.lineRange().endLine().line(); + int endOffset = location.lineRange().endLine().offset(); + return new LocationDetails(startLine, startOffset, endLine, endOffset); + } + + /** + * Represents the location details of a diagnostic. + * + * @param startLine The start line of the diagnostic. + * @param startOffset The start offset of the diagnostic. + * @param endLine The end line of the diagnostic. + * @param endOffset The end offset of the diagnostic. + */ + private record LocationDetails(int startLine, int startOffset, int endLine, int endOffset) { + + } + } diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index a028012b4ee1..953394c63840 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -74,6 +74,7 @@ public DiagnosticAnnotation(List lines, int start, int length, boolean i this.colorEnabled = colorEnabled; } + @Override public String toString() { if (!isMultiline) { int digitsNum = (int) Math.log10(startLineNumber) + 1; @@ -163,8 +164,8 @@ protected static TruncateResult truncate(String line, int maxLength, int diagnos if (diagnosticStart + diagnosticLength <= maxLength - 3) { return new TruncateResult(line.substring(0, maxLength - 3) + "...", diagnosticStart, diagnosticLength); } - int diagnosticMid = diagnosticStart + diagnosticLength / 2; - int stepsToMoveWindow = Math.max(0, diagnosticMid - maxLength / 2); + int diagnosticMid = diagnosticStart + (diagnosticLength / 2); + int stepsToMoveWindow = Math.max(0, diagnosticMid - (maxLength / 2)); int border = Math.min(line.length() - 1, stepsToMoveWindow + maxLength - 3); int newDiagnosticStart = Math.max(3, diagnosticStart - stepsToMoveWindow); int newDiagnosticLength = Math.min(diagnosticLength, maxLength - newDiagnosticStart - 3); @@ -177,15 +178,8 @@ protected static TruncateResult truncate(String line, int maxLength, int diagnos } private static String replaceTabs(String line, int end) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < end; i++) { - if (line.charAt(i) == '\t') { - sb.append(" "); - } else { - sb.append(line.charAt(i)); - } - } - return sb + line.substring(end); + int endIndex = Math.min(end, line.length()); + return line.substring(0, endIndex).replace("\t", " ") + line.substring(endIndex); } /** diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index 15ed4566f450..ecff61baf094 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -238,7 +238,7 @@ public void execute(Project project) { Document document = documentMap.get(d.location().lineRange().fileName()); if (document != null) { err.println(AnnotateDiagnostics.renderDiagnostic(d, document, - terminalWidth == 0 ? 999 : terminalWidth, colorEnabled)); + terminalWidth, colorEnabled)); } else { err.println(AnnotateDiagnostics.renderDiagnostic(d, colorEnabled)); } diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/.gitignore b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/.gitignore index 99b13f3d09ca..3749d15ac361 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/.gitignore +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/.gitignore @@ -1,4 +1,4 @@ target generated Config.toml -Dependencies.toml \ No newline at end of file +Dependencies.toml From c67a40d7c8696ee7851a5582a5c045e852d04c93 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 29 Mar 2024 09:44:57 +0530 Subject: [PATCH 40/55] Fix tests for new diagnostics --- .../unix/project-with-provided-warning.txt | 12 ++++++++++-- .../unix/run-project-with-provided-dep.txt | 12 ++++++++++-- .../windows/project-with-provided-warning.txt | 12 ++++++++++-- .../windows/run-project-with-provided-dep.txt | 12 ++++++++++-- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/project-with-provided-warning.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/project-with-provided-warning.txt index 0c5296acdd2f..b08037712ac3 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/project-with-provided-warning.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/project-with-provided-warning.txt @@ -1,7 +1,15 @@ Compiling source foo/pkg_b:1.0.0 -WARNING [main.bal:(26:5,26:41)] unused variable 'msgHello' -WARNING [main.bal:(27:5,27:53)] unused variable 'msg' +WARNING [main.bal:(26:5,26:41)] unused variable 'msgHello' (BCE20403) + | +26 | string msgHello = pkg_a:helloCall(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(27:5,27:53)] unused variable 'msg' (BCE20403) + | +27 | handle? msg = greeting(java:fromString("Jane")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Generating executable diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/run-project-with-provided-dep.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/run-project-with-provided-dep.txt index 40189cda7c25..3947e28698dc 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/run-project-with-provided-dep.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/run-project-with-provided-dep.txt @@ -1,6 +1,14 @@ Compiling source foo/pkg_b:1.0.0 -WARNING [main.bal:(26:5,26:41)] unused variable 'msgHello' -WARNING [main.bal:(27:5,27:53)] unused variable 'msg' +WARNING [main.bal:(26:5,26:41)] unused variable 'msgHello' (BCE20403) + | +26 | string msgHello = pkg_a:helloCall(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(27:5,27:53)] unused variable 'msg' (BCE20403) + | +27 | handle? msg = greeting(java:fromString("Jane")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running executable \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/project-with-provided-warning.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/project-with-provided-warning.txt index 8d8206099dfd..3a6b0250097e 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/project-with-provided-warning.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/project-with-provided-warning.txt @@ -1,7 +1,15 @@ Compiling source foo/pkg_b:1.0.0 -WARNING [main.bal:(26:5,26:41)] unused variable 'msgHello' -WARNING [main.bal:(27:5,27:53)] unused variable 'msg' +WARNING [main.bal:(26:5,26:41)] unused variable 'msgHello' (BCE20403) + | +26 | string msgHello = pkg_a:helloCall(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(27:5,27:53)] unused variable 'msg' (BCE20403) + | +27 | handle? msg = greeting(java:fromString("Jane")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Generating executable diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/run-project-with-provided-dep.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/run-project-with-provided-dep.txt index 40189cda7c25..3947e28698dc 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/run-project-with-provided-dep.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/run-project-with-provided-dep.txt @@ -1,6 +1,14 @@ Compiling source foo/pkg_b:1.0.0 -WARNING [main.bal:(26:5,26:41)] unused variable 'msgHello' -WARNING [main.bal:(27:5,27:53)] unused variable 'msg' +WARNING [main.bal:(26:5,26:41)] unused variable 'msgHello' (BCE20403) + | +26 | string msgHello = pkg_a:helloCall(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +WARNING [main.bal:(27:5,27:53)] unused variable 'msg' (BCE20403) + | +27 | handle? msg = greeting(java:fromString("Jane")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Running executable \ No newline at end of file From bb727975012fd6ece659f4fb712cfee03cbccb65 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Fri, 29 Mar 2024 10:39:34 +0530 Subject: [PATCH 41/55] Use string builder for truncation --- .../cli/diagnostics/DiagnosticAnnotation.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index 953394c63840..b1e77f0051a9 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -161,19 +161,24 @@ protected static TruncateResult truncate(String line, int maxLength, int diagnos if (line.length() < maxLength - 3) { return new TruncateResult(line, diagnosticStart, diagnosticLength); } + + StringBuilder truncatedLineBuilder = new StringBuilder(); + String ellipsis = "..."; if (diagnosticStart + diagnosticLength <= maxLength - 3) { - return new TruncateResult(line.substring(0, maxLength - 3) + "...", diagnosticStart, diagnosticLength); + truncatedLineBuilder.append(line, 0, maxLength - 3).append(ellipsis); + return new TruncateResult(truncatedLineBuilder.toString(), diagnosticStart, diagnosticLength); } + int diagnosticMid = diagnosticStart + (diagnosticLength / 2); int stepsToMoveWindow = Math.max(0, diagnosticMid - (maxLength / 2)); int border = Math.min(line.length() - 1, stepsToMoveWindow + maxLength - 3); int newDiagnosticStart = Math.max(3, diagnosticStart - stepsToMoveWindow); int newDiagnosticLength = Math.min(diagnosticLength, maxLength - newDiagnosticStart - 3); int stringStart = Math.min(stepsToMoveWindow + 3, border); - int stringEnd = border; - String truncatedLine = "..." + line.substring(stringStart, stringEnd) + "..."; - return new TruncateResult(truncatedLine, newDiagnosticStart, Math.max(0, newDiagnosticLength)); + truncatedLineBuilder.append(ellipsis).append(line, stringStart, border).append(ellipsis); + return new TruncateResult(truncatedLineBuilder.toString(), newDiagnosticStart, + Math.max(0, newDiagnosticLength)); } From a81b064d3147d6ec9151cbae8a97792f8e1ad471 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 9 Apr 2024 12:22:13 +0530 Subject: [PATCH 42/55] Refactor truncation logic, rename function name Current implementation started truncating before the line is equal to the max length. --- .../ballerina/cli/diagnostics/AnnotateDiagnostics.java | 10 +++++----- .../cli/diagnostics/DiagnosticAnnotation.java | 2 +- .../cli/diagnostics/DiagnosticAnnotationTest.java | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index 156cfce86375..f94413cebd0e 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -71,7 +71,7 @@ public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, in document, packageDiagnostic, diagnosticCodeNumber, terminalWidth, colorEnabled)); } } - DiagnosticAnnotation diagnosticAnnotation = getDiagnosticLineFromSyntaxAPI( + DiagnosticAnnotation diagnosticAnnotation = getDiagnosticAnnotation( document, diagnostic.location(), diagnostic.diagnosticInfo().severity(), terminalWidth, colorEnabled); return Ansi.ansi().render(diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + diagnosticAnnotation); @@ -124,9 +124,9 @@ private static String diagnosticToString(Diagnostic diagnostic, boolean colorEna return String.format(formatString, severityString, message, code != null ? code : ""); } - private static DiagnosticAnnotation getDiagnosticLineFromSyntaxAPI(Document document, Location location, - DiagnosticSeverity severity, int terminalWidth, - boolean colorEnabled) { + private static DiagnosticAnnotation getDiagnosticAnnotation(Document document, Location location, + DiagnosticSeverity severity, int terminalWidth, + boolean colorEnabled) { TextDocument textDocument = document.textDocument(); LocationDetails locationDetails = getLocationDetails(location); boolean isMultiline = locationDetails.startLine != locationDetails.endLine; @@ -163,7 +163,7 @@ private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document docum if (diagnosticCode == INVALID_TOKEN_CODE) { return getInvalidTokenAnnotation(textDocument, locationDetails, color, colorEnabled, terminalWidth); } - return getDiagnosticLineFromSyntaxAPI(document, location, DiagnosticSeverity.ERROR, terminalWidth, + return getDiagnosticAnnotation(document, location, DiagnosticSeverity.ERROR, terminalWidth, colorEnabled); } diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index b1e77f0051a9..55a6496cf23d 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -158,7 +158,7 @@ private static int countTabChars(String line, int end) { } protected static TruncateResult truncate(String line, int maxLength, int diagnosticStart, int diagnosticLength) { - if (line.length() < maxLength - 3) { + if (line.length() <= maxLength) { return new TruncateResult(line, diagnosticStart, diagnosticLength); } diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java index ccc331a318e4..6dbd055c8c54 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java @@ -36,6 +36,7 @@ public void testTruncation() { int importantPartStart = 15; int importantPartLength = 7; Map truncatedLines = new HashMap<>(); + truncatedLines.put(49, "This is a long message that needs to be truncated"); truncatedLines.put(30, "This is a long message that..."); truncatedLines.put(25, "This is a long message..."); truncatedLines.put(20, "...ong message th..."); @@ -44,7 +45,7 @@ public void testTruncation() { truncatedLines.put(5, "......"); truncatedLines.put(0, "......"); - int[] lengths = {30, 25, 20, 13, 10, 5, 0}; + int[] lengths = {49, 30, 25, 20, 13, 10, 5, 0}; for (int length : lengths) { DiagnosticAnnotation.TruncateResult truncatedMessage = DiagnosticAnnotation.truncate(message, length, importantPartStart, importantPartLength); From a4ece31cea19ea7c4ac7938a98b6056a2440f28e Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Wed, 10 Apr 2024 15:07:09 +0530 Subject: [PATCH 43/55] Pull reusable method calls into variables --- .../cli/diagnostics/AnnotateDiagnostics.java | 39 ++++++++++++------- .../cli/diagnostics/DiagnosticAnnotation.java | 12 +++--- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index f94413cebd0e..4e8a3e46aacd 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -21,10 +21,12 @@ import io.ballerina.compiler.internal.diagnostics.StringDiagnosticProperty; import io.ballerina.projects.Document; import io.ballerina.projects.DocumentId; +import io.ballerina.projects.Module; import io.ballerina.projects.ModuleName; import io.ballerina.projects.Package; import io.ballerina.projects.internal.PackageDiagnostic; import io.ballerina.tools.diagnostics.Diagnostic; +import io.ballerina.tools.diagnostics.DiagnosticInfo; import io.ballerina.tools.diagnostics.DiagnosticSeverity; import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.TextDocument; @@ -59,21 +61,21 @@ public class AnnotateDiagnostics { public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth, boolean colorEnabled) { - - String diagnosticCode = diagnostic.diagnosticInfo().code(); + DiagnosticInfo diagnosticInfo = diagnostic.diagnosticInfo(); + String diagnosticCode = diagnosticInfo.code(); terminalWidth = terminalWidth == 0 ? NO_TRUNCATE_WIDTH : terminalWidth; if (diagnostic instanceof PackageDiagnostic packageDiagnostic && diagnosticCode != null && diagnosticCode.startsWith(COMPILER_ERROR_PREFIX)) { int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); if (diagnosticCodeNumber < SYNTAX_ERROR_CODE_THRESHOLD) { - return Ansi.ansi() - .render(diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + getSyntaxDiagnosticAnnotation( + return renderAnsi( + diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + getSyntaxDiagnosticAnnotation( document, packageDiagnostic, diagnosticCodeNumber, terminalWidth, colorEnabled)); } } DiagnosticAnnotation diagnosticAnnotation = getDiagnosticAnnotation( - document, diagnostic.location(), diagnostic.diagnosticInfo().severity(), terminalWidth, colorEnabled); - return Ansi.ansi().render(diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + diagnosticAnnotation); + document, diagnostic.location(), diagnosticInfo.severity(), terminalWidth, colorEnabled); + return renderAnsi(diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + diagnosticAnnotation); } @@ -86,18 +88,19 @@ public static int getTerminalWidth() { } public static Ansi renderDiagnostic(Diagnostic diagnostic, boolean colorEnabled) { - return Ansi.ansi().render(diagnosticToString(diagnostic, colorEnabled)); + return renderAnsi(diagnosticToString(diagnostic, colorEnabled)); } public static Map getDocumentMap(Package currentPackage) { Map documentMap = new HashMap<>(); currentPackage.moduleIds().forEach(moduleId -> { + Module module = currentPackage.module(moduleId); Consumer consumer = documentId -> { - Document document = currentPackage.module(moduleId).document(documentId); - documentMap.put(getDocumentPath(document.module().moduleName(), document.name()), document); + Document document = module.document(documentId); + documentMap.put(getDocumentPath(module.moduleName(), document.name()), document); }; - currentPackage.module(moduleId).documentIds().forEach(consumer); - currentPackage.module(moduleId).testDocumentIds().forEach(consumer); + module.documentIds().forEach(consumer); + module.testDocumentIds().forEach(consumer); }); return documentMap; @@ -112,16 +115,18 @@ private static String getDocumentPath(ModuleName moduleName, String documentName } private static String diagnosticToString(Diagnostic diagnostic, boolean colorEnabled) { - DiagnosticSeverity severity = diagnostic.diagnosticInfo().severity(); + DiagnosticInfo diagnosticInfo = diagnostic.diagnosticInfo(); + DiagnosticSeverity severity = diagnosticInfo.severity(); String severityString = severity.toString(); String color = SEVERITY_COLORS.get(severity); String message = diagnostic.toString().substring(severityString.length()); - String code = diagnostic.diagnosticInfo().code(); + String code = diagnosticInfo.code(); boolean isMultiline = diagnostic.message().contains(NEW_LINE); + boolean isCodeNotNull = code != null; String formatString = getColoredString("%s", color, colorEnabled) + "%s" + - (code != null ? (isMultiline ? NEW_LINE + "(%s)" : " (%s)") : ""); + (isCodeNotNull ? (isMultiline ? NEW_LINE + "(%s)" : " (%s)") : ""); - return String.format(formatString, severityString, message, code != null ? code : ""); + return String.format(formatString, severityString, message, isCodeNotNull ? code : ""); } private static DiagnosticAnnotation getDiagnosticAnnotation(Document document, Location location, @@ -238,6 +243,10 @@ private static LocationDetails getLocationDetails(Location location) { return new LocationDetails(startLine, startOffset, endLine, endOffset); } + private static Ansi renderAnsi(String message) { + return Ansi.ansi().render(message); + } + /** * Represents the location details of a diagnostic. * diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index 55a6496cf23d..7a17fa819834 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -88,8 +88,10 @@ public String toString() { colorEnabled) + NEW_LINE; } + String startLine = lines.get(0); + String endLine = lines.get(lines.size() - 1); - int maxLineLength = Math.max(lines.get(0).length(), lines.get(lines.size() - 1).length()); + int maxLineLength = Math.max(startLine.length(), endLine.length()); int endDigitsNum = (int) Math.log10(startLineNumber + lines.size() - 1) + 1; String padding; String paddingWithColon; @@ -100,11 +102,11 @@ public String toString() { padding = " ".repeat(endDigitsNum + 1); paddingWithColon = " :" + " ".repeat(endDigitsNum - 1); } - int tabsInLastLine = countTabChars(lines.get(lines.size() - 1), this.endOffset); - lines.set(lines.size() - 1, replaceTabs(lines.get(lines.size() - 1), this.endOffset)); + int tabsInLastLine = countTabChars(endLine, this.endOffset); + endLine = replaceTabs(endLine, this.endOffset); int maxLength = terminalWidth - endDigitsNum - 3; - TruncateResult result1 = truncate(lines.get(0), maxLength, start, length); - TruncateResult result2 = truncate(lines.get(lines.size() - 1), maxLength, 0, + TruncateResult result1 = truncate(startLine, maxLength, start, length); + TruncateResult result2 = truncate(endLine, maxLength, 0, endOffset + 3 * tabsInLastLine); if (lines.size() == 2) { From 7cf46e5e3a7f1e17e2317e567bb10629d84658ee Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Wed, 17 Apr 2024 11:20:45 +0530 Subject: [PATCH 44/55] Address code review comments --- .../cli/diagnostics/AnnotateDiagnostics.java | 50 ++++++++++++++----- .../cli/diagnostics/DiagnosticAnnotation.java | 24 ++++++--- .../diagnostics/AnnotateDiagnosticsTest.java | 23 +++++++++ .../diagnostics/DiagnosticAnnotationTest.java | 23 +++++++++ 4 files changed, 101 insertions(+), 19 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index 4e8a3e46aacd..1b49eab99440 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -29,6 +29,7 @@ import io.ballerina.tools.diagnostics.DiagnosticInfo; import io.ballerina.tools.diagnostics.DiagnosticSeverity; import io.ballerina.tools.diagnostics.Location; +import io.ballerina.tools.text.LinePosition; import io.ballerina.tools.text.TextDocument; import org.jline.jansi.Ansi; import org.jline.terminal.TerminalBuilder; @@ -39,7 +40,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Consumer; import static io.ballerina.cli.diagnostics.DiagnosticAnnotation.NEW_LINE; import static io.ballerina.cli.diagnostics.DiagnosticAnnotation.SEVERITY_COLORS; @@ -59,6 +59,15 @@ public class AnnotateDiagnostics { private static final int INVALID_TOKEN_CODE = 600; private static final int NO_TRUNCATE_WIDTH = 999; + /** + * Returns an annotated diagnostic that is ready to be printed to the console. + * + * @param diagnostic The diagnostic to be annotated. + * @param document The document that the diagnostic is associated with. + * @param terminalWidth The width of the terminal. This is used to truncate the diagnostic message. + * @param colorEnabled Whether to enable color in the diagnostic message. + * @return The annotated diagnostic. + */ public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth, boolean colorEnabled) { DiagnosticInfo diagnosticInfo = diagnostic.diagnosticInfo(); @@ -79,6 +88,9 @@ public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, in } + /** + * @return The width of the terminal. + */ public static int getTerminalWidth() { try { return TerminalBuilder.builder().dumb(true).build().getWidth(); @@ -87,20 +99,36 @@ public static int getTerminalWidth() { } } + /** + * Returns a diagnostic without any code annotations that is ready to be printed to the console. This is for when + * there is no Document associated with the diagnostic, but we can still render the diagnostic in the terminal with + * color. + * + * @param diagnostic The diagnostic to be rendered in the console. + * @param colorEnabled Whether to enable color in the diagnostic message. + * @return The diagnostic message. + */ public static Ansi renderDiagnostic(Diagnostic diagnostic, boolean colorEnabled) { return renderAnsi(diagnosticToString(diagnostic, colorEnabled)); } + private static void processDocuments(Module module, DocumentId documentId, Map documentMap) { + Document document = module.document(documentId); + documentMap.put(getDocumentPath(module.moduleName(), document.name()), document); + } + + /** + * Returns a map of documents in the given package. + * + * @param currentPackage The package to get the documents from. + * @return A map of document paths to documents. + */ public static Map getDocumentMap(Package currentPackage) { Map documentMap = new HashMap<>(); currentPackage.moduleIds().forEach(moduleId -> { Module module = currentPackage.module(moduleId); - Consumer consumer = documentId -> { - Document document = module.document(documentId); - documentMap.put(getDocumentPath(module.moduleName(), document.name()), document); - }; - module.documentIds().forEach(consumer); - module.testDocumentIds().forEach(consumer); + module.documentIds().forEach(documentId -> processDocuments(module, documentId, documentMap)); + module.testDocumentIds().forEach(documentId -> processDocuments(module, documentId, documentMap)); }); return documentMap; @@ -236,11 +264,9 @@ private static List getLines(TextDocument textDocument, int start, int e } private static LocationDetails getLocationDetails(Location location) { - int startLine = location.lineRange().startLine().line(); - int startOffset = location.lineRange().startLine().offset(); - int endLine = location.lineRange().endLine().line(); - int endOffset = location.lineRange().endLine().offset(); - return new LocationDetails(startLine, startOffset, endLine, endOffset); + LinePosition startLine = location.lineRange().startLine(); + LinePosition endLine = location.lineRange().endLine(); + return new LocationDetails(startLine.line(), startLine.offset(), endLine.line(), endLine.offset()); } private static Ansi renderAnsi(String message) { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index 7a17fa819834..4d0be5e7f729 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -33,12 +33,18 @@ public class DiagnosticAnnotation { public static final String NEW_LINE = System.lineSeparator(); public static final String JANSI_ANNOTATOR = "@|"; public static final String JANSI_RESET = "|@"; + private static final String INTERNAL_COLOR = "blue"; + private static final String HINT_COLOR = "blue"; + private static final String INFO_COLOR = "blue"; + private static final String WARNING_COLOR = "yellow"; + private static final String ERROR_COLOR = "red"; public static final Map SEVERITY_COLORS; static { SEVERITY_COLORS = - Map.of(DiagnosticSeverity.INTERNAL, "blue", DiagnosticSeverity.HINT, "blue", DiagnosticSeverity.INFO, - "blue", DiagnosticSeverity.WARNING, "yellow", DiagnosticSeverity.ERROR, "red"); + Map.of(DiagnosticSeverity.INTERNAL, INTERNAL_COLOR, DiagnosticSeverity.HINT, HINT_COLOR, + DiagnosticSeverity.INFO, INFO_COLOR, DiagnosticSeverity.WARNING, WARNING_COLOR, + DiagnosticSeverity.ERROR, ERROR_COLOR); } public enum DiagnosticAnnotationType { @@ -82,7 +88,7 @@ public String toString() { int maxLength = terminalWidth - digitsNum - 3; TruncateResult result = truncate(lines.get(0), maxLength, start, length); return padding + "|" + NEW_LINE - + String.format("%" + digitsNum + "d ", startLineNumber) + "| " + result.line + NEW_LINE + + getLineNumberString(digitsNum, startLineNumber) + "| " + result.line + NEW_LINE + padding + "| " + getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type, colorEnabled) + NEW_LINE; @@ -111,24 +117,24 @@ public String toString() { if (lines.size() == 2) { return padding + "|" + NEW_LINE - + String.format("%" + endDigitsNum + "d ", startLineNumber) + "| " + result1.line + NEW_LINE + + getLineNumberString(endDigitsNum, startLineNumber) + "| " + result1.line + NEW_LINE + padding + "| " + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type, colorEnabled) + NEW_LINE - + String.format("%" + endDigitsNum + "d ", startLineNumber + 1) + "| " + result2.line + NEW_LINE + + getLineNumberString(endDigitsNum, startLineNumber + 1) + "| " + result2.line + NEW_LINE + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type, colorEnabled) + NEW_LINE; } String padding2 = " ".repeat(Math.min(terminalWidth, maxLineLength) / 2); return padding + "|" + NEW_LINE - + String.format("%" + endDigitsNum + "d ", startLineNumber) + "| " + result1.line + NEW_LINE + + getLineNumberString(endDigitsNum, startLineNumber) + "| " + result1.line + NEW_LINE + paddingWithColon + "| " + getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type, colorEnabled) + NEW_LINE + paddingWithColon + "| " + padding2 + ":" + NEW_LINE + paddingWithColon + "| " + padding2 + ":" + NEW_LINE - + String.format("%" + endDigitsNum + "d ", startLineNumber + lines.size() - 1) + "| " + + getLineNumberString(endDigitsNum, startLineNumber + lines.size() - 1) + "| " + result2.line + NEW_LINE + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type, colorEnabled) + NEW_LINE; @@ -139,6 +145,10 @@ public static String getColoredString(String message, String color, boolean colo return colorEnabled ? JANSI_ANNOTATOR + color + " " + message + JANSI_RESET : message; } + private static String getLineNumberString(int numberOfDigits, int lineNumber) { + return String.format("%" + numberOfDigits + "d ", lineNumber); + } + private static String getUnderline(int offset, int length, DiagnosticSeverity severity, DiagnosticAnnotationType type, boolean colorEnabled) { String symbol = "^"; diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index 26918f298687..db92bc44067b 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package io.ballerina.cli.diagnostics; import io.ballerina.projects.Document; @@ -21,6 +39,11 @@ import static io.ballerina.cli.utils.OsUtils.isWindows; +/** + * Test cases for AnnotateDiagnostics class. + * + * @since 2201.9.0 + */ public class AnnotateDiagnosticsTest { private Path testResources; diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java index 6dbd055c8c54..0da942929b9e 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package io.ballerina.cli.diagnostics; import io.ballerina.tools.diagnostics.DiagnosticSeverity; @@ -7,6 +25,11 @@ import java.util.HashMap; import java.util.Map; +/** + * Test cases for DiagnosticAnnotation class. + * + * @since 2201.9.0 + */ public class DiagnosticAnnotationTest { @Test From ce37ed7b6905fabe4948461f948b8a90583ec987 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Wed, 17 Apr 2024 15:27:40 +0530 Subject: [PATCH 45/55] Move logic from CompileTask to AnnotateDiagnostics Switched from using only static methods to an instance based approach for AnnotateDiagnostics, making the code in CompileTask more readable. --- .../cli/diagnostics/AnnotateDiagnostics.java | 56 +++++++------- .../io/ballerina/cli/task/CompileTask.java | 13 +--- .../diagnostics/AnnotateDiagnosticsTest.java | 73 ++++++++++--------- .../bal-error/long-line-expected6.txt | 4 + 4 files changed, 70 insertions(+), 76 deletions(-) create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected6.txt diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index 1b49eab99440..380a6c590f8d 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -47,7 +47,7 @@ import static io.ballerina.cli.utils.OsUtils.isWindows; /** - * This class is used to generate diagnostic annotations from diagnostics. + * This class is used to generate diagnostic annotated messages from diagnostics. * * @since 2201.9.0 */ @@ -59,39 +59,50 @@ public class AnnotateDiagnostics { private static final int INVALID_TOKEN_CODE = 600; private static final int NO_TRUNCATE_WIDTH = 999; + private final Map documentMap; + private int terminalWidth; + private final boolean colorEnabled; + + public AnnotateDiagnostics(Package currentPackage) { + this.documentMap = getDocumentMap(currentPackage); + this.terminalWidth = getTerminalWidth(); + this.colorEnabled = this.terminalWidth != 0; + } + /** * Returns an annotated diagnostic that is ready to be printed to the console. * - * @param diagnostic The diagnostic to be annotated. - * @param document The document that the diagnostic is associated with. - * @param terminalWidth The width of the terminal. This is used to truncate the diagnostic message. - * @param colorEnabled Whether to enable color in the diagnostic message. + * @param diagnostic The diagnostic to be annotated. * @return The annotated diagnostic. */ - public static Ansi renderDiagnostic(Diagnostic diagnostic, Document document, int terminalWidth, - boolean colorEnabled) { + public Ansi renderDiagnostic(Diagnostic diagnostic) { + Location diagnosticLocation = diagnostic.location(); + Document document = documentMap.get(diagnosticLocation.lineRange().fileName()); + if (document == null) { + return renderAnsi(diagnosticToString(diagnostic, colorEnabled)); + } + DiagnosticInfo diagnosticInfo = diagnostic.diagnosticInfo(); String diagnosticCode = diagnosticInfo.code(); - terminalWidth = terminalWidth == 0 ? NO_TRUNCATE_WIDTH : terminalWidth; + this.terminalWidth = this.terminalWidth == 0 ? NO_TRUNCATE_WIDTH : this.terminalWidth; if (diagnostic instanceof PackageDiagnostic packageDiagnostic && diagnosticCode != null && diagnosticCode.startsWith(COMPILER_ERROR_PREFIX)) { int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); if (diagnosticCodeNumber < SYNTAX_ERROR_CODE_THRESHOLD) { return renderAnsi( diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + getSyntaxDiagnosticAnnotation( - document, packageDiagnostic, diagnosticCodeNumber, terminalWidth, colorEnabled)); + document, packageDiagnostic, diagnosticCodeNumber, this.terminalWidth, colorEnabled)); } } - DiagnosticAnnotation diagnosticAnnotation = getDiagnosticAnnotation( - document, diagnostic.location(), diagnosticInfo.severity(), terminalWidth, colorEnabled); + + DiagnosticAnnotation diagnosticAnnotation = + getDiagnosticAnnotation(document, diagnosticLocation, diagnosticInfo.severity(), this.terminalWidth, + colorEnabled); return renderAnsi(diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + diagnosticAnnotation); } - /** - * @return The width of the terminal. - */ - public static int getTerminalWidth() { + private static int getTerminalWidth() { try { return TerminalBuilder.builder().dumb(true).build().getWidth(); } catch (IOException e) { @@ -99,19 +110,6 @@ public static int getTerminalWidth() { } } - /** - * Returns a diagnostic without any code annotations that is ready to be printed to the console. This is for when - * there is no Document associated with the diagnostic, but we can still render the diagnostic in the terminal with - * color. - * - * @param diagnostic The diagnostic to be rendered in the console. - * @param colorEnabled Whether to enable color in the diagnostic message. - * @return The diagnostic message. - */ - public static Ansi renderDiagnostic(Diagnostic diagnostic, boolean colorEnabled) { - return renderAnsi(diagnosticToString(diagnostic, colorEnabled)); - } - private static void processDocuments(Module module, DocumentId documentId, Map documentMap) { Document document = module.document(documentId); documentMap.put(getDocumentPath(module.moduleName(), document.name()), document); @@ -123,7 +121,7 @@ private static void processDocuments(Module module, DocumentId documentId, Map getDocumentMap(Package currentPackage) { + private static Map getDocumentMap(Package currentPackage) { Map documentMap = new HashMap<>(); currentPackage.moduleIds().forEach(moduleId -> { Module module = currentPackage.module(moduleId); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index ecff61baf094..ae1d97a82254 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -22,7 +22,6 @@ import io.ballerina.cli.utils.BuildTime; import io.ballerina.projects.CodeGeneratorResult; import io.ballerina.projects.CodeModifierResult; -import io.ballerina.projects.Document; import io.ballerina.projects.JBallerinaBackend; import io.ballerina.projects.JvmTarget; import io.ballerina.projects.PackageCompilation; @@ -224,9 +223,7 @@ public void execute(Project project) { // HashSet to keep track of the diagnostics to avoid duplicate diagnostics Set diagnosticSet = new HashSet<>(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(project.currentPackage()); - int terminalWidth = AnnotateDiagnostics.getTerminalWidth(); - boolean colorEnabled = terminalWidth != 0; + AnnotateDiagnostics annotateDiagnostics = new AnnotateDiagnostics(project.currentPackage()); // Report package compilation and backend diagnostics diagnostics.addAll(jBallerinaBackend.diagnosticResult().diagnostics(false)); @@ -235,13 +232,7 @@ public void execute(Project project) { ProjectDiagnosticErrorCode.BUILT_WITH_OLDER_SL_UPDATE_DISTRIBUTION.diagnosticId()) && !d.diagnosticInfo().code().startsWith(TOOL_DIAGNOSTIC_CODE_PREFIX))) { if (diagnosticSet.add(d.toString())) { - Document document = documentMap.get(d.location().lineRange().fileName()); - if (document != null) { - err.println(AnnotateDiagnostics.renderDiagnostic(d, document, - terminalWidth, colorEnabled)); - } else { - err.println(AnnotateDiagnostics.renderDiagnostic(d, colorEnabled)); - } + err.println(annotateDiagnostics.renderDiagnostic(d)); } } }); diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index db92bc44067b..b2c05b7de465 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -20,6 +20,7 @@ import io.ballerina.projects.Document; import io.ballerina.projects.DocumentConfig; +import io.ballerina.projects.Package; import io.ballerina.tools.diagnostics.Diagnostic; import io.ballerina.tools.diagnostics.DiagnosticSeverity; import org.ballerinalang.test.BCompileUtil; @@ -29,6 +30,7 @@ import org.testng.annotations.Test; import java.io.IOException; +import java.lang.reflect.Field; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Files; @@ -60,13 +62,12 @@ public void testMissingTokenAnnotation() throws IOException { CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-missing-error/semicolon-missing.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String expectedOutput = Files.readString(testResources.resolve("bal-missing-error") .resolve("semicolon-missing-expected.txt")); Assert.assertTrue(diagnostics.length > 0); Diagnostic diagnostic = diagnostics[0]; - Document document = documentMap.get(diagnostic.location().lineRange().fileName()); - String output = AnnotateDiagnostics.renderDiagnostic(diagnostic, document, 999, false).toString(); + AnnotateDiagnostics annotateDiagnostics = new AnnotateDiagnostics(result.project().currentPackage()); + String output = annotateDiagnostics.renderDiagnostic(diagnostic).toString(); Assert.assertEquals(output, expectedOutput); } @@ -75,13 +76,12 @@ public void testMissingFunctionKeywordAnnotation() throws IOException { CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String expectedOutput = Files.readString(testResources.resolve("bal-missing-error") .resolve("missing-function-keyword-expected.txt")); Assert.assertEquals(diagnostics.length, 1); Diagnostic diagnostic = diagnostics[0]; - Document document = documentMap.get(diagnostic.location().lineRange().fileName()); - String output = AnnotateDiagnostics.renderDiagnostic(diagnostic, document, 999, false).toString(); + AnnotateDiagnostics annotateDiagnostics = new AnnotateDiagnostics(result.project().currentPackage()); + String output = annotateDiagnostics.renderDiagnostic(diagnostic).toString(); Assert.assertEquals(output, expectedOutput); } @@ -90,11 +90,10 @@ public void testMissingMultipleKeywordsAnnotation() throws IOException { CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-missing-error/missing-multiple-keywords.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String expectedOutput = Files.readString(testResources.resolve("bal-missing-error") .resolve("missing-multiple-keywords-expected.txt")); Assert.assertTrue(diagnostics.length > 0); - String output = getAnnotatedDiagnostics(diagnostics, documentMap); + String output = getAnnotatedDiagnostics(diagnostics, result.project().currentPackage()); Assert.assertEquals(output, expectedOutput); } @@ -103,29 +102,29 @@ void testInvalidTokenAnnotation() throws IOException { CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-invalid-error/invalid-token.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String expectedOutput = Files.readString(testResources.resolve("bal-invalid-error") .resolve("invalid-token-expected.txt")); Assert.assertEquals(diagnostics.length, 1); Diagnostic diagnostic = diagnostics[0]; - Document document = documentMap.get(diagnostic.location().lineRange().fileName()); - String output = AnnotateDiagnostics.renderDiagnostic(diagnostic, document, 999, false).toString(); + AnnotateDiagnostics annotateDiagnostics = new AnnotateDiagnostics(result.project().currentPackage()); + String output = annotateDiagnostics.renderDiagnostic(diagnostic).toString(); Assert.assertEquals(output, expectedOutput); } @Test(description = "Test annotations when erroneous line is longer than the terminal width. Tests truncation") - void testLongLineAnnotation() throws IOException { - int[] terminalWidth = {999, 200, 150, 100, 50, 40}; + void testLongLineAnnotation() throws IOException, NoSuchFieldException, IllegalAccessException { + int[] terminalWidth = {999, 200, 150, 100, 50, 40, 38}; CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-error/long-line.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + AnnotateDiagnostics annotateDiagnostics = new AnnotateDiagnostics(result.project().currentPackage()); Assert.assertEquals(diagnostics.length, 1); Diagnostic diagnostic = diagnostics[0]; - Document document = documentMap.get(diagnostic.location().lineRange().fileName()); + Field terminalWidthField = AnnotateDiagnostics.class.getDeclaredField("terminalWidth"); + terminalWidthField.setAccessible(true); for (int i = 0; i < terminalWidth.length; i++) { - String output = - AnnotateDiagnostics.renderDiagnostic(diagnostic, document, terminalWidth[i], false).toString(); + terminalWidthField.setInt(annotateDiagnostics, terminalWidth[i]); + String output = annotateDiagnostics.renderDiagnostic(diagnostic).toString(); String expectedOutput = Files.readString(testResources.resolve("bal-error").resolve("long-line-expected" + i + ".txt")); Assert.assertEquals(output, expectedOutput); @@ -137,8 +136,7 @@ void testProjectErrorAnnotation() throws IOException { CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-project-error/project1"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); - String output = getAnnotatedDiagnostics(diagnostics, documentMap); + String output = getAnnotatedDiagnostics(diagnostics, result.project().currentPackage()); String expectedOutput = getExpectedOutput(testResources.resolve("bal-project-error"), "project1-expected.txt"); Assert.assertEquals(output, expectedOutput); @@ -150,14 +148,13 @@ void testProjectWarningAnnotation() throws IOException { BCompileUtil.compileWithoutInitInvocation( "test-resources/diagnostics-test-files/bal-project-error/project2"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + AnnotateDiagnostics annotateDiagnostics = new AnnotateDiagnostics(result.project().currentPackage()); StringBuilder output = new StringBuilder(); for (Diagnostic diagnostic : diagnostics) { if (diagnostic.diagnosticInfo().severity() != DiagnosticSeverity.WARNING) { continue; } - Document document = documentMap.get(diagnostic.location().lineRange().fileName()); - output.append(AnnotateDiagnostics.renderDiagnostic(diagnostic, document, 999, false).toString()); + output.append(annotateDiagnostics.renderDiagnostic(diagnostic).toString()); output.append(System.lineSeparator()); } String expectedOutput = getExpectedOutput(testResources.resolve("bal-project-error"), "project2-expected.txt"); @@ -169,8 +166,7 @@ void testTwoLinedAnnotations() throws IOException { CompileResult result = BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/two-line-error.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); - String output = getAnnotatedDiagnostics(diagnostics, documentMap); + String output = getAnnotatedDiagnostics(diagnostics, result.project().currentPackage()); String expectedOutput = Files.readString(testResources.resolve("bal-error").resolve("two-line-error-expected.txt")); Assert.assertEquals(output, expectedOutput); @@ -181,8 +177,7 @@ void testMultiLinedAnnotations() throws IOException { CompileResult result = BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/multi-line.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); - String output = getAnnotatedDiagnostics(diagnostics, documentMap); + String output = getAnnotatedDiagnostics(diagnostics, result.project().currentPackage()); String expectedOutput = Files.readString(testResources.resolve("bal-error").resolve("multi-line-expected.txt")); Assert.assertEquals(output, expectedOutput); } @@ -191,8 +186,7 @@ void testMultiLinedAnnotations() throws IOException { void testAnnotationsWithTabs() throws IOException { CompileResult result = BCompileUtil.compile("test-resources/diagnostics-test-files/bal-error/tabs.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); - String output = getAnnotatedDiagnostics(diagnostics, documentMap); + String output = getAnnotatedDiagnostics(diagnostics, result.project().currentPackage()); String expectedOutput = Files.readString(testResources.resolve("bal-error").resolve("tabs-expected.txt")); Assert.assertEquals(output, expectedOutput); } @@ -202,22 +196,28 @@ void testNonTerminalNodeMissingAnnotation() throws IOException { CompileResult result = BCompileUtil.compile( "test-resources/diagnostics-test-files/bal-missing-error/missing-non-terminal.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); String expectedOutput = Files.readString(testResources.resolve("bal-missing-error") .resolve("missing-non-terminal-expected.txt")); Assert.assertEquals(diagnostics.length, 8); - String output = getAnnotatedDiagnostics(diagnostics, documentMap); + String output = getAnnotatedDiagnostics(diagnostics, result.project().currentPackage()); Assert.assertEquals(output, expectedOutput); } @Test(description = "Test missing token annotation padding") - void testMissingTokenAnnotationPadding() throws IOException { + void testMissingTokenAnnotationPadding() throws IOException, NoSuchFieldException, IllegalAccessException { CompileResult result = BCompileUtil.compile( "test-resources/diagnostics-test-files/bal-missing-error/missing-function-keyword.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); Assert.assertEquals(diagnostics.length, 1); - Map documentMap = AnnotateDiagnostics.getDocumentMap(result.project().currentPackage()); + AnnotateDiagnostics annotateDiagnostics = new AnnotateDiagnostics(result.project().currentPackage()); + Field documentMapField = AnnotateDiagnostics.class.getDeclaredField("documentMap"); + documentMapField.setAccessible(true); + Assert.assertTrue(documentMapField.get(annotateDiagnostics) instanceof Map); + Object value = documentMapField.get(annotateDiagnostics); + Assert.assertTrue(value instanceof Map); + Map documentMap = (Map) value; + Document document = documentMap.get(diagnostics[0].location().lineRange().fileName()); int index = diagnostics[0].location().textRange().startOffset(); @@ -225,19 +225,20 @@ void testMissingTokenAnnotationPadding() throws IOException { document.textDocument().toString().substring(index); DocumentConfig documentConfig = DocumentConfig.from(document.documentId(), documentString, document.name()); Document updatedDocument = Document.from(documentConfig, document.module()); + documentMap.put(diagnostics[0].location().lineRange().fileName(), updatedDocument); - String output = AnnotateDiagnostics.renderDiagnostic(diagnostics[0], updatedDocument, 999, false).toString(); + String output = annotateDiagnostics.renderDiagnostic(diagnostics[0]).toString(); String expectedOutput = Files.readString(testResources.resolve("bal-missing-error") .resolve("missing-token-padding-expected.txt")); Assert.assertEquals(output, expectedOutput); } - private static String getAnnotatedDiagnostics(Diagnostic[] diagnostics, Map documentMap) { + private static String getAnnotatedDiagnostics(Diagnostic[] diagnostics, Package currentPackage) { StringBuilder output = new StringBuilder(); + AnnotateDiagnostics annotateDiagnostics = new AnnotateDiagnostics(currentPackage); for (Diagnostic diagnostic : diagnostics) { - Document document = documentMap.get(diagnostic.location().lineRange().fileName()); - output.append(AnnotateDiagnostics.renderDiagnostic(diagnostic, document, 999, false).toString()); + output.append(annotateDiagnostics.renderDiagnostic(diagnostic).toString()); output.append(System.lineSeparator()); } return output.toString(); diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected6.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected6.txt new file mode 100644 index 000000000000..209752195553 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected6.txt @@ -0,0 +1,4 @@ +ERROR [long-line.bal:(2:68,2:96)] operator '+' not defined for 'int' and 'string' (BCE2070) + | +2 | ...4 + 5 + 6 + 7 + 8 + 9 + "10"... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 998bfd3b526f0ee4dc64070f5d9235095108f159 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 30 Apr 2024 15:59:18 +0530 Subject: [PATCH 46/55] Address suggestions made at code review Shifted from string concatenation to string builders. Combined some common login in DiagnosticAnnotation for when lines are hidden and not hidden in the multi-line diagnostic case. Also made the amount of lines to be shown before we start hiding lines configurable. --- .../cli/diagnostics/AnnotateDiagnostics.java | 97 +++++++------- .../cli/diagnostics/DiagnosticAnnotation.java | 122 ++++++++++-------- 2 files changed, 116 insertions(+), 103 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index 380a6c590f8d..6cc73d909544 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -51,7 +51,7 @@ * * @since 2201.9.0 */ -public class AnnotateDiagnostics { +public final class AnnotateDiagnostics { private static final String COMPILER_ERROR_PREFIX = "BCE"; private static final int SYNTAX_ERROR_CODE_THRESHOLD = 1000; @@ -60,13 +60,14 @@ public class AnnotateDiagnostics { private static final int NO_TRUNCATE_WIDTH = 999; private final Map documentMap; - private int terminalWidth; - private final boolean colorEnabled; + private final int terminalWidth; + private final boolean isColorEnabled; public AnnotateDiagnostics(Package currentPackage) { this.documentMap = getDocumentMap(currentPackage); - this.terminalWidth = getTerminalWidth(); - this.colorEnabled = this.terminalWidth != 0; + int terminalWidth = getTerminalWidth(); + this.isColorEnabled = terminalWidth != 0; + this.terminalWidth = terminalWidth == 0 ? NO_TRUNCATE_WIDTH : terminalWidth; } /** @@ -79,26 +80,24 @@ public Ansi renderDiagnostic(Diagnostic diagnostic) { Location diagnosticLocation = diagnostic.location(); Document document = documentMap.get(diagnosticLocation.lineRange().fileName()); if (document == null) { - return renderAnsi(diagnosticToString(diagnostic, colorEnabled)); + return renderAnsi(diagnosticToString(diagnostic, isColorEnabled)); } DiagnosticInfo diagnosticInfo = diagnostic.diagnosticInfo(); String diagnosticCode = diagnosticInfo.code(); - this.terminalWidth = this.terminalWidth == 0 ? NO_TRUNCATE_WIDTH : this.terminalWidth; if (diagnostic instanceof PackageDiagnostic packageDiagnostic && diagnosticCode != null && diagnosticCode.startsWith(COMPILER_ERROR_PREFIX)) { - int diagnosticCodeNumber = Integer.parseInt(diagnosticCode.substring(3)); + int diagnosticCodeNumber = getCompilerErrorCodeNumber(diagnosticCode); if (diagnosticCodeNumber < SYNTAX_ERROR_CODE_THRESHOLD) { return renderAnsi( - diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + getSyntaxDiagnosticAnnotation( - document, packageDiagnostic, diagnosticCodeNumber, this.terminalWidth, colorEnabled)); + diagnosticToString(diagnostic, isColorEnabled) + NEW_LINE + getSyntaxDiagnosticAnnotation( + document, packageDiagnostic, diagnosticCodeNumber)); } } DiagnosticAnnotation diagnosticAnnotation = - getDiagnosticAnnotation(document, diagnosticLocation, diagnosticInfo.severity(), this.terminalWidth, - colorEnabled); - return renderAnsi(diagnosticToString(diagnostic, colorEnabled) + NEW_LINE + diagnosticAnnotation); + getDiagnosticAnnotation(document, diagnosticLocation, diagnosticInfo.severity()); + return renderAnsi(diagnosticToString(diagnostic, isColorEnabled) + NEW_LINE + diagnosticAnnotation); } @@ -140,7 +139,11 @@ private static String getDocumentPath(ModuleName moduleName, String documentName return Paths.get("modules", moduleName.moduleNamePart(), documentNameFixed).toString(); } - private static String diagnosticToString(Diagnostic diagnostic, boolean colorEnabled) { + private static int getCompilerErrorCodeNumber(String diagnosticCode) { + return Integer.parseInt(diagnosticCode.substring(COMPILER_ERROR_PREFIX.length())); + } + + private static String diagnosticToString(Diagnostic diagnostic, boolean isColorEnabled) { DiagnosticInfo diagnosticInfo = diagnostic.diagnosticInfo(); DiagnosticSeverity severity = diagnosticInfo.severity(); String severityString = severity.toString(); @@ -149,15 +152,14 @@ private static String diagnosticToString(Diagnostic diagnostic, boolean colorEna String code = diagnosticInfo.code(); boolean isMultiline = diagnostic.message().contains(NEW_LINE); boolean isCodeNotNull = code != null; - String formatString = getColoredString("%s", color, colorEnabled) + "%s" + + String formatString = getColoredString("%s", color, isColorEnabled) + "%s" + (isCodeNotNull ? (isMultiline ? NEW_LINE + "(%s)" : " (%s)") : ""); return String.format(formatString, severityString, message, isCodeNotNull ? code : ""); } - private static DiagnosticAnnotation getDiagnosticAnnotation(Document document, Location location, - DiagnosticSeverity severity, int terminalWidth, - boolean colorEnabled) { + private DiagnosticAnnotation getDiagnosticAnnotation(Document document, Location location, + DiagnosticSeverity severity) { TextDocument textDocument = document.textDocument(); LocationDetails locationDetails = getLocationDetails(location); boolean isMultiline = locationDetails.startLine != locationDetails.endLine; @@ -165,47 +167,42 @@ private static DiagnosticAnnotation getDiagnosticAnnotation(Document document, L locationDetails.endOffset - locationDetails.startOffset; return new DiagnosticAnnotation( - getLines(textDocument, locationDetails.startLine, locationDetails.endLine), + getLines(textDocument, locationDetails), locationDetails.startOffset, length == 0 ? 1 : length, isMultiline, locationDetails.endOffset, - locationDetails.startLine + 1, + locationDetails.startLine, severity, DiagnosticAnnotation.DiagnosticAnnotationType.REGULAR, - terminalWidth, colorEnabled); + terminalWidth, isColorEnabled); } - private static DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document document, - PackageDiagnostic packageDiagnostic, - int diagnosticCode, int terminalWidth, - boolean colorEnabled) { + private DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document document, + PackageDiagnostic packageDiagnostic, + int diagnosticCode) { TextDocument textDocument = document.textDocument(); Location location = packageDiagnostic.location(); LocationDetails locationDetails = getLocationDetails(location); - int padding = 0; String color = SEVERITY_COLORS.get(DiagnosticSeverity.ERROR); if (diagnosticCode < MISSING_TOKEN_KEYWORD_CODE_THRESHOLD) { - return getMissingTokenAnnotation(packageDiagnostic, textDocument, locationDetails, color, colorEnabled, - terminalWidth, padding); + return getMissingTokenAnnotation(packageDiagnostic, textDocument, locationDetails, color); } if (diagnosticCode == INVALID_TOKEN_CODE) { - return getInvalidTokenAnnotation(textDocument, locationDetails, color, colorEnabled, terminalWidth); + return getInvalidTokenAnnotation(textDocument, locationDetails, color); } - return getDiagnosticAnnotation(document, location, DiagnosticSeverity.ERROR, terminalWidth, - colorEnabled); + return getDiagnosticAnnotation(document, location, DiagnosticSeverity.ERROR); } - private static DiagnosticAnnotation getMissingTokenAnnotation(PackageDiagnostic packageDiagnostic, - TextDocument textDocument, - LocationDetails locationDetails, String color, - boolean colorEnabled, int terminalWidth, - int padding) { + private DiagnosticAnnotation getMissingTokenAnnotation(PackageDiagnostic packageDiagnostic, + TextDocument textDocument, LocationDetails locationDetails, + String color) { StringDiagnosticProperty strProperty = (StringDiagnosticProperty) packageDiagnostic.properties().get(0); String lineString = textDocument.line(locationDetails.startLine).text(); - String missingTokenString = getColoredString(strProperty.value(), color, colorEnabled); + String missingTokenString = getColoredString(strProperty.value(), color, isColorEnabled); + int padding = 0; if (locationDetails.startOffset < lineString.length() && lineString.charAt(locationDetails.startOffset) != ' ') { missingTokenString = missingTokenString + " "; @@ -216,29 +213,27 @@ private static DiagnosticAnnotation getMissingTokenAnnotation(PackageDiagnostic } String lineWithMissingToken = lineString.substring(0, locationDetails.startOffset) + missingTokenString + - lineString.substring(locationDetails.startOffset); - List lines = new ArrayList<>(); - lines.add(lineWithMissingToken); + lineString.substring(locationDetails.startOffset); // TODO: Use a string builder instead + List lines = new ArrayList<>(List.of(lineWithMissingToken)); return new DiagnosticAnnotation( lines, padding + locationDetails.startOffset, strProperty.value().length(), false, 0, - locationDetails.startLine + 1, + locationDetails.startLine, DiagnosticSeverity.ERROR, DiagnosticAnnotation.DiagnosticAnnotationType.MISSING, - terminalWidth, colorEnabled); + terminalWidth, isColorEnabled); } - private static DiagnosticAnnotation getInvalidTokenAnnotation(TextDocument textDocument, - LocationDetails locationDetails, String color, - boolean colorEnabled, int terminalWidth) { - List lines = getLines(textDocument, locationDetails.startLine, locationDetails.endLine); + private DiagnosticAnnotation getInvalidTokenAnnotation(TextDocument textDocument, + LocationDetails locationDetails, String color) { + List lines = getLines(textDocument, locationDetails); // TODO: Remove reusable code to separate methods String line = lines.get(0); String annotatedLine = line.substring(0, locationDetails.startOffset) + getColoredString(line.substring(locationDetails.startOffset, locationDetails.endOffset), color, - colorEnabled) + + isColorEnabled) + line.substring(locationDetails.endOffset); lines.set(0, annotatedLine); return new DiagnosticAnnotation( @@ -247,15 +242,15 @@ private static DiagnosticAnnotation getInvalidTokenAnnotation(TextDocument textD locationDetails.endOffset - locationDetails.startOffset, false, 0, - locationDetails.startLine + 1, + locationDetails.startLine, DiagnosticSeverity.ERROR, DiagnosticAnnotation.DiagnosticAnnotationType.INVALID, - terminalWidth, colorEnabled); + terminalWidth, isColorEnabled); } - private static List getLines(TextDocument textDocument, int start, int end) { + private static List getLines(TextDocument textDocument, LocationDetails locationDetails) { List lines = new ArrayList<>(); - for (int i = start; i <= end; i++) { + for (int i = locationDetails.startLine; i <= locationDetails.endLine; i++) { lines.add(textDocument.line(i).text()); } return lines; diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index 4d0be5e7f729..e89fb25550ea 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -28,13 +28,18 @@ * * @since 2201.9.0 */ -public class DiagnosticAnnotation { +public final class DiagnosticAnnotation { public static final String NEW_LINE = System.lineSeparator(); public static final String JANSI_ANNOTATOR = "@|"; - public static final String JANSI_RESET = "|@"; + public static final String JANSI_RESET = "|@"; // @|red , TEXT |@ + private static final String PIPE = "|"; + private static final String COLON = ":"; + private static final String ELLIPSIS = "..."; + private static final int PIPE_AND_PADDING_LENGTH = " | ".length(); + private static final int MAX_LINES_BEFORE_HIDING = 2; private static final String INTERNAL_COLOR = "blue"; - private static final String HINT_COLOR = "blue"; + private static final String HINT_COLOR = "blue"; // TODO: Color of hints should be different from INFO private static final String INFO_COLOR = "blue"; private static final String WARNING_COLOR = "yellow"; private static final String ERROR_COLOR = "red"; @@ -62,36 +67,39 @@ public enum DiagnosticAnnotationType { private final int terminalWidth; private final DiagnosticSeverity severity; private final DiagnosticAnnotationType type; - private final boolean colorEnabled; + private final boolean isColorEnabled; public DiagnosticAnnotation(List lines, int start, int length, boolean isMultiline, int endOffset, int startLineNumber, DiagnosticSeverity severity, DiagnosticAnnotationType type, - int terminalWidth, boolean colorEnabled) { - this.start = start + 3 * countTabChars(lines.get(0), start); + int terminalWidth, boolean isColorEnabled) { + this.start = getStart(lines, start); lines.set(0, replaceTabs(lines.get(0), start)); this.lines = lines; this.length = length; this.endOffset = endOffset; this.isMultiline = isMultiline; - this.startLineNumber = startLineNumber; + this.startLineNumber = startLineNumber + 1; this.severity = severity; this.type = type; this.terminalWidth = terminalWidth; - this.colorEnabled = colorEnabled; + this.isColorEnabled = isColorEnabled; } @Override public String toString() { + StringBuilder outputBuilder = new StringBuilder(); if (!isMultiline) { int digitsNum = (int) Math.log10(startLineNumber) + 1; String padding = " ".repeat(digitsNum + 1); - int maxLength = terminalWidth - digitsNum - 3; + int maxLength = terminalWidth - digitsNum - PIPE_AND_PADDING_LENGTH; TruncateResult result = truncate(lines.get(0), maxLength, start, length); - return padding + "|" + NEW_LINE - + getLineNumberString(digitsNum, startLineNumber) + "| " + result.line + NEW_LINE - + padding + "| " + - getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type, - colorEnabled) + NEW_LINE; + outputBuilder.append(padding).append(PIPE).append(NEW_LINE) + .append(getLineNumberString(digitsNum, startLineNumber)).append(PIPE).append(" ") + .append(result.line).append(NEW_LINE) + .append(padding).append(PIPE).append(" ") + .append(getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type, + isColorEnabled)).append(NEW_LINE); + return outputBuilder.toString(); } String startLine = lines.get(0); @@ -99,64 +107,76 @@ public String toString() { int maxLineLength = Math.max(startLine.length(), endLine.length()); int endDigitsNum = (int) Math.log10(startLineNumber + lines.size() - 1) + 1; - String padding; + String padding = " ".repeat(endDigitsNum + 1); String paddingWithColon; if (endDigitsNum == 1) { - padding = " ".repeat(endDigitsNum + 1); - paddingWithColon = ":" + " ".repeat(endDigitsNum); + paddingWithColon = COLON + " ".repeat(endDigitsNum); } else { - padding = " ".repeat(endDigitsNum + 1); - paddingWithColon = " :" + " ".repeat(endDigitsNum - 1); + paddingWithColon = " " + COLON + " ".repeat(endDigitsNum - 1); } int tabsInLastLine = countTabChars(endLine, this.endOffset); endLine = replaceTabs(endLine, this.endOffset); - int maxLength = terminalWidth - endDigitsNum - 3; - TruncateResult result1 = truncate(startLine, maxLength, start, length); - TruncateResult result2 = truncate(endLine, maxLength, 0, + int maxLength = terminalWidth - endDigitsNum - PIPE_AND_PADDING_LENGTH; + TruncateResult startLineResult = truncate(startLine, maxLength, start, length); + TruncateResult endLineResult = truncate(endLine, maxLength, 0, endOffset + 3 * tabsInLastLine); - if (lines.size() == 2) { - return padding + "|" + NEW_LINE - + getLineNumberString(endDigitsNum, startLineNumber) + "| " + result1.line + NEW_LINE - + padding + "| " + - getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type, - colorEnabled) + NEW_LINE - + getLineNumberString(endDigitsNum, startLineNumber + 1) + "| " + result2.line + NEW_LINE - + padding + "| " + - getUnderline(0, result2.diagnosticLength, this.severity, this.type, colorEnabled) + NEW_LINE; + outputBuilder.append(padding).append(PIPE).append(NEW_LINE) + .append(getLineNumberString(endDigitsNum, startLineNumber)).append(PIPE).append(" ") + .append(startLineResult.line).append(NEW_LINE); + + if (lines.size() <= MAX_LINES_BEFORE_HIDING) { + outputBuilder.append(padding).append(PIPE).append(" ") + .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength, + this.severity, + this.type, isColorEnabled)).append(NEW_LINE); + for (int i = 1; i < lines.size() - 1; i++) { + String line = replaceTabs(lines.get(i), 0); + TruncateResult lineResult = truncate(line, maxLength, 0, line.length()); + outputBuilder.append(getLineNumberString(endDigitsNum, startLineNumber + i)).append(PIPE).append(" ") + .append(lineResult.line).append(NEW_LINE) + .append(padding).append(PIPE).append(" ") + .append(getUnderline(lineResult.diagnosticStart, lineResult.diagnosticLength, this.severity, + this.type, isColorEnabled)).append(NEW_LINE); + } - } - String padding2 = " ".repeat(Math.min(terminalWidth, maxLineLength) / 2); - return padding + "|" + NEW_LINE - + getLineNumberString(endDigitsNum, startLineNumber) + "| " + result1.line + NEW_LINE - + paddingWithColon + "| " + - getUnderline(result1.diagnosticStart, result1.diagnosticLength, this.severity, this.type, - colorEnabled) + NEW_LINE - + paddingWithColon + "| " + padding2 + ":" + NEW_LINE - + paddingWithColon + "| " + padding2 + ":" + NEW_LINE - + getLineNumberString(endDigitsNum, startLineNumber + lines.size() - 1) + "| " - + result2.line + NEW_LINE - + padding + "| " + getUnderline(0, result2.diagnosticLength, this.severity, this.type, colorEnabled) + - NEW_LINE; + } else { + String paddingToMiddleColon = " ".repeat(Math.min(terminalWidth, maxLineLength) / 2); + String hiddenLinesPlaceholder = paddingWithColon + PIPE + " " + paddingToMiddleColon + COLON + NEW_LINE; + outputBuilder.append(paddingWithColon).append(PIPE).append(" ") + .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength, + this.severity, + this.type, isColorEnabled)).append(NEW_LINE) + .append(hiddenLinesPlaceholder).append(hiddenLinesPlaceholder); + } + return outputBuilder.append(getLineNumberString(endDigitsNum, startLineNumber + lines.size() - 1)) + .append(PIPE).append(" ").append(endLineResult.line).append(NEW_LINE) + .append(padding).append(PIPE).append(" ") + .append(getUnderline(0, endLineResult.diagnosticLength, this.severity, this.type, isColorEnabled)) + .append(NEW_LINE).toString(); } - public static String getColoredString(String message, String color, boolean colorEnabled) { - return colorEnabled ? JANSI_ANNOTATOR + color + " " + message + JANSI_RESET : message; + public static String getColoredString(String message, String color, boolean isColorEnabled) { + return isColorEnabled ? JANSI_ANNOTATOR + color + " " + message + JANSI_RESET : message; } private static String getLineNumberString(int numberOfDigits, int lineNumber) { return String.format("%" + numberOfDigits + "d ", lineNumber); } + private static int getStart(List lines, int start) { + return start + 3 * countTabChars(lines.get(0), start); + } + private static String getUnderline(int offset, int length, DiagnosticSeverity severity, - DiagnosticAnnotationType type, boolean colorEnabled) { + DiagnosticAnnotationType type, boolean isColorEnabled) { String symbol = "^"; if (type == DiagnosticAnnotationType.MISSING) { symbol = "+"; } return " ".repeat(offset) + - getColoredString(symbol.repeat(length), SEVERITY_COLORS.get(severity), colorEnabled); + getColoredString(symbol.repeat(length), SEVERITY_COLORS.get(severity), isColorEnabled); } private static int countTabChars(String line, int end) { @@ -175,9 +195,8 @@ protected static TruncateResult truncate(String line, int maxLength, int diagnos } StringBuilder truncatedLineBuilder = new StringBuilder(); - String ellipsis = "..."; if (diagnosticStart + diagnosticLength <= maxLength - 3) { - truncatedLineBuilder.append(line, 0, maxLength - 3).append(ellipsis); + truncatedLineBuilder.append(line, 0, maxLength - 3).append(ELLIPSIS); return new TruncateResult(truncatedLineBuilder.toString(), diagnosticStart, diagnosticLength); } @@ -188,10 +207,9 @@ protected static TruncateResult truncate(String line, int maxLength, int diagnos int newDiagnosticLength = Math.min(diagnosticLength, maxLength - newDiagnosticStart - 3); int stringStart = Math.min(stepsToMoveWindow + 3, border); - truncatedLineBuilder.append(ellipsis).append(line, stringStart, border).append(ellipsis); + truncatedLineBuilder.append(ELLIPSIS).append(line, stringStart, border).append(ELLIPSIS); return new TruncateResult(truncatedLineBuilder.toString(), newDiagnosticStart, Math.max(0, newDiagnosticLength)); - } private static String replaceTabs(String line, int end) { From b903b1b5b1495c120ec68e9d6bbdf9f53d9477e8 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Mon, 6 May 2024 09:38:58 +0530 Subject: [PATCH 47/55] Format test bal files, update toml files --- .../cli/diagnostics/AnnotateDiagnostics.java | 9 +- .../cli/diagnostics/DiagnosticAnnotation.java | 4 +- .../diagnostics/AnnotateDiagnosticsTest.java | 2 +- .../diagnostics/DiagnosticAnnotationTest.java | 2 +- .../bal-error/multi-line-expected.txt | 272 +++++++------- .../bal-error/multi-line.bal | 347 +++++++++--------- .../bal-project-error/project1/Ballerina.toml | 5 +- .../bal-project-error/project2/Ballerina.toml | 2 +- .../diagnostics/StringDiagnosticProperty.java | 2 +- 9 files changed, 326 insertions(+), 319 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index 6cc73d909544..d3af79ec2f31 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -49,7 +49,7 @@ /** * This class is used to generate diagnostic annotated messages from diagnostics. * - * @since 2201.9.0 + * @since 2201.10.0 */ public final class AnnotateDiagnostics { @@ -178,8 +178,7 @@ private DiagnosticAnnotation getDiagnosticAnnotation(Document document, Location terminalWidth, isColorEnabled); } - private DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document document, - PackageDiagnostic packageDiagnostic, + private DiagnosticAnnotation getSyntaxDiagnosticAnnotation(Document document, PackageDiagnostic packageDiagnostic, int diagnosticCode) { TextDocument textDocument = document.textDocument(); Location location = packageDiagnostic.location(); @@ -227,8 +226,8 @@ private DiagnosticAnnotation getMissingTokenAnnotation(PackageDiagnostic package terminalWidth, isColorEnabled); } - private DiagnosticAnnotation getInvalidTokenAnnotation(TextDocument textDocument, - LocationDetails locationDetails, String color) { + private DiagnosticAnnotation getInvalidTokenAnnotation(TextDocument textDocument, LocationDetails locationDetails, + String color) { List lines = getLines(textDocument, locationDetails); // TODO: Remove reusable code to separate methods String line = lines.get(0); String annotatedLine = line.substring(0, locationDetails.startOffset) + diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index e89fb25550ea..f52d29e769b7 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -26,7 +26,7 @@ /** * Represents a diagnostic annotation that is used to annotate the source code with diagnostics. * - * @since 2201.9.0 + * @since 2201.10.0 */ public final class DiagnosticAnnotation { @@ -39,7 +39,7 @@ public final class DiagnosticAnnotation { private static final int PIPE_AND_PADDING_LENGTH = " | ".length(); private static final int MAX_LINES_BEFORE_HIDING = 2; private static final String INTERNAL_COLOR = "blue"; - private static final String HINT_COLOR = "blue"; // TODO: Color of hints should be different from INFO + private static final String HINT_COLOR = "green"; private static final String INFO_COLOR = "blue"; private static final String WARNING_COLOR = "yellow"; private static final String ERROR_COLOR = "red"; diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index b2c05b7de465..f7a5681fb084 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -44,7 +44,7 @@ /** * Test cases for AnnotateDiagnostics class. * - * @since 2201.9.0 + * @since 2201.10.0 */ public class AnnotateDiagnosticsTest { diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java index 0da942929b9e..dcfeb2e0fbd8 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java @@ -28,7 +28,7 @@ /** * Test cases for DiagnosticAnnotation class. * - * @since 2201.9.0 + * @since 2201.10.0 */ public class DiagnosticAnnotationTest { diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt index 8df8e8343c03..bb06433a5089 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line-expected.txt @@ -1,110 +1,110 @@ -ERROR [multi-line.bal:(63:38,63:45)] incompatible types: expected 'Person', found 'Teacher' (BCE2066) +ERROR [multi-line.bal:(62:38,62:45)] incompatible types: expected 'Person', found 'Teacher' (BCE2066) | -63 | Person[] outputPersonList = from Teacher person in personList +62 | Person[] outputPersonList = from Teacher person in personList | ^^^^^^^ -ERROR [multi-line.bal:(66:30,66:45)] undeclared field 'lastName' in record 'Teacher' (BCE2119) +ERROR [multi-line.bal:(65:23,65:38)] undeclared field 'lastName' in record 'Teacher' (BCE2119) | -66 | lastName: person.lastName, - | ^^^^^^^^^^^^^^^ +65 | lastName: person.lastName, + | ^^^^^^^^^^^^^^^ -ERROR [multi-line.bal:(67:25,67:35)] undeclared field 'age' in record 'Teacher' (BCE2119) +ERROR [multi-line.bal:(66:18,66:28)] undeclared field 'age' in record 'Teacher' (BCE2119) | -67 | age: person.age - | ^^^^^^^^^^ +66 | age: person.age + | ^^^^^^^^^^ -ERROR [multi-line.bal:(82:18,82:21)] unknown type 'XYZ' (BCE2069) +ERROR [multi-line.bal:(81:18,81:21)] unknown type 'XYZ' (BCE2069) | -82 | from XYZ person in personList +81 | from XYZ person in personList | ^^^ -ERROR [multi-line.bal:(102:20,102:28)] undefined field 'lastName' in record 'Teacher' (BCE2023) +ERROR [multi-line.bal:(101:9,101:17)] undefined field 'lastName' in record 'Teacher' (BCE2023) | -102 | lastName: person.lastName - | ^^^^^^^^ +101 | lastName: person.lastName + | ^^^^^^^^ -ERROR [multi-line.bal:(115:32,115:34)] incompatible types: 'int' is not an iterable collection (BCE2800) +ERROR [multi-line.bal:(114:32,114:34)] incompatible types: 'int' is not an iterable collection (BCE2800) | -115 | from var person in 10 +114 | from var person in 10 | ^^ -ERROR [multi-line.bal:(116:19,116:21)] incompatible types: expected 'boolean', found 'int' (BCE2066) +ERROR [multi-line.bal:(115:11,115:13)] incompatible types: expected 'boolean', found 'int' (BCE2066) | -116 | where 20 - | ^^ +115 | where 20 + | ^^ -ERROR [multi-line.bal:(117:20,117:22)] incompatible types: expected 'Person', found 'int' (BCE2066) +ERROR [multi-line.bal:(116:12,116:14)] incompatible types: expected 'Person', found 'int' (BCE2066) | -117 | select 30; - | ^^ +116 | select 30; + | ^^ -ERROR [multi-line.bal:(131:10,134:4)] missing non-defaultable required record field 'lastName' (BCE2520) +ERROR [multi-line.bal:(130:12,133:6)] missing non-defaultable required record field 'lastName' (BCE2520) | -131 | select { - : | ^ - : | : - : | : -134 | }; - | ^^^^^^^^^ +130 | select { + : | ^ + : | : + : | : +133 | }; + | ^^^^^ -ERROR [multi-line.bal:(152:13,152:25)] incompatible types: expected 'float', found 'int' (BCE2066) +ERROR [multi-line.bal:(151:16,151:28)] incompatible types: expected 'float', found 'int' (BCE2066) | -152 | score:invalidScore - | ^^^^^^^^^^^^ +151 | score: invalidScore + | ^^^^^^^^^^^^ -ERROR [multi-line.bal:(167:22,167:38)] undefined function 'calculateScore' (BCE2011) +ERROR [multi-line.bal:(166:26,166:42)] undefined function 'calculateScore' (BCE2011) | -167 | let float avgScore=calculateScore() - | ^^^^^^^^^^^^^^^^ +166 | let float avgScore = calculateScore() + | ^^^^^^^^^^^^^^^^ -ERROR [multi-line.bal:(204:8,204:34)] invalid record binding pattern; unknown field 'fname' in record type 'Student' (BCE2576) +ERROR [multi-line.bal:(203:6,203:34)] invalid record binding pattern; unknown field 'fname' in record type 'Student' (BCE2576) | -204 | from var {fname,lastName,score} in studentList - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +203 | from var {fname, lastName, score} in studentList + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -ERROR [multi-line.bal:(206:15,206:20)] undefined symbol 'fname' (BCE2010) +ERROR [multi-line.bal:(205:20,205:25)] undefined symbol 'fname' (BCE2010) | -206 | firstName: fname, - | ^^^^^ +205 | firstName: fname, + | ^^^^^ -ERROR [multi-line.bal:(221:10,221:17)] incompatible types: expected 'Student', found '(string|float)' (BCE2066) +ERROR [multi-line.bal:(220:12,220:19)] incompatible types: expected 'Student', found '(string|float)' (BCE2066) | -221 | select student; - | ^^^^^^^ +220 | select student; + | ^^^^^^^ -ERROR [multi-line.bal:(240:13,240:18)] incompatible types: expected 'Address', found 'map' (BCE2066) +ERROR [multi-line.bal:(239:18,239:23)] incompatible types: expected 'Address', found 'map' (BCE2066) | -240 | address: addr1 - | ^^^^^ +239 | address: addr1 + | ^^^^^ -ERROR [multi-line.bal:(265:13,265:27)] incompatible types: expected 'FullName[]', found '()' (BCE2066) +ERROR [multi-line.bal:(264:12,264:26)] incompatible types: expected 'FullName[]', found '()' (BCE2066) | -265 | return outputNameList; - | ^^^^^^^^^^^^^^ +264 | return outputNameList; + | ^^^^^^^^^^^^^^ -ERROR [multi-line.bal:(277:24,277:34)] incompatible types: expected 'string', found 'int' (BCE2066) +ERROR [multi-line.bal:(276:12,276:22)] incompatible types: expected 'string', found 'int' (BCE2066) | -277 | select person.age; - | ^^^^^^^^^^ +276 | select person.age; + | ^^^^^^^^^^ -ERROR [multi-line.bal:(291:24,294:18)] a type compatible with mapping constructor expressions not found in type 'string' (BCE2508) +ERROR [multi-line.bal:(290:12,293:6)] a type compatible with mapping constructor expressions not found in type 'string' (BCE2508) | -291 | select { - : | ^ - : | : - : | : -294 | }; - | ^^^^^^^^^^^^^^^^^ +290 | select { + : | ^ + : | : + : | : +293 | }; + | ^^^^^ -ERROR [multi-line.bal:(350:36,350:41)] redeclared symbol 'fname' (BCE2008) +ERROR [multi-line.bal:(349:36,349:41)] redeclared symbol 'fname' (BCE2008) | -350 | Employee[] records = from var {fname, lname, age} in entities select {fname, lname, age}; +349 | Employee[] records = from var {fname, lname, age} in entities | ^^^^^ -ERROR [multi-line.bal:(363:21,363:24)] redeclared symbol 'age' (BCE2008) +ERROR [multi-line.bal:(363:13,363:16)] redeclared symbol 'age' (BCE2008) | -363 | let int age = 35 - | ^^^ +363 | let int age = 35 + | ^^^ ERROR [multi-line.bal:(380:44,380:47)] redeclared symbol 'age' (BCE2008) | @@ -113,159 +113,165 @@ ERROR [multi-line.bal:(380:44,380:47)] redeclared symbol 'age' (BCE2008) ERROR [multi-line.bal:(400:11,400:14)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) | -400 | table ids = from var x in t select x.id; +400 | table ids = from var x in t | ^^^ -ERROR [multi-line.bal:(400:22,400:49)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) +ERROR [multi-line.bal:(400:22,401:20)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) | -400 | table ids = from var x in t select x.id; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +400 | table ids = from var x in t + | ^^^^^^^^^^^^^^^ +401 | select x.id; + | ^^^^^^^^^^^^^^^^^^^ -ERROR [multi-line.bal:(410:11,410:14)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) +ERROR [multi-line.bal:(411:11,411:14)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) | -410 | table ids = from var {id} in t select id; +411 | table ids = from var {id} in t | ^^^ -ERROR [multi-line.bal:(410:22,410:50)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) +ERROR [multi-line.bal:(411:22,412:18)] invalid constraint type. expected subtype of 'map' but found 'int' (BCE3300) | -410 | table ids = from var {id} in t select id; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +411 | table ids = from var {id} in t + | ^^^^^^^^^^^^^^^^^^ +412 | select id; + | ^^^^^^^^^^^^^^^^^ -ERROR [multi-line.bal:(415:29,415:30)] incompatible types: 'int' is not an iterable collection (BCE2800) +ERROR [multi-line.bal:(417:29,417:30)] incompatible types: 'int' is not an iterable collection (BCE2800) | -415 | int[] w = from var a in x +417 | int[] w = from var a in x | ^ -ERROR [multi-line.bal:(420:12,420:64)] incompatible types: expected 'error?', found 'stream' (BCE2066) +ERROR [multi-line.bal:(422:12,423:22)] incompatible types: expected 'error?', found 'stream' (BCE2066) | -420 | return stream from string num in clientStream select {a: 1}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +422 | return stream from string num in clientStream + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +423 | select {a: 1}; + | ^^^^^^^^^^^^^^^^^^^^^ -ERROR [multi-line.bal:(425:22,425:29)] invalid record binding pattern with type 'anydata' (BCE2607) +ERROR [multi-line.bal:(428:22,428:29)] invalid record binding pattern with type 'anydata' (BCE2607) | -425 | var x = map from var {k} in keyValsMap +428 | var x = map from var {k} in keyValsMap | ^^^^^^^ -ERROR [multi-line.bal:(426:25,426:26)] undefined symbol 'k' (BCE2010) +ERROR [multi-line.bal:(429:16,429:17)] undefined symbol 'k' (BCE2010) | -426 | select k; - | ^ +429 | select k; + | ^ -ERROR [multi-line.bal:(431:22,431:29)] invalid record binding pattern with type 'any' (BCE2607) +ERROR [multi-line.bal:(434:22,434:29)] invalid record binding pattern with type 'any' (BCE2607) | -431 | var x = map from var {k} in keyValsMap +434 | var x = map from var {k} in keyValsMap | ^^^^^^^ -ERROR [multi-line.bal:(432:25,432:26)] undefined symbol 'k' (BCE2010) +ERROR [multi-line.bal:(435:16,435:17)] undefined symbol 'k' (BCE2010) | -432 | select k; - | ^ +435 | select k; + | ^ -ERROR [multi-line.bal:(450:28,450:30)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) +ERROR [multi-line.bal:(453:28,453:30)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) | -450 | var result = table key(id) from var user in users +453 | var result = table key(id) from var user in users | ^^ -ERROR [multi-line.bal:(455:24,455:26)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) +ERROR [multi-line.bal:(458:24,458:26)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) | -455 | result = table key(id) from var user in userList +458 | result = table key(id) from var user in userList | ^^ -ERROR [multi-line.bal:(468:28,468:30)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) +ERROR [multi-line.bal:(471:28,471:30)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) | -468 | var result = table key(id, firstName) from var user in users +471 | var result = table key(id, firstName) from var user in users | ^^ -ERROR [multi-line.bal:(468:32,468:41)] field name 'firstName' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) +ERROR [multi-line.bal:(471:32,471:41)] field name 'firstName' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) | -468 | var result = table key(id, firstName) from var user in users +471 | var result = table key(id, firstName) from var user in users | ^^^^^^^^^ -ERROR [multi-line.bal:(473:24,473:26)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) +ERROR [multi-line.bal:(476:24,476:26)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) | -473 | result = table key(id, firstName) from var user in userList +476 | result = table key(id, firstName) from var user in userList | ^^ -ERROR [multi-line.bal:(473:28,473:37)] field name 'firstName' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) +ERROR [multi-line.bal:(476:28,476:37)] field name 'firstName' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) | -473 | result = table key(id, firstName) from var user in userList +476 | result = table key(id, firstName) from var user in userList | ^^^^^^^^^ -ERROR [multi-line.bal:(489:14,489:17)] incompatible types: expected 'ScoreEventType', found 'int' (BCE2066) +ERROR [multi-line.bal:(492:14,492:17)] incompatible types: expected 'ScoreEventType', found 'int' (BCE2066) | -489 | _ = from int ev in events +492 | _ = from int ev in events | ^^^ -ERROR [multi-line.bal:(493:1,493:14)] unknown type 'UndefinedType' (BCE2069) +ERROR [multi-line.bal:(496:1,496:14)] unknown type 'UndefinedType' (BCE2069) | -493 | UndefinedType[] undefinedTypeList = []; +496 | UndefinedType[] undefinedTypeList = []; | ^^^^^^^^^^^^^ -ERROR [multi-line.bal:(504:14,504:27)] unknown type 'UndefinedType' (BCE2069) +ERROR [multi-line.bal:(507:14,507:27)] unknown type 'UndefinedType' (BCE2069) | -504 | join UndefinedType item in undefinedTypeList +507 | join UndefinedType item in undefinedTypeList | ^^^^^^^^^^^^^ -ERROR [multi-line.bal:(513:29,513:31)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) +ERROR [multi-line.bal:(516:29,516:31)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) | -513 | var result1 = table key(id) from var user in users +516 | var result1 = table key(id) from var user in users | ^^ -ERROR [multi-line.bal:(515:47,515:48)] incompatible types: expected 'error?', found 'int' (BCE2066) +ERROR [multi-line.bal:(519:21,519:22)] incompatible types: expected 'error?', found 'int' (BCE2066) | -515 | select {user} on conflict 1; - | ^ +519 | on conflict 1; + | ^ -ERROR [multi-line.bal:(517:29,517:31)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) +ERROR [multi-line.bal:(521:29,521:31)] field name 'id' used in key specifier is not found in table constraint type 'record {| User user; |}' (BCE3306) | -517 | var result2 = table key(id) from var user in users +521 | var result2 = table key(id) from var user in users | ^^ -ERROR [multi-line.bal:(519:47,519:50)] incompatible types: expected 'error?', found '(error|int)' (BCE2066) +ERROR [multi-line.bal:(524:21,524:24)] incompatible types: expected 'error?', found '(error|int)' (BCE2066) | -519 | select {user} on conflict msg; - | ^^^ +524 | on conflict msg; + | ^^^ -ERROR [multi-line.bal:(524:16,524:17)] incompatible types: expected 'int', found 'string' (BCE2066) +ERROR [multi-line.bal:(529:16,529:17)] incompatible types: expected 'int', found 'string' (BCE2066) | -524 | select s); +529 | select s); | ^ -ERROR [multi-line.bal:(529:20,529:28)] incompatible types: expected 'int', found 'string' (BCE2066) +ERROR [multi-line.bal:(534:20,534:28)] incompatible types: expected 'int', found 'string' (BCE2066) | -529 | select s.trim()); +534 | select s.trim()); | ^^^^^^^^ -WARNING [multi-line.bal:(543:15,543:26)] invalid usage of the 'check' expression operator: no expression type is equivalent to error type (BCE20404) +WARNING [multi-line.bal:(548:15,548:26)] invalid usage of the 'check' expression operator: no expression type is equivalent to error type (BCE20404) | -543 | check returnNil(); +548 | check returnNil(); | ^^^^^^^^^^^ -WARNING [multi-line.bal:(552:15,552:26)] invalid usage of the 'check' expression operator: no expression type is equivalent to error type (BCE20404) +WARNING [multi-line.bal:(557:15,557:26)] invalid usage of the 'check' expression operator: no expression type is equivalent to error type (BCE20404) | -552 | check returnNil(); +557 | check returnNil(); | ^^^^^^^^^^^ -ERROR [multi-line.bal:(573:13,577:28)] incompatible types: expected 'int', found 'string[]' (BCE2066) +ERROR [multi-line.bal:(578:13,582:28)] incompatible types: expected 'int', found 'string[]' (BCE2066) | -573 | from var person in +578 | from var person in : | ^^^^^^^^^^^^^^^^^^ : | : : | : -577 | select person.firstName; +582 | select person.firstName; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -ERROR [multi-line.bal:(583:12,583:28)] incompatible types: expected 'PersonA', found 'string' (BCE2066) +ERROR [multi-line.bal:(588:12,588:28)] incompatible types: expected 'PersonA', found 'string' (BCE2066) | -583 | select person.firstName; +588 | select person.firstName; | ^^^^^^^^^^^^^^^^ -ERROR [multi-line.bal:(585:28,588:28)] incompatible types: expected 'PersonA', found 'string[]' (BCE2066) +ERROR [multi-line.bal:(590:28,593:32)] incompatible types: expected 'PersonA', found 'string[]' (BCE2066) | -585 | PersonA outputPerson = from var person in personList +590 | PersonA outputPerson = from var person in personList : | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ : | : : | : -588 | select person.firstName; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +593 | select person.firstName; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line.bal index f779a62fd1e4..d0897f96462d 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/multi-line.bal @@ -15,44 +15,43 @@ // under the License. type Person record {| - string firstName; - string lastName; - int age; + string firstName; + string lastName; + int age; |}; type Teacher record {| - string firstName; + string firstName; |}; type Department record {| - string name; + string name; |}; -type Student record{| +type Student record {| string firstName; string lastName; float score; |}; -type FullName record{| - string firstName; - string lastName; +type FullName record {| + string firstName; + string lastName; |}; type Person1 record {| - string firstName; - string lastName; - string deptAccess; - Address address; + string firstName; + string lastName; + string deptAccess; + Address address; |}; -type Address record{| +type Address record {| string city; string country; |}; - -function testFromClauseWithInvalidType() returns Person[]{ +function testFromClauseWithInvalidType() returns Person[] { Person p1 = {firstName: "Alex", lastName: "George", age: 23}; Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; @@ -61,16 +60,16 @@ function testFromClauseWithInvalidType() returns Person[]{ Person[] personList = [p1, p2, p3]; Person[] outputPersonList = from Teacher person in personList - select { - firstName: person.firstName, - lastName: person.lastName, - age: person.age - }; + select { + firstName: person.firstName, + lastName: person.lastName, + age: person.age + }; - return outputPersonList; + return outputPersonList; } -function testFromClauseWithUnDefinedType() returns Person[]{ +function testFromClauseWithUnDefinedType() returns Person[] { Person p1 = {firstName: "Alex", lastName: "George", age: 23}; Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; @@ -80,13 +79,13 @@ function testFromClauseWithUnDefinedType() returns Person[]{ Person[] outputPersonList = from XYZ person in personList - select { - firstName: person.firstName, - lastName: person.lastName, - age: person.age - }; + select { + firstName: person.firstName, + lastName: person.lastName, + age: person.age + }; - return outputPersonList; + return outputPersonList; } function testSelectTypeMismatch() { @@ -97,13 +96,13 @@ function testSelectTypeMismatch() { Teacher[] outputPersonList = from Person person in personList - select { - firstName: person.firstName, - lastName: person.lastName - }; + select { + firstName: person.firstName, + lastName: person.lastName + }; } -function testQueryWithInvalidExpressions() returns Person[]{ +function testQueryWithInvalidExpressions() returns Person[] { Person p1 = {firstName: "Alex", lastName: "George", age: 23}; Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; @@ -113,156 +112,156 @@ function testQueryWithInvalidExpressions() returns Person[]{ Person[] outputPersonList = from var person in 10 - where 20 - select 30; + where 20 + select 30; - return outputPersonList; + return outputPersonList; } -function testMissingRequiredRecordField() returns Student[]{ +function testMissingRequiredRecordField() returns Student[] { Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; Student[] studentList = [s1, s2]; - Student[] outputStudentList= - from var student in studentList - select { - firstName: student.firstName, - score:student.score - }; - - return outputStudentList; + Student[] outputStudentList = +from var student in studentList + select { + firstName: student.firstName, + score: student.score + }; + + return outputStudentList; } -function testInvalidFieldValueInSelect() returns Student[]{ +function testInvalidFieldValueInSelect() returns Student[] { Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; Student[] studentList = [s1, s2]; - Student[] outputStudentList= - from var student in studentList - let int invalidScore=90 - select { - firstName: student.firstName, - lastName:student.lastName, - score:invalidScore - }; + Student[] outputStudentList = + from var student in studentList + let int invalidScore = 90 + select { + firstName: student.firstName, + lastName: student.lastName, + score: invalidScore + }; - return outputStudentList; + return outputStudentList; } -function testUndefinedFunctionInLet() returns Student[]{ +function testUndefinedFunctionInLet() returns Student[] { Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; Student[] studentList = [s1, s2]; - Student[] outputStudentList= - from var student in studentList - let float avgScore=calculateScore() - select { - firstName: student.firstName, - lastName:student.lastName, - score:avgScore - }; + Student[] outputStudentList = +from var student in studentList + let float avgScore = calculateScore() + select { + firstName: student.firstName, + lastName: student.lastName, + score: avgScore + }; - return outputStudentList; + return outputStudentList; } -function testDuplicateKeyInSelect() returns Student[]{ +function testDuplicateKeyInSelect() returns Student[] { Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; Student[] studentList = [s1, s2]; - Student[] outputStudentList= - from var student in studentList - select { - firstName: student.firstName, - lastName:student.lastName, - score:student.score, - lastName:student.lastName - }; + Student[] outputStudentList = +from var student in studentList + select { + firstName: student.firstName, + lastName: student.lastName, + score: student.score, + lastName: student.lastName + }; - return outputStudentList; + return outputStudentList; } -function testInvalidRecordBindingPattern() returns Student[]{ +function testInvalidRecordBindingPattern() returns Student[] { Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; Student[] studentList = [s1, s2]; - Student[] outputStudentList= - from var {fname,lastName,score} in studentList - select { - firstName: fname, - lastName: lastName, - score: score - }; + Student[] outputStudentList = +from var {fname, lastName, score} in studentList + select { + firstName: fname, + lastName: lastName, + score: score + }; - return outputStudentList; + return outputStudentList; } -function testIncompatibleTypesInFrom() returns Student[]{ +function testIncompatibleTypesInFrom() returns Student[] { Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; - Student[] outputStudentList= - from var student in s1 - select student; + Student[] outputStudentList = +from var student in s1 + select student; - return outputStudentList; + return outputStudentList; } -function testMapAssignmetToRecordTypesWithRequiredFields() returns Person1[]{ +function testMapAssignmetToRecordTypesWithRequiredFields() returns Person1[] { - Person1 p1 = {firstName: "Alex", lastName: "George", deptAccess: "XYZ", address:{city:"NY", country:"America"}}; - Person1 p2 = {firstName: "Ranjan", lastName: "Fonseka", deptAccess: "XYZ", address:{city:"NY", country:"America"}}; + Person1 p1 = {firstName: "Alex", lastName: "George", deptAccess: "XYZ", address: {city: "NY", country: "America"}}; + Person1 p2 = {firstName: "Ranjan", lastName: "Fonseka", deptAccess: "XYZ", address: {city: "NY", country: "America"}}; Person1[] personList = [p1, p2]; - map addr1 = {city:"Manchester",country:"UK"}; - - Person1[] outputPersonList= - from var person in personList - select { - firstName: person.firstName, - lastName: person.lastName, - deptAccess: person.deptAccess, - address: addr1 - }; + map addr1 = {city: "Manchester", country: "UK"}; + + Person1[] outputPersonList = +from var person in personList + select { + firstName: person.firstName, + lastName: person.lastName, + deptAccess: person.deptAccess, + address: addr1 + }; - return outputPersonList; + return outputPersonList; } -function testReassignValueInLet() returns FullName[]{ +function testReassignValueInLet() returns FullName[] { Student s1 = {firstName: "Alex", lastName: "George", score: 82.5}; Student s2 = {firstName: "Ranjan", lastName: "Fonseka", score: 90.6}; Student[] studentList = [s1, s2]; - FullName[] nameList = []; + FullName[] nameList = []; - var outputNameList = - from var student in studentList - let float twiceScore = (student.score * 2.0) - do { - twiceScore = 1000; - if(twiceScore < 50.00){ - FullName fullname = {firstName:student.firstName,lastName:student.lastName}; - nameList.push(fullname); - } - }; + var outputNameList = + from var student in studentList + let float twiceScore = (student.score * 2.0) + do { + twiceScore = 1000; + if (twiceScore < 50.00) { + FullName fullname = {firstName: student.firstName, lastName: student.lastName}; + nameList.push(fullname); + } + }; - return outputNameList; + return outputNameList; } function testQueryExprForString() returns string { @@ -274,7 +273,7 @@ function testQueryExprForString() returns string { string outputNameString = from var person in personList - select person.age; + select person.age; return outputNameString; } @@ -288,10 +287,10 @@ function testQueryExprForString2() returns string { string outputNameString = from var person in personList - select { - firstName: person.firstName, - lastName: person.lastName - }; + select { + firstName: person.firstName, + lastName: person.lastName + }; return outputNameString; } @@ -310,7 +309,7 @@ function testQueryExprWithAmbigousTypeForXML() { xml book = book1 + book2; xml|xml[] books = from var x in book/ - select x; + select x; } @@ -323,7 +322,7 @@ function testQueryExprWithAmbigousTypeForString() { string|string[] outputNameString = from var person in personList - select person.firstName; + select person.firstName; } type EmployeeEntity record { @@ -342,12 +341,13 @@ type Employee record {| function testVariableShadowingWithQueryExpressions() { string fname = ""; EmployeeEntity[] entities = [ - {id: 1232, fname: "Sameera", lname: "Jayasoma", age: 30}, - {id: 1232, fname: "Asanthi", lname: "Kulasinghe", age: 30}, - {id: 1232, fname: "Khiana", lname: "Jayasoma", age: 2} - ]; + {id: 1232, fname: "Sameera", lname: "Jayasoma", age: 30}, + {id: 1232, fname: "Asanthi", lname: "Kulasinghe", age: 30}, + {id: 1232, fname: "Khiana", lname: "Jayasoma", age: 2} + ]; - Employee[] records = from var {fname, lname, age} in entities select {fname, lname, age}; + Employee[] records = from var {fname, lname, age} in entities + select {fname, lname, age}; } public function testMethodParamWithLet(int age) { @@ -360,12 +360,12 @@ public function testMethodParamWithLet(int age) { Person[] outputPersonList = from var person in personList - let int age = 35 - select { - firstName: person.firstName, - lastName: person.lastName, - age: age - }; + let int age = 35 + select { + firstName: person.firstName, + lastName: person.lastName, + age: age + }; } public function testMethodParamInQuery(int age) { @@ -378,11 +378,11 @@ public function testMethodParamInQuery(int age) { Person[] outputPersonList = from var {firstName, lastName, age} in personList - select { - firstName: firstName, - lastName: lastName, - age: age - }; + select { + firstName: firstName, + lastName: lastName, + age: age + }; } type TableRecord record { @@ -393,43 +393,46 @@ type TableRecord record { function testTableWithNonMappingType() { table key(name) t = table [ - {name: "Amy", id: 1234}, - {name: "John", id: 4567} - ]; + {name: "Amy", id: 1234}, + {name: "John", id: 4567} + ]; - table ids = from var x in t select x.id; + table ids = from var x in t + select x.id; } function testTableWithNonMappingTypeWithBindingPatterns() { table key(name) t = table [ - {name: "Amy", id: 1234}, - {name: "John", id: 4567} - ]; + {name: "Amy", id: 1234}, + {name: "John", id: 4567} + ]; - table ids = from var {id} in t select id; + table ids = from var {id} in t + select id; } public function testInvalidInputType() { int x = 1; int[] w = from var a in x - select 1; + select 1; } function testIncompatibleSelectType(stream clientStream) returns error? { - return stream from string num in clientStream select {a: 1}; + return stream from string num in clientStream + select {a: 1}; } function testMapBindingPatternsAnydataType() { - map keyValsMap = {foo:"sss", bar:"ffff"}; + map keyValsMap = {foo: "sss", bar: "ffff"}; var x = map from var {k} in keyValsMap - select k; + select k; } function testMapBindingPatternsAnyType() { - map keyValsMap = {foo:"sss", bar:"ffff"}; + map keyValsMap = {foo: "sss", bar: "ffff"}; var x = map from var {k} in keyValsMap - select k; + select k; } type User record { @@ -448,13 +451,13 @@ function testInvalidTypeInSelectWithQueryConstructingTable() { users.add(u2); var result = table key(id) from var user in users - where user.age > 21 && user.age < 60 - select {user}; + where user.age > 21 && user.age < 60 + select {user}; User[] userList = [u1, u2]; result = table key(id) from var user in userList - where user.age > 21 && user.age < 60 - select {user}; + where user.age > 21 && user.age < 60 + select {user}; } function testInvalidTypeInSelectWithQueryConstructingTable2() { @@ -466,13 +469,13 @@ function testInvalidTypeInSelectWithQueryConstructingTable2() { users.add(u2); var result = table key(id, firstName) from var user in users - where user.age > 21 && user.age < 60 - select {user}; + where user.age > 21 && user.age < 60 + select {user}; User[] userList = [u1, u2]; result = table key(id, firstName) from var user in userList - where user.age > 21 && user.age < 60 - select {user}; + where user.age > 21 && user.age < 60 + select {user}; } type ScoreEvent readonly & record {| @@ -494,7 +497,7 @@ UndefinedType[] undefinedTypeList = []; public function testVariableOfUndefinedTypeUsedInFromClause() { int[] _ = from var item in undefinedTypeList - select 1; + select 1; } int[] customerList = []; @@ -511,12 +514,14 @@ function testInvalidTypeInOnConflictClauseWithQueryConstructingTable() { error|int msg = error("Error"); var result1 = table key(id) from var user in users - where user.age > 21 && user.age < 60 - select {user} on conflict 1; + where user.age > 21 && user.age < 60 + select {user} + on conflict 1; var result2 = table key(id) from var user in users - where user.age > 21 && user.age < 60 - select {user} on conflict msg; + where user.age > 21 && user.age < 60 + select {user} + on conflict msg; } function testQueryUsedAsFuncArg() { @@ -571,7 +576,7 @@ function testInvalidContextuallyExpectedTypes() { PersonA[] personList = []; int outputPersonList = from var person in - personList + personList let int newAge = 20 where person.age == 33 select person.firstName; @@ -583,7 +588,7 @@ function testInvalidContextuallyExpectedTypes() { select person.firstName; PersonA outputPerson = from var person in personList - let int newAge = 20 - where person.age == 33 - select person.firstName; + let int newAge = 20 + where person.age == 33 + select person.firstName; } diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/Ballerina.toml index 56d23377fe8b..95e1990c2c6f 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project1/Ballerina.toml @@ -1,8 +1,5 @@ [package] -org = "radith" +org = "testdig" name = "project1" version = "0.1.0" distribution = "2201.8.4" - -[build-options] -observabilityIncluded = true diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/Ballerina.toml index 4d24c5ab04b9..68a164cdecbc 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "radith" +org = "testdig" name = "project2" version = "0.1.0" distribution = "2201.8.4" diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java index 1ec0727a85b0..2f7bda466e2a 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/diagnostics/StringDiagnosticProperty.java @@ -26,7 +26,7 @@ /** * Represents a string diagnostic property. * - * @since 2201.9.0 + * @since 2201.10.0 */ public class StringDiagnosticProperty implements DiagnosticProperty { From 85d3c9818e446cdf081e194296d85b267a08fedf Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Mon, 6 May 2024 09:51:18 +0530 Subject: [PATCH 48/55] Integrate dataprovider for resilient tests --- .../diagnostics/AnnotateDiagnosticsTest.java | 33 +++++++++++++------ ...xpected3.txt => long-line-expected100.txt} | 0 ...xpected2.txt => long-line-expected150.txt} | 0 ...xpected1.txt => long-line-expected200.txt} | 0 ...expected6.txt => long-line-expected38.txt} | 0 ...expected5.txt => long-line-expected40.txt} | 0 ...expected4.txt => long-line-expected50.txt} | 0 ...xpected0.txt => long-line-expected999.txt} | 0 8 files changed, 23 insertions(+), 10 deletions(-) rename cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/{long-line-expected3.txt => long-line-expected100.txt} (100%) rename cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/{long-line-expected2.txt => long-line-expected150.txt} (100%) rename cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/{long-line-expected1.txt => long-line-expected200.txt} (100%) rename cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/{long-line-expected6.txt => long-line-expected38.txt} (100%) rename cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/{long-line-expected5.txt => long-line-expected40.txt} (100%) rename cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/{long-line-expected4.txt => long-line-expected50.txt} (100%) rename cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/{long-line-expected0.txt => long-line-expected999.txt} (100%) diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index f7a5681fb084..cf1465d33696 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -27,6 +27,7 @@ import org.ballerinalang.test.CompileResult; import org.testng.Assert; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.io.IOException; @@ -111,9 +112,22 @@ void testInvalidTokenAnnotation() throws IOException { Assert.assertEquals(output, expectedOutput); } - @Test(description = "Test annotations when erroneous line is longer than the terminal width. Tests truncation") - void testLongLineAnnotation() throws IOException, NoSuchFieldException, IllegalAccessException { - int[] terminalWidth = {999, 200, 150, 100, 50, 40, 38}; + @DataProvider(name = "terminalWidthProvider") + public Object[][] terminalWidthProvider() { + return new Object[][]{ + {999}, + {200}, + {150}, + {100}, + {50}, + {40}, + {38} + }; + } + + @Test(description = "Test annotations when erroneous line is longer than the terminal width. Tests truncation", + dataProvider = "terminalWidthProvider") + void testLongLineAnnotation(int terminalWidth) throws IOException, NoSuchFieldException, IllegalAccessException { CompileResult result = BCompileUtil.compileOffline( "test-resources/diagnostics-test-files/bal-error/long-line.bal"); Diagnostic[] diagnostics = result.getDiagnostics(); @@ -122,13 +136,12 @@ void testLongLineAnnotation() throws IOException, NoSuchFieldException, IllegalA Diagnostic diagnostic = diagnostics[0]; Field terminalWidthField = AnnotateDiagnostics.class.getDeclaredField("terminalWidth"); terminalWidthField.setAccessible(true); - for (int i = 0; i < terminalWidth.length; i++) { - terminalWidthField.setInt(annotateDiagnostics, terminalWidth[i]); - String output = annotateDiagnostics.renderDiagnostic(diagnostic).toString(); - String expectedOutput = - Files.readString(testResources.resolve("bal-error").resolve("long-line-expected" + i + ".txt")); - Assert.assertEquals(output, expectedOutput); - } + terminalWidthField.setInt(annotateDiagnostics, terminalWidth); + String output = annotateDiagnostics.renderDiagnostic(diagnostic).toString(); + String expectedOutput = + Files.readString( + testResources.resolve("bal-error").resolve("long-line-expected" + terminalWidth + ".txt")); + Assert.assertEquals(output, expectedOutput); } @Test(description = "Test annotations when a ballerina project contains errors in multiple files") diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected100.txt similarity index 100% rename from cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected3.txt rename to cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected100.txt diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected2.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected150.txt similarity index 100% rename from cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected2.txt rename to cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected150.txt diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected1.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected200.txt similarity index 100% rename from cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected1.txt rename to cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected200.txt diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected6.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected38.txt similarity index 100% rename from cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected6.txt rename to cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected38.txt diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected40.txt similarity index 100% rename from cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected5.txt rename to cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected40.txt diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected50.txt similarity index 100% rename from cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected4.txt rename to cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected50.txt diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected0.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected999.txt similarity index 100% rename from cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected0.txt rename to cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-error/long-line-expected999.txt From a66495b30ca2b01289785376f60ccfc909cb52a7 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Mon, 6 May 2024 10:54:30 +0530 Subject: [PATCH 49/55] Use listener class instead of http library --- .../diagnostics/AnnotateDiagnosticsTest.java | 22 ++++++++++++++++++- .../bal-project-error/project2/main.bal | 21 ++++++++++++++++-- .../unix/project2-expected-hints.txt | 10 +++++++++ ...ted.txt => project2-expected-warnings.txt} | 0 ...pected.txt => project2-expected-hints.txt} | 0 .../windows/project2-expected-warnings.txt | 10 +++++++++ 6 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected-hints.txt rename cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/{project2-expected.txt => project2-expected-warnings.txt} (100%) rename cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/{project2-expected.txt => project2-expected-hints.txt} (100%) create mode 100644 cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected-warnings.txt diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java index cf1465d33696..2e339253ddf7 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/AnnotateDiagnosticsTest.java @@ -170,7 +170,27 @@ void testProjectWarningAnnotation() throws IOException { output.append(annotateDiagnostics.renderDiagnostic(diagnostic).toString()); output.append(System.lineSeparator()); } - String expectedOutput = getExpectedOutput(testResources.resolve("bal-project-error"), "project2-expected.txt"); + String expectedOutput = + getExpectedOutput(testResources.resolve("bal-project-error"), "project2-expected-warnings.txt"); + Assert.assertEquals(output.toString(), expectedOutput); + } + + @Test(description = "Test hint annotations in a ballerina project") + void testProjectHintAnnotation() throws IOException { + CompileResult result = BCompileUtil.compileWithoutInitInvocation( + "test-resources/diagnostics-test-files/bal-project-error/project2"); + Diagnostic[] diagnostics = result.getDiagnostics(); + AnnotateDiagnostics annotateDiagnostics = new AnnotateDiagnostics(result.project().currentPackage()); + StringBuilder output = new StringBuilder(); + for (Diagnostic diagnostic : diagnostics) { + if (diagnostic.diagnosticInfo().severity() != DiagnosticSeverity.HINT) { + continue; + } + output.append(annotateDiagnostics.renderDiagnostic(diagnostic).toString()); + output.append(System.lineSeparator()); + } + String expectedOutput = + getExpectedOutput(testResources.resolve("bal-project-error"), "project2-expected-hints.txt"); Assert.assertEquals(output.toString(), expectedOutput); } diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal index d9dc0ea4799d..ec9e8359d5da 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/project2/main.bal @@ -1,7 +1,6 @@ -import ballerina/http; import project2.mymath; -service / on new http:Listener(9090) { +service / on new Listener() { resource function get greeting() returns string { return "Hello, World!"; @@ -16,3 +15,21 @@ service / on new http:Listener(9090) { } } + +public class Listener { + public isolated function 'start() returns error? { + return; + } + public isolated function gracefulStop() returns error? { + return; + } + public isolated function immediateStop() returns error? { + return; + } + public isolated function detach(service object {} s) returns error? { + return; + } + public isolated function attach(service object {} s, string[]|string? name = ()) returns error? { + return; + } +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected-hints.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected-hints.txt new file mode 100644 index 000000000000..ad5a0d95e6a5 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected-hints.txt @@ -0,0 +1,10 @@ +HINT [main.bal:(9:5,9:5)] concurrent calls will not be made to this method since the method is not an 'isolated' method (BCH2005) + | +9 | resource function get add(int a, int b) returns int { + | ^ + +HINT [main.bal:(13:5,13:5)] concurrent calls will not be made to this method since the method is not an 'isolated' method (BCH2005) + | +13 | resource function get subtract(int a, int b) returns int { + | ^ + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected-warnings.txt similarity index 100% rename from cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected.txt rename to cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/unix/project2-expected-warnings.txt diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected-hints.txt similarity index 100% rename from cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected.txt rename to cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected-hints.txt diff --git a/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected-warnings.txt b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected-warnings.txt new file mode 100644 index 000000000000..ad5a0d95e6a5 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/diagnostics-test-files/bal-project-error/windows/project2-expected-warnings.txt @@ -0,0 +1,10 @@ +HINT [main.bal:(9:5,9:5)] concurrent calls will not be made to this method since the method is not an 'isolated' method (BCH2005) + | +9 | resource function get add(int a, int b) returns int { + | ^ + +HINT [main.bal:(13:5,13:5)] concurrent calls will not be made to this method since the method is not an 'isolated' method (BCH2005) + | +13 | resource function get subtract(int a, int b) returns int { + | ^ + From 7f4f3ed86f7719e96525acee3e362980d19233ce Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Mon, 6 May 2024 14:12:37 +0530 Subject: [PATCH 50/55] Update color annotation test with new hint color --- .../io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java index dcfeb2e0fbd8..7d50ffaccb1b 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/diagnostics/DiagnosticAnnotationTest.java @@ -49,7 +49,7 @@ public void testColorAnnotations() { Assert.assertEquals(warningMessage, expected); String hintMessage = DiagnosticAnnotation.getColoredString(message, hintColor, true); - expected = DiagnosticAnnotation.JANSI_ANNOTATOR + "blue" + " " + message + DiagnosticAnnotation.JANSI_RESET; + expected = DiagnosticAnnotation.JANSI_ANNOTATOR + "green" + " " + message + DiagnosticAnnotation.JANSI_RESET; Assert.assertEquals(hintMessage, expected); } From 2ede880a2aa63aa39f680c36d5226e3be87b08bc Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 7 May 2024 11:53:22 +0530 Subject: [PATCH 51/55] Fix bug found in code review --- .../cli/diagnostics/DiagnosticAnnotation.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index f52d29e769b7..904da011edc7 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -195,19 +195,22 @@ protected static TruncateResult truncate(String line, int maxLength, int diagnos } StringBuilder truncatedLineBuilder = new StringBuilder(); - if (diagnosticStart + diagnosticLength <= maxLength - 3) { - truncatedLineBuilder.append(line, 0, maxLength - 3).append(ELLIPSIS); + if (diagnosticStart + diagnosticLength <= maxLength - ELLIPSIS.length()) { + truncatedLineBuilder.append(line, 0, maxLength - ELLIPSIS.length()).append(ELLIPSIS); return new TruncateResult(truncatedLineBuilder.toString(), diagnosticStart, diagnosticLength); } int diagnosticMid = diagnosticStart + (diagnosticLength / 2); int stepsToMoveWindow = Math.max(0, diagnosticMid - (maxLength / 2)); - int border = Math.min(line.length() - 1, stepsToMoveWindow + maxLength - 3); - int newDiagnosticStart = Math.max(3, diagnosticStart - stepsToMoveWindow); - int newDiagnosticLength = Math.min(diagnosticLength, maxLength - newDiagnosticStart - 3); - int stringStart = Math.min(stepsToMoveWindow + 3, border); - - truncatedLineBuilder.append(ELLIPSIS).append(line, stringStart, border).append(ELLIPSIS); + int border = Math.min(line.length(), stepsToMoveWindow + maxLength - ELLIPSIS.length()); + int newDiagnosticStart = Math.max(ELLIPSIS.length(), diagnosticStart - stepsToMoveWindow); + int newDiagnosticLength = Math.min(diagnosticLength, maxLength - newDiagnosticStart - ELLIPSIS.length()); + int stringStart = Math.min(stepsToMoveWindow + ELLIPSIS.length(), border); + + truncatedLineBuilder.append(ELLIPSIS).append(line, stringStart, border); + if (border < line.length()) { + truncatedLineBuilder.append(ELLIPSIS); + } return new TruncateResult(truncatedLineBuilder.toString(), newDiagnosticStart, Math.max(0, newDiagnosticLength)); } From 4129911c12febf45b052107d3aa2248833cb1262 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Tue, 7 May 2024 11:54:36 +0530 Subject: [PATCH 52/55] Refactor method visibility for cleaner code --- .../cli/diagnostics/AnnotateDiagnostics.java | 1 - .../cli/diagnostics/DiagnosticAnnotation.java | 28 ++++++++----------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index d3af79ec2f31..1f7f8bba233d 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -98,7 +98,6 @@ public Ansi renderDiagnostic(Diagnostic diagnostic) { DiagnosticAnnotation diagnosticAnnotation = getDiagnosticAnnotation(document, diagnosticLocation, diagnosticInfo.severity()); return renderAnsi(diagnosticToString(diagnostic, isColorEnabled) + NEW_LINE + diagnosticAnnotation); - } private static int getTerminalWidth() { diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index 904da011edc7..93c26bdfac10 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -32,7 +32,7 @@ public final class DiagnosticAnnotation { public static final String NEW_LINE = System.lineSeparator(); public static final String JANSI_ANNOTATOR = "@|"; - public static final String JANSI_RESET = "|@"; // @|red , TEXT |@ + public static final String JANSI_RESET = "|@"; private static final String PIPE = "|"; private static final String COLON = ":"; private static final String ELLIPSIS = "..."; @@ -97,10 +97,8 @@ public String toString() { .append(getLineNumberString(digitsNum, startLineNumber)).append(PIPE).append(" ") .append(result.line).append(NEW_LINE) .append(padding).append(PIPE).append(" ") - .append(getUnderline(result.diagnosticStart, result.diagnosticLength, this.severity, this.type, - isColorEnabled)).append(NEW_LINE); + .append(getUnderline(result.diagnosticStart, result.diagnosticLength)).append(NEW_LINE); return outputBuilder.toString(); - } String startLine = lines.get(0); String endLine = lines.get(lines.size() - 1); @@ -127,33 +125,30 @@ public String toString() { if (lines.size() <= MAX_LINES_BEFORE_HIDING) { outputBuilder.append(padding).append(PIPE).append(" ") - .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength, - this.severity, - this.type, isColorEnabled)).append(NEW_LINE); + .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength)) + .append(NEW_LINE); for (int i = 1; i < lines.size() - 1; i++) { String line = replaceTabs(lines.get(i), 0); TruncateResult lineResult = truncate(line, maxLength, 0, line.length()); outputBuilder.append(getLineNumberString(endDigitsNum, startLineNumber + i)).append(PIPE).append(" ") .append(lineResult.line).append(NEW_LINE) .append(padding).append(PIPE).append(" ") - .append(getUnderline(lineResult.diagnosticStart, lineResult.diagnosticLength, this.severity, - this.type, isColorEnabled)).append(NEW_LINE); + .append(getUnderline(lineResult.diagnosticStart, lineResult.diagnosticLength)).append(NEW_LINE); } } else { String paddingToMiddleColon = " ".repeat(Math.min(terminalWidth, maxLineLength) / 2); String hiddenLinesPlaceholder = paddingWithColon + PIPE + " " + paddingToMiddleColon + COLON + NEW_LINE; outputBuilder.append(paddingWithColon).append(PIPE).append(" ") - .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength, - this.severity, - this.type, isColorEnabled)).append(NEW_LINE) + .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength)) + .append(NEW_LINE) .append(hiddenLinesPlaceholder).append(hiddenLinesPlaceholder); } return outputBuilder.append(getLineNumberString(endDigitsNum, startLineNumber + lines.size() - 1)) .append(PIPE).append(" ").append(endLineResult.line).append(NEW_LINE) .append(padding).append(PIPE).append(" ") - .append(getUnderline(0, endLineResult.diagnosticLength, this.severity, this.type, isColorEnabled)) + .append(getUnderline(0, endLineResult.diagnosticLength)) .append(NEW_LINE).toString(); } @@ -169,14 +164,13 @@ private static int getStart(List lines, int start) { return start + 3 * countTabChars(lines.get(0), start); } - private static String getUnderline(int offset, int length, DiagnosticSeverity severity, - DiagnosticAnnotationType type, boolean isColorEnabled) { + private String getUnderline(int offset, int length) { String symbol = "^"; - if (type == DiagnosticAnnotationType.MISSING) { + if (this.type == DiagnosticAnnotationType.MISSING) { symbol = "+"; } return " ".repeat(offset) + - getColoredString(symbol.repeat(length), SEVERITY_COLORS.get(severity), isColorEnabled); + getColoredString(symbol.repeat(length), SEVERITY_COLORS.get(this.severity), this.isColorEnabled); } private static int countTabChars(String line, int end) { From fda21281e81f73ee1eee4654171e5aef2dd958be Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Thu, 9 May 2024 13:53:37 +0530 Subject: [PATCH 53/55] Use string builder for efficiency --- .../cli/diagnostics/AnnotateDiagnostics.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java index 1f7f8bba233d..724cafffcec5 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/AnnotateDiagnostics.java @@ -199,20 +199,20 @@ private DiagnosticAnnotation getMissingTokenAnnotation(PackageDiagnostic package String color) { StringDiagnosticProperty strProperty = (StringDiagnosticProperty) packageDiagnostic.properties().get(0); String lineString = textDocument.line(locationDetails.startLine).text(); - String missingTokenString = getColoredString(strProperty.value(), color, isColorEnabled); + StringBuilder lineBuilder = new StringBuilder().append(lineString, 0, locationDetails.startOffset); + StringBuilder missingTokenBuilder = + new StringBuilder(getColoredString(strProperty.value(), color, isColorEnabled)); int padding = 0; if (locationDetails.startOffset < lineString.length() && lineString.charAt(locationDetails.startOffset) != ' ') { - missingTokenString = missingTokenString + " "; + missingTokenBuilder.append(" "); } if (locationDetails.startOffset > 0 && lineString.charAt(locationDetails.startOffset - 1) != ' ') { - missingTokenString = " " + missingTokenString; + missingTokenBuilder.insert(0, " "); padding++; } - - String lineWithMissingToken = lineString.substring(0, locationDetails.startOffset) + missingTokenString + - lineString.substring(locationDetails.startOffset); // TODO: Use a string builder instead - List lines = new ArrayList<>(List.of(lineWithMissingToken)); + lineBuilder.append(missingTokenBuilder).append(lineString, locationDetails.startOffset, lineString.length()); + List lines = new ArrayList<>(List.of(lineBuilder.toString())); return new DiagnosticAnnotation( lines, padding + locationDetails.startOffset, @@ -231,8 +231,7 @@ private DiagnosticAnnotation getInvalidTokenAnnotation(TextDocument textDocument String line = lines.get(0); String annotatedLine = line.substring(0, locationDetails.startOffset) + getColoredString(line.substring(locationDetails.startOffset, locationDetails.endOffset), color, - isColorEnabled) + - line.substring(locationDetails.endOffset); + isColorEnabled) + line.substring(locationDetails.endOffset); lines.set(0, annotatedLine); return new DiagnosticAnnotation( lines, From 12e70f6cc803091233d45d19f47b5d13a0404c63 Mon Sep 17 00:00:00 2001 From: Radith Samarakoon Date: Sat, 25 May 2024 00:02:01 +0530 Subject: [PATCH 54/55] WIP diagnostic area text wrap --- .../cli/diagnostics/DiagnosticAnnotation.java | 120 ++++++++++++++---- 1 file changed, 95 insertions(+), 25 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index 93c26bdfac10..75291512c178 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -37,7 +37,7 @@ public final class DiagnosticAnnotation { private static final String COLON = ":"; private static final String ELLIPSIS = "..."; private static final int PIPE_AND_PADDING_LENGTH = " | ".length(); - private static final int MAX_LINES_BEFORE_HIDING = 2; + private static final int MAX_LINES_BEFORE_HIDING = 3; private static final String INTERNAL_COLOR = "blue"; private static final String HINT_COLOR = "green"; private static final String INFO_COLOR = "blue"; @@ -94,10 +94,23 @@ public String toString() { int maxLength = terminalWidth - digitsNum - PIPE_AND_PADDING_LENGTH; TruncateResult result = truncate(lines.get(0), maxLength, start, length); outputBuilder.append(padding).append(PIPE).append(NEW_LINE) - .append(getLineNumberString(digitsNum, startLineNumber)).append(PIPE).append(" ") - .append(result.line).append(NEW_LINE) - .append(padding).append(PIPE).append(" ") - .append(getUnderline(result.diagnosticStart, result.diagnosticLength)).append(NEW_LINE); + .append(getLineNumberString(digitsNum, startLineNumber)).append(PIPE).append(" "); + if (result.needsWrap) { + int firstUnderlineLength = Math.min(result.diagnosticLength, maxLength - result.diagnosticStart); + String underlineFirstHalf = getUnderline(result.diagnosticStart, firstUnderlineLength); + String underlineSecondHalf = + getUnderline(0, result.diagnosticLength - maxLength + result.diagnosticStart); + outputBuilder.append(result.line, 0, maxLength).append(NEW_LINE) + .append(padding).append(PIPE).append(" ") + .append(underlineFirstHalf).append(NEW_LINE) + .append(result.line, maxLength, result.line.length()).append(NEW_LINE) + .append(underlineSecondHalf); + } else { + String underline = getUnderline(result.diagnosticStart, result.diagnosticLength); + outputBuilder.append(result.line).append(NEW_LINE) + .append(padding).append(PIPE).append(" ") + .append(underline).append(NEW_LINE); + } return outputBuilder.toString(); } String startLine = lines.get(0); @@ -119,30 +132,71 @@ public String toString() { TruncateResult endLineResult = truncate(endLine, maxLength, 0, endOffset + 3 * tabsInLastLine); + int firstUnderlineLength = + Math.min(startLineResult.diagnosticLength, maxLength - startLineResult.diagnosticStart); + String underlineFirstHalf = getUnderline(startLineResult.diagnosticStart, firstUnderlineLength); + String underlineSecondHalf = + getUnderline(0, startLineResult.diagnosticLength - maxLength + startLineResult.diagnosticStart); + outputBuilder.append(padding).append(PIPE).append(NEW_LINE) - .append(getLineNumberString(endDigitsNum, startLineNumber)).append(PIPE).append(" ") - .append(startLineResult.line).append(NEW_LINE); + .append(getLineNumberString(endDigitsNum, startLineNumber)).append(PIPE).append(" "); + if (startLineResult.needsWrap) { + outputBuilder.append(startLineResult.line, 0, maxLength).append(NEW_LINE); + } else { + outputBuilder.append(startLineResult.line).append(NEW_LINE); + } if (lines.size() <= MAX_LINES_BEFORE_HIDING) { - outputBuilder.append(padding).append(PIPE).append(" ") - .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength)) - .append(NEW_LINE); + outputBuilder.append(padding).append(PIPE).append(" "); + if (startLineResult.needsWrap) { + outputBuilder.append(underlineFirstHalf).append(NEW_LINE) + .append(startLineResult.line, maxLength, startLineResult.line.length()).append(NEW_LINE) + .append(underlineSecondHalf).append(NEW_LINE); + } else { + outputBuilder + .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength)) + .append(NEW_LINE); + } for (int i = 1; i < lines.size() - 1; i++) { String line = replaceTabs(lines.get(i), 0); TruncateResult lineResult = truncate(line, maxLength, 0, line.length()); - outputBuilder.append(getLineNumberString(endDigitsNum, startLineNumber + i)).append(PIPE).append(" ") - .append(lineResult.line).append(NEW_LINE) - .append(padding).append(PIPE).append(" ") - .append(getUnderline(lineResult.diagnosticStart, lineResult.diagnosticLength)).append(NEW_LINE); + outputBuilder.append(getLineNumberString(endDigitsNum, startLineNumber + i)).append(PIPE).append(" "); + if (lineResult.needsWrap) { + int midFirstUnderlineLength = + Math.min(lineResult.diagnosticLength, maxLength - lineResult.diagnosticStart); + String midUnderlineFirstHalf = getUnderline(lineResult.diagnosticStart, midFirstUnderlineLength); + String midUnderlineSecondHalf = + getUnderline(0, lineResult.diagnosticLength - maxLength + lineResult.diagnosticStart); + outputBuilder.append(lineResult.line, 0, maxLength).append(NEW_LINE) + .append(padding).append(PIPE).append(" ") + .append(midUnderlineFirstHalf).append(NEW_LINE) + .append(lineResult.line, maxLength, lineResult.line.length()).append(NEW_LINE) + .append(midUnderlineSecondHalf).append(NEW_LINE); + + } else { + outputBuilder.append(lineResult.line).append(NEW_LINE) + .append(padding).append(PIPE).append(" ") + .append(getUnderline(lineResult.diagnosticStart, lineResult.diagnosticLength)) + .append(NEW_LINE); + } } } else { String paddingToMiddleColon = " ".repeat(Math.min(terminalWidth, maxLineLength) / 2); String hiddenLinesPlaceholder = paddingWithColon + PIPE + " " + paddingToMiddleColon + COLON + NEW_LINE; - outputBuilder.append(paddingWithColon).append(PIPE).append(" ") - .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength)) - .append(NEW_LINE) - .append(hiddenLinesPlaceholder).append(hiddenLinesPlaceholder); + outputBuilder.append(paddingWithColon).append(PIPE).append(" "); + if (startLineResult.needsWrap) { + outputBuilder.append(underlineFirstHalf).append(NEW_LINE) + .append(startLineResult.line, maxLength, startLineResult.line.length()).append(NEW_LINE) + .append(underlineSecondHalf).append(NEW_LINE); + } + else { + + outputBuilder + .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength)) + .append(NEW_LINE) + .append(hiddenLinesPlaceholder).append(hiddenLinesPlaceholder); + } } return outputBuilder.append(getLineNumberString(endDigitsNum, startLineNumber + lines.size() - 1)) @@ -165,6 +219,9 @@ private static int getStart(List lines, int start) { } private String getUnderline(int offset, int length) { + if (length <= 0) { + return ""; + } String symbol = "^"; if (this.type == DiagnosticAnnotationType.MISSING) { symbol = "+"; @@ -185,28 +242,41 @@ private static int countTabChars(String line, int end) { protected static TruncateResult truncate(String line, int maxLength, int diagnosticStart, int diagnosticLength) { if (line.length() <= maxLength) { - return new TruncateResult(line, diagnosticStart, diagnosticLength); + return new TruncateResult(line, diagnosticStart, diagnosticLength, false); } StringBuilder truncatedLineBuilder = new StringBuilder(); if (diagnosticStart + diagnosticLength <= maxLength - ELLIPSIS.length()) { truncatedLineBuilder.append(line, 0, maxLength - ELLIPSIS.length()).append(ELLIPSIS); - return new TruncateResult(truncatedLineBuilder.toString(), diagnosticStart, diagnosticLength); + return new TruncateResult(truncatedLineBuilder.toString(), diagnosticStart, diagnosticLength, false); + } + + if (diagnosticStart == 0 && diagnosticLength > maxLength - ELLIPSIS.length()) { + // TODO: Handle the case where diagnostic spans the entire terminal + truncatedLineBuilder.append(line, 0, diagnosticLength).append(ELLIPSIS); + return new TruncateResult(truncatedLineBuilder.toString(), 0, diagnosticLength, true); + } else if (diagnosticStart + diagnosticLength == line.length()) { + if (diagnosticLength > maxLength - ELLIPSIS.length()) { + truncatedLineBuilder.append(ELLIPSIS).append(line, diagnosticStart, diagnosticStart + diagnosticLength); + return new TruncateResult(truncatedLineBuilder.toString(), ELLIPSIS.length(), diagnosticLength, true); + } + } else if (diagnosticLength > maxLength - ELLIPSIS.length() * 2) { + truncatedLineBuilder.append(ELLIPSIS).append(line, diagnosticStart, diagnosticStart + diagnosticLength) + .append(ELLIPSIS); + return new TruncateResult(truncatedLineBuilder.toString(), ELLIPSIS.length(), diagnosticLength, true); } int diagnosticMid = diagnosticStart + (diagnosticLength / 2); int stepsToMoveWindow = Math.max(0, diagnosticMid - (maxLength / 2)); int border = Math.min(line.length(), stepsToMoveWindow + maxLength - ELLIPSIS.length()); - int newDiagnosticStart = Math.max(ELLIPSIS.length(), diagnosticStart - stepsToMoveWindow); - int newDiagnosticLength = Math.min(diagnosticLength, maxLength - newDiagnosticStart - ELLIPSIS.length()); + int newDiagnosticStart = diagnosticStart - stepsToMoveWindow; int stringStart = Math.min(stepsToMoveWindow + ELLIPSIS.length(), border); truncatedLineBuilder.append(ELLIPSIS).append(line, stringStart, border); if (border < line.length()) { truncatedLineBuilder.append(ELLIPSIS); } - return new TruncateResult(truncatedLineBuilder.toString(), newDiagnosticStart, - Math.max(0, newDiagnosticLength)); + return new TruncateResult(truncatedLineBuilder.toString(), newDiagnosticStart, diagnosticLength, false); } private static String replaceTabs(String line, int end) { @@ -221,7 +291,7 @@ private static String replaceTabs(String line, int end) { * @param diagnosticStart The start of the diagnostic in the truncated line * @param diagnosticLength The length of the diagnostic in the truncated line */ - protected record TruncateResult(String line, int diagnosticStart, int diagnosticLength) { + protected record TruncateResult(String line, int diagnosticStart, int diagnosticLength, boolean needsWrap) { } } From ca8c1922f4253d1cd001b51f3d339ac918bd8555 Mon Sep 17 00:00:00 2001 From: Gimantha Bandara Date: Wed, 2 Oct 2024 16:14:45 +0530 Subject: [PATCH 55/55] Apply suggestions from code review Co-authored-by: Felix Schnabel --- .../io/ballerina/cli/diagnostics/DiagnosticAnnotation.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java index 75291512c178..0fc7427b523a 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/diagnostics/DiagnosticAnnotation.java @@ -189,9 +189,7 @@ public String toString() { outputBuilder.append(underlineFirstHalf).append(NEW_LINE) .append(startLineResult.line, maxLength, startLineResult.line.length()).append(NEW_LINE) .append(underlineSecondHalf).append(NEW_LINE); - } - else { - + } else { outputBuilder .append(getUnderline(startLineResult.diagnosticStart, startLineResult.diagnosticLength)) .append(NEW_LINE) @@ -286,7 +284,7 @@ private static String replaceTabs(String line, int end) { /** * Represents a result of truncating a line. - * + * @param needsWrap If the result needs to be wrapped * @param line The truncated line * @param diagnosticStart The start of the diagnostic in the truncated line * @param diagnosticLength The length of the diagnostic in the truncated line