Skip to content

Commit

Permalink
Allow empty body blocks with comments (#10969)
Browse files Browse the repository at this point in the history
close #10849

Changelog:
- update: empty body blocks return an `Empty` node resulting in `Nothing`

(cherry picked from commit bc3ab2c)
  • Loading branch information
4e6 authored and jdunkerley committed Sep 9, 2024
1 parent e81e98f commit f314635
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.junit.Assert.assertTrue;

import org.enso.compiler.core.ir.Empty;
import org.enso.compiler.core.ir.Expression;
import org.enso.compiler.core.ir.Location;
import org.enso.compiler.core.ir.Module;
import org.enso.compiler.core.ir.expression.errors.Syntax;
Expand Down Expand Up @@ -580,6 +581,19 @@ public void testEmptyBody() throws Exception {
assertTrue(method.body() instanceof Empty);
}

@Test
public void testBodyWithComment() throws Exception {
var ir = parse("""
main =
# comment
""");

var method = (Method) ir.bindings().apply(0);
var body = (Expression.Block) method.body();
assertTrue(body.expressions().isEmpty());
assertTrue(body.returnValue() instanceof Empty);
}

@Test
public void exportAllIsNotAllowed() {
var ir = parse("""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7463,6 +7463,54 @@ class RuntimeServerTest
)
}

it should "run methods with empty body ending with comment" in {
val contextId = UUID.randomUUID()
val requestId = UUID.randomUUID()
val moduleName = "Enso_Test.Test.Main"
val code =
"""foo =
| # TODO
|
|main =
| foo
|""".stripMargin.linesIterator.mkString("\n")

val mainFile = context.writeMain(code)

// create context
context.send(Api.Request(requestId, Api.CreateContextRequest(contextId)))
context.receive shouldEqual Some(
Api.Response(requestId, Api.CreateContextResponse(contextId))
)

// Set sources for the module
context.send(
Api.Request(requestId, Api.OpenFileRequest(mainFile, code))
)
context.receive shouldEqual Some(
Api.Response(Some(requestId), Api.OpenFileResponse)
)

// push main
context.send(
Api.Request(
requestId,
Api.PushContextRequest(
contextId,
Api.StackItem.ExplicitCall(
Api.MethodPointer(moduleName, moduleName, "main"),
None,
Vector()
)
)
)
)
context.receiveNIgnoreStdLib(2) should contain theSameElementsAs Seq(
Api.Response(requestId, Api.PushContextResponse(contextId)),
context.executionComplete(contextId)
)
}

it should "support file edit notification with IdMap" in {
val contextId = UUID.randomUUID()
val requestId = UUID.randomUUID()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1019,20 +1019,21 @@ yield translateSyntaxError(l.getExpression().getExpression(),
}
last = translateExpression(expr, false);
}
// If the block ended in a documentation node without an expression, last may be null;
// the return value of the block is a doc comment.
// (This is to match the behavior of AstToIr; after the parser transition, we should probably
// ignore the orphaned documentation and return the last actual expression in the block.)
if (last == null && expressions.size() > 0) {
last = expressions.get(expressions.size() - 1);
expressions.remove(expressions.size() - 1);
var locationWithANewLine = getIdentifiedLocation(body, 0, 0, null);
if (last == null) {
if (expressions.isEmpty()) {
last = new Empty(locationWithANewLine, meta());
} else {
last = expressions.get(expressions.size() - 1);
expressions.remove(expressions.size() - 1);
}
}
var list = CollectionConverters.asScala(expressions.iterator()).toList();
var locationWithANewLine = getIdentifiedLocation(body, 0, 0, null);
if (last != null && last.location().isDefined()
if (last != null
&& last.location().isDefined()
&& last.location().get().end() != locationWithANewLine.get().end()) {
var patched = new Location(last.location().get().start(),
locationWithANewLine.get().end() - 1);
var patched =
new Location(last.location().get().start(), locationWithANewLine.get().end() - 1);
var id = IdentifiedLocation.create(patched, last.location().get().id());
last = last.setLocation(Option.apply(id));
}
Expand Down

0 comments on commit f314635

Please sign in to comment.