mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-30 11:08:34 +08:00
333 lines
7.5 KiB
JavaScript
333 lines
7.5 KiB
JavaScript
const fs = require('fs');
|
|
const glob = require('glob')
|
|
|
|
class IDLGenerator {
|
|
parseDesc(str) {
|
|
if (str.indexOf('/**') < 0 && str.indexOf('*/') < 0) {
|
|
let desc = str;
|
|
let start = desc.indexOf('*');
|
|
|
|
if (start >= 0) {
|
|
desc = desc.substr(start + 1);
|
|
}
|
|
|
|
return desc + '\n';
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
parseAnnotation(str) {
|
|
let annotation = {};
|
|
let value = str.substr(str.indexOf('['));
|
|
let arr = JSON.parse(value);
|
|
|
|
arr.forEach(iter => {
|
|
const d = iter.indexOf(':');
|
|
if (d >= 0) {
|
|
const k = iter.substr(0, d);
|
|
const v = iter.substr(d + 1);
|
|
annotation[k] = v;
|
|
} else {
|
|
annotation[iter] = true;
|
|
}
|
|
})
|
|
|
|
return annotation;
|
|
}
|
|
|
|
getValue(str) {
|
|
const s = str.substr(str.indexOf('@') + 1)
|
|
const v = s.substr(s.indexOf(' '));
|
|
|
|
return v.trim();
|
|
}
|
|
|
|
parseName(str) {
|
|
return this.getValue(str);
|
|
}
|
|
|
|
parseAlias(str) {
|
|
return this.getValue(str);
|
|
}
|
|
|
|
parsePrefix(str) {
|
|
return this.getValue(str);
|
|
}
|
|
|
|
parseParent(str) {
|
|
return this.getValue(str);
|
|
}
|
|
|
|
parseParam(str) {
|
|
const param = {};
|
|
const type = this.parseType(str);
|
|
const nameDesc = str.substr(str.indexOf('}') + 1).trim();
|
|
const d = nameDesc.indexOf(' ');
|
|
const name = nameDesc.substr(0, d).trim();
|
|
const desc = nameDesc.substr(d).trim();
|
|
|
|
param.type = type;
|
|
param.name = name;
|
|
param.desc = desc;
|
|
|
|
return param;
|
|
}
|
|
|
|
parseTypeAndName(str) {
|
|
const typeAndName = {};
|
|
const type = this.parseType(str);
|
|
const name = str.substr(str.indexOf('}') + 1).trim();
|
|
|
|
typeAndName.type = type.trim();
|
|
typeAndName.name = name.trim();
|
|
|
|
return typeAndName;
|
|
}
|
|
|
|
parseType(str) {
|
|
const start = str.indexOf('{');
|
|
const end = str.indexOf('}');
|
|
const type = str.substr(start + 1, end - start - 1);
|
|
|
|
return type;
|
|
}
|
|
|
|
parseReturn(str) {
|
|
const ret = {};
|
|
const type = this.parseType(str);
|
|
const desc = str.substr(str.indexOf('}') + 1);
|
|
|
|
ret.type = type.trim();
|
|
ret.desc = desc.trim();
|
|
|
|
return ret;
|
|
}
|
|
|
|
parseMethod(comment) {
|
|
const method = {
|
|
params: [],
|
|
annotation: {},
|
|
desc: '',
|
|
name: ''
|
|
};
|
|
|
|
comment.split('\n').forEach(iter => {
|
|
if (iter.indexOf('@method') >= 0) {
|
|
method.name = this.parseName(iter);
|
|
}else if (iter.indexOf('@alias') >= 0) {
|
|
method.alias = this.parseAlias(iter);
|
|
} else if (iter.indexOf(' @annotation') >= 0) {
|
|
method.annotation = this.parseAnnotation(iter);
|
|
} else if (iter.indexOf(' @param') >= 0) {
|
|
method.params.push(this.parseParam(iter));
|
|
} else if (iter.indexOf(' @return') >= 0) {
|
|
method.return = this.parseReturn(iter);
|
|
} else {
|
|
method.desc += this.parseDesc(iter);
|
|
}
|
|
});
|
|
|
|
if (method.annotation.global) {
|
|
method.type = 'method';
|
|
method.header = this.filename;
|
|
|
|
this.result.push(method);
|
|
} else if (this.cls) {
|
|
this.cls.methods.push(method);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
parseProperty(comment) {
|
|
const property = {
|
|
name: '',
|
|
desc: ''
|
|
};
|
|
|
|
comment.split('\n').forEach(iter => {
|
|
if (iter.indexOf('@property') >= 0) {
|
|
const typeAndName = this.parseTypeAndName(iter);
|
|
property.type = typeAndName.type;
|
|
property.name = typeAndName.name;
|
|
} else if (iter.indexOf('@annotation') >= 0) {
|
|
property.annotation = this.parseAnnotation(iter);
|
|
} else {
|
|
property.desc += this.parseDesc(iter);
|
|
}
|
|
});
|
|
|
|
if(this.cls) {
|
|
this.cls.properties.push(property);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
parseEvent(comment) {
|
|
const event = {
|
|
name: '',
|
|
desc: ''
|
|
};
|
|
|
|
comment.split('\n').forEach(iter => {
|
|
if (iter.indexOf('@event') >= 0) {
|
|
const typeAndName = this.parseTypeAndName(iter);
|
|
event.type = typeAndName.type;
|
|
event.name = typeAndName.name;
|
|
} else if (iter.indexOf('@annotation') >= 0) {
|
|
event.annotation = this.parseAnnotation(iter);
|
|
} else {
|
|
event.desc += this.parseDesc(iter);
|
|
}
|
|
});
|
|
|
|
if(this.cls) {
|
|
this.cls.events.push(event);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
parseClass(comment) {
|
|
let cls = {};
|
|
cls.type = 'class';
|
|
cls.methods = [];
|
|
cls.events = [];
|
|
cls.properties = [];
|
|
cls.header = this.filename;
|
|
cls.desc = '';
|
|
|
|
this.cls = cls;
|
|
|
|
comment.split('\n').forEach(iter => {
|
|
if (iter.indexOf('@class') >= 0) {
|
|
cls.name = this.parseName(iter);
|
|
} else if (iter.indexOf('@annotation') >= 0) {
|
|
cls.annotation = this.parseAnnotation(iter);
|
|
} else if (iter.indexOf('@parent') >= 0) {
|
|
cls.parent = this.parseParent(iter);
|
|
} else {
|
|
cls.desc += this.parseDesc(iter);
|
|
}
|
|
});
|
|
|
|
this.result.push(cls);
|
|
}
|
|
|
|
parseEnum(comment) {
|
|
let cls = {};
|
|
cls.type = 'enum';
|
|
cls.desc = '';
|
|
cls.consts = [];
|
|
cls.header = this.filename;
|
|
|
|
this.cls = cls;
|
|
|
|
comment.split('\n').forEach(iter => {
|
|
if (iter.indexOf('@enum') >= 0) {
|
|
cls.name = this.parseName(iter);
|
|
cls.prefix = cls.name.replace(/t$/, "").toUpperCase();
|
|
} else if (iter.indexOf('@annotation') >= 0) {
|
|
cls.annotation = this.parseAnnotation(iter);
|
|
} else if (iter.indexOf('@prefix') >= 0) {
|
|
cls.prefix = this.parsePrefix(iter);
|
|
} else {
|
|
cls.desc += this.parseDesc(iter);
|
|
}
|
|
});
|
|
|
|
this.result.push(cls);
|
|
}
|
|
|
|
parseConst(comment) {
|
|
let c = {};
|
|
c.desc = '';
|
|
|
|
comment.split('\n').forEach(iter => {
|
|
if (iter.indexOf('@const') >= 0) {
|
|
c.name = this.parseName(iter);
|
|
} else {
|
|
c.desc += this.parseDesc(iter);
|
|
}
|
|
});
|
|
|
|
if (this.cls) {
|
|
this.cls.consts.push(c);
|
|
}
|
|
}
|
|
|
|
parseFileContent(filename, content) {
|
|
let start = 0;
|
|
let end = 0;
|
|
let str = content;
|
|
|
|
do {
|
|
start = str.indexOf('/**');
|
|
if (start >= 0) {
|
|
str = str.substr(start);
|
|
end = str.indexOf('*/');
|
|
if (end >= 0) {
|
|
const comment = str.substr(0, end + 3);
|
|
if (comment.indexOf('* @') >= 0) {
|
|
if (comment.indexOf(' @class') >= 0) {
|
|
this.parseClass(comment);
|
|
} else if (comment.indexOf(' @method') >= 0) {
|
|
this.parseMethod(comment);
|
|
} else if (comment.indexOf(' @property') >= 0) {
|
|
this.parseProperty(comment);
|
|
} else if (comment.indexOf(' @event') >= 0) {
|
|
this.parseEvent(comment);
|
|
} else if (comment.indexOf(' @const') >= 0) {
|
|
this.parseConst(comment);
|
|
} else if (comment.indexOf(' @enum') >= 0) {
|
|
this.parseEnum(comment);
|
|
}
|
|
}
|
|
|
|
str = str.substr(end + 3);
|
|
}
|
|
}
|
|
|
|
} while (start >= 0 && end >= 0)
|
|
|
|
return;
|
|
}
|
|
|
|
parseFile(filename) {
|
|
const content = fs.readFileSync(filename).toString();
|
|
const name = filename.match(/[a-z|_\d|\.|A-Z]*\/[a-z|_\d|\.|A-Z]*$/)[0];
|
|
|
|
console.log('Process: ' + filename);
|
|
this.filename = name;
|
|
this.fullFileName = filename;
|
|
this.parseFileContent(name, content);
|
|
}
|
|
|
|
parseFolder(folder) {
|
|
const files = glob.sync(folder);
|
|
for (let i = 0; i < files.length; i++) {
|
|
const iter = files[i];
|
|
this.parseFile(iter);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
saveResult() {
|
|
const str = JSON.stringify(this.result, null, ' ');
|
|
fs.writeFileSync('idl.json', str);
|
|
}
|
|
|
|
static gen() {
|
|
let gen = new IDLGenerator();
|
|
|
|
gen.result = []
|
|
gen.parseFolder('../../src/**/*.h');
|
|
gen.saveResult('idl.json');
|
|
}
|
|
}
|
|
|
|
IDLGenerator.gen()
|