lib/enum_generator.js (86 lines of code) (raw):
/* eslint-disable max-len */
'use strict';
const assert = require('assert');
const DSL = require('@darabonba/parser');
const { _name, _type, getEnumAttr } = require('./util');
const CommonGenerator = require('./common_generator');
class Generator extends CommonGenerator {
constructor(ast, ctx) {
super(ast, ctx);
}
codegen(level = 0) {
const enumType = _type(this.ast.enumType.lexeme);
const enumName = this.ast.enumName.lexeme;
this.emitHeader(enumName, level);
this.emitEnumBody(this.ast.enumBody, enumType, level + 1);
this.emitConstructor(enumName, enumType, level + 1);
this.emitln();
this.emitGetters(enumType, level + 1);
this.emitln();
this.emitln('}', level);
}
emitHeader(enumName, level) {
this.emitln(`// This file is auto-generated, don't edit it. Thanks.`, level);
this.emitln(`package ${this.ctx.package}.models;`, level);
this.emitln();
this.emitln(`@com.aliyun.core.annotation.EnumType`, level);
this.emitln(`public enum ${enumName} {`, level);
this.emitln();
}
emitEnumBody(ast, enumType, level) {
assert.equal(ast.type, 'enumBody');
let node;
for (let i = 0; i < ast.nodes.length; i++) {
node = ast.nodes[i];
let comments = DSL.comment.getFrontComments(this.ctx.comments, node.tokenRange[0]);
this.visitComments(comments, level);
const fieldName = _name(node.fieldName);
const value = getEnumAttr(node, 'value') || fieldName;
const description = getEnumAttr(node, 'description');
if (enumType === 'String') {
this.emit(`${fieldName}("${value}"`, level);
} else if (enumType === 'Number' || enumType === 'Integer') {
this.emit(`${fieldName}(${value}`, level);
} else if (enumType === 'Long') {
this.emit(`${fieldName}(${value}L`, level);
} else if (enumType === 'Float') {
this.emit(`${fieldName}(${value}F`, level);
} else if (enumType === 'Double') {
this.emit(`${fieldName}(${value}D`, level);
}
this.emit(`, "${description}")`);
this.emitln(`,`);
this.emitln();
}
this.emitln(`UNKNOWN_VALUE(null, "UNKNOWN_VALUE");`, level);
this.emitln();
if (node) {
//find the last node's back comment
let comments = DSL.comment.getBetweenComments(this.ctx.comments, node.tokenRange[0], ast.tokenRange[1]);
this.visitComments(comments, level);
}
if (ast.nodes.length === 0) {
//empty block's comment
let comments = DSL.comment.getBetweenComments(this.ctx.comments, ast.tokenRange[0], ast.tokenRange[1]);
this.visitComments(comments, level);
}
}
emitConstructor(enumName, enumType, level) {
this.emitln(`private ${enumType} value;`, level);
this.emitln(`private String description;`, level);
this.emitln();
this.emitln(`${enumName}(${enumType} value, String description) {`, level);
this.emitln(`this.value = value;`, level + 1);
this.emitln(`this.description = description;`, level + 1);
this.emitln(`}`, level);
}
emitGetters(enumType, level) {
this.emit('public ', level);
this.emitln(`${enumType} getValue() {`);
this.emitln(`return this.value;`, level + 1);
this.emitln('}', level);
this.emitln();
this.emit('public ', level);
this.emitln(`String getDescription() {`);
this.emitln(`return this.description;`, level + 1);
this.emitln('}', level);
}
}
module.exports = Generator;