Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import/export syntax error have more specific messages #6808

Merged
merged 1 commit into from
May 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions engine/runtime/src/main/java/org/enso/compiler/TreeToIr.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
import org.enso.compiler.core.IR$Error$Syntax$UnexpectedExpression$;
import org.enso.compiler.core.IR$Error$Syntax$InvalidEscapeSequence$;
import org.enso.compiler.core.IR$Error$Syntax$EmptyParentheses$;
import org.enso.compiler.core.IR$Error$Syntax$InvalidImport$;
import org.enso.compiler.core.IR$Error$Syntax$InvalidImport;
import org.enso.compiler.core.IR$Error$Syntax$InvalidExport;
import org.enso.compiler.core.IR$Error$Syntax$Reason;
import org.enso.compiler.core.IR$Error$Syntax$UnrecognizedToken$;
import org.enso.compiler.core.IR$Error$Syntax$UnsupportedSyntax;
Expand Down Expand Up @@ -70,6 +71,7 @@
import org.enso.syntax2.Token;
import org.enso.syntax2.Tree;

import org.enso.syntax2.Tree.Invalid;
import scala.Option;
import scala.collection.immutable.LinearSeq;
import scala.collection.immutable.List;
Expand Down Expand Up @@ -1525,10 +1527,24 @@ hidingNames, getIdentifiedLocation(imp), false,
meta(), diag()
);
} catch (SyntaxException err) {
return err.toError(IR$Error$Syntax$InvalidImport$.MODULE$);
if (err.where instanceof Invalid invalid) {
return err.toError(invalidImportReason(invalid.getError()));
} else {
return err.toError(invalidImportReason(null));
}
}
}

private IR$Error$Syntax$Reason invalidImportReason(String msg) {
return new IR$Error$Syntax$InvalidImport(
Objects.requireNonNullElse(msg, "Imports must have a valid module path"));
}

private IR$Error$Syntax$Reason invalidExportReason(String msg) {
return new IR$Error$Syntax$InvalidExport(
Objects.requireNonNullElse(msg, "Exports must have a valid module path"));
}

@SuppressWarnings("unchecked")
private String extractPackageAndName(List<IR.Name> qualifiedName, StringBuilder pkg) {
String cls = null;
Expand Down Expand Up @@ -1583,7 +1599,11 @@ hidingNames, getIdentifiedLocation(exp), false,
meta(), diag()
);
} catch (SyntaxException err) {
return err.toError(IR$Error$Syntax$InvalidImport$.MODULE$);
if (err.where instanceof Invalid invalid) {
return err.toError(invalidExportReason(invalid.getError()));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The underlying reason comes directly from the parser.

} else {
return err.toError(invalidExportReason(null));
}
}
}

Expand Down
13 changes: 11 additions & 2 deletions engine/runtime/src/main/scala/org/enso/compiler/core/IR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7803,9 +7803,18 @@ object IR {
s"Cannot define a pattern outside a pattern context"
}

case object InvalidImport extends Reason {
case class InvalidImport(
message: String = "Imports must have a valid module path"
) extends Reason {
override def explanation: String =
s"Invalid Import: $message"
}

case class InvalidExport(
message: String = "Exports must have a valid module path"
) extends Reason {
override def explanation: String =
s"Imports must have a valid module path"
s"Invalid Export: $message"
}

case object InvalidStandaloneSignature extends Reason {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.enso.compiler;

import java.util.Objects;
import org.enso.compiler.core.IR;
import org.enso.compiler.core.IR$Error$Syntax;
import org.enso.compiler.core.IR$Error$Syntax$InvalidEscapeSequence$;
import org.enso.compiler.core.IR$Error$Syntax$Reason;
import org.enso.compiler.core.IR$Error$Syntax$InvalidImport$;
import org.enso.compiler.core.IR$Error$Syntax$InvalidImport;
import org.enso.compiler.core.IR$Error$Syntax$InvalidExport;
import org.enso.compiler.core.IR$Error$Syntax$UnexpectedExpression$;
import org.enso.compiler.core.IR$Error$Syntax$UnrecognizedToken$;
import org.enso.compiler.core.IR$Error$Syntax$UnsupportedSyntax;
Expand Down Expand Up @@ -144,40 +146,49 @@ public void malformedImport2() throws Exception {
assertSingleSyntaxError(ir, IR$Error$Syntax$UnexpectedExpression$.MODULE$, "Unexpected expression", 0, 13);
}


private IR$Error$Syntax$InvalidImport invalidImport(String msg) {
return new IR$Error$Syntax$InvalidImport(msg);
}

private IR$Error$Syntax$InvalidExport invalidExport(String msg) {
return new IR$Error$Syntax$InvalidExport(msg);
}

@Test
public void malformedImport3() throws Exception {
var ir = parse("import Foo as Foo, Bar");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 14, 22);
assertSingleSyntaxError(ir, invalidImport("Expected identifier."), null, 14, 22);
}

@Test
public void malformedImport4() throws Exception {
var ir = parse("import Foo as Foo.Bar");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 14, 21);
assertSingleSyntaxError(ir, invalidImport("Expected identifier."), null, 14, 21);
}

