mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-14 01:24:09 +00:00
Array syntax is now functional and resolves i.e. 'items[i].getName()'
This commit is contained in:
1 parent
131f0e2d74
commit
ad2c8c89c1
2 files changed
+81
-12
No files matched your search
@@ -4954,9 +4954,15 @@ public class ScriptDocument {
|
||||
String fieldName = segments.get(1).name;
|
||||
if (globalFields.containsKey(fieldName)) {
|
||||
currentType = globalFields.get(fieldName).getTypeInfo();
|
||||
if (currentType != null && segments.get(1).hasArrayAccess) {
|
||||
currentType = unwrapArrayElement(currentType);
|
||||
}
|
||||
// Continue from segment 2
|
||||
for (int i = 2; i < segments.size(); i++) {
|
||||
currentType = resolveChainSegment(currentType, segments.get(i));
|
||||
if (currentType != null && segments.get(i).hasArrayAccess) {
|
||||
currentType = unwrapArrayElement(currentType);
|
||||
}
|
||||
if (currentType == null) return null;
|
||||
}
|
||||
return currentType;
|
||||
@@ -5004,10 +5010,17 @@ public class ScriptDocument {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (currentType != null && first.hasArrayAccess) {
|
||||
currentType = unwrapArrayElement(currentType);
|
||||
}
|
||||
|
||||
// Resolve the rest of the chain
|
||||
for (int i = 1; i < segments.size(); i++) {
|
||||
currentType = resolveChainSegment(currentType, segments.get(i));
|
||||
if (currentType != null && segments.get(i).hasArrayAccess) {
|
||||
currentType = unwrapArrayElement(currentType);
|
||||
}
|
||||
if (currentType == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -5104,13 +5117,12 @@ public class ScriptDocument {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if followed by array brackets (array access)
|
||||
// Skip array accesses like [0] or [i] - treat them as part of the current segment
|
||||
boolean hasArrayAccess = false;
|
||||
while (i < expr.length() && Character.isWhitespace(expr.charAt(i))) {
|
||||
i++;
|
||||
}
|
||||
if (i < expr.length() && expr.charAt(i) == '[') {
|
||||
// Skip to the matching closing bracket
|
||||
hasArrayAccess = true;
|
||||
int depth = 1;
|
||||
i++;
|
||||
while (i < expr.length() && depth > 0) {
|
||||
@@ -5121,7 +5133,7 @@ public class ScriptDocument {
|
||||
}
|
||||
}
|
||||
|
||||
segments.add(new ChainSegment(name, start, i, isMethodCall, arguments));
|
||||
segments.add(new ChainSegment(name, start, i, isMethodCall, arguments, hasArrayAccess));
|
||||
|
||||
// Skip whitespace
|
||||
while (i < expr.length() && Character.isWhitespace(expr.charAt(i))) {
|
||||
@@ -5239,16 +5251,48 @@ public class ScriptDocument {
|
||||
final int end;
|
||||
final boolean isMethodCall;
|
||||
final String arguments; // The text between parentheses for method calls, or null for fields
|
||||
final boolean hasArrayAccess;
|
||||
|
||||
ChainSegment(String name, int start, int end, boolean isMethodCall, String arguments) {
|
||||
ChainSegment(String name, int start, int end, boolean isMethodCall, String arguments, boolean hasArrayAccess) {
|
||||
this.name = name;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.isMethodCall = isMethodCall;
|
||||
this.arguments = arguments;
|
||||
this.hasArrayAccess = hasArrayAccess;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the element type from an array type, using multiple fallback strategies.
|
||||
*
|
||||
* Used when a chain segment has array subscript notation (e.g., items[1]).
|
||||
* Given an array type like IItemStack[], returns IItemStack so that subsequent
|
||||
* chain resolution (e.g., .getName()) operates on the element type, not the array type.
|
||||
*
|
||||
* Strategy (in priority order):
|
||||
* 1. If TypeInfo stores elementType (preferred, from arrayOf factory), use it directly
|
||||
* 2. If fullName has [] suffix (legacy or JS types), strip it and re-resolve
|
||||
* 3. If underlying javaClass is an array, use Class.getComponentType()
|
||||
* 4. Fallback to ANY type to prevent null propagation
|
||||
*
|
||||
* @param arrayType The array type to unwrap
|
||||
* @return The element type, or TypeInfo.ANY if unwrapping fails
|
||||
*/
|
||||
private TypeInfo unwrapArrayElement(TypeInfo arrayType) {
|
||||
if (arrayType == null) return null;
|
||||
TypeInfo el = arrayType.getElementType();
|
||||
if (el != null) return el;
|
||||
String name = arrayType.getFullName();
|
||||
if (name != null && name.endsWith("[]")) {
|
||||
return resolveType(name.substring(0, name.length() - 2));
|
||||
}
|
||||
if (arrayType.getJavaClass() != null && arrayType.getJavaClass().isArray()) {
|
||||
return TypeInfo.fromClass(arrayType.getJavaClass().getComponentType());
|
||||
}
|
||||
return TypeInfo.ANY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a single segment of a chain given the current type context.
|
||||
*/
|
||||
@@ -5741,9 +5785,16 @@ public class ScriptDocument {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (currentType != null && first.hasArrayAccess) {
|
||||
currentType = unwrapArrayElement(currentType);
|
||||
}
|
||||
|
||||
for (int i = 1; i < segments.size(); i++) {
|
||||
currentType = resolveChainSegment(currentType, segments.get(i));
|
||||
if (currentType != null && segments.get(i).hasArrayAccess) {
|
||||
currentType = unwrapArrayElement(currentType);
|
||||
}
|
||||
if (currentType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,10 @@ public class TypeInfo {
|
||||
// Null for non-parameterized types
|
||||
private final TypeInfo rawType;
|
||||
|
||||
// For array types, the element type (e.g., IItemStack for IItemStack[])
|
||||
// Null for non-array types
|
||||
private final TypeInfo elementType;
|
||||
|
||||
// Documentation (script-defined types)
|
||||
private JSDocInfo jsDocInfo;
|
||||
|
||||
@@ -90,18 +94,18 @@ public class TypeInfo {
|
||||
|
||||
private TypeInfo(String simpleName, String fullName, String packageName,
|
||||
Kind kind, Class<?> javaClass, boolean resolved, TypeInfo enclosingType) {
|
||||
this(simpleName, fullName, packageName, kind, javaClass, resolved, enclosingType, null, null, null);
|
||||
this(simpleName, fullName, packageName, kind, javaClass, resolved, enclosingType, null, null, null, null);
|
||||
}
|
||||
|
||||
private TypeInfo(String simpleName, String fullName, String packageName,
|
||||
Kind kind, Class<?> javaClass, boolean resolved, TypeInfo enclosingType,
|
||||
JSTypeInfo jsTypeInfo) {
|
||||
this(simpleName, fullName, packageName, kind, javaClass, resolved, enclosingType, jsTypeInfo, null, null);
|
||||
this(simpleName, fullName, packageName, kind, javaClass, resolved, enclosingType, jsTypeInfo, null, null, null);
|
||||
}
|
||||
|
||||
private TypeInfo(String simpleName, String fullName, String packageName,
|
||||
Kind kind, Class<?> javaClass, boolean resolved, TypeInfo enclosingType,
|
||||
JSTypeInfo jsTypeInfo, TypeInfo rawType, List<TypeInfo> appliedTypeArgs) {
|
||||
JSTypeInfo jsTypeInfo, TypeInfo rawType, List<TypeInfo> appliedTypeArgs, TypeInfo elementType) {
|
||||
this.simpleName = simpleName;
|
||||
this.fullName = fullName;
|
||||
this.packageName = packageName;
|
||||
@@ -111,6 +115,7 @@ public class TypeInfo {
|
||||
this.enclosingType = enclosingType;
|
||||
this.jsTypeInfo = jsTypeInfo;
|
||||
this.rawType = rawType;
|
||||
this.elementType = elementType;
|
||||
if (appliedTypeArgs != null) {
|
||||
this.appliedTypeArgs.addAll(appliedTypeArgs);
|
||||
}
|
||||
@@ -129,6 +134,7 @@ public class TypeInfo {
|
||||
this.enclosingType = enclosingType;
|
||||
this.jsTypeInfo = null;
|
||||
this.rawType = null;
|
||||
this.elementType = null;
|
||||
}
|
||||
|
||||
// Factory methods
|
||||
@@ -178,6 +184,10 @@ public class TypeInfo {
|
||||
enclosing = fromClass(clazz.getEnclosingClass());
|
||||
}
|
||||
|
||||
if (clazz.isArray()) {
|
||||
return arrayOf(fromClass(clazz.getComponentType()));
|
||||
}
|
||||
|
||||
return new TypeInfo(simpleName, fullName, packageName, kind, clazz, true, enclosing);
|
||||
}
|
||||
|
||||
@@ -333,7 +343,7 @@ public class TypeInfo {
|
||||
}
|
||||
}
|
||||
|
||||
return new TypeInfo(simpleName, fullName, pkg, Kind.CLASS, arrayClass, true, null);
|
||||
return new TypeInfo(simpleName, fullName, pkg, Kind.CLASS, arrayClass, true, null, null, null, null, elementType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -390,6 +400,14 @@ public class TypeInfo {
|
||||
public TypeInfo getRawType() {
|
||||
return rawType != null ? rawType : this;
|
||||
}
|
||||
|
||||
public TypeInfo getElementType() {
|
||||
return elementType;
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return elementType != null || (javaClass != null && javaClass.isArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the applied type arguments.
|
||||
@@ -417,7 +435,7 @@ public class TypeInfo {
|
||||
// Generic arguments are tracked via appliedTypeArgs and rendered via getDisplayName*().
|
||||
TypeInfo raw = getRawType();
|
||||
return new TypeInfo(raw.simpleName, raw.fullName, raw.packageName, raw.kind, raw.javaClass,
|
||||
raw.resolved, raw.enclosingType, raw.jsTypeInfo, raw, typeArgs);
|
||||
raw.resolved, raw.enclosingType, raw.jsTypeInfo, raw, typeArgs, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user