From 80c0bb53a42ef36ff5f5f52643cd4fc78e3447ea Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Mon, 4 Oct 2021 11:59:16 -0500 Subject: [PATCH] Fix for #1304: identify reserved word `yield` within `switch` expression --- .../test/ui/SemanticHighlightingTests.groovy | 77 +++++++++++++++++++ ...emanticHighlightingReferenceRequestor.java | 6 +- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/ui/SemanticHighlightingTests.groovy b/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/ui/SemanticHighlightingTests.groovy index f517c884d2..b3209d8f34 100644 --- a/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/ui/SemanticHighlightingTests.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/ui/SemanticHighlightingTests.groovy @@ -3800,6 +3800,83 @@ final class SemanticHighlightingTests extends GroovyEclipseTestSuite { new HighlightedTypedPosition(contents.indexOf('String'), 6, CLASS)) } + @Test + void testSwitch1() { + assumeTrue(isParrotParser() && isAtLeastGroovy(40)) + + String contents = '''\ + |int yield = switch (x) { + | case 'Foo': + | yield 1 + | case 'Bar': + | print 2 + | case 'Baz': + | yield 3 + | default: { + | yield 0 + | } + |} + |'''.stripMargin() + + assertHighlighting(contents, + new HighlightedTypedPosition(contents.indexOf('yield'), 5, VARIABLE), + new HighlightedTypedPosition(contents.indexOf('x'), 1, UNKNOWN), + new HighlightedTypedPosition(contents.indexOf('yield', 40), 5, RESERVED), + new HighlightedTypedPosition(contents.indexOf('1'), 1, NUMBER), + new HighlightedTypedPosition(contents.indexOf('print'), 5, METHOD_CALL), + new HighlightedTypedPosition(contents.indexOf('2'), 1, NUMBER), + new HighlightedTypedPosition(contents.indexOf('yield', 80), 5, RESERVED), + new HighlightedTypedPosition(contents.indexOf('3'), 1, NUMBER), + new HighlightedTypedPosition(contents.lastIndexOf('yield'), 5, RESERVED), + new HighlightedTypedPosition(contents.indexOf('0'), 1, NUMBER)) + } + + @Test + void testSwitch2() { + assumeTrue(isParrotParser() && isAtLeastGroovy(40)) + + String contents = '''\ + |import java.time.DayOfWeek + |import static java.time.DayOfWeek.* + | + |void test(DayOfWeek day) { + | int letterCount = switch (day) { + | case MONDAY, FRIDAY, SUNDAY -> 6 + | case TUESDAY -> { 7 } + | case THURSDAY, SATURDAY -> { yield 8 } + | case WEDNESDAY -> { if (true) yield 9; else 0 } + | default -> throw new IllegalStateException("Invalid day: $day") + | } + |} + |'''.stripMargin() + + assertHighlighting(contents, + new HighlightedTypedPosition(contents.indexOf('test'), 4, METHOD), + new HighlightedTypedPosition(contents.lastIndexOf('DayOfWeek'), 9, ENUMERATION), + new HighlightedTypedPosition(contents.indexOf('day'), 3, PARAMETER), + new HighlightedTypedPosition(contents.indexOf('letterCount'), 11, VARIABLE), + new HighlightedTypedPosition(contents.indexOf('(day') + 1, 3, PARAMETER), + new HighlightedTypedPosition(contents.indexOf('MONDAY'), 6, STATIC_VALUE), + new HighlightedTypedPosition(contents.indexOf('FRIDAY'), 6, STATIC_VALUE), + new HighlightedTypedPosition(contents.indexOf('SUNDAY'), 6, STATIC_VALUE), + new HighlightedTypedPosition(contents.indexOf('6'), 1, NUMBER), + new HighlightedTypedPosition(contents.indexOf('TUESDAY'), 7, STATIC_VALUE), + new HighlightedTypedPosition(contents.indexOf('7'), 1, NUMBER), + new HighlightedTypedPosition(contents.indexOf('THURSDAY'), 8, STATIC_VALUE), + new HighlightedTypedPosition(contents.indexOf('SATURDAY'), 8, STATIC_VALUE), + new HighlightedTypedPosition(contents.indexOf('yield'), 5, RESERVED), + new HighlightedTypedPosition(contents.indexOf('8'), 1, NUMBER), + new HighlightedTypedPosition(contents.indexOf('WEDNESDAY'), 9, STATIC_VALUE), + new HighlightedTypedPosition(contents.lastIndexOf('yield'), 5, RESERVED), + new HighlightedTypedPosition(contents.indexOf('9'), 1, NUMBER), + new HighlightedTypedPosition(contents.indexOf('0'), 1, NUMBER), + new HighlightedTypedPosition(contents.lastIndexOf('IllegalStateException'), 'IllegalStateException'.length(), CLASS), + new HighlightedTypedPosition(contents.lastIndexOf('IllegalStateException'), 'IllegalStateException'.length(), CTOR_CALL), + new HighlightedTypedPosition(contents.indexOf('"'), '"Invalid day: $day"'.length(), GSTRING), + new HighlightedTypedPosition(contents.indexOf('"') + 1, 'Invalid day: '.length(), STRING), + new HighlightedTypedPosition(contents.lastIndexOf('day'), 3, PARAMETER)) + } + @Test void testTraits1() { String contents = '''\ diff --git a/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/editor/highlighting/SemanticHighlightingReferenceRequestor.java b/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/editor/highlighting/SemanticHighlightingReferenceRequestor.java index 7fb1a69b53..423a1dcb33 100644 --- a/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/editor/highlighting/SemanticHighlightingReferenceRequestor.java +++ b/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/editor/highlighting/SemanticHighlightingReferenceRequestor.java @@ -46,6 +46,7 @@ import org.codehaus.groovy.ast.expr.MethodPointerExpression; import org.codehaus.groovy.ast.expr.StaticMethodCallExpression; import org.codehaus.groovy.ast.expr.VariableExpression; +import org.codehaus.groovy.ast.stmt.ReturnStatement; import org.codehaus.groovy.eclipse.editor.highlighting.HighlightedTypedPosition.HighlightKind; import org.codehaus.groovy.transform.trait.Traits; import org.codehaus.jdt.groovy.model.GroovyCompilationUnit; @@ -103,7 +104,7 @@ private int unitLength() { @Override public VisitStatus acceptASTNode(ASTNode node, TypeLookupResult result, IJavaElement enclosingElement) { // ignore statements or nodes with invalid source locations - if (!(node instanceof AnnotatedNode) || node instanceof ImportNode || endOffset(node, result) < 1) { + if (!(node instanceof AnnotatedNode || node instanceof ReturnStatement) || node instanceof ImportNode || endOffset(node, result) < 1) { if (DEBUG) System.err.println("skipping: " + node); return VisitStatus.CONTINUE; } @@ -220,6 +221,9 @@ public VisitStatus acceptASTNode(ASTNode node, TypeLookupResult result, IJavaEle if (var != null) { pos = new HighlightedTypedPosition(var.getStart(), var.getLength(), HighlightKind.RESERVED); } + } else if (node instanceof ReturnStatement && node.getNodeMetaData("_IS_YIELD_STATEMENT") != null) { + pos = new HighlightedTypedPosition(new Position(node.getStart(), 5), HighlightKind.RESERVED); + } else if (DEBUG) { String type = node.getClass().getSimpleName(); if (!type.matches("(Class|Binary|ArgumentList|Closure(List)?|Property|List|Map)Expression"))