visitTry()

in lib/common_generator.js [660:1138]


  visitTry(ast, isAsync, level) {
    this.emit('try {\n', level);
    this.visitStmts(ast.tryBlock, isAsync, level + 1);
    this.emit('}', level);
    if (ast.catchBlock && ast.catchBlock.stmts.length > 0) {
      let errorName = _name(ast.catchId);
      this.emit(` catch (TeaException ${errorName}) {\n`);
      this.visitStmts(ast.catchBlock, isAsync, level + 1);
      this.emit(`} catch (Exception _${errorName}) {`, level);
      this.emit('\n');
      this.emit(`TeaException ${errorName} = new TeaException(_${errorName}.getMessage(), _${errorName});\n`, level + 1);
      this.visitStmts(ast.catchBlock, isAsync, level + 1);
      this.emit('}', level);
    }

    if (ast.finallyBlock && ast.finallyBlock.stmts.length > 0) {
      this.emit(' finally {\n');
      this.visitStmts(ast.finallyBlock, isAsync, level + 1);
      this.emit('}', level);
    }
    this.emit('\n', level);
  }

  visitParams(ast) {
    assert.equal(ast.type, 'params');
    this.emit('(');
    for (var i = 0; i < ast.params.length; i++) {
      if (i !== 0) {
        this.emit(', ');
      }
      const node = ast.params[i];
      assert.equal(node.type, 'param');
      this.visitType(node.paramType);
      this.emit(` ${avoidReserveName(_name(node.paramName))}`);
    }

    this.emit(')');
  }

  visitPureParams(ast) {
    assert.equal(ast.type, 'params');
    for (var i = 0; i < ast.params.length; i++) {
      if (i !== 0) {
        this.emit(', ');
      }
      const node = ast.params[i];
      assert.equal(node.type, 'param');
      this.visitType(node.paramType);
      this.emit(` ${avoidReserveName(_name(node.paramName))}`);
    }
  }

  getSubFieldClassName(className, hasModel) {
    if (className.indexOf('.') > 0) {
      var names = className.split('.');
      var name = '';
      if (hasModel) {
        name = names[0] + '.';
      }
      name += _subModelName(className, this.ctx.conflictModelNameMap, this.ctx.allModleNameMap);
      return name;
    }
    return className;
  }

  getSubModelClassName(names, index, currentName) {
    if (index < names.length) {
      names[index] = currentName + _upperFirst(names[index]);
      return this.getSubModelClassName(names, index + 1, names[index]);
    }
    return names.join('.');
  }

  visitAnnotation(annotation, level) {
    if (!annotation || !annotation.value) {
      if (this.ast.modelName) {
        const modelName = _name(this.ast.modelName);
        this.emitln(`/**`, level);
        this.emitln(` * `, level);
        this.emitln(` * {@link ${this.ast.title ? this.ast.title : modelName}} extends {@link ${this.ctx.isRequestModel ? 'RequestModel' : 'TeaModel'}}`, level);
        this.emitln(` *`, level);
        this.emitln(` * <p>${this.ast.title ? this.ast.title : modelName}</p>`, level);
        this.emitln(` */`, level);
      }
      return;
    }
    let comments = DSL.comment.getFrontComments(this.ctx.comments, annotation.index);
    this.visitComments(comments, level);
    var node = Annotation.parse(annotation.value);
    var description = node.items.find((item) => {
      return item.type === 'description';
    });
    var summary = node.items.find((item) => {
      return item.type === 'summary';
    });
    var _return = node.items.find((item) => {
      return item.type === 'return';
    });
    var deprecated = node.items.find((item) => {
      return item.type === 'deprecated';
    });
    var params = node.items.filter((item) => {
      return item.type === 'param';
    }).map((item) => {
      return {
        name: item.name.id,
        text: item.text.text.trimEnd()
      };
    });
    var throws = node.items.filter((item) => {
      return item.type === 'throws';
    }).map((item) => {
      return item.text.text.trimEnd();
    });

    let hasNextSection = false;
    this.emitln(`/**`, level);
    const descriptionText = description ? description.text.text : '';
    const summaryText = summary ? summary.text.text : '';
    const returnText = _return ? _return.text.text.trimEnd() : '';
    if (summaryText !== '') {
      if (hasNextSection) {
        this.emitln(` * `, level);
      }
      this.emitln(` * <b>summary</b> : `, level);
      const summaryTexts = md2Html(summaryText).trimEnd();
      summaryTexts.split('\n').forEach((line) => {
        this.emitln(` * ${line}`, level);
      });
      hasNextSection = true;
    }
    if (descriptionText !== '') {
      this.emitln(` * <b>description</b> :`, level);
      const descriptionTexts = md2Html(descriptionText).trimEnd();
      descriptionTexts.split('\n').forEach((line) => {
        this.emitln(` * ${line}`, level);
      });
      hasNextSection = true;
    }
    if (deprecated) {
      if (hasNextSection) {
        this.emitln(` * `, level);
      }
      const deprecatedText = deprecated.text.text.trimEnd();
      this.emit(` * @deprecated `, level);
      deprecatedText.split('\n').forEach((line, index) => {
        if (index === 0) {
          this.emitln(`${line}`);
        } else {
          this.emitln(` * ${line}`, level);
        }
      });
      hasNextSection = true;
    }
    if (params.length > 0) {
      if (hasNextSection) {
        this.emitln(` * `, level);
      }
      params.forEach((item) => {
        this.emit(` * @param ${item.name} `, level);
        const items = item.text.trimEnd().split('\n');
        items.forEach((line, index) => {
          if (index === 0) {
            this.emitln(`${line}`);
          } else {
            this.emitln(` * ${line}`, level);
          }
        });
      });
      hasNextSection = true;
    }
    if (returnText !== '') {
      this.emit(` * @return `, level);
      const returns = returnText.split('\n');
      returns.forEach((line, index) => {
        if (index === 0) {
          this.emitln(`${line}`);
        } else {
          this.emitln(` * ${line}`, level);
        }
      });
      hasNextSection = true;
    }
    if (throws.length > 0) {
      if (hasNextSection) {
        this.emitln(` * `, level);
      }
      throws.forEach((item) => {
        this.emit(` * @throws `, level);
        const items = item.trimEnd().split('\n');
        items.forEach((line, index) => {
          if (index === 0) {
            this.emitln(`${line}`);
          } else {
            this.emitln(` * ${line}`, level);
          }
        });
      });
    }

    if (this.ast.modelName) {
      const modelName = _name(this.ast.modelName);
      this.emitln(` * `, level);
      this.emitln(` * {@link ${this.ast.title ? this.ast.title : modelName}} extends {@link ${this.ctx.isRequestModel ? 'RequestModel' : 'TeaModel'}}`, level);
      this.emitln(` *`, level);
      this.emitln(` * <p>${this.ast.title ? this.ast.title : modelName}</p>`, level);
    }

    this.emitln(` */`, level);
    if (deprecated) {
      this.emitln(`@Deprecated`, level);
    }
  }

  visitObjectFieldValue(ast, level) {
    this.visitExpr(ast, level);
  }

  visitObjectField(ast, level) {
    let comments = DSL.comment.getFrontComments(this.ctx.comments, ast.tokenRange[0]);
    this.visitComments(comments, level);
    if (ast.type === 'objectField') {
      if (typeof ast.fieldName.string !== 'undefined') {
        this.emit(`new TeaPair("${_string(ast.fieldName)}", `, level);
      } else {
        this.emit(`new TeaPair("${_name(ast.fieldName)}", `, level);
      }
      this.visitObjectFieldValue(ast.expr, level);
    } else {
      throw new Error('unimpelemented');
    }
    this.emit(')');
  }

  visitObject(ast, level) {
    assert.equal(ast.type, 'object');
    if (ast.fields.length === 0) {
      this.emit('new java.util.HashMap<>()');
      return;
    }
    var hasExpandField = false;
    var hasNotExpandField = false;
    for (let i = 0; i < ast.fields.length; i++) {
      const field = ast.fields[i];
      if (field.type === 'expandField') {
        hasExpandField = true;
        break;
      } else {
        hasNotExpandField = true;
      }
    }

    if (!hasExpandField) {
      this.emit('CommonUtil.buildMap(\n');
      for (let i = 0; i < ast.fields.length; i++) {
        this.visitObjectField(ast.fields[i], level + 1);
        if (i < ast.fields.length - 1) {
          this.emit(',');
        }
        this.emit('\n');
      }
      this.emit(')', level);
      return;
    }

    var all = [];
    // 分段
    var current = [];
    for (let i = 0; i < ast.fields.length; i++) {
      const field = ast.fields[i];
      if (field.type === 'objectField') {
        current.push(field);
      } else {
        if (current.length > 0) {
          all.push(current);
        }
        all.push(field);
        current = [];
      }
    }

    if (current.length > 0) {
      all.push(current);
    }

    this.emit('CommonUtil.merge(');
    if (ast.inferred && ast.inferred.valueType.name === 'string') {
      this.emit('String.class');
    } else {
      this.emit('Object.class');
    }
    var hasExpandFieldBuildMap = false;
    if (hasExpandField && hasNotExpandField) {
      hasExpandFieldBuildMap = true;
      this.emit(',\n');
      this.emit('CommonUtil.buildMap(\n', level + 1);
    } else {
      this.emit(',\n');
    }

    for (let i = 0; i < all.length; i++) {
      const item = all[i];
      if (Array.isArray(item)) {
        for (var j = 0; j < item.length; j++) {
          this.visitObjectField(item[j], level + 2);
          if (item[j + 1]) {
            this.emit(',\n');
          } else {
            this.emit('\n');
          }
        }
      } else {
        this.emit('', level + 1);
        this.visitExpr(item.expr, level);
        if (all[i + 1]) {
          this.emit(',');
        }
        this.emit('\n');
      }
      if (hasExpandFieldBuildMap) {
        this.emit(')', level + 1);
        if (all[i + 1]) {
          this.emit(',\n');
        } else {
          this.emit('\n');
        }
        hasExpandFieldBuildMap = false;
      }
    }
    this.emit(')', level);
  }

  visitFieldType(value, node, modelName, useEnum) {
    if (value.fieldType === 'array') {
      // basic type
      this.emit(`java.util.List < `);
      if (value.fieldItemType.tag === 8) {
        this.emit(`${collectionType(_type(value.fieldItemType.lexeme))} `);
      } else if (value.fieldItemType.type === 'map') {
        this.visitType(value.fieldItemType);
      } else if (value.fieldItemType.fieldType === 'array') {
        this.visitFieldType(value.fieldItemType, node, modelName);
      } else {
        if (node.fieldValue.itemType) {
          this.emit(_subModelName(node.fieldValue.itemType, this.ctx.conflictModelNameMap, this.ctx.allModleNameMap));
        } else {
          this.emit(`${_name(node.fieldValue.fieldItemType)} `);
        }
      }
      this.emit(`> `);
    } else if (value.fieldType === 'map') {
      this.emit(`java.util.Map < ${collectionType(_type(value.keyType.lexeme))}, `);
      if (value.valueType.type) {
        this.visitType(value.valueType);
      } else {
        this.emit(`${collectionType(_type(value.valueType.lexeme))} `);
      }
      this.emit('> ');
    } else if (typeof value.fieldType === 'string') {
      this.emit(`${_type(value.fieldType)} `);
    } else if (value.fieldType) {
      if (value.fieldType.idType && value.fieldType.idType === 'module') {
        var className = this.ctx.imports[`${_type(value.fieldType.lexeme)}`].className || 'DefaultAsyncClient';
        this.emit(this.ctx.imports[`${_type(value.fieldType.lexeme)}`].package);
        this.emit(`.${className} `);
      } else if (value.fieldType.type && value.fieldType.type === 'moduleModel') {
        this.emit(this.ctx.imports[_name(value.fieldType.path[0])].package);
        this.emit(`.models.${_name(value.fieldType.path[1])} `);
      } else if (value.fieldType.idType && value.fieldType.idType === 'enum') {
        if (useEnum) {
          this.emit(`${_type(value.fieldType.lexeme)} `);
        } else {
          this.emit(`${_type(this.ctx.enumMap[value.fieldType.lexeme])} `);
        }
      } else {
        this.emit(`${_type(value.fieldType.lexeme)} `);
      }
    } else {
      this.emit(_subModelName([modelName, _name(node.fieldName)].join('.'), this.ctx.conflictModelNameMap, this.ctx.allModleNameMap));
      this.emit(' ');
    }
  }

  visitType(ast, isSubType = false) {
    if (ast.type === 'map') {
      this.emit(`java.util.Map<`);
      this.visitType(ast.keyType, true);
      this.emit(`, `);
      this.visitType(ast.valueType, true);
      this.emit(`>`);
    } else if (ast.type === 'array') {
      this.emit(`java.util.List<`);
      this.visitType(ast.subType || ast.itemType, true);
      this.emit(`>`);
    } else if (ast.type === 'model') {
      if (ast.moduleName) {
        const modelMap = `${ast.moduleName}:${_name(ast)}`;
        if (this.ctx.conflictModels.get(modelMap)) {
          this.emit(`${this.ctx.imports[ast.moduleName].package}.models.`);
        }
      } else {
        const modelMap = `${_name(ast)}`;
        if (this.ctx.conflictModels.get(modelMap)) {
          this.emit(`${this.ctx.package}.models.`);
        }
      }
      this.emit(`${_type(this.getSubFieldClassName(ast.name, true))}`);
    } else if (ast.type === 'subModel') {
      let className = '';
      for (let i = 0; i < ast.path.length; i++) {
        const item = ast.path[i];
        if (i > 0) {
          className += '.';
        }
        className += item.lexeme;
      }
      let resultName = this.getSubModelClassName(className.split('.'), 0, '');
      this.emit(resultName);
    } else if (ast.type === 'moduleModel') {
      const [moduleId, ...rest] = ast.path;
      let pathName = rest.map((item) => {
        return item.lexeme;
      }).join('.');
      let subModelName = '';
      if (rest.length > 1) {
        subModelName = `.${_subModelName(pathName, this.ctx.conflictModelNameMap, this.ctx.allModleNameMap)}`;
      }
      var modelName = rest[0].lexeme;
      var moduleName = moduleId.lexeme;
      var packageName = `${this.ctx.imports[moduleName].package}.models.`;
      const checkModel = moduleName + ':' + pathName;
      if (this.ctx.conflictModels.get(checkModel)) {
        this.emit(packageName + modelName + subModelName);
      } else {
        this.emit(modelName + subModelName);
      }
    } else if (ast.type === 'basic') {
      this.emit(_type(ast.name));
    } else if (this.ctx.predefined && this.ctx.predefined[`module:${_name(ast)}`]) {
      var className = this.ctx.imports[ast.lexeme || ast.name].className || 'DefaultAsyncClient';
      this.emit(`${this.ctx.imports[_name(ast)]}.${className}`);
    } else if (ast.idType === 'module') {
      let className = this.ctx.imports[ast.lexeme || ast.name].className;
      if (this.ctx.conflictModels.get(className) && this.ctx.conflictModels.get(className) !== this.ctx.imports[ast.lexeme].package) {
        this.emit(`${this.ctx.imports[ast.lexeme || ast.name].package}.${className}`);
      } else {
        if (!this.ctx.conflictModels.get(className)) {
          this.ctx.conflictModels.set(className, this.ctx.imports[ast.lexeme || ast.name].package);
        }
        this.emit(className);
      }
    } else if (ast.idType === 'model') {
      const modelMap = `${_name(ast)}`;
      if (this.ctx.conflictModels.get(modelMap)) {
        this.emit(`${this.ctx.package}.models.`);
      }
      this.emit(modelMap);
    } else if (ast.type === 'module_instance') {
      let className = this.ctx.imports[ast.lexeme || ast.name].className;
      if (this.ctx.conflictModels.get(className) && this.ctx.conflictModels.get(className) !== this.ctx.imports[ast.lexeme].package) {
        this.emit(`${this.ctx.imports[ast.lexeme || ast.name].package}.${className}`);
      } else {
        if (!this.ctx.conflictModels.get(className)) {
          this.ctx.conflictModels.set(className, this.ctx.imports[ast.lexeme || ast.name].package);
        }
        this.emit(className);
      }
    } else if (ast.type === 'iterator') {
      this.emit(`ResponseIterable<${_type(ast.valueType.lexeme || ast.valueType.name)}>`);
    } else {
      if (isSubType) {
        this.emit(collectionType(_type(ast.lexeme || ast.name)));
      } else {
        this.emit(_type(ast.lexeme || ast.name));
      }
    }
  }

}