generateType method

Future<TypeDeclaration> generateType(
  1. TypeMirror typeMirror,
  2. Package package,
  3. String libraryUri
)

Generate type declaration with analyzer support

Implementation

Future<TypeDeclaration> generateType(mirrors.TypeMirror typeMirror, Package package, String libraryUri) async {
  // Handle type variables
  if (typeMirror is mirrors.TypeVariableMirror) {
    return await _generateTypeVariable(typeMirror, package, libraryUri);
  }

  // Handle dynamic and void
  if (typeMirror.runtimeType.toString() == 'dynamic') {
    return StandardTypeDeclaration(
      name: 'dynamic',
      type: dynamic,
      element: null,
      dartType: null,
      qualifiedName: _buildQualifiedName('dynamic', 'dart:core'),
      simpleName: 'dynamic',
      packageUri: 'dart:core',
      isNullable: false,
      kind: TypeKind.dynamicType,
      isPublic: true,
      isSynthetic: false,
    );
  }

  if (typeMirror.runtimeType.toString() == 'void') {
    return StandardTypeDeclaration(
      name: 'void',
      type: VoidType,
      element: null,
      dartType: null,
      qualifiedName: _buildQualifiedName('void', 'dart:core'),
      simpleName: 'void',
      packageUri: 'dart:core',
      isNullable: false,
      kind: TypeKind.voidType,
      isPublic: true,
      isSynthetic: false,
    );
  }

  Type runtimeType;
  try {
    runtimeType = typeMirror.hasReflectedType ? typeMirror.reflectedType : typeMirror.runtimeType;
  } catch (e) {
    runtimeType = typeMirror.runtimeType;
  }

  if (_typeCache.containsKey(runtimeType)) {
    return _typeCache[runtimeType]!;
  }

  final typeName = mirrors.MirrorSystem.getName(typeMirror.simpleName);

  // Get analyzer element for the type
  final typeElement = await _getTypeElement(typeName, Uri.parse(libraryUri));
  final dartType = typeElement != null ? (typeElement as InterfaceElement).thisType : null;

  if (_isRecordType(runtimeType)) {
    return await _generateRecordType(typeMirror, typeElement, package, libraryUri);
  }

  // Handle primitive types
  if (_isPrimitiveType(runtimeType)) {
    return StandardTypeDeclaration(
      name: typeName,
      type: runtimeType,
      element: typeElement,
      dartType: dartType,
      qualifiedName: _buildQualifiedName(typeName, 'dart:core'),
      simpleName: typeName,
      packageUri: 'dart:core',
      isNullable: false,
      kind: TypeKind.primitiveType,
      isPublic: !_isInternal(typeName),
      isSynthetic: _isSynthetic(typeName),
    );
  }

  // Extract type arguments with analyzer support - now as LinkDeclarations
  final typeArguments = <LinkDeclaration>[];
  if (typeMirror is mirrors.ClassMirror && typeMirror.typeArguments.isNotEmpty) {
    for (final arg in typeMirror.typeArguments) {
      final argLink = await _generateLinkDeclarationFromMirror(arg, package, libraryUri);
      if (argLink != null) {
        typeArguments.add(argLink);
      }
    }
  }

  // Determine type kind
  final kind = _determineTypeKind(typeMirror, dartType);

  final declaration = StandardTypeDeclaration(
    name: typeName,
    type: runtimeType,
    element: typeElement,
    dartType: dartType,
    qualifiedName: _buildQualifiedName(typeName, libraryUri),
    simpleName: typeName,
    packageUri: libraryUri,
    isNullable: false,
    kind: kind,
    typeArguments: typeArguments,
    isPublic: !_isInternal(typeName),
    isSynthetic: _isSynthetic(typeName),
  );

  _typeCache[runtimeType] = declaration;
  return declaration;
}