@Test
public void malformedImport5() throws Exception {
var ir = parse("import Foo as");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 13, 13);
assertSingleSyntaxError(ir, invalidImport("Expected tokens."), null, 13, 13);
}

@Test
public void malformedImport6() throws Exception {
var ir = parse("import Foo as Bar.Baz");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 14, 21);
assertSingleSyntaxError(ir, invalidImport("Expected identifier."), null, 14, 21);
}

@Test
public void malformedImport7() throws Exception {
var ir = parse("import Foo hiding");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 7, 17);
assertSingleSyntaxError(ir, invalidImport("Expected qualified name."), null, 7, 17);
}

@Test
public void malformedImport8() throws Exception {
var ir = parse("import Foo hiding X,");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 7, 20);
assertSingleSyntaxError(ir, invalidImport("Malformed comma-delimited sequence."), null, 7, 20);
}

@Test
Expand All @@ -203,25 +214,25 @@ public void malformedTypeException() throws Exception {
@Test
public void malformedImport11() throws Exception {
var ir = parse("from import all");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 4, 4);
assertSingleSyntaxError(ir, invalidImport("Expected tokens."), null, 4, 4);
}

@Test
public void malformedImport12() throws Exception {
var ir = parse("from Foo import all hiding");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 26, 26);
assertSingleSyntaxError(ir, invalidImport("Expected tokens."), null, 26, 26);
}

@Test
public void malformedImport13() throws Exception {
var ir = parse("from Foo import all hiding X.Y");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 27, 30);
assertSingleSyntaxError(ir, invalidImport("Expected identifier."), null, 27, 30);
}

@Test
public void malformedImport14() throws Exception {
var ir = parse("from Foo import Some.Nested.Module.Path");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 16, 39);
assertSingleSyntaxError(ir, invalidImport("Expected identifier."), null, 16, 39);
}

@Test
Expand All @@ -239,55 +250,55 @@ public void malformedExport2() throws Exception {
@Test
public void malformedExport3() throws Exception {
var ir = parse("export Foo as Foo, Bar");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 14, 22);
assertSingleSyntaxError(ir, invalidExport("Expected identifier."), null, 14, 22);
}

@Test
public void malformedExport4() throws Exception {
var ir = parse("export Foo as Foo.Bar");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 14, 21);
assertSingleSyntaxError(ir, invalidExport("Expected identifier."), null, 14, 21);
}

@Test
public void malformedExport5() throws Exception {
var ir = parse("export Foo as");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 13, 13);
assertSingleSyntaxError(ir, invalidExport("Expected tokens."), null, 13, 13);
}

@Test
public void malformedExport6() throws Exception {
var ir = parse("export Foo as Bar.Baz");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 14, 21);
assertSingleSyntaxError(ir, invalidExport("Expected identifier."), null, 14, 21);
}

@Test
public void malformedExport7() throws Exception {
var ir = parse("export Foo hiding");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 7, 17);
assertSingleSyntaxError(ir, invalidExport("Expected qualified name."), null, 7, 17);
}

@Test
public void malformedExport8() throws Exception {
var ir = parse("export Foo hiding X,");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 7, 20);
assertSingleSyntaxError(ir, invalidExport("Malformed comma-delimited sequence."), null, 7, 20);
}

@Test
public void malformedExport9() throws Exception {
var ir = parse("from export all");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 4, 4);
assertSingleSyntaxError(ir, invalidExport("Expected tokens."), null, 4, 4);
}

@Test
public void malformedExport10() throws Exception {
var ir = parse("from Foo export all hiding");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 26, 26);
assertSingleSyntaxError(ir, invalidExport("Expected tokens."), null, 26, 26);
}

@Test
public void malformedExport11() throws Exception {
var ir = parse("from Foo export all hiding X.Y");
assertSingleSyntaxError(ir, IR$Error$Syntax$InvalidImport$.MODULE$, "Imports must have a valid module path", 27, 30);
assertSingleSyntaxError(ir, invalidExport("Expected identifier."), null, 27, 30);
}

@Test
Expand Down Expand Up @@ -367,7 +378,9 @@ private void assertSingleSyntaxError(
) {
var errors = assertIR(ir, IR$Error$Syntax.class, 1);
assertEquals(type, errors.head().reason());
assertEquals(msg, errors.head().message());
if (msg != null) {
assertEquals(msg, errors.head().message());
}
assertEquals(new Location(start, end), errors.head().location().get().location());
}

Expand Down