Skip to content

Commit

Permalink
fix: independent to PHP function#bindTo and #bind
Browse files Browse the repository at this point in the history
  • Loading branch information
harttle committed Oct 25, 2019
1 parent d85b921 commit ee2af63
Show file tree
Hide file tree
Showing 18 changed files with 88 additions and 70 deletions.
Empty file added demo/dist/.gitignore
Empty file.
5 changes: 2 additions & 3 deletions demo/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { FilterDeclarations, ComputedDeclarations } from 'san-ssr'
import { Component } from 'san'

export default class DemoComponent extends Component {
static filters: FilterDeclarations = {
static filters = {
sum: function (a: number, b: number) {
return a + b
}
}
static computed: ComputedDeclarations = {
static computed = {
name: function () {
const f = this.data.get('firstName')
const l = this.data.get('lastName')
Expand Down
2 changes: 1 addition & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { SanComponent, Component, Data, ComputedDeclarations, FilterDeclarations } from './runtime/san'
export * from './runtime/san'
export { ToJSCompiler, ToPHPCompiler } from './dist/index'
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"clean": "rm -rf ./dist test/cases/*/ssr.{php,js}",
"lint": "eslint 'src/**/*.ts' 'test/**/*.ts'",
"docs": "typedoc --out docs src && touch docs/.nojekyll",
"build": "tsc",
"build": "tsc && chmod a+x dist/bin/*",
"build-watch": "tsc --watch",
"unit-php": "./vendor/bin/phpunit --bootstrap vendor/autoload.php test/unit/*.spec.php",
"unit-ts": "jest test/unit",
Expand Down
15 changes: 5 additions & 10 deletions runtime/san.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
export class Data {
class Data {
public get (path: string): any {
return path
}
}

export interface SanComponent {
computed?: ComputedDeclarations
filters?: FilterDeclarations
}

export class Component {
public data: Data;
}

export class FilterDeclarations {
[key: string]: (this: Component, ...args: any[]) => any
export class SanSSRFiltersDeclarations {
[key: string]: (...args: any[]) => any
}

export class ComputedDeclarations {
[key: string]: (this: Component) => any
export class TargetComputedDeclarations {
[key: string]: (sanssrSelf: Component) => any
}
30 changes: 17 additions & 13 deletions runtime/underscore.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
<?php
final class _
{
private const HTML_ENTITY = [
'&' => '&amp;',
'<' => '&lt;',
'>' => '&gt;',
'"' => '&quot;',
"'" => '&#39;'
];

public static $HTML_ENTITY;

public static function data($ctx, $seq = []) {
$data = $ctx->data;
foreach ($seq as $name) {
Expand Down Expand Up @@ -107,7 +101,7 @@ public static function contains($array, $value)

public static function htmlFilterReplacer($c)
{
return _::HTML_ENTITY[$c];
return _::$HTML_ENTITY[$c];
}

public static function escapeHTML($source)
Expand Down Expand Up @@ -187,7 +181,8 @@ public static function getClassByCtx($ctx) {

public static function callFilter($ctx, $name, $args)
{
$func = _::getClassByCtx($ctx)::$filters[$name];
$cls = _::getClassByCtx($ctx);
$func = $cls::$filters[$name];
if (is_callable($func)) {
return call_user_func_array($func, $args);
}
Expand All @@ -205,9 +200,10 @@ public static function createComponent (&$ctx) {

public static function callComputed($ctx, $name)
{
$func = _::getClassByCtx($ctx)::$computed[$name];
$cls = _::getClassByCtx($ctx);
$func = $cls::$computed[$name];
if (is_callable($func)) {
$result = call_user_func($func->bindTo($ctx->instance));
$result = call_user_func($func, $ctx->instance);
return is_array($result) ? (object)$result : $result;
}
}
Expand All @@ -223,4 +219,12 @@ public static function stringifyStyles($source)
}
return $source;
}
}
}

_::$HTML_ENTITY = [
'&' => '&amp;',
'<' => '&lt;',
'>' => '&gt;',
'"' => '&quot;',
"'" => '&#39;'
];
2 changes: 1 addition & 1 deletion src/bin/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function test (got) {
}

function deepEqual (lhs, rhs) {
if (typeof lhs === 'object') {
if (typeof lhs === 'object' && lhs !== null) {
for (const key of Object.keys(lhs)) {
if (!deepEqual(lhs[key], rhs[key])) return false
}
Expand Down
22 changes: 12 additions & 10 deletions src/compilers/to-php-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,31 @@ const debug = debugFactory('ast-util')
export type ToPHPCompilerOptions = {
tsConfigFilePath?: string,
root?: string,
externalModules?: ModuleInfo[]
sanssr?: string
}

export class ToPHPCompiler implements Compiler {
private root: string
private tsConfigFilePath: string
private externalModules: ModuleInfo[]
private requiredModules: ModuleInfo[]
private toJSCompiler: ToJSCompiler
private project: Project
private sanssr: string

constructor ({
tsConfigFilePath = getDefaultConfigPath(),
root = tsConfigFilePath.split(sep).slice(0, -1).join(sep),
externalModules = []
sanssr = 'san-ssr'
}: ToPHPCompilerOptions = {}) {
this.externalModules = [{
name: 'san-ssr',
this.sanssr = sanssr
this.requiredModules = [{
name: sanssr,
required: true
}, {
name: 'san',
required: true,
namespace: '\\san\\runtime\\'
}, ...externalModules]
}]
this.root = root
this.tsConfigFilePath = tsConfigFilePath
this.project = new Project({ tsConfigFilePath })
Expand Down Expand Up @@ -94,21 +96,21 @@ export class ToPHPCompiler implements Compiler {
}

public compileToPHP (sourceFile: SanSourceFile, nsPrefix = '') {
transformAstToPHP(sourceFile)
transformAstToPHP(sourceFile, this.sanssr)
const tsconfig = require(this.tsConfigFilePath)
const externalModules = [...this.externalModules]
const requiredModules = [...this.requiredModules]
for (const decl of getInlineDeclarations(sourceFile.origin)) {
const ns = nsPrefix + this.ns(decl.getModuleSpecifierSourceFile().getFilePath())
const literal = decl.getModuleSpecifierValue()
externalModules.push({
requiredModules.push({
name: literal,
required: true,
namespace: '\\' + ns + '\\'
})
}
return generatePHPCode(
sourceFile,
externalModules,
requiredModules,
tsconfig['compilerOptions'],
nsPrefix
)
Expand Down
40 changes: 39 additions & 1 deletion src/transformers/to-php.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { removeObjectLiteralInitiator } from '../utils/ast-util'
import { SanSourceFile } from '../parsers/san-sourcefile'
import { isReserved } from '../utils/php-util'
import { TypeGuards, PropertyDeclaration } from 'ts-morph'

const uselessComponentProps = ['components']

export function transformAstToPHP (sourceFile: SanSourceFile) {
export function transformAstToPHP (sourceFile: SanSourceFile, sanssr = 'san-ssr') {
sourceFile.fakeProperties.forEach(prop => prop.remove())

for (const clazz of sourceFile.componentClasses.values()) {
Expand All @@ -14,6 +15,11 @@ export function transformAstToPHP (sourceFile: SanSourceFile) {
}

for (const prop of clazz.getProperties()) {
if (prop.getName() === 'computed') {
refactorComputedProperty(prop, sanssr)
} else if (prop.getName() === 'filters') {
refactorFiltersProperty(prop, sanssr)
}
removeObjectLiteralInitiator(sourceFile.origin, clazz, prop)
}
}
Expand All @@ -28,3 +34,35 @@ export function transformAstToPHP (sourceFile: SanSourceFile) {
}
}
}

function refactorFiltersProperty (filters: PropertyDeclaration, sanssr = 'san-ssr') {
filters.setType(`import("${sanssr}").SanSSRFiltersDeclarations`)
}

function refactorComputedProperty (computed: PropertyDeclaration, sanssr = 'san-ssr') {
computed.removeType()

const computedDefinitions = computed.getInitializer()
if (!computedDefinitions) return
if (!TypeGuards.isObjectLiteralExpression(computedDefinitions)) return
for (const prop of computedDefinitions.getProperties()) {
let body
if (TypeGuards.isMethodDeclaration(prop)) {
body = prop
}
if (TypeGuards.isPropertyAssignment(prop)) {
const init = prop.getInitializer()
if (TypeGuards.isFunctionExpression(init)) body = init
}
if (body) {
body.insertParameter(0, {
name: 'sanssrSelf',
type: `import("${sanssr}").Component`
})
const text = body
.getBodyText()
.replace(/this\.data\.get\(/g, 'sanssrSelf.data.get(')
body.setBodyText(text)
}
}
}
2 changes: 1 addition & 1 deletion src/utils/case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const cases = readdirSync(caseRoot)
const toJSCompiler = new ToJSCompiler({ tsConfigFilePath })
const toPHPCompiler = new ToPHPCompiler({
tsConfigFilePath,
externalModules: [{ name: '../../..', required: true }]
sanssr: '../../..'
})
const multiFileCases = ['multi-component-files', 'multi-files']

Expand Down
3 changes: 1 addition & 2 deletions test/cases/computed-data/component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Component } from 'san'
import { ComputedDeclarations } from '../../..'

export default class MyComponent extends Component {
static computed: ComputedDeclarations = {
static computed = {
realTitle: function () {
return 'real' + this.data.get('title')
}
Expand Down
3 changes: 1 addition & 2 deletions test/cases/computed-dep/component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Component } from 'san'
import { ComputedDeclarations } from '../../..'

export default class MyComponent extends Component {
static computed: ComputedDeclarations = {
static computed = {
less () {
return this.data.get('normal') - 1
},
Expand Down
3 changes: 1 addition & 2 deletions test/cases/date-data-init-data/component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Component } from 'san'
import { FilterDeclarations } from '../../..'

// date init data
export default class MyComponent extends Component {
public static filters: FilterDeclarations = {
public static filters = {
year: function (date: Date) {
return date.getFullYear()
}
Expand Down
3 changes: 1 addition & 2 deletions test/cases/date-data/component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Component } from 'san'
import { FilterDeclarations } from '../../..'

// date data
export default class MyComponent extends Component {
public static filters: FilterDeclarations = {
public static filters = {
year: function (date: Date) {
return date.getFullYear()
}
Expand Down
3 changes: 1 addition & 2 deletions test/cases/nest-for-computed/component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Component } from 'san'
import { ComputedDeclarations } from '../../..'

export default class MyComponent extends Component {
public static template = '<form>' +
Expand All @@ -14,7 +13,7 @@ export default class MyComponent extends Component {
}
}

static computed: ComputedDeclarations = {
static computed = {
forms () {
const cates = this.data.get('cates')
const formLen = this.data.get('formLen')
Expand Down
13 changes: 0 additions & 13 deletions test/cases/nest-for-computed/san.ts

This file was deleted.

5 changes: 2 additions & 3 deletions test/cases/scoped-slot-default-filter/component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Component } from 'san'
import { FilterDeclarations } from '../../..'

class Man extends Component {
filters: FilterDeclarations = {
filters = {
upper: function (source: string) {
return source[0].toUpperCase() + source.slice(1)
}
Expand All @@ -15,7 +14,7 @@ export default class MyComponent extends Component {
'x-man': Man
}

filters: FilterDeclarations = {
filters = {
upper: function (source: string) {
return source.toUpperCase()
}
Expand Down
5 changes: 2 additions & 3 deletions test/cases/scoped-slot-given-filter/component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Component } from 'san'
import { FilterDeclarations } from '../../..'

class Man extends Component {
filters: FilterDeclarations = {
filters = {
upper: function (source: string) {
return source[0].toUpperCase() + source.slice(1)
}
Expand All @@ -16,7 +15,7 @@ export default class MyComponent extends Component {
'x-man': Man
}

filters: FilterDeclarations = {
filters = {
upper: function (source: string) {
return source.toUpperCase()
}
Expand Down

0 comments on commit ee2af63

Please sign in to comment.