From 7d6f65ce1b50ed253a1bc6b323928888ed1acd2d Mon Sep 17 00:00:00 2001 From: Frotty Date: Mon, 8 Dec 2025 11:52:03 +0100 Subject: [PATCH] add suggestion for constant array length --- .../requests/GetCompletions.java | 24 ++++++++++++ .../wurstscript/tests/AutoCompleteTests.java | 39 ++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/requests/GetCompletions.java b/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/requests/GetCompletions.java index 4c9153829..3403956fa 100644 --- a/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/requests/GetCompletions.java +++ b/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/requests/GetCompletions.java @@ -145,6 +145,8 @@ private void calculateCompletions(List completions) { WurstType leftType = e.getLeft().attrTyp(); + addArrayLengthCompletion(completions, e, leftType); + if (leftType instanceof WurstTypeNamedScope) { WurstTypeNamedScope ct = (WurstTypeNamedScope) leftType; for (DefLink nameLink : ct.nameLinks().values()) { @@ -229,6 +231,28 @@ private void calculateCompletions(List completions) { } + private void addArrayLengthCompletion(List completions, ExprMember member, WurstType leftType) { + boolean hasConstArrayInitializer = false; + if (member.getLeft() instanceof NameRef) { + NameDef nameDef = ((NameRef) member.getLeft()).tryGetNameDef(); + if (nameDef instanceof GlobalOrLocalVarDef) { + GlobalOrLocalVarDef varDef = (GlobalOrLocalVarDef) nameDef; + hasConstArrayInitializer = varDef.getInitialExpr() instanceof ArrayInitializer; + } + } + + if (!hasConstArrayInitializer || !isSuitableCompletion("length")) { + return; + } + + CompletionItem completion = new CompletionItem("length"); + completion.setKind(CompletionItemKind.Property); + completion.setDetail("int length"); + completion.setInsertText("length"); + completion.setSortText(ratingToString(calculateRating("length", WurstTypeInt.instance()))); + completions.add(completion); + } + private void addKeywordCompletions(List completions) { for (String keyword : WurstKeywords.KEYWORDS) { if (keyword.startsWith(alreadyEntered)) { diff --git a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/AutoCompleteTests.java b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/AutoCompleteTests.java index 13f2dd93f..41eb58c7c 100644 --- a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/AutoCompleteTests.java +++ b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/AutoCompleteTests.java @@ -14,8 +14,7 @@ import java.util.List; import java.util.stream.Collectors; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; +import static org.testng.Assert.*; /** * tests the autocomplete functionality. @@ -416,6 +415,42 @@ public void testInnerClasses() { testCompletions(testData, "Banana", "Blue", "Boris"); } + @Test + public void constantArrayLengthCompletion() { + CompletionTestData testData = input( + "package test", + "const ints = [1, 2, 3]", + "init", + " ints.|", + "endpackage" + ); + + CompletionList completions = calculateCompletions(testData); + + assertTrue( + completions.getItems().stream().anyMatch(c -> "length".equals(c.getLabel())), + "Expected to suggest the synthetic array length property" + ); + } + + @Test + public void nonConstantArrayDoesNotSuggestLength() { + CompletionTestData testData = input( + "package test", + "int array ints", + "init", + " ints.|", + "endpackage" + ); + + CompletionList completions = calculateCompletions(testData); + + assertFalse( + completions.getItems().stream().anyMatch(c -> "length".equals(c.getLabel())), + "Did not expect to suggest length for non-constant arrays" + ); + } + private void testCompletions(CompletionTestData testData, String... expectedCompletions) { testCompletions(testData, Arrays.asList(expectedCompletions)); }