in lib/generator.js [1014:1346]
eachSubModel(ast, level) {
assert.equal(ast.type, 'model');
const modelName = _name(ast.modelName);
this.visitAnnotation(ast.annotation, level);
this.emit(`public static class ${_subModelName(modelName, this.conflictModelNameMap, this.allModleNameMap, this.enableMinimizeModelName)} extends TeaModel {\n`, level);
this.visitModelBody(ast.modelBody, level + 1, modelName);
this.visitBuildMethod(ast, level + 1);
this.createGetSetMethod(ast.modelBody, level + 1, modelName);
this.emit('}\n\n', level);
}
visitObjectFieldValue(ast, level) {
this.visitExpr(ast, level);
}
visitObjectField(ast, level) {
let comments = DSL.comment.getFrontComments(this.comments, ast.tokenRange[0]);
this.visitComments(comments, level);
if (ast.type === 'objectField') {
var key = _escape(_name(ast.fieldName) || _string(ast.fieldName));
this.emit(`new TeaPair("${key}", `, 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('TeaConverter.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('TeaConverter.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('TeaConverter.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);
}
visitCall(ast, level) {
assert.equal(ast.type, 'call');
if (ast.left.type === 'method_call') {
this.visitMethodCall(ast, level);
} else if (ast.left.type === 'instance_call') {
this.visitInstanceCall(ast, level);
} else if (ast.left.type === 'static_call') {
this.visitStaticCall(ast, level);
} else {
throw new Error('unimplemented');
}
}
visitStaticCall(ast, level) {
assert.equal(ast.left.type, 'static_call');
var className = this.imports[ast.left.id.lexeme].className || 'Client';
this.emit(`${this.imports[ast.left.id.lexeme].package}.${className}.${_name(ast.left.propertyPath[0])}(`);
for (let i = 0; i < ast.args.length; i++) {
const expr = ast.args[i];
if (expr.needCast) {
this.emit('TeaModel.buildMap(');
}
this.visitExpr(expr, level);
if (expr.needCast) {
this.emit(')');
}
if (i !== ast.args.length - 1) {
this.emit(', ');
}
}
this.emit(')');
}
visitInstanceCall(ast, level) {
assert.equal(ast.left.type, 'instance_call');
const method = ast.left.propertyPath[0];
var id = _name(ast.left.id);
if (id.indexOf('@') > -1) {
id = `_${_lowerFirst(id.substr(1))}`;
}
this.emit(`${id}.${_name(method)}(`);
for (let i = 0; i < ast.args.length; i++) {
const expr = ast.args[i];
this.visitExpr(expr, level);
if (i !== ast.args.length - 1) {
this.emit(', ');
}
}
this.emit(')');
}
visitMethodCall(ast, level) {
assert.equal(ast.left.type, 'method_call');
if (ast.isStatic) {
var className = this.className || 'Client';
this.emit(`${className}.${_name(ast.left.id)}(`);
} else {
this.emit(`this.${_name(ast.left.id)}(`);
}
for (let i = 0; i < ast.args.length; i++) {
const expr = ast.args[i];
if (expr.needCast) {
this.emit('TeaModel.buildMap(');
}
this.visitExpr(expr, level);
if (expr.needCast) {
this.emit(')');
}
if (i !== ast.args.length - 1) {
this.emit(', ');
}
}
this.emit(')');
}
visitPropertyAccess(ast) {
assert.equal(ast.type, 'property_access');
var id = _name(ast.id);
var expr = '';
if (id === '__response') {
expr += RESPONSE;
} else if (id === '__request') {
expr += REQUEST;
} else {
expr += avoidReserveName(id);
}
var current = ast.id.inferred;
for (var i = 0; i < ast.propertyPath.length; i++) {
var name = _name(ast.propertyPath[i]);
if (current.type === 'model') {
expr += `.${name}`;
} else {
expr += `.get("${name}")`;
}
current = ast.propertyPathTypes[i];
}
this.emit(expr);
}
emitNumber(ast, level) {
this.emit(ast.value.value, level);
if (ast.value.type === 'long') {
this.emit('L');
}
if (ast.value.type === 'double') {
this.emit('D');
}
if (ast.value.type === 'float') {
this.emit('F');
}
}
visitExpr(ast, level) {
if (ast.type === 'boolean') {
this.emit(`${ast.value}`);
} else if (ast.type === 'property_access') {
this.visitPropertyAccess(ast, level);
} else if (ast.type === 'string') {
this.emit(`"${ast.value.string.replace(new RegExp('"', 'g'), '\\"')}"`);
} else if (ast.type === 'null') {
this.emit('null');
} else if (ast.type === 'number') {
this.emitNumber(ast);
} else if (ast.type === 'object') {
this.visitObject(ast, level);
} else if (ast.type === 'variable') {
var id = _name(ast.id);
if (id === '__response') {
this.emit(RESPONSE);
} else if (id === '__request') {
this.emit(REQUEST);
} else if (ast.inferred && ast.inferred.name === 'class') {
this.emit(avoidReserveName(id) + '.class');
} else {
this.emit(avoidReserveName(id));
}
} else if (ast.type === 'virtualVariable') {
const vid = `_${_lowerFirst(_name(ast.vid).substr(1))}`;
this.emit(`${vid}`);
} else if (ast.type === 'template_string') {
for (let i = 0; i < ast.elements.length; i++) {
var item = ast.elements[i];
if (item.type === 'element') {
this.emit('"');
this.emit(item.value.string);
this.emit('"');
} else if (item.type === 'expr') {
if (item.expr.type === 'property_access' && _name(item.expr.id) === '__module') {
var value = this.__module;
for (let i = 0; i < item.expr.propertyPath.length; i++) {
value = value[_name(item.expr.propertyPath[i])];
}
this.emit('"');
this.emit(value);
this.emit('"');
} else {
this.visitExpr(item.expr, level);
}
} else {
throw new Error('unimpelemented');
}
if (i < ast.elements.length - 1) {
this.emit(' + ');
}
}
} else if (ast.type === 'call') {
this.visitCall(ast, level);
} else if (ast.type === 'construct') {
this.visitConstruct(ast, level);
} else if (ast.type === 'array') {
this.visitArray(ast, level);
} else if (ast.type === 'and') {
this.visitExpr(ast.left, level);
this.emit(' && ');
this.visitExpr(ast.right, level);
} else if (ast.type === 'or') {
this.visitExpr(ast.left, level);
this.emit(' || ');
this.visitExpr(ast.right, level);
} else if (ast.type === 'null') {
this.emit('null');
} else if (ast.type === 'not') {
this.emit('!');
this.visitExpr(ast.expr, level);
} else if (ast.type === 'construct_model') {
this.visitConstructModel(ast, level);
} else if (ast.type === 'super') {
this.emit('super(');
if (ast.args) {
for (let i = 0; i < ast.args.length; i++) {
if (i > 0) {
this.emit(', ');
}
this.visitExpr(ast.args[i], level);
}
}
this.emit(')');
} else if (ast.type === 'map_access') {
this.visitMapAccess(ast, true);
} else if (ast.type === 'array_access') {
this.visitArrayAccess(ast, true);
} else {
throw new Error('unimpelemented');
}
}