visitModule()

in lib/generator.js [279:414]


  visitModule(ast, filepath, level) {
    assert.equal(ast.type, 'module');
    this.ast = ast;
    this.predefined = ast.models;
    this.usedExternException = ast.usedExternException;
    this.usedExternModel = ast.usedExternModel;
    this.parentModule = ast.extends;
    this.comments = ast.comments;
    this.notes = ast.notes;
    this.builtin = getBuiltin(this);
    ast.innerModule = new Map();

    this.clientName = new Map();
    this.packageInfo = {};
    this.fileBuffer = {};
    this.usedTypes = [];
    this.imports = [];
    if(this.overwrite(ast, filepath) === false) {
      return;
    }

    if(!this.className) {
      let clientName = this.config.clientName.replace(/(?:^|_)([a-z])/g, (_, c) => (c ? c.toUpperCase() : ''));
      this.className = clientName;
    }


    this.eachImport(ast.imports, ast.usedExternModel, ast.innerModule, filepath, level);

    const subModels = Object.keys(this.predefined).filter((key) => {
      return !key.startsWith('$') && this.predefined[key].type === 'model' && key.indexOf('.') !== -1;
    }).map((key) => {
      return this.predefined[key];
    });

    for (let i = 0; i < subModels.length; i++) {
      // sub model
      // TODO: 生成model class之前需要判断属性是否为自定义类型,如果属性是自定义类型,需要先定义自定义类型
      this.eachSubModel(subModels[i], level);
    }

    const models = ast.moduleBody.nodes.filter((item) => {
      return item.type === 'model';
    });

    this.modelBefore(ast, level);
    for (let i = 0; i < models.length; i++) {
      this.eachModel(models[i], level);
    }
    if (models.length > 0 || subModels.length > 0) {
      // 存一笔 models
      this.modelInitBefore(ast, level);
      this.visitModelInit(subModels.concat(models));
    }

    const exceptions = ast.moduleBody.nodes.filter((item) => {
      return item.type === 'exception';
    });

    
    if (exceptions.length > 0) {
      for (let i = 0; i < exceptions.length; i++) {
        this.eachException(exceptions[i], level);
      }
      this.visitExceptionInit(exceptions);
    }
    this.flushBuffer();


    this.visitModuleInit();
    this.moduleBefore(ast, level);

    this.visitAnnotation(ast.annotation, level);

   

    // models definition
    this.apiBefore(level);
    // TODO: 这个types里有type对应的类型,在这块加上一个非基础类型筛选,然后根据类型引入对应的模块
    const types = ast.moduleBody.nodes.filter((item) => {
      return item.type === 'type';
    });

    const inits = ast.moduleBody.nodes.filter((item) => {
      return item.type === 'init';
    });

    const [init] = inits;
    if (init) {
      this.visitInit(init, types, level);
    } else {
      // 没有 init 的时候,也要处理 types
      this.emit('\n');
      types.forEach((type) => {
        let comments = DSL.comment.getFrontComments(this.comments, type.tokenRange[0]);
        this.visitComments(comments, level + 2);
        this.emit(`${_snakeCase(_vid(type.vid))}: `, level + 2);
        this.visitType(type.value);
        this.emit(' = None\n');
      });
      this.emit('\n');
      this.emit(`    def __init__(self):
        pass\n`);
    }
    
    const apis = ast.moduleBody.nodes.filter((item) => {
      return item.type === 'api';
    });

    for (let i = 0; i < apis.length; i++) {
      // 每个API都需要 Tea.request import TeaRequest
      // from Tea.core import TeaCore
      // 但是不需要重复引入
      this.imports.push({
        className: `${CORE}Core`,
        packageName: 'darabonba.core'
      });
      this.eachAPI(apis[i], level + 2);
    }

    // this.functionBefore();
    const functions = ast.moduleBody.nodes.filter((item) => {
      return item.type === 'function';
    });

    for (let i = 0; i < functions.length; i++) {
      this.eachFunction(functions[i], level + 2);
    }

    if (this.config.exec) {
      this.emitExec();
    }
    // 最后处理import
    this.save(filepath);
    this.saveInnerModule(ast, filepath);
  }