mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Sync with 0.17.2 branch
This commit is contained in:
+17
-19
@@ -5,13 +5,14 @@ import * as escodegen from 'escodegen-wallaby';
|
||||
import * as espree from 'espree';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TObfuscatedCodeFactory } from './types/container/source-code/TObfuscatedCodeFactory';
|
||||
|
||||
import { IGeneratorOutput } from './interfaces/IGeneratorOutput';
|
||||
import { IJavaScriptObfuscator } from './interfaces/IJavaScriptObfsucator';
|
||||
import { ILogger } from './interfaces/logger/ILogger';
|
||||
import { IObfuscationResult } from './interfaces/IObfuscationResult';
|
||||
import { IObfuscatedCode } from './interfaces/source-code/IObfuscatedCode';
|
||||
import { IOptions } from './interfaces/options/IOptions';
|
||||
import { IRandomGenerator } from './interfaces/utils/IRandomGenerator';
|
||||
import { ISourceMapCorrector } from './interfaces/source-map/ISourceMapCorrector';
|
||||
import { ITransformersRunner } from './interfaces/node-transformers/ITransformersRunner';
|
||||
|
||||
import { LoggingMessage } from './enums/logger/LoggingMessage';
|
||||
@@ -79,6 +80,11 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
|
||||
*/
|
||||
private readonly logger: ILogger;
|
||||
|
||||
/**
|
||||
* @type {TObfuscatedCodeFactory}
|
||||
*/
|
||||
private readonly obfuscatedCodeFactory: TObfuscatedCodeFactory;
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
@@ -89,11 +95,6 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
|
||||
*/
|
||||
private readonly randomGenerator: IRandomGenerator;
|
||||
|
||||
/**
|
||||
* @type {ISourceMapCorrector}
|
||||
*/
|
||||
private readonly sourceMapCorrector: ISourceMapCorrector;
|
||||
|
||||
/**
|
||||
* @type {ITransformersRunner}
|
||||
*/
|
||||
@@ -101,30 +102,30 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
|
||||
|
||||
/**
|
||||
* @param {ITransformersRunner} transformersRunner
|
||||
* @param {ISourceMapCorrector} sourceMapCorrector
|
||||
* @param {IRandomGenerator} randomGenerator
|
||||
* @param {TObfuscatedCodeFactory} obfuscatedCodeFactory
|
||||
* @param {ILogger} logger
|
||||
* @param {IOptions} options
|
||||
*/
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.ITransformersRunner) transformersRunner: ITransformersRunner,
|
||||
@inject(ServiceIdentifiers.ISourceMapCorrector) sourceMapCorrector: ISourceMapCorrector,
|
||||
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscatedCode) obfuscatedCodeFactory: TObfuscatedCodeFactory,
|
||||
@inject(ServiceIdentifiers.ILogger) logger: ILogger,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
this.transformersRunner = transformersRunner;
|
||||
this.sourceMapCorrector = sourceMapCorrector;
|
||||
this.randomGenerator = randomGenerator;
|
||||
this.obfuscatedCodeFactory = obfuscatedCodeFactory;
|
||||
this.logger = logger;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sourceCode
|
||||
* @returns {IObfuscationResult}
|
||||
* @returns {IObfuscatedCode}
|
||||
*/
|
||||
public obfuscate (sourceCode: string): IObfuscationResult {
|
||||
public obfuscate (sourceCode: string): IObfuscatedCode {
|
||||
const timeStart: number = Date.now();
|
||||
this.logger.info(LoggingMessage.Version, process.env.VERSION);
|
||||
this.logger.info(LoggingMessage.ObfuscationStarted);
|
||||
@@ -142,7 +143,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
|
||||
const obfuscationTime: number = (Date.now() - timeStart) / 1000;
|
||||
this.logger.success(LoggingMessage.ObfuscationCompleted, obfuscationTime);
|
||||
|
||||
return this.getObfuscationResult(generatorOutput);
|
||||
return this.getObfuscatedCode(generatorOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,13 +216,10 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
|
||||
|
||||
/**
|
||||
* @param {IGeneratorOutput} generatorOutput
|
||||
* @returns {IObfuscationResult}
|
||||
* @returns {IObfuscatedCode}
|
||||
*/
|
||||
private getObfuscationResult (generatorOutput: IGeneratorOutput): IObfuscationResult {
|
||||
return this.sourceMapCorrector.correct(
|
||||
generatorOutput.code,
|
||||
generatorOutput.map
|
||||
);
|
||||
private getObfuscatedCode (generatorOutput: IGeneratorOutput): IObfuscatedCode {
|
||||
return this.obfuscatedCodeFactory(generatorOutput.code, generatorOutput.map);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@ import { TInputOptions } from './types/options/TInputOptions';
|
||||
|
||||
import { IInversifyContainerFacade } from './interfaces/container/IInversifyContainerFacade';
|
||||
import { IJavaScriptObfuscator } from './interfaces/IJavaScriptObfsucator';
|
||||
import { IObfuscationResult } from './interfaces/IObfuscationResult';
|
||||
import { IObfuscatedCode } from './interfaces/source-code/IObfuscatedCode';
|
||||
|
||||
import { InversifyContainerFacade } from './container/InversifyContainerFacade';
|
||||
|
||||
@@ -19,20 +19,20 @@ class JavaScriptObfuscatorFacade {
|
||||
/**
|
||||
* @param {string} sourceCode
|
||||
* @param {TInputOptions} inputOptions
|
||||
* @returns {IObfuscationResult}
|
||||
* @returns {IObfuscatedCode}
|
||||
*/
|
||||
public static obfuscate (sourceCode: string, inputOptions: TInputOptions = {}): IObfuscationResult {
|
||||
public static obfuscate (sourceCode: string, inputOptions: TInputOptions = {}): IObfuscatedCode {
|
||||
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
|
||||
|
||||
inversifyContainerFacade.load(sourceCode, inputOptions);
|
||||
inversifyContainerFacade.load(sourceCode, '', inputOptions);
|
||||
|
||||
const javaScriptObfuscator: IJavaScriptObfuscator = inversifyContainerFacade
|
||||
.get<IJavaScriptObfuscator>(ServiceIdentifiers.IJavaScriptObfuscator);
|
||||
const obfuscationResult: IObfuscationResult = javaScriptObfuscator.obfuscate(sourceCode);
|
||||
const obfuscatedCode: IObfuscatedCode = javaScriptObfuscator.obfuscate(sourceCode);
|
||||
|
||||
inversifyContainerFacade.unload();
|
||||
|
||||
return obfuscationResult;
|
||||
return obfuscatedCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
import { injectable } from 'inversify';
|
||||
|
||||
import { IObfuscationResult } from './interfaces/IObfuscationResult';
|
||||
|
||||
import { initializable } from './decorators/Initializable';
|
||||
|
||||
@injectable()
|
||||
export class ObfuscationResult implements IObfuscationResult {
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@initializable()
|
||||
private obfuscatedCode!: string;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@initializable()
|
||||
private sourceMap!: string;
|
||||
|
||||
/**
|
||||
* @param {string} obfuscatedCode
|
||||
* @param {string} sourceMap
|
||||
*/
|
||||
public initialize (obfuscatedCode: string, sourceMap: string): void {
|
||||
this.obfuscatedCode = obfuscatedCode;
|
||||
this.sourceMap = sourceMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getObfuscatedCode (): string {
|
||||
return this.obfuscatedCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getSourceMap (): string {
|
||||
return this.sourceMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public toString (): string {
|
||||
return this.obfuscatedCode;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { ISourceCode } from './interfaces/ISourceCode';
|
||||
|
||||
export class SourceCode implements ISourceCode {
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private readonly sourceCode: string;
|
||||
|
||||
/**
|
||||
* @param {string} sourceCode
|
||||
*/
|
||||
constructor (sourceCode: string) {
|
||||
this.sourceCode = sourceCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getSourceCode (): string {
|
||||
return this.sourceCode;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import { IStackTraceData } from '../../interfaces/analyzers/stack-trace-analyzer
|
||||
import { CalleeDataExtractor } from '../../enums/analyzers/stack-trace-analyzer/CalleeDataExtractor';
|
||||
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { NodeStatementUtils } from '../../node/NodeStatementUtils';
|
||||
|
||||
/**
|
||||
* This class generates a data with a stack trace of functions calls
|
||||
@@ -131,7 +131,7 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (blockScopeBodyNode.parentNode !== NodeUtils.getBlockScopeOfNode(node)) {
|
||||
if (blockScopeBodyNode.parentNode !== NodeStatementUtils.getParentNodeWithStatements(node)) {
|
||||
return estraverse.VisitorOption.Skip;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ import { ICalleeData } from '../../../interfaces/analyzers/stack-trace-analyzer/
|
||||
|
||||
import { AbstractCalleeDataExtractor } from './AbstractCalleeDataExtractor';
|
||||
import { NodeGuards } from '../../../node/NodeGuards';
|
||||
import { NodeUtils } from '../../../node/NodeUtils';
|
||||
import { NodeStatementUtils } from '../../../node/NodeStatementUtils';
|
||||
|
||||
@injectable()
|
||||
export class FunctionDeclarationCalleeDataExtractor extends AbstractCalleeDataExtractor {
|
||||
@@ -22,7 +22,7 @@ export class FunctionDeclarationCalleeDataExtractor extends AbstractCalleeDataEx
|
||||
}
|
||||
|
||||
const calleeBlockStatement: ESTree.BlockStatement | null = this.getCalleeBlockStatement(
|
||||
NodeUtils.getBlockScopeOfNode(blockScopeBody[0]),
|
||||
NodeStatementUtils.getParentNodeWithStatements(blockScopeBody[0]),
|
||||
callee.name
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ import { ICalleeData } from '../../../interfaces/analyzers/stack-trace-analyzer/
|
||||
|
||||
import { AbstractCalleeDataExtractor } from './AbstractCalleeDataExtractor';
|
||||
import { NodeGuards } from '../../../node/NodeGuards';
|
||||
import { NodeUtils } from '../../../node/NodeUtils';
|
||||
import { NodeStatementUtils } from '../../../node/NodeStatementUtils';
|
||||
|
||||
@injectable()
|
||||
export class FunctionExpressionCalleeDataExtractor extends AbstractCalleeDataExtractor {
|
||||
@@ -21,7 +21,7 @@ export class FunctionExpressionCalleeDataExtractor extends AbstractCalleeDataExt
|
||||
|
||||
if (NodeGuards.isIdentifierNode(callee)) {
|
||||
calleeBlockStatement = this.getCalleeBlockStatement(
|
||||
NodeUtils.getBlockScopeOfNode(blockScopeBody[0]),
|
||||
NodeStatementUtils.getParentNodeWithStatements(blockScopeBody[0]),
|
||||
callee.name
|
||||
);
|
||||
}
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import { ICalleeData } from '../../../interfaces/analyzers/stack-trace-analyzer/
|
||||
|
||||
import { AbstractCalleeDataExtractor } from './AbstractCalleeDataExtractor';
|
||||
import { NodeGuards } from '../../../node/NodeGuards';
|
||||
import { NodeUtils } from '../../../node/NodeUtils';
|
||||
import { NodeStatementUtils } from '../../../node/NodeStatementUtils';
|
||||
|
||||
@injectable()
|
||||
export class ObjectExpressionCalleeDataExtractor extends AbstractCalleeDataExtractor {
|
||||
@@ -51,7 +51,7 @@ export class ObjectExpressionCalleeDataExtractor extends AbstractCalleeDataExtra
|
||||
|
||||
const functionExpressionName: string | number | null = objectMembersCallsChain[objectMembersCallsChain.length - 1];
|
||||
const calleeBlockStatement: ESTree.BlockStatement | null = this.getCalleeBlockStatement(
|
||||
NodeUtils.getBlockScopeOfNode(blockScopeBody[0]),
|
||||
NodeStatementUtils.getParentNodeWithStatements(blockScopeBody[0]),
|
||||
objectMembersCallsChain
|
||||
);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { TSourceCodeData } from '../types/cli/TSourceCodeData';
|
||||
|
||||
import { IFileData } from '../interfaces/cli/IFileData';
|
||||
import { IInitializable } from '../interfaces/IInitializable';
|
||||
import { IObfuscationResult } from '../interfaces/IObfuscationResult';
|
||||
import { IObfuscatedCode } from '../interfaces/source-code/IObfuscatedCode';
|
||||
|
||||
import { initializable } from '../decorators/Initializable';
|
||||
|
||||
@@ -131,12 +131,12 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
|
||||
sourceMapFileName: path.basename(outputSourceMapPath)
|
||||
};
|
||||
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(sourceCode, options);
|
||||
const obfuscatedCode: IObfuscatedCode = JavaScriptObfuscator.obfuscate(sourceCode, options);
|
||||
|
||||
CLIUtils.writeFile(outputCodePath, obfuscationResult.getObfuscatedCode());
|
||||
CLIUtils.writeFile(outputCodePath, obfuscatedCode.getObfuscatedCode());
|
||||
|
||||
if (options.sourceMapMode === 'separate' && obfuscationResult.getSourceMap()) {
|
||||
CLIUtils.writeFile(outputSourceMapPath, obfuscationResult.getSourceMap());
|
||||
if (options.sourceMapMode === 'separate' && obfuscatedCode.getSourceMap()) {
|
||||
CLIUtils.writeFile(outputSourceMapPath, obfuscatedCode.getSourceMap());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,17 +20,15 @@ import { IInversifyContainerFacade } from '../interfaces/container/IInversifyCon
|
||||
import { IJavaScriptObfuscator } from '../interfaces/IJavaScriptObfsucator';
|
||||
import { ILogger } from '../interfaces/logger/ILogger';
|
||||
import { IObfuscationEventEmitter } from '../interfaces/event-emitters/IObfuscationEventEmitter';
|
||||
import { IObfuscationResult } from '../interfaces/IObfuscationResult';
|
||||
import { ISourceCode } from '../interfaces/ISourceCode';
|
||||
import { ISourceMapCorrector } from '../interfaces/source-map/ISourceMapCorrector';
|
||||
import { IObfuscatedCode } from '../interfaces/source-code/IObfuscatedCode';
|
||||
import { ISourceCode } from '../interfaces/source-code/ISourceCode';
|
||||
import { ITransformersRunner } from '../interfaces/node-transformers/ITransformersRunner';
|
||||
|
||||
import { JavaScriptObfuscator } from '../JavaScriptObfuscator';
|
||||
import { Logger } from '../logger/Logger';
|
||||
import { ObfuscationEventEmitter } from '../event-emitters/ObfuscationEventEmitter';
|
||||
import { ObfuscationResult } from '../ObfuscationResult';
|
||||
import { SourceCode } from '../SourceCode';
|
||||
import { SourceMapCorrector } from '../source-map/SourceMapCorrector';
|
||||
import { ObfuscatedCode } from '../source-code/ObfuscatedCode';
|
||||
import { SourceCode } from '../source-code/SourceCode';
|
||||
import { TransformersRunner } from '../node-transformers/TransformersRunner';
|
||||
|
||||
export class InversifyContainerFacade implements IInversifyContainerFacade {
|
||||
@@ -140,12 +138,13 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
|
||||
|
||||
/**
|
||||
* @param {string} sourceCode
|
||||
* @param {string} sourceMap
|
||||
* @param {TInputOptions} options
|
||||
*/
|
||||
public load (sourceCode: string, options: TInputOptions): void {
|
||||
public load (sourceCode: string, sourceMap: string, options: TInputOptions): void {
|
||||
this.container
|
||||
.bind<ISourceCode>(ServiceIdentifiers.ISourceCode)
|
||||
.toDynamicValue(() => new SourceCode(sourceCode))
|
||||
.toDynamicValue(() => new SourceCode(sourceCode, sourceMap))
|
||||
.inSingletonScope();
|
||||
|
||||
this.container
|
||||
@@ -169,28 +168,22 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
|
||||
.inSingletonScope();
|
||||
|
||||
this.container
|
||||
.bind<IObfuscationResult>(ServiceIdentifiers.IObfuscationResult)
|
||||
.to(ObfuscationResult)
|
||||
.inSingletonScope();
|
||||
.bind<IObfuscatedCode>(ServiceIdentifiers.IObfuscatedCode)
|
||||
.to(ObfuscatedCode);
|
||||
|
||||
this.container
|
||||
.bind<IObfuscationResult>(ServiceIdentifiers.Factory__IObfuscationResult)
|
||||
.toFactory<IObfuscationResult>((context: interfaces.Context) => {
|
||||
return (obfuscatedCode: string, sourceMap: string) => {
|
||||
const obfuscationResult: IObfuscationResult = context.container
|
||||
.get<IObfuscationResult>(ServiceIdentifiers.IObfuscationResult);
|
||||
.bind<IObfuscatedCode>(ServiceIdentifiers.Factory__IObfuscatedCode)
|
||||
.toFactory<IObfuscatedCode>((context: interfaces.Context) => {
|
||||
return (obfuscatedCodeAsString: string, sourceMapAsString: string) => {
|
||||
const obfuscatedCode: IObfuscatedCode = context.container
|
||||
.get<IObfuscatedCode>(ServiceIdentifiers.IObfuscatedCode);
|
||||
|
||||
obfuscationResult.initialize(obfuscatedCode, sourceMap);
|
||||
obfuscatedCode.initialize(obfuscatedCodeAsString, sourceMapAsString);
|
||||
|
||||
return obfuscationResult;
|
||||
return obfuscatedCode;
|
||||
};
|
||||
});
|
||||
|
||||
this.container
|
||||
.bind<ISourceMapCorrector>(ServiceIdentifiers.ISourceMapCorrector)
|
||||
.to(SourceMapCorrector)
|
||||
.inSingletonScope();
|
||||
|
||||
this.container
|
||||
.bind<IObfuscationEventEmitter>(ServiceIdentifiers.IObfuscationEventEmitter)
|
||||
.to(ObfuscationEventEmitter)
|
||||
|
||||
@@ -9,7 +9,7 @@ export enum ServiceIdentifiers {
|
||||
Factory__IIdentifierObfuscatingReplacer = 'Factory<IIdentifierObfuscatingReplacer>',
|
||||
Factory__INodeGuard = 'Factory<INodeGuard>',
|
||||
Factory__INodeTransformer = 'Factory<INodeTransformer[]>',
|
||||
Factory__IObfuscationResult = 'Factory<IObfuscationResult>',
|
||||
Factory__IObfuscatedCode = 'Factory<IObfuscatedCode>',
|
||||
Factory__IObfuscatingReplacer = 'Factory<IObfuscatingReplacer>',
|
||||
Factory__IPropertiesExtractor = 'Factory<IPropertiesExtractor>',
|
||||
Factory__TControlFlowStorage = 'Factory<TControlFlowStorage>',
|
||||
@@ -27,7 +27,7 @@ export enum ServiceIdentifiers {
|
||||
INodeGuard = 'INodeGuard',
|
||||
INodeTransformer = 'INodeTransformer',
|
||||
IObfuscationEventEmitter = 'IObfuscationEventEmitter',
|
||||
IObfuscationResult = 'IObfuscationResult',
|
||||
IObfuscatedCode = 'IObfuscatedCode',
|
||||
IOptions = 'IOptions',
|
||||
IOptionsNormalizer = 'IOptionsNormalizer',
|
||||
IObfuscatingReplacer = 'IObfuscatingReplacer',
|
||||
|
||||
@@ -59,9 +59,9 @@ export abstract class AbstractCustomNode implements ICustomNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any[]} args
|
||||
* @param {unknown[]} args
|
||||
*/
|
||||
public abstract initialize (...args: any[]): void;
|
||||
public abstract initialize (...args: unknown[]): void;
|
||||
|
||||
/**
|
||||
* @returns {TStatement[]}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { inject, injectable } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
|
||||
|
||||
import { TIdentifierNamesGeneratorFactory } from '../types/container/generators/TIdentifierNamesGeneratorFactory';
|
||||
import { TNodeWithBlockScope } from '../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithStatements } from '../types/node/TNodeWithStatements';
|
||||
|
||||
import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
|
||||
import { ICustomNodeGroup } from '../interfaces/custom-nodes/ICustomNodeGroup';
|
||||
@@ -58,10 +58,10 @@ export abstract class AbstractCustomNodeGroup implements ICustomNodeGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {IStackTraceData[]} stackTraceData
|
||||
*/
|
||||
public abstract appendCustomNodes (blockScopeNode: TNodeWithBlockScope, stackTraceData: IStackTraceData[]): void;
|
||||
public abstract appendCustomNodes (nodeWithStatements: TNodeWithStatements, stackTraceData: IStackTraceData[]): void;
|
||||
|
||||
/**
|
||||
* @returns {ObfuscationEvent}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory';
|
||||
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
|
||||
import { TNodeWithBlockScope } from '../../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
|
||||
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
@@ -55,17 +55,17 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {IStackTraceData[]} stackTraceData
|
||||
*/
|
||||
public appendCustomNodes (blockScopeNode: TNodeWithBlockScope, stackTraceData: IStackTraceData[]): void {
|
||||
public appendCustomNodes (nodeWithStatements: TNodeWithStatements, stackTraceData: IStackTraceData[]): void {
|
||||
const randomStackTraceIndex: number = this.getRandomStackTraceIndex(stackTraceData.length);
|
||||
|
||||
// consoleOutputDisableExpressionNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.ConsoleOutputDisableExpressionNode, (customNode: ICustomNode) => {
|
||||
NodeAppender.appendToOptimalBlockScope(
|
||||
stackTraceData,
|
||||
blockScopeNode,
|
||||
nodeWithStatements,
|
||||
customNode.getNode(),
|
||||
randomStackTraceIndex
|
||||
);
|
||||
@@ -73,15 +73,11 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
|
||||
// nodeCallsControllerFunctionNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.NodeCallsControllerFunctionNode, (customNode: ICustomNode) => {
|
||||
let targetBlockScope: TNodeWithBlockScope;
|
||||
const targetNodeWithStatements: TNodeWithStatements = stackTraceData.length
|
||||
? NodeAppender.getOptimalBlockScope(stackTraceData, randomStackTraceIndex, 1)
|
||||
: nodeWithStatements;
|
||||
|
||||
if (stackTraceData.length) {
|
||||
targetBlockScope = NodeAppender.getOptimalBlockScope(stackTraceData, randomStackTraceIndex, 1);
|
||||
} else {
|
||||
targetBlockScope = blockScopeNode;
|
||||
}
|
||||
|
||||
NodeAppender.prepend(targetBlockScope, customNode.getNode());
|
||||
NodeAppender.prepend(targetNodeWithStatements, customNode.getNode());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory';
|
||||
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
|
||||
import { TNodeWithBlockScope } from '../../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
|
||||
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
@@ -17,6 +17,7 @@ import { ObfuscationEvent } from '../../../enums/event-emitters/ObfuscationEvent
|
||||
|
||||
import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup';
|
||||
import { NodeAppender } from '../../../node/NodeAppender';
|
||||
import { NodeGuards } from '../../../node/NodeGuards';
|
||||
|
||||
@injectable()
|
||||
export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
@@ -55,17 +56,17 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {IStackTraceData[]} stackTraceData
|
||||
*/
|
||||
public appendCustomNodes (blockScopeNode: TNodeWithBlockScope, stackTraceData: IStackTraceData[]): void {
|
||||
public appendCustomNodes (nodeWithStatements: TNodeWithStatements, stackTraceData: IStackTraceData[]): void {
|
||||
const randomStackTraceIndex: number = this.getRandomStackTraceIndex(stackTraceData.length);
|
||||
|
||||
// debugProtectionFunctionCallNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.DebugProtectionFunctionCallNode, (customNode: ICustomNode) => {
|
||||
NodeAppender.appendToOptimalBlockScope(
|
||||
stackTraceData,
|
||||
blockScopeNode,
|
||||
nodeWithStatements,
|
||||
customNode.getNode(),
|
||||
randomStackTraceIndex
|
||||
);
|
||||
@@ -73,28 +74,26 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
|
||||
// debugProtectionFunctionNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.DebugProtectionFunctionNode, (customNode: ICustomNode) => {
|
||||
NodeAppender.append(blockScopeNode, customNode.getNode());
|
||||
NodeAppender.append(nodeWithStatements, customNode.getNode());
|
||||
});
|
||||
|
||||
// debugProtectionFunctionIntervalNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.DebugProtectionFunctionIntervalNode, (customNode: ICustomNode) => {
|
||||
const programBodyLength: number = blockScopeNode.body.length;
|
||||
const programBodyLength: number = NodeGuards.isSwitchCaseNode(nodeWithStatements)
|
||||
? nodeWithStatements.consequent.length
|
||||
: nodeWithStatements.body.length;
|
||||
const randomIndex: number = this.randomGenerator.getRandomInteger(0, programBodyLength);
|
||||
|
||||
NodeAppender.insertAtIndex(blockScopeNode, customNode.getNode(), randomIndex);
|
||||
NodeAppender.insertAtIndex(nodeWithStatements, customNode.getNode(), randomIndex);
|
||||
});
|
||||
|
||||
// nodeCallsControllerFunctionNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.NodeCallsControllerFunctionNode, (customNode: ICustomNode) => {
|
||||
let targetBlockScope: TNodeWithBlockScope;
|
||||
const targetNodeWithStatements: TNodeWithStatements = stackTraceData.length
|
||||
? NodeAppender.getOptimalBlockScope(stackTraceData, randomStackTraceIndex, 1)
|
||||
: nodeWithStatements;
|
||||
|
||||
if (stackTraceData.length) {
|
||||
targetBlockScope = NodeAppender.getOptimalBlockScope(stackTraceData, randomStackTraceIndex, 1);
|
||||
} else {
|
||||
targetBlockScope = blockScopeNode;
|
||||
}
|
||||
|
||||
NodeAppender.prepend(targetBlockScope, customNode.getNode());
|
||||
NodeAppender.prepend(targetNodeWithStatements, customNode.getNode());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory';
|
||||
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
|
||||
import { TNodeWithBlockScope } from '../../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
|
||||
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
@@ -55,17 +55,17 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {IStackTraceData[]} stackTraceData
|
||||
*/
|
||||
public appendCustomNodes (blockScopeNode: TNodeWithBlockScope, stackTraceData: IStackTraceData[]): void {
|
||||
public appendCustomNodes (nodeWithStatements: TNodeWithStatements, stackTraceData: IStackTraceData[]): void {
|
||||
const randomStackTraceIndex: number = this.getRandomStackTraceIndex(stackTraceData.length);
|
||||
|
||||
// domainLockNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.DomainLockNode, (customNode: ICustomNode) => {
|
||||
NodeAppender.appendToOptimalBlockScope(
|
||||
stackTraceData,
|
||||
blockScopeNode,
|
||||
nodeWithStatements,
|
||||
customNode.getNode(),
|
||||
randomStackTraceIndex
|
||||
);
|
||||
@@ -73,15 +73,11 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
|
||||
// nodeCallsControllerFunctionNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.NodeCallsControllerFunctionNode, (customNode: ICustomNode) => {
|
||||
let targetBlockScope: TNodeWithBlockScope;
|
||||
const targetNodeWithStatements: TNodeWithStatements = stackTraceData.length
|
||||
? NodeAppender.getOptimalBlockScope(stackTraceData, randomStackTraceIndex, 1)
|
||||
: nodeWithStatements;
|
||||
|
||||
if (stackTraceData.length) {
|
||||
targetBlockScope = NodeAppender.getOptimalBlockScope(stackTraceData, randomStackTraceIndex, 1);
|
||||
} else {
|
||||
targetBlockScope = blockScopeNode;
|
||||
}
|
||||
|
||||
NodeAppender.prepend(targetBlockScope, customNode.getNode());
|
||||
NodeAppender.prepend(targetNodeWithStatements, customNode.getNode());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory';
|
||||
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
|
||||
import { TNodeWithBlockScope } from '../../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
|
||||
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
@@ -55,17 +55,17 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {IStackTraceData[]} stackTraceData
|
||||
*/
|
||||
public appendCustomNodes (blockScopeNode: TNodeWithBlockScope, stackTraceData: IStackTraceData[]): void {
|
||||
public appendCustomNodes (nodeWithStatements: TNodeWithStatements, stackTraceData: IStackTraceData[]): void {
|
||||
const randomStackTraceIndex: number = this.getRandomStackTraceIndex(stackTraceData.length);
|
||||
|
||||
// selfDefendingUnicodeNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.SelfDefendingUnicodeNode, (customNode: ICustomNode) => {
|
||||
NodeAppender.appendToOptimalBlockScope(
|
||||
stackTraceData,
|
||||
blockScopeNode,
|
||||
nodeWithStatements,
|
||||
customNode.getNode(),
|
||||
randomStackTraceIndex
|
||||
);
|
||||
@@ -73,15 +73,11 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
|
||||
// nodeCallsControllerFunctionNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.NodeCallsControllerFunctionNode, (customNode: ICustomNode) => {
|
||||
let targetBlockScope: TNodeWithBlockScope;
|
||||
const targetNodeWithStatements: TNodeWithStatements = stackTraceData.length
|
||||
? NodeAppender.getOptimalBlockScope(stackTraceData, randomStackTraceIndex, 1)
|
||||
: nodeWithStatements;
|
||||
|
||||
if (stackTraceData.length) {
|
||||
targetBlockScope = NodeAppender.getOptimalBlockScope(stackTraceData, randomStackTraceIndex, 1);
|
||||
} else {
|
||||
targetBlockScope = blockScopeNode;
|
||||
}
|
||||
|
||||
NodeAppender.prepend(targetBlockScope, customNode.getNode());
|
||||
NodeAppender.prepend(targetNodeWithStatements, customNode.getNode());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import { TCustomNodeFactory } from '../../../types/container/custom-nodes/TCustomNodeFactory';
|
||||
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
|
||||
import { TNodeWithBlockScope } from '../../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
|
||||
import { TStringArrayStorage } from '../../../types/storages/TStringArrayStorage';
|
||||
|
||||
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
|
||||
@@ -64,27 +64,27 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {IStackTraceData[]} stackTraceData
|
||||
*/
|
||||
public appendCustomNodes (blockScopeNode: TNodeWithBlockScope, stackTraceData: IStackTraceData[]): void {
|
||||
public appendCustomNodes (nodeWithStatements: TNodeWithStatements, stackTraceData: IStackTraceData[]): void {
|
||||
if (!this.stringArrayStorage.getLength()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// stringArrayNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.StringArrayNode, (customNode: ICustomNode) => {
|
||||
NodeAppender.prepend(blockScopeNode, customNode.getNode());
|
||||
NodeAppender.prepend(nodeWithStatements, customNode.getNode());
|
||||
});
|
||||
|
||||
// stringArrayCallsWrapper append
|
||||
this.appendCustomNodeIfExist(CustomNode.StringArrayCallsWrapper, (customNode: ICustomNode) => {
|
||||
NodeAppender.insertAtIndex(blockScopeNode, customNode.getNode(), 1);
|
||||
NodeAppender.insertAtIndex(nodeWithStatements, customNode.getNode(), 1);
|
||||
});
|
||||
|
||||
// stringArrayRotateFunctionNode append
|
||||
this.appendCustomNodeIfExist(CustomNode.StringArrayRotateFunctionNode, (customNode: ICustomNode) => {
|
||||
NodeAppender.insertAtIndex(blockScopeNode, customNode.getNode(), 1);
|
||||
NodeAppender.insertAtIndex(nodeWithStatements, customNode.getNode(), 1);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -1,8 +1,8 @@
|
||||
export interface IInitializable {
|
||||
export interface IInitializable <T extends any[] = never[]> {
|
||||
[key: string]: any;
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
initialize (...args: any[]): void;
|
||||
initialize (...args: T): void;
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
import { IObfuscationResult } from './IObfuscationResult';
|
||||
import { IObfuscatedCode } from './source-code/IObfuscatedCode';
|
||||
|
||||
export interface IJavaScriptObfuscator {
|
||||
/**
|
||||
* @param sourceCode
|
||||
* @returns IObfuscationResult
|
||||
* @returns IObfuscatedCode
|
||||
*/
|
||||
obfuscate (sourceCode: string): IObfuscationResult;
|
||||
obfuscate (sourceCode: string): IObfuscatedCode;
|
||||
}
|
||||
|
||||
+4
-3
@@ -15,10 +15,11 @@ export interface IInversifyContainerFacade {
|
||||
getNamed <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>, named: string | number | symbol): T;
|
||||
|
||||
/**
|
||||
* @param sourceCode
|
||||
* @param options
|
||||
* @param {string} sourceCode
|
||||
* @param {string} sourceMap
|
||||
* @param {TInputOptions} options
|
||||
*/
|
||||
load (sourceCode: string, options: TInputOptions): void;
|
||||
load (sourceCode: string, sourceMap: string, options: TInputOptions): void;
|
||||
|
||||
unload (): void;
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { TStatement } from '../../types/node/TStatement';
|
||||
|
||||
import { IInitializable } from '../IInitializable';
|
||||
|
||||
export interface ICustomNode extends IInitializable {
|
||||
export interface ICustomNode extends IInitializable<any[]> {
|
||||
/**
|
||||
* @returns ESTree.Node[]
|
||||
*/
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithStatements } from '../../types/node/TNodeWithStatements';
|
||||
|
||||
import { ICustomNode } from './ICustomNode';
|
||||
import { IInitializable } from '../IInitializable';
|
||||
@@ -9,10 +9,10 @@ import { ObfuscationEvent } from '../../enums/event-emitters/ObfuscationEvent';
|
||||
|
||||
export interface ICustomNodeGroup extends IInitializable {
|
||||
/**
|
||||
* @param blockScopeNode
|
||||
* @param nodeWithStatements
|
||||
* @param stackTraceData
|
||||
*/
|
||||
appendCustomNodes (blockScopeNode: TNodeWithBlockScope, stackTraceData: IStackTraceData[]): void;
|
||||
appendCustomNodes (nodeWithStatements: TNodeWithStatements, stackTraceData: IStackTraceData[]): void;
|
||||
|
||||
/**
|
||||
* @returns {ObfuscationEvent}
|
||||
|
||||
+5
-5
@@ -1,19 +1,19 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockScope } from '../../../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithLexicalScope } from '../../../../types/node/TNodeWithLexicalScope';
|
||||
|
||||
import { IObfuscatingReplacer } from './IObfuscatingReplacer';
|
||||
|
||||
export interface IIdentifierObfuscatingReplacer extends IObfuscatingReplacer <ESTree.Identifier> {
|
||||
/**
|
||||
* @param {string} nodeValue
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
storeGlobalName (nodeValue: string, blockScopeNode: TNodeWithBlockScope): void;
|
||||
storeGlobalName (nodeValue: string, lexicalScopeNode: TNodeWithLexicalScope): void;
|
||||
|
||||
/**
|
||||
* @param {string} nodeValue
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
storeLocalName (nodeValue: string, blockScopeNode: TNodeWithBlockScope): void;
|
||||
storeLocalName (nodeValue: string, lexicalScopeNode: TNodeWithLexicalScope): void;
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,13 +1,13 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockScope } from '../../../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithLexicalScope } from '../../../../types/node/TNodeWithLexicalScope';
|
||||
|
||||
export interface IObfuscatingReplacer <T = ESTree.Node> {
|
||||
/**
|
||||
* @param {SimpleLiteral["value"]} nodeValue
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
* @param {number} nodeIdentifier
|
||||
* @returns {T}
|
||||
*/
|
||||
replace (nodeValue: ESTree.SimpleLiteral['value'], blockScopeNode?: TNodeWithBlockScope, nodeIdentifier?: number): T;
|
||||
replace (nodeValue: ESTree.SimpleLiteral['value'], lexicalScopeNode?: TNodeWithLexicalScope, nodeIdentifier?: number): T;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { IInitializable } from './IInitializable';
|
||||
import { IInitializable } from '../IInitializable';
|
||||
|
||||
export interface IObfuscationResult extends IInitializable {
|
||||
export interface IObfuscatedCode extends IInitializable <[string, string]> {
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
@@ -3,4 +3,9 @@ export interface ISourceCode {
|
||||
* @returns string
|
||||
*/
|
||||
getSourceCode (): string;
|
||||
|
||||
/**
|
||||
* @returns string
|
||||
*/
|
||||
getSourceMap (): string;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { IObfuscationResult } from '../IObfuscationResult';
|
||||
|
||||
export interface ISourceMapCorrector {
|
||||
/**
|
||||
* @param {string} obfuscatedCode
|
||||
* @param {string} sourceMap
|
||||
* @returns {IObfuscationResult}
|
||||
*/
|
||||
correct (obfuscatedCode: string, sourceMap: string): IObfuscationResult;
|
||||
}
|
||||
-5
@@ -28,11 +28,6 @@ export interface IArrayStorage <V> extends IInitializable {
|
||||
*/
|
||||
getStorageId (): string;
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
initialize (...args: any[]): void;
|
||||
|
||||
/**
|
||||
* @param storage
|
||||
* @param mergeId
|
||||
|
||||
-5
@@ -34,11 +34,6 @@ export interface IMapStorage <K, V> extends IInitializable {
|
||||
*/
|
||||
has (key: K): boolean;
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
initialize (...args: any[]): void;
|
||||
|
||||
/**
|
||||
* @param storage
|
||||
* @param mergeId
|
||||
|
||||
-7
@@ -6,13 +6,6 @@ export interface IRandomGenerator {
|
||||
*/
|
||||
getMathRandom (): number;
|
||||
|
||||
/**
|
||||
* @param min
|
||||
* @param max
|
||||
* @returns {number}
|
||||
*/
|
||||
getRandomFloat (min: number, max: number): number;
|
||||
|
||||
/**
|
||||
* @returns {Chance.Chance}
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,7 @@ import { TControlFlowCustomNodeFactory } from '../../types/container/custom-node
|
||||
import { TControlFlowReplacerFactory } from '../../types/container/node-transformers/TControlFlowReplacerFactory';
|
||||
import { TControlFlowStorage } from '../../types/storages/TControlFlowStorage';
|
||||
import { TControlFlowStorageFactory } from '../../types/container/node-transformers/TControlFlowStorageFactory';
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithStatements } from '../../types/node/TNodeWithStatements';
|
||||
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
@@ -24,7 +24,7 @@ import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeAppender } from '../../node/NodeAppender';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeMetadata } from '../../node/NodeMetadata';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { NodeStatementUtils } from '../../node/NodeStatementUtils';
|
||||
|
||||
@injectable()
|
||||
export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
|
||||
@@ -59,9 +59,9 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
|
||||
private readonly visitedFunctionNodes: Set<ESTree.Function> = new Set();
|
||||
|
||||
/**
|
||||
* @type {Set<TNodeWithBlockScope>}
|
||||
* @type {Set<TNodeWithStatements>}
|
||||
*/
|
||||
private readonly hostNodesWithControlFlowNode: Set<TNodeWithBlockScope> = new Set();
|
||||
private readonly hostNodesWithControlFlowNode: Set<TNodeWithStatements> = new Set();
|
||||
|
||||
/**
|
||||
* @type {TControlFlowReplacerFactory}
|
||||
@@ -140,7 +140,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
|
||||
return functionNode;
|
||||
}
|
||||
|
||||
const hostNode: TNodeWithBlockScope = this.getHostNode(functionNode.body);
|
||||
const hostNode: TNodeWithStatements = this.getHostNode(functionNode.body);
|
||||
const controlFlowStorage: TControlFlowStorage = this.getControlFlowStorage(hostNode);
|
||||
|
||||
this.controlFlowData.set(hostNode, controlFlowStorage);
|
||||
@@ -162,15 +162,19 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} hostNode
|
||||
* @param {TNodeWithStatements} hostNode
|
||||
* @returns {TControlFlowStorage}
|
||||
*/
|
||||
private getControlFlowStorage (hostNode: TNodeWithBlockScope): TControlFlowStorage {
|
||||
private getControlFlowStorage (hostNode: TNodeWithStatements): TControlFlowStorage {
|
||||
const controlFlowStorage: TControlFlowStorage = this.controlFlowStorageFactory();
|
||||
|
||||
if (this.controlFlowData.has(hostNode)) {
|
||||
if (this.hostNodesWithControlFlowNode.has(hostNode)) {
|
||||
hostNode.body.shift();
|
||||
if (NodeGuards.isSwitchCaseNode(hostNode)) {
|
||||
hostNode.consequent.shift();
|
||||
} else {
|
||||
hostNode.body.shift();
|
||||
}
|
||||
}
|
||||
|
||||
const hostControlFlowStorage: TControlFlowStorage = <TControlFlowStorage>this.controlFlowData.get(hostNode);
|
||||
@@ -183,10 +187,10 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {BlockStatement} functionNodeBody
|
||||
* @returns {TNodeWithBlockScope}
|
||||
* @returns {TNodeWithStatements}
|
||||
*/
|
||||
private getHostNode (functionNodeBody: ESTree.BlockStatement): TNodeWithBlockScope {
|
||||
const blockScopesOfNode: TNodeWithBlockScope[] = NodeUtils.getBlockScopesOfNode(functionNodeBody);
|
||||
private getHostNode (functionNodeBody: ESTree.BlockStatement): TNodeWithStatements {
|
||||
const blockScopesOfNode: TNodeWithStatements[] = NodeStatementUtils.getParentNodesWithStatements(functionNodeBody);
|
||||
|
||||
if (blockScopesOfNode.length === 1) {
|
||||
return functionNodeBody;
|
||||
|
||||
+18
-15
@@ -3,7 +3,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithScope } from '../../../types/node/TNodeWithScope';
|
||||
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
|
||||
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
import { IPropertiesExtractor } from '../../../interfaces/node-transformers/converting-transformers/properties-extractors/IPropertiesExtractor';
|
||||
@@ -12,14 +12,14 @@ import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
|
||||
import { NodeAppender } from '../../../node/NodeAppender';
|
||||
import { NodeFactory } from '../../../node/NodeFactory';
|
||||
import { NodeGuards } from '../../../node/NodeGuards';
|
||||
import { NodeUtils } from '../../../node/NodeUtils';
|
||||
import { NodeStatementUtils } from '../../../node/NodeStatementUtils';
|
||||
|
||||
@injectable()
|
||||
export abstract class AbstractPropertiesExtractor implements IPropertiesExtractor {
|
||||
/**
|
||||
* @type {Map<ESTree.ObjectExpression, TNodeWithScope>}
|
||||
* @type {Map<ESTree.ObjectExpression, TNodeWithStatements>}
|
||||
*/
|
||||
protected readonly cachedHostScopesMap: Map <ESTree.ObjectExpression, TNodeWithScope> = new Map();
|
||||
protected readonly cachedHostNodesWithStatementsMap: Map <ESTree.ObjectExpression, TNodeWithStatements> = new Map();
|
||||
|
||||
/**
|
||||
* @type {Map<ESTree.ObjectExpression, ESTree.Statement>}
|
||||
@@ -179,10 +179,13 @@ export abstract class AbstractPropertiesExtractor implements IPropertiesExtracto
|
||||
.extractPropertiesToExpressionStatements(properties, memberExpressionHostNode);
|
||||
|
||||
const hostStatement: ESTree.Statement = this.getHostStatement(objectExpressionNode);
|
||||
const scopeNode: TNodeWithScope = this.getHostScopeNode(objectExpressionNode, hostStatement);
|
||||
const hostNodeWithStatements: TNodeWithStatements = this.getHostNodeWithStatements(
|
||||
objectExpressionNode,
|
||||
hostStatement
|
||||
);
|
||||
|
||||
this.filterExtractedObjectExpressionProperties(objectExpressionNode, removablePropertyIds);
|
||||
NodeAppender.insertAfter(scopeNode, expressionStatements, hostStatement);
|
||||
NodeAppender.insertAfter(hostNodeWithStatements, expressionStatements, hostStatement);
|
||||
|
||||
return objectExpressionNode;
|
||||
}
|
||||
@@ -190,21 +193,21 @@ export abstract class AbstractPropertiesExtractor implements IPropertiesExtracto
|
||||
/**
|
||||
* @param {ObjectExpression} objectExpressionNode
|
||||
* @param {Statement} hostStatement
|
||||
* @returns {TNodeWithScope}
|
||||
* @returns {TNodeWithStatements}
|
||||
*/
|
||||
protected getHostScopeNode (
|
||||
protected getHostNodeWithStatements (
|
||||
objectExpressionNode: ESTree.ObjectExpression,
|
||||
hostStatement: ESTree.Statement
|
||||
): TNodeWithScope {
|
||||
if (this.cachedHostScopesMap.has(objectExpressionNode)) {
|
||||
return <TNodeWithScope>this.cachedHostScopesMap.get(objectExpressionNode);
|
||||
): TNodeWithStatements {
|
||||
if (this.cachedHostNodesWithStatementsMap.has(objectExpressionNode)) {
|
||||
return <TNodeWithStatements>this.cachedHostNodesWithStatementsMap.get(objectExpressionNode);
|
||||
}
|
||||
|
||||
const scopeNode: TNodeWithScope = NodeUtils.getScopeOfNode(hostStatement);
|
||||
const nodeWithStatements: TNodeWithStatements = NodeStatementUtils.getScopeOfNode(hostStatement);
|
||||
|
||||
this.cachedHostScopesMap.set(objectExpressionNode, scopeNode);
|
||||
this.cachedHostNodesWithStatementsMap.set(objectExpressionNode, nodeWithStatements);
|
||||
|
||||
return scopeNode;
|
||||
return nodeWithStatements;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,7 +221,7 @@ export abstract class AbstractPropertiesExtractor implements IPropertiesExtracto
|
||||
return <ESTree.Statement>this.cachedHostStatementsMap.get(objectExpressionNode);
|
||||
}
|
||||
|
||||
const hostStatement: ESTree.Statement = NodeUtils.getRootStatementOfNode(objectExpressionNode);
|
||||
const hostStatement: ESTree.Statement = NodeStatementUtils.getRootStatementOfNode(objectExpressionNode);
|
||||
|
||||
this.cachedHostStatementsMap.set(objectExpressionNode, hostStatement);
|
||||
|
||||
|
||||
+19
-12
@@ -5,8 +5,7 @@ import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TDeadNodeInjectionCustomNodeFactory } from '../../types/container/custom-nodes/TDeadNodeInjectionCustomNodeFactory';
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithScope } from '../../types/node/TNodeWithScope';
|
||||
import { TNodeWithStatements } from '../../types/node/TNodeWithStatements';
|
||||
|
||||
import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
@@ -22,6 +21,7 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeFactory } from '../../node/NodeFactory';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeStatementUtils } from '../../node/NodeStatementUtils';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
@injectable()
|
||||
@@ -117,7 +117,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
return false;
|
||||
}
|
||||
|
||||
const scopeNode: TNodeWithScope = NodeUtils.getScopeOfNode(targetNode);
|
||||
const scopeNode: TNodeWithStatements = NodeStatementUtils.getScopeOfNode(targetNode);
|
||||
const scopeBody: ESTree.Statement[] = !NodeGuards.isSwitchCaseNode(scopeNode)
|
||||
? <ESTree.Statement[]>scopeNode.body
|
||||
: scopeNode.consequent;
|
||||
@@ -204,10 +204,10 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
return false;
|
||||
}
|
||||
|
||||
const blockScopeOfBlockStatementNode: TNodeWithBlockScope = NodeUtils
|
||||
.getBlockScopeOfNode(blockStatementNode);
|
||||
const parentNodeWithStatements: TNodeWithStatements = NodeStatementUtils
|
||||
.getParentNodeWithStatements(blockStatementNode);
|
||||
|
||||
return blockScopeOfBlockStatementNode.type !== NodeType.Program;
|
||||
return parentNodeWithStatements.type !== NodeType.Program;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -261,7 +261,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
return;
|
||||
}
|
||||
|
||||
let clonedBlockStatementNode: ESTree.BlockStatement = NodeUtils.clone(node);
|
||||
const clonedBlockStatementNode: ESTree.BlockStatement = NodeUtils.clone(node);
|
||||
|
||||
if (!DeadCodeInjectionTransformer.isValidCollectedBlockStatementNode(clonedBlockStatementNode)) {
|
||||
return;
|
||||
@@ -270,10 +270,10 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
/**
|
||||
* We should transform identifiers in the dead code block statement to avoid conflicts with original code
|
||||
*/
|
||||
NodeUtils.parentizeNode(clonedBlockStatementNode, clonedBlockStatementNode);
|
||||
clonedBlockStatementNode = this.makeClonedBlockStatementNodeUnique(clonedBlockStatementNode);
|
||||
const transformedBlockStatementNode: ESTree.BlockStatement =
|
||||
this.makeClonedBlockStatementNodeUnique(clonedBlockStatementNode);
|
||||
|
||||
this.collectedBlockStatements.push(clonedBlockStatementNode);
|
||||
this.collectedBlockStatements.push(transformedBlockStatementNode);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -346,11 +346,18 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
* @returns {BlockStatement}
|
||||
*/
|
||||
private makeClonedBlockStatementNodeUnique (clonedBlockStatementNode: ESTree.BlockStatement): ESTree.BlockStatement {
|
||||
// should wrap cloned block statement node into function node for correct scope encapsulation
|
||||
const hostNode: ESTree.FunctionExpression = NodeFactory
|
||||
.functionExpressionNode([], clonedBlockStatementNode);
|
||||
|
||||
NodeUtils.parentizeNode(hostNode, hostNode);
|
||||
NodeUtils.parentizeNode(clonedBlockStatementNode, hostNode);
|
||||
|
||||
return this.transformersRunner.transform(
|
||||
clonedBlockStatementNode,
|
||||
hostNode,
|
||||
DeadCodeInjectionTransformer.transformersToRenameBlockScopeIdentifiers,
|
||||
TransformationStage.Obfuscating
|
||||
);
|
||||
).body;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory';
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
|
||||
|
||||
import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
@@ -17,8 +17,8 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeLexicalScopeUtils } from '../../node/NodeLexicalScopeUtils';
|
||||
import { NodeMetadata } from '../../node/NodeMetadata';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -79,40 +79,44 @@ export class CatchClauseTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (catchClauseNode: ESTree.CatchClause, parentNode: ESTree.Node): ESTree.Node {
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(catchClauseNode);
|
||||
const lexicalScopeNode: TNodeWithLexicalScope | undefined = NodeLexicalScopeUtils.getLexicalScope(catchClauseNode);
|
||||
|
||||
this.storeCatchClauseParam(catchClauseNode, blockScopeNode);
|
||||
this.replaceCatchClauseParam(catchClauseNode, blockScopeNode);
|
||||
if (!lexicalScopeNode) {
|
||||
return catchClauseNode;
|
||||
}
|
||||
|
||||
this.storeCatchClauseParam(catchClauseNode, lexicalScopeNode);
|
||||
this.replaceCatchClauseParam(catchClauseNode, lexicalScopeNode);
|
||||
|
||||
return catchClauseNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CatchClause} catchClauseNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private storeCatchClauseParam (
|
||||
catchClauseNode: ESTree.CatchClause,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
lexicalScopeNode: TNodeWithLexicalScope
|
||||
): void {
|
||||
if (NodeGuards.isIdentifierNode(catchClauseNode.param)) {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(catchClauseNode.param.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(catchClauseNode.param.name, lexicalScopeNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CatchClause} catchClauseNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private replaceCatchClauseParam (
|
||||
catchClauseNode: ESTree.CatchClause,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
lexicalScopeNode: TNodeWithLexicalScope
|
||||
): void {
|
||||
estraverse.replace(catchClauseNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
|
||||
if (parentNode && NodeGuards.isReplaceableIdentifierNode(node, parentNode)) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, blockScopeNode);
|
||||
.replace(node.name, lexicalScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierObfuscatingReplacerFactory } from "../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory";
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
|
||||
import { TReplaceableIdentifiers } from '../../types/node-transformers/TReplaceableIdentifiers';
|
||||
import { TReplaceableIdentifiersNames } from '../../types/node-transformers/TReplaceableIdentifiersNames';
|
||||
|
||||
@@ -20,8 +20,8 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeLexicalScopeUtils } from '../../node/NodeLexicalScopeUtils';
|
||||
import { NodeMetadata } from '../../node/NodeMetadata';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -92,20 +92,25 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (classDeclarationNode: ESTree.ClassDeclaration, parentNode: ESTree.Node): ESTree.Node {
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(classDeclarationNode);
|
||||
const isGlobalDeclaration: boolean = blockScopeNode.type === NodeType.Program;
|
||||
const lexicalScopeNode: TNodeWithLexicalScope | undefined = NodeLexicalScopeUtils.getLexicalScope(classDeclarationNode);
|
||||
|
||||
if (!lexicalScopeNode) {
|
||||
return classDeclarationNode;
|
||||
}
|
||||
|
||||
const isGlobalDeclaration: boolean = lexicalScopeNode.type === NodeType.Program;
|
||||
|
||||
if (!this.options.renameGlobals && isGlobalDeclaration) {
|
||||
return classDeclarationNode;
|
||||
}
|
||||
|
||||
this.storeClassName(classDeclarationNode, blockScopeNode, isGlobalDeclaration);
|
||||
this.storeClassName(classDeclarationNode, lexicalScopeNode, isGlobalDeclaration);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(blockScopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(classDeclarationNode, blockScopeNode);
|
||||
if (this.replaceableIdentifiers.has(lexicalScopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(classDeclarationNode, lexicalScopeNode);
|
||||
} else {
|
||||
this.replaceScopeIdentifiers(blockScopeNode);
|
||||
this.replaceScopeIdentifiers(lexicalScopeNode);
|
||||
}
|
||||
|
||||
return classDeclarationNode;
|
||||
@@ -113,31 +118,31 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {ClassDeclaration} classDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
* @param {boolean} isGlobalDeclaration
|
||||
*/
|
||||
private storeClassName (
|
||||
classDeclarationNode: ESTree.ClassDeclaration,
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
lexicalScopeNode: TNodeWithLexicalScope,
|
||||
isGlobalDeclaration: boolean
|
||||
): void {
|
||||
if (isGlobalDeclaration) {
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(classDeclarationNode.id.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(classDeclarationNode.id.name, lexicalScopeNode);
|
||||
} else {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(classDeclarationNode.id.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(classDeclarationNode.id.name, lexicalScopeNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ClassDeclaration} classDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private replaceScopeCachedIdentifiers (
|
||||
classDeclarationNode: ESTree.ClassDeclaration,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
lexicalScopeNode: TNodeWithLexicalScope
|
||||
): void {
|
||||
const cachedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames =
|
||||
<TReplaceableIdentifiersNames>this.replaceableIdentifiers.get(blockScopeNode);
|
||||
<TReplaceableIdentifiersNames>this.replaceableIdentifiers.get(lexicalScopeNode);
|
||||
|
||||
const cachedReplaceableIdentifiers: ESTree.Identifier[] | undefined = cachedReplaceableIdentifiersNamesMap
|
||||
.get(classDeclarationNode.id.name);
|
||||
@@ -151,7 +156,7 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
for (let i: number = 0; i < cachedReplaceableIdentifierLength; i++) {
|
||||
const replaceableIdentifier: ESTree.Identifier = cachedReplaceableIdentifiers[i];
|
||||
const newReplaceableIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(replaceableIdentifier.name, blockScopeNode);
|
||||
.replace(replaceableIdentifier.name, lexicalScopeNode);
|
||||
|
||||
replaceableIdentifier.name = newReplaceableIdentifier.name;
|
||||
NodeMetadata.set(replaceableIdentifier, { renamedIdentifier: true });
|
||||
@@ -159,12 +164,12 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private replaceScopeIdentifiers (blockScopeNode: TNodeWithBlockScope): void {
|
||||
private replaceScopeIdentifiers (lexicalScopeNode: TNodeWithLexicalScope): void {
|
||||
const storedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames = new Map();
|
||||
|
||||
estraverse.replace(blockScopeNode, {
|
||||
estraverse.replace(lexicalScopeNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
|
||||
if (
|
||||
parentNode
|
||||
@@ -172,7 +177,7 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
&& !NodeMetadata.isRenamedIdentifier(node)
|
||||
) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, blockScopeNode);
|
||||
.replace(node.name, lexicalScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
@@ -189,6 +194,6 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
});
|
||||
|
||||
this.replaceableIdentifiers.set(blockScopeNode, storedReplaceableIdentifiersNamesMap);
|
||||
this.replaceableIdentifiers.set(lexicalScopeNode, storedReplaceableIdentifiersNamesMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierObfuscatingReplacerFactory } from "../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory";
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
|
||||
import { TReplaceableIdentifiers } from '../../types/node-transformers/TReplaceableIdentifiers';
|
||||
import { TReplaceableIdentifiersNames } from '../../types/node-transformers/TReplaceableIdentifiersNames';
|
||||
|
||||
@@ -20,8 +20,8 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeLexicalScopeUtils } from '../../node/NodeLexicalScopeUtils';
|
||||
import { NodeMetadata } from '../../node/NodeMetadata';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -92,20 +92,25 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): ESTree.Node {
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(functionDeclarationNode);
|
||||
const isGlobalDeclaration: boolean = blockScopeNode.type === NodeType.Program;
|
||||
const lexicalScopeNode: TNodeWithLexicalScope | undefined = NodeLexicalScopeUtils.getLexicalScope(parentNode);
|
||||
|
||||
if (!lexicalScopeNode) {
|
||||
return functionDeclarationNode;
|
||||
}
|
||||
|
||||
const isGlobalDeclaration: boolean = lexicalScopeNode.type === NodeType.Program;
|
||||
|
||||
if (!this.options.renameGlobals && isGlobalDeclaration) {
|
||||
return functionDeclarationNode;
|
||||
}
|
||||
|
||||
this.storeFunctionName(functionDeclarationNode, blockScopeNode, isGlobalDeclaration);
|
||||
this.storeFunctionName(functionDeclarationNode, lexicalScopeNode, isGlobalDeclaration);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(blockScopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(functionDeclarationNode, blockScopeNode);
|
||||
if (this.replaceableIdentifiers.has(lexicalScopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(functionDeclarationNode, lexicalScopeNode);
|
||||
} else {
|
||||
this.replaceScopeIdentifiers(blockScopeNode);
|
||||
this.replaceScopeIdentifiers(lexicalScopeNode);
|
||||
}
|
||||
|
||||
return functionDeclarationNode;
|
||||
@@ -113,31 +118,31 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {FunctionDeclaration} functionDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
* @param {boolean} isGlobalDeclaration
|
||||
*/
|
||||
private storeFunctionName (
|
||||
functionDeclarationNode: ESTree.FunctionDeclaration,
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
lexicalScopeNode: TNodeWithLexicalScope,
|
||||
isGlobalDeclaration: boolean
|
||||
): void {
|
||||
if (isGlobalDeclaration) {
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(functionDeclarationNode.id.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(functionDeclarationNode.id.name, lexicalScopeNode);
|
||||
} else {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(functionDeclarationNode.id.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(functionDeclarationNode.id.name, lexicalScopeNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FunctionDeclaration} functionDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private replaceScopeCachedIdentifiers (
|
||||
functionDeclarationNode: ESTree.FunctionDeclaration,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
lexicalScopeNode: TNodeWithLexicalScope
|
||||
): void {
|
||||
const cachedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames =
|
||||
<TReplaceableIdentifiersNames>this.replaceableIdentifiers.get(blockScopeNode);
|
||||
<TReplaceableIdentifiersNames>this.replaceableIdentifiers.get(lexicalScopeNode);
|
||||
|
||||
const cachedReplaceableIdentifiers: ESTree.Identifier[] | undefined = cachedReplaceableIdentifiersNamesMap
|
||||
.get(functionDeclarationNode.id.name);
|
||||
@@ -151,7 +156,7 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
for (let i: number = 0; i < cachedReplaceableIdentifierLength; i++) {
|
||||
const replaceableIdentifier: ESTree.Identifier = cachedReplaceableIdentifiers[i];
|
||||
const newReplaceableIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(replaceableIdentifier.name, blockScopeNode);
|
||||
.replace(replaceableIdentifier.name, lexicalScopeNode);
|
||||
|
||||
replaceableIdentifier.name = newReplaceableIdentifier.name;
|
||||
NodeMetadata.set(replaceableIdentifier, { renamedIdentifier: true });
|
||||
@@ -159,12 +164,12 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private replaceScopeIdentifiers (blockScopeNode: TNodeWithBlockScope): void {
|
||||
private replaceScopeIdentifiers (lexicalScopeNode: TNodeWithLexicalScope): void {
|
||||
const storedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames = new Map();
|
||||
|
||||
estraverse.replace(blockScopeNode, {
|
||||
estraverse.replace(lexicalScopeNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
|
||||
if (
|
||||
parentNode
|
||||
@@ -172,7 +177,7 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
&& !NodeMetadata.isRenamedIdentifier(node)
|
||||
) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, blockScopeNode);
|
||||
.replace(node.name, lexicalScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
@@ -189,6 +194,6 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
});
|
||||
|
||||
this.replaceableIdentifiers.set(blockScopeNode, storedReplaceableIdentifiersNamesMap);
|
||||
this.replaceableIdentifiers.set(lexicalScopeNode, storedReplaceableIdentifiersNamesMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory';
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
|
||||
|
||||
import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
@@ -17,8 +17,8 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeLexicalScopeUtils } from '../../node/NodeLexicalScopeUtils';
|
||||
import { NodeMetadata } from '../../node/NodeMetadata';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -53,6 +53,16 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private static isProhibitedPropertyNode (node: ESTree.Node): node is ESTree.Property & {key: ESTree.Identifier} {
|
||||
return NodeGuards.isPropertyNode(node)
|
||||
&& node.shorthand
|
||||
&& NodeGuards.isIdentifierNode(node.key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TransformationStage} transformationStage
|
||||
* @returns {IVisitor | null}
|
||||
@@ -62,13 +72,7 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
case TransformationStage.Obfuscating:
|
||||
return {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null) => {
|
||||
if (
|
||||
parentNode && (
|
||||
NodeGuards.isFunctionDeclarationNode(node) ||
|
||||
NodeGuards.isFunctionExpressionNode(node) ||
|
||||
NodeGuards.isArrowFunctionExpressionNode(node)
|
||||
)
|
||||
) {
|
||||
if (parentNode && NodeGuards.isFunctionNode(node)) {
|
||||
return this.transformNode(node, parentNode);
|
||||
}
|
||||
}
|
||||
@@ -85,37 +89,39 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (functionNode: ESTree.Function, parentNode: ESTree.Node): ESTree.Node {
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeGuards.isBlockStatementNode(functionNode.body)
|
||||
? functionNode.body
|
||||
: NodeUtils.getBlockScopeOfNode(functionNode.body);
|
||||
const lexicalScopeNode: TNodeWithLexicalScope | undefined = NodeLexicalScopeUtils.getLexicalScope(functionNode);
|
||||
|
||||
this.storeFunctionParams(functionNode, blockScopeNode);
|
||||
this.replaceFunctionParams(functionNode, blockScopeNode);
|
||||
if (!lexicalScopeNode) {
|
||||
return functionNode;
|
||||
}
|
||||
|
||||
this.storeFunctionParams(functionNode, lexicalScopeNode);
|
||||
this.replaceFunctionParams(functionNode, lexicalScopeNode);
|
||||
|
||||
return functionNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} functionNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private storeFunctionParams (functionNode: ESTree.Function, blockScopeNode: TNodeWithBlockScope): void {
|
||||
private storeFunctionParams (functionNode: ESTree.Function, lexicalScopeNode: TNodeWithLexicalScope): void {
|
||||
functionNode.params
|
||||
.forEach((paramsNode: ESTree.Node) => {
|
||||
estraverse.traverse(paramsNode, {
|
||||
enter: (node: ESTree.Node): estraverse.VisitorOption | void => {
|
||||
if (NodeGuards.isPropertyNode(paramsNode)) {
|
||||
if (FunctionTransformer.isProhibitedPropertyNode(node)) {
|
||||
return estraverse.VisitorOption.Skip;
|
||||
}
|
||||
|
||||
if (NodeGuards.isAssignmentPatternNode(node) && NodeGuards.isIdentifierNode(node.left)) {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(node.left.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(node.left.name, lexicalScopeNode);
|
||||
|
||||
return estraverse.VisitorOption.Skip;
|
||||
}
|
||||
|
||||
if (NodeGuards.isIdentifierNode(node)) {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(node.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(node.name, lexicalScopeNode);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -123,42 +129,40 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Property[]} properties
|
||||
* @param {Function} functionNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
* @param {Set<string>} ignoredIdentifierNamesSet
|
||||
*/
|
||||
private addIdentifiersToIgnoredIdentifierNamesSet (
|
||||
properties: ESTree.Property[],
|
||||
ignoredIdentifierNamesSet: Set<string>
|
||||
private replaceFunctionParams (
|
||||
functionNode: ESTree.Function,
|
||||
lexicalScopeNode: TNodeWithLexicalScope,
|
||||
ignoredIdentifierNamesSet: Set <string> = new Set()
|
||||
): void {
|
||||
properties.forEach((property: ESTree.Property) => {
|
||||
if (!property.key || !NodeGuards.isIdentifierNode(property.key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ignoredIdentifierNamesSet.add(property.key.name);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} functionNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
private replaceFunctionParams (functionNode: ESTree.Function, blockScopeNode: TNodeWithBlockScope): void {
|
||||
const ignoredIdentifierNamesSet: Set<string> = new Set();
|
||||
|
||||
const replaceVisitor: estraverse.Visitor = {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
|
||||
if (NodeGuards.isObjectPatternNode(node)) {
|
||||
this.addIdentifiersToIgnoredIdentifierNamesSet(node.properties, ignoredIdentifierNamesSet);
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void | estraverse.VisitorOption => {
|
||||
/**
|
||||
* Should to process nested functions in different traverse loop to avoid wrong code generation
|
||||
*/
|
||||
if (NodeGuards.isFunctionNode(node)) {
|
||||
this.replaceFunctionParams(node, lexicalScopeNode, new Set(ignoredIdentifierNamesSet));
|
||||
|
||||
return estraverse.VisitorOption.Skip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should to ignore all identifiers that related to shorthand properties
|
||||
*/
|
||||
if (FunctionTransformer.isProhibitedPropertyNode(node)) {
|
||||
ignoredIdentifierNamesSet.add(node.key.name);
|
||||
}
|
||||
|
||||
if (
|
||||
parentNode &&
|
||||
NodeGuards.isReplaceableIdentifierNode(node, parentNode) &&
|
||||
!ignoredIdentifierNamesSet.has(node.name)
|
||||
parentNode
|
||||
&& NodeGuards.isReplaceableIdentifierNode(node, parentNode)
|
||||
&& !ignoredIdentifierNamesSet.has(node.name)
|
||||
) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, blockScopeNode);
|
||||
.replace(node.name, lexicalScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierObfuscatingReplacerFactory } from "../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory";
|
||||
import { TImportSpecifier } from '../../types/node/TimportSpecifier';
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
|
||||
|
||||
import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
@@ -18,8 +18,8 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeLexicalScopeUtils } from '../../node/NodeLexicalScopeUtils';
|
||||
import { NodeMetadata } from '../../node/NodeMetadata';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -95,15 +95,19 @@ export class ImportDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @returns {Node}
|
||||
*/
|
||||
public transformNode (importDeclarationNode: ESTree.ImportDeclaration, parentNode: ESTree.Node): ESTree.Node {
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(importDeclarationNode);
|
||||
const lexicalScopeNode: TNodeWithLexicalScope | undefined = NodeLexicalScopeUtils.getLexicalScope(importDeclarationNode);
|
||||
|
||||
this.storeImportSpecifierNames(importDeclarationNode, blockScopeNode);
|
||||
if (!lexicalScopeNode) {
|
||||
return importDeclarationNode;
|
||||
}
|
||||
|
||||
this.storeImportSpecifierNames(importDeclarationNode, lexicalScopeNode);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(blockScopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(blockScopeNode);
|
||||
if (this.replaceableIdentifiers.has(lexicalScopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(lexicalScopeNode);
|
||||
} else {
|
||||
this.replaceScopeIdentifiers(blockScopeNode);
|
||||
this.replaceScopeIdentifiers(lexicalScopeNode);
|
||||
}
|
||||
|
||||
return importDeclarationNode;
|
||||
@@ -111,31 +115,31 @@ export class ImportDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {ImportDeclaration} importDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private storeImportSpecifierNames (
|
||||
importDeclarationNode: ESTree.ImportDeclaration,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
lexicalScopeNode: TNodeWithLexicalScope
|
||||
): void {
|
||||
importDeclarationNode.specifiers.forEach((importSpecifierNode: TImportSpecifier) => {
|
||||
if (ImportDeclarationTransformer.isProhibitedImportSpecifierNode(importSpecifierNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(importSpecifierNode.local.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(importSpecifierNode.local.name, lexicalScopeNode);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private replaceScopeCachedIdentifiers (blockScopeNode: TNodeWithBlockScope): void {
|
||||
private replaceScopeCachedIdentifiers (lexicalScopeNode: TNodeWithLexicalScope): void {
|
||||
const cachedReplaceableIdentifiers: ESTree.Identifier[] =
|
||||
<ESTree.Identifier[]>this.replaceableIdentifiers.get(blockScopeNode);
|
||||
<ESTree.Identifier[]>this.replaceableIdentifiers.get(lexicalScopeNode);
|
||||
|
||||
cachedReplaceableIdentifiers.forEach((replaceableIdentifier: ESTree.Identifier) => {
|
||||
const newReplaceableIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(replaceableIdentifier.name, blockScopeNode);
|
||||
.replace(replaceableIdentifier.name, lexicalScopeNode);
|
||||
|
||||
replaceableIdentifier.name = newReplaceableIdentifier.name;
|
||||
NodeMetadata.set(replaceableIdentifier, { renamedIdentifier: true });
|
||||
@@ -143,12 +147,12 @@ export class ImportDeclarationTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private replaceScopeIdentifiers (blockScopeNode: TNodeWithBlockScope): void {
|
||||
private replaceScopeIdentifiers (lexicalScopeNode: TNodeWithLexicalScope): void {
|
||||
const storedReplaceableIdentifiers: ESTree.Identifier[] = [];
|
||||
|
||||
estraverse.replace(blockScopeNode, {
|
||||
estraverse.replace(lexicalScopeNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
|
||||
if (
|
||||
parentNode
|
||||
@@ -156,7 +160,7 @@ export class ImportDeclarationTransformer extends AbstractNodeTransformer {
|
||||
&& !NodeMetadata.isRenamedIdentifier(node)
|
||||
) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, blockScopeNode);
|
||||
.replace(node.name, lexicalScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
@@ -169,6 +173,6 @@ export class ImportDeclarationTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
});
|
||||
|
||||
this.replaceableIdentifiers.set(blockScopeNode, storedReplaceableIdentifiers);
|
||||
this.replaceableIdentifiers.set(lexicalScopeNode, storedReplaceableIdentifiers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory';
|
||||
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
|
||||
|
||||
import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
@@ -16,8 +17,7 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { NodeLexicalScopeUtils } from '../../node/NodeLexicalScopeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -86,38 +86,42 @@ export class LabeledStatementTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (labeledStatementNode: ESTree.LabeledStatement, parentNode: ESTree.Node): ESTree.Node {
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(labeledStatementNode);
|
||||
const lexicalScopeNode: TNodeWithLexicalScope | undefined = NodeLexicalScopeUtils.getLexicalScope(labeledStatementNode);
|
||||
|
||||
this.storeLabeledStatementName(labeledStatementNode, blockScopeNode);
|
||||
this.replaceLabeledStatementName(labeledStatementNode, blockScopeNode);
|
||||
if (!lexicalScopeNode) {
|
||||
return labeledStatementNode;
|
||||
}
|
||||
|
||||
this.storeLabeledStatementName(labeledStatementNode, lexicalScopeNode);
|
||||
this.replaceLabeledStatementName(labeledStatementNode, lexicalScopeNode);
|
||||
|
||||
return labeledStatementNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {LabeledStatement} labeledStatementNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private storeLabeledStatementName (
|
||||
labeledStatementNode: ESTree.LabeledStatement,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
lexicalScopeNode: TNodeWithLexicalScope
|
||||
): void {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(labeledStatementNode.label.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(labeledStatementNode.label.name, lexicalScopeNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {LabeledStatement} labeledStatementNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private replaceLabeledStatementName (
|
||||
labeledStatementNode: ESTree.LabeledStatement,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
lexicalScopeNode: TNodeWithLexicalScope
|
||||
): void {
|
||||
estraverse.replace(labeledStatementNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
|
||||
if (parentNode && NodeGuards.isLabelIdentifierNode(node, parentNode)) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, blockScopeNode);
|
||||
.replace(node.name, lexicalScopeNode);
|
||||
|
||||
node.name = newIdentifier.name;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory';
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
|
||||
import { TReplaceableIdentifiers } from '../../types/node-transformers/TReplaceableIdentifiers';
|
||||
import { TReplaceableIdentifiersNames } from '../../types/node-transformers/TReplaceableIdentifiersNames';
|
||||
|
||||
@@ -20,8 +20,8 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeLexicalScopeUtils } from '../../node/NodeLexicalScopeUtils';
|
||||
import { NodeMetadata } from '../../node/NodeMetadata';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -93,24 +93,29 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): ESTree.Node {
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(variableDeclarationNode);
|
||||
const isGlobalDeclaration: boolean = blockScopeNode.type === NodeType.Program;
|
||||
const lexicalScopeNode: TNodeWithLexicalScope | undefined = NodeLexicalScopeUtils.getLexicalScope(variableDeclarationNode);
|
||||
|
||||
if (!lexicalScopeNode) {
|
||||
return variableDeclarationNode;
|
||||
}
|
||||
|
||||
const isGlobalDeclaration: boolean = lexicalScopeNode.type === NodeType.Program;
|
||||
|
||||
if (!this.options.renameGlobals && isGlobalDeclaration) {
|
||||
return variableDeclarationNode;
|
||||
}
|
||||
|
||||
const scopeNode: ESTree.Node = variableDeclarationNode.kind === 'var'
|
||||
? blockScopeNode
|
||||
? lexicalScopeNode
|
||||
: parentNode;
|
||||
|
||||
this.storeVariableNames(variableDeclarationNode, blockScopeNode, isGlobalDeclaration);
|
||||
this.storeVariableNames(variableDeclarationNode, lexicalScopeNode, isGlobalDeclaration);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(scopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(variableDeclarationNode, blockScopeNode, scopeNode);
|
||||
this.replaceScopeCachedIdentifiers(variableDeclarationNode, lexicalScopeNode, scopeNode);
|
||||
} else {
|
||||
this.replaceScopeIdentifiers(scopeNode, blockScopeNode);
|
||||
this.replaceScopeIdentifiers(scopeNode, lexicalScopeNode);
|
||||
}
|
||||
|
||||
return variableDeclarationNode;
|
||||
@@ -118,31 +123,31 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {VariableDeclaration} variableDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
* @param {boolean} isGlobalDeclaration
|
||||
*/
|
||||
private storeVariableNames (
|
||||
variableDeclarationNode: ESTree.VariableDeclaration,
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
lexicalScopeNode: TNodeWithLexicalScope,
|
||||
isGlobalDeclaration: boolean
|
||||
): void {
|
||||
this.traverseDeclarationIdentifiers(variableDeclarationNode, (identifierNode: ESTree.Identifier) => {
|
||||
if (isGlobalDeclaration) {
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(identifierNode.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(identifierNode.name, lexicalScopeNode);
|
||||
} else {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(identifierNode.name, blockScopeNode);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(identifierNode.name, lexicalScopeNode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VariableDeclaration} variableDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
* @param {Node} scopeNode
|
||||
*/
|
||||
private replaceScopeCachedIdentifiers (
|
||||
variableDeclarationNode: ESTree.VariableDeclaration,
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
lexicalScopeNode: TNodeWithLexicalScope,
|
||||
scopeNode: ESTree.Node
|
||||
): void {
|
||||
const cachedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames =
|
||||
@@ -172,7 +177,7 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
const newReplaceableIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(replaceableIdentifier.name, blockScopeNode);
|
||||
.replace(replaceableIdentifier.name, lexicalScopeNode);
|
||||
|
||||
replaceableIdentifier.name = newReplaceableIdentifier.name;
|
||||
NodeMetadata.set(replaceableIdentifier, { renamedIdentifier: true });
|
||||
@@ -182,9 +187,9 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {Node} scopeNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
private replaceScopeIdentifiers (scopeNode: ESTree.Node, blockScopeNode: TNodeWithBlockScope): void {
|
||||
private replaceScopeIdentifiers (scopeNode: ESTree.Node, lexicalScopeNode: TNodeWithLexicalScope): void {
|
||||
const storedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames = new Map();
|
||||
|
||||
estraverse.replace(scopeNode, {
|
||||
@@ -195,7 +200,7 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
&& !NodeMetadata.isRenamedIdentifier(node)
|
||||
) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, blockScopeNode);
|
||||
.replace(node.name, lexicalScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockScope } from '../../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithLexicalScope } from '../../../types/node/TNodeWithLexicalScope';
|
||||
|
||||
import { IObfuscatingReplacer } from '../../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IObfuscatingReplacer';
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
@@ -26,8 +26,8 @@ export abstract class AbstractObfuscatingReplacer implements IObfuscatingReplace
|
||||
|
||||
/**
|
||||
* @param {SimpleLiteral["value"]} nodeValue
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
* @returns {Node}
|
||||
*/
|
||||
public abstract replace (nodeValue: ESTree.SimpleLiteral['value'], blockScopeNode?: TNodeWithBlockScope): ESTree.Node;
|
||||
public abstract replace (nodeValue: ESTree.SimpleLiteral['value'], lexicalScopeNode?: TNodeWithLexicalScope): ESTree.Node;
|
||||
}
|
||||
|
||||
+17
-17
@@ -4,7 +4,7 @@ import { ServiceIdentifiers } from '../../../../container/ServiceIdentifiers';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierNamesGeneratorFactory } from '../../../../types/container/generators/TIdentifierNamesGeneratorFactory';
|
||||
import { TNodeWithBlockScope } from '../../../../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithLexicalScope } from '../../../../types/node/TNodeWithLexicalScope';
|
||||
|
||||
import { IIdentifierNamesGenerator } from '../../../../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
|
||||
import { IIdentifierObfuscatingReplacer } from '../../../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
|
||||
@@ -21,9 +21,9 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac
|
||||
private readonly identifierNamesGenerator: IIdentifierNamesGenerator;
|
||||
|
||||
/**
|
||||
* @type {Map<TNodeWithBlockScope, Map<string, string>>}
|
||||
* @type {Map<TNodeWithLexicalScope, Map<string, string>>}
|
||||
*/
|
||||
private readonly blockScopesMap: Map<TNodeWithBlockScope, Map<string, string>> = new Map();
|
||||
private readonly blockScopesMap: Map<TNodeWithLexicalScope, Map<string, string>> = new Map();
|
||||
|
||||
/**
|
||||
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
|
||||
@@ -41,12 +41,12 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac
|
||||
|
||||
/**
|
||||
* @param {string} nodeValue
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
* @returns {Identifier}
|
||||
*/
|
||||
public replace (nodeValue: string, blockScopeNode: TNodeWithBlockScope): ESTree.Identifier {
|
||||
if (this.blockScopesMap.has(blockScopeNode)) {
|
||||
const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(blockScopeNode);
|
||||
public replace (nodeValue: string, lexicalScopeNode: TNodeWithLexicalScope): ESTree.Identifier {
|
||||
if (this.blockScopesMap.has(lexicalScopeNode)) {
|
||||
const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(lexicalScopeNode);
|
||||
|
||||
if (namesMap.has(nodeValue)) {
|
||||
nodeValue = <string>namesMap.get(nodeValue);
|
||||
@@ -61,20 +61,20 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac
|
||||
* Reserved name will be ignored.
|
||||
*
|
||||
* @param {string} nodeName
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
public storeGlobalName (nodeName: string, blockScopeNode: TNodeWithBlockScope): void {
|
||||
public storeGlobalName (nodeName: string, lexicalScopeNode: TNodeWithLexicalScope): void {
|
||||
if (this.isReservedName(nodeName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const identifierName: string = this.identifierNamesGenerator.generateWithPrefix();
|
||||
|
||||
if (!this.blockScopesMap.has(blockScopeNode)) {
|
||||
this.blockScopesMap.set(blockScopeNode, new Map());
|
||||
if (!this.blockScopesMap.has(lexicalScopeNode)) {
|
||||
this.blockScopesMap.set(lexicalScopeNode, new Map());
|
||||
}
|
||||
|
||||
const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(blockScopeNode);
|
||||
const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(lexicalScopeNode);
|
||||
|
||||
namesMap.set(nodeName, identifierName);
|
||||
}
|
||||
@@ -84,20 +84,20 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac
|
||||
* Reserved name will be ignored.
|
||||
*
|
||||
* @param {string} nodeName
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithLexicalScope} lexicalScopeNode
|
||||
*/
|
||||
public storeLocalName (nodeName: string, blockScopeNode: TNodeWithBlockScope): void {
|
||||
public storeLocalName (nodeName: string, lexicalScopeNode: TNodeWithLexicalScope): void {
|
||||
if (this.isReservedName(nodeName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const identifierName: string = this.identifierNamesGenerator.generate();
|
||||
|
||||
if (!this.blockScopesMap.has(blockScopeNode)) {
|
||||
this.blockScopesMap.set(blockScopeNode, new Map());
|
||||
if (!this.blockScopesMap.has(lexicalScopeNode)) {
|
||||
this.blockScopesMap.set(lexicalScopeNode, new Map());
|
||||
}
|
||||
|
||||
const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(blockScopeNode);
|
||||
const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(lexicalScopeNode);
|
||||
|
||||
namesMap.set(nodeName, identifierName);
|
||||
}
|
||||
|
||||
+42
-39
@@ -1,22 +1,22 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockScope } from '../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithStatements } from '../types/node/TNodeWithStatements';
|
||||
import { TStatement } from '../types/node/TStatement';
|
||||
|
||||
import { IStackTraceData } from '../interfaces/analyzers/stack-trace-analyzer/IStackTraceData';
|
||||
import { TNodeWithScope } from '../types/node/TNodeWithScope';
|
||||
|
||||
import { NodeGuards } from './NodeGuards';
|
||||
|
||||
export class NodeAppender {
|
||||
/**
|
||||
* @param {TNodeWithScope} scope
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {TStatement[]} statements
|
||||
*/
|
||||
public static append (scope: TNodeWithScope, statements: TStatement[]): void {
|
||||
statements = NodeAppender.parentizeScopeStatementsBeforeAppend(scope, statements);
|
||||
public static append (nodeWithStatements: TNodeWithStatements, statements: TStatement[]): void {
|
||||
statements = NodeAppender.parentizeScopeStatementsBeforeAppend(nodeWithStatements, statements);
|
||||
|
||||
NodeAppender.setScopeStatements(scope, [
|
||||
...NodeAppender.getScopeStatements(scope),
|
||||
NodeAppender.setScopeStatements(nodeWithStatements, [
|
||||
...NodeAppender.getScopeStatements(nodeWithStatements),
|
||||
...statements
|
||||
]);
|
||||
}
|
||||
@@ -39,19 +39,19 @@ export class NodeAppender {
|
||||
* Appends node into block statement of `baz` function expression
|
||||
*
|
||||
* @param {IStackTraceData[]} stackTraceData
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {TStatement[]} bodyStatements
|
||||
* @param {number} index
|
||||
*/
|
||||
public static appendToOptimalBlockScope (
|
||||
stackTraceData: IStackTraceData[],
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
nodeWithStatements: TNodeWithStatements,
|
||||
bodyStatements: TStatement[],
|
||||
index: number = 0
|
||||
): void {
|
||||
const targetBlockScope: TNodeWithBlockScope = stackTraceData.length
|
||||
const targetBlockScope: TNodeWithStatements = stackTraceData.length
|
||||
? NodeAppender.getOptimalBlockScope(stackTraceData, index)
|
||||
: blockScopeNode;
|
||||
: nodeWithStatements;
|
||||
|
||||
NodeAppender.prepend(targetBlockScope, bodyStatements);
|
||||
}
|
||||
@@ -83,90 +83,93 @@ export class NodeAppender {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithScope} scope
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {TStatement[]} statements
|
||||
* @param {Node} target
|
||||
*/
|
||||
public static insertAfter (
|
||||
scope: TNodeWithScope,
|
||||
nodeWithStatements: TNodeWithStatements,
|
||||
statements: TStatement[],
|
||||
target: ESTree.Statement
|
||||
): void {
|
||||
const indexInScopeStatement: number = NodeAppender
|
||||
.getScopeStatements(scope)
|
||||
.getScopeStatements(nodeWithStatements)
|
||||
.indexOf(target);
|
||||
|
||||
NodeAppender.insertAtIndex(scope, statements, indexInScopeStatement + 1);
|
||||
NodeAppender.insertAtIndex(nodeWithStatements, statements, indexInScopeStatement + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithScope} scope
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {TStatement[]} statements
|
||||
* @param {number} index
|
||||
*/
|
||||
public static insertAtIndex (
|
||||
scope: TNodeWithScope,
|
||||
nodeWithStatements: TNodeWithStatements,
|
||||
statements: TStatement[],
|
||||
index: number
|
||||
): void {
|
||||
statements = NodeAppender.parentizeScopeStatementsBeforeAppend(scope, statements);
|
||||
statements = NodeAppender.parentizeScopeStatementsBeforeAppend(nodeWithStatements, statements);
|
||||
|
||||
NodeAppender.setScopeStatements(scope, [
|
||||
...NodeAppender.getScopeStatements(scope).slice(0, index),
|
||||
NodeAppender.setScopeStatements(nodeWithStatements, [
|
||||
...NodeAppender.getScopeStatements(nodeWithStatements).slice(0, index),
|
||||
...statements,
|
||||
...NodeAppender.getScopeStatements(scope).slice(index)
|
||||
...NodeAppender.getScopeStatements(nodeWithStatements).slice(index)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithScope} scope
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {TStatement[]} statements
|
||||
*/
|
||||
public static prepend (scope: TNodeWithScope, statements: TStatement[]): void {
|
||||
statements = NodeAppender.parentizeScopeStatementsBeforeAppend(scope, statements);
|
||||
public static prepend (nodeWithStatements: TNodeWithStatements, statements: TStatement[]): void {
|
||||
statements = NodeAppender.parentizeScopeStatementsBeforeAppend(nodeWithStatements, statements);
|
||||
|
||||
NodeAppender.setScopeStatements(scope, [
|
||||
NodeAppender.setScopeStatements(nodeWithStatements, [
|
||||
...statements,
|
||||
...NodeAppender.getScopeStatements(scope),
|
||||
...NodeAppender.getScopeStatements(nodeWithStatements),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithScope} scope
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
private static getScopeStatements (scope: TNodeWithScope): TStatement[] {
|
||||
if (NodeGuards.isSwitchCaseNode(scope)) {
|
||||
return scope.consequent;
|
||||
private static getScopeStatements (nodeWithStatements: TNodeWithStatements): TStatement[] {
|
||||
if (NodeGuards.isSwitchCaseNode(nodeWithStatements)) {
|
||||
return nodeWithStatements.consequent;
|
||||
}
|
||||
|
||||
return scope.body;
|
||||
return nodeWithStatements.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithScope} scope
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {TStatement[]} statements
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
private static parentizeScopeStatementsBeforeAppend (scope: TNodeWithScope, statements: TStatement[]): TStatement[] {
|
||||
private static parentizeScopeStatementsBeforeAppend (
|
||||
nodeWithStatements: TNodeWithStatements,
|
||||
statements: TStatement[]
|
||||
): TStatement[] {
|
||||
statements.forEach((statement: TStatement) => {
|
||||
statement.parentNode = scope;
|
||||
statement.parentNode = nodeWithStatements;
|
||||
});
|
||||
|
||||
return statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithScope} scope
|
||||
* @param {TNodeWithStatements} nodeWithStatements
|
||||
* @param {TStatement[]} statements
|
||||
*/
|
||||
private static setScopeStatements (scope: TNodeWithScope, statements: TStatement[]): void {
|
||||
if (NodeGuards.isSwitchCaseNode(scope)) {
|
||||
scope.consequent = <ESTree.Statement[]>statements;
|
||||
private static setScopeStatements (nodeWithStatements: TNodeWithStatements, statements: TStatement[]): void {
|
||||
if (NodeGuards.isSwitchCaseNode(nodeWithStatements)) {
|
||||
nodeWithStatements.consequent = <ESTree.Statement[]>statements;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
scope.body = statements;
|
||||
nodeWithStatements.body = statements;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-14
@@ -92,16 +92,11 @@ export class NodeFactory {
|
||||
* @returns {BreakStatement}
|
||||
*/
|
||||
public static breakStatement (label?: ESTree.Identifier): ESTree.BreakStatement {
|
||||
const breakStatementNode: ESTree.BreakStatement = {
|
||||
return {
|
||||
type: NodeType.BreakStatement,
|
||||
label,
|
||||
metadata: { ignoredNode: false }
|
||||
};
|
||||
|
||||
if (label) {
|
||||
breakStatementNode.label = label;
|
||||
}
|
||||
|
||||
return breakStatementNode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,16 +121,11 @@ export class NodeFactory {
|
||||
* @returns {ContinueStatement}
|
||||
*/
|
||||
public static continueStatement (label?: ESTree.Identifier): ESTree.ContinueStatement {
|
||||
const continueStatementNode: ESTree.ContinueStatement = {
|
||||
return {
|
||||
type: NodeType.ContinueStatement,
|
||||
label,
|
||||
metadata: { ignoredNode: false }
|
||||
};
|
||||
|
||||
if (label) {
|
||||
continueStatementNode.label = label;
|
||||
}
|
||||
|
||||
return continueStatementNode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+28
-41
@@ -1,7 +1,7 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockScope } from '../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithScope } from '../types/node/TNodeWithScope';
|
||||
import { TNodeWithLexicalScope } from '../types/node/TNodeWithLexicalScope';
|
||||
import { TNodeWithStatements } from '../types/node/TNodeWithStatements';
|
||||
|
||||
import { NodeType } from '../enums/node/NodeType';
|
||||
|
||||
@@ -9,7 +9,7 @@ export class NodeGuards {
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
private static readonly nodesWithBlockScope: string[] = [
|
||||
private static readonly nodesWithLexicalStatements: string[] = [
|
||||
NodeType.ArrowFunctionExpression,
|
||||
NodeType.FunctionDeclaration,
|
||||
NodeType.FunctionExpression,
|
||||
@@ -32,14 +32,6 @@ export class NodeGuards {
|
||||
return node.type === NodeType.ArrowFunctionExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isAssignmentExpressionNode (node: ESTree.Node): node is ESTree.AssignmentExpression {
|
||||
return node.type === NodeType.AssignmentExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
@@ -120,6 +112,16 @@ export class NodeGuards {
|
||||
return node.type === NodeType.ExpressionStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isFunctionNode (node: ESTree.Node): node is ESTree.Function {
|
||||
return NodeGuards.isFunctionDeclarationNode(node) ||
|
||||
NodeGuards.isFunctionExpressionNode(node) ||
|
||||
NodeGuards.isArrowFunctionExpressionNode(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
@@ -144,14 +146,6 @@ export class NodeGuards {
|
||||
return node.type === NodeType.Identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isIfStatementNode (node: ESTree.Node): node is ESTree.IfStatement {
|
||||
return node.type === NodeType.IfStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
@@ -160,22 +154,6 @@ export class NodeGuards {
|
||||
return node.type === NodeType.ImportDeclaration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isImportDefaultSpecifierNode (node: ESTree.Node): node is ESTree.ImportDefaultSpecifier {
|
||||
return node.type === NodeType.ImportDefaultSpecifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isImportNamespaceSpecifierNode (node: ESTree.Node): node is ESTree.ImportNamespaceSpecifier {
|
||||
return node.type === NodeType.ImportNamespaceSpecifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
@@ -237,23 +215,32 @@ export class NodeGuards {
|
||||
return object && !object.type !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isNodeWithLexicalScope (node: ESTree.Node): node is TNodeWithLexicalScope {
|
||||
return NodeGuards.isProgramNode(node) || NodeGuards.isFunctionNode(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @param {Node} parentNode
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isNodeHasBlockScope (node: ESTree.Node, parentNode: ESTree.Node): node is TNodeWithBlockScope {
|
||||
return NodeGuards.isProgramNode(node) || (
|
||||
NodeGuards.isBlockStatementNode(node)
|
||||
&& NodeGuards.nodesWithBlockScope.includes(parentNode.type)
|
||||
);
|
||||
public static isNodeWithLexicalScopeStatements (
|
||||
node: ESTree.Node,
|
||||
parentNode: ESTree.Node
|
||||
): node is TNodeWithStatements {
|
||||
return NodeGuards.isProgramNode(node)
|
||||
|| (NodeGuards.isBlockStatementNode(node) && NodeGuards.nodesWithLexicalStatements.includes(parentNode.type));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public static isNodeHasScope (node: ESTree.Node): node is TNodeWithScope {
|
||||
public static isNodeWithStatements (node: ESTree.Node): node is TNodeWithStatements {
|
||||
return NodeGuards.isProgramNode(node)
|
||||
|| NodeGuards.isBlockStatementNode(node)
|
||||
|| NodeGuards.isSwitchCaseNode(node);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithLexicalScope } from '../types/node/TNodeWithLexicalScope';
|
||||
|
||||
import { NodeGuards } from './NodeGuards';
|
||||
|
||||
export class NodeLexicalScopeUtils {
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {TNodeWithLexicalScope}
|
||||
*/
|
||||
public static getLexicalScope (node: ESTree.Node): TNodeWithLexicalScope | undefined {
|
||||
return NodeLexicalScopeUtils.getLexicalScopesRecursive(node, 1)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {TNodeWithLexicalScope[]}
|
||||
*/
|
||||
public static getLexicalScopes (node: ESTree.Node): TNodeWithLexicalScope[] {
|
||||
return NodeLexicalScopeUtils.getLexicalScopesRecursive(node);
|
||||
}
|
||||
|
||||
/***
|
||||
* @param {Node} node
|
||||
* @param {number} maxSize
|
||||
* @param {TNodeWithLexicalScope[]} nodesWithLexicalScope
|
||||
* @param {number} depth
|
||||
* @returns {TNodeWithLexicalScope[]}
|
||||
*/
|
||||
private static getLexicalScopesRecursive (
|
||||
node: ESTree.Node,
|
||||
maxSize: number = Infinity,
|
||||
nodesWithLexicalScope: TNodeWithLexicalScope[] = [],
|
||||
depth: number = 0
|
||||
): TNodeWithLexicalScope[] {
|
||||
if (nodesWithLexicalScope.length >= maxSize) {
|
||||
return nodesWithLexicalScope;
|
||||
}
|
||||
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
throw new ReferenceError('`parentNode` property of given node is `undefined`');
|
||||
}
|
||||
|
||||
if (NodeGuards.isNodeWithLexicalScope(node)) {
|
||||
nodesWithLexicalScope.push(node);
|
||||
}
|
||||
|
||||
if (node !== parentNode) {
|
||||
return NodeLexicalScopeUtils.getLexicalScopesRecursive(parentNode, maxSize, nodesWithLexicalScope, ++depth);
|
||||
}
|
||||
|
||||
return nodesWithLexicalScope;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithStatements } from '../types/node/TNodeWithStatements';
|
||||
import { TStatement } from '../types/node/TStatement';
|
||||
|
||||
import { NodeGuards } from './NodeGuards';
|
||||
|
||||
export class NodeStatementUtils {
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {TNodeWithStatements}
|
||||
*/
|
||||
public static getParentNodeWithStatements (node: ESTree.Node): TNodeWithStatements {
|
||||
return NodeStatementUtils.getParentNodesWithStatementsRecursive(node, 1)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {TNodeWithStatements[]}
|
||||
*/
|
||||
public static getParentNodesWithStatements (node: ESTree.Node): TNodeWithStatements[] {
|
||||
return NodeStatementUtils.getParentNodesWithStatementsRecursive(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Statement} statement
|
||||
* @returns {TStatement | null}
|
||||
*/
|
||||
public static getNextSiblingStatement (statement: ESTree.Statement): TStatement | null {
|
||||
return NodeStatementUtils.getSiblingStatementByOffset(statement, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Statement} statement
|
||||
* @returns {TStatement | null}
|
||||
*/
|
||||
public static getPreviousSiblingStatement (statement: ESTree.Statement): TStatement | null {
|
||||
return NodeStatementUtils.getSiblingStatementByOffset(statement, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {Statement}
|
||||
*/
|
||||
public static getRootStatementOfNode (node: ESTree.Node): ESTree.Statement {
|
||||
if (NodeGuards.isProgramNode(node)) {
|
||||
throw new Error('Unable to find root statement for `Program` node');
|
||||
}
|
||||
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
throw new ReferenceError('`parentNode` property of given node is `undefined`');
|
||||
}
|
||||
|
||||
if (!NodeGuards.isNodeWithStatements(parentNode)) {
|
||||
return NodeStatementUtils.getRootStatementOfNode(parentNode);
|
||||
}
|
||||
|
||||
return <ESTree.Statement>node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeGuards} node
|
||||
* @returns {TNodeWithStatements}
|
||||
*/
|
||||
public static getScopeOfNode (node: ESTree.Node): TNodeWithStatements {
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
throw new ReferenceError('`parentNode` property of given node is `undefined`');
|
||||
}
|
||||
|
||||
if (!NodeGuards.isNodeWithStatements(parentNode)) {
|
||||
return NodeStatementUtils.getScopeOfNode(parentNode);
|
||||
}
|
||||
|
||||
return parentNode;
|
||||
}
|
||||
|
||||
/***
|
||||
* @param {Node} node
|
||||
* @param {number} maxSize
|
||||
* @param {TNodeWithStatements[]} nodesWithStatements
|
||||
* @param {number} depth
|
||||
* @returns {TNodeWithStatements[]}
|
||||
*/
|
||||
private static getParentNodesWithStatementsRecursive (
|
||||
node: ESTree.Node,
|
||||
maxSize: number = Infinity,
|
||||
nodesWithStatements: TNodeWithStatements[] = [],
|
||||
depth: number = 0
|
||||
): TNodeWithStatements[] {
|
||||
if (nodesWithStatements.length >= maxSize) {
|
||||
return nodesWithStatements;
|
||||
}
|
||||
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
throw new ReferenceError('`parentNode` property of given node is `undefined`');
|
||||
}
|
||||
|
||||
if (
|
||||
/**
|
||||
* we can add program node instantly
|
||||
*/
|
||||
NodeGuards.isProgramNode(node) ||
|
||||
(NodeGuards.isNodeWithLexicalScopeStatements(node, parentNode) && depth > 0)
|
||||
) {
|
||||
nodesWithStatements.push(node);
|
||||
}
|
||||
|
||||
if (node !== parentNode) {
|
||||
return NodeStatementUtils.getParentNodesWithStatementsRecursive(parentNode, maxSize, nodesWithStatements, ++depth);
|
||||
}
|
||||
|
||||
return nodesWithStatements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Statement} statement
|
||||
* @param {number} offset
|
||||
* @returns {TStatement | null}
|
||||
*/
|
||||
private static getSiblingStatementByOffset (statement: ESTree.Statement, offset: number): TStatement | null {
|
||||
const scopeNode: TNodeWithStatements = NodeStatementUtils.getScopeOfNode(statement);
|
||||
const scopeBody: TStatement[] = !NodeGuards.isSwitchCaseNode(scopeNode)
|
||||
? scopeNode.body
|
||||
: scopeNode.consequent;
|
||||
const indexInScope: number = scopeBody.indexOf(statement);
|
||||
|
||||
return scopeBody[indexInScope + offset] || null;
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,7 @@ import * as espree from 'espree';
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockScope } from '../types/node/TNodeWithBlockScope';
|
||||
import { TNodeWithScope } from '../types/node/TNodeWithScope';
|
||||
import { TObject } from '../types/TObject';
|
||||
import { TStatement } from '../types/node/TStatement';
|
||||
|
||||
import { NodeGuards } from './NodeGuards';
|
||||
import { NodeMetadata } from './NodeMetadata';
|
||||
@@ -69,78 +66,6 @@ export class NodeUtils {
|
||||
}, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {TNodeWithBlockScope}
|
||||
*/
|
||||
public static getBlockScopeOfNode (node: ESTree.Node): TNodeWithBlockScope {
|
||||
return NodeUtils.getBlockScopesOfNodeRecursive(node, 1)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {TNodeWithBlockScope[]}
|
||||
*/
|
||||
public static getBlockScopesOfNode (node: ESTree.Node): TNodeWithBlockScope[] {
|
||||
return NodeUtils.getBlockScopesOfNodeRecursive(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Statement} statement
|
||||
* @returns {TStatement | null}
|
||||
*/
|
||||
public static getNextSiblingStatement (statement: ESTree.Statement): TStatement | null {
|
||||
return NodeUtils.getSiblingStatementByOffset(statement, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Statement} statement
|
||||
* @returns {TStatement | null}
|
||||
*/
|
||||
public static getPreviousSiblingStatement (statement: ESTree.Statement): TStatement | null {
|
||||
return NodeUtils.getSiblingStatementByOffset(statement, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {Statement}
|
||||
*/
|
||||
public static getRootStatementOfNode (node: ESTree.Node): ESTree.Statement {
|
||||
if (NodeGuards.isProgramNode(node)) {
|
||||
throw new Error('Unable to find root statement for `Program` node');
|
||||
}
|
||||
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
throw new ReferenceError('`parentNode` property of given node is `undefined`');
|
||||
}
|
||||
|
||||
if (!NodeGuards.isNodeHasScope(parentNode)) {
|
||||
return NodeUtils.getRootStatementOfNode(parentNode);
|
||||
}
|
||||
|
||||
return <ESTree.Statement>node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeGuards} node
|
||||
* @returns {TNodeWithScope}
|
||||
*/
|
||||
public static getScopeOfNode (node: ESTree.Node): TNodeWithScope {
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
throw new ReferenceError('`parentNode` property of given node is `undefined`');
|
||||
}
|
||||
|
||||
if (!NodeGuards.isNodeHasScope(parentNode)) {
|
||||
return NodeUtils.getScopeOfNode(parentNode);
|
||||
}
|
||||
|
||||
return parentNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {UnaryExpression} unaryExpressionNode
|
||||
* @returns {NodeGuards}
|
||||
@@ -213,73 +138,4 @@ export class NodeUtils {
|
||||
|
||||
return <T>copy;
|
||||
}
|
||||
|
||||
/***
|
||||
* @param {Node} node
|
||||
* @param {number} maxSize
|
||||
* @param {TNodeWithBlockScope[]} blockScopes
|
||||
* @param {number} depth
|
||||
* @returns {TNodeWithBlockScope[]}
|
||||
*/
|
||||
private static getBlockScopesOfNodeRecursive (
|
||||
node: ESTree.Node,
|
||||
maxSize: number = Infinity,
|
||||
blockScopes: TNodeWithBlockScope[] = [],
|
||||
depth: number = 0
|
||||
): TNodeWithBlockScope[] {
|
||||
if (blockScopes.length >= maxSize) {
|
||||
return blockScopes;
|
||||
}
|
||||
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
throw new ReferenceError('`parentNode` property of given node is `undefined`');
|
||||
}
|
||||
|
||||
/**
|
||||
* Stage 1: process root block statement node of the slice of AST-tree
|
||||
*/
|
||||
if (NodeGuards.isBlockStatementNode(node) && parentNode === node) {
|
||||
blockScopes.push(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stage 2: process any other nodes
|
||||
*/
|
||||
if (
|
||||
/**
|
||||
* we can add program node instantly
|
||||
*/
|
||||
NodeGuards.isProgramNode(node) ||
|
||||
/**
|
||||
* we shouldn't add to the array input node that is node with block scope itself
|
||||
* so, on depth 0 we will skip push to the array of block scopes
|
||||
*/
|
||||
(depth && NodeGuards.isNodeHasBlockScope(node, parentNode))
|
||||
) {
|
||||
blockScopes.push(node);
|
||||
}
|
||||
|
||||
if (node !== parentNode) {
|
||||
return NodeUtils.getBlockScopesOfNodeRecursive(parentNode, maxSize, blockScopes, ++depth);
|
||||
}
|
||||
|
||||
return blockScopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Statement} statement
|
||||
* @param {number} offset
|
||||
* @returns {TStatement | null}
|
||||
*/
|
||||
private static getSiblingStatementByOffset (statement: ESTree.Statement, offset: number): TStatement | null {
|
||||
const scopeNode: TNodeWithScope = NodeUtils.getScopeOfNode(statement);
|
||||
const scopeBody: TStatement[] = !NodeGuards.isSwitchCaseNode(scopeNode)
|
||||
? scopeNode.body
|
||||
: scopeNode.consequent;
|
||||
const indexInScope: number = scopeBody.indexOf(statement);
|
||||
|
||||
return scopeBody[indexInScope + offset] || null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
|
||||
|
||||
import { TObfuscationResultFactory } from '../types/container/TObfuscationResultFactory';
|
||||
|
||||
import { ICryptUtils } from '../interfaces/utils/ICryptUtils';
|
||||
import { IObfuscationResult } from '../interfaces/IObfuscationResult';
|
||||
import { IOptions } from '../interfaces/options/IOptions';
|
||||
import { ISourceMapCorrector } from '../interfaces/source-map/ISourceMapCorrector';
|
||||
import { IObfuscatedCode } from '../interfaces/source-code/IObfuscatedCode';
|
||||
|
||||
import { initializable } from '../decorators/Initializable';
|
||||
import { SourceMapMode } from '../enums/source-map/SourceMapMode';
|
||||
import { IOptions } from '../interfaces/options/IOptions';
|
||||
|
||||
@injectable()
|
||||
export class SourceMapCorrector implements ISourceMapCorrector {
|
||||
export class ObfuscatedCode implements IObfuscatedCode {
|
||||
/**
|
||||
* @type {ICryptUtils}
|
||||
*/
|
||||
private readonly cryptUtils: ICryptUtils;
|
||||
|
||||
/**
|
||||
* @type {TObfuscationResultFactory}
|
||||
* @type {string}
|
||||
*/
|
||||
private readonly obfuscationResultFactory: TObfuscationResultFactory;
|
||||
@initializable()
|
||||
private obfuscatedCode!: string;
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
@@ -28,16 +27,15 @@ export class SourceMapCorrector implements ISourceMapCorrector {
|
||||
private readonly options: IOptions;
|
||||
|
||||
/**
|
||||
* @param {TObfuscationResultFactory} obfuscationResultFactory
|
||||
* @param {ICryptUtils} cryptUtils
|
||||
* @param {IOptions} options
|
||||
* @type {string}
|
||||
*/
|
||||
@initializable()
|
||||
private sourceMap!: string;
|
||||
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IObfuscationResult) obfuscationResultFactory: TObfuscationResultFactory,
|
||||
@inject(ServiceIdentifiers.ICryptUtils) cryptUtils: ICryptUtils,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
this.obfuscationResultFactory = obfuscationResultFactory;
|
||||
this.cryptUtils = cryptUtils;
|
||||
this.options = options;
|
||||
}
|
||||
@@ -45,23 +43,39 @@ export class SourceMapCorrector implements ISourceMapCorrector {
|
||||
/**
|
||||
* @param {string} obfuscatedCode
|
||||
* @param {string} sourceMap
|
||||
* @returns {IObfuscationResult}
|
||||
*/
|
||||
public correct (obfuscatedCode: string, sourceMap: string): IObfuscationResult {
|
||||
return this.obfuscationResultFactory(
|
||||
this.correctObfuscatedCode(obfuscatedCode, sourceMap),
|
||||
sourceMap
|
||||
);
|
||||
public initialize (obfuscatedCode: string, sourceMap: string): void {
|
||||
this.obfuscatedCode = obfuscatedCode;
|
||||
this.sourceMap = sourceMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} obfuscatedCode
|
||||
* @param {string} sourceMap
|
||||
* @returns {string}
|
||||
*/
|
||||
private correctObfuscatedCode (obfuscatedCode: string, sourceMap: string): string {
|
||||
if (!sourceMap) {
|
||||
return obfuscatedCode;
|
||||
public getObfuscatedCode (): string {
|
||||
return this.correctObfuscatedCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getSourceMap (): string {
|
||||
return this.sourceMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public toString (): string {
|
||||
return this.obfuscatedCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
private correctObfuscatedCode (): string {
|
||||
if (!this.sourceMap) {
|
||||
return this.obfuscatedCode;
|
||||
}
|
||||
|
||||
const sourceMapUrl: string = this.options.sourceMapBaseUrl + this.options.sourceMapFileName;
|
||||
@@ -70,19 +84,19 @@ export class SourceMapCorrector implements ISourceMapCorrector {
|
||||
|
||||
switch (this.options.sourceMapMode) {
|
||||
case SourceMapMode.Inline:
|
||||
sourceMappingUrl += `data:application/json;base64,${this.cryptUtils.btoa(sourceMap)}`;
|
||||
sourceMappingUrl += `data:application/json;base64,${this.cryptUtils.btoa(this.sourceMap)}`;
|
||||
|
||||
break;
|
||||
|
||||
case SourceMapMode.Separate:
|
||||
default:
|
||||
if (!sourceMapUrl) {
|
||||
return obfuscatedCode;
|
||||
return this.obfuscatedCode;
|
||||
}
|
||||
|
||||
sourceMappingUrl += sourceMapUrl;
|
||||
}
|
||||
|
||||
return `${obfuscatedCode}\n${sourceMappingUrl}`;
|
||||
return `${this.obfuscatedCode}\n${sourceMappingUrl}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { ISourceCode } from '../interfaces/source-code/ISourceCode';
|
||||
|
||||
export class SourceCode implements ISourceCode {
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private readonly sourceCode: string;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
private readonly sourceMap: string;
|
||||
|
||||
/**
|
||||
* @param {string} sourceCode
|
||||
* @param {string} sourceMap
|
||||
*/
|
||||
constructor (sourceCode: string, sourceMap: string) {
|
||||
this.sourceCode = sourceCode;
|
||||
this.sourceMap = sourceMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getSourceCode (): string {
|
||||
return this.sourceCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public getSourceMap (): string {
|
||||
return this.sourceMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
public toString (): string {
|
||||
return this.sourceCode;
|
||||
}
|
||||
}
|
||||
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
||||
/* tslint:disable:interface-over-type-literal */
|
||||
|
||||
export type TObject <T = any> = {[key: string]: T};
|
||||
export type TObject <T = unknown> = {[key: string]: T};
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
import { IObfuscationResult } from '../../interfaces/IObfuscationResult';
|
||||
|
||||
export type TObfuscationResultFactory = (obfuscatedCode: string, sourceMap: string) => IObfuscationResult;
|
||||
@@ -0,0 +1,3 @@
|
||||
import { IObfuscatedCode } from '../../../interfaces/source-code/IObfuscatedCode';
|
||||
|
||||
export type TObfuscatedCodeFactory = (obfuscatedCode: string, sourceMap: string) => IObfuscatedCode;
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
export type TNodeWithBlockScope = ESTree.Program | ESTree.BlockStatement;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
export type TNodeWithLexicalScope = ESTree.Program | ESTree.Function;
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
export type TNodeWithScope = ESTree.Program | ESTree.BlockStatement | ESTree.SwitchCase;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
export type TNodeWithStatements = ESTree.Program | ESTree.BlockStatement | ESTree.SwitchCase;
|
||||
-1
@@ -1 +0,0 @@
|
||||
export type TSourceMapMode = 'inline' | 'separate';
|
||||
@@ -7,7 +7,7 @@ import { Chance } from 'chance';
|
||||
import { IInitializable } from '../interfaces/IInitializable';
|
||||
import { IOptions } from '../interfaces/options/IOptions';
|
||||
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
|
||||
import { ISourceCode } from '../interfaces/ISourceCode';
|
||||
import { ISourceCode } from '../interfaces/source-code/ISourceCode';
|
||||
|
||||
import { initializable } from '../decorators/Initializable';
|
||||
|
||||
@@ -81,19 +81,6 @@ export class RandomGenerator implements IRandomGenerator, IInitializable {
|
||||
return this.getRandomInteger(0, 99999) / 100000;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} min
|
||||
* @param {number} max
|
||||
* @returns {number}
|
||||
*/
|
||||
public getRandomFloat (min: number, max: number): number {
|
||||
return this.getRandomGenerator().floating({
|
||||
min: min,
|
||||
max: max,
|
||||
fixed: 7
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Chance.Chance}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user