Added StringArrayCallNode custom node

This commit is contained in:
sanex
2020-09-10 20:46:53 +03:00
parent b483ef17cf
commit 7df32035ec
7 changed files with 164 additions and 55 deletions
+6 -6
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -18,6 +18,7 @@ import { CallExpressionFunctionNode } from '../../../custom-nodes/control-flow-f
import { ControlFlowStorageNode } from '../../../custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ControlFlowStorageNode';
import { ExpressionWithOperatorControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ExpressionWithOperatorControlFlowStorageCallNode';
import { LogicalExpressionFunctionNode } from '../../../custom-nodes/control-flow-flattening-nodes/LogicalExpressionFunctionNode';
import { StringArrayCallNode } from '../../../custom-nodes/string-array-nodes/StringArrayCallNode';
import { StringArrayIntermediateCallsWrapperNode } from '../../../custom-nodes/string-array-nodes/StringArrayIntermediateCallsWrapperNode';
import { StringLiteralControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/StringLiteralControlFlowStorageCallNode';
import { StringLiteralNode } from '../../../custom-nodes/control-flow-flattening-nodes/StringLiteralNode';
@@ -71,6 +72,10 @@ export const customNodesModule: interfaces.ContainerModule = new ContainerModule
.whenTargetNamed(ObjectExpressionKeysTransformerCustomNode.ObjectExpressionVariableDeclarationHostNode);
// string array transformer nodes
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(StringArrayCallNode)
.whenTargetNamed(StringArrayTransformerCustomNode.StringArrayCallNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(StringArrayIntermediateCallsWrapperNode)
.whenTargetNamed(StringArrayTransformerCustomNode.StringArrayIntermediateCallsWrapperNode);
@@ -0,0 +1,130 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as ESTree from 'estree';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { initializable } from '../../decorators/Initializable';
import { AbstractCustomNode } from '../AbstractCustomNode';
import { NodeFactory } from '../../node/NodeFactory';
import { NodeMetadata } from '../../node/NodeMetadata';
import { NodeUtils } from '../../node/NodeUtils';
import { NumberUtils } from '../../utils/NumberUtils';
@injectable()
export class StringArrayCallNode extends AbstractCustomNode {
/**
* @type {string | null}
*/
@initializable()
private decodeKey!: string | null;
/**
* @type {number}
*/
@initializable()
private index!: number;
/**
* @type {string}
*/
@initializable()
private stringArrayCallsWrapperName!: string;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(
identifierNamesGeneratorFactory,
customCodeHelperFormatter,
randomGenerator,
options
);
}
/**
* @param {string} hexadecimalIndex
* @returns {Literal}
*/
private static getHexadecimalLiteralNode (hexadecimalIndex: string): ESTree.Literal {
const hexadecimalLiteralNode: ESTree.Literal = NodeFactory.literalNode(hexadecimalIndex);
NodeMetadata.set(hexadecimalLiteralNode, { replacedLiteral: true });
return hexadecimalLiteralNode;
}
/**
* @param {string} decodeKey
* @returns {Literal}
*/
private static getRc4KeyLiteralNode (decodeKey: string): ESTree.Literal {
const rc4KeyLiteralNode: ESTree.Literal = NodeFactory.literalNode(decodeKey);
NodeMetadata.set(rc4KeyLiteralNode, { replacedLiteral: true });
return rc4KeyLiteralNode;
}
/**
* @param {string} stringArrayCallsWrapperName
* @param {number} index
* @param {string | null} decodeKey
*/
public initialize (
stringArrayCallsWrapperName: string,
index: number,
decodeKey: string | null
): void {
this.stringArrayCallsWrapperName = stringArrayCallsWrapperName;
this.index = index;
this.decodeKey = decodeKey;
}
/**
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
const hexadecimalIndex: string = NumberUtils.toHex(this.index);
const callExpressionArgs: ESTree.Literal[] = [
StringArrayCallNode.getHexadecimalLiteralNode(hexadecimalIndex)
];
if (this.decodeKey) {
callExpressionArgs.push(StringArrayCallNode.getRc4KeyLiteralNode(this.decodeKey));
}
const stringArrayIdentifierNode: ESTree.Identifier =
NodeFactory.identifierNode(this.stringArrayCallsWrapperName);
const structure: TStatement = NodeFactory.expressionStatementNode(
NodeFactory.callExpressionNode(
stringArrayIdentifierNode,
callExpressionArgs
)
);
NodeUtils.parentizeAst(structure);
return [structure];
}
}
@@ -1,3 +1,4 @@
export enum StringArrayTransformerCustomNode {
StringArrayCallNode = 'StringArrayCallNode',
StringArrayIntermediateCallsWrapperNode = 'StringArrayIntermediateCallsWrapperNode'
}
@@ -5,6 +5,7 @@ import * as ESTree from 'estree';
import { TInitialData } from '../../types/TInitialData';
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
import { TStatement } from '../../types/node/TStatement';
import { TStringArrayEncoding } from '../../types/options/TStringArrayEncoding';
import { TStringArrayIntermediateCallsWrapperDataByEncoding } from '../../types/node-transformers/string-array-transformers/TStringArrayIntermediateCallsWrapperDataByEncoding';
import { TStringArrayTransformerCustomNodeFactory } from '../../types/container/custom-nodes/TStringArrayTransformerCustomNodeFactory';
@@ -17,6 +18,7 @@ import { TIdentifierNamesGeneratorFactory } from '../../types/container/generato
import { ILiteralNodesCacheStorage } from '../../interfaces/storages/string-array-transformers/ILiteralNodesCacheStorage';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { IStringArrayIntermediateCallsWrapperData } from '../../interfaces/node-transformers/string-array-transformers/IStringArrayIntermediateCallsWrapperData';
import { IStringArrayStorage } from '../../interfaces/storages/string-array-transformers/IStringArrayStorage';
import { IStringArrayStorageAnalyzer } from '../../interfaces/analyzers/string-array-storage-analyzer/IStringArrayStorageAnalyzer';
import { IStringArrayStorageItemData } from '../../interfaces/storages/string-array-transformers/IStringArrayStorageItem';
@@ -32,7 +34,7 @@ import { NodeGuards } from '../../node/NodeGuards';
import { NodeLiteralUtils } from '../../node/NodeLiteralUtils';
import { NodeMetadata } from '../../node/NodeMetadata';
import { NodeUtils } from '../../node/NodeUtils';
import { NumberUtils } from '../../utils/NumberUtils';
import { StringArrayCallNode } from '../../custom-nodes/string-array-nodes/StringArrayCallNode';
import { StringArrayIntermediateCallsWrapperNode } from '../../custom-nodes/string-array-nodes/StringArrayIntermediateCallsWrapperNode';
@injectable()
@@ -120,30 +122,6 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
this.stringArrayTransformerCustomNodeFactory = stringArrayTransformerCustomNodeFactory;
}
/**
* @param {string} hexadecimalIndex
* @returns {Literal}
*/
private static getHexadecimalLiteralNode (hexadecimalIndex: string): ESTree.Literal {
const hexadecimalLiteralNode: ESTree.Literal = NodeFactory.literalNode(hexadecimalIndex);
NodeMetadata.set(hexadecimalLiteralNode, { replacedLiteral: true });
return hexadecimalLiteralNode;
}
/**
* @param {string} literalValue
* @returns {Literal}
*/
private static getRc4KeyLiteralNode (literalValue: string): ESTree.Literal {
const rc4KeyLiteralNode: ESTree.Literal = NodeFactory.literalNode(literalValue);
NodeMetadata.set(rc4KeyLiteralNode, { replacedLiteral: true });
return rc4KeyLiteralNode;
}
/**
* @param {NodeTransformationStage} nodeTransformationStage
* @returns {IVisitor | null}
@@ -248,27 +226,21 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
* @returns {Node}
*/
private getStringArrayCallNode (stringArrayStorageItemData: IStringArrayStorageItemData): ESTree.Node {
const stringArrayCallsWrapperName: string = this.getStringArrayCallsWrapperName(stringArrayStorageItemData);
const { index, decodeKey } = stringArrayStorageItemData;
const hexadecimalIndex: string = NumberUtils.toHex(index);
const callExpressionArgs: (ESTree.Expression | ESTree.SpreadElement)[] = [
StringArrayTransformer.getHexadecimalLiteralNode(hexadecimalIndex)
];
const stringArrayCallCustomNode: ICustomNode<TInitialData<StringArrayCallNode>> =
this.stringArrayTransformerCustomNodeFactory(StringArrayTransformerCustomNode.StringArrayCallNode);
if (decodeKey) {
callExpressionArgs.push(StringArrayTransformer.getRc4KeyLiteralNode(decodeKey));
stringArrayCallCustomNode.initialize(stringArrayCallsWrapperName, index, decodeKey);
const statementNode: TStatement = stringArrayCallCustomNode.getNode()[0];
if (!NodeGuards.isExpressionStatementNode(statementNode)) {
throw new Error('`stringArrayCallCustomNode.getNode()[0]` should returns array with `ExpressionStatement` node');
}
const stringArrayCallsWrapperName: string = this.getStringArrayCallsWrapperName(stringArrayStorageItemData);
const stringArrayIdentifierNode: ESTree.Identifier = NodeFactory.identifierNode(
stringArrayCallsWrapperName
);
return NodeFactory.callExpressionNode(
stringArrayIdentifierNode,
callExpressionArgs
);
return statementNode.expression;
}
/**
@@ -280,7 +252,6 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
const stringArrayCallsWrapperName: string = this.stringArrayStorage.getStorageCallsWrapperName(encoding);
// Name of the string array calls wrapper itself
if (!this.options.stringArrayIntermediateVariablesCount) {
return stringArrayCallsWrapperName;
}
@@ -291,13 +262,12 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
throw new Error('Cannot find current lexical scope node');
}
const stringArrayIntermediateCallsWrapperDataByEncoding: TStringArrayIntermediateCallsWrapperDataByEncoding = currentLexicalScopeNode
? this.stringArrayIntermediateCallsWrapperDataByEncodingMap.get(currentLexicalScopeNode) ?? {}
: {};
const stringArrayIntermediateCallsWrapperDataByEncoding: TStringArrayIntermediateCallsWrapperDataByEncoding =
this.stringArrayIntermediateCallsWrapperDataByEncodingMap.get(currentLexicalScopeNode) ?? {};
const stringArrayIntermediateCallsWrapperNames: string[] = stringArrayIntermediateCallsWrapperDataByEncoding[encoding]?.names ?? [];
const isFilledIntermediateCallsWrapperNamesList: boolean = stringArrayIntermediateCallsWrapperNames.length === this.options.stringArrayIntermediateVariablesCount;
if (currentLexicalScopeNode && !isFilledIntermediateCallsWrapperNamesList) {
if (!isFilledIntermediateCallsWrapperNamesList) {
const nextIntermediateCallsWrapperName: string = this.identifierNamesGenerator.generateForLexicalScope(currentLexicalScopeNode);
stringArrayIntermediateCallsWrapperNames.push(nextIntermediateCallsWrapperName);
@@ -348,6 +318,7 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
? lexicalScopeNode
: lexicalScopeNode.body;
// invalid lexical scope node
if (
!lexicalScopeBodyNode.parentNode
|| !NodeGuards.isNodeWithLexicalScopeStatements(lexicalScopeBodyNode, lexicalScopeBodyNode.parentNode)
@@ -362,9 +333,10 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
return lexicalScopeNode;
}
const stringArrayIntermediateCallsWrapperDataList =
const stringArrayIntermediateCallsWrapperDataList: (IStringArrayIntermediateCallsWrapperData | undefined)[] =
Object.values(stringArrayIntermediateCallsWrapperDataByEncoding);
// iterates over data for each encoding type
for (const stringArrayIntermediateCallsWrapperData of stringArrayIntermediateCallsWrapperDataList) {
if (!stringArrayIntermediateCallsWrapperData) {
continue;
@@ -372,6 +344,7 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
const {encoding, names} = stringArrayIntermediateCallsWrapperData;
// iterates over each name of intermediate calls wrapper name
for (const stringArrayIntermediateCallsWrapperName of names) {
const stringArrayRootCallsWrapperName: string = this.getStringArrayRootCallsWrapperName(encoding);
const stringArrayIntermediateCallsWrapperNode: ICustomNode<TInitialData<StringArrayIntermediateCallsWrapperNode>> =