From f8c2b81fe175b44a147a1ab24da0419316a9ccbe Mon Sep 17 00:00:00 2001 From: harttle Date: Wed, 28 Oct 2020 18:23:08 +0800 Subject: [PATCH] feat: is directive --- package-lock.json | 17 +++++++---------- package.json | 6 +++--- src/models/component-info.ts | 14 +++++++------- src/parsers/component-class-parser.ts | 23 +++-------------------- src/parsers/san-file-parser.ts | 17 ++++++++++++++--- src/target-js/compilers/anode-compiler.ts | 2 +- 6 files changed, 35 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02cf5793..c6355968 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11817,19 +11817,16 @@ "dev": true }, "san": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/san/-/san-3.9.2.tgz", - "integrity": "sha512-yr2k1zCLPSA2cEVol0StDLOhpY8BLk5ce5Tt9DvFxutkV1845h4pxcMIoIrOGyDZbSodCEfFb+tLTSh8ub8SRQ==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/san/-/san-3.9.5.tgz", + "integrity": "sha512-g746ljkycqtIin38dzxhfQfEPgt2IC04G5TZH+qxIrigM107zYw5J/8hdcQiB06XolB3EK3AiZQx2EZpjII7pQ==", "dev": true }, "san-html-cases": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/san-html-cases/-/san-html-cases-2.1.0.tgz", - "integrity": "sha512-y+G8k9NY69vgjC/AXhOJhF5q5I9A1dpYdxWiv2XMOKtoTPoOmtZ/a6cO76Wy2K8cBBViTSvm4vmRKf/VhBOmLg==", - "dev": true, - "requires": { - "san": "^3.9.2" - } + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/san-html-cases/-/san-html-cases-3.10.1.tgz", + "integrity": "sha512-LO9w8RDq0PYevY8tYjBFLwKMsQo7bEmp4wigZ3o8mPQ4pGHhjhFVte7UHD656ZLa1YaMFJ5NHToajl5pTre3ZA==", + "dev": true }, "san-ssr-target-fake-cmd": { "version": "1.0.0", diff --git a/package.json b/package.json index a5a284bb..c358dfb7 100644 --- a/package.json +++ b/package.json @@ -77,8 +77,8 @@ "handlebars": "^4.7.6", "jest": "^26.2.2", "mustache": "^4.0.1", - "san": "^3.9.2", - "san-html-cases": "^2.1.0", + "san": "^3.9.5", + "san-html-cases": "^3.10.1", "san-ssr-target-fake-cmd": "^1.0.0", "san-ssr-target-fake-esm": "^1.0.0", "semantic-release": "^17.1.1", @@ -99,7 +99,7 @@ "yargs": "^15.4.1" }, "peerDependencies": { - "san": "^3.9.2" + "san": "^3.9.5" }, "release": { "branch": "master", diff --git a/src/models/component-info.ts b/src/models/component-info.ts index 1597442a..dfd54a91 100644 --- a/src/models/component-info.ts +++ b/src/models/component-info.ts @@ -13,12 +13,12 @@ type TrimWhitespace = 'none' | 'blank' | 'all' | undefined export interface ComponentInfo { id: string, root: ANode, - childComponents: Map + childComponents: Map hasMethod (name: string): boolean initData?(): any, getComputedNames (): string[] getFilterNames (): string[] - getChildComponentRenference (aNode: ANode): ComponentReference | undefined + getChildComponentRenference (tagName: string): ComponentReference | undefined } /** @@ -35,15 +35,15 @@ abstract class ComponentInfoImpl + public readonly childComponents: Map ) {} abstract hasMethod (name: string): boolean abstract getComputedNames (): string[] abstract getFilterNames (): string[] - getChildComponentRenference (aNode: ANode): R | undefined { - return this.childComponents.get(aNode) || this.childComponents.get(aNode.tagName) + getChildComponentRenference (tagName: string): R | undefined { + return this.childComponents.get(tagName) } } @@ -58,7 +58,7 @@ export class DynamicComponentInfo extends ComponentInfoImpl, + childComponents: Map, public readonly componentClass: ComponentClass ) { super(id, root, childComponents) @@ -136,7 +136,7 @@ export class TypedComponentInfo extends ComponentInfoImpl implements ComponentIn constructor ( id: string, root: ANode, - childComponents: Map, + childComponents: Map, public readonly classDeclaration: ClassDeclaration ) { super(id, root, childComponents) diff --git a/src/parsers/component-class-parser.ts b/src/parsers/component-class-parser.ts index 27efd9cf..69802f57 100644 --- a/src/parsers/component-class-parser.ts +++ b/src/parsers/component-class-parser.ts @@ -4,7 +4,6 @@ import { DynamicSanSourceFile } from '../models/san-source-file' import { DynamicComponentInfo } from '../models/component-info' import { getMember } from '../utils/lang' import { isComponentLoader, ComponentClass } from '../models/component' -import { visitANodeRecursively } from '../utils/anode-util' import { parseAndNormalizeTemplate } from './parse-template' import { componentID, DynamicComponentReference } from '../models/component-reference' @@ -52,18 +51,16 @@ export class ComponentClassParser { const trimWhitespace = getMember<'none' | 'blank' | 'all'>(componentClass, 'trimWhitespace') const delimiters = getMember<[string, string]>(componentClass, 'delimiters') const rootANode = parseAndNormalizeTemplate(template, { trimWhitespace, delimiters }) - const childComponents = this.getChildComponentClasses(componentClass, rootANode) + const childComponents = this.getChildComponentClasses(componentClass) return new DynamicComponentInfo(id, rootANode, childComponents, componentClass) } /** * 从组件 class 得到子组件 class - * - 从 .components 属性获取 - * - 从 .getComponentType() 方法获取 */ - getChildComponentClasses (parentComponentClass: ComponentClass, rootANode: ANode): Map { - const children: Map = new Map() + getChildComponentClasses (parentComponentClass: ComponentClass): Map { + const children: Map = new Map() const components: { [key: string]: ComponentConstructor<{}, {}> } = getMember(parentComponentClass, 'components', {}) for (const [tagName, componentClass] of Object.entries(components)) { @@ -74,20 +71,6 @@ export class ComponentClassParser { componentClass }) } - - const getComponentType = parentComponentClass.prototype.getComponentType - if (typeof getComponentType !== 'function') return children - - visitANodeRecursively(rootANode, (aNode: ANode) => { - const childClazz: ComponentClass = getComponentType(aNode) - if (!childClazz) return - - children.set(aNode, { - specifier: '.', - id: componentID(childClazz === this.root, () => this.getOrSetID(childClazz)), - componentClass: childClazz - }) - }) return children } diff --git a/src/parsers/san-file-parser.ts b/src/parsers/san-file-parser.ts index a89fdeda..80620c11 100644 --- a/src/parsers/san-file-parser.ts +++ b/src/parsers/san-file-parser.ts @@ -32,8 +32,11 @@ export class SanFileParser { return this.parser.parse() } - expandToSanComponent (options: ObjectExpression) { - const opts = { ...options } + /** + * 把简写的 san options 替换为 san Component。 + * { inited(){} } -> require('san').defineComponent({ inited(){} }) + */ + private expandToSanComponent (options: ObjectExpression) { const defineComponent: CallExpression = { type: 'CallExpression', callee: { @@ -48,12 +51,17 @@ export class SanFileParser { computed: false, optional: false }, - arguments: [opts], + arguments: [{ ...options }], optional: false } Object.assign(options, defineComponent) } + /** + * 把模板字符串插入到 san 组件定义中 + * - 情况一:defineComponent({ inited(){} }) -> defineComponent({ inited(){}, template: '
...
' }) + * - 情况二:class XComponent { constructor() {} } -> class XComponent { constructor() { this.template='
...
' } } + */ private insertTemplate (expr: Node) { if (isCallExpression(expr)) { assert(expr.arguments[0], 'cannot parse san script') @@ -83,6 +91,9 @@ export class SanFileParser { } } + /** + * 创建给 this.template 赋值为 this.templateContent 的表达式 + */ private createTemplateAssignmentExpression (): ExpressionStatement { return { type: 'ExpressionStatement', diff --git a/src/target-js/compilers/anode-compiler.ts b/src/target-js/compilers/anode-compiler.ts index 95c512b0..7ef4d892 100644 --- a/src/target-js/compilers/anode-compiler.ts +++ b/src/target-js/compilers/anode-compiler.ts @@ -40,7 +40,7 @@ export class ANodeCompiler { if (TypeGuards.isATemplateNode(aNode)) return this.compileTemplate(aNode) if (TypeGuards.isAFragmentNode(aNode)) return this.compileFragment(aNode) - const ref = this.componentInfo.getChildComponentRenference(aNode) + const ref = this.componentInfo.getChildComponentRenference(aNode.tagName) if (ref) { return this.compileComponent(aNode, ref, isRootElement) }