From eaedb1b88fedfa9e104978e425eac40d1523fc23 Mon Sep 17 00:00:00 2001 From: bigguy345 Date: Thu, 5 Mar 2026 20:25:38 +0200 Subject: [PATCH] Added array.length and array.clone() to TypeInfo arrays --- .../autocomplete/JSAutocompleteProvider.java | 8 ++++++ .../JavaAutocompleteProvider.java | 6 +++++ .../script/interpreter/type/TypeInfo.java | 25 +++++++++++++------ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/JSAutocompleteProvider.java b/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/JSAutocompleteProvider.java index 1348cf19f..c87e8dd5c 100644 --- a/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/JSAutocompleteProvider.java +++ b/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/JSAutocompleteProvider.java @@ -2,6 +2,7 @@ package noppes.npcs.client.gui.util.script.autocomplete; import noppes.npcs.client.gui.util.script.interpreter.js_parser.*; import noppes.npcs.client.gui.util.script.interpreter.field.FieldInfo; +import noppes.npcs.client.gui.util.script.interpreter.method.MethodInfo; import noppes.npcs.client.gui.util.script.interpreter.type.synthetic.*; import noppes.npcs.client.gui.util.script.interpreter.type.TypeChecker; import noppes.npcs.client.gui.util.script.interpreter.type.TypeInfo; @@ -61,6 +62,13 @@ public class JSAutocompleteProvider extends JavaAutocompleteProvider { super.addMemberSuggestions(context, items); return; } + + // Add synthetic members (e.g., array built-ins: length, clone) + for (FieldInfo field : receiverType.syntheticFields) + if (!context.methodsOnly) + items.add(AutocompleteItem.fromField(field)); + for (MethodInfo method : receiverType.syntheticMethods) + items.add(AutocompleteItem.fromMethod(method, context.methodsOnly)); // For pure JS types, check JSTypeRegistry JSTypeInfo jsTypeInfo = receiverType.getJSTypeInfo(); diff --git a/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/JavaAutocompleteProvider.java b/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/JavaAutocompleteProvider.java index 3c582929e..49fcd0d36 100644 --- a/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/JavaAutocompleteProvider.java +++ b/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/JavaAutocompleteProvider.java @@ -136,6 +136,9 @@ public class JavaAutocompleteProvider implements AutocompleteProvider { } } } + + for (MethodInfo method : receiverType.syntheticMethods) + items.add(AutocompleteItem.fromMethod(method, context.methodsOnly)); // Add fields (skip if methodsOnly is true - but the filtering will be done in getSuggestions) if (!context.methodsOnly) { @@ -150,6 +153,9 @@ public class JavaAutocompleteProvider implements AutocompleteProvider { items.add(AutocompleteItem.fromField(fieldInfo)); } } + + for (FieldInfo field : receiverType.syntheticFields) + items.add(AutocompleteItem.fromField(field)); } // Add nested types (inner classes/interfaces) in static context diff --git a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/type/TypeInfo.java b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/type/TypeInfo.java index b23e4b664..790b1f35b 100644 --- a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/type/TypeInfo.java +++ b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/type/TypeInfo.java @@ -10,13 +10,9 @@ import noppes.npcs.client.gui.util.script.interpreter.jsdoc.JSDocInfo; import noppes.npcs.client.gui.util.script.interpreter.method.MethodInfo; import noppes.npcs.client.gui.util.script.interpreter.token.TokenType; -import java.lang.reflect.Constructor; -import java.lang.reflect.GenericArrayType; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.lang.reflect.WildcardType; +import java.lang.reflect.*; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -85,6 +81,10 @@ public class TypeInfo { // Null for non-array types private final TypeInfo elementType; + // Synthetic members injected at construction time (e.g. array built-ins: length, clone) + public final List syntheticFields = new ArrayList<>(); + public final List syntheticMethods = new ArrayList<>(); + // Documentation (script-defined types) private JSDocInfo jsDocInfo; @@ -343,7 +343,12 @@ public class TypeInfo { } } - return new TypeInfo(simpleName, fullName, pkg, elementType.kind, arrayClass, true, null, null, null, null, elementType); + TypeInfo arr = new TypeInfo(simpleName, fullName, pkg, elementType.kind, arrayClass, true, null, null, null, null, elementType); + arr.syntheticFields.add(FieldInfo.external("length", TypeInfo.fromPrimitive("int"), null, + Modifier.PUBLIC | Modifier.FINAL)); + arr.syntheticMethods.add(MethodInfo.external("clone", arr, null, + Collections.emptyList(), Modifier.PUBLIC, null)); + return arr; } /** @@ -540,6 +545,7 @@ public class TypeInfo { * Check if this type has a method with the given name. */ public boolean hasMethod(String methodName) { + for (MethodInfo m : syntheticMethods) if (m.getName().equals(methodName)) return true; // Check JS type first if (jsTypeInfo != null) { return jsTypeInfo.hasMethod(methodName); @@ -562,6 +568,7 @@ public class TypeInfo { * Check if this type has a method with the given name and parameter count. */ public boolean hasMethod(String methodName, int paramCount) { + for (MethodInfo m : syntheticMethods) if (m.getName().equals(methodName) && m.getParameterCount() == paramCount) return true; // Check JS type first if (jsTypeInfo != null) { List overloads = jsTypeInfo.getMethodOverloads(methodName); @@ -670,6 +677,7 @@ public class TypeInfo { * Check if this type has a field with the given name. */ public boolean hasField(String fieldName) { + for (FieldInfo f : syntheticFields) if (f.getName().equals(fieldName)) return true; // Check JS type first if (jsTypeInfo != null) { return jsTypeInfo.hasField(fieldName); @@ -724,6 +732,7 @@ public class TypeInfo { * Creates a synthetic MethodInfo based on reflection data or JS type data. */ public MethodInfo getMethodInfo(String methodName) { + for (MethodInfo m : syntheticMethods) if (m.getName().equals(methodName)) return m; // Check JS type first if (jsTypeInfo != null) { JSMethodInfo jsMethod = jsTypeInfo.getMethod(methodName); @@ -813,6 +822,7 @@ public class TypeInfo { * @return The best matching MethodInfo, or null if not found */ public MethodInfo getBestMethodOverload(String methodName, TypeInfo[] argTypes) { + for (MethodInfo m : syntheticMethods) if (m.getName().equals(methodName)) return m; java.util.List overloads = getAllMethodOverloads(methodName); if (overloads.isEmpty()) return null; return OverloadSelector.selectBestOverload(overloads, argTypes); @@ -823,6 +833,7 @@ public class TypeInfo { * Creates a synthetic FieldInfo based on reflection data or JS type data. */ public FieldInfo getFieldInfo(String fieldName) { + for (FieldInfo f : syntheticFields) if (f.getName().equals(fieldName)) return f; // Check JS type first if (jsTypeInfo != null) { JSFieldInfo jsField = jsTypeInfo.getField(fieldName);