validateObjectPath method

void validateObjectPath(
  1. MemberExpression node
)

Validates a chain of property accesses

Implementation

void validateObjectPath(MemberExpression node) {
  dynamic currentObj;
  String path = '';

  // First get the base object
  if (node.object is NameExpression) {
    String objectName = (node.object as NameExpression).name.value;
    validateContextExistence(objectName, node, context, isObject: true);
    currentObj = context.getContextById(objectName);
    path = objectName;
  } else if (node.object is MemberExpression) {
    // Recursively validate the nested object path
    validateObjectPath(node.object as MemberExpression);
    currentObj = _interpreter.getValueFromNode(node.object);
    path = _interpreter.getCode(node.object);
  }

  // Then validate the current property access
  if (currentObj != null && node.property is Name) {
    String propertyName = (node.property as Name).value;
    if (currentObj is Map) {
      // For object literals, check if the property exists
      if (!currentObj.containsKey(propertyName)) {
        final availableProps = currentObj.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 "$path"',
          detailedError:
              'Code: ${_interpreter.getCode(node)}\nAvailable properties: ${availableProps.join(", ")}',
          recovery: recovery,
        );
      }
      // Update currentObj to the nested object for the next property access
      currentObj = currentObj[propertyName];
    } else {
      // For other types of objects, use the standard property validation
      validatePropertyOrMethodAccess(propertyName, path, currentObj, node);
    }
  }
}