diff --git a/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/AutocompleteMenu.java b/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/AutocompleteMenu.java index 0bbf30c15..89318f6a5 100644 --- a/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/AutocompleteMenu.java +++ b/src/main/java/noppes/npcs/client/gui/util/script/autocomplete/AutocompleteMenu.java @@ -457,7 +457,7 @@ public class AutocompleteMenu extends Gui { TypeInfo type = item.getTypeInfo(); int col = type != null ? type.getTokenType().getHexColor() : DIM_TEXT_COLOR; - font.drawString(typeLabel, typeLabelX, textY, col); + drawTypeLabelWithArraySuffix(typeLabel, typeLabelX, textY, col); } } @@ -629,9 +629,22 @@ public class AutocompleteMenu extends Gui { return text; } - /** - * Draw the scrollbar. - */ + private void drawTypeLabelWithArraySuffix(String typeLabel, int x, int y, int typeColor) { + if (!typeLabel.endsWith("[]")) { + font.drawString(typeLabel, x, y, typeColor); + return; + } + int suffixStart = typeLabel.length() - 2; + while (suffixStart >= 2 && typeLabel.charAt(suffixStart - 2) == '[' && typeLabel.charAt(suffixStart - 1) == ']') { + suffixStart -= 2; + } + String core = typeLabel.substring(0, suffixStart); + String suffix = typeLabel.substring(suffixStart); + font.drawString(core, x, y, typeColor); + int coreWidth = font.getStringWidth(core); + font.drawString(suffix, x + coreWidth, y, TokenType.DEFAULT.getHexColor()); + } + private void drawScrollbar(int mouseX, int mouseY) { int scrollbarX = x + width - 8; int scrollbarY = y + PADDING; diff --git a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptDocument.java b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptDocument.java index 110d9bb64..174afeb9c 100644 --- a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptDocument.java +++ b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/ScriptDocument.java @@ -3231,7 +3231,7 @@ public class ScriptDocument { // Try to resolve as a type TypeInfo typeInfo = resolveType(target); if (typeInfo != null && typeInfo.isResolved()) { - marks.add(new ScriptLine.Mark(start, end, TokenType.IMPORTED_CLASS, typeInfo)); + addTypeMark(marks, start, end, TokenType.IMPORTED_CLASS, typeInfo); return; } // Otherwise mark the parts separately @@ -3253,7 +3253,7 @@ public class ScriptDocument { // Check for type name (imported class) TypeInfo typeInfo = resolveType(target); if (typeInfo != null && typeInfo.isResolved()) { - marks.add(new ScriptLine.Mark(start, end, TokenType.IMPORTED_CLASS, typeInfo)); + addTypeMark(marks, start, end, TokenType.IMPORTED_CLASS, typeInfo); return; } @@ -3929,13 +3929,20 @@ public class ScriptDocument { posAfterType++; } + int varScanPos = posAfterType; + while (text.startsWith("[]", varScanPos)) { + marks.add(new ScriptLine.Mark(varScanPos, varScanPos + 2, TokenType.DEFAULT, null)); + varScanPos += 2; + while (varScanPos < text.length() && Character.isWhitespace(text.charAt(varScanPos))) varScanPos++; + } + // Check if this looks like a type declaration: boolean hasGeneric = genericContent != null && !genericContent.isEmpty(); boolean followedByVarName = false; - boolean atEndOfLine = posAfterType >= text.length() || text.charAt(posAfterType) == '\n'; + boolean atEndOfLine = varScanPos >= text.length() || text.charAt(varScanPos) == '\n'; - if (!atEndOfLine && posAfterType < text.length()) { - char nextChar = text.charAt(posAfterType); + if (!atEndOfLine && varScanPos < text.length()) { + char nextChar = text.charAt(varScanPos); followedByVarName = Character.isLetter(nextChar) || nextChar == '_'; } @@ -4169,7 +4176,9 @@ public class ScriptDocument { // Try to resolve the type for hover info TypeInfo resolvedType = resolveType(typeName); - marks.add(new ScriptLine.Mark(typeStart, typeEnd, resolvedType != null? resolvedType.getTokenType() : TokenType.UNDEFINED_VAR, resolvedType)); + addTypeMark(marks, typeStart, typeEnd, + resolvedType != null ? resolvedType.getTokenType() : TokenType.UNDEFINED_VAR, + resolvedType); } // Sort special ranges by start position @@ -4271,6 +4280,13 @@ public class ScriptDocument { } } + private void addTypeMark(List marks, int start, int end, TokenType type, Object metadata) { + int bracketStart = text.indexOf('[', start); + int coreEnd = (bracketStart >= start && bracketStart < end) ? bracketStart : end; + if (coreEnd < end) marks.add(new ScriptLine.Mark(coreEnd, end, TokenType.DEFAULT, null)); + marks.add(new ScriptLine.Mark(start, coreEnd, type, metadata)); + } + private void markMethodDeclarations(List marks) { Matcher m = METHOD_DECL_PATTERN.matcher(text); while (m.find()) { @@ -4304,8 +4320,10 @@ public class ScriptDocument { if (methodInfo != null) returnToken = methodInfo.getReturnType().getTokenType(); - marks.add(new ScriptLine.Mark(m.start(1), m.end(1), returnToken, - methodInfo != null ? methodInfo.getReturnType() : null)); + int returnStart = m.start(1); + int returnEnd = m.end(1); + addTypeMark(marks, returnStart, returnEnd, + returnToken, methodInfo != null ? methodInfo.getReturnType() : null); // Method name with MethodInfo metadata marks.add(new ScriptLine.Mark(m.start(2), m.end(2), TokenType.METHOD_DECL, methodInfo)); } diff --git a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/hover/TokenHoverInfo.java b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/hover/TokenHoverInfo.java index 66a686b53..6011a44fa 100644 --- a/src/main/java/noppes/npcs/client/gui/util/script/interpreter/hover/TokenHoverInfo.java +++ b/src/main/java/noppes/npcs/client/gui/util/script/interpreter/hover/TokenHoverInfo.java @@ -699,9 +699,10 @@ public class TokenHoverInfo { } else { // Unresolved type iconIndicator = "?"; - addSegment(getName(typeInfo), token.getType().getHexColor()); + String typeName = getName(typeInfo); + splitAndAddTypeName(typeName, token.getType().getHexColor()); if (!typeInfo.isResolved()) { - errors.add("Cannot resolve class '" + getName(typeInfo) + "'"); + errors.add("Cannot resolve class '" + typeName + "'"); } } @@ -1001,14 +1002,14 @@ public class TokenHoverInfo { return; } if (depth > 25) { - // Safety guard against pathological recursive types addSegment(getName(typeInfo), getColorForTypeInfo(typeInfo)); return; } if (typeInfo.isParameterized()) { TypeInfo raw = typeInfo.getRawType(); - addSegment(getName(raw), getColorForTypeInfo(raw)); + String rawName = getName(raw); + splitAndAddTypeName(rawName, getColorForTypeInfo(raw)); addSegment("<", TokenType.DEFAULT.getHexColor()); java.util.List args = typeInfo.getAppliedTypeArgs(); @@ -1023,7 +1024,23 @@ public class TokenHoverInfo { return; } - addSegment(getName(typeInfo), getColorForTypeInfo(typeInfo)); + String typeName = getName(typeInfo); + splitAndAddTypeName(typeName, getColorForTypeInfo(typeInfo)); + } + + private void splitAndAddTypeName(String typeName, int typeColor) { + if (typeName == null || !typeName.endsWith("[]")) { + addSegment(typeName, typeColor); + return; + } + int idx = typeName.length() - 2; + while (idx >= 1 && typeName.charAt(idx - 1) == '[' && typeName.charAt(idx) == ']') { + idx -= 2; + } + if (idx > 0) { + addSegment(typeName.substring(0, idx), typeColor); + } + addSegment(typeName.substring(idx), TokenType.DEFAULT.getHexColor()); } private void extractFieldInfoGeneric(Token token) { @@ -1098,10 +1115,11 @@ public class TokenHoverInfo { if (Modifier.isAbstract(mods)) addSegment("abstract ", TokenType.MODIFIER.getHexColor()); if (Modifier.isSynchronized(mods)) addSegment("synchronized ", TokenType.MODIFIER.getHexColor()); - // Return type - check for actual type color + // Return type - check for actual type color (handle array suffix coloring) Class returnType = method.getReturnType(); int returnTypeColor = getColorForClass(returnType); - addSegment(returnType.getSimpleName(), returnTypeColor); + String returnTypeName = returnType.getSimpleName(); + splitAndAddTypeName(returnTypeName, getColorForTypeInfo(containingType)); addSegment(" ", TokenType.DEFAULT.getHexColor()); // Method name @@ -1114,7 +1132,8 @@ public class TokenHoverInfo { for (int i = 0; i < paramTypes.length; i++) { if (i > 0) addSegment(", ", TokenType.DEFAULT.getHexColor()); int paramTypeColor = getColorForClass(paramTypes[i]); - addSegment(paramTypes[i].getSimpleName(), paramTypeColor); + String paramTypeName = paramTypes[i].getSimpleName(); + splitAndAddTypeName(paramTypeName, paramTypeColor); addSegment(" ", TokenType.DEFAULT.getHexColor()); // Try to get parameter name if available String paramName = params.length > i ? params[i].getName() : "arg" + i; 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 aa6ad6408..b23e4b664 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 @@ -343,7 +343,7 @@ public class TypeInfo { } } - return new TypeInfo(simpleName, fullName, pkg, Kind.CLASS, arrayClass, true, null, null, null, null, elementType); + return new TypeInfo(simpleName, fullName, pkg, elementType.kind, arrayClass, true, null, null, null, null, elementType); } /**