From 1645e787461d2cc555f8d8d747f6b7ec43fe237c Mon Sep 17 00:00:00 2001 From: buzhifeng Date: Wed, 28 Sep 2022 19:08:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=20interface=5Fsdk-js=20?= =?UTF-8?q?=E4=BB=93=E5=BA=93api=E4=B8=AD=E7=9A=84.d.ts=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90mock=E6=8E=A5=E5=8F=A3=20pa?= =?UTF-8?q?rt1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: buzhifeng --- BUILD.gn | 2 + js_framework_build.sh | 5 + mock-generate/.eslintrc | 102 +++++++++ mock-generate/build.js | 47 ++++ mock-generate/package.json | 19 ++ mock-generate/src/common/commonUtils.ts | 200 ++++++++++++++++++ .../callSignatureDeclaration.ts | 37 ++++ .../src/declaration-node/classDeclaration.ts | 88 ++++++++ .../constructorDeclaration.ts | 44 ++++ .../src/declaration-node/enumDeclaration.ts | 46 ++++ .../declaration-node/functionDeclaration.ts | 31 +++ .../heritageClauseDeclaration.ts | 27 +++ .../importAndExportDeclaration.ts | 91 ++++++++ .../indexSignatureDeclaration.ts | 21 ++ .../declaration-node/interfaceDeclaration.ts | 89 ++++++++ .../src/declaration-node/methodDeclaration.ts | 64 ++++++ .../methodSignatureDeclaration.ts | 34 +++ .../src/declaration-node/moduleDeclaration.ts | 111 ++++++++++ .../declaration-node/propertyDeclaration.ts | 54 +++++ .../propertySignatureDeclaration.ts | 42 ++++ .../sourceFileElementsAssemply.ts | 149 +++++++++++++ .../declaration-node/typeAliasDeclaration.ts | 71 +++++++ .../typeParameterDeclaration.ts | 35 +++ .../variableStatementResolve.ts | 39 ++++ mock-generate/tsconfig.json | 22 ++ runtime/main/model/selector.ts | 2 +- runtime/vdom/Element.ts | 8 +- 27 files changed, 1475 insertions(+), 5 deletions(-) create mode 100644 mock-generate/.eslintrc create mode 100644 mock-generate/build.js create mode 100644 mock-generate/package.json create mode 100644 mock-generate/src/common/commonUtils.ts create mode 100644 mock-generate/src/declaration-node/callSignatureDeclaration.ts create mode 100644 mock-generate/src/declaration-node/classDeclaration.ts create mode 100644 mock-generate/src/declaration-node/constructorDeclaration.ts create mode 100644 mock-generate/src/declaration-node/enumDeclaration.ts create mode 100644 mock-generate/src/declaration-node/functionDeclaration.ts create mode 100644 mock-generate/src/declaration-node/heritageClauseDeclaration.ts create mode 100644 mock-generate/src/declaration-node/importAndExportDeclaration.ts create mode 100644 mock-generate/src/declaration-node/indexSignatureDeclaration.ts create mode 100644 mock-generate/src/declaration-node/interfaceDeclaration.ts create mode 100644 mock-generate/src/declaration-node/methodDeclaration.ts create mode 100644 mock-generate/src/declaration-node/methodSignatureDeclaration.ts create mode 100644 mock-generate/src/declaration-node/moduleDeclaration.ts create mode 100644 mock-generate/src/declaration-node/propertyDeclaration.ts create mode 100644 mock-generate/src/declaration-node/propertySignatureDeclaration.ts create mode 100644 mock-generate/src/declaration-node/sourceFileElementsAssemply.ts create mode 100644 mock-generate/src/declaration-node/typeAliasDeclaration.ts create mode 100644 mock-generate/src/declaration-node/typeParameterDeclaration.ts create mode 100644 mock-generate/src/declaration-node/variableStatementResolve.ts create mode 100644 mock-generate/tsconfig.json diff --git a/BUILD.gn b/BUILD.gn index 6d18dff1..7b33b93b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -33,6 +33,7 @@ action("gen_snapshot") { script = "//third_party/jsframework/js_framework_build.sh" js_framework = "//third_party/jsframework/runtime" + js_framework_mock_generate = "//third_party/jsframework/mock-generate" is_mac = "false" use_mac = host_os == "mac" @@ -83,6 +84,7 @@ action("gen_snapshot") { rebase_path("//prebuilts", root_build_dir), rebase_path(buildfile_native_min, root_build_dir), rebase_path(css_what, root_build_dir), + rebase_path(js_framework_mock_generate, root_build_dir), ] inputs = [ diff --git a/js_framework_build.sh b/js_framework_build.sh index e624f36c..fef25a10 100755 --- a/js_framework_build.sh +++ b/js_framework_build.sh @@ -21,8 +21,10 @@ prebuilts_path=${12} # copy runtime to target out, and runtime/css-what is solt link, copy it always follow symbolic links in SOURCE if [ "${11}" == 'true' ];then cp -R -L $3 $9 + cp -R ${15} $9 else cp -r -L $3 $9 + cp -r ${15} $9 fi # $2 => node $4 => node_modules @@ -55,12 +57,14 @@ if [ -d "$prebuilts_path" ]; then cp -r $2 $9 cd $9 if [ "${11}" == 'true' ];then + ./node-v12.18.4-darwin-x64/bin/node ./mock-generate/build.js && ./node-v12.18.4-darwin-x64/bin/node build_jsmock_system_plugin.js || exit 1 & ./node-v12.18.4-darwin-x64/bin/node build_strip_native_min.js || exit 1 & # run unit test ./node-v12.18.4-darwin-x64/bin/node node_modules/.bin/mocha -r ts-node/register test/lib.ts test/ut/**/*.ts test/ut/*.ts || exit 1 & wait else + ./node-v12.18.4-linux-x64/bin/node ./mock-generate/build.js && ./node-v12.18.4-linux-x64/bin/node build_jsmock_system_plugin.js || exit 1 & ./node-v12.18.4-linux-x64/bin/node build_strip_native_min.js || exit 1 & # run unit test @@ -88,3 +92,4 @@ rm -rf ./test rm -rf ./.eslintrc rm -rf ./.babelrc rm -rf ./package.json +rm -rf ./mock-generate diff --git a/mock-generate/.eslintrc b/mock-generate/.eslintrc new file mode 100644 index 00000000..e5056f61 --- /dev/null +++ b/mock-generate/.eslintrc @@ -0,0 +1,102 @@ +{ + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + + "env": { + "es6": true, + "node": true, + "mocha": true + }, + + "globals": { + "ace": false, + "aceConsole": false, + "aceapp": false, + "markupState": false, + "notifyTrimMemory": false, + "i18nPluralRules": false, + "compileAndRunBundle": false, + "language": false + }, + + "extends": "eslint:recommended", + + "parser": "@typescript-eslint/parser", + + "rules": { + "camelcase": "off", + "accessor-pairs": 2, + "arrow-spacing": 2, + "block-spacing": 2, + "brace-style": 2, + "comma-dangle": 2, + "comma-spacing": 2, + "comma-style": 2, + "curly": 2, + "dot-location": [2, "property"], + "eol-last": 2, + "eqeqeq": 2, + "indent": [2, 2, { "SwitchCase": 1 }], + "key-spacing": 2, + "keyword-spacing": 2, + "new-cap": 2, + "new-parens": 2, + "no-array-constructor": 2, + "no-caller": 2, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-extra-parens": 2, + "no-floating-decimal": 2, + "no-implied-eval": 2, + "no-iterator": 2, + "no-label-var": 2, + "no-labels": 2, + "no-lone-blocks": 2, + "no-multi-spaces": 2, + "no-multi-str": 2, + "no-multiple-empty-lines": [2, { "max": 1 }], + "no-new-object": 2, + "no-new-wrappers": 2, + "no-octal-escape": 2, + "no-proto": 2, + "no-return-assign": 2, + "no-self-compare": 2, + "no-sequences": 2, + "func-call-spacing": 2, + "no-throw-literal": 2, + "no-trailing-spaces": 2, + "no-undef-init": "off", + "no-unmodified-loop-condition": 2, + "no-unneeded-ternary": [2, { "defaultAssignment": false }], + "no-unused-vars": "off", + "no-useless-computed-key": 2, + "no-useless-constructor": "off", + "no-whitespace-before-property": 2, + "one-var": [2, { "initialized": "never" }], + "padded-blocks": [2, "never"], + "quotes": [2, "single", {"avoidEscape": true, "allowTemplateLiterals": true}], + "semi": 2, + "semi-spacing": 2, + "space-before-blocks": 2, + "space-before-function-paren": [2, "never"], + "space-in-parens": 2, + "space-infix-ops": 2, + "space-unary-ops": [2, { "words": true, "nonwords": false }], + "spaced-comment": 2, + "template-curly-spacing": 2, + "wrap-iife": [2, "any"], + "no-var": 2, + "prefer-const": 2, + "array-bracket-spacing": 2, + "no-useless-escape": 0 + }, + + "settings": { + "flowtype": { + "onlyFilesWithFlowAnnotation": true + } + } +} diff --git a/mock-generate/build.js b/mock-generate/build.js new file mode 100644 index 00000000..eadfaf1d --- /dev/null +++ b/mock-generate/build.js @@ -0,0 +1,47 @@ +const fs = require('fs'); +const { spawn } = require('child_process'); +const path = require('path'); +const os = require('os'); +function compileMock() { + const mockJsPath = path.join(__dirname, '..', './runtime/main/extend/systemplugin'); + let nodeDir = ''; + if (os.platform() === 'linux') { + nodeDir = './node-v12.18.4-linux-x64/bin/node'; + } else { + nodeDir = './node-v12.18.4-darwin-x64/bin/node'; + } + + const bat = spawn(`${path.join(__dirname, '..', nodeDir)} ${path.join(__dirname, '..','./node_modules/typescript/bin/tsc')} && + ${path.join(__dirname, '..', nodeDir)} ${path.join(__dirname, 'dist')}/main.js && + ${path.join(__dirname, '..', nodeDir)} ${path.join(__dirname, '..', './node_modules/eslint/bin/eslint.js')} -c .eslintrc --fix ${mockJsPath}/**/*.js`, { + cwd: __dirname, + shell: true + }); + shellOutput(bat); +} + +function shellOutput(bat) { + bat.stdout.on('data', (data) => { + const lines = `${data}`.split(/\r{0,1}\n/); + if (lines) { + lines.forEach(line => { + if (line.length > 0) { + console.log(line.toString()); + } + }); + } + }); + + bat.stderr.on('data', (data) => { + const lines = `${data}`.split(/\r{0,1}\n/); + if (lines) { + lines.forEach(line => { + if (line.length > 0) { + console.log(line.toString()); + } + }); + } + }); +} + +compileMock(); diff --git a/mock-generate/package.json b/mock-generate/package.json new file mode 100644 index 00000000..7681826a --- /dev/null +++ b/mock-generate/package.json @@ -0,0 +1,19 @@ +{ + "name": "mock-generate", + "version": "1.0.0", + "description": "generate mock", + "main": "main.js", + "scripts": { + "build": "npm install && tsc && cd dist && node main.js && cd .. && eslint -c .eslintrc --fix ../runtime/**/systemplugin/**/*.js" + }, + "keywords": [ + "mock" + ], + "license": "Apache 2.0", + "devDependencies": { + "@types/node": "^14.18.21", + "typescript": "4.1.3", + "eslint": "^7.14.0", + "@typescript-eslint/parser": "^4.8.2" + } +} diff --git a/mock-generate/src/common/commonUtils.ts b/mock-generate/src/common/commonUtils.ts new file mode 100644 index 00000000..0801ba41 --- /dev/null +++ b/mock-generate/src/common/commonUtils.ts @@ -0,0 +1,200 @@ +import path from 'path'; +import { + CallSignatureDeclaration, ComputedPropertyName, FunctionDeclaration, Identifier, isClassDeclaration, + isComputedPropertyName, isIdentifier, isModuleBlock, isModuleDeclaration, isPrivateIdentifier, MethodDeclaration, + MethodSignature, ModifiersArray, ModuleDeclaration, NodeArray, ParameterDeclaration, PropertyName, SourceFile +} from 'typescript'; + +const allLegalImports = new Set(); +const fileNameList = new Set(); +const allClassSet = new Set(); + +/** + * get all legal imports + * @returns + */ +export function getAllLegalImports(): Set { + return allLegalImports; +} + +/** + * get all legal imports + * @param element + */ +export function collectAllLegalImports(element: string) { + allLegalImports.add(element); +} + +/** + * collect all mock js file path + * @returns + */ +export function getAllFileNameList(): Set { + return fileNameList; +} + +/** + * collect all file name + */ +export function collectAllFileName(filePath: string) { + const fileName = path.basename(filePath).split('.d.ts')[0]; + let outputFileName = ''; + if (fileName.includes('@')) { + outputFileName = fileName.split('@')[1].replace(/\./g, '_'); + } else { + outputFileName = fileName; + } + fileNameList.add(outputFileName); +} + +/** + * get all class name set + * @returns + */ +export function getClassNameSet(): Set { + return allClassSet; +} + +/** + * get all class declaration + * @param sourceFile + * @returns + */ +export function getAllClassDeclaration(sourceFile: SourceFile): Set { + sourceFile.forEachChild(node => { + if (isClassDeclaration(node)) { + if (node.name !== undefined) { + allClassSet.add(node.name.escapedText.toString()); + } + } else if (isModuleDeclaration(node)) { + const moduleDeclaration = node as ModuleDeclaration; + const moduleBody = moduleDeclaration.body; + if (moduleBody !== undefined && isModuleBlock(moduleBody)) { + moduleBody.statements.forEach(value => { + if (isClassDeclaration(value)) { + if (value.name !== undefined) { + allClassSet.add(firstCharacterToUppercase(value.name?.escapedText.toString())); + } + } + }); + } + } + }); + return allClassSet; +} + +/** + * get keywords + * @param modifiers + * @returns + */ +export function getModifiers(modifiers: ModifiersArray): Array { + const modifiersArray: Array = []; + modifiers.forEach(value => modifiersArray.push(value.kind)); + return modifiersArray; +} + +/** + * get property name + * @param node property node + * @param sourceFile + * @returns + */ +export function getPropertyName(node: PropertyName, sourceFile: SourceFile): string { + let propertyName = ''; + if (isIdentifier(node) || isPrivateIdentifier(node)) { + const newNameNode = node as Identifier; + propertyName = newNameNode.escapedText.toString(); + } else if (isComputedPropertyName(node)) { + const newNameNode = node as ComputedPropertyName; + propertyName = sourceFile.text.substring(newNameNode.expression.pos, newNameNode.expression.end).trimStart().trimEnd(); + } else { + propertyName = sourceFile.text.substring(node.pos, node.end).trimStart().trimEnd(); + } + return propertyName; +} + +/** + * get parameter declaration + * @param parameter + * @param sourceFile + * @returns + */ +export function getParameter(parameter: ParameterDeclaration, sourceFile: SourceFile): ParameterEntity { + let paramName = ''; + let paramTypeString = ''; + const paramTypeKind = parameter.type?.kind === undefined ? -1 : parameter.type.kind; + if (isIdentifier(parameter.name)) { + paramName = parameter.name.escapedText === undefined ? '' : parameter.name.escapedText.toString(); + } else { + const start = parameter.name.pos === undefined ? 0 : parameter.name.pos; + const end = parameter.name.end === undefined ? 0 : parameter.name.end; + paramName = sourceFile.text.substring(start, end).trimStart().trimEnd(); + } + + const start = parameter.type?.pos === undefined ? 0 : parameter.type.pos; + const end = parameter.type?.end === undefined ? 0 : parameter.type.end; + paramTypeString = sourceFile.text.substring(start, end).trimStart().trimEnd(); + return { + paramName: paramName, + paramTypeString: paramTypeString, + paramTypeKind: paramTypeKind + }; +} + +/** + * get method or function return info + * @param node + * @param sourceFile + * @returns + */ +export function getFunctionAndMethodReturnInfo(node: FunctionDeclaration | MethodDeclaration | + MethodSignature | CallSignatureDeclaration, sourceFile: SourceFile): ReturnTypeEntity { + const returnInfo = { returnKindName: '', returnKind: -1 }; + if (node.type !== undefined) { + const start = node.type.pos === undefined ? 0 : node.type.pos; + const end = node.type.end === undefined ? 0 : node.type.end; + returnInfo.returnKindName = sourceFile.text.substring(start, end).trimStart().trimEnd(); + returnInfo.returnKind = node.type.kind; + } + return returnInfo; +} + +/** + * get export modifiers + * @param modifiers + * @returns + */ +export function getExportKeyword(modifiers: ModifiersArray): Array { + const modifiersArray: Array = []; + modifiers.forEach(value => { + modifiersArray.push(value.kind); + }); + return modifiersArray; +} + +/** + * + * @param str first letter capitalization + * @returns + */ +export function firstCharacterToUppercase(str: string): string { + return str.slice(0, 1).toUpperCase() + str.slice(1); +} + +/** + * parameters entity + */ +export interface ParameterEntity { + paramName: string, + paramTypeString: string, + paramTypeKind: number +} + +/** + * return type entity + */ +export interface ReturnTypeEntity { + returnKindName: string, + returnKind: number +} diff --git a/mock-generate/src/declaration-node/callSignatureDeclaration.ts b/mock-generate/src/declaration-node/callSignatureDeclaration.ts new file mode 100644 index 00000000..c68a9b5c --- /dev/null +++ b/mock-generate/src/declaration-node/callSignatureDeclaration.ts @@ -0,0 +1,37 @@ +import { CallSignatureDeclaration, Node, SourceFile } from 'typescript'; +import { + getFunctionAndMethodReturnInfo, getParameter, getPropertyName, + ParameterEntity, ReturnTypeEntity +} from '../common/commonUtils'; + +/** + * get nameless function info + * @param node + * @param sourceFile + * @returns + */ +export function getCallSignatureDeclaration(node: Node, sourceFile: SourceFile): CallSignatureEntity { + const callSignatureNode = node as CallSignatureDeclaration; + let functionName = ''; + const args: Array = []; + const returnType = getFunctionAndMethodReturnInfo(callSignatureNode, sourceFile); + if (callSignatureNode.name !== undefined) { + functionName = getPropertyName(callSignatureNode.name, sourceFile); + } + + callSignatureNode.parameters.forEach(value => { + args.push(getParameter(value, sourceFile)); + }); + + return { + functionName: functionName, + returnType: returnType, + args: args + }; +} + +export interface CallSignatureEntity { + functionName: string, + returnType: ReturnTypeEntity, + args: Array +} diff --git a/mock-generate/src/declaration-node/classDeclaration.ts b/mock-generate/src/declaration-node/classDeclaration.ts new file mode 100644 index 00000000..61956779 --- /dev/null +++ b/mock-generate/src/declaration-node/classDeclaration.ts @@ -0,0 +1,88 @@ +import { + ClassDeclaration, isConstructorDeclaration, + isMethodDeclaration, isPropertyDeclaration, + isTypeParameterDeclaration, SourceFile, SyntaxKind +} from 'typescript'; +import { getExportKeyword } from '../common/commonUtils'; +import { ConstructorEntity, getConstructorDeclaration } from './constructorDeclaration'; +import { getHeritageClauseDeclaration, HeritageClauseEntity } from './heritageClauseDeclaration'; +import { getMethodDeclaration, MethodEntity, StaticMethodEntity } from './methodDeclaration'; +import { getPropertyDeclaration, PropertyEntity } from './propertyDeclaration'; +import { getTypeParameterDeclaration, TypeParameterEntity } from './typeParameterDeclaration'; + +/** + * get class info + * @param classNode + * @param sourceFile + * @returns + */ +export function getClassDeclaration(classNode: ClassDeclaration, sourceFile: SourceFile): ClassEntity { + let exportModifiers: Array = []; + if (classNode.modifiers !== undefined) { + exportModifiers = getExportKeyword(classNode.modifiers); + } + + const className = classNode.name === undefined ? '' : classNode.name.escapedText.toString(); + const heritageClauses: Array = []; + const classConstructor: Array> = []; + const classMethod: Map> = new Map>(); + const classProperty: Array = []; + const typeParameters: Array = []; + const staticMethods: Array = []; + + if (classNode.heritageClauses !== undefined) { + classNode.heritageClauses.forEach(value => { + heritageClauses.push(getHeritageClauseDeclaration(value, sourceFile)); + }); + } + + classNode.members.forEach(value => { + if (isMethodDeclaration(value)) { + const methodEntity = getMethodDeclaration(value, sourceFile); + if (methodEntity.modifiers.includes(SyntaxKind.StaticKeyword)) { + staticMethods.push({ className: className, methodEntity: methodEntity }); + } else { + if (classMethod.get(methodEntity.functionName.name) !== undefined) { + classMethod.get(methodEntity.functionName.name)?.push(methodEntity); + } else { + const methodArray: Array = []; + methodArray.push(methodEntity); + classMethod.set(methodEntity.functionName.name, methodArray); + } + } + } else if (isPropertyDeclaration(value)) { + classProperty.push(getPropertyDeclaration(value, sourceFile)); + } else if (isConstructorDeclaration(value)) { + classConstructor.push(getConstructorDeclaration(value, sourceFile)); + } else if (isTypeParameterDeclaration(value)) { + typeParameters.push(getTypeParameterDeclaration(value, sourceFile)); + } else { + console.log('--------------------------- uncaught class type start -----------------------'); + console.log('className: ' + className); + console.log(value); + console.log('--------------------------- uncaught class type end -----------------------'); + } + }); + + return { + className: className, + typeParameters: typeParameters, + heritageClauses: heritageClauses, + classConstructor: classConstructor, + classMethod: classMethod, + classProperty: classProperty, + exportModifiers: exportModifiers, + staticMethods: staticMethods + }; +} + +export interface ClassEntity { + className: string, + typeParameters: Array, + heritageClauses: Array, + classConstructor: Array>, + classMethod: Map>, + classProperty: Array, + exportModifiers: Array, + staticMethods: Array +} diff --git a/mock-generate/src/declaration-node/constructorDeclaration.ts b/mock-generate/src/declaration-node/constructorDeclaration.ts new file mode 100644 index 00000000..82e8fe1b --- /dev/null +++ b/mock-generate/src/declaration-node/constructorDeclaration.ts @@ -0,0 +1,44 @@ +import { ConstructorDeclaration, isIdentifier, Node, SourceFile } from 'typescript'; + +/** + * get constructors info + * @param node + * @param sourceFile + * @returns + */ +export function getConstructorDeclaration(node: Node, sourceFile: SourceFile): Array { + const constructorNode = node as ConstructorDeclaration; + const constructors: Array = []; + constructorNode.parameters.forEach(value => { + const paramElement = value.name; + let name = ''; + let typeName = ''; + let typeKind = -1; + if (isIdentifier(paramElement)) { + name = paramElement.escapedText.toString(); + } else { + name = sourceFile.text.substring(paramElement.pos, paramElement.end).trimStart().trimEnd(); + } + + const paramTypeElement = value.type; + if (paramTypeElement !== undefined) { + typeName = sourceFile.text.substring(paramTypeElement.pos, paramTypeElement.end).trimStart().trimEnd(); + typeKind = paramTypeElement.kind; + } + + constructors.push( + { + name: name, + typeName: typeName, + typeKind: typeKind + } + ); + }); + return constructors; +} + +export interface ConstructorEntity { + name: string, + typeName: string, + typeKind: number +} diff --git a/mock-generate/src/declaration-node/enumDeclaration.ts b/mock-generate/src/declaration-node/enumDeclaration.ts new file mode 100644 index 00000000..1cc509b6 --- /dev/null +++ b/mock-generate/src/declaration-node/enumDeclaration.ts @@ -0,0 +1,46 @@ +import { EnumDeclaration, SourceFile } from 'typescript'; +import { getExportKeyword, getPropertyName } from '../common/commonUtils'; + +/** + * get enum info + * @param node + * @param sourceFile + * @returns + */ +export function getEnumDeclaration(node: EnumDeclaration, sourceFile: SourceFile): EnumEntity { + const enumName = node.name.escapedText.toString(); + const enumMembers: Array = []; + let exportModifiers: Array = []; + + if (node.modifiers !== undefined) { + exportModifiers = getExportKeyword(node.modifiers); + } + + node.members.forEach(value => { + const enumValueName = getPropertyName(value.name, sourceFile); + let enumValue = ''; + if (value.initializer !== undefined) { + enumValue = sourceFile.text.substring(value.initializer.pos, value.initializer.end).trimEnd().trimStart(); + } + const enumKind = value.initializer?.kind === undefined ? -1 : value.initializer?.kind; + enumMembers.push({ enumValueName: enumValueName, enumValue: enumValue, enumKind: enumKind }); + }); + + return { + enumName: enumName, + enumMembers: enumMembers, + exportModifiers: exportModifiers + }; +} + +export interface EnumEntity { + enumName: string, + enumMembers: Array, + exportModifiers: Array +} + +export interface MemberEntity { + enumValueName: string, + enumValue: string, + enumKind: number, +} diff --git a/mock-generate/src/declaration-node/functionDeclaration.ts b/mock-generate/src/declaration-node/functionDeclaration.ts new file mode 100644 index 00000000..7ed2f5f4 --- /dev/null +++ b/mock-generate/src/declaration-node/functionDeclaration.ts @@ -0,0 +1,31 @@ +import { FunctionDeclaration, Node, SourceFile } from 'typescript'; +import { getFunctionAndMethodReturnInfo, getParameter, ParameterEntity, ReturnTypeEntity } from '../common/commonUtils'; + +/** + * get function info + * @param node + * @param sourceFile + * @returns + */ +export function getFunctionDeclaration(node: Node, sourceFile: SourceFile): FunctionEntity { + const funcNode = node as FunctionDeclaration; + let functionName = ''; + const args: Array = []; + const returnType = getFunctionAndMethodReturnInfo(funcNode, sourceFile); + functionName = funcNode.name?.escapedText === undefined ? 'undefind' : funcNode.name.escapedText.toString(); + funcNode.parameters.forEach(value => { + args.push(getParameter(value, sourceFile)); + }); + + return { + functionName: functionName, + returnType: returnType, + args: args + }; +} + +export interface FunctionEntity { + functionName: string, + returnType: ReturnTypeEntity, + args: Array +} diff --git a/mock-generate/src/declaration-node/heritageClauseDeclaration.ts b/mock-generate/src/declaration-node/heritageClauseDeclaration.ts new file mode 100644 index 00000000..b736877c --- /dev/null +++ b/mock-generate/src/declaration-node/heritageClauseDeclaration.ts @@ -0,0 +1,27 @@ +import { HeritageClause, Node, SourceFile, SyntaxKind } from 'typescript'; + +/** + * get heritage info + * @param node + * @param sourceFile + * @returns + */ +export function getHeritageClauseDeclaration(node: Node, sourceFile: SourceFile): HeritageClauseEntity { + const HeritageClauseNode = node as HeritageClause; + const clauseToken = HeritageClauseNode.token === SyntaxKind.ExtendsKeyword ? 'extends' : 'implements'; + const types: Array = []; + + HeritageClauseNode.types.forEach(value => { + types.push(sourceFile.text.substring(value.pos, value.end).trimStart().trimEnd()); + }); + + return { + clauseToken: clauseToken, + types: types + }; +} + +export interface HeritageClauseEntity { + clauseToken: string, + types: Array +} diff --git a/mock-generate/src/declaration-node/importAndExportDeclaration.ts b/mock-generate/src/declaration-node/importAndExportDeclaration.ts new file mode 100644 index 00000000..b1373930 --- /dev/null +++ b/mock-generate/src/declaration-node/importAndExportDeclaration.ts @@ -0,0 +1,91 @@ +import { ExportAssignment, ExportDeclaration, ImportDeclaration, + ImportEqualsDeclaration, isImportDeclaration, Node, SourceFile } from 'typescript'; + +/** + * get current sourceFile all imports + * @param sourceFile + * @returns + */ +export function getImportDeclarationArray(sourceFile: SourceFile): Array { + const importDeclarations: Array = []; + sourceFile.forEachChild(node => { + if (isImportDeclaration(node)) { + importDeclarations.push(getImportDeclaration(node, sourceFile)); + } + }); + return importDeclarations; +} + +/** + * get module inner import info + * @param importEqualNode + * @param sourceFile + * @returns + */ +export function getModuleImportEqual(importEqualNode: ImportEqualsDeclaration, sourceFile: SourceFile): ImportEuqalEntity { + return { + importEqualName: importEqualNode.name.escapedText.toString(), + importEqualTypeName: sourceFile.text.substring(importEqualNode.moduleReference.pos, importEqualNode.moduleReference.end).trimStart().trimEnd(), + importEqualTypeKind: importEqualNode.moduleReference.kind + }; +} + +/** + * get export info + * @param exportNode + * @param sourceFile + * @returns + */ +export function getExportDeclaration(exportNode: ExportDeclaration, sourceFile: SourceFile): string { + return sourceFile.text.substring(exportNode.pos, exportNode.end).trimStart().trimEnd(); +} + +/** + * get import info + * @param node + * @param sourceFile + * @returns + */ +export function getImportDeclaration(node: Node, sourceFile: SourceFile): ImportElementEntity { + let importElements = ''; + const importNode = node as ImportDeclaration; + const importPath = sourceFile.text.substring(importNode.moduleSpecifier.pos, importNode.moduleSpecifier.end).trimStart().trimEnd(); + const importClause = importNode.importClause; + if (importClause !== undefined) { + importElements = sourceFile.text.substring(importClause.pos, importClause.end).trimStart().trimEnd(); + } + + return { + importPath: importPath, + importElements: importElements + }; +} + +/** + * get export info + * @param exportAssigment + * @param sourceFile + * @returns + */ +export function getExportAssignment(exportAssigment: ExportAssignment, sourceFile: SourceFile): Array { + const exportAssignments: Array = []; + if (exportAssigment.expression !== undefined) { + exportAssignments.push(sourceFile.text.substring(exportAssigment.expression.pos, exportAssigment.expression.end).trimStart().trimEnd()); + } + return exportAssignments; +} + +export interface ImportElementEntity { + importPath: string, + importElements: string +} + +export interface ExportElementEntity { + exportName: string +} + +export interface ImportEuqalEntity { + importEqualName: string, + importEqualTypeName: string, + importEqualTypeKind: number +} diff --git a/mock-generate/src/declaration-node/indexSignatureDeclaration.ts b/mock-generate/src/declaration-node/indexSignatureDeclaration.ts new file mode 100644 index 00000000..9aaac595 --- /dev/null +++ b/mock-generate/src/declaration-node/indexSignatureDeclaration.ts @@ -0,0 +1,21 @@ +import { IndexSignatureDeclaration, SourceFile } from 'typescript'; + +/** + * get index signature info + * @param indexSignature + * @param sourceFile + * @returns + */ +export function getIndexSignatureDeclaration(indexSignature: IndexSignatureDeclaration, sourceFile: SourceFile): IndexSignatureEntity { + return { + indexSignatureKey: 'key', + indexSignatureKind: indexSignature.type.kind, + indexSignatureTypeName: sourceFile.text.substring(indexSignature.type.pos, indexSignature.type.end).trimStart().trimEnd() + }; +} + +export interface IndexSignatureEntity { + indexSignatureKey: string, + indexSignatureKind: number, + indexSignatureTypeName: string +} diff --git a/mock-generate/src/declaration-node/interfaceDeclaration.ts b/mock-generate/src/declaration-node/interfaceDeclaration.ts new file mode 100644 index 00000000..d498adfb --- /dev/null +++ b/mock-generate/src/declaration-node/interfaceDeclaration.ts @@ -0,0 +1,89 @@ +import { + InterfaceDeclaration, isCallSignatureDeclaration, isConstructSignatureDeclaration, + isHeritageClause, isIndexSignatureDeclaration, isMethodSignature, isPropertySignature, + isTypeParameterDeclaration, SourceFile +} from 'typescript'; +import { getExportKeyword } from '../common/commonUtils'; +import { CallSignatureEntity, getCallSignatureDeclaration } from './callSignatureDeclaration'; +import { ConstructorEntity, getConstructorDeclaration } from './constructorDeclaration'; +import { getHeritageClauseDeclaration, HeritageClauseEntity } from './heritageClauseDeclaration'; +import { getIndexSignatureDeclaration, IndexSignatureEntity } from './indexSignatureDeclaration'; +import { getMethodSignatureDeclaration, MethodSignatureEntity } from './methodSignatureDeclaration'; +import { getPropertySignatureDeclaration, PropertySignatureEntity } from './propertySignatureDeclaration'; +import { getTypeParameterDeclaration, TypeParameterEntity } from './typeParameterDeclaration'; + +/** + * get interface info + * @param interfaceNode + * @param sourceFile + * @returns + */ +export function getInterfaceDeclaration(interfaceNode: InterfaceDeclaration, sourceFile: SourceFile): InterfaceEntity { + let exportModifiers: Array = []; + if (interfaceNode.modifiers !== undefined) { + exportModifiers = getExportKeyword(interfaceNode.modifiers); + } + + const interfaceName = interfaceNode.name.escapedText.toString(); + const heritageClauses: Array = []; + const interfaceConstructors: Array> = []; + const interfaceMethodSignature: Map> = new Map>(); + const interfacePropertySignatures: Array = []; + const callSignature: Array = []; + const typeParameters: Array = []; + const indexSignature: Array = []; + + interfaceNode.members.forEach(value => { + if (isPropertySignature(value)) { + interfacePropertySignatures.push(getPropertySignatureDeclaration(value, sourceFile)); + } else if (isMethodSignature(value)) { + const methodSignature = getMethodSignatureDeclaration(value, sourceFile); + if (interfaceMethodSignature.get(methodSignature.functionName) !== undefined) { + interfaceMethodSignature.get(methodSignature.functionName)?.push(methodSignature); + } else { + const methodSignatureArray: Array = []; + methodSignatureArray.push(methodSignature); + interfaceMethodSignature.set(methodSignature.functionName, methodSignatureArray); + } + } else if (isHeritageClause(value)) { + heritageClauses.push(getHeritageClauseDeclaration(value, sourceFile)); + } else if (isConstructSignatureDeclaration(value)) { + interfaceConstructors.push(getConstructorDeclaration(value, sourceFile)); + } else if (isCallSignatureDeclaration(value)) { + callSignature.push(getCallSignatureDeclaration(value, sourceFile)); + } else if (isTypeParameterDeclaration(value)) { + typeParameters.push(getTypeParameterDeclaration(value, sourceFile)); + } else if (isIndexSignatureDeclaration(value)) { + indexSignature.push(getIndexSignatureDeclaration(value, sourceFile)); + } else { + console.log('--------------------------- uncaught interface type start -----------------------'); + console.log('interfaceName: ' + interfaceName); + console.log(value); + console.log('--------------------------- uncaught interface type end -----------------------'); + } + }); + + return { + interfaceName: interfaceName, + typeParameters: typeParameters, + heritageClauses: heritageClauses, + interfaceConstructors: interfaceConstructors, + interfaceMethodSignature: interfaceMethodSignature, + interfacePropertySignatures: interfacePropertySignatures, + callSignatures: callSignature, + exportModifiers: exportModifiers, + indexSignature: indexSignature + }; +} + +export interface InterfaceEntity { + interfaceName: string, + typeParameters: Array, + heritageClauses: Array, + interfaceConstructors: Array>, + interfaceMethodSignature: Map>, + interfacePropertySignatures: Array, + callSignatures: Array, + exportModifiers: Array, + indexSignature: Array +} diff --git a/mock-generate/src/declaration-node/methodDeclaration.ts b/mock-generate/src/declaration-node/methodDeclaration.ts new file mode 100644 index 00000000..3bbedcac --- /dev/null +++ b/mock-generate/src/declaration-node/methodDeclaration.ts @@ -0,0 +1,64 @@ +import { isComputedPropertyName, MethodDeclaration, Node, SourceFile } from 'typescript'; +import { + getFunctionAndMethodReturnInfo, getModifiers, getParameter, + getPropertyName, ParameterEntity, ReturnTypeEntity +} from '../common/commonUtils'; + +/** + * get method info + * @param node + * @param sourceFile + * @returns + */ +export function getMethodDeclaration(node: Node, sourceFile: SourceFile): MethodEntity { + const methodNode = node as MethodDeclaration; + const functionName = { + name: '', + expressionKind: -1, + kind: -1 + }; + + const args: Array = []; + let modifiers: Array = []; + + if (methodNode.modifiers !== undefined) { + modifiers = getModifiers(methodNode.modifiers); + } + + const returnType = getFunctionAndMethodReturnInfo(methodNode, sourceFile); + functionName.name = getPropertyName(methodNode.name, sourceFile); + if (isComputedPropertyName(methodNode.name)) { + functionName.expressionKind = methodNode.name.expression.kind; + } + + functionName.kind = methodNode.name.kind; + + methodNode.parameters.forEach(value => { + args.push(getParameter(value, sourceFile)); + }); + + return { + modifiers: modifiers, + functionName: functionName, + returnType: returnType, + args: args + }; +} + +export interface StaticMethodEntity { + className: string, + methodEntity: MethodEntity +} + +export interface MethodEntity { + modifiers: Array, + functionName: FunctionNameEntity, + returnType: ReturnTypeEntity, + args: Array +} + +export interface FunctionNameEntity { + name: string, + expressionKind: number, + kind: number +} diff --git a/mock-generate/src/declaration-node/methodSignatureDeclaration.ts b/mock-generate/src/declaration-node/methodSignatureDeclaration.ts new file mode 100644 index 00000000..74ef04d0 --- /dev/null +++ b/mock-generate/src/declaration-node/methodSignatureDeclaration.ts @@ -0,0 +1,34 @@ +import { MethodSignature, Node, SourceFile } from 'typescript'; +import { + getFunctionAndMethodReturnInfo, getParameter, getPropertyName, + ParameterEntity, ReturnTypeEntity +} from '../common/commonUtils'; + +/** + * get interface signature info + * @param node + * @param sourceFile + * @returns + */ +export function getMethodSignatureDeclaration(node: Node, sourceFile: SourceFile): MethodSignatureEntity { + const methodSignatureNode = node as MethodSignature; + let functionName = ''; + const args: Array = []; + const returnType = getFunctionAndMethodReturnInfo(methodSignatureNode, sourceFile); + functionName = getPropertyName(methodSignatureNode.name, sourceFile); + methodSignatureNode.parameters.forEach(value => { + args.push(getParameter(value, sourceFile)); + }); + + return { + functionName: functionName, + returnType: returnType, + args: args + }; +} + +export interface MethodSignatureEntity { + functionName: string, + returnType: ReturnTypeEntity, + args: Array +} diff --git a/mock-generate/src/declaration-node/moduleDeclaration.ts b/mock-generate/src/declaration-node/moduleDeclaration.ts new file mode 100644 index 00000000..b38caf80 --- /dev/null +++ b/mock-generate/src/declaration-node/moduleDeclaration.ts @@ -0,0 +1,111 @@ +import { + isClassDeclaration, isEnumDeclaration, isExportDeclaration, isFunctionDeclaration, isIdentifier, + isImportEqualsDeclaration, isInterfaceDeclaration, isModuleBlock, isModuleDeclaration, isTypeAliasDeclaration, + isVariableStatement, ModuleDeclaration, Node, SourceFile +} from 'typescript'; +import { getExportKeyword } from '../common/commonUtils'; +import { ClassEntity, getClassDeclaration } from './classDeclaration'; +import { EnumEntity, getEnumDeclaration } from './enumDeclaration'; +import { FunctionEntity, getFunctionDeclaration } from './functionDeclaration'; +import { getExportDeclaration, getModuleImportEqual, ImportEuqalEntity } from './importAndExportDeclaration'; +import { getInterfaceDeclaration, InterfaceEntity } from './interfaceDeclaration'; +import { getTypeAliasDeclaration, TypeAliasEntity } from './typeAliasDeclaration'; +import { getVariableStatementDeclaration, StatementEntity } from './variableStatementResolve'; + +/** + * get module info + * @param node + * @param sourceFile + * @param fileName + * @returns + */ +export function getModuleDeclaration(node: Node, sourceFile: SourceFile, fileName: string): ModuleBlockEntity { + const moduleNode = node as ModuleDeclaration; + let moduleName = ''; + if (isIdentifier(moduleNode.name)) { + moduleName = moduleNode.name.escapedText.toString(); + } else { + moduleName = sourceFile.text.substring(moduleNode.name.pos, moduleNode.name.end).trimStart().trimEnd(); + } + + let exportModifiers: Array = []; + const modifiers = moduleNode.modifiers; + if (modifiers !== undefined) { + exportModifiers = getExportKeyword(modifiers); + } + + const typeAliasDeclarations: Array = []; + const classDeclarations: Array = []; + const interfaceDeclarations: Array = []; + const functionDeclarations: Map> = new Map>(); + const enumDeclarations: Array = []; + const moduleDeclarations: Array = []; + const variableStatements: Array> = []; + const moduleImportEquaqls: Array = []; + const exportDeclarations: Array = []; + const moduleBody = moduleNode.body; + + if (moduleBody !== undefined && isModuleBlock(moduleBody)) { + moduleBody.statements.forEach(value => { + if (isFunctionDeclaration(value)) { + const FunctionEntity = getFunctionDeclaration(value, sourceFile); + if (functionDeclarations.get(FunctionEntity.functionName) !== undefined) { + functionDeclarations.get(FunctionEntity.functionName)?.push(FunctionEntity); + } else { + const functionArray: Array = []; + functionArray.push(FunctionEntity); + functionDeclarations.set(FunctionEntity.functionName, functionArray); + } + } else if (isTypeAliasDeclaration(value)) { + typeAliasDeclarations.push(getTypeAliasDeclaration(value, sourceFile)); + } else if (isEnumDeclaration(value)) { + enumDeclarations.push(getEnumDeclaration(value, sourceFile)); + } else if (isClassDeclaration(value)) { + classDeclarations.push(getClassDeclaration(value, sourceFile)); + } else if (isInterfaceDeclaration(value)) { + interfaceDeclarations.push(getInterfaceDeclaration(value, sourceFile)); + } else if (isModuleDeclaration(value)) { + moduleDeclarations.push(getModuleDeclaration(value, sourceFile, fileName)); + } else if (isVariableStatement(value)) { + variableStatements.push(getVariableStatementDeclaration(value, sourceFile)); + } else if (isImportEqualsDeclaration(value)) { + moduleImportEquaqls.push(getModuleImportEqual(value, sourceFile)); + } else if (isExportDeclaration(value)) { + exportDeclarations.push(getExportDeclaration(value, sourceFile)); + } else { + console.log('--------------------------- uncaught module type start -----------------------'); + console.log('fileName: ' + fileName); + console.log(value); + console.log('--------------------------- uncaught module type end -----------------------'); + } + }); + } + + return { + moduleName: moduleName, + exportModifiers: exportModifiers, + typeAliasDeclarations: typeAliasDeclarations, + classDeclarations: classDeclarations, + interfaceDeclarations: interfaceDeclarations, + functionDeclarations: functionDeclarations, + enumDeclarations: enumDeclarations, + moduleDeclarations: moduleDeclarations, + variableStatements: variableStatements, + moduleImportEquaqls: moduleImportEquaqls, + exportDeclarations: exportDeclarations + }; +} + +export interface ModuleBlockEntity { + moduleName: string, + exportModifiers: Array, + typeAliasDeclarations: Array, + classDeclarations: Array, + interfaceDeclarations: Array, + functionDeclarations: Map>, + enumDeclarations: Array, + moduleDeclarations: Array, + variableStatements: Array>, + moduleImportEquaqls: Array, + exportDeclarations: Array +} diff --git a/mock-generate/src/declaration-node/propertyDeclaration.ts b/mock-generate/src/declaration-node/propertyDeclaration.ts new file mode 100644 index 00000000..488c0575 --- /dev/null +++ b/mock-generate/src/declaration-node/propertyDeclaration.ts @@ -0,0 +1,54 @@ +import { PropertyDeclaration, SourceFile } from 'typescript'; +import { getPropertyName } from '../common/commonUtils'; + +/** + * get property node info + * @param node + * @param sourceFile + * @returns + */ +export function getPropertyDeclaration(node: PropertyDeclaration, sourceFile: SourceFile): PropertyEntity { + let propertyName = ''; + let propertyTypeName = ''; + let kind = -1; + let isInitializer = false; + let initializer = ''; + const modifiers: Array = []; + + if (node.modifiers !== undefined) { + node.modifiers.forEach(value => { + modifiers.push(sourceFile.text.substring(value.pos, value.end)); + }); + } + + if (node.initializer !== undefined) { + isInitializer = true; + initializer = sourceFile.text.substring(node.initializer.pos, node.initializer.end).trimStart().trimEnd(); + } + + propertyName = getPropertyName(node.name, sourceFile); + + const propertyType = node.type; + if (propertyType !== undefined) { + propertyTypeName = sourceFile.text.substring(propertyType.pos, propertyType.end).trimStart().trimEnd(); + kind = propertyType.kind; + } + + return { + modifiers: modifiers, + propertyName: propertyName, + propertyTypeName: propertyTypeName, + kind: kind, + isInitializer: isInitializer, + initializer: initializer + }; +} + +export interface PropertyEntity { + modifiers: Array, + propertyName: string, + propertyTypeName: string, + kind: number, + isInitializer: boolean, + initializer: string +} diff --git a/mock-generate/src/declaration-node/propertySignatureDeclaration.ts b/mock-generate/src/declaration-node/propertySignatureDeclaration.ts new file mode 100644 index 00000000..1c46f166 --- /dev/null +++ b/mock-generate/src/declaration-node/propertySignatureDeclaration.ts @@ -0,0 +1,42 @@ +import { PropertySignature, SourceFile } from 'typescript'; +import { getPropertyName } from '../common/commonUtils'; + +/** + * get interface property signature info + * @param node + * @param sourceFile + * @returns + */ +export function getPropertySignatureDeclaration(node: PropertySignature, sourceFile: SourceFile): PropertySignatureEntity { + let propertyName = ''; + let propertyTypeName = ''; + let kind = -1; + + propertyName = getPropertyName(node.name, sourceFile); + const propertyType = node.type; + const modifiers: Array = []; + if (node.modifiers !== undefined) { + node.modifiers.forEach(value => { + modifiers.push(sourceFile.text.substring(value.pos, value.end)); + }); + } + + if (propertyType !== undefined) { + propertyTypeName = sourceFile.text.substring(propertyType.pos, propertyType.end).trimStart().trimEnd(); + kind = propertyType.kind; + } + + return { + modifiers: modifiers, + propertyName: propertyName, + propertyTypeName: propertyTypeName, + kind: kind + }; +} + +export interface PropertySignatureEntity { + modifiers: Array, + propertyName: string, + propertyTypeName: string, + kind: number +} diff --git a/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts b/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts new file mode 100644 index 00000000..ba4d0cff --- /dev/null +++ b/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts @@ -0,0 +1,149 @@ +import { + isClassDeclaration, isEnumDeclaration, isExportAssignment, isExportDeclaration, isFunctionDeclaration, + isImportDeclaration, isInterfaceDeclaration, isModuleDeclaration, isTypeAliasDeclaration, isVariableStatement, + SourceFile, SyntaxKind +} from 'typescript'; +import { ClassEntity, getClassDeclaration } from './classDeclaration'; +import { EnumEntity, getEnumDeclaration } from './enumDeclaration'; +import { FunctionEntity, getFunctionDeclaration } from './functionDeclaration'; +import { getExportAssignment, getImportDeclaration, ImportElementEntity } from './importAndExportDeclaration'; +import { getInterfaceDeclaration, InterfaceEntity } from './interfaceDeclaration'; +import { StaticMethodEntity } from './methodDeclaration'; +import { getModuleDeclaration, ModuleBlockEntity } from './moduleDeclaration'; +import { getTypeAliasDeclaration, TypeAliasEntity } from './typeAliasDeclaration'; +import { getVariableStatementDeclaration, StatementEntity } from './variableStatementResolve'; + +/** + * assembly all sourceFile node info + * @param sourceFile + * @param fileName + * @returns + */ +export function getSourceFileAssembly(sourceFile: SourceFile, fileName: string): SourceFileEntity { + const importDeclarations: Array = []; + const moduleDeclarations: Array = []; + const typeAliasDeclarations: Array = []; + const classDeclarations: Array = []; + const interfaceDeclarations: Array = []; + const enumDeclarations: Array = []; + let exportAssignment: Array = []; + const staticMethods: Array> = []; + const exportDeclarations: Array = []; + + sourceFile.forEachChild(node => { + if (isImportDeclaration(node)) { + importDeclarations.push(getImportDeclaration(node, sourceFile)); + } else if (isModuleDeclaration(node)) { + moduleDeclarations.push(getModuleDeclaration(node, sourceFile, fileName)); + } else if (isTypeAliasDeclaration(node)) { + typeAliasDeclarations.push(getTypeAliasDeclaration(node, sourceFile)); + } else if (isClassDeclaration(node)) { + let isDefaultExportClass = false; + if (node.modifiers !== undefined) { + node.modifiers.forEach(value => { + if (value.kind === SyntaxKind.DefaultKeyword) { + isDefaultExportClass = true; + } + }); + } + if (isDefaultExportClass) { + const classDeclarationEntity = getClassDeclaration(node, sourceFile); + classDeclarations.push(classDeclarationEntity); + if (classDeclarationEntity.staticMethods.length > 0) { + staticMethods.push(classDeclarationEntity.staticMethods); + } + } + } else if (isInterfaceDeclaration(node)) { + interfaceDeclarations.push(getInterfaceDeclaration(node, sourceFile)); + } else if (isExportAssignment(node)) { + exportAssignment = getExportAssignment(node, sourceFile); + } else if (isEnumDeclaration(node)) { + enumDeclarations.push(getEnumDeclaration(node, sourceFile)); + } else if (isExportDeclaration(node)) { + exportDeclarations.push(sourceFile.text.substring(node.pos, node.end).trimStart().trimEnd()); + } else { + if (node.kind !== SyntaxKind.EndOfFileToken && !isFunctionDeclaration(node) && !isVariableStatement(node)) { + console.log('--------------------------- uncaught sourceFile type start -----------------------'); + console.log('fileName: ' + fileName); + console.log(node); + console.log('--------------------------- uncaught sourceFile type end -----------------------'); + } + } + }); + + return { + importDeclarations: importDeclarations, + moduleDeclarations: moduleDeclarations, + typeAliasDeclarations: typeAliasDeclarations, + classDeclarations: classDeclarations, + interfaceDeclarations: interfaceDeclarations, + enumDeclarations: enumDeclarations, + exportAssignment: exportAssignment, + staticMethods: staticMethods, + exportDeclarations: exportDeclarations + }; +} + +/** + * get default export class + * @param sourceFile + * @returns + */ +export function getDefaultExportClassDeclaration(sourceFile: SourceFile): Array { + const defaultExportClass: Array = []; + sourceFile.forEachChild(node => { + if (isClassDeclaration(node)) { + defaultExportClass.push(getClassDeclaration(node, sourceFile)); + } + }); + return defaultExportClass; +} + +/** + * get sourceFile const variable statement + * @param sourceFile + * @returns + */ +export function getSourceFileVariableStatements(sourceFile: SourceFile): Array> { + const variableStatements: Array> = []; + sourceFile.forEachChild(node => { + if (isVariableStatement(node)) { + variableStatements.push(getVariableStatementDeclaration(node, sourceFile)); + } + }); + return variableStatements; +} + +/** + * get sourcefile functions + * @param sourceFile + * @returns + */ +export function getSourceFileFunctions(sourceFile: SourceFile): Map> { + const functionDeclarations: Map> = new Map>(); + sourceFile.forEachChild(node => { + if (isFunctionDeclaration(node)) { + const functionEntity = getFunctionDeclaration(node, sourceFile); + if (functionDeclarations.get(functionEntity.functionName) !== undefined) { + functionDeclarations.get(functionEntity.functionName)?.push(functionEntity); + } else { + const functionArray: Array = []; + functionArray.push(functionEntity); + functionDeclarations.set(functionEntity.functionName, functionArray); + } + } + }); + return functionDeclarations; +} + +export interface SourceFileEntity { + importDeclarations: Array, + moduleDeclarations: Array, + typeAliasDeclarations: Array, + classDeclarations: Array, + interfaceDeclarations: Array, + enumDeclarations: Array, + exportAssignment: Array, + staticMethods: Array>, + exportDeclarations: Array +} diff --git a/mock-generate/src/declaration-node/typeAliasDeclaration.ts b/mock-generate/src/declaration-node/typeAliasDeclaration.ts new file mode 100644 index 00000000..712d6b12 --- /dev/null +++ b/mock-generate/src/declaration-node/typeAliasDeclaration.ts @@ -0,0 +1,71 @@ +import { + isTypeLiteralNode, isTypeReferenceNode, + isUnionTypeNode, Node, SourceFile, TypeAliasDeclaration +} from 'typescript'; + +/** + * get type alias info + * @param node + * @param sourceFile + * @returns + */ +export function getTypeAliasDeclaration(node: Node, sourceFile: SourceFile): TypeAliasEntity { + const typeAliasNode = node as TypeAliasDeclaration; + const typeAliasName = typeAliasNode.name.escapedText.toString(); + const typeAliasTypeKind = typeAliasNode.type.kind; + const typeAliasTypeElements: Array = []; + const modifiers: Array = []; + + const modifiersNode = typeAliasNode.modifiers; + if (modifiersNode !== undefined) { + modifiersNode.forEach(value => { + modifiers.push(value.kind); + }); + } + + const typeAliasTypeElementsNode = typeAliasNode.type; + if (typeAliasTypeElementsNode !== undefined) { + if (isUnionTypeNode(typeAliasTypeElementsNode)) { + typeAliasTypeElementsNode.types.forEach(value => { + const typeName = sourceFile.text.substring(value.pos, value.end).trimStart().trimEnd(); + const typeKind = value.kind; + typeAliasTypeElements.push({ typeName: typeName, typeKind: typeKind }); + }); + } else if (isTypeReferenceNode(typeAliasTypeElementsNode)) { + const typeName = sourceFile.text.substring(typeAliasTypeElementsNode.typeName.pos, typeAliasTypeElementsNode.typeName.end).trimStart().trimEnd(); + typeAliasTypeElements.push({ typeName: typeName, typeKind: typeAliasTypeElementsNode.typeName.kind }); + } else if (isTypeLiteralNode(typeAliasTypeElementsNode)) { + typeAliasTypeElementsNode.members.forEach(value => { + const typeName = sourceFile.text.substring(value.pos, value.end).trimStart().trimEnd(); + const typeKind = value.kind; + typeAliasTypeElements.push({ typeName: typeName, typeKind: typeKind }); + }); + } else { + typeAliasTypeElements.push( + { + typeName: sourceFile.text.substring(typeAliasTypeElementsNode.pos, typeAliasTypeElementsNode.end), + typeKind: typeAliasTypeElementsNode.kind + } + ); + } + } + + return { + typeAliasName: typeAliasName, + typeAliasTypeKind: typeAliasTypeKind, + typeAliasTypeElements: typeAliasTypeElements, + modifiers: modifiers + }; +} + +export interface TypeAliasEntity { + typeAliasName: string, + typeAliasTypeKind: number, + typeAliasTypeElements: Array, + modifiers: Array +} + +export interface TypeAliasTypeEntity { + typeName: string, + typeKind: number +} diff --git a/mock-generate/src/declaration-node/typeParameterDeclaration.ts b/mock-generate/src/declaration-node/typeParameterDeclaration.ts new file mode 100644 index 00000000..b1b7a4be --- /dev/null +++ b/mock-generate/src/declaration-node/typeParameterDeclaration.ts @@ -0,0 +1,35 @@ +import { Node, SourceFile, TypeParameterDeclaration } from 'typescript'; + +/** + * get generic type node info + * @param node + * @param sourceFile + * @returns + */ +export function getTypeParameterDeclaration(node: Node, sourceFile: SourceFile): TypeParameterEntity { + const typeParameterNode = node as TypeParameterDeclaration; + const typeParameterName = typeParameterNode.name.escapedText.toString(); + let constraitValue = ''; + let constraintDefaultValue = ''; + const constraint = typeParameterNode.constraint; + if (constraint !== undefined) { + constraitValue = sourceFile.text.substring(constraint.pos, constraint.end).trimStart().trimEnd(); + } + + const defaultValue = typeParameterNode.default; + if (defaultValue !== undefined) { + constraintDefaultValue = sourceFile.text.substring(defaultValue.pos, defaultValue.end).trimStart().trimEnd(); + } + + return { + typeParameterName: typeParameterName, + constraitValue: constraitValue, + constraintDefaultValue: constraintDefaultValue + }; +} + +export interface TypeParameterEntity { + typeParameterName: string, + constraitValue: string, + constraintDefaultValue: string +} diff --git a/mock-generate/src/declaration-node/variableStatementResolve.ts b/mock-generate/src/declaration-node/variableStatementResolve.ts new file mode 100644 index 00000000..57363ccd --- /dev/null +++ b/mock-generate/src/declaration-node/variableStatementResolve.ts @@ -0,0 +1,39 @@ +import { isIdentifier, SourceFile, VariableStatement } from 'typescript'; + +/** + * get const declaration variable + * @param variableStatement + * @param sourceFile + * @returns + */ +export function getVariableStatementDeclaration(variableStatement: VariableStatement, sourceFile: SourceFile): Array { + const statementsArray: Array = []; + variableStatement.declarationList.declarations.forEach(value => { + let statementName = ''; + let initializer = ''; + let typeName = ''; + let typeKind = -1; + + if (isIdentifier(value.name)) { + statementName = value.name.escapedText.toString(); + } else { + statementName = sourceFile.text.substring(value.pos, value.end).trimStart().trimEnd(); + } + if (value.initializer !== undefined) { + initializer = sourceFile.text.substring(value.initializer.pos, value.initializer.end); + } + if (value.type !== undefined) { + typeName = sourceFile.text.substring(value.type.pos, value.type.end); + typeKind = value.type.kind; + } + statementsArray.push({ statementName: statementName, typeName: typeName, typeKind: typeKind, initializer: initializer }); + }); + return statementsArray; +} + +export interface StatementEntity { + statementName: string, + typeName: string, + typeKind: number, + initializer: string +} diff --git a/mock-generate/tsconfig.json b/mock-generate/tsconfig.json new file mode 100644 index 00000000..459b2605 --- /dev/null +++ b/mock-generate/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "allowJs": true, + "moduleResolution": "node", + "module": "commonjs", + "target": "ES2019", + "outDir": "dist", + "esModuleInterop": true, + "types": [ + "node" + ], + "typeRoots": [ + "./node_modules/@types" + ] + }, + "include": [ + "./src/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/runtime/main/model/selector.ts b/runtime/main/model/selector.ts index 2290bb19..cde3e3d0 100644 --- a/runtime/main/model/selector.ts +++ b/runtime/main/model/selector.ts @@ -19,7 +19,7 @@ import { Log } from '../../utils/index'; import { watch } from './directive'; -import { parse, Selector } from '../../css-what/src/index'; +import { parse, Selector } from '../../css-what/src/index'; import Element from '../../vdom/Element'; import Vm from './index'; import { cssType } from './vmOptions'; diff --git a/runtime/vdom/Element.ts b/runtime/vdom/Element.ts index 6ca28f43..68083815 100644 --- a/runtime/vdom/Element.ts +++ b/runtime/vdom/Element.ts @@ -34,8 +34,8 @@ import { FragBlockInterface, import Vm from '../main/model'; import { CSS_INHERITANCE } from '../main/app/bundle'; import {interceptCallback} from '../main/manage/event/callbackIntercept'; -import {mockwebgl} from '../main/extend/systemplugin/napi/webgl'; -import {mockwebgl2} from '../main/extend/systemplugin/napi/webgl2'; +import {mockWebgl} from '../main/extend/systemplugin/napi/webgl/webgl'; +import {mockWebgl2} from '../main/extend/systemplugin/napi/webgl/webgl2'; import { VmOptions } from '../main/model/vmOptions'; /** * Element is a basic class to describe a tree node in vdom. @@ -84,9 +84,9 @@ class Element extends Node { // support aceapp callback style args = interceptCallback(args); if (args[0] === 'webgl') { - return mockwebgl(); + return mockWebgl(); } else if (args[0] === 'webgl2') { - return mockwebgl2(); + return mockWebgl2(); } const ret = taskCenter.send('component', { ref: this.ref,