generate method

Future<String> generate()

Implementation

Future<String> generate() async {
  timer.start('composer');
  try {
    output.writeSplit();
    output.writeLn('// generated by swift_composer at ${timer.starts.first}');
    output.writeLn(
      '// ignore common warnings in generated code, you can also exclude this file in analysis_options.yaml',
    );
    output.writeLn('// ignore_for_file: unnecessary_non_null_assertion');
    output.writeLn('// ignore_for_file: dead_null_aware_expression');
    output.writeSplit();
    timer.start('config');
    output.writeLn('// CONFIG');
    await _loadLibraryFiles();
    await _loadConfig();
    output.writeSplit();
    output.writeLn('// MERGED CONFIG');
    config.config.forEach((key, value) {
      output.writeLn("// $key: $value".replaceAll('\n', '\\n'));
    });
    output.writeSplit();
    timer.end();

    for (var importElement in library.element.firstFragment.libraryImports) {
      if (!importElement.importedLibrary!.isDartCore) {
        String prefix = importElement.prefix?.element.name ?? '';
        if (prefix.isNotEmpty) {
          prefix = '$prefix.';
        }
        importElement.namespace.definedNames2.forEach((key, value) {
          //output.writeLn('//' + key + ' ' + value.displayName + ' ' + value.getExtendedDisplayName() + " ${value.hashCode}");
        });
        //importedLibrariesMap[importElement!.importedLibrary!] = importElement.prefix == null ? null : importElement.prefix!.name;
        //output.writeLn('// import ' + (importElement.importedLibrary?.identifier ?? 'null') + (importElement.prefix == null ? '' : ' as ' + importElement.prefix!.name));

        importElement.namespace.definedNames2.forEach((name, element) {
          for (var metadataElement in element.metadata.annotations) {
            // TODO: if ComposeIfModule is checked here, Compose can also be checked here so non composed classes wont be registered?
            var annotation = metadataElement.toSource();
            if (annotation.startsWith('@ComposeIfModule(')) {
              var requireModule = annotation.substring(
                18,
                annotation.length - 2,
              );
              if (modules
                  .where((module) => module.name == requireModule)
                  .isEmpty) {
                output.writeLn(
                  '//type: ${element.name ?? 'NULL'} requires module: $requireModule but it is not imported. skipping',
                );
                return;
              }
            }
          }
          typeMap.registerClassElement(prefix + name, element);
        });
      }
    }
    for (var element in library.allElements) {
      (element.name != null)
          ? typeMap.registerClassElement(element.name!, element)
          : null;
    }

    //DEBUG INFO

    Map<String, TypeInfo>.from(typeMap.allTypes).forEach((key, value) {
      value.preAnaliseAllUsedTypes();
    });

    if (debug) {
      output.writeLn('// ALL TYPES INFO');
      output.writeSplit();
      typeMap.allTypes.forEach((key, value) {
        output.writeLn('// $key => ${value.debugInfo}');
      });
    }

    timer.start('interceptors');
    for (int i = 0; i < typeMap.allTypes.keys.length; i++) {
      TypeInfo type = typeMap.allTypes[typeMap.allTypes.keys.elementAt(i)]!;
      if (type.hasInterceptor() && !type.isNullable) {
        output.writeSplit();
        if (debug) {
          output.writeLn("// interceptor for [${type.uniqueName}]");
          await type.writeDebugInfo(output);
        }
        await type.generateInterceptor(output, this);
      } else {
        if (debug) {
          output.writeLn("// no interceptor for [${type.uniqueName}]");
          await type.writeDebugInfo(output);
        }
      }
    }
    timer.end();
    /*List<String> allTypes = [];
    allTypes.addAll(typeMap.allTypes.keys);
    for (var s in allTypes) {
      output.writeSplit();
      if (typeMap.allTypes[s]!.hasInterceptor()) {
          output.writeLn("//interceptor for [${typeMap.allTypes[s]!.fullName}]");
          await typeMap.allTypes[s]!.generateInterceptor(output, this);
      } else {
        output.writeLn("//no interceptor for [${typeMap.allTypes[s]!.fullName}]");
      }
    };*/
    timer.start('om');
    output.writeSplit();
    generateSubtypesOf();
    output.writeSplit();
    generateCompiledMethodsParts();
    output.writeSplit();
    generateObjectManager();
    timer.end();
  } catch (e, stacktrace) {
    output.writeLn(
      '/* unhandled code generator exception: \n$e\n$stacktrace*/',
    );
  }
  timer.start('index');
  await _buildWidgetsIndex();
  timer.end();
  timer.end();
  timer.print(output, debug);
  return output.getOutput();
}