mediashare/simple-javascript-compilation

[已归档] 通过一系列操作编译JavaScript代码。

dev-master 2020-12-19 19:13 UTC

This package is auto-updated.

Last update: 2021-04-04 03:45:53 UTC


README

CircleCI

此库支持在没有PHP V8JS的情况下编译简单的JavaScript声明和表达式。

支持的表达式

- 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
  • 使用DeclarationStreamReaderExpressionInterpreter解释一组声明,最终返回一个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中找到