feat: optimize type file generate

Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
MiaoWoo 2020-06-02 18:06:15 +08:00
parent a7a40b374b
commit 80c6b123c1

View File

@ -1,23 +1,23 @@
import * as fs from "fs"; import * as fs from "fs"
function convertJson2TypeDefiend(infile: string, outDir: string) { function convertJson2TypeDefiend(infile: string, outDir: string) {
const file = infile.split(".json")[0]; const file = infile.substr(0, infile.length - 5)
const json = fs.readFileSync(`${inDir}/${file}.json`).toString(); const json = fs.readFileSync(`${inDir}/${file}.json`).toString()
const obj = JSON.parse(json); const obj = JSON.parse(json)
const qnas: string[] = obj.qualifiedName.split("."); const qnas: string[] = obj.qualifiedName.split(".")
let closeBuk = 0; let closeBuk = 0
let temp = `declare namespace ${qnas[0]} {\n`; let temp = `declare namespace ${mappingNamespace(qnas[0])} {\n`
closeBuk++; closeBuk++
const nms = qnas.slice(1, qnas.length - 1); const nms = qnas.slice(1, qnas.length - 1)
for (const nm of nms) { for (const nm of nms) {
temp += `${' '.repeat(closeBuk)}namespace ${nm.replace('function', 'function$')} {\n`; temp += `${' '.repeat(closeBuk)}namespace ${mappingNamespace(nm)} {\n`
closeBuk++; closeBuk++
} }
let classModifier = formatClassModifier(obj.modifiers) let classModifier = formatClassModifier(obj.modifiers)
temp += `${' '.repeat(closeBuk)}// @ts-ignore\n` temp += `${' '.repeat(closeBuk)}// @ts-ignore\n`
temp += `${' '.repeat(closeBuk)}${classModifier}${qnas[qnas.length - 1]}` temp += `${' '.repeat(closeBuk)}${classModifier}${qnas[qnas.length - 1]}`
let isInterface = classModifier.includes('interface') let isInterface = classModifier.includes('interface')
let safeInterface = []; let safeInterface = []
for (const ifs of obj.interfaces) { for (const ifs of obj.interfaces) {
// if (!ifs.qualifiedName.startsWith('java')) { // if (!ifs.qualifiedName.startsWith('java')) {
safeInterface.push(ifs) safeInterface.push(ifs)
@ -27,174 +27,171 @@ function convertJson2TypeDefiend(infile: string, outDir: string) {
if (safeInterface.length > 0) { if (safeInterface.length > 0) {
temp += ' extends ' temp += ' extends '
for (const ifs of safeInterface) { for (const ifs of safeInterface) {
temp += ifs.qualifiedName; temp += ifs.qualifiedName
temp += ', ' temp += ', '
} }
temp = temp.substr(0, temp.length - 2); temp = temp.substr(0, temp.length - 2)
} }
} else { } else {
temp += `${(obj.superclass) ? (' extends ' + (obj.superclass.qualifiedName == "<any>" ? "object" : obj.superclass.qualifiedName)) : ''}`; temp += `${(obj.superclass) ? (' extends ' + (obj.superclass.qualifiedName == "<any>" ? "object" : obj.superclass.qualifiedName)) : ''}`
if (safeInterface.length > 0) { if (safeInterface.length > 0) {
temp += ' implements ' temp += ' implements '
for (const ifs of safeInterface) { for (const ifs of safeInterface) {
temp += ifs.qualifiedName; temp += ifs.qualifiedName
temp += ', ' temp += ', '
} }
temp = temp.substr(0, temp.length - 2); temp = temp.substr(0, temp.length - 2)
} }
} }
temp += ' {\n' temp += ' {\n'
closeBuk++; closeBuk++
for (const constructor of obj.constructors) { for (const constructor of obj.constructors) {
temp += `${formatDoc(constructor.docString, closeBuk)}${' '.repeat(closeBuk)}// @ts-ignore\n${' '.repeat(closeBuk)}constructor(${formatParameters(constructor.parameters)})\n`; temp += `${formatDoc(constructor.docString, closeBuk)}${' '.repeat(closeBuk)}// @ts-ignore\n${' '.repeat(closeBuk)}constructor(${formatParameters(constructor.parameters)})\n`
} }
let members = []; let members = {}
let methods = ''; let methods = ''
for (const method of obj.methods) { for (const method of obj.methods) {
let methodModifier = isInterface ? '' : replaceModifiers(method.modifiers, classModifier.includes('abstract')) let methodModifier = isInterface ? '' : replaceModifiers(method.modifiers, classModifier.includes('abstract'))
if (!whiteKey.includes(method.name)) {
if (members[method.name] && methodModifier.includes('abstract')) { if (members[method.name] && methodModifier.includes('abstract')) {
continue; continue
} }
members[method.name] = methodModifier; members[method.name] = methodModifier
} methods += `${formatDoc(method.docString, closeBuk)}${' '.repeat(closeBuk)}// @ts-ignore\n${' '.repeat(closeBuk)}${methodModifier ? (methodModifier + ' ') : ''}${method.name}(${formatParameters(method.parameters)}): ${mappingType(method.returnType, false)};\n`
methods += `${formatDoc(method.docString, closeBuk)}${' '.repeat(closeBuk)}// @ts-ignore\n${' '.repeat(closeBuk)}${methodModifier} ${method.name}(${formatParameters(method.parameters)}): ${mappingType(method.returnType.type)};\n`;
} }
let fields = ''; let fields = ''
for (const field of obj.fields) { for (const field of obj.fields) {
if (members[field.name]) { if (members[field.name]) {
continue; continue
} }
fields += `${' '.repeat(closeBuk)}// @ts-ignore\n${' '.repeat(closeBuk)}${isInterface ? '' : replaceModifiers(field.modifiers)} ${field.name}: ${mappingType(field.type ? field.type.type : "any")};\n`; fields += `${' '.repeat(closeBuk)}// @ts-ignore\n${' '.repeat(closeBuk)}${isInterface ? '' : replaceModifiers(field.modifiers)} ${field.name}: ${mappingType(field.type)};\n`
} }
temp += fields + methods; temp += fields + methods
for (let index = 0; index < closeBuk; index++) { for (let index = 0; index < closeBuk; index++) {
temp += `${' '.repeat(closeBuk - index - 1)}}\n`; temp += `${' '.repeat(closeBuk - index - 1)}}\n`
} }
fs.writeFileSync(`${outDir}/${file}.${suffix}`, temp); fs.writeFileSync(`${outDir}/${file}.${suffix}`, temp)
return `${file}.${suffix}`; return `${file}.${suffix}`
} }
function formatClassModifier(modifiers: string) { function formatClassModifier(modifiers: string) {
let tempm = modifiers.replace('public', '').replace('static', '').replace('final', '').trim(); let tempm = modifiers.replace('public', '').replace('static', '').replace('final', '').trim()
if (!modifiers.includes('interface')) { tempm += ' class' } if (!modifiers.includes('interface')) {
return tempm.length > 0 ? (tempm + ' ') : ''; tempm += tempm.length == 0 ? 'class' : ' class'
}
return tempm.length > 0 ? (tempm + ' ') : ''
} }
function formatDoc(doc: string, closeBuk: number) { function formatDoc(doc: string, closeBuk: number) {
let middleDoc = ''; let middleDoc = ''
for (const line of doc.split('\n')) { for (const line of doc.split('\n')) {
if (line.trim().length != 0) { if (line.trim().length != 0) {
middleDoc += `${' '.repeat(closeBuk)} * ${line.trim()}\n` middleDoc += `${' '.repeat(closeBuk)} * ${line.trim()}\n`
} }
} }
return middleDoc.length > 0 ? `${' '.repeat(closeBuk)}/**\n${middleDoc}${' '.repeat(closeBuk)} */\n` : ''; return middleDoc.length > 0 ? `${' '.repeat(closeBuk)}/**\n${middleDoc}${' '.repeat(closeBuk)} */\n` : ''
} }
function replaceModifiers(modifiers: string, absClass = false): string { function replaceModifiers(modifiers: string, absClass = false): string {
// modifiers = modifiers.replace(' final', ' readonly'); // modifiers = modifiers.replace(' final', ' readonly')
modifiers = modifiers.split(" final")[0]; modifiers = modifiers.split(" final")[0]
modifiers = modifiers.split(" native")[0]; modifiers = modifiers.split(" native")[0]
modifiers = modifiers.split(" volatile")[0]; modifiers = modifiers.split(" volatile")[0]
modifiers = modifiers.split(" transient")[0]; modifiers = modifiers.split(" transient")[0]
modifiers = modifiers.split(" synchronized")[0]; modifiers = modifiers.split(" synchronized")[0]
if (!absClass) { if (!absClass) {
modifiers = modifiers.split(" abstract")[0]; modifiers = modifiers.split(" abstract")[0]
} }
return modifiers; return modifiers
} }
function formatParameters(params: any[]) { function formatParameters(params: any[]) {
let tempParam = ''; if (!params.length) return ''
for (const p of params) { let tempParam = ''
tempParam += `${mappingName(p.name)}: ${mappingType(p.type ? p.type.qualifiedName : 'any')}, ` for (let i = 0; i < params.length - 1; i++) {
const p = params[i];
tempParam += `${mappingName(p.name)}: ${mappingType(p.type)}, `
} }
return tempParam.substr(0, tempParam.length - 2); let lastParam = params[params.length - 1]
let lastMapType = mappingType(lastParam.type)
if (lastMapType.endsWith("[]")) {
tempParam += `...${mappingName(lastParam.name)}: ${lastMapType}`
} else {
tempParam += `${mappingName(lastParam.name)}: ${lastMapType}`
}
return tempParam
} }
const nameMap = []; const nameMap = {}
nameMap['function'] = 'func' nameMap['function'] = 'func'
nameMap['in'] = 'input' nameMap['in'] = 'input'
nameMap['var'] = 'variable' nameMap['var'] = 'variable'
nameMap['enum'] = 'enumerate'
nameMap['export'] = 'exporter'
nameMap['is'] = 'jis'
nameMap['with'] = 'jwith'
function mappingName(name: string) { function mappingNamespace(name: string) {
if (whiteKey.includes(name)) { return name } return typeof nameMap[name] == "string" ? name + '$' : name || ''
let outName = nameMap[name] || name || '';
return outName;
} }
let whiteKey = ['shift', "map", 'filter', 'values', 'valueOf', 'toString', 'length', 'includes', 'entries', 'keys', 'join', 'fill'] function mappingName(name: string) {
return typeof nameMap[name] == "string" ? nameMap[name] : name || ''
}
const typeMap = []; const typeMap = []
typeMap['int'] = 'number'; typeMap['int'] = 'number /*int*/'
typeMap['int[]'] = 'number[]'; typeMap['java.lang.Integer'] = "number"
typeMap['int[][]'] = 'number[][]'; typeMap['byte'] = 'number /*byte*/'
typeMap['byte'] = 'number'; typeMap['java.lang.Byte'] = "number"
typeMap['byte[]'] = 'number[]'; typeMap['double'] = 'number /*double*/'
typeMap['double'] = 'number'; typeMap['java.lang.Double'] = "number"
typeMap['double[]'] = 'number[]'; typeMap['short'] = 'number /*short*/'
typeMap['short'] = 'number'; typeMap['java.lang.Short'] = "number"
typeMap['short[]'] = 'number[]'; typeMap['float'] = 'number /*float*/'
typeMap['float'] = 'number'; typeMap['java.lang.Float'] = "number"
typeMap['float[]'] = 'number[]'; typeMap['long'] = 'number /*long*/'
typeMap['long'] = 'number'; typeMap['java.lang.Long'] = "number"
typeMap['long[]'] = 'number[]'; typeMap['<any>'] = 'any'
typeMap['<any>'] = 'any'; typeMap['char'] = 'string'
typeMap['char'] = 'string'; typeMap['java.lang.String'] = "string"
typeMap['char[]'] = 'string[]'; typeMap['java.lang.Object'] = "any"
typeMap['java.lang.String'] = "string"; typeMap['java.util.List'] = "Array"
typeMap['java.util.Set'] = "Array"
typeMap['java.util.Collection'] = "Array"
typeMap['java.lang.Throwable'] = "Error"
// typeMap['java.util.Date'] = 'any /*java.util.Date*/' // typeMap['java.util.Date'] = 'any /*java.util.Date*/'
// typeMap['java.util.List'] = 'any[] /*java.util.List*/' // typeMap['java.util.List'] = 'any[] /*java.util.List*/'
// typeMap['java.util.Set'] = 'any[] /*java.util.Set*/' // typeMap['java.util.Set'] = 'any[] /*java.util.Set*/'
// typeMap['java.util.Collection'] = 'any[] /*java.util.Collection*/' // typeMap['java.util.Collection'] = 'any[] /*java.util.Collection*/'
// typeMap['java.util.Map'] = 'Map<any, any> /*java.util.Map*/' // typeMap['java.util.Map'] = 'Map<any, any> /*java.util.Map*/'
// Sponge
typeMap['Vectori'] = 'any /*Vector3i*/'
typeMap['Vectord'] = 'any /*Vector3d*/'
typeMap['Vectorf'] = 'any /*Vector3f*/'
typeMap['Vector2i'] = 'any /*Vector2i*/'
typeMap['Vector2d'] = 'any /*Vector2d*/'
typeMap['Vector2f'] = 'any /*Vector2f*/'
typeMap['Vector3i'] = 'any /*Vector3i*/'
typeMap['Vector3d'] = 'any /*Vector3d*/'
typeMap['Vector3f'] = 'any /*Vector3f*/'
typeMap['Type'] = 'any /*Type*/'
typeMap['Gson'] = 'any /*Gson*/'
typeMap['Logger'] = 'any /*Logger*/'
typeMap['MethodVisitor'] = 'any /*MethodVisitor*/'
typeMap['ConfigurationNode'] = 'any /*ConfigurationNode*/'
typeMap['TypeSerializerCollection'] = 'any /*TypeSerializerCollection*/'
typeMap['Quaterniond'] = 'any /*Quaterniond*/'
typeMap['Matrix2d'] = 'any /*Matrix2d*/'
typeMap['Matrix3d'] = 'any /*Matrix3d*/'
typeMap['Matrix4d'] = 'any /*Matrix4d*/'
function mappingType(type: string): string { type JavaType = {
let outType = typeMap[type] || type || 'any'; qualifiedName: string,
if (outType.indexOf('.') != -1) { name: string,
if (outType.startsWith('java.') || outType.startsWith('org.') || outType.startsWith('net.') || outType.startsWith('cn.')) { type: string
}
} else { function mappingType(type: JavaType, isParam: boolean = true): string {
outType = `any /*${outType}*/` if (!type || !type.type) { return 'any' }
} let outType = typeMap[type.qualifiedName] || type.qualifiedName || 'any'
} let tsType = type.type.replace(type.qualifiedName, outType).replace('function', 'function$')
return outType.replace('function', 'function$'); return isParam && type.type !== tsType && type.type.includes('.') ? `${type.type} | ${tsType}` : tsType
} }
var args = process.argv.splice(2) var args = process.argv.splice(2)
const suffix = 'd.ts' const suffix = 'd.ts'
const inDir = `../docs/${args[0]}` const inDir = `../docs/${args[0]}`
const outDir = "./temp"; const outDir = "./temp"
const files = fs.readdirSync(inDir); const files = fs.readdirSync(inDir)
let index = ''; let index = ''
for (const file of files) { for (const file of files) {
index += `/// <reference path="./${convertJson2TypeDefiend(file, outDir)}" />\n`; index += `/// <reference path="./${convertJson2TypeDefiend(file, outDir)}" />\n`
} }
fs.writeFileSync(`${outDir}/index.${suffix}`, index); fs.writeFileSync(`${outDir}/index.${suffix}`, index)