Skip to content

Commit

Permalink
fix: refactor non-constant property initializer for php, fixes #16
Browse files Browse the repository at this point in the history
  • Loading branch information
harttle committed Nov 7, 2019
1 parent 1b044cf commit b112ed5
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 38 deletions.
2 changes: 1 addition & 1 deletion src/target-php/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getInlineDeclarations } from '../parsers/dependency-resolver'
import { keyBy } from 'lodash'
import { isReserved } from './util'
import { isReserved } from './utils/lang'
import { Modules, generatePHPCode } from './compilers/ts2php'
import { transformAstToPHP } from './transformers/index'
import { Project } from 'ts-morph'
Expand Down
5 changes: 3 additions & 2 deletions src/target-php/transformers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isReserved, removeObjectLiteralInitiator } from '../util'
import { isReserved } from '../utils/lang'
import { refactorMemberInitializer } from './refactor-member-initializer'
import { SanSourceFile } from '../..'
import { refactorFiltersProperty } from './refactor-filters-property'
import { refactorComputedProperty } from './refactor-computed-property'
Expand Down Expand Up @@ -26,7 +27,7 @@ export function transformAstToPHP (sourceFile: SanSourceFile) {
} else if (prop.getName() === 'filters') {
refactorFiltersProperty(prop, sanssr)
}
removeObjectLiteralInitiator(sourceFile.tsSourceFile, clazz, prop)
refactorMemberInitializer(clazz, prop)
}
}

Expand Down
25 changes: 25 additions & 0 deletions src/target-php/transformers/refactor-member-initializer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ClassDeclaration, TypeGuards, Expression, PropertyDeclaration } from 'ts-morph'

export function refactorMemberInitializer (clazz: ClassDeclaration, prop: PropertyDeclaration) {
const initializer = prop.getInitializer()
if (!initializer || isConstant(initializer)) return

if (prop.isStatic()) {
const statement = clazz.getName() + '.' + prop.getName() + ' = ' + initializer.getFullText()
clazz.getSourceFile().addStatements(statement)
} else {
let statement = 'this.' + prop.getName() + ' = ' + initializer.getFullText()
if (!clazz.getConstructors().length) {
clazz.addConstructor()
statement = 'super()\n' + statement
}
const init = clazz.getConstructors()[0]
init.setBodyText(init.getBodyText() + '\n' + statement)
}
prop.removeInitializer()
}

function isConstant (expr: Expression) {
if (TypeGuards.isLiteralExpression(expr)) return true
return false
}
35 changes: 0 additions & 35 deletions src/target-php/util.ts

This file was deleted.

8 changes: 8 additions & 0 deletions src/target-php/utils/lang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const reservedNames = [/^list$/i]

export function isReserved (name: string) {
for (const reserved of reservedNames) {
if (reserved.test(name)) return true
}
return false
}
12 changes: 12 additions & 0 deletions test/cases/property-initializer/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component } from 'san'

const TEMPLATE = '<div><b title="{{title | real}}">{{title | real}}</b></div>'

export default class MyComponent extends Component {
static template = TEMPLATE
static filters = {
real: function (x) {
return 'real' + x
}
}
}
3 changes: 3 additions & 0 deletions test/cases/property-initializer/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"title": "1"
}
1 change: 1 addition & 0 deletions test/cases/property-initializer/result.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div><!--s-data:{"title":"1"}--><b title="real1">real1</b></div>
7 changes: 7 additions & 0 deletions test/cases/property-initializer/spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
it('method', function () {
// [inject] init

const b = wrap.getElementsByTagName('b')[0]

expect(b.title).toBe('real1')
})
73 changes: 73 additions & 0 deletions test/unit/target-php/refactor-member-initializer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { refactorMemberInitializer } from '../../../src/target-php/transformers/refactor-member-initializer'
import { Project } from 'ts-morph'

describe('refactorMemberInitializer()', function () {
const project = new Project()

it('should skip string literal static initializer', function () {
const sourceFile = project.createSourceFile('/tmp/static-str-literal', `
class Foo {
static staticLiteralStr: string = "foo"
}`)
const clazz = sourceFile.getClass('Foo')
for (const prop of clazz.getProperties()) {
refactorMemberInitializer(clazz, prop)
}
sourceFile.formatText()
const text = sourceFile.getFullText()

expect(text).toContain(`static staticLiteralStr: string = "foo"`)
expect(text).not.toContain(`Foo.staticLiteralStr =`)
})

it('should refactor string variable static initializer', function () {
const sourceFile = project.createSourceFile('/tmp/static-str-var', `
const str = "foo"
class Foo {
static staticLiteralStr: string = str
}`)
const clazz = sourceFile.getClass('Foo')
for (const prop of clazz.getProperties()) {
refactorMemberInitializer(clazz, prop)
}
sourceFile.formatText()
const text = sourceFile.getFullText()

expect(text).toContain(`static staticLiteralStr: string`)
expect(text).toContain(`Foo.staticLiteralStr = str`)
})

it('should skip string literal initializer', function () {
const sourceFile = project.createSourceFile('/tmp/str-literal', `
class Foo {
literalStr: string = "str"
}`)
const clazz = sourceFile.getClass('Foo')
for (const prop of clazz.getProperties()) {
refactorMemberInitializer(clazz, prop)
}
const text = sourceFile.getFullText()

expect(text).toContain(`literalStr: string = "str"`)
expect(text).not.toContain(`constructor()`)
})

it('should refactor string literal initializer', function () {
const sourceFile = project.createSourceFile('/tmp/str-var', `
const str = "foo"
class Foo {
literalStr: string = str
}`)
const clazz = sourceFile.getClass('Foo')
for (const prop of clazz.getProperties()) {
refactorMemberInitializer(clazz, prop)
}
sourceFile.formatText()
const text = sourceFile.getFullText()

expect(text).toContain(`literalStr: string\n`)
expect(text).toContain(`constructor() {`)
expect(text).toContain(`super()`)
expect(text).toContain(`this.literalStr = str`)
})
})

0 comments on commit b112ed5

Please sign in to comment.