emitClass()

in src/langs/cpp/combinator.js [312:400]


  emitClass(emitter, object) {
    /***************************** initialize include list and class name ******************************/
    this.includeList = this.includeList.concat(object.includeList);
    this.includeModelList = this.includeModelList.concat(object.includeModelList);
    const className = object.name.split('.').map(item => _upperFirst(item)).join('');

    /***************************** emit class header ******************************/
    emitter.emit(`class ${className} `);
    if (object.type === 'model') {
      emitter.emit(`: public ${this.config.tea.model.name} `);
    } else if (object.extends.length) {
      emitter.emit(`: ${this.resolveName(object.extends[0])} `);
    }
    emitter.emitln('{');

    /***************************** emit class body ******************************/

    // emit common constructer
    let hasConstruct = false;
    if (object.type === 'model') {
      hasConstruct = true;
    }
    emitter.emitln('public:', this.level);
    this.levelUp();

    // emit child nodes
    object.body.forEach(node => {
      if (is.prop(node)) {
        // emit properties
        emitter.emitln(`shared_ptr<${this.emitType(node.type)}> ${_avoidKeywords(node.name)}{};`, this.level);
      } else if (is.annotation(node)) {
        // emit annotation
        this.emitAnnotation(emitter, node);
      } else if (is.func(node)) {
        let modify = _modify(node.modify);
        let returnType = this.emitType(node.return[0], true);
        let func_name = _avoidKeywords(node.name);
        if (this.config.exec && func_name === 'main') {
          return;
        }
        if (modify) {
          emitter.emit(`${modify} ${returnType} ${func_name}(`, this.level);
        } else {
          emitter.emit(`${returnType} ${func_name}(`, this.level);
        }
        this.emitParams(emitter, node.params);
        emitter.emitln(');');
      } else if (is.construct(node)) {
        // emit custom constructer
        if (node.params.length) {
          emitter.emit(`explicit ${className}(`, this.level);
          let tmp = [];
          node.params.forEach(param => {
            tmp.push(`const shared_ptr<${this.emitType(param.type, true)}>& ${_avoidKeywords(param.key)}`);
            this.addStatement(param.key, param.type, true);
          });
          let emit = new Emitter(this.config);
          let str;
          if (tmp.length > 3) {
            let curr_row_len = emitter.currRow().length;
            str = tmp.join(`,${emit.eol}${' '.repeat(curr_row_len)}`);
          } else {
            str = tmp.join(', ');
          }
          emitter.emit(str);
          emitter.emit(')');
        } else {
          emitter.emit(`${className}()`, this.level);
        }
        emitter.emitln(';');
        hasConstruct = true;
      }
    });

    if (object.type === 'model') {
      emitter.emitln();
      this.emitModelFunc(emitter, className, object);
    }
    emitter.emitln();
    if (!hasConstruct) {
      emitter.emitln(`${className}() {};`, this.level);
    }
    emitter.emitln(`virtual ~${className}() = default;`, this.level);

    this.levelDown();

    /***************************** emit class footer ******************************/
    emitter.emitln('};');
  }