Przeglądaj źródła

Merge pull request #916 from javascript-obfuscator/es2022-features

WIP es2022 features: escodegen update
Timofey Kachalov 3 lat temu
rodzic
commit
f875796308
31 zmienionych plików z 602 dodań i 298 usunięć
  1. 0 4
      .github/workflows/ci.yml
  2. 1 0
      .gitignore
  3. 6 0
      CHANGELOG.md
  4. 0 0
      dist/index.browser.js
  5. 0 0
      dist/index.cli.js
  6. 0 0
      dist/index.js
  7. 8 8
      package.json
  8. 3 1
      src/ASTParserFacade.ts
  9. 1 1
      src/JavaScriptObfuscator.ts
  10. 3 3
      src/container/modules/node-transformers/ConvertingTransformersModule.ts
  11. 2 1
      src/decorators/Initializable.ts
  12. 1 1
      src/enums/node-transformers/NodeTransformer.ts
  13. 2 0
      src/enums/node/NodeType.ts
  14. 2 1
      src/node-transformers/NodeTransformersRunner.ts
  15. 39 37
      src/node-transformers/converting-transformers/ClassFieldTransformer.ts
  16. 24 1
      src/node-transformers/rename-properties-transformers/RenamePropertiesTransformer.ts
  17. 18 0
      src/node/NodeGuards.ts
  18. 3 1
      src/utils/AbstractTransformerNamesGroupsBuilder.ts
  19. 3 1
      src/utils/Utils.ts
  20. 26 15
      test/dev/dev.ts
  21. 311 0
      test/functional-tests/node-transformers/converting-transformers/class-field-transformer/ClassFieldTransformer.spec.ts
  22. 1 0
      test/functional-tests/node-transformers/converting-transformers/class-field-transformer/fixtures/async-get-method.js
  23. 1 0
      test/functional-tests/node-transformers/converting-transformers/class-field-transformer/fixtures/identifier-key.js
  24. 1 0
      test/functional-tests/node-transformers/converting-transformers/class-field-transformer/fixtures/literal-key.js
  25. 0 179
      test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec.ts
  26. 94 12
      test/functional-tests/node-transformers/rename-properties-transformers/rename-properties-transformer/RenamePropertiesTransformer.spec.ts
  27. 7 0
      test/functional-tests/node-transformers/rename-properties-transformers/rename-properties-transformer/fixtures/property-definition-1.js
  28. 6 3
      test/functional-tests/node-transformers/rename-properties-transformers/rename-properties-transformer/fixtures/safe-mode.js
  29. 1 1
      test/index.spec.ts
  30. 3 1
      tsconfig.json
  31. 35 27
      yarn.lock

+ 0 - 4
.github/workflows/ci.yml

@@ -20,14 +20,10 @@ jobs:
             node-version: 12.x
           - os: ubuntu-latest,
             node-version: 14.x
-          - os: ubuntu-latest,
-            node-version: 15.x
           - os: ubuntu-latest,
             node-version: 16.x
           - os: windows-latest,
             node-version: 14.x
-          - os: windows-latest,
-            node-version: 15.x
           - os: windows-latest,
             node-version: 16.x
 

+ 1 - 0
.gitignore

@@ -11,3 +11,4 @@ npm-debug.log
 /tmp
 /test/benchmark/**/**
 *dockerfile
+/test*.js

+ 6 - 0
CHANGELOG.md

@@ -1,5 +1,11 @@
 Change Log
 
+v2.18.0
+---
+* Added support of `es2022` features: private identifiers and class properties
+* Dropped support for `node@15`. 
+* Increased minimum supported `node` versions: `^12.22.0 || ^14.17.0 || >=16.0.0`
+
 v2.17.0
 ---
 * **New option**: `sourceMapSourcesMode` allows to control `sources` and `sourcesContent` fields of the source map

Plik diff jest za duży
+ 0 - 0
dist/index.browser.js


Plik diff jest za duży
+ 0 - 0
dist/index.cli.js


Plik diff jest za duży
+ 0 - 0
dist/index.js


+ 8 - 8
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "2.17.0",
+  "version": "2.18.0",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",
@@ -12,7 +12,7 @@
     "js obfuscator"
   ],
   "engines": {
-    "node": ">=12"
+    "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
   },
   "main": "dist/index.js",
   "browser": "dist/index.browser.js",
@@ -30,7 +30,7 @@
     "chance": "1.1.7",
     "class-validator": "0.13.1",
     "commander": "8.0.0",
-    "eslint-scope": "5.1.1",
+    "eslint-scope": "6.0.0",
     "fast-deep-equal": "3.1.3",
     "inversify": "5.1.1",
     "js-string-escape": "1.0.1",
@@ -55,9 +55,9 @@
     "@types/js-string-escape": "1.0.0",
     "@types/md5": "2.3.1",
     "@types/mkdirp": "1.0.2",
-    "@types/mocha": "8.2.3",
+    "@types/mocha": "9.0.0",
     "@types/multimatch": "4.0.0",
-    "@types/node": "16.3.3",
+    "@types/node": "16.4.1",
     "@types/rimraf": "3.0.1",
     "@types/sinon": "10.0.2",
     "@types/string-template": "1.0.2",
@@ -69,7 +69,7 @@
     "cross-env": "7.0.3",
     "eslint": "7.31.0",
     "eslint-plugin-import": "2.23.4",
-    "eslint-plugin-jsdoc": "35.4.5",
+    "eslint-plugin-jsdoc": "35.5.1",
     "eslint-plugin-no-null": "1.0.2",
     "eslint-plugin-prefer-arrow": "1.2.3",
     "eslint-plugin-unicorn": "34.0.1",
@@ -85,8 +85,8 @@
     "threads": "1.6.5",
     "ts-loader": "9.2.3",
     "ts-node": "10.1.0",
-    "typescript": "4.3.5",
-    "webpack": "5.45.1",
+    "typescript": "4.4.0-beta",
+    "webpack": "5.46.0",
     "webpack-cli": "4.7.2",
     "webpack-node-externals": "3.0.0"
   },

+ 3 - 1
src/ASTParserFacade.ts

