Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Analysis.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ export default class Analysis {
}

const identifiersLengthArr = this.identifiersName
.filter((value) => value.type !== "property" && typeof value.name === "string").map((value) => value.name.length);
.filter((value) => value.type !== "property" && typeof value.name === "string")
.map((value) => value.name.length);

const [idsLengthAvg, stringScore] = [sum(identifiersLengthArr), sum(this.literalScores)];
if (!isMinified && identifiersLengthArr.length > 5 && idsLengthAvg <= 1.5) {
Expand Down
6 changes: 5 additions & 1 deletion src/probes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import isAssignmentExpression from "./isAssignmentExpression.js";
import isObjectExpression from "./isObjectExpression.js";
import isUnaryExpression from "./isUnaryExpression.js";
import isWeakCrypto from "./isWeakCrypto.js";
import isClassDeclaration from "./isClassDeclaration.js";
import isMethodDefinition from "./isMethodDefinition.js";

// CONSTANTS
const kListOfProbes = [
Expand All @@ -29,7 +31,9 @@ const kListOfProbes = [
isArrayExpression,
isFunctionDeclaration,
isUnaryExpression,
isWeakCrypto
isWeakCrypto,
isClassDeclaration,
isMethodDefinition
];

const kSymBreak = Symbol.for("breakWalk");
Expand Down
25 changes: 25 additions & 0 deletions src/probes/isClassDeclaration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Import Internal Dependencies
import { extractNode } from "../utils.js";

// CONSTANTS
const kIdExtractor = extractNode("Identifier");

function validateNode(node) {
return [
node.type === "ClassDeclaration"
];
}

function main(node, options) {
const { analysis } = options;

kIdExtractor(
({ name }) => analysis.identifiersName.push({ name, type: "class" }),
[node.id, node.superClass]
);
}

export default {
name: "isClassDeclaration",
validateNode, main, breakOnMatch: false
};
25 changes: 25 additions & 0 deletions src/probes/isMethodDefinition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Import Internal Dependencies
import { extractNode } from "../utils.js";

// CONSTANTS
const kIdExtractor = extractNode("Identifier");

function validateNode(node) {
return [
node.type === "MethodDefinition"
];
}

function main(node, options) {
const { analysis } = options;

kIdExtractor(
({ name }) => analysis.identifiersName.push({ name, type: "method" }),
[node.key]
);
}

export default {
name: "isMethodDefinition",
validateNode, main, breakOnMatch: false
};
12 changes: 12 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,15 @@ export function toArrayLocation(location = rootLocation()) {
[end.line || 0, end.column || 0]
];
}

export function extractNode(expectedType) {
return (callback, nodes) => {
const finalNodes = Array.isArray(nodes) ? nodes : [nodes];

for (const node of finalNodes) {
if (notNullOrUndefined(node) && node.type === expectedType) {
callback(node);
}
}
};
}
43 changes: 43 additions & 0 deletions test/probes/isClassDeclaration.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Require Internal Dependencies
import { getSastAnalysis, parseScript } from "../utils/index.js";
import isClassDeclaration from "../../src/probes/isClassDeclaration.js";

// Require Third-party dependencies
import test from "tape";

test("should detect two identifiers (class name and superClass name A.K.A extends)", (tape) => {
const str = "class File extends Blob {}";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isClassDeclaration);

tape.deepEqual(analysis.identifiersName, [
{ name: "File", type: "class" },
{ name: "Blob", type: "class" }
]);

tape.end();
});

test("should detect one identifier because there is no superClass (extension)", (tape) => {
const str = "class File {}";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isClassDeclaration);

tape.deepEqual(analysis.identifiersName, [
{ name: "File", type: "class" }
]);

tape.end();
});

test("should detect one identifier because superClass is not an Identifier but a CallExpression", (tape) => {
const str = "class File extends (foo()) {}";
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isClassDeclaration);

tape.deepEqual(analysis.identifiersName, [
{ name: "File", type: "class" }
]);

tape.end();
});
38 changes: 38 additions & 0 deletions test/probes/isMethodDefinition.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Require Internal Dependencies
import { getSastAnalysis, parseScript } from "../utils/index.js";
import isMethodDefinition from "../../src/probes/isMethodDefinition.js";

// Require Third-party dependencies
import test from "tape";

test("should detect two identifiers (constructor and one method definition)", (tape) => {
const str = `class File {
constructor() {}
foo() {}
}`;
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isMethodDefinition);

tape.deepEqual(analysis.identifiersName, [
{ name: "constructor", type: "method" },
{ name: "foo", type: "method" }
]);

tape.end();
});

test("should detect two identifiers (getter and setter)", (tape) => {
const str = `class File {
get foo() {}
set bar(value) {}
}`;
const ast = parseScript(str);
const analysis = getSastAnalysis(str, ast.body, isMethodDefinition);

tape.deepEqual(analysis.identifiersName, [
{ name: "foo", type: "method" },
{ name: "bar", type: "method" }
]);

tape.end();
});