diff --git a/src/main/java/net/prominic/groovyls/providers/DefinitionProvider.java b/src/main/java/net/prominic/groovyls/providers/DefinitionProvider.java index df0e0cfd..502089d2 100644 --- a/src/main/java/net/prominic/groovyls/providers/DefinitionProvider.java +++ b/src/main/java/net/prominic/groovyls/providers/DefinitionProvider.java @@ -25,9 +25,12 @@ import java.util.concurrent.CompletableFuture; import org.codehaus.groovy.ast.ASTNode; +import org.codehaus.groovy.ast.ClassNode; +import org.codehaus.groovy.ast.ConstructorNode; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.LocationLink; import org.eclipse.lsp4j.Position; +import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.eclipse.lsp4j.jsonrpc.messages.Either; @@ -56,7 +59,7 @@ public CompletableFuture, List, List> provideReferences(TextDocumen List references = GroovyASTUtils.getReferences(offsetNode, ast); List locations = references.stream().map(node -> { URI uri = ast.getURI(node); + if (uri == null) + return null; return GroovyLanguageServerUtils.astNodeToLocation(node, uri); }).filter(location -> location != null).collect(Collectors.toList()); diff --git a/src/test/java/net/prominic/groovyls/GroovyServicesDefinitionTests.java b/src/test/java/net/prominic/groovyls/GroovyServicesDefinitionTests.java index 93ce8f1a..83d53255 100644 --- a/src/test/java/net/prominic/groovyls/GroovyServicesDefinitionTests.java +++ b/src/test/java/net/prominic/groovyls/GroovyServicesDefinitionTests.java @@ -438,6 +438,50 @@ void testClassDefinitionFromImport() throws Exception { Assertions.assertEquals(1, location.getRange().getEnd().getCharacter()); } + @Test + void testImplicitClassDefinitionFromConstructorCall() throws Exception { + Path filePath = srcRoot.resolve("Definitions.groovy"); + String uri = filePath.toUri().toString(); + TextDocumentItem textDocumentItem = new TextDocumentItem(uri, LANGUAGE_GROOVY, 1, "new Definitions()"); + services.didOpen(new DidOpenTextDocumentParams(textDocumentItem)); + TextDocumentIdentifier textDocument = new TextDocumentIdentifier(uri); + Position position = new Position(0, 10); + List locations = services.definition(new DefinitionParams(textDocument, position)).get() + .getLeft(); + Assertions.assertEquals(1, locations.size()); + Location location = locations.get(0); + Assertions.assertEquals(uri, location.getUri()); + Assertions.assertEquals(0, location.getRange().getStart().getLine()); + Assertions.assertEquals(0, location.getRange().getStart().getCharacter()); + Assertions.assertEquals(1, location.getRange().getEnd().getLine()); + Assertions.assertEquals(1, location.getRange().getEnd().getCharacter()); + } + + @Test + void testImplicitClassDefinitionFromImport() throws Exception { + Path filePath = srcRoot.resolve("Definitions.groovy"); + String uri = filePath.toUri().toString(); + TextDocumentItem textDocumentItem = new TextDocumentItem(uri, LANGUAGE_GROOVY, 1, ""); + services.didOpen(new DidOpenTextDocumentParams(textDocumentItem)); + + Path filePath2 = srcRoot.resolve("Definitions2.groovy"); + String uri2 = filePath2.toUri().toString(); + TextDocumentItem textDocumentItem2 = new TextDocumentItem(uri2, LANGUAGE_GROOVY, 1, "import Definitions"); + services.didOpen(new DidOpenTextDocumentParams(textDocumentItem2)); + + TextDocumentIdentifier textDocument = new TextDocumentIdentifier(uri2); + Position position = new Position(0, 10); + List locations = services.definition(new DefinitionParams(textDocument, position)).get() + .getLeft(); + Assertions.assertEquals(1, locations.size()); + Location location = locations.get(0); + Assertions.assertEquals(uri, location.getUri()); + Assertions.assertEquals(0, location.getRange().getStart().getLine()); + Assertions.assertEquals(0, location.getRange().getStart().getCharacter()); + Assertions.assertEquals(1, location.getRange().getEnd().getLine()); + Assertions.assertEquals(1, location.getRange().getEnd().getCharacter()); + } + // --- parameters @Test