Implemented ES5.1 global functions

This commit is contained in:
bigguy345 committed 2026-03-05 21:12:50 +02:00
1 parent eaedb1b88f
commit 3172e6673f
4 files changed
+104 -4

No files matched your search

@@ -233,6 +233,11 @@ public class JSAutocompleteProvider extends JavaAutocompleteProvider {
items.add(AutocompleteItem.fromType(TypeInfo.fromJSTypeInfo(jsTypeInfo)));
}
}
// Add global engine functions (parseInt, parseFloat, isNaN, isFinite, etc.)
for (JSMethodInfo fn : registry.getGlobalEngineFunctions().values()) {
items.add(AutocompleteItem.fromJSMethod(fn, 0));
}
}
protected UsageTracker getUsageTracker() {
@@ -9,6 +9,7 @@ import noppes.npcs.client.gui.util.script.interpreter.field.EnumConstantInfo;
import noppes.npcs.client.gui.util.script.interpreter.field.FieldAccessInfo;
import noppes.npcs.client.gui.util.script.interpreter.field.FieldInfo;
import noppes.npcs.client.gui.util.script.interpreter.js_parser.JSScriptAnalyzer;
import noppes.npcs.client.gui.util.script.interpreter.js_parser.JSMethodInfo;
import noppes.npcs.client.gui.util.script.interpreter.js_parser.JSTypeRegistry;
import noppes.npcs.client.gui.util.script.interpreter.jsdoc.JSDocInfo;
import noppes.npcs.client.gui.util.script.interpreter.jsdoc.JSDocParamTag;
@@ -4502,6 +4503,26 @@ public class ScriptDocument {
methodCalls.add(callInfo);
marks.add(new ScriptLine.Mark(nameStart, nameEnd, TokenType.METHOD_CALL, callInfo));
}
} else if (isGlobalEngineFunction(methodName)) {
JSMethodInfo jsGlobalMethod = JSTypeRegistry.getInstance().getGlobalEngineFunction(methodName);
MethodInfo resolvedGlobal = MethodInfo.fromJSMethod(jsGlobalMethod, null);
List<MethodCallInfo.Argument> globalArguments = arguments;
if (resolvedGlobal.getParameters().size() == arguments.size()) {
globalArguments = parseMethodArguments(openParen + 1, closeParen, resolvedGlobal);
}
MethodCallInfo callInfo = new MethodCallInfo(
methodName, nameStart, nameEnd, openParen, closeParen,
globalArguments, null, resolvedGlobal
);
if (!isFollowedByDot(closeParen)) {
TypeInfo expectedType = findExpectedTypeAtPosition(nameStart);
if (expectedType != null) callInfo.setExpectedType(expectedType);
}
callInfo.validate();
methodCalls.add(callInfo);
marks.add(new ScriptLine.Mark(nameStart, nameEnd, TokenType.METHOD_CALL, callInfo));
} else {
marks.add(new ScriptLine.Mark(nameStart, nameEnd, TokenType.UNDEFINED_VAR));
}
@@ -5027,6 +5048,9 @@ public class ScriptDocument {
currentType = scriptMethod.getReturnType();
}
}
if (currentType == null && isGlobalEngineFunction(first.name)) {
currentType = getGlobalEngineFunctionReturnType(first.name);
}
}
if (currentType != null && first.hasArrayAccess) {
@@ -5658,6 +5682,9 @@ public class ScriptDocument {
return scriptMethod.getReturnType();
}
}
if (isGlobalEngineFunction(methodName)) {
return getGlobalEngineFunctionReturnType(methodName);
}
return null;
}
@@ -5802,6 +5829,9 @@ public class ScriptDocument {
currentType = scriptMethod.getReturnType();
}
}
if (currentType == null && isGlobalEngineFunction(first.name)) {
currentType = getGlobalEngineFunctionReturnType(first.name);
}
}
if (currentType != null && first.hasArrayAccess) {
@@ -6228,6 +6258,21 @@ public class ScriptDocument {
);
return null;
}
/**
* True if in JS mode and name is a registered global engine function (parseInt, parseFloat, etc.).
*/
private boolean isGlobalEngineFunction(String name) {
return isJavaScript() && JSTypeRegistry.getInstance().isGlobalEngineFunction(name);
}
/**
* Return the resolved return type of a global engine function call, or null if unknown.
*/
private TypeInfo getGlobalEngineFunctionReturnType(String name) {
JSMethodInfo m = JSTypeRegistry.getInstance().getGlobalEngineFunction(name);
return m != null ? m.getResolvedReturnType(null) : null;
}
private void injectSamParameterTypes(MethodInfo scriptMethod, MethodInfo sam) {
String methodName = scriptMethod.getName();
@@ -54,6 +54,8 @@ public class JSTypeRegistry {
private final Map<String, String> globalEngineObjects = new LinkedHashMap<>();
// Math / Number / Json / etc. built-in globals from ECMAScript 5.1
private final Map<String, JSTypeInfo> globalEngineImports = new LinkedHashMap<>();
// Top-level global functions from GlobalFunctions.d.ts (parseInt, parseFloat, isNaN, etc.)
private final Map<String, JSMethodInfo> globalEngineFunctions = new LinkedHashMap<>();
// Primitive types
private static final Set<String> PRIMITIVES = new HashSet<>(Arrays.asList(
@@ -856,6 +858,8 @@ public class JSTypeRegistry {
registerGlobalIfTypeExists("Boolean", "Boolean");
registerGlobalIfTypeExists("RegExp", "RegExp");
registerGlobalIfTypeExists("Error", "Error");
extractGlobalFunctions();
}
/**
@@ -869,6 +873,27 @@ public class JSTypeRegistry {
}
}
/**
* Extract top-level global functions from the GlobalFunctions JSTypeInfo.
* Moves all methods into globalEngineFunctions and removes the GlobalFunctions
* type from the registry (it is not a constructable type).
*/
private void extractGlobalFunctions() {
JSTypeInfo globalFns = types.get("GlobalFunctions");
if (globalFns == null) return;
for (Map.Entry<String, JSMethodInfo> entry : globalFns.getMethods().entrySet()) {
String key = entry.getKey();
// Strip overload suffix ($1, $2, …) to get base name
String baseName = key.contains("$") ? key.substring(0, key.indexOf('$')) : key;
// Keep the first overload per base name
globalEngineFunctions.putIfAbsent(baseName, entry.getValue());
}
// Remove GlobalFunctions from the main type registry — it is not a usable type name
types.remove("GlobalFunctions");
}
/**
* Get the type name for a global object.
* @param name The global variable name
@@ -891,6 +916,27 @@ public class JSTypeRegistry {
public Map<String, JSTypeInfo> getGlobalEngineImports() {
return Collections.unmodifiableMap(globalEngineImports);
}
/**
* Get JSMethodInfo for a global engine function by name (e.g., "parseInt").
*/
public JSMethodInfo getGlobalEngineFunction(String name) {
return globalEngineFunctions.get(name);
}
/**
* Check if a name is a registered global engine function.
*/
public boolean isGlobalEngineFunction(String name) {
return globalEngineFunctions.containsKey(name);
}
/**
* Get all registered global engine functions (parseInt, parseFloat, isNaN, etc.).
*/
public Map<String, JSMethodInfo> getGlobalEngineFunctions() {
return Collections.unmodifiableMap(globalEngineFunctions);
}
/**
* Check if initialized.
*/
@@ -911,6 +957,7 @@ public class JSTypeRegistry {
contextHooks.clear();
globalEngineObjects.clear();
globalEngineImports.clear();
globalEngineFunctions.clear();
DtsJavaBridge.clearCache();
initialized = false;
initializationAttempted = false;