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.inputFile.pascalName}.h',
        importType: ocImportTypeLocal),
    OCImport(fullImportName: 'Flutter/Flutter.h'),
    EmptyLine(),
    OCCustomNestedImports(module.inputFile, options,
        excludeImports: [typeUniCallback], methods: module.methods),
    EmptyLine(),
    ...OCClassUniCallback.genImplementationDeclarations(module.methods),
    EmptyLine(),
    ...OCClassUniCallback.genImplementationImplementation(module.methods,
        options: options),
    EmptyLine(),
    ...OCCollectionCloneFunction(methods: module.methods)
        .genCollectionFunction(),
    OCPredefinedFuncWrapResult(),
    EmptyLine(),
    OCFunction(
        functionName: '${module.name}Setup',
        isCFlavor: true,
        params: getSetupFuncParams(module.name),
        body: (depth) {
          final ret = <CodeUnit>[];

          for (final method in module.methods) {
            if (method.name == module.name) {
              continue;
            }

            ret.add(ScopeBlock(
                depth: depth + 1,
                body: (depth) {
                  final blockRet = <CodeUnit>[];
                  blockRet.add(OneLine(
                      depth: depth,
                      body: 'FlutterBasicMessageChannel *channel ='));
                  blockRet.add(OneLine(
                      depth: depth + 1, body: '[FlutterBasicMessageChannel'));
                  blockRet.add(OneLine(
                      depth: depth + 2,
                      body:
                          'messageChannelWithName:@"${makeChannelName(module, method)}"'));
                  blockRet.add(OneLine(
                      depth: depth + 2,
                      body: 'binaryMessenger:binaryMessenger];'));
                  blockRet.add(OneLine(depth: depth, body: 'if (api) {'));
                  blockRet.add(OneLine(
                      depth: depth + 1,
                      body:
                          '[channel setMessageHandler:^(id _Nullable message, FlutterReply reply) {'));
                  for (final param in method.parameters) {
                    final type = param.type.realType();
                    final name = param.name;

                    if (param.type.astType() == typeUniCallback) {
                      blockRet.add(OneLine(
                          depth: depth + 2,
                          body:
                              'NSString *${name}Name = [message objectForKey:@"$name"];'));
                      final className =
                          OCClassUniCallback.getName(method.name, name);
                      blockRet.add(OneLine(
                          depth: depth + 2,
                          body: '$className *$name = $className.new;'));
                      blockRet.add(OneLine(
                          depth: depth + 2,
                          body: '$name.callbackName = ${name}Name;'));
                      blockRet.add(OneLine(
                          depth: depth + 2,
                          body: '$name.binaryMessenger = binaryMessenger;'));
                    } else if (type != const AstVoid()) {
                      final decoded = type.convertOcJson2Obj(
                          vname: '[message objectForKey:@"$name"]');
                      blockRet.add(OneLine(
                          depth: depth + 2,
                          body:
                              '${OCReference(type).build()} $name = $decoded;'));
                    }
                  }

                  if (method.isAsync == true) {
                    final result = method.returnType.realType() is AstVoid
                        ? ''
                        : 'result';
                    final paramList = <OCFunctionCallRealParam>[];
                    paramList.addAll(method.parameters.map((param) =>
                        OCFunctionCallRealParam(param.name, param.name)));
                    paramList.add(OCFunctionCallRealParam(
                        'success',
                        AstLambda(
                            [Variable(method.returnType.realType(), result)],
                            const AstVoid(),
                            depth: depth + 2,
                            injectedOCCodes: (depth) => [
                                  OneLine(
                                      depth: depth,
                                      body:
                                          'reply(wrapResult(${method.returnType.realType().convertOcObj2Json('result')},nil));')
                                ]).ocType()));
                    if (method.ignoreError == false) {
                      paramList.add(OCFunctionCallRealParam(
                          'fail',
                          AstLambda([
                            Variable(AstCustomType(typeFlutterError), 'error')
                          ], const AstVoid(),
                              depth: depth + 2,
                              injectedOCCodes: (depth) => [
                                    OneLine(
                                        depth: depth,
                                        body: 'reply(wrapResult(nil,error));')
                                  ]).ocType()));
                    }
                    blockRet.add(OCFunctionCall(
                        depth: depth + 2,
                        instanceName: 'api',
                        functionName: method.name,
                        params: paramList));
                  } else {
                    blockRet.add(OneLine(
                        depth: depth + 2, body: 'FlutterError *error;'));

                    final paramList = <OCFunctionCallRealParam>[];
                    paramList.addAll(method.parameters.map((param) =>
                        OCFunctionCallRealParam(param.name, param.name)));
                    if (method.ignoreError == false) {
                      paramList
                          .add(OCFunctionCallRealParam('error', '&error'));
                    }
                    if (method.returnType is! AstVoid) {
                      blockRet.add(OneLine(
                          depth: depth + 2,
                          hasNewline: false,
                          body:
                              '${OCReference(method.returnType).build()} output = '));
                    }
                    blockRet.add(OCFunctionCall(
                        depth: (method.returnType is AstVoid) == true
                            ? depth + 2
                            : 0,
                        instanceName: 'api',
                        functionName: method.name,
                        ignoreError: true,
                        params: paramList));
                    blockRet.add(OneLine(
                        depth: depth + 2,
                        body:
                            'reply(wrapResult(${method.returnType.convertOcObj2Json('output')}, error));'));
                  }

                  blockRet.add(OneLine(depth: depth + 1, body: '}];'));
                  blockRet.add(OneLine(depth: depth, body: '} else {'));
                  blockRet.add(OneLine(
                      depth: depth + 1,
                      body: '[channel setMessageHandler:nil];'));
                  blockRet.add(OneLine(depth: depth, body: '}'));

                  return blockRet;
                }));
          }

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