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

ota-meshi / eslint-plugin-json-schema-validator / 14773577666

01 May 2025 10:00AM CUT coverage: 87.338%. Remained the same
14773577666

Pull #384

github

web-flow
Merge df5333731 into 327e06fbd
Pull Request #384: chore(deps): update dependency eslint-plugin-node-dependencies to v1

372 of 455 branches covered (81.76%)

Branch coverage included in aggregate %.

911 of 1014 relevant lines covered (89.84%)

176.76 hits per line

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

86.6
/src/utils/ast/js/utils.ts
1
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -- ignore
316✔
2
/* eslint-disable @typescript-eslint/no-explicit-any -- ignore */
3
import type { AST } from "vue-eslint-parser";
4
import type { RuleContext } from "../../../types";
5
// @ts-expect-error -- no type def
6
import * as eslintUtils from "@eslint-community/eslint-utils";
1✔
7
import type { Variable } from "eslint-scope";
8
import { getSourceCode } from "../../compat";
1✔
9

10
/**
11
 * Gets the property name of a given node.
12
 */
13
export function getStaticPropertyName(
14
  node: AST.ESLintProperty | AST.ESLintMemberExpression,
15
  context: RuleContext,
16
): string | null {
17
  let key;
18
  if (node.type === "Property") {
184✔
19
    key = node.key;
165✔
20
    if (!node.computed) {
165✔
21
      if (key.type === "Identifier") {
160✔
22
        return key.name;
93✔
23
      }
24
    }
25
  } else if (node.type === "MemberExpression") {
19!
26
    key = node.property;
19✔
27
    if (!node.computed) {
19✔
28
      if (key.type === "Identifier") {
15✔
29
        return key.name;
15✔
30
      }
31
      return null;
×
32
    }
33
  } else {
34
    return null;
×
35
  }
36
  if (key.type === "Literal" || key.type === "TemplateLiteral") {
76✔
37
    return getStringLiteralValue(key);
74✔
38
  }
39
  if (key.type === "Identifier") {
2✔
40
    const init = findInitNode(context, key);
2✔
41
    if (init) {
2✔
42
      if (
1✔
43
        init.node.type === "Literal" ||
1!
44
        init.node.type === "TemplateLiteral"
45
      ) {
46
        return getStringLiteralValue(init.node);
1✔
47
      }
48
    }
49
  }
50
  return null;
1✔
51
}
52

53
/**
54
 * Gets the string of a given node.
55
 */
56
export function getStringLiteralValue(
57
  node: AST.ESLintLiteral | AST.ESLintTemplateLiteral,
58
): string | null {
59
  if (node.type === "Literal") {
75✔
60
    if (node.value == null) {
74✔
61
      if ((node as any).bigint != null) {
1!
62
        return String((node as any).bigint);
×
63
      }
64
    }
65
    return String(node.value);
74✔
66
  }
67
  if (node.type === "TemplateLiteral") {
1✔
68
    if (node.expressions.length === 0 && node.quasis.length === 1) {
1✔
69
      return node.quasis[0].value.cooked;
1✔
70
    }
71
  }
72
  return null;
×
73
}
74

75
/**
76
 * Find the variable of a given name.
77
 */
78
function findVariable(
79
  context: RuleContext,
80
  node: AST.ESLintIdentifier,
81
): Variable | null {
82
  return eslintUtils.findVariable(getScope(context, node), node);
103✔
83
}
84

85
/**
86
 * Get the value of a given node if it's a static value.
87
 */
88
export function getStaticValue(
89
  context: RuleContext,
90
  node: AST.ESLintNode,
91
): { value: any } | null {
92
  return eslintUtils.getStaticValue(node, getScope(context, node));
31✔
93
}
94

95
/**
96
 * Find the node that initial value.
97
 */
98
export function findInitNode(
99
  context: RuleContext,
100
  node: AST.ESLintIdentifier,
101
): { node: AST.ESLintExpression; reads: AST.ESLintIdentifier[] } | null {
102
  const variable = findVariable(context, node);
103✔
103
  if (!variable) {
103!
104
    return null;
×
105
  }
106
  if (variable.defs.length === 1) {
103✔
107
    const def = variable.defs[0];
96✔
108
    if (
96✔
109
      def.type === "Variable" &&
267✔
110
      def.parent.kind === "const" &&
111
      def.node.init
112
    ) {
113
      let init = def.node.init as AST.ESLintExpression;
76✔
114
      const reads = variable.references
76✔
115
        .filter((ref) => ref.isRead())
364✔
116
        .map((ref) => ref.identifier as AST.ESLintIdentifier);
288✔
117
      if (init.type === "Identifier") {
76✔
118
        const data = findInitNode(context, init);
3✔
119
        if (!data) {
3✔
120
          return null;
2✔
121
        }
122
        init = data.node;
1✔
123
        reads.push(...data.reads);
1✔
124
      }
125

126
      return {
74✔
127
        node: init,
128
        reads,
129
      };
130
    }
131
  }
132
  return null;
27✔
133
}
134

135
/**
136
 * Gets the scope for the current node
137
 */
138
function getScope(context: RuleContext, currentNode: AST.ESLintNode) {
139
  // On Program node, get the outermost scope to avoid return Node.js special function scope or ES modules scope.
140
  const inner = currentNode.type !== "Program";
134✔
141
  const scopeManager = getSourceCode(context).scopeManager;
134✔
142

143
  let node: any = currentNode;
134✔
144
  for (; node; node = node.parent || null) {
134!
145
    const scope = scopeManager.acquire(node, inner);
744✔
146

147
    if (scope) {
744✔
148
      if (scope.type === "function-expression-name") {
134!
149
        return scope.childScopes[0];
×
150
      }
151
      return scope;
134✔
152
    }
153
  }
154

155
  return scopeManager.scopes[0];
×
156
}
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