validatePropertyOrMethodAccess method
void
validatePropertyOrMethodAccess()
Validates that a property or method exists on the given object. In case of a typo, it provides suggestions based on Levenshtein distance.
Implementation
void validatePropertyOrMethodAccess(
String propertyName, String objectName, dynamic obj, Node node) {
if (obj == null) {
throw JSException(
node.line ?? 1,
'Cannot access property "$propertyName" on null or undefined object "$objectName"',
detailedError: 'Code: ${_interpreter.getCode(node)}',
recovery:
'Make sure the object is properly initialized before accessing its properties.',
);
}
try {
// Get the property using InvokableController
InvokableController.getProperty(obj, propertyName);
} catch (e) {
if (e is InvalidPropertyException) {
// If property doesn't exist, check if it's a method
final hasMethod = obj is Invokable && obj.hasMethod(propertyName);
if (!hasMethod) {
// If neither property nor method exists, provide helpful suggestions
final availableProps = obj is Invokable
? [...Invokable.getGettableProperties(obj), ...obj.methods().keys]
: obj is Map
? obj.keys.toList()
: [];
final suggestions = availableProps
.where((prop) =>
_levenshteinDistance(propertyName, prop.toString()) <= 2)
.toList();
var recovery =
'Check if you have used the correct property name (case sensitive).';
if (suggestions.isNotEmpty) {
recovery +=
'\nDid you mean one of these? ${suggestions.join(", ")}';
}
throw JSException(
node.line ?? 1,
'Property "$propertyName" does not exist on object "$objectName"',
detailedError:
'Code: ${_interpreter.getCode(node)}\nAvailable properties: ${availableProps.join(", ")}',
recovery: recovery,
);
}
}
rethrow;
}
}