kyranrana / simple-javascript-compilation
通过一系列操作编译 JavaScript 代码。
0.3.1
2019-09-17 21:20 UTC
Requires
- php: ^7.0
- ext-bcmath: *
- ext-curl: *
- ext-mbstring: *
- krowinski/bcmath-extended: ^4.2.1
- matthiasmullie/minify: ^1.3
- myclabs/php-enum: ^1.6.6
Requires (Dev)
- phpunit/phpunit: ^6.5.5
README
此库支持编译简单的 JavaScript 声明和表达式,无需 PHP V8JS。
支持的表达式
- Global methods
- String.fromCharCode
- atob
- eval
- escape
- Primitive types
- Boolean
- Integer
- toFixed
- String
- charCodeAt
- italics
- length
- Null
- Undefined
- Arrays
架构
此库由 4 个主要类组成。
ExpressionStreamReader
-
读取并通过事件发射表达式的关键区域。
-
发射的事件
- EXPRESSION_START
{ castAndNegations: Array<String> // casts and negations (! +) before expression }
- EXPRESSION_END
{ additionalOps: Array<AdditionalCall> // function and index calls on result of expression operator: Operator // operator }
- ARRAY_START
{ castAndNegations: Array<String> // casts and negations (! +) before array }
- ARRAY_END
{ additionalOps: Array<AdditionalCall> // function and index calls on result of array operator: Operator // operator }
- BOOLEAN
{ value: String // true / false additionalOps: Array<AdditionalCall> // function or index calls on boolean castsAndNegations: Array<String> // casts and negations (! +) before boolean operator: Operator // operator }
- INTEGER
{ value: String // integer / NaN / Infinity / -Infinity additionalOps: Array<AdditionalCall> // function or index calls on integer castsAndNegations: Array<String> // casts and negations (! +) before integer operator: Operator // operator }
- STRING
{ value: String // string additionalOps: Array<AdditionalCall> // function or index calls on string castsAndNegations: Array<String> // casts and negations (! +) before string operator: Operator // operator }
- NULL
{ value: String // null additionalOps: Array<AdditionalCall> // functions or index calls on null castsAndNegations: Array<String> // casts and negations (! +) before null operator: Operator // operator }
- UNDEFINED
{ value: String // undefined additionalOps: Array<AdditionalCall> // functions or index calls on undefined castsAndNegations: Array<String> // casts and negations (! +) before undefined operator: Operator // operator }
- DEFINITION
{ name: String // definition name additionalOps: Array<AdditionalCall> // function or index calls on definition value castsAndNegations: Array<String> // casts and negations (! +) before definition operator: Operator // operator }
- FUNCTION_START
{ castsAndNegations: Array<String> // casts and negations (! +) before function call }
- FUNCTION_NAME
{ name: String // function name }
- FUNCTION_ARG
{ argData: Array<Event> // collection of expression events }
- FUNCTION_END
{ additionalOps: Array<AdditionalCall> // function or index calls on function operator: Array<String> // operator }
- INLINE_FUNCTION_START
{ castsAndNegations: Array<String> // casts and negations (! +) before inline function }
- INLINE_FUNCTION_ARG
{ arg: Array<Event> // collection of expression events }
- INLINE_FUNCTION_CODE
{ value: String // inline function code }
- INLINE_FUNCTION_ARG_DATA
{ argData: Array<Event> // collection of expression events }
- INLINE_FUNCTION_END
{ additionalOps: Array<AdditionalCall> // function or index calls on inline function operator: Operator // operator }
- FUNCTION_ONLY
{ castsAndNegations: Array<String> // casts and negations (! +) before function name name: String // function name operator: Operator // operator }
-
使用的模型
- AdditionalCall
{ type: String // property or function name: Array<Events> // property or function name args: Array<Array<Event>> // function arguments }
DeclarationStreamReader
-
读取并发射代码中每个声明的事件,代码仅包含声明。
-
发射的事件
- DECLARATION
{ declaration: String // declaration name operator: Operator // operator value: String // expression }
ExpressionInterpreter
- 使用
ExpressionStreamReader
和在内部函数使用时DeclarationInterpreter
来解析表达式,最终返回CustomDataType
。
<?php use SimpleJavaScriptCompilation\ExpressionInterpreterImpl; use SimpleJavaScriptCompilation\Model\Context; $customDataType = ExpressionInterpreterImpl::instance()->interpretExpression('2+2+"hey there"', new Context()); ?>
- 在解析表达式的过程中维护一个
Context
,它包含处理表达式特定区域所需的数据。如果您想向表达式解析器传递自己的定义,可以执行以下操作
<?php use SimpleJavaScriptCompilation\ExpressionInterpreterImpl; use SimpleJavaScriptCompilation\Model\Context; use SimpleJavaScriptCompilation\Model\DataType\CustomString; use SimpleJavaScriptCompilation\Model\DataType\CustomInteger; use SimpleJavaScriptCompilation\Model\DataType; $ctx = new Context(); $ctx->setCtxVar("a", new CustomInteger(new DataType(["value" => "2"]))); $ctx->setCtxVar("c", new CustomString(new DataType(["value" => '"hello, "']))); // You can also set functions in the context too // See a list of supported functions in SimpleJavaScriptCompilation\Model\FunctionMap\GlobalFunctionMap $ctx->setCtxFunc("e", "SimpleJavaScriptCompilation\Model\FunctionMap\GlobalFunctionMap::atob"); $customDataType = ExpressionInterpreterImpl::instance()->interpretExpression('a+2+c+"hey there"+(function(){ return "sup"; })()', $ctx); ?>
-
更多使用示例可以在
/src/test/ExpressionInterpreterImplTest.php
中找到 -
覆盖的模型
- Context
{ ctxStack: Array<Mixed> // INTERNAL ONLY ctxTmp: Array<String, Mixed> // INTERNAL ONLY ctxVarMap: Array<String, CustomDataType> // variables ctxFuncMap: Array<String, Mixed> // functions ctxSum: CustomDataType // computed result to start calculation with }
- CustomDataType
{ dataType: DataType // underlying data type model merge(DataType $dataType): CustomDataType add(DataType $dataType): CustomDataType // adds data type models and determines new CustomDataType subtract(DataType $dataType): CustomDataType // subtracts data type models and determines new CustomDataType multiply(DataType $dataType): CustomDataType // multiplies data type models and determines new CustomDataType divide(DataType $dataType): CustomDataType // divides data type models and determines new CustomDataType }
-
CustomDataType 实现们
- CustomInteger - 处理 JavaScript 整数的计算(数字 / NaN / Infinity)
- CustomString - 处理 JavaScript 字符串的计算
- CustomBoolean - 处理 JavaScript 布尔值的计算(true / false)
- CustomNull - 处理 JavaScript null 的计算
- CustomUndefined - 处理 JavaScript undefined 的计算
-
DataType
{ dataType: DataTypeEnum // type of data castsAndNegations: Array<String> // casts and negations (! +) before data type value: String // data type value additionalCalls: Array<AdditionalCall> // function or index calls on data type value operator: Operator // operator }
DeclarationInterpreter
- 使用
DeclarationStreamReader
和ExpressionInterpreter
解析一组声明,最终返回Context
。
<?php use SimpleJavaScriptCompilation\DeclarationInterpreterImpl; use SimpleJavaScriptCompilation\Model\Context; $ctx = DeclarationInterpreterImpl::instance()->interpretDeclarations('var a = 2+2; var b = "hey there";', new Context()); ?>
<?php use SimpleJavaScriptCompilation\DeclarationInterpreterImpl; use SimpleJavaScriptCompilation\Model\DataType\CustomInteger; use SimpleJavaScriptCompilation\Model\Context; use SimpleJavaScriptCompilation\Model\DataType; // You can also pass your own variables and functions to the context // Refer to examples in ExpressionInterpreter section $ctx = new Context(); $ctx->setCtxVar("a", new CustomInteger(new DataType(['value' => '4']))); $ctx = DeclarationInterpreterImpl::instance()->interpretDeclarations('var a = 2+2; var b = "hey there";', $ctx); ?>
- 更多使用示例可以在
/src/test/DeclarationInterpreterImplTest.php
中找到