UNPKG

dragonbones-runtime

Version:

the tools to build dragonbones file for diffrent framework

195 lines (172 loc) 6.92 kB
import utils = require('../lib/utils'); import file = require('../lib/FileUtil'); import ts = require("../lib/typescript-plus/lib/typescript"); import * as path from 'path'; export interface EgretCompilerHost { program: ts.Program; files?: string[]; exitStatus: number; compileWithChanges: (filesChanged: egret.FileChanges, sourceMap?: boolean) => EgretCompilerHost; messages?: string[]; } let compilerHost: ts.CompilerHost; let hostGetSourceFile; let hostFileExists; let cachedProgram: ts.Program; let cachedExistingFiles: utils.Map<boolean>; let changedFileNames: Array<string> = []; let getSourceFile = function (fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void) { if (cachedProgram && changedFileNames.indexOf(fileName) == -1) { const sourceFile = cachedProgram.getSourceFile(fileName); if (sourceFile) { return sourceFile; } } const sourceFile = hostGetSourceFile(fileName, languageVersion, onError); return sourceFile; } let cachedFileExists = function (fileName: string): boolean { return fileName in cachedExistingFiles ? cachedExistingFiles[fileName] : cachedExistingFiles[fileName] = hostFileExists(fileName); } export class Compiler { private sortedFiles: string[]; private program: ts.Program; private options: ts.CompilerOptions; public compile(options: ts.CompilerOptions, rootFileNames: string[]): EgretCompilerHost { this.fileNames = rootFileNames; this.options = options; cachedProgram = null; compilerHost = ts.createCompilerHost(options); hostGetSourceFile = compilerHost.getSourceFile; compilerHost.getSourceFile = getSourceFile; hostFileExists = compilerHost.fileExists; compilerHost.fileExists = cachedFileExists; return this.doCompile(); } private sortFiles(): void { let program = this.program; let sortResult = ts.reorderSourceFiles(program); if (sortResult.circularReferences.length > 0) { let error: string = ""; error += "error: circular references '" + "' :" + ts.sys.newLine; error += " at " + sortResult.circularReferences.join(ts.sys.newLine + " at ") + ts.sys.newLine + " at ..."; console.log(error); this.errors.push(error); } this.sortedFiles = sortResult.sortedFileNames; } private errors: string[] = []; private logErrors(diagnostics) { let allDiagnostics = ts.getPreEmitDiagnostics(this.program).concat(diagnostics); allDiagnostics.forEach(diagnostic => { let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); let msg; if (diagnostic.file) { let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); msg = ` Error ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`; } else { msg = ` Error: ${message}`; } console.log(msg); if (this.errors.length < 100) { this.errors.push(msg); } }); } private fileNames: Array<string>; compileWithChanges(filesChanged: egret.FileChanges, sourceMap?: boolean): EgretCompilerHost { this.errors = []; changedFileNames = []; let hasAddOrRemoved = false; filesChanged.forEach(file => { if (file.type == "added") { hasAddOrRemoved = true; this.fileNames.push(file.fileName); } else if (file.type == "removed") { hasAddOrRemoved = true; var index = this.fileNames.indexOf(file.fileName); if (index >= 0) { this.fileNames.splice(index, 1); } } else { changedFileNames.push(file.fileName); } }); if (hasAddOrRemoved) { cachedProgram = undefined; } return this.doCompile(); } private doCompile(): EgretCompilerHost { cachedExistingFiles = utils.createMap<boolean>(); this.program = ts.createProgram(this.fileNames, this.options, compilerHost); this.sortFiles(); let emitResult = this.program.emit(); this.logErrors(emitResult.diagnostics); cachedProgram = this.program; return { files: this.sortedFiles, program: this.program, exitStatus: 0, messages: this.errors, compileWithChanges: this.compileWithChanges.bind(this) }; } parseTsconfig(projectRoot: string, isPublish: boolean) { let url = projectRoot + "tsconfig.json"; var configObj: any; try { configObj = JSON.parse(file.read(url)); } catch (e) { console.log(utils.tr(1117))//不是有效的 json 文件 // errLog.push(); configObj = { "compilerOptions": { "target": "es5", "experimentalDecorators": true, "lib": [ "es5", "dom", "es2015.promise" ] }, "exclude": [ "node_modules" ] } } let notSupport = ["module", "noLib", "rootDir", "out"]; let defaultSupport = { outDir: "bin-debug" }; let compilerOptions = configObj.compilerOptions; for (let optionName of notSupport) { if (compilerOptions.hasOwnProperty(optionName)) { var error = utils.tr(1116, optionName);//这个编译选项目前不支持修改 console.log(error);//build -e 的时候输出 delete compilerOptions[optionName]; } } for (let optionName in defaultSupport) { if (compilerOptions[optionName] != defaultSupport[optionName]) { if (compilerOptions[optionName]) { var error = utils.tr(1116, optionName); error = utils.tr(1123, error, defaultSupport[optionName]); console.log(error); } compilerOptions[optionName] = defaultSupport[optionName]; } } var configParseResult = ts.parseJsonConfigFileContent(configObj, ts.sys, path.dirname(url)); compilerOptions = configParseResult.options; compilerOptions.defines = getCompilerDefines(isPublish); return configParseResult } } function getCompilerDefines(isPublish: boolean) { let defines: any = {}; if (isPublish) { defines.DEBUG = false; defines.RELEASE = true; } else { defines.DEBUG = true; defines.RELEASE = false; } return defines; }