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