mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-13 20:44:08 +00:00
New improved DocumentError framework
This commit is contained in:
1 parent
76fb5d04f7
commit
13b71a6c48
2 files changed
+115
-124
No files matched your search
+9
-124
@@ -1,16 +1,14 @@
|
||||
package noppes.npcs.client.gui.util.script.interpreter;
|
||||
|
||||
import noppes.npcs.client.ClientProxy;
|
||||
import noppes.npcs.client.gui.util.script.interpreter.field.AssignmentInfo;
|
||||
import noppes.npcs.client.gui.util.script.interpreter.field.FieldInfo;
|
||||
import noppes.npcs.client.gui.util.script.interpreter.method.MethodCallInfo;
|
||||
import noppes.npcs.client.gui.util.script.interpreter.method.MethodInfo;
|
||||
import noppes.npcs.client.gui.util.script.interpreter.type.ScriptTypeInfo;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
/**
|
||||
* Helper class for rendering error underlines in script editor lines.
|
||||
* Handles the repetitive calculation of underline positions and drawing of curly underlines.
|
||||
* Renders underlines from the document's centralized error list ({@link DocumentError}).
|
||||
*
|
||||
* <p>Error collection happens during analysis in {@link ScriptDocument#formatCodeText()}.
|
||||
* This renderer only draws; it does not detect or collect errors.
|
||||
*/
|
||||
public class ErrorUnderlineRenderer {
|
||||
private static final int ERROR_COLOR = 0xFF5555;
|
||||
@@ -32,6 +30,8 @@ public class ErrorUnderlineRenderer {
|
||||
|
||||
/**
|
||||
* Draw error underlines for all validation errors in the document that intersect the given line.
|
||||
* Iterates over the document's centralized error list and draws underlines for each error
|
||||
* whose span intersects this line.
|
||||
*
|
||||
* @param doc The script document containing all errors
|
||||
* @param lineStartX X coordinate where the line starts rendering
|
||||
@@ -47,125 +47,10 @@ public class ErrorUnderlineRenderer {
|
||||
|
||||
if (doc == null)
|
||||
return;
|
||||
|
||||
|
||||
// Check all method calls in the document
|
||||
for (MethodCallInfo call : doc.getMethodCalls()) {
|
||||
// Skip method declarations that were erroneously recorded as calls
|
||||
boolean isDeclaration = false;
|
||||
int methodStart = call.getMethodNameStart();
|
||||
for (MethodInfo mi : doc.getAllMethods()) {
|
||||
//!call.isConstructor for enum declarations
|
||||
if (!call.isConstructor() && mi.getDeclarationOffset() <= methodStart && mi.getBodyStart() >= methodStart) {
|
||||
isDeclaration = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isDeclaration)
|
||||
continue;
|
||||
|
||||
// Skip if this call doesn't intersect this line
|
||||
if (call.getCloseParenOffset() < lineStart || call.getOpenParenOffset() > lineEnd)
|
||||
continue;
|
||||
|
||||
// Handle arg count errors (underline the method name)
|
||||
if (call.hasArgCountError()) {
|
||||
int methodEnd = methodStart + call.getMethodName().length();
|
||||
drawUnderlineForSpan(methodStart, methodEnd, lineStartX, baselineY,
|
||||
lineText, lineStart, lineEnd, ERROR_COLOR);
|
||||
} else if (call.hasArgTypeError()) {
|
||||
// Handle return type mismatch (underline the method name) - currently commented out
|
||||
// if (call.hasReturnTypeMismatch()) { ... }
|
||||
|
||||
// Handle arg type errors (underline specific arguments)
|
||||
|
||||
for (MethodCallInfo.ArgumentTypeError error : call.getArgumentTypeErrors()) {
|
||||
MethodCallInfo.Argument arg = error.getArg();
|
||||
drawUnderlineForSpan(arg.getStartOffset(), arg.getEndOffset(),
|
||||
lineStartX, baselineY, lineText, lineStart, lineEnd, ERROR_COLOR);
|
||||
}
|
||||
} else if(call.hasError()){
|
||||
// Handle other call errors (underline the whole call)
|
||||
drawUnderlineForSpan(call.getMethodNameStart(), call.getCloseParenOffset() + 1,
|
||||
lineStartX, baselineY, lineText, lineStart, lineEnd, ERROR_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
// Check all field accesses in the document (currently commented out)
|
||||
// for (FieldAccessInfo access : doc.getFieldAccesses()) { ... }
|
||||
|
||||
// Check all errored assignments in the document
|
||||
for (AssignmentInfo assign : doc.getAllErroredAssignments()) {
|
||||
int underlineStart, underlineEnd;
|
||||
|
||||
if (assign.isLhsError()) {
|
||||
underlineStart = assign.getLhsStart();
|
||||
underlineEnd = assign.getLhsEnd();
|
||||
} else if (assign.isRhsError()) {
|
||||
underlineStart = assign.getRhsStart();
|
||||
underlineEnd = assign.getRhsEnd();
|
||||
} else if (assign.isFullLineError()) {
|
||||
underlineStart = assign.getStatementStart();
|
||||
underlineEnd = assign.getRhsEnd();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
drawUnderlineForSpan(underlineStart, underlineEnd, lineStartX, baselineY,
|
||||
lineText, lineStart, lineEnd, ERROR_COLOR);
|
||||
}
|
||||
|
||||
// Check all method declarations for errors
|
||||
for (MethodInfo method : doc.getAllMethods()) {
|
||||
if (!method.isDeclaration() || !method.hasError())
|
||||
continue;
|
||||
|
||||
// Handle return statement type errors
|
||||
if (method.hasReturnStatementErrors()) {
|
||||
for (MethodInfo.ReturnStatementError returnError : method.getReturnStatementErrors()) {
|
||||
drawUnderlineForSpan(returnError.getStartOffset(), returnError.getEndOffset(),
|
||||
lineStartX, baselineY, lineText, lineStart, lineEnd, ERROR_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle missing return error (underline the method name)
|
||||
else if (method.hasMissingReturnError()) {
|
||||
int methodNameStart = method.getNameOffset();
|
||||
int methodNameEnd = methodNameStart + method.getName().length();
|
||||
drawUnderlineForSpan(methodNameStart, methodNameEnd, lineStartX, baselineY,
|
||||
lineText, lineStart, lineEnd, ERROR_COLOR);
|
||||
}
|
||||
// Handle parameter errors
|
||||
else if (method.hasParameterErrors()) {
|
||||
for (MethodInfo.ParameterError paramError : method.getParameterErrors()) {
|
||||
FieldInfo param = paramError.getParameter();
|
||||
if (param == null || param.getDeclarationOffset() < 0)
|
||||
continue;
|
||||
|
||||
int paramStart = param.getDeclarationOffset();
|
||||
int paramEnd = paramStart + param.getName().length();
|
||||
drawUnderlineForSpan(paramStart, paramEnd, lineStartX, baselineY,
|
||||
lineText, lineStart, lineEnd, ERROR_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle all other errors
|
||||
else if (method.hasError()) {
|
||||
drawUnderlineForSpan(method.getFullDeclarationOffset(), method.getDeclarationEnd(), lineStartX,
|
||||
baselineY, lineText, lineStart, lineEnd, ERROR_COLOR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
for(ScriptTypeInfo types : doc.getScriptTypes()){
|
||||
if(!types.hasError())
|
||||
continue;
|
||||
|
||||
int typeStart = types.getDeclarationOffset();
|
||||
int typeEnd = types.getBodyStart();
|
||||
drawUnderlineForSpan(typeStart, typeEnd, lineStartX, baselineY,
|
||||
lineText, lineStart, lineEnd, ERROR_COLOR);
|
||||
for (DocumentError error : doc.getErrors()) {
|
||||
drawUnderlineForSpan(error.getStartPos(), error.getEndPos(),
|
||||
lineStartX, baselineY, lineText, lineStart, lineEnd, ERROR_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,6 +140,9 @@ public class ScriptDocument {
|
||||
// Declaration errors (duplicate declarations, etc.)
|
||||
private final List<AssignmentInfo> declarationErrors = new ArrayList<>();
|
||||
|
||||
// Centralized error list - populated by ErrorUnderlineRenderer during rendering
|
||||
private final List<DocumentError> errors = new ArrayList<>();
|
||||
|
||||
// Excluded regions (strings/comments) - positions where other patterns shouldn't match
|
||||
private final List<int[]> excludedRanges = new ArrayList<>();
|
||||
|
||||
@@ -361,6 +364,7 @@ public class ScriptDocument {
|
||||
*/
|
||||
public void formatCodeText() {
|
||||
// Clear previous state (same for both languages)
|
||||
errors.clear();
|
||||
imports.clear();
|
||||
methods.clear();
|
||||
globalFields.clear();
|
||||
@@ -394,6 +398,9 @@ public class ScriptDocument {
|
||||
|
||||
// Phase 7: Compute indent guides
|
||||
computeIndentGuides(marks);
|
||||
|
||||
// Phase 8: Populate centralized error list from all error sources
|
||||
populateErrors();
|
||||
}
|
||||
|
||||
// Store the last JS analyzer for autocomplete (deprecated - use methods/globalFields/methodLocals instead)
|
||||
@@ -10097,6 +10104,105 @@ for (ScriptTypeInfo type:scriptTypes.values()) {
|
||||
return errored;
|
||||
}
|
||||
|
||||
public void addError(Token token, int startPos, int endPos, String message) {
|
||||
errors.add(new DocumentError(token, startPos, endPos, message));
|
||||
}
|
||||
|
||||
public List<DocumentError> getErrors() {
|
||||
return Collections.unmodifiableList(errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all validation errors from MethodCallInfo, AssignmentInfo, MethodInfo, and ScriptTypeInfo
|
||||
* into the centralized error list. Called once during analysis (formatCodeText), not during rendering.
|
||||
*/
|
||||
private void populateErrors() {
|
||||
// Method call errors
|
||||
List<MethodInfo> allMethods = getAllMethods();
|
||||
for (MethodCallInfo call : getMethodCalls()) {
|
||||
boolean isDeclaration = false;
|
||||
int methodStart = call.getMethodNameStart();
|
||||
for (MethodInfo mi : allMethods) {
|
||||
if (!call.isConstructor() && mi.getDeclarationOffset() <= methodStart && mi.getBodyStart() >= methodStart) {
|
||||
isDeclaration = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isDeclaration)
|
||||
continue;
|
||||
|
||||
if (call.hasArgCountError()) {
|
||||
int methodEnd = methodStart + call.getMethodName().length();
|
||||
addError(null, methodStart, methodEnd, call.getErrorMessage());
|
||||
} else if (call.hasArgTypeError()) {
|
||||
for (MethodCallInfo.ArgumentTypeError error : call.getArgumentTypeErrors()) {
|
||||
MethodCallInfo.Argument arg = error.getArg();
|
||||
addError(null, arg.getStartOffset(), arg.getEndOffset(), error.getMessage());
|
||||
}
|
||||
} else if (call.hasError()) {
|
||||
addError(null, call.getMethodNameStart(), call.getCloseParenOffset() + 1, call.getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Assignment errors
|
||||
for (AssignmentInfo assign : getAllErroredAssignments()) {
|
||||
int underlineStart, underlineEnd;
|
||||
|
||||
if (assign.isLhsError()) {
|
||||
underlineStart = assign.getLhsStart();
|
||||
underlineEnd = assign.getLhsEnd();
|
||||
} else if (assign.isRhsError()) {
|
||||
underlineStart = assign.getRhsStart();
|
||||
underlineEnd = assign.getRhsEnd();
|
||||
} else if (assign.isFullLineError()) {
|
||||
underlineStart = assign.getStatementStart();
|
||||
underlineEnd = assign.getRhsEnd();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
addError(null, underlineStart, underlineEnd, assign.getErrorMessage());
|
||||
}
|
||||
|
||||
// Method declaration errors
|
||||
for (MethodInfo method : allMethods) {
|
||||
if (!method.isDeclaration() || !method.hasError())
|
||||
continue;
|
||||
|
||||
if (method.hasReturnStatementErrors()) {
|
||||
for (MethodInfo.ReturnStatementError returnError : method.getReturnStatementErrors()) {
|
||||
addError(null, returnError.getStartOffset(), returnError.getEndOffset(), returnError.getMessage());
|
||||
}
|
||||
} else if (method.hasMissingReturnError()) {
|
||||
int methodNameStart = method.getNameOffset();
|
||||
int methodNameEnd = methodNameStart + method.getName().length();
|
||||
addError(null, methodNameStart, methodNameEnd, method.getErrorMessage());
|
||||
} else if (method.hasParameterErrors()) {
|
||||
for (MethodInfo.ParameterError paramError : method.getParameterErrors()) {
|
||||
FieldInfo param = paramError.getParameter();
|
||||
if (param == null || param.getDeclarationOffset() < 0)
|
||||
continue;
|
||||
|
||||
int paramStart = param.getDeclarationOffset();
|
||||
int paramEnd = paramStart + param.getName().length();
|
||||
addError(null, paramStart, paramEnd, paramError.getMessage());
|
||||
}
|
||||
} else if (method.hasError()) {
|
||||
addError(null, method.getFullDeclarationOffset(), method.getDeclarationEnd(), method.getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Script type declaration errors
|
||||
for (ScriptTypeInfo type : getScriptTypes()) {
|
||||
if (!type.hasError())
|
||||
continue;
|
||||
|
||||
int typeStart = type.getDeclarationOffset();
|
||||
int typeEnd = type.getBodyStart();
|
||||
addError(null, typeStart, typeEnd, type.getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public TypeResolver getTypeResolver() {
|
||||
return typeResolver;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user