Skip to content

Commit

Permalink
feat: support ts2php modules config, close #8
Browse files Browse the repository at this point in the history
  • Loading branch information
harttle committed Nov 4, 2019
1 parent 015c594 commit fd072c0
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 19 deletions.
11 changes: 7 additions & 4 deletions src/target-php/compilers/ts2php.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import { compile } from 'ts2php'
import { keyBy } from 'lodash'
import { SourceFile } from 'ts-morph'
import debugFactory from 'debug'

const debug = debugFactory('san-ssr:ts2php')

export type ModuleInfo = {
export interface Modules {
[key:string]: ModuleInfo
}

type ModuleInfo = {
name: string,
required?: boolean,
namespace?: string
}

export function generatePHPCode (sourceFile: SourceFile, modules: ModuleInfo[], compilerOptions, nsPrefix: string) {
export function generatePHPCode (sourceFile: SourceFile, modules: Modules, compilerOptions, nsPrefix: string) {
debug('compile', sourceFile.getFilePath(), 'options:', modules, 'compilerOptions:', compilerOptions)
debug('source code:', sourceFile.getFullText())

const options = {
source: sourceFile.getFullText(),
emitHeader: false,
plugins: [],
modules: keyBy(modules, 'name'),
modules,
helperNamespace: `\\${nsPrefix}runtime\\`,
compilerOptions
}
Expand Down
28 changes: 15 additions & 13 deletions src/target-php/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getInlineDeclarations } from '../parsers/dependency-resolver'
import { keyBy, assign } from 'lodash'
import { isReserved } from './util'
import { ModuleInfo, generatePHPCode } from './compilers/ts2php'
import { Modules, generatePHPCode } from './compilers/ts2php'
import { transformAstToPHP } from './transformers/index'
import { Project } from 'ts-morph'
import { RendererCompiler } from './compilers/renderer-compiler'
Expand All @@ -25,34 +26,35 @@ export type ToPHPCompilerOptions = {
export class ToPHPCompiler implements Compiler {
private root: string
private tsConfigFilePath: string
private requiredModules: ModuleInfo[]
private ts2phpModules: Modules
private project: Project

constructor ({
tsConfigFilePath = getDefaultConfigPath(),
project
}: ToPHPCompilerOptions) {
this.project = project
this.requiredModules = [{
this.ts2phpModules = keyBy([{
name: process.env.SAN_SSR_PACKAGE_NAME || 'san-ssr',
required: true
}, {
name: 'san',
required: true,
namespace: '\\san\\runtime\\'
}]
}], 'name')
this.root = tsConfigFilePath.split(sep).slice(0, -1).join(sep)
this.tsConfigFilePath = tsConfigFilePath
}

public compile (sanApp: SanApp, {
funcName = 'render',
nsPrefix = 'san\\',
emitHeader = true
emitHeader = true,
modules = {}
}) {
const emitter = new PHPEmitter(emitHeader)
this.compileRenderer(emitter, funcName, nsPrefix, sanApp)
this.compileComponents(sanApp, emitter, nsPrefix)
this.compileComponents(sanApp, emitter, nsPrefix, modules)
emitRuntime(emitter, nsPrefix)
return emitter.fullText()
}
Expand All @@ -77,38 +79,38 @@ export class ToPHPCompiler implements Compiler {
emitter.endNamespace()
}

public compileComponent (sourceFile: SanSourceFile, nsPrefix: string) {
public compileComponent (sourceFile: SanSourceFile, nsPrefix: string, modules: Modules) {
if (!sourceFile.tsSourceFile) return ''

transformAstToPHP(sourceFile)
const tsconfig = require(this.tsConfigFilePath)
const requiredModules = [...this.requiredModules]
modules = { ...this.ts2phpModules, ...modules }
for (const decl of getInlineDeclarations(sourceFile.tsSourceFile)) {
const ns = nsPrefix + this.ns(decl.getModuleSpecifierSourceFile().getFilePath())
const literal = decl.getModuleSpecifierValue()
requiredModules.push({
modules[literal] = {
name: literal,
required: true,
namespace: '\\' + ns + '\\'
})
}
}
return generatePHPCode(
sourceFile.tsSourceFile,
requiredModules,
modules,
tsconfig['compilerOptions'],
nsPrefix
)
}

public compileComponents (entryComp: SanApp, emitter: PHPEmitter, nsPrefix: string) {
public compileComponents (entryComp: SanApp, emitter: PHPEmitter, nsPrefix: string, modules: Modules) {
const registry = new ComponentRegistry()
for (const [path, sourceFile] of entryComp.projectFiles) {
registry.registerComponents(sourceFile)

emitter.beginNamespace(nsPrefix + this.ns(path))
emitter.writeLine(`use ${nsPrefix}runtime\\_;`)
emitter.writeLine(`use ${nsPrefix}runtime\\Component;`)
emitter.writeLines(this.compileComponent(sourceFile, nsPrefix))
emitter.writeLines(this.compileComponent(sourceFile, nsPrefix, modules))
emitter.endNamespace()
}
registry.writeComponentRegistry(nsPrefix, path => this.ns(path), emitter)
Expand Down
5 changes: 4 additions & 1 deletion src/target-php/transformers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { refactorComputedProperty } from './refactor-computed-property'
const uselessComponentProps = ['components']

export function transformAstToPHP (sourceFile: SanSourceFile) {
sourceFile.fakeProperties.forEach(prop => prop.remove())
sourceFile.fakeProperties.forEach(prop => {
console.log(prop.getName())
prop.remove()
})

const sanssr = process.env.SAN_SSR_PACKAGE_NAME || 'san-ssr'

Expand Down
5 changes: 4 additions & 1 deletion test/stub/b.comp.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Component } from 'san'
import Foo from './foo'
import { defaultTo } from 'lodash'

export default class B extends Component {
public static template = 'B'
someMethod () {
console.log(defaultTo(0, 10))
}
}
20 changes: 20 additions & 0 deletions test/unit/to-php-compiler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,24 @@ describe('ToPHPCompiler', function () {
expect(result).toContain('ComponentRegistry::$comps = [')
expect(result).toContain('"0" => \'\\san\\stub\\aComp\\A\'')
})

it('should respect modules config for ts2php', function () {
const filepath = resolve(__dirname, '../stub/b.comp.ts')
const project = new Project({ tsConfigFilePath })
const parser = new SanAppParser(project)
const result1 = cc.compile(parser.parseSanApp(filepath), {})

expect(result1).toContain('require_once("lodash")')

const result2 = cc.compile(parser.parseSanApp(filepath), {
modules: {
lodash: {
name: 'lodash',
required: true
}
}
})

expect(result2).not.toContain('require_once("lodash")')
})
})

0 comments on commit fd072c0

Please sign in to comment.