diff --git a/src/main/java/software/amazon/smithy/lsp/language/HoverHandler.java b/src/main/java/software/amazon/smithy/lsp/language/HoverHandler.java index b7d72b1..79ba707 100644 --- a/src/main/java/software/amazon/smithy/lsp/language/HoverHandler.java +++ b/src/main/java/software/amazon/smithy/lsp/language/HoverHandler.java @@ -247,5 +247,4 @@ private static String serializeShape(Model model, Shape shape) { System.lineSeparator() + System.lineSeparator()), System.lineSeparator()); return serializedShape; } - } diff --git a/src/main/java/software/amazon/smithy/lsp/language/IdlPosition.java b/src/main/java/software/amazon/smithy/lsp/language/IdlPosition.java index 40f3600..a13a469 100644 --- a/src/main/java/software/amazon/smithy/lsp/language/IdlPosition.java +++ b/src/main/java/software/amazon/smithy/lsp/language/IdlPosition.java @@ -12,7 +12,11 @@ * Represents different kinds of positions within an IDL file. */ sealed interface IdlPosition { - default boolean isEasyShapeReference() { + /** + * @return Whether the token at this position is definitely a reference + * to a root/top-level shape. + */ + default boolean isRootShapeReference() { return switch (this) { case TraitId ignored -> true; case MemberTarget ignored -> true; @@ -25,6 +29,9 @@ default boolean isEasyShapeReference() { }; } + /** + * @return The view this position is within. + */ StatementView view(); record TraitId(StatementView view) implements IdlPosition {} @@ -53,7 +60,7 @@ record MetadataValue(StatementView view, Syntax.Statement.Metadata metadata) imp record StatementKeyword(StatementView view) implements IdlPosition {} - record MemberName(StatementView view) implements IdlPosition {} + record MemberName(StatementView view, String name) implements IdlPosition {} record ElidedMember(StatementView view) implements IdlPosition {} @@ -92,7 +99,7 @@ static IdlPosition of(StatementView view) { when m.inTarget(documentIndex) -> new IdlPosition.MemberTarget(view); case Syntax.Statement.MemberDef m - when m.name().isIn(documentIndex) -> new IdlPosition.MemberName(view); + when m.name().isIn(documentIndex) -> new IdlPosition.MemberName(view, m.name().stringValue()); case Syntax.Statement.NodeMemberDef m when m.inValue(documentIndex) -> new IdlPosition.NodeMemberTarget(view, m); @@ -109,9 +116,9 @@ static IdlPosition of(StatementView view) { case Syntax.Statement.ShapeDef ignored -> new IdlPosition.ShapeDef(view); - case Syntax.Statement.NodeMemberDef ignored -> new IdlPosition.MemberName(view); + case Syntax.Statement.NodeMemberDef m -> new IdlPosition.MemberName(view, m.name().stringValue()); - case Syntax.Statement.Block ignored -> new IdlPosition.MemberName(view); + case Syntax.Statement.Block ignored -> new IdlPosition.MemberName(view, ""); case Syntax.Statement.ForResource ignored -> new IdlPosition.ForResource(view); diff --git a/src/main/java/software/amazon/smithy/lsp/language/ShapeSearch.java b/src/main/java/software/amazon/smithy/lsp/language/ShapeSearch.java index 5eb1c77..d86e9be 100644 --- a/src/main/java/software/amazon/smithy/lsp/language/ShapeSearch.java +++ b/src/main/java/software/amazon/smithy/lsp/language/ShapeSearch.java @@ -78,7 +78,7 @@ private static Optional tryFrom(String id) { private static Optional tryFromParts(String namespace, String name) { try { - return Optional.of(ShapeId.fromParts(namespace, name)); + return Optional.of(ShapeId.fromRelative(namespace, name)); } catch (ShapeIdSyntaxException ignored) { return Optional.empty(); } @@ -118,7 +118,16 @@ static Optional findShapeDefinition(IdlPosition idlPosition, Do case IdlPosition.ElidedMember elidedMember -> findElidedMemberParent(elidedMember, id, model); - case IdlPosition pos when pos.isEasyShapeReference() -> + case IdlPosition.MemberName memberName -> { + var parentDef = memberName.view().nearestShapeDefBefore(); + if (parentDef == null) { + yield Optional.empty(); + } + var relativeId = parentDef.shapeName().stringValue() + "$" + memberName.name(); + yield findShape(memberName.view().parseResult(), relativeId, model); + } + + case IdlPosition pos when pos.isRootShapeReference() -> findShape(pos.view().parseResult(), id.copyIdValue(), model); default -> Optional.empty(); diff --git a/src/test/java/software/amazon/smithy/lsp/language/HoverHandlerTest.java b/src/test/java/software/amazon/smithy/lsp/language/HoverHandlerTest.java index 1bdfdc4..5f37e89 100644 --- a/src/test/java/software/amazon/smithy/lsp/language/HoverHandlerTest.java +++ b/src/test/java/software/amazon/smithy/lsp/language/HoverHandlerTest.java @@ -122,6 +122,32 @@ public void absoluteShapeId() { assertThat(hovers, contains(containsString("string String"))); } + @Test + public void selfShapeDefinition() { + TextWithPositions text = TextWithPositions.from(""" + $version: "2" + namespace com.foo + structure %Foo {} + """); + List hovers = getHovers(text); + + assertThat(hovers, contains(containsString("structure Foo"))); + } + + @Test + public void selfMemberDefinition() { + TextWithPositions text = TextWithPositions.from(""" + $version: "2" + namespace com.foo + structure Foo { + %bar: String + } + """); + List hovers = getHovers(text); + + assertThat(hovers, contains(containsString("bar: String"))); + } + private static List getHovers(TextWithPositions text) { return getHovers(text.text(), text.positions()); }