visitClassDeclaration method

  1. @override
void visitClassDeclaration(
  1. SClassDeclaration node
)
override

Implementation

@override
void visitClassDeclaration(SClassDeclaration node) {
  final className = node.name?.name ?? '';
  if (environment.isDefinedLocally(className)) {
    return;
  }

  // Extract type parameter information
  final typeParameters = node.typeParameters;
  Environment? tempEnvironment;

  if (typeParameters != null) {
    Logger.debug(
        "[DeclarationVisitor.visitClassDeclaration] Class '$className' has ${typeParameters.typeParameters.length} type parameters");

    // Create a temporary environment for type resolution
    tempEnvironment = Environment(enclosing: environment);

    // Create temporary type parameter placeholders
    for (final typeParam in typeParameters.typeParameters) {
      final paramName = typeParam.name?.name ?? '';
      final typeParamPlaceholder = TypeParameter(paramName);
      tempEnvironment.define(paramName, typeParamPlaceholder);

      Logger.debug(
          "[DeclarationVisitor.visitClassDeclaration]   Defined type parameter '$paramName' in temp environment");
    }
  }

  // Use the temp environment (if any) for type resolution
  final resolveEnvironment = tempEnvironment ?? environment;

  // Extract type parameter names and bounds
  final typeParameterNames =
      InterpretedClass.extractTypeParameterNames(typeParameters);
  final typeParameterBounds = InterpretedClass.extractTypeParameterBounds(
      typeParameters, resolveEnvironment);

  // Create a placeholder for the class with the required positional arguments
  final placeholder = InterpretedClass(
    className, // name
    null, // superclass (initialized to null)
    environment, // classDefinitionEnvironment
    <SFieldDeclaration>[], // fieldDeclarations (initially empty)
    // Member tables use FrozenNameMap (perf T6): mutable while wiring, then
    // frozen via klass.freezeMemberTables() at the end of the Pass-2 loop.
    FrozenNameMap<InterpretedFunction>(), // methods
    FrozenNameMap<InterpretedFunction>(), // getters
    FrozenNameMap<InterpretedFunction>(), // setters
    FrozenNameMap<InterpretedFunction>(), // staticMethods
    FrozenNameMap<InterpretedFunction>(), // staticGetters
    FrozenNameMap<InterpretedFunction>(), // staticSetters
    <String, Object?>{}, // staticFields (deferred init — left mutable)
    FrozenNameMap<InterpretedFunction>(), // constructors
    FrozenNameMap<InterpretedFunction>(), // operators
    // Named parameters
    isAbstract: node.isAbstract,
    isMixin: node.isMixin, // 'mixin class' declaration
    interfaces: [], // Initially empty
    onClauseTypes: [], // Initially empty
    mixins: [], // Initially empty
    // Read modifiers from AST node
    isFinal: node.isFinal,
    isInterface: node.isInterface,
    isBase: node.isBase,
    isSealed: node.isSealed,
    // Add type parameter information
    typeParameterNames: typeParameterNames,
    typeParameterBounds: typeParameterBounds,
  );
  environment.define(className, placeholder);
  Logger.debug(
      "[DeclarationVisitor] Defined placeholder for class '$className' in env: ${environment.hashCode}");
}