Commit 3b92a949 authored by rockyl's avatar rockyl

init

parents
Pipeline #121050 failed with stages
in 0 seconds
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
#!/usr/bin/env node
/**
* Created by rockyl on 2019-04-26.
*/
const os = require('os');
const path = require('path');
const fs = require('fs-extra');
const program = require('commander');
const {generateDeclareMap} = require('../src/index');
program
.version('1.0.1')
.description('scilla declare generator')
.option('-i, --input [string]', 'input file')
.option('-o, --output [string]', 'output file')
.parse(process.argv);
const systemComponentsPath = path.join(os.homedir(), '.scilla', 'components');
const systemComponentsSrcPath = path.join(systemComponentsPath, 'src');
const tsconfig = fs.readJsonSync(path.join(systemComponentsPath, 'tsconfig.json'));
const inputFile = program.input;
const inputFileFolder = path.dirname(path.dirname(inputFile));
const projectPath = process.cwd();
function declareFilter(source) {
return source.fileName.indexOf(inputFileFolder) >= 0;
}
const result = generateDeclareMap(
tsconfig,
program.input,
systemComponentsSrcPath,
projectPath,
null,
declareFilter
);
console.log(result);
{
"properties": {
"PuzzleItemPrefab": {
"type": "resource"
},
"disrupt": {
"type": "(Anonymous function)"
},
"onCoverOther": {
"type": "(Anonymous function)"
},
"cancelCoverOther": {
"type": "(Anonymous function)"
},
"onItemMove": {
"type": "(Anonymous function)"
},
"missionComplete": {
"type": "(Anonymous function)"
},
"onAlertClose": {
"type": "(Anonymous function)"
}
},
"methods": {
"getPuzzleItem": {
"item": {
"type": "any"
}
},
"start": {
"img": {
"type": "any"
},
"segmentation": {
"type": "any"
},
"_items": {
"type": "Array"
},
"frames": {
"type": "frames"
},
"perSize": {
"type": "number"
},
"offset": {
"type": "number"
},
"sheet": {
"type": "\"node_modules/scilla/src/core/Sheet\".Sheet",
"defaultValue": [
"img",
"frames"
]
}
},
"judgement": {
"complete": {
"type": "boolean",
"defaultValue": true
}
}
},
"bases": [
"\"node_modules/scilla-components/src/base/ScillaComponent\".ScillaComponent",
"\"node_modules/scilla/src/core/Component\".Component",
"\"node_modules/scilla/src/core/HashObject\".HashObject"
]
}
\ No newline at end of file
{
"name": "scilla-declare-generator",
"version": "1.0.1",
"main": "src/index.js",
"license": "MIT",
"dependencies": {
"commander": "^2.20.0",
"fs-extra": "^7.0.1",
"typescript": "^3.2.2"
}
}
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/../scilla-declare-generator" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
/**
* Created by rockyl on 2019-01-22.
*/
const ts = require('typescript');
let classDeclareMap;
let _componentsPath;
let _projectPath;
let _assetsPath;
let _filter;
const scillaCorePrefix = 'node_modules/scilla/src';
const componentBaseClassName = '"scilla/core/Component".Component';
const showLog = false;
const showVerboseLog = false;
exports.generateDeclareMap = function(tsconfig, file, componentsPath, projectPath, assetsPath, filter) {
_componentsPath = componentsPath;
_projectPath = projectPath;
_assetsPath = assetsPath;
_filter = filter;
const config = ts.parseJsonConfigFileContent(tsconfig, ts.sys, projectPath);
const files = file ? [file] : config.fileNames;
const program = ts.createProgram(files, config.options);
const sourceFiles = program.getSourceFiles();
classDeclareMap = {};
if(showLog) console.time('getTypeChecker');
const checker = program.getTypeChecker();
if(showLog) console.timeEnd('getTypeChecker');
if(showLog) console.time('delint');
for(let sourceFile of sourceFiles){
if (sourceFile.fileName.indexOf('.d.ts') < 0) {
if(!_filter || _filter(sourceFile)){
if(showLog && showVerboseLog) console.time(sourceFile.fileName);
delint(checker, sourceFile);
if(showLog && showVerboseLog) console.timeEnd(sourceFile.fileName);
}
}
}
if(showLog) console.timeEnd('delint');
/*for(let name in classDeclareMap){
transFullyDeclare(name);
}*/
return classDeclareMap;
};
function delint(checker, sourceFile) {
delintNode(sourceFile);
function delintNode(node) {
switch (node.kind) {
case ts.SyntaxKind.EnumDeclaration:
const enumType = checker.getTypeAtLocation(node);
const {fullClassName: enumName} = getFullyQualifiedNameOfType(checker.getTypeAtLocation(node), checker);
let members;
if (enumName in classDeclareMap) {
members = classDeclareMap[enumName];
} else {
classDeclareMap[enumName] = members = {
__type__: 'enum',
map: {},
};
}
for (let type of enumType.types) {
let name = type.symbol.escapedName;
members.map[name] = {
value: type.value,
};
let s = type.getSymbol();
getJsDoc(members.map[name], s.valueDeclaration)
}
break;
case ts.SyntaxKind.ClassDeclaration:
const theType = checker.getTypeAtLocation(node);
let mf = ts.getCombinedModifierFlags(node);
if (!(mf & ts.ModifierFlags.Abstract)) {
const {fullClassName, path, className} = getFullyQualifiedNameOfType(checker.getTypeAtLocation(node), checker);
let members;
if (fullClassName in classDeclareMap) {
members = classDeclareMap[fullClassName];
} else {
classDeclareMap[fullClassName] = members = {properties: {}, methods: {}};
}
getJsDoc(members, node);
const analyseResult = analyseBases(theType, checker);
if(analyseResult.bases.length > 0){
members["bases"] = analyseResult.bases;
}
if(analyseResult.isComponent){
members['isComponent'] = analyseResult.isComponent;
}
members['path'] = path;
members['className'] = className;
const props = theType.getSymbol().members;
props.forEach(function (value) {
let name = value.name;
if (name.indexOf("$") === 0 || name.indexOf("_") === 0)
return;
const {flags, declarations, valueDeclaration, valueDeclaration: {modifiers}} = value;
let isAccessibility = true;
if (modifiers) {
for (const modifier of modifiers) {
if (modifier.kind === ts.SyntaxKind.PrivateKeyword || modifier.kind === ts.SyntaxKind.ProtectedKeyword) {
isAccessibility = false;
break;
}
}
}
if (isAccessibility) {
//console.log(name, flags, valueDeclaration.kind);
if ((flags & ts.SymbolFlags.Property) || ((flags & ts.SymbolFlags.Accessor) && declarations.length === 2)) {
addProp(members.properties, name, valueDeclaration, checker);
} else if (flags & ts.SymbolFlags.Method) {
const method = members.methods[name] = {};
getJsDoc(method, valueDeclaration);
valueDeclaration.locals.forEach(local => {
const {valueDeclaration, name} = local;
addProp(method, name, valueDeclaration, checker);
})
}
}
});
}
}
ts.forEachChild(node, delintNode);
}
}
function addProp(dataContainer, name, valueDeclaration, checker) {
if (!valueDeclaration) {
return;
}
const {initializer, type: typeNode} = valueDeclaration;
let typeName;
if (typeNode && typeNode.typeName && typeNode.typeName.escapedText && typeNode.typeName.escapedText.charCodeAt(0) >= 97) {
typeName = typeNode.typeName.escapedText;
} else {
let typeDef = checker.getTypeAtLocation(valueDeclaration);
const {fullClassName} = getFullyQualifiedNameOfType(typeDef, checker);
typeName = fullClassName;
}
let defaultValue;
if (initializer) {
if (typeName === 'boolean') {
defaultValue = initializer.end - initializer.pos === 5;
} else if (initializer.arguments) {
defaultValue = [];
for (let argument of initializer.arguments) {
let typeDef = checker.getTypeAtLocation(argument);
let value = argument.text || (argument.name && argument.name.escapedText);
defaultValue.push(value);
}
} else {
defaultValue = initializer && (initializer.text || (initializer.name && initializer.name.escapedText));
}
}
const prop = {type: typeName};
getJsDoc(prop, valueDeclaration);
if (defaultValue !== undefined) {
prop.defaultValue = defaultValue;
}
dataContainer[name] = prop;
}
function getJsDoc(dataContainer, valueDeclaration) {
const jsDoc = valueDeclaration.jsDoc;
if (jsDoc && jsDoc.length > 0) {
dataContainer.__comment__ = jsDoc[jsDoc.length - 1].comment;
}
}
function getFullyQualifiedNameOfType(type, checker) {
let symbol = type.getSymbol(), fullClassName, path, className;
if (symbol) {
fullClassName = checker.getFullyQualifiedName(symbol);
if (fullClassName.indexOf('\"') >= 0) {
path = fullClassName.substring(1, fullClassName.lastIndexOf('.') - 1);
className = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
if (path.indexOf(scillaCorePrefix) >= 0) {
path = path.substr(path.indexOf(scillaCorePrefix)).replace(scillaCorePrefix, 'scilla');
} else if (path.indexOf(_assetsPath) >= 0) {
path = path.replace(_assetsPath, '.')
} else {
path = path.replace(_componentsPath, 'components')
}
fullClassName = `"${path}".${className}`;
}
} else {
fullClassName = checker.typeToString(type);
}
return {
fullClassName,
path,
className,
}
}
function analyseBases(type, checker) {
const bases = [];
let types, isComponent = false;
while (true) {
types = checker.getBaseTypes(type);
if (types.length === 0) {
break;
}
type = types[0];
const {fullClassName} = getFullyQualifiedNameOfType(type, checker);
bases.push(fullClassName);
if (fullClassName === componentBaseClassName) {
isComponent = true;
}
}
return {
bases,
isComponent,
};
}
/**
* Created by rockyl on 2018-12-19.
*/
const {generateDeclareMap, } = require('./src/index');
async function exec(){
let classDeclareMap = await generateDeclareMap(
'/Users/rockyl/.scilla/components',
'/Users/rockyl/WorkSpaces/scilla/jigsaw-puzzle',
'/Users/rockyl/WorkSpaces/scilla/jigsaw-puzzle/assets',
'/Users/rockyl/WorkSpaces/scilla/jigsaw-puzzle/assets/scripts/game/Puzzle.ts'
);
console.log(JSON.stringify(classDeclareMap, null, '\t'));
//const keys = Object.keys(classDeclareMap);
//console.log(keys);
//console.log(JSON.stringify(classDeclareMap[keys[keys.length - 1]], null, '\t'));
}
exec();
{
"compilerOptions": {
"target": "es5",
"experimentalDecorators": true,
"removeComments": true,
"sourceMap": true,
"importHelpers": true,
"noImplicitAny": false,
"noEmitOnError": true,
"downlevelIteration": true,
"lib": [
"es5",
"es6",
"dom",
"es2015.promise"
],
"baseUrl": "./",
"paths": {
}
},
"include": [
"src",
"libs"
]
}
\ No newline at end of file
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
commander@^2.20.0:
version "2.20.0"
resolved "https://registry.npm.taobao.org/commander/download/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
integrity sha1-1YuytcHuj4ew00ACfp6U4iLFpCI=
fs-extra@^7.0.1:
version "7.0.1"
resolved "https://registry.npm.taobao.org/fs-extra/download/fs-extra-7.0.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffs-extra%2Fdownload%2Ffs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
integrity sha1-TxicRKoSO4lfcigE9V6iPq3DSOk=
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
universalify "^0.1.0"
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.15"
resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
integrity sha1-/7cD4QZuig7qpMi4C6klPu77+wA=
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
optionalDependencies:
graceful-fs "^4.1.6"
typescript@^3.2.2:
version "3.2.2"
resolved "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5"
integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.npm.taobao.org/universalify/download/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment