UNPKG

4.71 kBJavaScriptView Raw
1var guessMethodLocation = require('./guess-method-location').guessMethodLocation;
2var guessMethodName = require('./guess-method-name').guessMethodName;
3var astUtils = require('sl-esprima-ast-utils');
4var md5 = require('md5');
5var babelGenerator = require("@babel/generator");
6var traverse = require('ast-traverse');
7var AstNodeTypes = require("./ast-node-types");
8var utils = require("../utils");
9var globalMethodIndexer = require("./globalMethodIndexer");
10
11/**
12 * Crates method object from node recived from ast
13 * @constructor
14 */
15function MethodSignature(node, parentNode, nodeToParent, absolutePath, relativePath, logger) {
16 this.node = node;
17 this.parentNode = parentNode;
18 this.nodeToParent = nodeToParent;
19 this.logger = logger;
20 this.generatedData = new MethodData(absolutePath, relativePath);
21 this.srcData = new MethodData();
22 this.meta = {};
23 this.type = null;
24 this.shouldSkip = false;
25 this.hasSourceData = false;
26 this.techSpecificInfo = this.createTechSpecificInfoInterface();
27 this.idxInMapping = globalMethodIndexer.getCurrentIndex()
28}
29
30MethodSignature.prototype._createSignature = function () {
31 var location = guessMethodLocation(this.node, this.nodeToParent);
32 var nameObject = guessMethodName(this.node, this.parentNode);
33 this.type = nameObject.type;
34 this.generatedData.position = formatLocationToArray(location.start);
35 this.generatedData.endPosition = formatLocationToArray(this.node.loc.end);
36 this.generatedData.hash = this.calculateHash();
37 this.generatedData.sigHash = this.calculateSigHash();
38 this.generatedData.displayName = nameObject.name;
39 this.meta.anonymous = nameObject.isAnonymous;
40 this.techSpecificInfo.isAnonymous = nameObject.isAnonymous;
41 this.srcData = utils.cloneObject(this.generatedData, this.logger);
42};
43
44MethodSignature.prototype.calculateHash = function () {
45 var context = this;
46 var clonedNode = astUtils.clone(this.node);
47 // Visit node in pre order and calculate body hash.
48 traverse(clonedNode, {
49 pre: function (node) {
50 // If current node is the root node given return (we want to calculate the body hash only).
51 if (node == clonedNode)
52 return;
53 if (AstNodeTypes.isMethodNode(node)) {
54 context.emptyNode(node);
55 }
56 }
57 });
58 var generatedCode = this.generateCodeFromAST(clonedNode);
59 return md5(generatedCode);
60};
61
62MethodSignature.prototype.calculateSigHash = function () {
63 var context = this;
64 if (!this.node.params || this.node.params.length == 0) {
65 return "";
66 }
67 var paramsStr = this.node.params.map(function (param) {
68 return context.generateCodeFromAST(param);
69 }).join(',');
70
71 return md5(paramsStr);
72};
73
74MethodSignature.prototype.emptyNode = function (node) {
75 node.body = {
76 type: AstNodeTypes.BlockStatement,
77 body: []
78 }
79 node.params = [];
80 node.id = {
81 name: '_',
82 type: AstNodeTypes.Identifier
83 };
84};
85
86MethodSignature.prototype.generateCodeFromAST = function (node) {
87 return babelGenerator.default(node, {
88 comments: false
89 }, '').code;
90
91};
92
93MethodSignature.prototype.createTechSpecificInfoInterface = function () {
94 return {
95 isAsync: this.node.async || false,
96 isComputed: this.node.computed || false,
97 isExpression: this.node.expression || false,
98 isGenerator: this.node.generator || false,
99 kind: this.node.kind,
100 isStatic: this.node.static || false
101 }
102};
103
104MethodSignature.prototype.createUniqueId = function() {
105 var relevantData = this.hasSourceData ? this.srcData : this.generatedData;
106 return [relevantData.relativeFilename, relevantData.position.join(',')].join('@')
107};
108
109
110MethodSignature.prototype.createDTO = function() {
111 return {
112 meta: this.meta,
113 techSpecificInfo: this.techSpecificInfo,
114 type: this.type,
115 srcData: this.srcData,
116 generatedData: this.generatedData,
117 uniqueId: this.createUniqueId(),
118 idxInMapping: this.idxInMapping
119 }
120};
121
122MethodSignature.create = function (node, parentNode, nodeToParent, absolutePath, relativePath, logger) {
123 var signature = new this(node, parentNode, nodeToParent, absolutePath, relativePath, logger);
124 signature._createSignature();
125 return signature;
126}
127
128function formatLocationToArray(loc) {
129 return [loc.line, loc.column];
130}
131
132function MethodData(absolutePath, relativePath) {
133 this.position = null;
134 this.endPosition = null;
135 this.displayName = null;
136 this.hash = null;
137 this.sigHash = null;
138 this.relativeFilename = relativePath;
139 this.absoluteFilename = absolutePath;
140}
141module.exports = MethodSignature;
\No newline at end of file