@@ -91,7 +91,9 @@ export class ASTParserFacade {
         errorMessage: string,
         position: ESTree.Position | null
     ): never {
-        if (!position || !position.line || !position.column) {
+        const isMissingLocationData = !position || !position.line || !position.column;
+
+        if (isMissingLocationData) {
             throw new Error(errorMessage);
         }
 

+ 1 - 1
src/JavaScriptObfuscator.ts

@@ -66,6 +66,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
         NodeTransformer.BooleanLiteralTransformer,
         NodeTransformer.BlockStatementControlFlowTransformer,
         NodeTransformer.BlockStatementSimplifyTransformer,
+        NodeTransformer.ClassFieldTransformer,
         NodeTransformer.CommentsTransformer,
         NodeTransformer.CustomCodeHelpersTransformer,
         NodeTransformer.DeadCodeInjectionTransformer,
@@ -79,7 +80,6 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
         NodeTransformer.RenamePropertiesTransformer,
         NodeTransformer.MemberExpressionTransformer,
         NodeTransformer.MetadataTransformer,
-        NodeTransformer.MethodDefinitionTransformer,
         NodeTransformer.NumberLiteralTransformer,
         NodeTransformer.NumberToNumericalExpressionTransformer,
         NodeTransformer.ObfuscatingGuardsTransformer,

+ 3 - 3
src/container/modules/node-transformers/ConvertingTransformersModule.ts

@@ -12,7 +12,7 @@ import { BasePropertiesExtractor } from '../../../node-transformers/converting-t
 import { BooleanLiteralTransformer } from '../../../node-transformers/converting-transformers/BooleanLiteralTransformer';
 import { ExportSpecifierTransformer } from '../../../node-transformers/converting-transformers/ExportSpecifierTransformer';
 import { MemberExpressionTransformer } from '../../../node-transformers/converting-transformers/MemberExpressionTransformer';
-import { MethodDefinitionTransformer } from '../../../node-transformers/converting-transformers/MethodDefinitionTransformer';
+import { ClassFieldTransformer } from '../../../node-transformers/converting-transformers/ClassFieldTransformer';
 import { NumberLiteralTransformer } from '../../../node-transformers/converting-transformers/NumberLiteralTransformer';
 import { NumberToNumericalExpressionTransformer } from '../../../node-transformers/converting-transformers/NumberToNumericalExpressionTransformer';
 import { ObjectExpressionKeysTransformer } from '../../../node-transformers/converting-transformers/ObjectExpressionKeysTransformer';
@@ -37,8 +37,8 @@ export const convertingTransformersModule: interfaces.ContainerModule = new Cont
         .whenTargetNamed(NodeTransformer.MemberExpressionTransformer);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
-        .to(MethodDefinitionTransformer)
-        .whenTargetNamed(NodeTransformer.MethodDefinitionTransformer);
+        .to(ClassFieldTransformer)
+        .whenTargetNamed(NodeTransformer.ClassFieldTransformer);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(NumberLiteralTransformer)

+ 2 - 1
src/decorators/Initializable.ts

@@ -18,8 +18,9 @@ const initializeMethodName: 'initialize' = 'initialize';
 export function initializable (): (target: IInitializable, propertyKey: string | symbol) => any {
     return (target: IInitializable, propertyKey: string | symbol): PropertyDescriptor => {
         const initializeMethod: Function = target[initializeMethodName];
+        const isInvalidInitializeMethod = !initializeMethod || typeof initializeMethod !== 'function';
 
-        if (!initializeMethod || typeof initializeMethod !== 'function') {
+        if (isInvalidInitializeMethod) {
             throw new Error(`\`${initializeMethodName}\` method with initialization logic not ` +
                 `found. \`@${decoratorName}\` decorator requires \`${initializeMethodName}\` method`);
         }

+ 1 - 1
src/enums/node-transformers/NodeTransformer.ts

@@ -2,6 +2,7 @@ export enum NodeTransformer {
     BooleanLiteralTransformer = 'BooleanLiteralTransformer',
     BlockStatementControlFlowTransformer = 'BlockStatementControlFlowTransformer',
     BlockStatementSimplifyTransformer = 'BlockStatementSimplifyTransformer',
+    ClassFieldTransformer = 'ClassFieldTransformer',
     CommentsTransformer = 'CommentsTransformer',
     CustomCodeHelpersTransformer = 'CustomCodeHelpersTransformer',
     DeadCodeInjectionIdentifiersTransformer = 'DeadCodeInjectionIdentifiersTransformer',
@@ -16,7 +17,6 @@ export enum NodeTransformer {
     LabeledStatementTransformer = 'LabeledStatementTransformer',
     MemberExpressionTransformer = 'MemberExpressionTransformer',
     MetadataTransformer = 'MetadataTransformer',
-    MethodDefinitionTransformer = 'MethodDefinitionTransformer',
     NumberLiteralTransformer = 'NumberLiteralTransformer',
     NumberToNumericalExpressionTransformer = 'NumberToNumericalExpressionTransformer',
     ObfuscatingGuardsTransformer = 'ObfuscatingGuardsTransformer',

+ 2 - 0
src/enums/node/NodeType.ts

@@ -11,6 +11,7 @@ export enum NodeType {
     CallExpression = 'CallExpression',
     CatchClause = 'CatchClause',
     ChainExpression = 'ChainExpression',
+    ClassBody = 'ClassBody',
     ClassDeclaration = 'ClassDeclaration',
     ConditionalExpression = 'ConditionalExpression',
     ContinueStatement = 'ContinueStatement',
@@ -40,6 +41,7 @@ export enum NodeType {
     ObjectPattern = 'ObjectPattern',
     Program = 'Program',
     Property = 'Property',
+    PropertyDefinition = 'PropertyDefinition',
     RestElement = 'RestElement',
     ReturnStatement = 'ReturnStatement',
     SequenceExpression = 'SequenceExpression',

+ 2 - 1
src/node-transformers/NodeTransformersRunner.ts

@@ -161,8 +161,9 @@ export class NodeTransformersRunner implements INodeTransformersRunner {
                 }
 
                 const visitorResult: TVisitorResult = visitorFunction(node, parentNode);
+                const isValidVisitorResult = visitorResult && NodeGuards.isNode(visitorResult);
 
-                if (!visitorResult || !NodeGuards.isNode(visitorResult)) {
+                if (!isValidVisitorResult) {
                     continue;
                 }
 

+ 39 - 37
src/node-transformers/converting-transformers/MethodDefinitionTransformer.ts → src/node-transformers/converting-transformers/ClassFieldTransformer.ts

@@ -16,17 +16,20 @@ import { NodeGuards } from '../../node/NodeGuards';
 /**
  * replaces:
  *     foo () { //... };
+ *     foo = 1;
  *
  * or
  *     'foo' () { //... };
+ *     'foo' = 1;
  *
  * on:
- *     ['foo'] { //... };
+ *     ['foo'] () { //... };
+ *     ['foo'] = 1;
  *
  * Literal node will be obfuscated by LiteralTransformer
  */
 @injectable()
-export class MethodDefinitionTransformer extends AbstractNodeTransformer {
+export class ClassFieldTransformer extends AbstractNodeTransformer {
     /**
      * @type {string[]}
      */
@@ -52,7 +55,13 @@ export class MethodDefinitionTransformer extends AbstractNodeTransformer {
             case NodeTransformationStage.Converting:
                 return {
                     enter: (node: ESTree.Node, parentNode: ESTree.Node | null): ESTree.Node | undefined => {
-                        if (parentNode && NodeGuards.isMethodDefinitionNode(node)) {
+                        if (
+                            parentNode
+                            && (
+                                NodeGuards.isMethodDefinitionNode(node)
+                                || NodeGuards.isPropertyDefinitionNode(node)
+                            )
+                        ) {
                             return this.transformNode(node, parentNode);
                         }
                     }
@@ -64,69 +73,62 @@ export class MethodDefinitionTransformer extends AbstractNodeTransformer {
     }
 
     /**
-     * replaces:
-     *     object.identifier = 1;
-     *
-     * on:
-     *     object['identifier'] = 1;
-     *
-     * and skip:
-     *     object[identifier] = 1;
-     * Literal node will be obfuscated by LiteralTransformer
-     *
-     * @param {MethodDefinition} methodDefinitionNode
+     * @param {MethodDefinition | PropertyDefinition} classFieldNode
      * @param {NodeGuards} parentNode
      * @returns {NodeGuards}
      */
-    public transformNode (methodDefinitionNode: ESTree.MethodDefinition, parentNode: ESTree.Node): ESTree.Node {
-        if (NodeGuards.isIdentifierNode(methodDefinitionNode.key)) {
-            return this.replaceIdentifierKey(methodDefinitionNode, methodDefinitionNode.key);
+    public transformNode (
+        classFieldNode: ESTree.MethodDefinition | ESTree.PropertyDefinition,
+        parentNode: ESTree.Node
+    ): ESTree.Node {
+        if (NodeGuards.isIdentifierNode(classFieldNode.key)) {
+            return this.replaceIdentifierKey(classFieldNode, classFieldNode.key);
         }
 
-        if (NodeGuards.isLiteralNode(methodDefinitionNode.key)) {
-            return this.replaceLiteralKey(methodDefinitionNode, methodDefinitionNode.key);
+        if (NodeGuards.isLiteralNode(classFieldNode.key)) {
+            return this.replaceLiteralKey(classFieldNode, classFieldNode.key);
         }
 
-        return methodDefinitionNode;
+        return classFieldNode;
     }
 
     /**
-     * @param {MethodDefinition} methodDefinitionNode
+     * @param {MethodDefinition | PropertyDefinition} classFieldNode
      * @param {Identifier} keyNode
-     * @returns {MethodDefinition}
+     * @returns {MethodDefinition | PropertyDefinition}
      */
     private replaceIdentifierKey (
-        methodDefinitionNode: ESTree.MethodDefinition,
+        classFieldNode: ESTree.MethodDefinition | ESTree.PropertyDefinition,
         keyNode: ESTree.Identifier
-    ): ESTree.MethodDefinition {
+    ): ESTree.MethodDefinition | ESTree.PropertyDefinition {
         if (
-            !MethodDefinitionTransformer.ignoredNames.includes(keyNode.name)
-            && !methodDefinitionNode.computed
+            !ClassFieldTransformer.ignoredNames.includes(keyNode.name)
+            && !classFieldNode.computed
         ) {
-            methodDefinitionNode.computed = true;
-            methodDefinitionNode.key = NodeFactory.literalNode(keyNode.name);
+            classFieldNode.computed = true;
+            classFieldNode.key = NodeFactory.literalNode(keyNode.name);
         }
 
-        return methodDefinitionNode;
+        return classFieldNode;
     }
 
     /**
-     * @param {MethodDefinition} methodDefinitionNode
+     * @param {MethodDefinition | PropertyDefinition} classFieldNode
      * @param {Literal} keyNode
-     * @returns {MethodDefinition}
+     * @returns {MethodDefinition | PropertyDefinition}
      */
     private replaceLiteralKey (
-        methodDefinitionNode: ESTree.MethodDefinition,
+        classFieldNode: ESTree.MethodDefinition | ESTree.PropertyDefinition,
         keyNode: ESTree.Literal
-    ): ESTree.MethodDefinition {
+    ): ESTree.MethodDefinition | ESTree.PropertyDefinition {
         if (
             typeof keyNode.value === 'string'
-            && !MethodDefinitionTransformer.ignoredNames.includes(keyNode.value)
-            && !methodDefinitionNode.computed
+            && !ClassFieldTransformer.ignoredNames.includes(keyNode.value)
+            && !classFieldNode.computed
         ) {
-            methodDefinitionNode.computed = true;
+            classFieldNode.computed = true;
         }
 
-        return methodDefinitionNode;
+        return classFieldNode;
     }
 }

+ 24 - 1
src/node-transformers/rename-properties-transformers/RenamePropertiesTransformer.ts

@@ -43,7 +43,10 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
      * @returns {boolean}
      */
     private static isValidPropertyNode<
-        TNode extends ESTree.Property | ESTree.MemberExpression | ESTree.MethodDefinition
+        TNode extends ESTree.Property
+            | ESTree.PropertyDefinition
+            | ESTree.MemberExpression
+            | ESTree.MethodDefinition
     > (
         propertyNode: TNode,
         propertyKeyNode: ESTree.Expression | ESTree.PrivateIdentifier
@@ -107,6 +110,10 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
             return this.transformPropertyNode(node);
         }
 
+        if (NodeGuards.isPropertyDefinitionNode(node)) {
+            return this.transformPropertyDefinitionNode(node);
+        }
+
         if (NodeGuards.isMemberExpressionNode(node)) {
             return this.transformMemberExpressionNode(node);
         }
@@ -133,6 +140,20 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
         return propertyNode;
     }
 
+    /**
+     * @param {PropertyDefinition} propertyNode
+     * @returns {PropertyDefinition}
+     */
+    private transformPropertyDefinitionNode (propertyNode: ESTree.PropertyDefinition): ESTree.PropertyDefinition {
+        const propertyKeyNode: ESTree.Expression | ESTree.PrivateIdentifier = propertyNode.key;
+
+        if (RenamePropertiesTransformer.isValidPropertyNode(propertyNode, propertyKeyNode)) {
+            propertyNode.key = this.renamePropertiesReplacer.replace(propertyKeyNode);
+        }
+
+        return propertyNode;
+    }
+
     /**
      * @param {Property} memberExpressionNode
      * @returns {Property}
@@ -165,6 +186,7 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
      * @param {Node} node
      * @param {Node} parentNode
      */
+    // eslint-disable-next-line complexity
     private analyzeAutoExcludedPropertyNames (
         node: ESTree.Node,
         parentNode: ESTree.Node
@@ -177,6 +199,7 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
             (NodeGuards.isPropertyNode(parentNode) && parentNode.key === node)
             || NodeGuards.isMemberExpressionNode(parentNode) && parentNode.property === node
             || NodeGuards.isMethodDefinitionNode(parentNode) && parentNode.key === node
+            || NodeGuards.isPropertyDefinitionNode(parentNode) && parentNode.key === node
         ) {
             return;
         }

+ 18 - 0
src/node/NodeGuards.ts

@@ -91,6 +91,16 @@ export class NodeGuards {
         return node.type === NodeType.CallExpression;
     }
 
+    /**
+     * @param {Node} node
+     * @returns {boolean}
+     */
+    public static isClassBodyNode (
+        node: ESTree.Node
+    ): node is ESTree.ClassBody {
+        return node.type === NodeType.ClassBody;
+    }
+
     /**
      * @param {Node} node
      * @returns {boolean}
@@ -442,6 +452,14 @@ export class NodeGuards {
         return node.type === NodeType.Property;
     }
 
+    /**
+     * @param {Node} node
+     * @returns {boolean}
+     */
+    public static isPropertyDefinitionNode (node: ESTree.Node): node is ESTree.PropertyDefinition {
+        return node.type === NodeType.PropertyDefinition;
+    }
+
     /**
      * @param {Node} node
      * @returns {boolean}

+ 3 - 1
src/utils/AbstractTransformerNamesGroupsBuilder.ts

@@ -78,9 +78,11 @@ export abstract class AbstractTransformerNamesGroupsBuilder <
 
         for (const transformerName of transformerNames) {
             const transformer: TTransformer = normalizedTransformers[transformerName];
+
             const runAfterRelations: TTransformerName[] | undefined = transformer.runAfter;
+            const areRunAfterRelationsEmpty = !runAfterRelations || !runAfterRelations.length;
 
-            if (!runAfterRelations || !runAfterRelations.length) {
+            if (areRunAfterRelationsEmpty) {
                 relationEdges.push([transformerName, null]);
                 continue;
             }

+ 3 - 1
src/utils/Utils.ts

@@ -15,7 +15,9 @@ export class Utils {
      * @returns {string}
      */
     public static buildVersionMessage (version?: string, buildTimestamp?: string): string {
-        if (!version || !buildTimestamp) {
+        const isUnknownVersion = !version || !buildTimestamp;
+
+        if (isUnknownVersion) {
             return 'unknown';
         }
 

+ 26 - 15
test/dev/dev.ts

@@ -5,28 +5,39 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
 (function () {
     const JavaScriptObfuscator: any = require('../../index');
 
-    let obfuscationResult = JavaScriptObfuscator.obfuscate(
+    let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         `
-             var object = {
-                b: 'field',
-                bar: 'value'
-             };
+            class Test {
+                constructor () {
+                    let test = {}
+                }
+                
+                static methodA = () => {
+                    console.log('method_A');
+                }
+                
+                methodB () {
+                    console.log('method_B');
+                    
+                    Test.methodA();
+                }
+            }
+            
+            const instance = new Test();
+            
+            Test.methodA();
+            instance.methodB();
         `,
         {
             ...NO_ADDITIONAL_NODES_PRESET,
             compact: false,
-            simplify: false,
-            renameProperties: true,
-            renamePropertiesMode: 'safe',
-            identifierNamesGenerator: 'mangled',
-            reservedNames: ['^a$']
+            stringArray: true,
+            stringArrayThreshold: 1,
+            transformObjectKeys: true,
+            renameProperties: true
         }
-    );
-
-    let obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
-    let identifierNamesCache = obfuscationResult.getIdentifierNamesCache();
+    ).getObfuscatedCode();
 
     console.log(obfuscatedCode);
     console.log(eval(obfuscatedCode));
-    console.log(identifierNamesCache);
 })();

+ 311 - 0
test/functional-tests/node-transformers/converting-transformers/class-field-transformer/ClassFieldTransformer.spec.ts

@@ -0,0 +1,311 @@
+import { assert } from 'chai';
+
+import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
+
+import { readFileAsString } from '../../../../helpers/readFileAsString';
+
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
+
+describe('ClassFieldTransformer', () => {
+    describe('Variant #1: `MethodDefinition` node', () => {
+        describe('Variant #1: identifier key', () => {
+            describe('Variant #1: default behaviour', () => {
+                const regExp: RegExp = /\['bar'\]\(\)\{\}/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/identifier-key.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should replace method definition node `key` property with square brackets literal', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
+
+            describe('Variant #2: `stringArray` option is enabled', () => {
+                const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['property', *'bar'\];/;
+                const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\(0x1\)\]\(\)\{\}/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/identifier-key.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            stringArray: true,
+                            stringArrayThreshold: 1
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should add method definition node `key` property to string array', () => {
+                    assert.match(obfuscatedCode,  stringArrayRegExp);
+                });
+
+                it('should replace method definition node `key` property with call to string array', () => {
+                    assert.match(obfuscatedCode,  stringArrayCallRegExp);
+                });
+            });
+
+            describe('Variant #3: `constructor` key', () => {
+                const regExp: RegExp = /constructor\(\)\{\}/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/identifier-key.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('shouldn\'t transform method definition node with `constructor` key', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
+        });
+
+        describe('Variant #2: literal key', () => {
+            describe('Variant #1: Default behaviour', () => {
+                const regExp: RegExp = /\['bar'\]\(\)\{\}/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/literal-key.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should replace method definition node `key` property with square brackets literal', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
+
+            describe('Variant #2: `stringArray` option is enabled', () => {
+                const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['property', *'constructor', *'bar'];/;
+                const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\(0x2\)\]\(\)\{\}/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/literal-key.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            stringArray: true,
+                            stringArrayThreshold: 1
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should add method definition node `key` property to string array', () => {
+                    assert.match(obfuscatedCode,  stringArrayRegExp);
+                });
+
+                it('should replace method definition node `key` property with call to string array', () => {
+                    assert.match(obfuscatedCode,  stringArrayCallRegExp);
+                });
+            });
+
+            describe('Variant #3: `constructor` key', () => {
+                const regExp: RegExp = /'constructor'\(\)\{\}/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/literal-key.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('shouldn\'t transform method definition node with `constructor` key', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
+        });
+
+        describe('Variant #3: async `get()` method', () => {
+            const classDeclarationRegExp: RegExp = /class *(_0x[a-f0-9]{4,6}) *{/;
+            const asyncMethodRegExp: RegExp = /static *async *\['get'] *\(\) *{}/;
+
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/async-get-method.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('Match #1: should rename class declaration name', () => {
+                assert.match(obfuscatedCode, classDeclarationRegExp);
+            });
+
+            it('Match #2: should correctly rename async method name', () => {
+                assert.match(obfuscatedCode, asyncMethodRegExp);
+            });
+        });
+    });
+
+    describe('Variant #2: `PropertyDefinition` node', () => {
+        describe('Variant #1: identifier key', () => {
+            describe('Variant #1: default behaviour', () => {
+                const regExp: RegExp = /\['property'\] *= *0x1;/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/identifier-key.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should replace property definition node `key` property with square brackets literal', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
+
+            describe('Variant #2: `stringArray` option is enabled', () => {
+                const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['property', *'bar'\];/;
+                const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\(0x0\)\] *= *0x1;/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/identifier-key.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            stringArray: true,
+                            stringArrayThreshold: 1
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should add property definition node `key` property to string array', () => {
+                    assert.match(obfuscatedCode,  stringArrayRegExp);
+                });
+
+                it('should replace property definition node `key` property with call to string array', () => {
+                    assert.match(obfuscatedCode,  stringArrayCallRegExp);
+                });
+            });
+        });
+
+        describe('Variant #2: literal key', () => {
+            describe('Variant #1: Default behaviour', () => {
+                const regExp: RegExp = /\['property'\] *= *0x1;/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/literal-key.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should replace property definition node `key` property with square brackets literal', () => {
+                    assert.match(obfuscatedCode, regExp);
+                });
+            });
+
+            describe('Variant #2: `stringArray` option is enabled', () => {
+                const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['property', *'constructor', *'bar'];/;
+                const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\(0x0\)\] *= *0x1;/;
+
+                let obfuscatedCode: string;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/literal-key.js');
+
+                    obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            stringArray: true,
+                            stringArrayThreshold: 1
+                        }
+                    ).getObfuscatedCode();
+                });
+
+                it('should add property definition node `key` property to string array', () => {
+                    assert.match(obfuscatedCode,  stringArrayRegExp);
+                });
+
+                it('should replace property definition node `key` property with call to string array', () => {
+                    assert.match(obfuscatedCode,  stringArrayCallRegExp);
+                });
+            });
+        });
+
+        describe('Variant #3: async `property` method', () => {
+            const classDeclarationRegExp: RegExp = /class *(_0x[a-f0-9]{4,6}) *{/;
+            const asyncMethodRegExp: RegExp = /static \['property'] *= *async *\(\) *=> *{}/;
+
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/async-get-method.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('Match #1: should rename class declaration name', () => {
+                assert.match(obfuscatedCode, classDeclarationRegExp);
+            });
+
+            it('Match #2: should correctly rename async property method name', () => {
+                assert.match(obfuscatedCode, asyncMethodRegExp);
+            });
+        });
+    });
+});

+ 1 - 0
test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/fixtures/async-get-method.js → test/functional-tests/node-transformers/converting-transformers/class-field-transformer/fixtures/async-get-method.js

@@ -1,5 +1,6 @@
 (function () {
     class Foo {
+        static property = async () => {};
         static async get() {}
     }
 })();

+ 1 - 0
test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/fixtures/identifier-key.js → test/functional-tests/node-transformers/converting-transformers/class-field-transformer/fixtures/identifier-key.js

@@ -1,4 +1,5 @@
 class Foo {
+    property = 1;
     constructor () {}
     bar () {}
 }

+ 1 - 0
test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/fixtures/literal-key.js → test/functional-tests/node-transformers/converting-transformers/class-field-transformer/fixtures/literal-key.js

@@ -1,4 +1,5 @@
 class Foo {
+    'property' = 1;
     'constructor' () {}
     'bar' () {}
 }

+ 0 - 179
test/functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec.ts

@@ -1,179 +0,0 @@
-import { assert } from 'chai';
-
-import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
-
-import { readFileAsString } from '../../../../helpers/readFileAsString';
-
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
-
-describe('MethodDefinitionTransformer', () => {
-    describe('Variant #1: identifier key', () => {
-        describe('Variant #1: default behaviour', () => {
-            const regExp: RegExp = /\['bar'\]\(\)\{\}/;
-
-            let obfuscatedCode: string;
-
-            before(() => {
-                const code: string = readFileAsString(__dirname + '/fixtures/identifier-key.js');
-
-                obfuscatedCode = JavaScriptObfuscator.obfuscate(
-                    code,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET
-                    }
-                ).getObfuscatedCode();
-            });
-
-            it('should replace method definition node `key` property with square brackets literal', () => {
-                assert.match(obfuscatedCode, regExp);
-            });
-        });
-
-        describe('Variant #2: `stringArray` option is enabled', () => {
-            const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['bar'\];/;
-            const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\(0x0\)\]\(\)\{\}/;
-
-            let obfuscatedCode: string;
-
-            before(() => {
-                const code: string = readFileAsString(__dirname + '/fixtures/identifier-key.js');
-
-                obfuscatedCode = JavaScriptObfuscator.obfuscate(
-                    code,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET,
-                        stringArray: true,
-                        stringArrayThreshold: 1
-                    }
-                ).getObfuscatedCode();
-            });
-
-            it('should add method definition node `key` property to string array', () => {
-                assert.match(obfuscatedCode,  stringArrayRegExp);
-            });
-
-            it('should replace method definition node `key` property with call to string array', () => {
-                assert.match(obfuscatedCode,  stringArrayCallRegExp);
-            });
-        });
-
-        describe('Variant #3: `constructor` key', () => {
-            const regExp: RegExp = /constructor\(\)\{\}/;
-
-            let obfuscatedCode: string;
-
-            before(() => {
-                const code: string = readFileAsString(__dirname + '/fixtures/identifier-key.js');
-
-                obfuscatedCode = JavaScriptObfuscator.obfuscate(
-                    code,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET
-                    }
-                ).getObfuscatedCode();
-            });
-
-            it('shouldn\'t transform method definition node with `constructor` key', () => {
-                assert.match(obfuscatedCode, regExp);
-            });
-        });
-    });
-
-    describe('Variant #2: literal key', () => {
-        describe('Variant #1: Default behaviour', () => {
-            const regExp: RegExp = /\['bar'\]\(\)\{\}/;
-
-            let obfuscatedCode: string;
-
-            before(() => {
-                const code: string = readFileAsString(__dirname + '/fixtures/literal-key.js');
-
-                obfuscatedCode = JavaScriptObfuscator.obfuscate(
-                    code,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET
-                    }
-                ).getObfuscatedCode();
-            });
-
-            it('should replace method definition node `key` property with square brackets literal', () => {
-                assert.match(obfuscatedCode, regExp);
-            });
-        });
-
-        describe('Variant #2: `stringArray` option is enabled', () => {
-            const stringArrayRegExp: RegExp = /var _0x([a-f0-9]){4} *= *\['constructor', *'bar'];/;
-            const stringArrayCallRegExp: RegExp = /\[_0x([a-f0-9]){4}\(0x1\)\]\(\)\{\}/;
-
-            let obfuscatedCode: string;
-
-            before(() => {
-                const code: string = readFileAsString(__dirname + '/fixtures/literal-key.js');
-
-                obfuscatedCode = JavaScriptObfuscator.obfuscate(
-                    code,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET,
-                        stringArray: true,
-                        stringArrayThreshold: 1
-                    }
-                ).getObfuscatedCode();
-            });
-
-            it('should add method definition node `key` property to string array', () => {
-                assert.match(obfuscatedCode,  stringArrayRegExp);
-            });
-
-            it('should replace method definition node `key` property with call to string array', () => {
-                assert.match(obfuscatedCode,  stringArrayCallRegExp);
-            });
-        });
-
-        describe('Variant #3: `constructor` key', () => {
-            const regExp: RegExp = /'constructor'\(\)\{\}/;
-
-            let obfuscatedCode: string;
-
-            before(() => {
-                const code: string = readFileAsString(__dirname + '/fixtures/literal-key.js');
-
-                obfuscatedCode = JavaScriptObfuscator.obfuscate(
-                    code,
-                    {
-                        ...NO_ADDITIONAL_NODES_PRESET
-                    }
-                ).getObfuscatedCode();
-            });
-
-            it('shouldn\'t transform method definition node with `constructor` key', () => {
-                assert.match(obfuscatedCode, regExp);
-            });
-        });
-    });
-
-    describe('Variant #3: async `get()` method', () => {
-        const classDeclarationRegExp: RegExp = /class *(_0x[a-f0-9]{4,6}) *{/;
-        const asyncMethodRegExp: RegExp = /static *async *\['get'] *\(\) *{}/;
-
-        let obfuscatedCode: string;
-
-        before(() => {
-            const code: string = readFileAsString(__dirname + '/fixtures/async-get-method.js');
-
-            obfuscatedCode = JavaScriptObfuscator.obfuscate(
-                code,
-                {
-                    ...NO_ADDITIONAL_NODES_PRESET,
-                }
-            ).getObfuscatedCode();
-        });
-
-        it('Match #1: should rename class declaration name', () => {
-            assert.match(obfuscatedCode, classDeclarationRegExp);
-        });
-
-        it('Match #2: should correctly rename async method name', () => {
-            assert.match(obfuscatedCode, asyncMethodRegExp);
-        });
-    });
-});

+ 94 - 12
test/functional-tests/node-transformers/rename-properties-transformers/rename-properties-transformer/RenamePropertiesTransformer.spec.ts

@@ -13,7 +13,7 @@ describe('RenamePropertiesTransformer', () => {
     describe('transformNode', () => {
         describe('Mode: `unsafe`', () => {
             describe('Variant #1: Hexadecimal identifier names generator', () => {
-                describe('Variant #1: base properties rename', () => {
+                describe('Variant #1: object properties rename', () => {
                     const property1RegExp: RegExp = /'(_0x[a-f0-9]{4,6})': *0x1/;
                     const property2RegExp: RegExp = /'(_0x[a-f0-9]{4,6})': *0x2/;
                     const property3RegExp: RegExp = /\['(_0x[a-f0-9]{4,6})']: *0x3/;
@@ -52,10 +52,49 @@ describe('RenamePropertiesTransformer', () => {
                         assert.match(obfuscatedCode, property4RegExp);
                     });
                 });
+
+                describe('Variant #2: class property definitions rename', () => {
+                    const propertyDefinition1RegExp: RegExp = /\['(_0x[a-f0-9]{4,6})'] *= *0x1;/;
+                    const propertyDefinition2RegExp: RegExp = /static \['(_0x[a-f0-9]{4,6})'] *= *0x2/;
+                    const propertyDefinition3RegExp: RegExp = /\['(_0x[a-f0-9]{4,6})'] *= *0x3/;
+                    const propertyDefinition4RegExp: RegExp = /\[hawk] *= *0x4/;
+
+                    let obfuscatedCode: string;
+
+                    before(() => {
+                        const code: string = readFileAsString(__dirname + '/fixtures/property-definition-1.js');
+
+                        obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                            code,
+                            {
+                                ...NO_ADDITIONAL_NODES_PRESET,
+                                renameProperties: true,
+                                renamePropertiesMode: RenamePropertiesMode.Unsafe,
+                                identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
+                            }
+                        ).getObfuscatedCode();
+                    });
+
+                    it('Match #1: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition1RegExp);
+                    });
+
+                    it('Match #2: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition2RegExp);
+                    });
+
+                    it('Match #3: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition3RegExp);
+                    });
+
+                    it('Match #4: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition4RegExp);
+                    });
+                });
             });
 
             describe('Variant #2: Mangled identifier names generator', () => {
-                describe('Variant #1: base properties mangle', () => {
+                describe('Variant #1: object properties mangle', () => {
                     const property1RegExp: RegExp = /'a': *0x1/;
                     const property2RegExp: RegExp = /'b': *0x2/;
                     const property3RegExp: RegExp = /\['c']: *0x3/;
@@ -95,7 +134,46 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #2: base properties rename with rename globals', () => {
+                describe('Variant #2: class property definitions rename', () => {
+                    const propertyDefinition1RegExp: RegExp = /\['a'] *= *0x1;/;
+                    const propertyDefinition2RegExp: RegExp = /static \['b'] *= *0x2/;
+                    const propertyDefinition3RegExp: RegExp = /\['c'] *= *0x3/;
+                    const propertyDefinition4RegExp: RegExp = /\[hawk] *= *0x4/;
+
+                    let obfuscatedCode: string;
+
+                    before(() => {
+                        const code: string = readFileAsString(__dirname + '/fixtures/property-definition-1.js');
+
+                        obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                            code,
+                            {
+                                ...NO_ADDITIONAL_NODES_PRESET,
+                                renameProperties: true,
+                                renamePropertiesMode: RenamePropertiesMode.Unsafe,
+                                identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator
+                            }
+                        ).getObfuscatedCode();
+                    });
+
+                    it('Match #1: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition1RegExp);
+                    });
+
+                    it('Match #2: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition2RegExp);
+                    });
+
+                    it('Match #3: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition3RegExp);
+                    });
+
+                    it('Match #4: should rename property definition', () => {
+                        assert.match(obfuscatedCode, propertyDefinition4RegExp);
+                    });
+                });
+
+                describe('Variant #3: base properties rename with rename globals', () => {
                     const variable1RegExp: RegExp = /const d *= *'hawk'/;
                     const variable2RegExp: RegExp = /const e *= *{/;
                     const property1RegExp: RegExp = /'a': *0x1/;
@@ -146,7 +224,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #3: properties rename of nested objects', () => {
+                describe('Variant #4: properties rename of nested objects', () => {
                     const regExp: RegExp = new RegExp('' +
                         'const foo *= *{' +
                             '\'a\': *{' +
@@ -177,7 +255,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #4: properties rename of rest element', () => {
+                describe('Variant #5: properties rename of rest element', () => {
                     const regExp: RegExp = new RegExp('' +
                         'const foo *= *{' +
                             '\'a\': *0x1' +
@@ -207,7 +285,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #5: reserved dom properties', () => {
+                describe('Variant #6: reserved dom properties', () => {
                     const regExp: RegExp = new RegExp('' +
                         'const foo *= *{' +
                             '\'a\': *0x1,' +
@@ -239,7 +317,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #6: reserved names properties', () => {
+                describe('Variant #7: reserved names properties', () => {
                     const regExp: RegExp = new RegExp('' +
                         'const foo *= *{' +
                             '\'a\': *0x1,' +
@@ -272,7 +350,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #7: class methods', () => {
+                describe('Variant #8: class methods', () => {
                     const regExp: RegExp = new RegExp('' +
                         'class Foo *{' +
                             '\\[\'a\'] *\\(\\) *{}' +
@@ -303,7 +381,7 @@ describe('RenamePropertiesTransformer', () => {
                     });
                 });
 
-                describe('Variant #8: integration with `splitStrings` option', () => {
+                describe('Variant #9: integration with `splitStrings` option', () => {
                     const propertyRegExp: RegExp = new RegExp(
                         'const foo *= *{' +
                             '\'a\': *\'long\' *\\+ *\'Prop\' *\\+ *\'erty\' *\\+ *\'Valu\' *\\+ *\'e\'' +
@@ -394,8 +472,10 @@ describe('RenamePropertiesTransformer', () => {
                         '\'a\': *0x2 *' +
                     '}; *' +
                     'class Class *{ *' +
-                        'static\\[\'baz\'] *\\(\\) *{} *' +
-                        'static\\[\'b\'] *\\(\\) *{} *' +
+                        '\\[\'baz\'] *= *0x1; *' +
+                        'static *\\[\'b\'] *= *0x2;*' +
+                        'static *\\[\'hawk\'] *\\(\\) *{} *' +
+                        'static *\\[\'c\'] *\\(\\) *{} *' +
                     '}' +
                 '');
                 const referencesRegExp: RegExp = new RegExp('' +
@@ -403,7 +483,9 @@ describe('RenamePropertiesTransformer', () => {
                         'object\\[\'foo\'], *' +
                         'object\\[\'a\'], *' +
                         'Class\\[\'baz\'], *' +
-                        'Class\\[\'b\'] *' +
+                        'Class\\[\'b\'], *' +
+                        'Class\\[\'hawk\'], *' +
+                        'Class\\[\'c\'] *' +
                     '\\);' +
                 '');
 

+ 7 - 0
test/functional-tests/node-transformers/rename-properties-transformers/rename-properties-transformer/fixtures/property-definition-1.js

@@ -0,0 +1,7 @@
+const hawk = 'hawk';
+class Foo {
+    bar = 1;
+    static 'baz' = 2;
+    ['bark'] = 3;
+    [hawk] = 4;
+}

+ 6 - 3
test/functional-tests/node-transformers/rename-properties-transformers/rename-properties-transformer/fixtures/safe-mode.js

@@ -3,11 +3,14 @@ const object = {
     bar: 2
 };
 class Class {
-    static baz () {}
-    static bark () {}
+    baz = 1;
+    static bark = 2;
+    static hawk () {}
+    static eagle () {}
 }
 
 var excluded1 = 'foo';
 var excluded2 = 'baz';
+var excluded3 = 'hawk';
 
-console.log(object.foo, object['bar'], Class.baz, Class['bark']);
+console.log(object.foo, object['bar'], Class.baz, Class['bark'], Class.hawk, Class['eagle']);

+ 1 - 1
test/index.spec.ts

@@ -91,9 +91,9 @@ import './functional-tests/node-transformers/control-flow-transformers/control-f
 import './functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/string-litertal-control-flow-replacer/StringLiteralControlFlowReplacer.spec';
 import './functional-tests/node-transformers/control-flow-transformers/function-control-flow-transformer/FunctionControlFlowTransformer.spec';
 import './functional-tests/node-transformers/converting-transformers/boolean-literal-transformer/BooleanLiteralTransformer.spec';
+import './functional-tests/node-transformers/converting-transformers/class-field-transformer/ClassFieldTransformer.spec';
 import './functional-tests/node-transformers/converting-transformers/export-specifier-transformer/ExportSpecifierTransformer.spec';
 import './functional-tests/node-transformers/converting-transformers/member-expression-transformer/MemberExpressionTransformer.spec';
-import './functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec';
 import './functional-tests/node-transformers/converting-transformers/number-literal-transformer/NumberLiteralTransformer.spec';
 import './functional-tests/node-transformers/converting-transformers/numbers-to-numerical-expressions-transformer/NumbersToNumericalExpressionsTransformer.spec';
 import './functional-tests/node-transformers/converting-transformers/object-expression-keys-transformer/ObjectExpressionKeysTransformer.spec';

+ 3 - 1
tsconfig.json

@@ -4,6 +4,7 @@
   },
   "compilerOptions": {
     "emitDecoratorMetadata": true,
+    "exactOptionalPropertyTypes": false,
     "experimentalDecorators": true,
     "lib": [
       "es2019",
@@ -17,7 +18,8 @@
     "noImplicitThis": false,
     "noUnusedLocals": true,
     "removeComments": true,
-    "strict": true
+    "strict": true,
+    "useUnknownInCatchVariables": false
   },
   "exclude": [
     "node_modules"

+ 35 - 27
yarn.lock

@@ -405,7 +405,7 @@
   resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz"
   integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==
 
-"@es-joy/jsdoccomment@^0.9.0-alpha.1":
+"@es-joy/[email protected]":
   version "0.9.0-alpha.1"
   resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.9.0-alpha.1.tgz#f48bd162e185ec7f9f222273a282d10e52fe52f7"
   integrity sha512-Clxxc0PwpISoYYBibA+1L2qFJ7gvFVhI2Hos87S06K+Q0cXdOhZQJNKWuaQGPAeHjZEuUB/YoWOfwjuF2wirqA==
@@ -698,10 +698,10 @@
   dependencies:
     "@types/node" "*"
 
-"@types/mocha@8.2.3":
-  version "8.2.3"
-  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323"
-  integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==
+"@types/mocha@9.0.0":
+  version "9.0.0"
+  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.0.0.tgz#3205bcd15ada9bc681ac20bef64e9e6df88fd297"
+  integrity sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==
 
 "@types/[email protected]":
   version "4.0.0"
@@ -715,10 +715,10 @@
   resolved "https://registry.npmjs.org/@types/node/-/node-13.9.3.tgz"
   integrity sha512-01s+ac4qerwd6RHD+mVbOEsraDHSgUaefQlEdBbUolnQFjKwCr7luvAlEwW1RFojh67u0z4OUTjPn9LEl4zIkA==
 
-"@types/node@16.3.3":
-  version "16.3.3"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-16.3.3.tgz#0c30adff37bbbc7a50eb9b58fae2a504d0d88038"
-  integrity sha512-8h7k1YgQKxKXWckzFCMfsIwn0Y61UK6tlD6y2lOb3hTOIMlK3t9/QwHOhc81TwU+RMf0As5fj7NPjroERCnejQ==
+"@types/node@16.4.1":
+  version "16.4.1"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.1.tgz#9fad171a5b701613ee8a6f4ece3c88b1034b1b03"
+  integrity sha512-UW7cbLqf/Wu5XH2RKKY1cHwUNLicIDRLMraYKz+HHAerJ0ZffUEk+fMnd8qU2JaS6cAy0r8tsaf7yqHASf/Y0Q==
 
 "@types/normalize-package-data@^2.4.0":
   version "2.4.0"
@@ -1927,12 +1927,12 @@ [email protected]:
     resolve "^1.20.0"
     tsconfig-paths "^3.9.0"
 
-eslint-plugin-jsdoc@35.4.5:
-  version "35.4.5"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-35.4.5.tgz#20e9e52328b0e3dea1a70a965877dfe9d2b66edc"
-  integrity sha512-CguI9uhIJoihCsW5WTUY9xX2w9EpovmmHCz/JzAevC7Fcop+wyJLDjzaBnTh2LlSJvG9qVfkr7OJ+9i4cv1Kzg==
[email protected].1:
+  version "35.5.1"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-35.5.1.tgz#45932ee22669bbe06c97b82b936d56361efad370"
+  integrity sha512-pPYPWtsykwVEue1tYEyoppBj4dgF7XicF67tLLLraY6RQYBq7qMKjUHji19+hfiTtYKKBD0YfeK8hgjPAE5viw==
   dependencies:
-    "@es-joy/jsdoccomment" "^0.9.0-alpha.1"
+    "@es-joy/jsdoccomment" "0.9.0-alpha.1"
     comment-parser "1.1.6-beta.0"
     debug "^4.3.2"
     esquery "^1.4.0"
@@ -1986,6 +1986,14 @@ [email protected], eslint-scope@^5.1.1:
     esrecurse "^4.3.0"
     estraverse "^4.1.1"
 
[email protected]:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-6.0.0.tgz#9cf45b13c5ac8f3d4c50f46a5121f61b3e318978"
+  integrity sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==
+  dependencies:
+    esrecurse "^4.3.0"
+    estraverse "^5.2.0"
+
 eslint-template-visitor@^2.3.2:
   version "2.3.2"
   resolved "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz"
@@ -4534,10 +4542,10 @@ typedarray@^0.0.6:
   resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
   integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
 
-typescript@4.3.5:
-  version "4.3.5"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
-  integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==
+typescript@4.4.0-beta:
+  version "4.4.0-beta"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.0-beta.tgz#a5b8a3a0d260fa5ce84daa3ab58f7102ad19a655"
+  integrity sha512-qMxA8NzN3igwX8Mii7MXGNW+YeFAkUKyKg+x4F1CCFsO36LqISf1EXXSOLDuRIdGjdVvV53grRxfHjOW65YfMA==
 
 unbox-primitive@^1.0.1:
   version "1.0.1"
@@ -4646,18 +4654,18 @@ [email protected]:
   resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz#1a3407c158d547a9feb4229a9e3385b7b60c9917"
   integrity sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==
 
-webpack-sources@^2.3.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.0.tgz#9ed2de69b25143a4c18847586ad9eccb19278cfa"
-  integrity sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==
+webpack-sources@^2.3.1:
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd"
+  integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==
   dependencies:
     source-list-map "^2.0.1"
     source-map "^0.6.1"
 
[email protected]5.1:
-  version "5.45.1"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.45.1.tgz#d78dcbeda18a872dc62b0455d3ed3dcfd1c886bb"
-  integrity sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==
[email protected]6.0:
+  version "5.46.0"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.46.0.tgz#105d20d96f79db59b316b0ae54316f0f630314b5"
+  integrity sha512-qxD0t/KTedJbpcXUmvMxY5PUvXDbF8LsThCzqomeGaDlCA6k998D8yYVwZMvO8sSM3BTEOaD4uzFniwpHaTIJw==
   dependencies:
     "@types/eslint-scope" "^3.7.0"
     "@types/estree" "^0.0.50"
@@ -4681,7 +4689,7 @@ [email protected]:
     tapable "^2.1.1"
     terser-webpack-plugin "^5.1.3"
     watchpack "^2.2.0"
-    webpack-sources "^2.3.0"
+    webpack-sources "^2.3.1"
 
 which-boxed-primitive@^1.0.2:
   version "1.0.2"

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików