Skip to content

Commit

Permalink
fix: 输入为 TypeScript 时不调用构造函数
Browse files Browse the repository at this point in the history
原则上 SSR 期间不调用 san 核心代码,构造函数会调用基类,而基类在 san
核心里,因此违反了这一点。
  • Loading branch information
harttle committed Jul 31, 2020
1 parent a0afdc4 commit 40bf654
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/models/san-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class SanProject {
if (/\.ts$/.test(filePath)) {
if (!this.tsProject) throw new Error(`Error parsing ${input}, tsconfig not specified`)
const sourceFile = this.createOrRefreshSourceFile(this.tsProject, filePath, fileContent)
return new TypeScriptSanParser(sourceFile).parse()
return new TypeScriptSanParser().parse(sourceFile)
}
return new ComponentClassParser(require(filePath), filePath).parse()
}
Expand Down
15 changes: 8 additions & 7 deletions src/parsers/typescript-san-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,23 @@ const debug = debugFactory('ts-component-parser')
* 把包含 San 组件定义的 TypeScript 源码,通过静态分析(AST),得到组件信息。
*/
export class TypeScriptSanParser {
constructor (
private readonly sourceFile: SourceFile
) {}

parse () {
const classDeclarations = getComponentDeclarations(this.sourceFile).map(normalizeComponentClass)
parse (sourceFile: SourceFile) {
const classDeclarations = getComponentDeclarations(sourceFile).map(normalizeComponentClass)
const defaultClassDeclaration = classDeclarations.find(clazz => clazz.isDefaultExport())
const componentInfos: TypedComponentInfo[] = classDeclarations.map(decl => this.parseComponentClassDeclaration(decl, defaultClassDeclaration))
return new TypedSanSourceFile(componentInfos, this.sourceFile, componentInfos.find(info => info.classDeclaration.isDefaultExport()))
return new TypedSanSourceFile(componentInfos, sourceFile, componentInfos.find(info => info.classDeclaration.isDefaultExport()))
}

private parseComponentClassDeclaration (classDeclaration: ClassDeclaration, defaultClassDeclaration?: ClassDeclaration): TypedComponentInfo {
const template = getPropertyStringValue(classDeclaration, 'template', '')
const trimWhitespace = getPropertyStringValue<'none' | 'blank' | 'all'>(classDeclaration, 'trimWhitespace')
const delimiters = getPropertyStringArrayValue<[string, string]>(classDeclaration, 'delimiters')
const childComponents = getChildComponents(classDeclaration, defaultClassDeclaration)

for (const constructorDelcaration of classDeclaration.getConstructors()) {
constructorDelcaration.remove()
}

return new TypedComponentInfo(
classDeclaration.isDefaultExport() ? getDefaultExportedComponentID() : getExportedComponentID(classDeclaration.getName()!),
template,
Expand Down
20 changes: 19 additions & 1 deletion test/unit/parsers/typescript-san-parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,26 @@ describe('.parseFromTypeScript()', () => {
class Foo extends Component {}
export default class Bar extends Component {}
`)
const sourceFile = new TypeScriptSanParser(file).parse()
const sourceFile = new TypeScriptSanParser().parse(file)
expect(sourceFile.componentInfos[0].classDeclaration.isDefaultExport()).toBe(false)
expect(sourceFile.componentInfos[1].classDeclaration.isDefaultExport()).toBe(true)
})

it('should remove constructors', function () {
const file = proj.createSourceFile('foo.ts', `
import { Component } from 'san'
function foo () {}
export class MyComponent extends Component {
foo = 'bar'
constructor() {
foo()
}
}
`)
const sourceFile = new TypeScriptSanParser().parse(file)
expect(sourceFile.componentInfos).toHaveLength(1)

const [info] = sourceFile.componentInfos
expect(info.classDeclaration.getConstructors()).toHaveLength(0)
})
})
2 changes: 1 addition & 1 deletion test/unit/target-js/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('ToJSCompiler', () => {
import { Component } from 'san';
class Foo extends Component {}
`)
expect(() => cc.compileToSource(new TypeScriptSanParser(sourceFile).parse())).not.toThrow()
expect(() => cc.compileToSource(new TypeScriptSanParser().parse(sourceFile))).not.toThrow()
})
})
})

0 comments on commit 40bf654

Please sign in to comment.