mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 23:37:32 +00:00
Expanded scope of "this." resolution to account for JS script types and inner scopes too. (compat for new ObjectLiterals & not implemented yet but soonTM JS prototypes)
This commit is contained in:
1 parent
86c3277075
commit
c0d5bf3acc
3 files changed
+35
-13
No files matched your search
@@ -188,7 +188,10 @@ public class FieldChainMarker {
|
||||
|
||||
if (ctx.firstIsThis) {
|
||||
// 'this' - resolve to enclosing class/global fields
|
||||
ctx.currentType = ctx.enclosingType;
|
||||
ctx.currentType = document.resolveThisType(chainStart);
|
||||
if (ctx.currentType == null) {
|
||||
ctx.currentType = ctx.enclosingType;
|
||||
}
|
||||
} else if (ctx.firstIsSuper) {
|
||||
// 'super' - resolve to parent class
|
||||
if (ctx.enclosingType != null && ctx.enclosingType.hasSuperClass()) {
|
||||
@@ -228,7 +231,7 @@ public class FieldChainMarker {
|
||||
|
||||
// Case 2: this.field
|
||||
if (index == 1 && ctx.firstIsThis) {
|
||||
return resolveThisFieldMark(ctx);
|
||||
return resolveThisFieldMark(ctx);
|
||||
}
|
||||
|
||||
// Case 3: super.field
|
||||
@@ -286,17 +289,18 @@ public class FieldChainMarker {
|
||||
boolean found = false;
|
||||
FieldInfo fieldInfo = null;
|
||||
|
||||
// First check enclosing script type fields
|
||||
if (ctx.enclosingType != null && ctx.enclosingType.hasField(segment)) {
|
||||
TypeInfo thisType = ctx.currentType != null ? ctx.currentType : ctx.enclosingType;
|
||||
|
||||
if (thisType != null && thisType.hasField(segment)) {
|
||||
found = true;
|
||||
fieldInfo = ctx.enclosingType.getFieldInfo(segment);
|
||||
fieldInfo = thisType.getFieldInfo(segment);
|
||||
} else if (document.getGlobalFields().containsKey(segment)) {
|
||||
found = true;
|
||||
fieldInfo = document.getGlobalFields().get(segment);
|
||||
}
|
||||
|
||||
if (found) {
|
||||
FieldAccessInfo accessInfo = document.createFieldAccessInfo(segment, pos[0], pos[1], ctx.enclosingType,
|
||||
FieldAccessInfo accessInfo = document.createFieldAccessInfo(segment, pos[0], pos[1], thisType,
|
||||
fieldInfo, isLast, false);
|
||||
|
||||
return new MarkResult(new ScriptLine.Mark(pos[0], pos[1], getFieldTokenType(fieldInfo), accessInfo),
|
||||
|
||||
@@ -29,6 +29,7 @@ public class InnerCallableScope {
|
||||
private final Map<String, FieldInfo> locals = new HashMap<>();
|
||||
private InnerCallableScope parentScope; // Enclosing inner scope (for nested lambdas)
|
||||
private TypeInfo expectedType; // The expected functional interface type (set during resolution)
|
||||
private TypeInfo containingObjectType; // For object-literal methods, the synthetic object-literal type
|
||||
|
||||
public InnerCallableScope(Kind kind, int headerStart, int headerEnd, int bodyStart, int bodyEnd) {
|
||||
this.kind = kind;
|
||||
@@ -48,10 +49,12 @@ public class InnerCallableScope {
|
||||
public Map<String, FieldInfo> getLocals() { return locals; }
|
||||
public InnerCallableScope getParentScope() { return parentScope; }
|
||||
public TypeInfo getExpectedType() { return expectedType; }
|
||||
public TypeInfo getContainingObjectType() { return containingObjectType; }
|
||||
|
||||
// Setters
|
||||
public void setParentScope(InnerCallableScope parent) { this.parentScope = parent; }
|
||||
public void setExpectedType(TypeInfo type) { this.expectedType = type; }
|
||||
public void setContainingObjectType(TypeInfo type) { this.containingObjectType = type; }
|
||||
|
||||
public void addParameter(FieldInfo param) {
|
||||
parameters.add(param);
|
||||
|
||||
@@ -5394,7 +5394,7 @@ public class ScriptDocument {
|
||||
|
||||
// "this" keyword
|
||||
if (expr.equals("this")) {
|
||||
return findEnclosingScriptType(position);
|
||||
return resolveThisType(position);
|
||||
}
|
||||
|
||||
if (expr.startsWith("new ")) {
|
||||
@@ -5430,7 +5430,7 @@ public class ScriptDocument {
|
||||
TypeInfo currentType = null;
|
||||
|
||||
if (first.name.equals("this")) {
|
||||
currentType = findEnclosingScriptType(position);
|
||||
currentType = resolveThisType(position);
|
||||
// Handle this.field where we don't have a script type
|
||||
if (currentType == null && segments.size() > 1 && !segments.get(1).isMethodCall) {
|
||||
String fieldName = segments.get(1).name;
|
||||
@@ -5909,8 +5909,23 @@ public class ScriptDocument {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolve the type of "this" at a given position by finding the innermost scope and checking for containing object types.
|
||||
* For both Java and JavaScript, this will correctly resolve to the appropriate type based on the current context (e.g., enclosing class, script type, or synthetic type).
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
TypeInfo resolveThisType(int position) {
|
||||
Object innermostScope = findInnermostScopeAt(position);
|
||||
if (innermostScope instanceof InnerCallableScope) {
|
||||
TypeInfo objectType = ((InnerCallableScope) innermostScope).getContainingObjectType();
|
||||
if (objectType != null && objectType.isResolved()) {
|
||||
return objectType;
|
||||
}
|
||||
}
|
||||
return findEnclosingScriptType(position);
|
||||
}
|
||||
|
||||
// ==================== OPERATOR EXPRESSION RESOLUTION ====================
|
||||
|
||||
@@ -6099,7 +6114,7 @@ public class ScriptDocument {
|
||||
@Override
|
||||
public TypeInfo resolveIdentifier(String name) {
|
||||
if ("this".equals(name)) {
|
||||
return findEnclosingScriptType(position);
|
||||
return resolveThisType(position);
|
||||
}
|
||||
if ("super".equals(name)) {
|
||||
// Resolve super to parent class type
|
||||
@@ -6257,7 +6272,7 @@ public class ScriptDocument {
|
||||
|
||||
// "this" keyword
|
||||
if (expr.equals("this")) {
|
||||
return findEnclosingScriptType(position);
|
||||
return resolveThisType(position);
|
||||
}
|
||||
|
||||
// "new Type()" expressions
|
||||
@@ -6289,7 +6304,7 @@ public class ScriptDocument {
|
||||
TypeInfo currentType = null;
|
||||
|
||||
if (first.name.equals("this")) {
|
||||
currentType = findEnclosingScriptType(position);
|
||||
currentType = resolveThisType(position);
|
||||
} else {
|
||||
// Check if first segment is a type name
|
||||
TypeInfo typeCheck = resolveType(first.name);
|
||||
@@ -8228,7 +8243,7 @@ public class ScriptDocument {
|
||||
// First check inner callable scopes (most specific)
|
||||
InnerCallableScope innermost = null;
|
||||
for (InnerCallableScope scope : innerScopes) {
|
||||
if (scope.containsPosition(position)) {
|
||||
if (scope.containsPosition(position) || scope.containsHeaderPosition(position)) {
|
||||
if (innermost == null || scope.getBodyStart() > innermost.getBodyStart()) {
|
||||
innermost = scope;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user