mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 20:07:32 +00:00
Added INTERFACE_METHOD_BODY error & improved logic
This commit is contained in:
1 parent
c97de07ef7
commit
6cdb222b67
3 files changed
+36
-61
No files matched your search
@@ -448,7 +448,9 @@ public class ScriptDocument {
|
||||
// Constructors don't have a return type, but we'll use the containing type as a marker
|
||||
MethodInfo constructorInfo = MethodInfo.declaration(
|
||||
typeName,
|
||||
scriptType, // Return type is the type itself
|
||||
scriptType,
|
||||
// Return type is the type itself
|
||||
scriptType,
|
||||
params,
|
||||
fullDeclOffset,
|
||||
typeOffset,
|
||||
@@ -456,8 +458,7 @@ public class ScriptDocument {
|
||||
constructorBodyStart,
|
||||
constructorBodyEnd,
|
||||
modifiers,
|
||||
documentation
|
||||
);
|
||||
documentation);
|
||||
scriptType.addConstructor(constructorInfo);
|
||||
}
|
||||
}
|
||||
@@ -504,10 +505,10 @@ public class ScriptDocument {
|
||||
String methodName = m.group(2);
|
||||
String paramList = m.group(3);
|
||||
String delimiter = m.group(4);
|
||||
boolean bodyless = delimiter.equals(";");
|
||||
boolean hasBody = delimiter.equals("{");
|
||||
|
||||
int bodyStart = bodyless ? m.end() : text.indexOf('{', m.end() - 1);
|
||||
int bodyEnd = bodyless ? m.end() : findMatchingBrace(bodyStart);
|
||||
int bodyStart = !hasBody ? m.end() : text.indexOf('{', m.end() - 1);
|
||||
int bodyEnd = !hasBody ? m.end() : findMatchingBrace(bodyStart);
|
||||
if (bodyEnd < 0)
|
||||
bodyEnd = text.length();
|
||||
|
||||
@@ -523,11 +524,19 @@ public class ScriptDocument {
|
||||
int nameOffset = m.start(2); // Start of method name
|
||||
int fullDeclOffset = findFullDeclarationStart(m.start(1), text); // Start including modifiers
|
||||
|
||||
ScriptTypeInfo scriptType = null;
|
||||
for (ScriptTypeInfo type : scriptTypes.values())
|
||||
if (type.containsPosition(bodyStart)) {
|
||||
scriptType = type;
|
||||
break;
|
||||
}
|
||||
|
||||
// Parse parameters with their actual positions
|
||||
List<FieldInfo> params = parseParametersWithPositions(paramList, m.start(3));
|
||||
|
||||
MethodInfo methodInfo = MethodInfo.declaration(
|
||||
methodName,
|
||||
scriptType,
|
||||
resolveType(returnType),
|
||||
params,
|
||||
fullDeclOffset,
|
||||
@@ -539,25 +548,15 @@ public class ScriptDocument {
|
||||
documentation
|
||||
);
|
||||
|
||||
ScriptTypeInfo scriptType = null;
|
||||
for (ScriptTypeInfo type : scriptTypes.values())
|
||||
if (type.containsPosition(bodyStart)) {
|
||||
scriptType = type;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Validate the method (return statements, parameters) with type resolution
|
||||
String methodBodyText = bodyEnd > bodyStart + 1 ? text.substring(bodyStart + 1, bodyEnd) : "";
|
||||
methodInfo.validate(methodBodyText, (expr, pos) -> resolveExpressionType(expr, pos));
|
||||
|
||||
if (scriptType != null) {
|
||||
if (scriptType.getKind() == TypeInfo.Kind.INTERFACE)
|
||||
methodInfo.setBodyless(bodyless);
|
||||
|
||||
scriptType.addMethod(methodInfo);
|
||||
} else
|
||||
methods.add(methodInfo);
|
||||
|
||||
// Validate the method (return statements, parameters) with type resolution
|
||||
String methodBodyText = bodyEnd > bodyStart + 1 ? text.substring(bodyStart + 1, bodyEnd) : "";
|
||||
methodInfo.validate(methodBodyText, hasBody, (expr, pos) -> resolveExpressionType(expr, pos));
|
||||
}
|
||||
|
||||
// Check for duplicate method declarations
|
||||
|
||||
+14
-40
@@ -33,7 +33,8 @@ public final class MethodInfo {
|
||||
*/
|
||||
public enum ErrorType {
|
||||
NONE,
|
||||
MISSING_RETURN, // Non-void method missing return statement
|
||||
MISSING_RETURN, // Non-void method missing return statement,
|
||||
INTERFACE_METHOD_BODY, // Interface method has a body
|
||||
MISSING_BODY, // Non-void method missing return statement
|
||||
RETURN_TYPE_MISMATCH, // Return statement type doesn't match method return type
|
||||
VOID_METHOD_RETURNS_VALUE, // Void method returns a value
|
||||
@@ -57,7 +58,6 @@ public final class MethodInfo {
|
||||
private final String documentation; // Javadoc/comment documentation for this method
|
||||
private final java.lang.reflect.Method javaMethod; // The Java reflection Method, if this was created from reflection
|
||||
|
||||
private boolean bodyless;
|
||||
// Error tracking for method declarations
|
||||
private ErrorType errorType = ErrorType.NONE;
|
||||
private String errorMessage;
|
||||
@@ -84,31 +84,10 @@ public final class MethodInfo {
|
||||
this.javaMethod = javaMethod;
|
||||
}
|
||||
|
||||
// Factory methods
|
||||
public static MethodInfo declaration(String name, TypeInfo returnType, List<FieldInfo> params,
|
||||
int fullDeclOffset, int typeOffset, int nameOffset,
|
||||
int bodyStart, int bodyEnd) {
|
||||
return new MethodInfo(name, returnType, null, params, fullDeclOffset, typeOffset, nameOffset, bodyStart, bodyEnd, true, true, 0, null, null);
|
||||
}
|
||||
|
||||
public static MethodInfo declaration(String name, TypeInfo returnType, List<FieldInfo> params,
|
||||
int fullDeclOffset, int typeOffset, int nameOffset,
|
||||
int bodyStart, int bodyEnd, boolean isStatic) {
|
||||
int modifiers = isStatic ? Modifier.STATIC : 0;
|
||||
return new MethodInfo(name, returnType, null, params, fullDeclOffset, typeOffset, nameOffset, bodyStart, bodyEnd, true, true, modifiers, null, null);
|
||||
}
|
||||
|
||||
public static MethodInfo declaration(String name, TypeInfo returnType, List<FieldInfo> params,
|
||||
int fullDeclOffset, int typeOffset, int nameOffset,
|
||||
int bodyStart, int bodyEnd, boolean isStatic, String documentation) {
|
||||
int modifiers = isStatic ? Modifier.STATIC : 0;
|
||||
return new MethodInfo(name, returnType, null, params, fullDeclOffset, typeOffset, nameOffset, bodyStart, bodyEnd, true, true, modifiers, documentation, null);
|
||||
}
|
||||
|
||||
public static MethodInfo declaration(String name, TypeInfo returnType, List<FieldInfo> params,
|
||||
public static MethodInfo declaration(String name, TypeInfo containingType, TypeInfo returnType, List<FieldInfo> params,
|
||||
int fullDeclOffset, int typeOffset, int nameOffset,
|
||||
int bodyStart, int bodyEnd, int modifiers, String documentation) {
|
||||
return new MethodInfo(name, returnType, null, params, fullDeclOffset, typeOffset, nameOffset, bodyStart, bodyEnd, true, true, modifiers, documentation, null);
|
||||
return new MethodInfo(name, returnType, containingType, params, fullDeclOffset, typeOffset, nameOffset, bodyStart, bodyEnd, true, true, modifiers, documentation, null);
|
||||
}
|
||||
|
||||
public static MethodInfo call(String name, TypeInfo containingType, int paramCount) {
|
||||
@@ -195,8 +174,6 @@ public final class MethodInfo {
|
||||
public boolean isPrivate() { return Modifier.isPrivate(modifiers); }
|
||||
public boolean isProtected() { return Modifier.isProtected(modifiers); }
|
||||
public String getDocumentation() { return documentation; }
|
||||
public boolean isBodyless() { return bodyless; }
|
||||
public void setBodyless(boolean bodyless) { this.bodyless = bodyless; }
|
||||
|
||||
/**
|
||||
* Check if a position is inside this method's body.
|
||||
@@ -407,16 +384,7 @@ public final class MethodInfo {
|
||||
public interface TypeResolver {
|
||||
TypeInfo resolveExpression(String expression, int position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate this method declaration.
|
||||
* Checks for parameter errors and missing return statements.
|
||||
*
|
||||
* @param methodBodyText The text content of the method body (between { and })
|
||||
*/
|
||||
public void validate(String methodBodyText) {
|
||||
validate(methodBodyText, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate this method declaration with type resolution for return statements.
|
||||
@@ -425,16 +393,22 @@ public final class MethodInfo {
|
||||
* @param methodBodyText The text content of the method body (between { and })
|
||||
* @param typeResolver Optional callback to resolve expression types (for return type checking)
|
||||
*/
|
||||
public void validate(String methodBodyText, TypeResolver typeResolver) {
|
||||
public void validate(String methodBodyText, boolean hasBody, TypeResolver typeResolver) {
|
||||
if (!isDeclaration) return;
|
||||
|
||||
// Validate parameters
|
||||
validateParameters();
|
||||
|
||||
boolean interfaceMember = containingType != null && containingType.isInterface();
|
||||
if (hasBody && (interfaceMember || isAbstract() || isNative())) {
|
||||
setError(MethodInfo.ErrorType.INTERFACE_METHOD_BODY, "Interface or abstract methods cannot have a body");
|
||||
return;
|
||||
}
|
||||
|
||||
//No need to check for return types/statements
|
||||
if(bodyless)
|
||||
if(interfaceMember)
|
||||
return;
|
||||
|
||||
//If no body and not interface or abstract/native
|
||||
if (bodyStart == bodyEnd && !isAbstract() && !isNative()) {
|
||||
setError(ErrorType.MISSING_BODY, "Method must have a body or be declared abstract/native.");
|
||||
return;
|
||||
|
||||
@@ -130,7 +130,9 @@ public class TypeInfo {
|
||||
public boolean isResolved() { return resolved; }
|
||||
public TypeInfo getEnclosingType() { return enclosingType; }
|
||||
public boolean isInnerClass() { return enclosingType != null; }
|
||||
|
||||
public boolean isInterface() {return kind == Kind.INTERFACE;}
|
||||
public boolean isEnum() {return kind == Kind.ENUM;}
|
||||
|
||||
/**
|
||||
* Get the appropriate TokenType for highlighting this type.
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user