import * as fs from "fs-extra-promise"; import * as path from "path"; import * as ts from "typescript"; import * as utils from "./typescript-utils"; import * as CONFIG from "../config"; let dataPrototypePath = path.join(CONFIG.getDir(), "raw/default.json"); var dataString = fs.readFileSync(dataPrototypePath, "utf-8"); dataString = dataString.replace(/^\uFEFF/, ''); var baseTypeCache: ts.Map> = {}; function hasBaseTypes(theType: ts.Type, typeToFind: string, checker: ts.TypeChecker) { var q: string[] = []; var result = find(theType); if (result) { if (!baseTypeCache[typeToFind]) { baseTypeCache[typeToFind] = {}; } q.forEach(t => baseTypeCache[typeToFind][t] = true); } return result; function find(target: ts.ObjectType): boolean { var name = checker.getFullyQualifiedName(target.getSymbol()); q.push(name); if (name == typeToFind || (baseTypeCache[typeToFind] && baseTypeCache[typeToFind][name])) { return true; } var baseTypes = target.getBaseTypes().concat(utils.getImplementedInterfaces(target, checker)); for (var t of baseTypes) { var found = find(t); if (found) { return true; } } q.pop(); return false; } } function watch(rootFileNames: string[], options: ts.CompilerOptions) { const files: ts.Map<{ version: number }> = {}; // initialize the list of files rootFileNames.forEach(fileName => { files[fileName] = { version: 0 }; }); // Create the language service files var program = ts.createProgram(rootFileNames, options); var sourceCodes = program.getSourceFiles(); sourceCodes.forEach(source => { if (source.fileName.indexOf("lib.d.ts") >= 0) { return; } // if (source.fileName.indexOf("egret.d.ts") >= 0) { // return; // } delint(program, source, "eui.UIComponent"); }); rootFileNames.length = 0; program = null; if (global.gc) global.gc(); } var data = JSON.parse(dataString); function delint(program: ts.Program, sourceFile: ts.SourceFile, base: string) { var checker = program.getTypeChecker(); delintNode(sourceFile); function delintNode(node: ts.Node) { switch (node.kind) { case ts.SyntaxKind.ClassDeclaration: var theType = checker.getTypeAtLocation(node); var className = checker.getFullyQualifiedName(checker.getTypeAtLocation(node).getSymbol()); // console.log("-->" + className, node.flags & ts.NodeFlags.Abstract, hasBaseTypes(theType, base, checker)) if (!(node.flags & ts.NodeFlags.Abstract)) {//} && hasBaseTypes(theType, base, checker)) { var className = checker.getFullyQualifiedName(checker.getTypeAtLocation(node).getSymbol()); var superTypes = checker.getBaseTypes(theType); var __single__data = {}; if (className in data) { __single__data = data[className]; } else { data[className] = __single__data; } // console.log("==>" + className) superTypes.forEach(t => __single__data["super"] = checker.getFullyQualifiedName(t.getSymbol())); var props = theType.getSymbol().members; for (var name in props) { if (name.indexOf("$") == 0 || name.indexOf("_") == 0) continue; var p = props[name]; if ((p.flags & ts.SymbolFlags.Property) || (p.flags & ts.SymbolFlags.Accessor)) { var type = checker.getTypeAtLocation(p.declarations[0]); let typeString = utils.getFullyQualifiedNameOfType(type, checker); if(!__single__data.hasOwnProperty(p.name)){ //不允许重载的属性 if(!(p.name in { "itemRenderer":1, "itemRendererSkinName":1, "skinName":1 })){ __single__data[p.name] = typeString; } } // console.log() } // checker.getTypeAtLocation(p); // checker.getTypeOfSymbolAtLocation(p); // if((p.flags & ts.SymbolFlags.Property)||(p.flags & ts.SymbolFlags.Accessor)){ // if(name=="PPP"){ // var aaa = name; // //console.log(aaa); // } // if(p.declarations[0].flags&(ts.NodeFlags.Protected|ts.NodeFlags.Private)) // continue; // if((p.flags & ts.SymbolFlags.Accessor) && p.declarations.filter(d=>d.kind==ts.SyntaxKind.SetAccessor).length==0) // continue; // var isPrivate = p.getDocumentationComment().some(c=>c.text.indexOf("@private")>=0); // if(isPrivate) // continue; // console.log(name); // if((p.flags & ts.SymbolFlags.Property)&&p.valueDeclaration&&((p.valueDeclaration).initializer==null)){ // console.log("\t",name," == null"); // } // } } } } ts.forEachChild(node, delintNode); } } export async function run(egretProjectPath?: string) { // console.log(1) // console.log(2) let files = await walkFile( egretProjectPath ? egretProjectPath : "./test/TestEUIProject",(filePath:string)=>filePath.indexOf(".ts") >= 0); // console.log (files) // Start the watcher let testFiles = [ `./test/egret.d.ts`, `./test/eui.d.ts`, // `./test/test.ts` ] watch(files, { module: ts.ModuleKind.CommonJS }); //todo 这里存在重大隐患,需要尽快修复 return new Promise((reslove, rejct) => { setTimeout(() => reslove(data), 1000); }); } function walkFile(path, filter: Function):Promise> { let result = []; let isFinished = false; let visitor = (data) =>{ if (filter(data.path)) {result.push(data.path)}}; fs.walk(path).on("data", visitor).on("end", () => isFinished = true) return new Promise((reslove, reject) => { function onTimeout() { if (isFinished) { reslove(result); } else { setTimeout(onTimeout, 100) } } setTimeout(onTimeout, 100) }) }