react-doctor 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +54 -54
- package/dist/index.js +75 -53
- package/package.json +6 -5
- package/dist/chunk-q7NCDQ7-.js +0 -26
- package/dist/dist-2B-kn9PW.js +0 -17940
- package/dist/dist-BPzE37C6.js +0 -17940
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ import process$1 from "node:process";
|
|
|
6
6
|
import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, FRAMEWORK_SPECIFIC_RULE_KEYS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES } from "oxlint-plugin-react-doctor";
|
|
7
7
|
import { gzipSync } from "node:zlib";
|
|
8
8
|
import os, { tmpdir } from "node:os";
|
|
9
|
-
import * as ts
|
|
9
|
+
import * as ts from "typescript";
|
|
10
10
|
import { performance } from "node:perf_hooks";
|
|
11
11
|
import { stripVTControlCharacters } from "node:util";
|
|
12
12
|
import tty from "node:tty";
|
|
@@ -6681,7 +6681,7 @@ const toRelativeFilePath = (rootDirectory, filePath) => {
|
|
|
6681
6681
|
const checkDeadCode = async (options) => {
|
|
6682
6682
|
const { rootDirectory, userConfig } = options;
|
|
6683
6683
|
if (!fs.existsSync(path.join(rootDirectory, "package.json"))) return [];
|
|
6684
|
-
const { analyze, defineConfig } = await import("
|
|
6684
|
+
const { analyze, defineConfig } = await import("deslop-js");
|
|
6685
6685
|
const ignorePatterns = collectDeadCodeIgnorePatterns(rootDirectory, userConfig);
|
|
6686
6686
|
const result = await analyze(defineConfig({
|
|
6687
6687
|
rootDir: rootDirectory,
|
|
@@ -7918,43 +7918,43 @@ const REACT_USE_BINDING_RESOLUTION = {
|
|
|
7918
7918
|
isReactNamespaceBinding: false
|
|
7919
7919
|
};
|
|
7920
7920
|
const getScriptKind = (filename) => {
|
|
7921
|
-
if (filename.endsWith(".tsx")) return ts
|
|
7922
|
-
if (filename.endsWith(".jsx")) return ts
|
|
7923
|
-
if (filename.endsWith(".ts")) return ts
|
|
7924
|
-
return ts
|
|
7921
|
+
if (filename.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
7922
|
+
if (filename.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
7923
|
+
if (filename.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
7924
|
+
return ts.ScriptKind.JS;
|
|
7925
7925
|
};
|
|
7926
7926
|
const getUtf16Offset = (sourceText, utf8Offset) => Buffer.from(sourceText).subarray(0, utf8Offset).toString("utf8").length;
|
|
7927
7927
|
const unwrapExpression = (expression) => {
|
|
7928
7928
|
let currentExpression = expression;
|
|
7929
|
-
while (ts
|
|
7929
|
+
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
7930
7930
|
return currentExpression;
|
|
7931
7931
|
};
|
|
7932
7932
|
const getStaticPropertyName = (node) => {
|
|
7933
7933
|
if (!node) return null;
|
|
7934
|
-
if (ts
|
|
7935
|
-
if (ts
|
|
7934
|
+
if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node)) return node.text;
|
|
7935
|
+
if (ts.isComputedPropertyName(node)) {
|
|
7936
7936
|
const expression = unwrapExpression(node.expression);
|
|
7937
|
-
if (ts
|
|
7937
|
+
if (ts.isStringLiteral(expression) || ts.isNoSubstitutionTemplateLiteral(expression)) return expression.text;
|
|
7938
7938
|
}
|
|
7939
7939
|
return null;
|
|
7940
7940
|
};
|
|
7941
7941
|
const findBindingIdentifier = (bindingName, identifierName) => {
|
|
7942
|
-
if (ts
|
|
7942
|
+
if (ts.isIdentifier(bindingName)) return bindingName.text === identifierName ? bindingName : null;
|
|
7943
7943
|
for (const element of bindingName.elements) {
|
|
7944
|
-
if (ts
|
|
7944
|
+
if (ts.isOmittedExpression(element)) continue;
|
|
7945
7945
|
const nestedIdentifier = findBindingIdentifier(element.name, identifierName);
|
|
7946
7946
|
if (nestedIdentifier) return nestedIdentifier;
|
|
7947
7947
|
}
|
|
7948
7948
|
return null;
|
|
7949
7949
|
};
|
|
7950
7950
|
const bindingNameHasIdentifier = (bindingName, identifierName) => {
|
|
7951
|
-
if (ts
|
|
7951
|
+
if (ts.isIdentifier(bindingName)) return bindingName.text === identifierName;
|
|
7952
7952
|
return bindingName.elements.some((element) => {
|
|
7953
|
-
if (ts
|
|
7953
|
+
if (ts.isOmittedExpression(element)) return false;
|
|
7954
7954
|
return bindingNameHasIdentifier(element.name, identifierName);
|
|
7955
7955
|
});
|
|
7956
7956
|
};
|
|
7957
|
-
const getDirectBindingIdentifier = (bindingName) => ts
|
|
7957
|
+
const getDirectBindingIdentifier = (bindingName) => ts.isIdentifier(bindingName) ? bindingName : null;
|
|
7958
7958
|
const isReactUseObjectBindingElement = (bindingElement) => {
|
|
7959
7959
|
const bindingIdentifier = getDirectBindingIdentifier(bindingElement.name);
|
|
7960
7960
|
if (!bindingIdentifier) return false;
|
|
@@ -7963,12 +7963,12 @@ const isReactUseObjectBindingElement = (bindingElement) => {
|
|
|
7963
7963
|
};
|
|
7964
7964
|
const isReactRequireCall = (expression) => {
|
|
7965
7965
|
const unwrappedExpression = unwrapExpression(expression);
|
|
7966
|
-
return ts
|
|
7966
|
+
return ts.isCallExpression(unwrappedExpression) && ts.isIdentifier(unwrappedExpression.expression) && unwrappedExpression.expression.text === REQUIRE_IDENTIFIER && unwrappedExpression.arguments.length === 1 && ts.isStringLiteral(unwrappedExpression.arguments[0]) && unwrappedExpression.arguments[0].text === REACT_MODULE_SOURCE;
|
|
7967
7967
|
};
|
|
7968
7968
|
const getModuleSource = (node) => {
|
|
7969
7969
|
let currentNode = node;
|
|
7970
7970
|
while (currentNode) {
|
|
7971
|
-
if (ts
|
|
7971
|
+
if (ts.isImportDeclaration(currentNode) && ts.isStringLiteral(currentNode.moduleSpecifier)) return currentNode.moduleSpecifier.text;
|
|
7972
7972
|
currentNode = currentNode.parent;
|
|
7973
7973
|
}
|
|
7974
7974
|
return null;
|
|
@@ -7985,40 +7985,40 @@ const isReactObjectBindingName = (bindingPattern, identifierName) => bindingPatt
|
|
|
7985
7985
|
return isReactUseObjectBindingElement(bindingElement);
|
|
7986
7986
|
});
|
|
7987
7987
|
const isReactRequireBindingDeclaration = (node, identifierName) => {
|
|
7988
|
-
if (!ts
|
|
7988
|
+
if (!ts.isVariableDeclaration(node)) return false;
|
|
7989
7989
|
if (!node.initializer) return false;
|
|
7990
7990
|
if (!isReactRequireCall(node.initializer)) return false;
|
|
7991
|
-
if (ts
|
|
7992
|
-
return ts
|
|
7991
|
+
if (ts.isIdentifier(node.name)) return node.name.text === identifierName;
|
|
7992
|
+
return ts.isObjectBindingPattern(node.name) && isReactObjectBindingName(node.name, identifierName);
|
|
7993
7993
|
};
|
|
7994
7994
|
const collectReactImportBindings = (sourceFile) => {
|
|
7995
7995
|
const namespaceNames = /* @__PURE__ */ new Set();
|
|
7996
7996
|
const useImportNames = /* @__PURE__ */ new Set();
|
|
7997
7997
|
for (const statement of sourceFile.statements) {
|
|
7998
|
-
if (ts
|
|
7999
|
-
if (!ts
|
|
7998
|
+
if (ts.isImportDeclaration(statement)) {
|
|
7999
|
+
if (!ts.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
8000
8000
|
if (statement.moduleSpecifier.text !== REACT_MODULE_SOURCE) continue;
|
|
8001
8001
|
const importClause = statement.importClause;
|
|
8002
8002
|
if (!importClause) continue;
|
|
8003
8003
|
if (importClause.name) namespaceNames.add(importClause.name.text);
|
|
8004
8004
|
const namedBindings = importClause.namedBindings;
|
|
8005
8005
|
if (!namedBindings) continue;
|
|
8006
|
-
if (ts
|
|
8006
|
+
if (ts.isNamespaceImport(namedBindings)) {
|
|
8007
8007
|
namespaceNames.add(namedBindings.name.text);
|
|
8008
8008
|
continue;
|
|
8009
8009
|
}
|
|
8010
8010
|
for (const importSpecifier of namedBindings.elements) if (getImportedName(importSpecifier) === USE_IDENTIFIER) useImportNames.add(importSpecifier.name.text);
|
|
8011
8011
|
continue;
|
|
8012
8012
|
}
|
|
8013
|
-
if (!ts
|
|
8013
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
8014
8014
|
for (const declaration of statement.declarationList.declarations) {
|
|
8015
8015
|
if (!declaration.initializer) continue;
|
|
8016
8016
|
if (!isReactRequireCall(declaration.initializer)) continue;
|
|
8017
|
-
if (ts
|
|
8017
|
+
if (ts.isIdentifier(declaration.name)) {
|
|
8018
8018
|
namespaceNames.add(declaration.name.text);
|
|
8019
8019
|
continue;
|
|
8020
8020
|
}
|
|
8021
|
-
if (ts
|
|
8021
|
+
if (ts.isObjectBindingPattern(declaration.name)) collectReactObjectBindingNames(declaration.name, useImportNames);
|
|
8022
8022
|
}
|
|
8023
8023
|
}
|
|
8024
8024
|
return {
|
|
@@ -8029,24 +8029,24 @@ const collectReactImportBindings = (sourceFile) => {
|
|
|
8029
8029
|
const findBindingElement = (identifier) => {
|
|
8030
8030
|
let currentNode = identifier.parent;
|
|
8031
8031
|
while (currentNode) {
|
|
8032
|
-
if (ts
|
|
8033
|
-
if (ts
|
|
8032
|
+
if (ts.isBindingElement(currentNode)) return currentNode;
|
|
8033
|
+
if (ts.isVariableDeclaration(currentNode) || ts.isParameter(currentNode)) return null;
|
|
8034
8034
|
currentNode = currentNode.parent;
|
|
8035
8035
|
}
|
|
8036
8036
|
return null;
|
|
8037
8037
|
};
|
|
8038
8038
|
const declarationBindsIdentifier = (node, identifierName) => {
|
|
8039
|
-
if (ts
|
|
8040
|
-
if (ts
|
|
8039
|
+
if (ts.isVariableDeclaration(node) || ts.isParameter(node)) return bindingNameHasIdentifier(node.name, identifierName);
|
|
8040
|
+
if (ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node)) return node.name?.text === identifierName;
|
|
8041
8041
|
return false;
|
|
8042
8042
|
};
|
|
8043
|
-
const isScopeBoundary = (node) => ts
|
|
8043
|
+
const isScopeBoundary = (node) => ts.isFunctionLike(node) || ts.isClassLike(node) || ts.isBlock(node) || ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node) || ts.isCatchClause(node) || ts.isSourceFile(node) || ts.isModuleBlock(node);
|
|
8044
8044
|
const scopeContainsNonImportBinding = (node, scopeNode, identifierName) => {
|
|
8045
8045
|
if (isReactRequireBindingDeclaration(node, identifierName)) return false;
|
|
8046
8046
|
if (declarationBindsIdentifier(node, identifierName)) return true;
|
|
8047
8047
|
if (node !== scopeNode && isScopeBoundary(node)) return false;
|
|
8048
8048
|
let didFindBinding = false;
|
|
8049
|
-
ts
|
|
8049
|
+
ts.forEachChild(node, (child) => {
|
|
8050
8050
|
if (didFindBinding) return;
|
|
8051
8051
|
didFindBinding = scopeContainsNonImportBinding(child, scopeNode, identifierName);
|
|
8052
8052
|
});
|
|
@@ -8066,26 +8066,26 @@ const isIdentifierShadowedByLocalBinding = (identifier, sourceFile) => {
|
|
|
8066
8066
|
const isReactNamespaceExpression = (expression, reactImportBindings, sourceFile, visitedDeclarations) => {
|
|
8067
8067
|
const unwrappedExpression = unwrapExpression(expression);
|
|
8068
8068
|
if (isReactRequireCall(unwrappedExpression)) return true;
|
|
8069
|
-
if (!ts
|
|
8069
|
+
if (!ts.isIdentifier(unwrappedExpression)) return false;
|
|
8070
8070
|
if (reactImportBindings.namespaceNames.has(unwrappedExpression.text) && !isIdentifierShadowedByLocalBinding(unwrappedExpression, sourceFile)) return true;
|
|
8071
8071
|
return resolveIdentifierBinding(unwrappedExpression, reactImportBindings, sourceFile, visitedDeclarations)?.isReactNamespaceBinding ?? false;
|
|
8072
8072
|
};
|
|
8073
8073
|
const isReactUseExpression = (expression, reactImportBindings, sourceFile, visitedDeclarations) => {
|
|
8074
8074
|
if (!expression) return false;
|
|
8075
8075
|
const unwrappedExpression = unwrapExpression(expression);
|
|
8076
|
-
if (ts
|
|
8076
|
+
if (ts.isIdentifier(unwrappedExpression)) {
|
|
8077
8077
|
if (reactImportBindings.useImportNames.has(unwrappedExpression.text) && !isIdentifierShadowedByLocalBinding(unwrappedExpression, sourceFile)) return true;
|
|
8078
8078
|
if (unwrappedExpression.text === USE_IDENTIFIER) return false;
|
|
8079
8079
|
return resolveIdentifierBinding(unwrappedExpression, reactImportBindings, sourceFile, visitedDeclarations)?.isReactUseBinding ?? false;
|
|
8080
8080
|
}
|
|
8081
|
-
if (ts
|
|
8082
|
-
if (ts
|
|
8081
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === USE_IDENTIFIER && isReactNamespaceExpression(unwrappedExpression.expression, reactImportBindings, sourceFile, visitedDeclarations)) return true;
|
|
8082
|
+
if (ts.isElementAccessExpression(unwrappedExpression) && ts.isStringLiteral(unwrappedExpression.argumentExpression) && unwrappedExpression.argumentExpression.text === USE_IDENTIFIER) return isReactNamespaceExpression(unwrappedExpression.expression, reactImportBindings, sourceFile, visitedDeclarations);
|
|
8083
8083
|
return false;
|
|
8084
8084
|
};
|
|
8085
8085
|
const isReactUseObjectBinding = (identifier, variableDeclaration, reactImportBindings, sourceFile, visitedDeclarations) => {
|
|
8086
8086
|
const bindingElement = findBindingElement(identifier);
|
|
8087
8087
|
if (!bindingElement) return false;
|
|
8088
|
-
if (!ts
|
|
8088
|
+
if (!ts.isObjectBindingPattern(bindingElement.parent)) return false;
|
|
8089
8089
|
if (!variableDeclaration.initializer) return false;
|
|
8090
8090
|
if (!isReactNamespaceExpression(variableDeclaration.initializer, reactImportBindings, sourceFile, visitedDeclarations)) return false;
|
|
8091
8091
|
return isReactUseObjectBindingElement(bindingElement);
|
|
@@ -8097,23 +8097,23 @@ const getVariableDeclarationResolution = (variableDeclaration, identifierName, r
|
|
|
8097
8097
|
const nestedVisitedDeclarations = new Set(visitedDeclarations);
|
|
8098
8098
|
nestedVisitedDeclarations.add(variableDeclaration);
|
|
8099
8099
|
return {
|
|
8100
|
-
isReactNamespaceBinding: ts
|
|
8100
|
+
isReactNamespaceBinding: ts.isIdentifier(variableDeclaration.name) && variableDeclaration.initializer !== void 0 && isReactNamespaceExpression(variableDeclaration.initializer, reactImportBindings, sourceFile, new Set(nestedVisitedDeclarations)),
|
|
8101
8101
|
isReactUseBinding: isReactUseExpression(variableDeclaration.initializer, reactImportBindings, sourceFile, new Set(nestedVisitedDeclarations)) || isReactUseObjectBinding(bindingIdentifier, variableDeclaration, reactImportBindings, sourceFile, new Set(nestedVisitedDeclarations))
|
|
8102
8102
|
};
|
|
8103
8103
|
};
|
|
8104
8104
|
const getImportResolution = (node, identifierName) => {
|
|
8105
|
-
if (ts
|
|
8106
|
-
if (ts
|
|
8107
|
-
if (ts
|
|
8105
|
+
if (ts.isImportSpecifier(node) && node.name.text === identifierName) return getModuleSource(node) === REACT_MODULE_SOURCE && getImportedName(node) === USE_IDENTIFIER ? REACT_USE_BINDING_RESOLUTION : LOCAL_BINDING_RESOLUTION;
|
|
8106
|
+
if (ts.isNamespaceImport(node) && node.name.text === identifierName) return getModuleSource(node) === REACT_MODULE_SOURCE ? REACT_NAMESPACE_BINDING_RESOLUTION : LOCAL_BINDING_RESOLUTION;
|
|
8107
|
+
if (ts.isImportClause(node) && node.name?.text === identifierName) return getModuleSource(node) === REACT_MODULE_SOURCE ? REACT_NAMESPACE_BINDING_RESOLUTION : LOCAL_BINDING_RESOLUTION;
|
|
8108
8108
|
return null;
|
|
8109
8109
|
};
|
|
8110
8110
|
const getDeclarationResolution = (node, identifierName, reactImportBindings, sourceFile, visitedDeclarations) => {
|
|
8111
8111
|
const importResolution = getImportResolution(node, identifierName);
|
|
8112
8112
|
if (importResolution) return importResolution;
|
|
8113
|
-
if (ts
|
|
8114
|
-
if (ts
|
|
8115
|
-
if (ts
|
|
8116
|
-
if (ts
|
|
8113
|
+
if (ts.isVariableDeclaration(node)) return getVariableDeclarationResolution(node, identifierName, reactImportBindings, sourceFile, visitedDeclarations);
|
|
8114
|
+
if (ts.isParameter(node)) return bindingNameHasIdentifier(node.name, identifierName) ? LOCAL_BINDING_RESOLUTION : null;
|
|
8115
|
+
if (ts.isFunctionDeclaration(node) && node.name?.text === identifierName) return LOCAL_BINDING_RESOLUTION;
|
|
8116
|
+
if (ts.isClassDeclaration(node) && node.name?.text === identifierName) return LOCAL_BINDING_RESOLUTION;
|
|
8117
8117
|
return null;
|
|
8118
8118
|
};
|
|
8119
8119
|
const isNestedScopeBoundary = (node, scopeNode) => node !== scopeNode && isScopeBoundary(node);
|
|
@@ -8122,14 +8122,14 @@ const findResolutionInSubtree = (node, scopeNode, identifierName, reactImportBin
|
|
|
8122
8122
|
if (declarationResolution) return declarationResolution;
|
|
8123
8123
|
if (isNestedScopeBoundary(node, scopeNode)) return null;
|
|
8124
8124
|
let resolution = null;
|
|
8125
|
-
ts
|
|
8125
|
+
ts.forEachChild(node, (child) => {
|
|
8126
8126
|
if (resolution) return;
|
|
8127
8127
|
resolution = findResolutionInSubtree(child, scopeNode, identifierName, reactImportBindings, sourceFile, visitedDeclarations);
|
|
8128
8128
|
});
|
|
8129
8129
|
return resolution;
|
|
8130
8130
|
};
|
|
8131
8131
|
const findResolutionInFunctionParameters = (node, identifierName, reactImportBindings) => {
|
|
8132
|
-
if (!ts
|
|
8132
|
+
if (!ts.isFunctionLike(node)) return null;
|
|
8133
8133
|
for (const parameter of node.parameters) {
|
|
8134
8134
|
const parameterResolution = getDeclarationResolution(parameter, identifierName, reactImportBindings, parameter.getSourceFile(), /* @__PURE__ */ new Set());
|
|
8135
8135
|
if (parameterResolution) return parameterResolution;
|
|
@@ -8140,7 +8140,7 @@ const findResolutionInScope = (scopeNode, identifierName, reactImportBindings, s
|
|
|
8140
8140
|
const parameterResolution = findResolutionInFunctionParameters(scopeNode, identifierName, reactImportBindings);
|
|
8141
8141
|
if (parameterResolution) return parameterResolution;
|
|
8142
8142
|
let resolution = null;
|
|
8143
|
-
ts
|
|
8143
|
+
ts.forEachChild(scopeNode, (child) => {
|
|
8144
8144
|
if (resolution) return;
|
|
8145
8145
|
resolution = findResolutionInSubtree(child, scopeNode, identifierName, reactImportBindings, sourceFile, visitedDeclarations);
|
|
8146
8146
|
});
|
|
@@ -8158,22 +8158,22 @@ const resolveIdentifierBinding = (identifier, reactImportBindings, sourceFile, v
|
|
|
8158
8158
|
}
|
|
8159
8159
|
return null;
|
|
8160
8160
|
};
|
|
8161
|
-
const isUseCallIdentifier = (node) => node.text === USE_IDENTIFIER && ts
|
|
8161
|
+
const isUseCallIdentifier = (node) => node.text === USE_IDENTIFIER && ts.isCallExpression(node.parent) && node.parent.expression === node;
|
|
8162
8162
|
const findUseCallIdentifier = (sourceFile, useOffset) => {
|
|
8163
8163
|
let matchedIdentifier = null;
|
|
8164
8164
|
const visit = (node) => {
|
|
8165
8165
|
if (matchedIdentifier) return;
|
|
8166
|
-
if (ts
|
|
8166
|
+
if (ts.isIdentifier(node) && isUseCallIdentifier(node) && node.getStart(sourceFile) === useOffset) {
|
|
8167
8167
|
matchedIdentifier = node;
|
|
8168
8168
|
return;
|
|
8169
8169
|
}
|
|
8170
|
-
ts
|
|
8170
|
+
ts.forEachChild(node, visit);
|
|
8171
8171
|
};
|
|
8172
8172
|
visit(sourceFile);
|
|
8173
8173
|
return matchedIdentifier;
|
|
8174
8174
|
};
|
|
8175
8175
|
const resolveUseCallBinding = (sourceText, filename, utf8Offset) => {
|
|
8176
|
-
const sourceFile = ts
|
|
8176
|
+
const sourceFile = ts.createSourceFile(filename, sourceText, ts.ScriptTarget.Latest, true, getScriptKind(filename));
|
|
8177
8177
|
const useIdentifier = findUseCallIdentifier(sourceFile, getUtf16Offset(sourceText, utf8Offset));
|
|
8178
8178
|
if (!useIdentifier) return null;
|
|
8179
8179
|
return resolveIdentifierBinding(useIdentifier, collectReactImportBindings(sourceFile), sourceFile);
|
|
@@ -12247,7 +12247,7 @@ const handleError = (error, options = { shouldExit: true }) => {
|
|
|
12247
12247
|
};
|
|
12248
12248
|
//#endregion
|
|
12249
12249
|
//#region src/cli/utils/version.ts
|
|
12250
|
-
const VERSION = "0.2.
|
|
12250
|
+
const VERSION = "0.2.3";
|
|
12251
12251
|
//#endregion
|
|
12252
12252
|
//#region src/cli/utils/json-mode.ts
|
|
12253
12253
|
let context = null;
|
|
@@ -12842,6 +12842,6 @@ program.parseAsync().catch((error) => {
|
|
|
12842
12842
|
handleError(error);
|
|
12843
12843
|
});
|
|
12844
12844
|
//#endregion
|
|
12845
|
-
export {
|
|
12845
|
+
export {};
|
|
12846
12846
|
|
|
12847
12847
|
//# sourceMappingURL=cli.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { r as __toESM$1, t as __commonJSMin$1 } from "./chunk-q7NCDQ7-.js";
|
|
2
1
|
import { createRequire } from "node:module";
|
|
3
2
|
import path from "node:path";
|
|
4
3
|
import fs from "node:fs";
|
|
@@ -6,7 +5,30 @@ import { spawn, spawnSync } from "node:child_process";
|
|
|
6
5
|
import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, FRAMEWORK_SPECIFIC_RULE_KEYS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES } from "oxlint-plugin-react-doctor";
|
|
7
6
|
import { gzipSync } from "node:zlib";
|
|
8
7
|
import os from "node:os";
|
|
9
|
-
import * as ts
|
|
8
|
+
import * as ts from "typescript";
|
|
9
|
+
//#region \0rolldown/runtime.js
|
|
10
|
+
var __create$1 = Object.create;
|
|
11
|
+
var __defProp$1 = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames$1 = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf$1 = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __commonJSMin$1 = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
17
|
+
var __copyProps$1 = (to, from, except, desc) => {
|
|
18
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames$1(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
19
|
+
key = keys[i];
|
|
20
|
+
if (!__hasOwnProp$1.call(to, key) && key !== except) __defProp$1(to, key, {
|
|
21
|
+
get: ((k) => from[k]).bind(null, key),
|
|
22
|
+
enumerable: !(desc = __getOwnPropDesc$1(from, key)) || desc.enumerable
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toESM$1 = (mod, isNodeMode, target) => (target = mod != null ? __create$1(__getProtoOf$1(mod)) : {}, __copyProps$1(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", {
|
|
28
|
+
value: mod,
|
|
29
|
+
enumerable: true
|
|
30
|
+
}) : target, mod));
|
|
31
|
+
//#endregion
|
|
10
32
|
//#region ../types/dist/index.js
|
|
11
33
|
const REACT_NATIVE_DEPENDENCY_NAMES = new Set([
|
|
12
34
|
"react-native",
|
|
@@ -3647,7 +3669,7 @@ const toRelativeFilePath = (rootDirectory, filePath) => {
|
|
|
3647
3669
|
const checkDeadCode = async (options) => {
|
|
3648
3670
|
const { rootDirectory, userConfig } = options;
|
|
3649
3671
|
if (!fs.existsSync(path.join(rootDirectory, "package.json"))) return [];
|
|
3650
|
-
const { analyze, defineConfig } = await import("
|
|
3672
|
+
const { analyze, defineConfig } = await import("deslop-js");
|
|
3651
3673
|
const ignorePatterns = collectDeadCodeIgnorePatterns(rootDirectory, userConfig);
|
|
3652
3674
|
const result = await analyze(defineConfig({
|
|
3653
3675
|
rootDir: rootDirectory,
|
|
@@ -4776,43 +4798,43 @@ const REACT_USE_BINDING_RESOLUTION = {
|
|
|
4776
4798
|
isReactNamespaceBinding: false
|
|
4777
4799
|
};
|
|
4778
4800
|
const getScriptKind = (filename) => {
|
|
4779
|
-
if (filename.endsWith(".tsx")) return ts
|
|
4780
|
-
if (filename.endsWith(".jsx")) return ts
|
|
4781
|
-
if (filename.endsWith(".ts")) return ts
|
|
4782
|
-
return ts
|
|
4801
|
+
if (filename.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
4802
|
+
if (filename.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
4803
|
+
if (filename.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
4804
|
+
return ts.ScriptKind.JS;
|
|
4783
4805
|
};
|
|
4784
4806
|
const getUtf16Offset = (sourceText, utf8Offset) => Buffer.from(sourceText).subarray(0, utf8Offset).toString("utf8").length;
|
|
4785
4807
|
const unwrapExpression = (expression) => {
|
|
4786
4808
|
let currentExpression = expression;
|
|
4787
|
-
while (ts
|
|
4809
|
+
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
4788
4810
|
return currentExpression;
|
|
4789
4811
|
};
|
|
4790
4812
|
const getStaticPropertyName = (node) => {
|
|
4791
4813
|
if (!node) return null;
|
|
4792
|
-
if (ts
|
|
4793
|
-
if (ts
|
|
4814
|
+
if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node)) return node.text;
|
|
4815
|
+
if (ts.isComputedPropertyName(node)) {
|
|
4794
4816
|
const expression = unwrapExpression(node.expression);
|
|
4795
|
-
if (ts
|
|
4817
|
+
if (ts.isStringLiteral(expression) || ts.isNoSubstitutionTemplateLiteral(expression)) return expression.text;
|
|
4796
4818
|
}
|
|
4797
4819
|
return null;
|
|
4798
4820
|
};
|
|
4799
4821
|
const findBindingIdentifier = (bindingName, identifierName) => {
|
|
4800
|
-
if (ts
|
|
4822
|
+
if (ts.isIdentifier(bindingName)) return bindingName.text === identifierName ? bindingName : null;
|
|
4801
4823
|
for (const element of bindingName.elements) {
|
|
4802
|
-
if (ts
|
|
4824
|
+
if (ts.isOmittedExpression(element)) continue;
|
|
4803
4825
|
const nestedIdentifier = findBindingIdentifier(element.name, identifierName);
|
|
4804
4826
|
if (nestedIdentifier) return nestedIdentifier;
|
|
4805
4827
|
}
|
|
4806
4828
|
return null;
|
|
4807
4829
|
};
|
|
4808
4830
|
const bindingNameHasIdentifier = (bindingName, identifierName) => {
|
|
4809
|
-
if (ts
|
|
4831
|
+
if (ts.isIdentifier(bindingName)) return bindingName.text === identifierName;
|
|
4810
4832
|
return bindingName.elements.some((element) => {
|
|
4811
|
-
if (ts
|
|
4833
|
+
if (ts.isOmittedExpression(element)) return false;
|
|
4812
4834
|
return bindingNameHasIdentifier(element.name, identifierName);
|
|
4813
4835
|
});
|
|
4814
4836
|
};
|
|
4815
|
-
const getDirectBindingIdentifier = (bindingName) => ts
|
|
4837
|
+
const getDirectBindingIdentifier = (bindingName) => ts.isIdentifier(bindingName) ? bindingName : null;
|
|
4816
4838
|
const isReactUseObjectBindingElement = (bindingElement) => {
|
|
4817
4839
|
const bindingIdentifier = getDirectBindingIdentifier(bindingElement.name);
|
|
4818
4840
|
if (!bindingIdentifier) return false;
|
|
@@ -4821,12 +4843,12 @@ const isReactUseObjectBindingElement = (bindingElement) => {
|
|
|
4821
4843
|
};
|
|
4822
4844
|
const isReactRequireCall = (expression) => {
|
|
4823
4845
|
const unwrappedExpression = unwrapExpression(expression);
|
|
4824
|
-
return ts
|
|
4846
|
+
return ts.isCallExpression(unwrappedExpression) && ts.isIdentifier(unwrappedExpression.expression) && unwrappedExpression.expression.text === REQUIRE_IDENTIFIER && unwrappedExpression.arguments.length === 1 && ts.isStringLiteral(unwrappedExpression.arguments[0]) && unwrappedExpression.arguments[0].text === REACT_MODULE_SOURCE;
|
|
4825
4847
|
};
|
|
4826
4848
|
const getModuleSource = (node) => {
|
|
4827
4849
|
let currentNode = node;
|
|
4828
4850
|
while (currentNode) {
|
|
4829
|
-
if (ts
|
|
4851
|
+
if (ts.isImportDeclaration(currentNode) && ts.isStringLiteral(currentNode.moduleSpecifier)) return currentNode.moduleSpecifier.text;
|
|
4830
4852
|
currentNode = currentNode.parent;
|
|
4831
4853
|
}
|
|
4832
4854
|
return null;
|
|
@@ -4843,40 +4865,40 @@ const isReactObjectBindingName = (bindingPattern, identifierName) => bindingPatt
|
|
|
4843
4865
|
return isReactUseObjectBindingElement(bindingElement);
|
|
4844
4866
|
});
|
|
4845
4867
|
const isReactRequireBindingDeclaration = (node, identifierName) => {
|
|
4846
|
-
if (!ts
|
|
4868
|
+
if (!ts.isVariableDeclaration(node)) return false;
|
|
4847
4869
|
if (!node.initializer) return false;
|
|
4848
4870
|
if (!isReactRequireCall(node.initializer)) return false;
|
|
4849
|
-
if (ts
|
|
4850
|
-
return ts
|
|
4871
|
+
if (ts.isIdentifier(node.name)) return node.name.text === identifierName;
|
|
4872
|
+
return ts.isObjectBindingPattern(node.name) && isReactObjectBindingName(node.name, identifierName);
|
|
4851
4873
|
};
|
|
4852
4874
|
const collectReactImportBindings = (sourceFile) => {
|
|
4853
4875
|
const namespaceNames = /* @__PURE__ */ new Set();
|
|
4854
4876
|
const useImportNames = /* @__PURE__ */ new Set();
|
|
4855
4877
|
for (const statement of sourceFile.statements) {
|
|
4856
|
-
if (ts
|
|
4857
|
-
if (!ts
|
|
4878
|
+
if (ts.isImportDeclaration(statement)) {
|
|
4879
|
+
if (!ts.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
4858
4880
|
if (statement.moduleSpecifier.text !== REACT_MODULE_SOURCE) continue;
|
|
4859
4881
|
const importClause = statement.importClause;
|
|
4860
4882
|
if (!importClause) continue;
|
|
4861
4883
|
if (importClause.name) namespaceNames.add(importClause.name.text);
|
|
4862
4884
|
const namedBindings = importClause.namedBindings;
|
|
4863
4885
|
if (!namedBindings) continue;
|
|
4864
|
-
if (ts
|
|
4886
|
+
if (ts.isNamespaceImport(namedBindings)) {
|
|
4865
4887
|
namespaceNames.add(namedBindings.name.text);
|
|
4866
4888
|
continue;
|
|
4867
4889
|
}
|
|
4868
4890
|
for (const importSpecifier of namedBindings.elements) if (getImportedName(importSpecifier) === USE_IDENTIFIER) useImportNames.add(importSpecifier.name.text);
|
|
4869
4891
|
continue;
|
|
4870
4892
|
}
|
|
4871
|
-
if (!ts
|
|
4893
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
4872
4894
|
for (const declaration of statement.declarationList.declarations) {
|
|
4873
4895
|
if (!declaration.initializer) continue;
|
|
4874
4896
|
if (!isReactRequireCall(declaration.initializer)) continue;
|
|
4875
|
-
if (ts
|
|
4897
|
+
if (ts.isIdentifier(declaration.name)) {
|
|
4876
4898
|
namespaceNames.add(declaration.name.text);
|
|
4877
4899
|
continue;
|
|
4878
4900
|
}
|
|
4879
|
-
if (ts
|
|
4901
|
+
if (ts.isObjectBindingPattern(declaration.name)) collectReactObjectBindingNames(declaration.name, useImportNames);
|
|
4880
4902
|
}
|
|
4881
4903
|
}
|
|
4882
4904
|
return {
|
|
@@ -4887,24 +4909,24 @@ const collectReactImportBindings = (sourceFile) => {
|
|
|
4887
4909
|
const findBindingElement = (identifier) => {
|
|
4888
4910
|
let currentNode = identifier.parent;
|
|
4889
4911
|
while (currentNode) {
|
|
4890
|
-
if (ts
|
|
4891
|
-
if (ts
|
|
4912
|
+
if (ts.isBindingElement(currentNode)) return currentNode;
|
|
4913
|
+
if (ts.isVariableDeclaration(currentNode) || ts.isParameter(currentNode)) return null;
|
|
4892
4914
|
currentNode = currentNode.parent;
|
|
4893
4915
|
}
|
|
4894
4916
|
return null;
|
|
4895
4917
|
};
|
|
4896
4918
|
const declarationBindsIdentifier = (node, identifierName) => {
|
|
4897
|
-
if (ts
|
|
4898
|
-
if (ts
|
|
4919
|
+
if (ts.isVariableDeclaration(node) || ts.isParameter(node)) return bindingNameHasIdentifier(node.name, identifierName);
|
|
4920
|
+
if (ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node)) return node.name?.text === identifierName;
|
|
4899
4921
|
return false;
|
|
4900
4922
|
};
|
|
4901
|
-
const isScopeBoundary = (node) => ts
|
|
4923
|
+
const isScopeBoundary = (node) => ts.isFunctionLike(node) || ts.isClassLike(node) || ts.isBlock(node) || ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node) || ts.isCatchClause(node) || ts.isSourceFile(node) || ts.isModuleBlock(node);
|
|
4902
4924
|
const scopeContainsNonImportBinding = (node, scopeNode, identifierName) => {
|
|
4903
4925
|
if (isReactRequireBindingDeclaration(node, identifierName)) return false;
|
|
4904
4926
|
if (declarationBindsIdentifier(node, identifierName)) return true;
|
|
4905
4927
|
if (node !== scopeNode && isScopeBoundary(node)) return false;
|
|
4906
4928
|
let didFindBinding = false;
|
|
4907
|
-
ts
|
|
4929
|
+
ts.forEachChild(node, (child) => {
|
|
4908
4930
|
if (didFindBinding) return;
|
|
4909
4931
|
didFindBinding = scopeContainsNonImportBinding(child, scopeNode, identifierName);
|
|
4910
4932
|
});
|
|
@@ -4924,26 +4946,26 @@ const isIdentifierShadowedByLocalBinding = (identifier, sourceFile) => {
|
|
|
4924
4946
|
const isReactNamespaceExpression = (expression, reactImportBindings, sourceFile, visitedDeclarations) => {
|
|
4925
4947
|
const unwrappedExpression = unwrapExpression(expression);
|
|
4926
4948
|
if (isReactRequireCall(unwrappedExpression)) return true;
|
|
4927
|
-
if (!ts
|
|
4949
|
+
if (!ts.isIdentifier(unwrappedExpression)) return false;
|
|
4928
4950
|
if (reactImportBindings.namespaceNames.has(unwrappedExpression.text) && !isIdentifierShadowedByLocalBinding(unwrappedExpression, sourceFile)) return true;
|
|
4929
4951
|
return resolveIdentifierBinding(unwrappedExpression, reactImportBindings, sourceFile, visitedDeclarations)?.isReactNamespaceBinding ?? false;
|
|
4930
4952
|
};
|
|
4931
4953
|
const isReactUseExpression = (expression, reactImportBindings, sourceFile, visitedDeclarations) => {
|
|
4932
4954
|
if (!expression) return false;
|
|
4933
4955
|
const unwrappedExpression = unwrapExpression(expression);
|
|
4934
|
-
if (ts
|
|
4956
|
+
if (ts.isIdentifier(unwrappedExpression)) {
|
|
4935
4957
|
if (reactImportBindings.useImportNames.has(unwrappedExpression.text) && !isIdentifierShadowedByLocalBinding(unwrappedExpression, sourceFile)) return true;
|
|
4936
4958
|
if (unwrappedExpression.text === USE_IDENTIFIER) return false;
|
|
4937
4959
|
return resolveIdentifierBinding(unwrappedExpression, reactImportBindings, sourceFile, visitedDeclarations)?.isReactUseBinding ?? false;
|
|
4938
4960
|
}
|
|
4939
|
-
if (ts
|
|
4940
|
-
if (ts
|
|
4961
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === USE_IDENTIFIER && isReactNamespaceExpression(unwrappedExpression.expression, reactImportBindings, sourceFile, visitedDeclarations)) return true;
|
|
4962
|
+
if (ts.isElementAccessExpression(unwrappedExpression) && ts.isStringLiteral(unwrappedExpression.argumentExpression) && unwrappedExpression.argumentExpression.text === USE_IDENTIFIER) return isReactNamespaceExpression(unwrappedExpression.expression, reactImportBindings, sourceFile, visitedDeclarations);
|
|
4941
4963
|
return false;
|
|
4942
4964
|
};
|
|
4943
4965
|
const isReactUseObjectBinding = (identifier, variableDeclaration, reactImportBindings, sourceFile, visitedDeclarations) => {
|
|
4944
4966
|
const bindingElement = findBindingElement(identifier);
|
|
4945
4967
|
if (!bindingElement) return false;
|
|
4946
|
-
if (!ts
|
|
4968
|
+
if (!ts.isObjectBindingPattern(bindingElement.parent)) return false;
|
|
4947
4969
|
if (!variableDeclaration.initializer) return false;
|
|
4948
4970
|
if (!isReactNamespaceExpression(variableDeclaration.initializer, reactImportBindings, sourceFile, visitedDeclarations)) return false;
|
|
4949
4971
|
return isReactUseObjectBindingElement(bindingElement);
|
|
@@ -4955,23 +4977,23 @@ const getVariableDeclarationResolution = (variableDeclaration, identifierName, r
|
|
|
4955
4977
|
const nestedVisitedDeclarations = new Set(visitedDeclarations);
|
|
4956
4978
|
nestedVisitedDeclarations.add(variableDeclaration);
|
|
4957
4979
|
return {
|
|
4958
|
-
isReactNamespaceBinding: ts
|
|
4980
|
+
isReactNamespaceBinding: ts.isIdentifier(variableDeclaration.name) && variableDeclaration.initializer !== void 0 && isReactNamespaceExpression(variableDeclaration.initializer, reactImportBindings, sourceFile, new Set(nestedVisitedDeclarations)),
|
|
4959
4981
|
isReactUseBinding: isReactUseExpression(variableDeclaration.initializer, reactImportBindings, sourceFile, new Set(nestedVisitedDeclarations)) || isReactUseObjectBinding(bindingIdentifier, variableDeclaration, reactImportBindings, sourceFile, new Set(nestedVisitedDeclarations))
|
|
4960
4982
|
};
|
|
4961
4983
|
};
|
|
4962
4984
|
const getImportResolution = (node, identifierName) => {
|
|
4963
|
-
if (ts
|
|
4964
|
-
if (ts
|
|
4965
|
-
if (ts
|
|
4985
|
+
if (ts.isImportSpecifier(node) && node.name.text === identifierName) return getModuleSource(node) === REACT_MODULE_SOURCE && getImportedName(node) === USE_IDENTIFIER ? REACT_USE_BINDING_RESOLUTION : LOCAL_BINDING_RESOLUTION;
|
|
4986
|
+
if (ts.isNamespaceImport(node) && node.name.text === identifierName) return getModuleSource(node) === REACT_MODULE_SOURCE ? REACT_NAMESPACE_BINDING_RESOLUTION : LOCAL_BINDING_RESOLUTION;
|
|
4987
|
+
if (ts.isImportClause(node) && node.name?.text === identifierName) return getModuleSource(node) === REACT_MODULE_SOURCE ? REACT_NAMESPACE_BINDING_RESOLUTION : LOCAL_BINDING_RESOLUTION;
|
|
4966
4988
|
return null;
|
|
4967
4989
|
};
|
|
4968
4990
|
const getDeclarationResolution = (node, identifierName, reactImportBindings, sourceFile, visitedDeclarations) => {
|
|
4969
4991
|
const importResolution = getImportResolution(node, identifierName);
|
|
4970
4992
|
if (importResolution) return importResolution;
|
|
4971
|
-
if (ts
|
|
4972
|
-
if (ts
|
|
4973
|
-
if (ts
|
|
4974
|
-
if (ts
|
|
4993
|
+
if (ts.isVariableDeclaration(node)) return getVariableDeclarationResolution(node, identifierName, reactImportBindings, sourceFile, visitedDeclarations);
|
|
4994
|
+
if (ts.isParameter(node)) return bindingNameHasIdentifier(node.name, identifierName) ? LOCAL_BINDING_RESOLUTION : null;
|
|
4995
|
+
if (ts.isFunctionDeclaration(node) && node.name?.text === identifierName) return LOCAL_BINDING_RESOLUTION;
|
|
4996
|
+
if (ts.isClassDeclaration(node) && node.name?.text === identifierName) return LOCAL_BINDING_RESOLUTION;
|
|
4975
4997
|
return null;
|
|
4976
4998
|
};
|
|
4977
4999
|
const isNestedScopeBoundary = (node, scopeNode) => node !== scopeNode && isScopeBoundary(node);
|
|
@@ -4980,14 +5002,14 @@ const findResolutionInSubtree = (node, scopeNode, identifierName, reactImportBin
|
|
|
4980
5002
|
if (declarationResolution) return declarationResolution;
|
|
4981
5003
|
if (isNestedScopeBoundary(node, scopeNode)) return null;
|
|
4982
5004
|
let resolution = null;
|
|
4983
|
-
ts
|
|
5005
|
+
ts.forEachChild(node, (child) => {
|
|
4984
5006
|
if (resolution) return;
|
|
4985
5007
|
resolution = findResolutionInSubtree(child, scopeNode, identifierName, reactImportBindings, sourceFile, visitedDeclarations);
|
|
4986
5008
|
});
|
|
4987
5009
|
return resolution;
|
|
4988
5010
|
};
|
|
4989
5011
|
const findResolutionInFunctionParameters = (node, identifierName, reactImportBindings) => {
|
|
4990
|
-
if (!ts
|
|
5012
|
+
if (!ts.isFunctionLike(node)) return null;
|
|
4991
5013
|
for (const parameter of node.parameters) {
|
|
4992
5014
|
const parameterResolution = getDeclarationResolution(parameter, identifierName, reactImportBindings, parameter.getSourceFile(), /* @__PURE__ */ new Set());
|
|
4993
5015
|
if (parameterResolution) return parameterResolution;
|
|
@@ -4998,7 +5020,7 @@ const findResolutionInScope = (scopeNode, identifierName, reactImportBindings, s
|
|
|
4998
5020
|
const parameterResolution = findResolutionInFunctionParameters(scopeNode, identifierName, reactImportBindings);
|
|
4999
5021
|
if (parameterResolution) return parameterResolution;
|
|
5000
5022
|
let resolution = null;
|
|
5001
|
-
ts
|
|
5023
|
+
ts.forEachChild(scopeNode, (child) => {
|
|
5002
5024
|
if (resolution) return;
|
|
5003
5025
|
resolution = findResolutionInSubtree(child, scopeNode, identifierName, reactImportBindings, sourceFile, visitedDeclarations);
|
|
5004
5026
|
});
|
|
@@ -5016,22 +5038,22 @@ const resolveIdentifierBinding = (identifier, reactImportBindings, sourceFile, v
|
|
|
5016
5038
|
}
|
|
5017
5039
|
return null;
|
|
5018
5040
|
};
|
|
5019
|
-
const isUseCallIdentifier = (node) => node.text === USE_IDENTIFIER && ts
|
|
5041
|
+
const isUseCallIdentifier = (node) => node.text === USE_IDENTIFIER && ts.isCallExpression(node.parent) && node.parent.expression === node;
|
|
5020
5042
|
const findUseCallIdentifier = (sourceFile, useOffset) => {
|
|
5021
5043
|
let matchedIdentifier = null;
|
|
5022
5044
|
const visit = (node) => {
|
|
5023
5045
|
if (matchedIdentifier) return;
|
|
5024
|
-
if (ts
|
|
5046
|
+
if (ts.isIdentifier(node) && isUseCallIdentifier(node) && node.getStart(sourceFile) === useOffset) {
|
|
5025
5047
|
matchedIdentifier = node;
|
|
5026
5048
|
return;
|
|
5027
5049
|
}
|
|
5028
|
-
ts
|
|
5050
|
+
ts.forEachChild(node, visit);
|
|
5029
5051
|
};
|
|
5030
5052
|
visit(sourceFile);
|
|
5031
5053
|
return matchedIdentifier;
|
|
5032
5054
|
};
|
|
5033
5055
|
const resolveUseCallBinding = (sourceText, filename, utf8Offset) => {
|
|
5034
|
-
const sourceFile = ts
|
|
5056
|
+
const sourceFile = ts.createSourceFile(filename, sourceText, ts.ScriptTarget.Latest, true, getScriptKind(filename));
|
|
5035
5057
|
const useIdentifier = findUseCallIdentifier(sourceFile, getUtf16Offset(sourceText, utf8Offset));
|
|
5036
5058
|
if (!useIdentifier) return null;
|
|
5037
5059
|
return resolveIdentifierBinding(useIdentifier, collectReactImportBindings(sourceFile), sourceFile);
|