Improved arg count/type error underline rendering logic

This commit is contained in:
bigguy345 committed 2025-12-24 23:50:58 +02:00
1 parent 5af5793718
commit 2ff1b3a6cf
3 files changed
+87 -28

No files matched your search

@@ -202,19 +202,7 @@ public class MethodCallInfo {
public boolean hasArgTypeError() {
return !this.argumentTypeErrors.isEmpty();
}
public boolean hasArgTypeError(Token t) {
for (ArgumentTypeError ate : this.argumentTypeErrors) {
if (ate.getArg().equals(t)) {
return true;
}
}
return false;
}
public boolean hasArgCountError(Token t) {
return hasArgCountError() && t.isMethodCall();
}
/**
* Check if this is a static access error (underline method name).
@@ -233,6 +221,9 @@ public class MethodCallInfo {
this.argumentTypeErrors.add(new ArgumentTypeError(arguments.get(argIndex), argIndex, message));
}
public List<ArgumentTypeError> getArgumentTypeErrors() {
return argumentTypeErrors;
}
public class ArgumentTypeError {
private ErrorType type = ErrorType.WRONG_ARG_TYPE;
@@ -298,14 +289,11 @@ public class MethodCallInfo {
if (!isTypeCompatible(argType, paramType)) {
setArgTypeError(i, "Expected " + paramType.getSimpleName() +
" but got " + argType.getSimpleName());
return;
}
} else if (paramType == null) {
setArgTypeError(i, "Parameter type of '" + para.getName() + "' is unresolved");
return;
} else if (argType == null) {
setArgTypeError(i, "Cannot resolve type of argument '" + arg.getText() + "'");
return;
}
}
}
@@ -223,10 +223,8 @@ public class ScriptLine {
}
// Track underline position if token has one
if (t.hasUnderline()) {
int currentY = y + ClientProxy.Font.height() - 1;
drawCurlyUnderline(currentX + 1, currentY, tokenWidth + 1, t.getUnderlineColor());
}
t.drawUnderline(currentX, y + ClientProxy.Font.height() - 1);
// Append the colored token
builder.append(COLOR_CHAR)
@@ -1,5 +1,7 @@
package noppes.npcs.client.gui.util.script.interpreter;
import noppes.npcs.client.ClientProxy;
/**
* Represents a single token in the source code with its type and metadata.
* Tokens are the atomic units of the syntax highlighting system.
@@ -121,20 +123,91 @@ public class Token {
public ScriptLine getParentLine() { return parentLine; }
public boolean hasUnderline() {
if (methodCallInfo != null) {
if (methodCallInfo.hasArgCountError(this))
return true;
else if (methodCallInfo.hasArgTypeError(this)) {
return true;
}
}
return false;
return isMethodCall() && (methodCallInfo.hasArgTypeError() || methodCallInfo.hasArgCountError());
}
public int getUnderlineColor() {
return underlineColor;
}
/**
* Draw underlines for this token's errors.
* @param x start pixel of this token
* @param y baseline pixel for underline
*/
public void drawUnderline(int x, int y) {
if (methodCallInfo == null)
return;
if (methodCallInfo.hasArgCountError()) {
int tokenWidth = ClientProxy.Font.width(text);
ScriptLine.drawCurlyUnderline(x + 1, y, tokenWidth + 1, getUnderlineColor());
return;
}
if (methodCallInfo.hasArgTypeError()) {
// For arg type errors, underline the specific argument span(s).
// Compute pixel X for each argument by walking tokens on the same line
ScriptLine parent = getParentLine();
if (parent == null)
return;
for (MethodCallInfo.ArgumentTypeError error : methodCallInfo.getArgumentTypeErrors()) {
MethodCallInfo.Argument arg = error.getArg();
int argStart = arg.getStartOffset();
int argEnd = arg.getEndOffset();
// Skip args not on this line
if (!parent.containsPosition(argStart))
continue;
// Compute X position by summing token widths from this token up to argStart
int argX = x;
Token cur = this;
// If this token starts after the arg (shouldn't normally happen), skip
if (cur.getGlobalStart() > argStart)
continue;
while (cur != null && cur.getParentLine() == parent && cur.getGlobalEnd() <= argStart) {
argX += ClientProxy.Font.width(cur.getText());
cur = cur.nextOnLine();
}
if (cur == null || cur.getParentLine() != parent)
continue;
// Add partial width of the token containing the arg start
int overlapStart = Math.max(0, argStart - cur.getGlobalStart());
if (overlapStart > 0) {
String part = cur.getText().substring(0, Math.min(overlapStart, cur.getText().length()));
argX += ClientProxy.Font.width(part);
}
// Compute total width of the argument (may span multiple tokens)
int argWidth = 0;
Token cur2 = cur;
int remainingStart = argStart;
while (cur2 != null && cur2.getParentLine() == parent && remainingStart < argEnd) {
int segStart = Math.max(remainingStart, cur2.getGlobalStart());
int segEnd = Math.min(argEnd, cur2.getGlobalEnd());
if (segEnd > segStart) {
int localStart = segStart - cur2.getGlobalStart();
int localEnd = segEnd - cur2.getGlobalStart();
String segText = cur2.getText()
.substring(localStart, Math.min(localEnd, cur2.getText().length()));
argWidth += ClientProxy.Font.width(segText);
}
remainingStart = cur2.getGlobalEnd();
cur2 = cur2.nextOnLine();
}
if (argWidth > 0) {
ScriptLine.drawCurlyUnderline(argX, y, argWidth, getUnderlineColor());
}
}
}
}
// ==================== SETTERS ====================
public void setType(TokenType type) { this.type = type; }