ocSource static method

String ocSource(
  1. Module module,
  2. UniAPIOptions options
)

Implementation

static String ocSource(Module module, UniAPIOptions options) {
  return CodeTemplate(children: [
    CommentUniAPI(),
    EmptyLine(),
    OCImport(
        fullImportName: '${module.name}.h', importType: ocImportTypeLocal),
    OCImport(fullImportName: 'Flutter/Flutter.h'),
    EmptyLine(),
    OCCustomNestedImports(module.inputFile, options, methods: module.methods),
    EmptyLine(),
    ...OCCollectionCloneFunction(methods: module.methods)
        .genCollectionFunction(),
    OCClassDeclaration(
        className: module.name,
        isInterface: true,
        hasExtension: true,
        properties: [
          Variable(
            AstCustomType('id',
                generics: [AstCustomType('FlutterBinaryMessenger')]),
            'binaryMessenger',
          )
        ]),
    EmptyLine(),
    OCClassImplementation(
        className: module.name,
        injectOCCodeUnit: (depth) {
          final ret = <CodeUnit>[];

          // instance 方法
          ret.add(OneLine(depth: depth, body: '+ (instancetype)instance {'));
          ret.add(OneLine(
              depth: depth + 1,
              body: 'static ${module.name} *_instance = nil;'));
          ret.add(OneLine(
              depth: depth + 1, body: 'static dispatch_once_t onceToken;'));
          ret.add(OneLine(
              depth: depth + 1, body: 'dispatch_once(&onceToken, ^{'));
          ret.add(OneLine(
              depth: depth + 2,
              body: '_instance = [[${module.name} alloc] init];'));
          ret.add(OneLine(depth: depth + 1, body: '});'));
          ret.add(OneLine(depth: depth + 1, body: 'return _instance;'));
          ret.add(OneLine(depth: depth, body: '}'));
          ret.add(EmptyLine());

          // setup 方法
          ret.add(OneLine(
              depth: depth,
              body:
                  '+ (void)setup:(id<FlutterBinaryMessenger>)binaryMessenger {'));
          ret.add(OneLine(
              depth: depth + 1,
              body: '[[self instance] setBinaryMessenger:binaryMessenger];'));
          ret.add(OneLine(depth: depth, body: '}'));

          // 对每个模块方法进行封装
          for (final method in module.methods) {
            if (method.name == module.name) {
              continue;
            }

            // 在 FlutterModule 中,在生成的方法中,需要对方法签名进行修改
            final methodFixed = _transformFlutterModuleMethod(method);

            ret.add(OCFunction(
                depth: depth,
                functionName: methodFixed.name,
                params: methodFixed.parameters,
                isClassMethod: true,
                body: (depth) {
                  final funcBody = <CodeUnit>[];

                  funcBody.add(OneLine(
                      depth: depth + 1,
                      body: 'FlutterBasicMessageChannel *channel ='));
                  funcBody.add(OneLine(
                      depth: depth + 2, body: '[FlutterBasicMessageChannel'));
                  funcBody.add(OneLine(
                      depth: depth + 3,
                      body:
                          'messageChannelWithName:@"${makeChannelName(module, methodFixed)}"'));
                  funcBody.add(OneLine(
                      depth: depth + 3,
                      body:
                          'binaryMessenger:[[self instance] binaryMessenger]];'));
                  funcBody.add(EmptyLine());

                  funcBody.add(OneLine(depth: depth + 1, body: '// 数据处理'));
                  funcBody.add(OneLine(
                      depth: depth + 1,
                      body:
                          'NSDictionary *msg = [NSDictionary dictionaryWithObjectsAndKeys:'));

                  // 参数传递使用原方法(不带 block 的)
                  for (final param in method.parameters) {
                    funcBody.add(OneLine(
                        depth: depth + 2,
                        body:
                            '[self wrapNil:${param.type.convertOcObj2Json(param.name)}], @"${param.name}",'));
                  }
                  funcBody.add(OneLine(depth: depth + 2, body: 'nil];'));
                  funcBody.add(EmptyLine());

                  funcBody.add(OneLine(depth: depth + 1, body: '// 发送消息'));
                  // 判断返回类型也使用原方法,决定了时候有 block 调用
                  if (method.returnType is AstVoid) {
                    funcBody.add(OneLine(
                        depth: depth + 1,
                        body: '[channel sendMessage:msg];'));
                  } else {
                    funcBody.add(OneLine(
                        depth: depth + 1,
                        body:
                            '[channel sendMessage:msg reply:^(id  _Nullable reply) {'));
                    funcBody.add(OneLine(
                        depth: depth + 2,
                        body:
                            'if (reply && result) result(${method.returnType.realType().convertOcJson2Obj(vname: 'reply')});'));
                    funcBody.add(OneLine(depth: depth + 1, body: '}];'));
                  }

                  return funcBody;
                }));
            ret.add(EmptyLine());
          }

          // wrapNil 空值保护函数
          ret.add(OneLine(depth: depth, body: '+ (id)wrapNil:(id)value {'));
          ret.add(OneLine(
              depth: depth + 1,
              body: 'return value == nil ? [NSNull null] : value;'));
          ret.add(OneLine(depth: depth, body: '}'));

          return ret;
        })
  ]).build();
}