From 8284ddb756acc2c46266bbbcfdaa057ee5f8778e Mon Sep 17 00:00:00 2001 From: harttle Date: Fri, 10 Jan 2020 11:05:28 +0800 Subject: [PATCH] fix: ensure data access with valid identifier --- src/target-js/compilers/expr-compiler.ts | 27 +++++++++--------------- src/utils/lang.ts | 3 +++ test/cases/data-access/component.js | 6 ++++++ test/cases/data-access/data.json | 6 ++++++ test/cases/data-access/expected.html | 1 + 5 files changed, 26 insertions(+), 17 deletions(-) create mode 100644 src/utils/lang.ts create mode 100644 test/cases/data-access/component.js create mode 100644 test/cases/data-access/data.json create mode 100644 test/cases/data-access/expected.html diff --git a/src/target-js/compilers/expr-compiler.ts b/src/target-js/compilers/expr-compiler.ts index 5fc44fb3..2bf1d522 100644 --- a/src/target-js/compilers/expr-compiler.ts +++ b/src/target-js/compilers/expr-compiler.ts @@ -1,4 +1,6 @@ import { Expression } from '../../models/expression' +import { isString } from 'lodash' +import { isValidIdentifier } from '../../utils/lang' /** * 编译源码的 helper 方法集合对象 @@ -21,25 +23,16 @@ export const compileExprSource = { */ dataAccess: function (accessorExpr?: Expression): string { let code = 'componentCtx.data' - if (accessorExpr) { - for (const path of accessorExpr.paths) { - if (path.type === 4) { - code += '[' + compileExprSource.dataAccess(path) + ']' - continue - } - - switch (typeof path.value) { - case 'string': - code += '.' + path.value - continue - - case 'number': - code += '[' + path.value + ']' - continue - } + if (!accessorExpr) return code + for (const path of accessorExpr.paths) { + if (path.type === 4) { + code += '[' + compileExprSource.dataAccess(path) + ']' + } else if (isString(path.value) && isValidIdentifier(path.value)) { + code += '.' + path.value + } else { + code += '[' + path.value + ']' } } - return code }, diff --git a/src/utils/lang.ts b/src/utils/lang.ts new file mode 100644 index 00000000..0aa9531e --- /dev/null +++ b/src/utils/lang.ts @@ -0,0 +1,3 @@ +export function isValidIdentifier (str: string) { + return !!/^[a-zA-Z_$][\w$]*$/.exec(str) +} diff --git a/test/cases/data-access/component.js b/test/cases/data-access/component.js new file mode 100644 index 00000000..b7bb1898 --- /dev/null +++ b/test/cases/data-access/component.js @@ -0,0 +1,6 @@ +const { Component } = require('san') + +class MyComponent extends Component {} + +MyComponent.template = '
{{staff[0].first}} {{staff.0.last}}
' +module.exports = exports = MyComponent diff --git a/test/cases/data-access/data.json b/test/cases/data-access/data.json new file mode 100644 index 00000000..5deb2319 --- /dev/null +++ b/test/cases/data-access/data.json @@ -0,0 +1,6 @@ +{ + "staff": [{ + "first": "Berg", + "last": "Lay" + }] +} \ No newline at end of file diff --git a/test/cases/data-access/expected.html b/test/cases/data-access/expected.html new file mode 100644 index 00000000..f753323f --- /dev/null +++ b/test/cases/data-access/expected.html @@ -0,0 +1 @@ +
Berg Lay
\ No newline at end of file