literals) implements CompletionCandidates {}
/**
* Multiple label -> value pairs, where the label is displayed to the user,
* and may be used for matching, and the value is the literal text to complete.
*
+ * For example, completing enum value in a trait may display and match on the
+ * name, like FOO, but complete the actual value, like "foo".
+ *
* @param labeled The labeled completion values.
*/
- record Labeled(Map labeled) implements Candidates {}
+ record Labeled(Map labeled) implements CompletionCandidates {}
/**
* Multiple name -> constant pairs, where the name corresponds to a member
* name, and the constant is a default/empty value for that member.
*
+ * For example, shape members can be completed as {@code name: constant}.
+ *
* @param members The members completion values.
*/
- record Members(Map members) implements Candidates {}
+ record Members(Map members) implements CompletionCandidates {}
/**
* Multiple member names to complete as elided members.
+ *
* @apiNote These are distinct from {@link Literals} because they may have
* custom filtering/mapping, and may appear _with_ {@link Literals} in an
* {@link And}.
*
* @param memberNames The member names completion values.
*/
- record ElidedMembers(Collection memberNames) implements Candidates {}
+ record ElidedMembers(Collection memberNames) implements CompletionCandidates {}
/**
* A combination of two sets of completion candidates, of possibly different
@@ -218,13 +236,13 @@ record ElidedMembers(Collection memberNames) implements Candidates {}
* @param one The first set of completion candidates.
* @param two The second set of completion candidates.
*/
- record And(Candidates one, Candidates two) implements Candidates {}
+ record And(CompletionCandidates one, CompletionCandidates two) implements CompletionCandidates {}
/**
* Shape completion candidates, each corresponding to a different set of
* shapes that will be selected from the model.
*/
- enum Shapes implements Candidates {
+ enum Shapes implements CompletionCandidates {
ANY_SHAPE,
USE_TARGET,
TRAITS,
@@ -239,7 +257,7 @@ enum Shapes implements Candidates {
/**
* Candidates that require a custom computation to generate, lazily.
*/
- enum Custom implements Candidates {
+ enum Custom implements CompletionCandidates {
NAMESPACE_FILTER,
VALIDATOR_NAME,
PROJECT_NAMESPACES,
diff --git a/src/main/java/software/amazon/smithy/lsp/language/CompletionHandler.java b/src/main/java/software/amazon/smithy/lsp/language/CompletionHandler.java
index 182e1f10..f43d1bc6 100644
--- a/src/main/java/software/amazon/smithy/lsp/language/CompletionHandler.java
+++ b/src/main/java/software/amazon/smithy/lsp/language/CompletionHandler.java
@@ -72,22 +72,22 @@ public List handle(CompletionParams params, CancelChecker cc) {
case IdlPosition.ControlKey ignored -> builder
.literalKind(CompletionItemKind.Constant)
.buildSimpleCompletions()
- .getCompletionItems(Candidates.BUILTIN_CONTROLS);
+ .getCompletionItems(CompletionCandidates.BUILTIN_CONTROLS);
case IdlPosition.MetadataKey ignored -> builder
.literalKind(CompletionItemKind.Field)
.buildSimpleCompletions()
- .getCompletionItems(Candidates.BUILTIN_METADATA);
+ .getCompletionItems(CompletionCandidates.BUILTIN_METADATA);
case IdlPosition.StatementKeyword ignored -> builder
.literalKind(CompletionItemKind.Keyword)
.buildSimpleCompletions()
- .getCompletionItems(Candidates.KEYWORD);
+ .getCompletionItems(CompletionCandidates.KEYWORD);
case IdlPosition.Namespace ignored -> builder
.literalKind(CompletionItemKind.Module)
.buildSimpleCompletions()
- .getCompletionItems(Candidates.Custom.PROJECT_NAMESPACES);
+ .getCompletionItems(CompletionCandidates.Custom.PROJECT_NAMESPACES);
case IdlPosition.MetadataValue metadataValue -> metadataValueCompletions(metadataValue, builder);
@@ -129,7 +129,7 @@ private List metadataValueCompletions(
) {
var result = ShapeSearch.searchMetadataValue(metadataValue);
Set excludeKeys = getOtherPresentKeys(result);
- Candidates candidates = Candidates.fromSearchResult(result);
+ CompletionCandidates candidates = CompletionCandidates.fromSearchResult(result);
return builder.exclude(excludeKeys).buildSimpleCompletions().getCompletionItems(candidates);
}
@@ -176,10 +176,10 @@ private List modelBasedCompletions(IdlPosition idlPosition, Simp
return traitValueCompletions(traitValue, model, builder);
}
- Candidates candidates = shapeCandidates(idlPosition);
- if (candidates instanceof Candidates.Shapes shapes) {
+ CompletionCandidates candidates = CompletionCandidates.shapeCandidates(idlPosition);
+ if (candidates instanceof CompletionCandidates.Shapes shapes) {
return builder.buildShapeCompletions(idlPosition, model).getCompletionItems(shapes);
- } else if (candidates != Candidates.NONE) {
+ } else if (candidates != CompletionCandidates.NONE) {
return builder.buildSimpleCompletions().getCompletionItems(candidates);
}
@@ -191,7 +191,7 @@ private List elidedMemberCompletions(
Model model,
SimpleCompletions.Builder builder
) {
- Candidates candidates = getElidableMemberCandidates(elidedMember.statementIndex(), model);
+ CompletionCandidates candidates = getElidableMemberCandidates(elidedMember.statementIndex(), model);
if (candidates == null) {
return List.of();
}
@@ -210,24 +210,10 @@ private List traitValueCompletions(
) {
var result = ShapeSearch.searchTraitValue(traitValue, model);
Set excludeKeys = getOtherPresentKeys(result);
- Candidates candidates = Candidates.fromSearchResult(result);
+ CompletionCandidates candidates = CompletionCandidates.fromSearchResult(result);
return builder.exclude(excludeKeys).buildSimpleCompletions().getCompletionItems(candidates);
}
- private Candidates shapeCandidates(IdlPosition idlPosition) {
- return switch (idlPosition) {
- case IdlPosition.UseTarget ignored -> Candidates.Shapes.USE_TARGET;
- case IdlPosition.TraitId ignored -> Candidates.Shapes.TRAITS;
- case IdlPosition.Mixin ignored -> Candidates.Shapes.MIXINS;
- case IdlPosition.ForResource ignored -> Candidates.Shapes.RESOURCE_SHAPES;
- case IdlPosition.MemberTarget ignored -> Candidates.Shapes.MEMBER_TARGETABLE;
- case IdlPosition.ApplyTarget ignored -> Candidates.Shapes.ANY_SHAPE;
- case IdlPosition.NodeMemberTarget nodeMemberTarget -> Candidates.fromSearchResult(
- ShapeSearch.searchNodeMemberTarget(nodeMemberTarget));
- default -> Candidates.NONE;
- };
- }
-
private List memberNameCompletions(
IdlPosition.MemberName memberName,
SimpleCompletions.Builder builder
@@ -243,20 +229,20 @@ private List memberNameCompletions(
String shapeType = shapeDef.shapeType().copyValueFrom(smithyFile.document());
StructureShape shapeMembersDef = Builtins.getMembersForShapeType(shapeType);
- Candidates candidates = null;
+ CompletionCandidates candidates = null;
if (shapeMembersDef != null) {
- candidates = Candidates.membersCandidates(Builtins.MODEL, shapeMembersDef);
+ candidates = CompletionCandidates.membersCandidates(Builtins.MODEL, shapeMembersDef);
}
if (project.modelResult().getResult().isPresent()) {
- Candidates elidedCandidates = getElidableMemberCandidates(
+ CompletionCandidates elidedCandidates = getElidableMemberCandidates(
memberName.statementIndex(),
project.modelResult().getResult().get());
if (elidedCandidates != null) {
candidates = candidates == null
? elidedCandidates
- : new Candidates.And(candidates, elidedCandidates);
+ : new CompletionCandidates.And(candidates, elidedCandidates);
}
}
@@ -271,7 +257,7 @@ private List memberNameCompletions(
return builder.exclude(otherMembers).buildSimpleCompletions().getCompletionItems(candidates);
}
- private Candidates getElidableMemberCandidates(int statementIndex, Model model) {
+ private CompletionCandidates getElidableMemberCandidates(int statementIndex, Model model) {
var resourceAndMixins = ShapeSearch.findForResourceAndMixins(
SyntaxSearch.closestForResourceAndMixinsBeforeMember(smithyFile.statements(), statementIndex),
smithyFile,
@@ -291,6 +277,6 @@ private Candidates getElidableMemberCandidates(int statementIndex, Model model)
return null;
}
- return new Candidates.ElidedMembers(memberNames);
+ return new CompletionCandidates.ElidedMembers(memberNames);
}
}
diff --git a/src/main/java/software/amazon/smithy/lsp/language/ShapeCompletions.java b/src/main/java/software/amazon/smithy/lsp/language/ShapeCompletions.java
index 42571928..0c4d8c74 100644
--- a/src/main/java/software/amazon/smithy/lsp/language/ShapeCompletions.java
+++ b/src/main/java/software/amazon/smithy/lsp/language/ShapeCompletions.java
@@ -30,7 +30,7 @@
import software.amazon.smithy.model.traits.TraitDefinition;
/**
- * Maps {@link Candidates.Shapes} to {@link CompletionItem}s.
+ * Maps {@link CompletionCandidates.Shapes} to {@link CompletionItem}s.
*/
final class ShapeCompletions {
private final Model model;
@@ -45,14 +45,14 @@ private ShapeCompletions(Model model, SmithyFile smithyFile, Matcher matcher, Ma
this.mapper = mapper;
}
- List getCompletionItems(Candidates.Shapes candidates) {
+ List getCompletionItems(CompletionCandidates.Shapes candidates) {
return streamShapes(candidates)
.filter(matcher::test)
.mapMulti(mapper::accept)
.toList();
}
- private Stream extends Shape> streamShapes(Candidates.Shapes candidates) {
+ private Stream extends Shape> streamShapes(CompletionCandidates.Shapes candidates) {
return switch (candidates) {
case ANY_SHAPE -> model.shapes();
case STRING_SHAPES -> model.getStringShapes().stream();
@@ -202,7 +202,7 @@ public void add(Mapper mapper, String shapeLabel, Shape shape, Consumer getCompletionItems(Candidates candidates) {
+ List getCompletionItems(CompletionCandidates candidates) {
return switch (candidates) {
- case Candidates.Constant(var value)
+ case CompletionCandidates.Constant(var value)
when !value.isEmpty() && matcher.testConstant(value) -> List.of(mapper.constant(value));
- case Candidates.Literals(var literals) -> literals.stream()
+ case CompletionCandidates.Literals(var literals) -> literals.stream()
.filter(matcher::testLiteral)
.map(mapper::literal)
.toList();
- case Candidates.Labeled(var labeled) -> labeled.entrySet().stream()
+ case CompletionCandidates.Labeled(var labeled) -> labeled.entrySet().stream()
.filter(matcher::testLabeled)
.map(mapper::labeled)
.toList();
- case Candidates.Members(var members) -> members.entrySet().stream()
+ case CompletionCandidates.Members(var members) -> members.entrySet().stream()
.filter(matcher::testMember)
.map(mapper::member)
.toList();
- case Candidates.ElidedMembers(var memberNames) -> memberNames.stream()
+ case CompletionCandidates.ElidedMembers(var memberNames) -> memberNames.stream()
.filter(matcher::testElided)
.map(mapper::elided)
.toList();
- case Candidates.Custom custom
+ case CompletionCandidates.Custom custom
// TODO: Need to get rid of this stupid null check
when project != null -> getCompletionItems(customCandidates(custom));
- case Candidates.And(var one, var two) -> {
+ case CompletionCandidates.And(var one, var two) -> {
List oneItems = getCompletionItems(one);
List twoItems = getCompletionItems(two);
List completionItems = new ArrayList<>(oneItems.size() + twoItems.size());
@@ -73,14 +73,14 @@ List getCompletionItems(Candidates candidates) {
};
}
- private Candidates customCandidates(Candidates.Custom custom) {
+ private CompletionCandidates customCandidates(CompletionCandidates.Custom custom) {
return switch (custom) {
- case NAMESPACE_FILTER -> new Candidates.Labeled(Stream.concat(Stream.of("*"), streamNamespaces())
+ case NAMESPACE_FILTER -> new CompletionCandidates.Labeled(Stream.concat(Stream.of("*"), streamNamespaces())
.collect(StreamUtils.toWrappedMap()));
- case VALIDATOR_NAME -> Candidates.VALIDATOR_NAMES;
+ case VALIDATOR_NAME -> CompletionCandidates.VALIDATOR_NAMES;
- case PROJECT_NAMESPACES -> new Candidates.Literals(streamNamespaces().toList());
+ case PROJECT_NAMESPACES -> new CompletionCandidates.Literals(streamNamespaces().toList());
};
}
@@ -162,7 +162,7 @@ default boolean testLabeled(Map.Entry labeled) {
return test(labeled.getKey()) || test(labeled.getValue());
}
- default boolean testMember(Map.Entry member) {
+ default boolean testMember(Map.Entry member) {
return test(member.getKey());
}
@@ -206,7 +206,7 @@ CompletionItem labeled(Map.Entry entry) {
return textEditCompletion(entry.getKey(), CompletionItemKind.EnumMember, entry.getValue());
}
- CompletionItem member(Map.Entry entry) {
+ CompletionItem member(Map.Entry entry) {
String value = entry.getKey() + ": " + entry.getValue().value();
return textEditCompletion(entry.getKey(), CompletionItemKind.Field, value);
}
diff --git a/src/main/java/software/amazon/smithy/lsp/project/ProjectLoader.java b/src/main/java/software/amazon/smithy/lsp/project/ProjectLoader.java
index dafbb7ba..6d18ff95 100644
--- a/src/main/java/software/amazon/smithy/lsp/project/ProjectLoader.java
+++ b/src/main/java/software/amazon/smithy/lsp/project/ProjectLoader.java
@@ -267,7 +267,6 @@ public static SmithyFile.Builder buildSmithyFile(String path, Document document,
.documentShapes(documentShapes)
.documentVersion(documentVersion)
.statements(statements);
- // .changeVersion(document.changeVersion());
}
// This is gross, but necessary to deal with the way that array metadata gets merged.
diff --git a/src/main/java/software/amazon/smithy/lsp/project/SmithyFile.java b/src/main/java/software/amazon/smithy/lsp/project/SmithyFile.java
index ba6d3680..5cc23442 100644
--- a/src/main/java/software/amazon/smithy/lsp/project/SmithyFile.java
+++ b/src/main/java/software/amazon/smithy/lsp/project/SmithyFile.java
@@ -40,7 +40,6 @@ public final class SmithyFile implements ProjectFile {
private final Map documentShapes;
private final DocumentVersion documentVersion;
private List statements;
- private int changeVersion;
private SmithyFile(Builder builder) {
this.path = builder.path;
@@ -51,7 +50,6 @@ private SmithyFile(Builder builder) {
this.documentShapes = builder.documentShapes;
this.documentVersion = builder.documentVersion;
this.statements = builder.statements;
- this.changeVersion = builder.changeVersion;
}
/**
@@ -155,14 +153,6 @@ public boolean isAccessible(Shape shape) {
|| !shape.hasTrait(PrivateTrait.ID);
}
- public int changeVersion() {
- return changeVersion;
- }
-
- public void setChangeVersion(int changeVersion) {
- this.changeVersion = changeVersion;
- }
-
/**
* @return The parsed statements in this file
*/
@@ -204,7 +194,6 @@ public static final class Builder {
private Map documentShapes;
private DocumentVersion documentVersion;
private List statements;
- private int changeVersion;
private Builder() {
}
@@ -249,11 +238,6 @@ public Builder statements(List statements) {
return this;
}
- public Builder changeVersion(int changeVersion) {
- this.changeVersion = changeVersion;
- return this;
- }
-
public SmithyFile build() {
return new SmithyFile(this);
}
diff --git a/src/main/java/software/amazon/smithy/lsp/util/StreamUtils.java b/src/main/java/software/amazon/smithy/lsp/util/StreamUtils.java
index 86b0d669..55187018 100644
--- a/src/main/java/software/amazon/smithy/lsp/util/StreamUtils.java
+++ b/src/main/java/software/amazon/smithy/lsp/util/StreamUtils.java
@@ -6,6 +6,7 @@
package software.amazon.smithy.lsp.util;
import java.util.Map;
+import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
@@ -13,11 +14,11 @@ public final class StreamUtils {
private StreamUtils() {
}
- public static Collector, ?, Map> toMap() {
- return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue);
- }
-
public static Collector> toWrappedMap() {
return Collectors.toMap(s -> s, s -> "\"" + s + "\"");
}
+
+ public static Collector, ?, Map> mappingValue(Function valueMapper) {
+ return Collectors.toMap(Map.Entry::getKey, entry -> valueMapper.apply(entry.getValue()));
+ }
}
diff --git a/src/test/java/software/amazon/smithy/lsp/language/CompletionHandlerTest.java b/src/test/java/software/amazon/smithy/lsp/language/CompletionHandlerTest.java
index a633888c..81007c00 100644
--- a/src/test/java/software/amazon/smithy/lsp/language/CompletionHandlerTest.java
+++ b/src/test/java/software/amazon/smithy/lsp/language/CompletionHandlerTest.java
@@ -274,7 +274,7 @@ public void completesStatementKeywords() {
app%""");
List comps = getCompLabels(text);
- String[] keywords = Candidates.KEYWORD.literals().toArray(new String[0]);
+ String[] keywords = CompletionCandidates.KEYWORD.literals().toArray(new String[0]);
assertThat(comps, containsInAnyOrder(keywords));
}