• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

reactjs / react-docgen / 15503494088

07 Jun 2025 02:52AM CUT coverage: 95.479% (-0.01%) from 95.49%
15503494088

Pull #999

github

web-flow
Merge c42d1b242 into ec11d1f1e
Pull Request #999: Packages ready to publish

1393 of 1494 branches covered (93.24%)

Branch coverage included in aggregate %.

4605 of 4788 relevant lines covered (96.18%)

522.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.0
/packages/react-docgen/src/utils/getMemberExpressionValuePath.ts
1
import type { NodePath } from '@babel/traverse';
2
import { visitors } from '@babel/traverse';
3✔
3
import type { Expression } from '@babel/types';
4
import getNameOrValue from './getNameOrValue.js';
3✔
5
import { String as toString } from './expressionTo.js';
3✔
6
import isReactForwardRefCall from './isReactForwardRefCall.js';
3✔
7

8
function resolveName(path: NodePath): string | undefined {
1,752✔
9
  if (path.isVariableDeclaration()) {
1,752✔
10
    const declarations = path.get('declarations');
51✔
11

12
    if (declarations.length > 1) {
51!
13
      throw new TypeError(
×
14
        'Got unsupported VariableDeclaration. VariableDeclaration must only ' +
×
15
          'have a single VariableDeclarator. Got ' +
16
          declarations.length +
×
17
          ' declarations.',
×
18
      );
×
19
    }
×
20
    // VariableDeclarator always has at least one declaration, hence the non-null-assertion
21
    const id = declarations[0]!.get('id');
51✔
22

23
    if (id.isIdentifier()) {
51✔
24
      return id.node.name;
51✔
25
    }
51!
26

27
    return;
×
28
  }
✔
29

30
  if (path.isFunctionDeclaration()) {
1,731✔
31
    const id = path.get('id');
477✔
32

33
    if (id.isIdentifier()) {
477✔
34
      return id.node.name;
474✔
35
    }
474✔
36

37
    return;
3✔
38
  }
3✔
39

40
  if (
1,224✔
41
    path.isFunctionExpression() ||
1,224✔
42
    path.isArrowFunctionExpression() ||
1,185✔
43
    path.isTaggedTemplateExpression() ||
858✔
44
    path.isCallExpression() ||
858!
45
    isReactForwardRefCall(path)
×
46
  ) {
1,752✔
47
    let currentPath: NodePath = path;
1,224✔
48

49
    while (currentPath.parentPath) {
1,224✔
50
      if (currentPath.parentPath.isVariableDeclarator()) {
2,043✔
51
        const id = currentPath.parentPath.get('id');
1,029✔
52

53
        if (id.isIdentifier()) {
1,029✔
54
          return id.node.name;
1,029✔
55
        }
1,029!
56

57
        return;
×
58
      }
✔
59

60
      currentPath = currentPath.parentPath;
1,014✔
61
    }
1,014✔
62

63
    return;
195✔
64
  }
195!
65

66
  throw new TypeError(
×
67
    'Attempted to resolveName for an unsupported path. resolveName does not accept ' +
×
68
      path.node.type +
×
69
      '".',
×
70
  );
×
71
}
×
72

73
interface TraverseState {
74
  readonly memberName: string;
75
  readonly localName: string;
76
  result: NodePath<Expression> | null;
77
}
78

79
const explodedVisitors = visitors.explode<TraverseState>({
3✔
80
  AssignmentExpression: {
3✔
81
    enter: function (path, state) {
3✔
82
      const memberPath = path.get('left');
1,224✔
83

84
      if (!memberPath.isMemberExpression()) {
1,224!
85
        return;
×
86
      }
×
87
      const property = memberPath.get('property');
1,224✔
88

89
      if (
1,224✔
90
        ((!memberPath.node.computed && property.isIdentifier()) ||
1,224✔
91
          property.isStringLiteral() ||
12✔
92
          property.isNumericLiteral()) &&
9✔
93
        getNameOrValue(property) === state.memberName &&
1,215✔
94
        toString(memberPath.get('object')) === state.localName
438✔
95
      ) {
1,224✔
96
        state.result = path.get('right');
426✔
97
        path.stop();
426✔
98
      }
426✔
99
    },
1,224✔
100
  },
3✔
101
});
3✔
102

103
export default function getMemberExpressionValuePath(
1,752✔
104
  variableDefinition: NodePath,
1,752✔
105
  memberName: string,
1,752✔
106
): NodePath<Expression> | null {
1,752✔
107
  const localName = resolveName(variableDefinition);
1,752✔
108

109
  if (!localName) {
1,752✔
110
    // likely an immediately exported and therefore nameless/anonymous node
111
    // passed in
112
    return null;
198✔
113
  }
198✔
114

115
  const state: TraverseState = {
1,554✔
116
    localName,
1,554✔
117
    memberName,
1,554✔
118
    result: null,
1,554✔
119
  };
1,554✔
120

121
  variableDefinition.hub.file.traverse(explodedVisitors, state);
1,554✔
122

123
  return state.result;
1,554✔
124
}
1,554✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc