UNPKG

3.69 kBJavaScriptView Raw
1var createNodeKey = require('./create-node-key').createNodeKey;
2var AstNodeTypes = require("./ast-node-types.js");
3var SlJsInfra = require("sl-js-infra").SlJsInfra;
4
5/*
6When working in React, components are being generated by the "_createClass" method of the framework.
7As a result, we have an issue when we try to map it back to source maps.
8The method make sure to verify if a component is a React component by going through the parent nodes
9fpr a specific node, and verifying that they have the same pattern as the expected code.
10
11React Code
12================== START CODE ============
13 import React, { Component } from 'react';
14 import logo from './logo.svg';
15 import './App.css';
16
17 class App extends Component {
18 someFunc(){
19 console.log("hezi func")
20 }
21 }
22
23 export default App;
24 ================== END CODE ============
25
26This code generates the following code
27 ================== START CODE ============
28 _createClass(App, [{
29 key: 'someFunc',
30 value: function someFunc() {
31 console.log("Some func is invoked");
32 }
33}]);
34 ================== END CODE ============
35
36So basically we are searching for the "value" node, the array which contains it and the "_createClass" method.
37* */
38function isReact(node, nodeToParent){
39 if (node.type != "FunctionExpression")
40 return false;
41 var key = createNodeKey(node);
42 var valueNode = nodeToParent[key];
43 if (valueNode == null)
44 return false;
45 if (valueNode.key == null || (valueNode.key !=null && valueNode.key.name != "value"))
46 return false; //That's note the 'value' node. Return.
47 key = createNodeKey(valueNode);
48 parent = nodeToParent[key];
49 if (parent == null)
50 return false;
51 var objectNode = parent;
52 key = createNodeKey(objectNode);
53 arrayNode = nodeToParent[key];
54 if (arrayNode == null || arrayNode.type != "ArrayExpression")
55 return false;
56 key = createNodeKey(arrayNode);
57 var createClassNode = nodeToParent[key];
58 if (createClassNode == null || createClassNode.callee == null){
59 return false;
60 }
61 var result = createClassNode.callee.name == "_createClass";
62 return result;
63}
64
65/**
66
67 * */
68function guessMethodLocation(node, nodeToParent) {
69 if (isReact(node, nodeToParent) && node.type == AstNodeTypes.FunctionExpression) {
70 return node.body.loc;
71 }
72
73 /* According to this link, Istanbul uses the "node.id.loc" for FunctionDeclaration and FunctionExpression.
74 * https://github.com/istanbuljs/istanbuljs/blob/cbd1c1473da0dc34051c332170544529d59eda03/packages/istanbul-lib-instrument/src/visitor.js#L216
75 */
76 if (!SlJsInfra.SlEnvVars.isUseIstanbul() && shouldUseLocFromID(node) && node.id && node.id.loc) {
77 return node.id.loc;
78 }
79
80
81 /*
82 In typescript, in case of below code, diferrent location recieved from source maps and babel parser.
83 export function foo(){
84
85 }
86 Source maps: column 0
87 Babel parser: cloumn 7 (the 'function' woord.
88 Here we fix the location to be column 0 (export statement location)
89 */
90 if(node.type === "FunctionDeclaration"){
91 var key = createNodeKey(node);
92 var parentNode = nodeToParent[key];
93 if(parentNode.type == "ExportDefaultDeclaration" || parentNode.type == "ExportNamedDeclaration") {
94 return parentNode.loc
95 }
96 }
97 return node.loc;
98}
99
100function shouldUseLocFromID(node) {
101 return node.type === AstNodeTypes.FunctionDeclaration || node.type === AstNodeTypes.FunctionExpression;
102}
103
104module.exports.guessMethodLocation = guessMethodLocation;
\No newline at end of file