@rehearsal/ts-utils
Advanced tools
Comparing version 2.0.0-beta to 2.0.0
@@ -11,2 +11,6 @@ import type { TextChange } from 'typescript'; | ||
/** | ||
* Compares two text changes | ||
*/ | ||
export declare function isSameChange(a: TextChange, b: TextChange): boolean; | ||
/** | ||
* Prepares text changes to be applying to file | ||
@@ -13,0 +17,0 @@ * by removing duplicates and sort them backwards to apply from the bottom of the file, |
@@ -20,2 +20,8 @@ /** | ||
/** | ||
* Compares two text changes | ||
*/ | ||
export function isSameChange(a, b) { | ||
return (a.span.start === b.span.start && a.span.length === b.span.length && a.newText === b.newText); | ||
} | ||
/** | ||
* Prepares text changes to be applying to file | ||
@@ -26,3 +32,2 @@ * by removing duplicates and sort them backwards to apply from the bottom of the file, | ||
export function normalizeTextChanges(textChanges) { | ||
const isSameChange = (a, b) => a.span.start === a.span.start && a.span.length === b.span.length && a.newText === b.newText; | ||
// TODO: Probably need to remove overlapping entries, see `normalizeEdits` from `parserharness.ts` of TS source code | ||
@@ -29,0 +34,0 @@ return textChanges |
/** | ||
* This file contains helper functions to work with Typescript AST nodes and diagnostics | ||
*/ | ||
import type { DiagnosticWithLocation, Node, SourceFile, TypeChecker, TypeNode } from 'typescript'; | ||
import type { Node, SourceFile, TypeChecker, TypeNode } from 'typescript'; | ||
/** | ||
@@ -10,6 +10,2 @@ * Checks if node starts with `start` position and its length equals to `length`. | ||
/** | ||
* Checks if node is the node related to diagnostic. | ||
*/ | ||
export declare function isNodeDiagnosed(node: Node, diagnostic: DiagnosticWithLocation): boolean; | ||
/** | ||
* Checks if node is the first in the line. | ||
@@ -23,10 +19,5 @@ * e.g. for the node `revert` of `function revert(...)` the `function` is the first in the line. | ||
*/ | ||
export declare function findNodeAtPosition(sourceFile: SourceFile, start: number, length: number): Node | undefined; | ||
export declare function findNodeAtPosition(sourceFile: SourceFile, start: number, length: number, includeJSDocNodes?: boolean): Node | undefined; | ||
export declare function findNodeEndsAtPosition(sourceFile: SourceFile, pos: number): Node | undefined; | ||
/** | ||
* Finds the first node in the line. | ||
* e.g. in `function revert(...)` the `revert` node has `function` node is the first in the line. | ||
*/ | ||
export declare function findTheFirstParentNodeInTheLine(node: Node): Node; | ||
/** | ||
* Checks if the node is the part of JSX Text (Element or Fragment) | ||
@@ -33,0 +24,0 @@ */ |
@@ -13,8 +13,2 @@ /** | ||
/** | ||
* Checks if node is the node related to diagnostic. | ||
*/ | ||
export function isNodeDiagnosed(node, diagnostic) { | ||
return isNodeAtPosition(node, diagnostic.start, diagnostic.length); | ||
} | ||
/** | ||
* Checks if node is the first in the line. | ||
@@ -36,3 +30,3 @@ * e.g. for the node `revert` of `function revert(...)` the `function` is the first in the line. | ||
*/ | ||
export function findNodeAtPosition(sourceFile, start, length) { | ||
export function findNodeAtPosition(sourceFile, start, length, includeJSDocNodes = false) { | ||
const visitor = (node) => { | ||
@@ -42,5 +36,13 @@ if (isNodeAtPosition(node, start, length)) { | ||
} | ||
if (node.getStart() <= start && node.getEnd() >= start + length) { | ||
return ts.forEachChild(node, visitor); | ||
if (includeJSDocNodes) { | ||
if (node.getFullStart() <= start && node.getEnd() >= start + length) { | ||
const tags = [...ts.getJSDocTags(node)]; | ||
return tags.find((n) => visitor(n)) || ts.forEachChild(node, visitor); | ||
} | ||
} | ||
else { | ||
if (node.getStart() <= start && node.getEnd() >= start + length) { | ||
return ts.forEachChild(node, visitor); | ||
} | ||
} | ||
return undefined; | ||
@@ -64,10 +66,2 @@ }; | ||
/** | ||
* Finds the first node in the line. | ||
* e.g. in `function revert(...)` the `revert` node has `function` node is the first in the line. | ||
*/ | ||
export function findTheFirstParentNodeInTheLine(node) { | ||
const visit = (node) => isTheFirstParentNodeInTheLIne(node) ? node : visit(node.parent); | ||
return visit(node); | ||
} | ||
/** | ||
* Checks if the node is the part of JSX Text (Element or Fragment) | ||
@@ -98,10 +92,18 @@ */ | ||
if (isTypeReferenceNode(typeNode)) { | ||
const type = checker.getTypeFromTypeNode(typeNode); | ||
const typeArguments = typeNode.typeArguments || []; | ||
const isTypeError = (type) => { | ||
// Check if Type can't be resolved | ||
//return (type as unknown as { intrinsicName?: string }).intrinsicName === 'error'; | ||
return type.flags === ts.TypeFlags.Any; | ||
// Checks if the type node can represent come meaningful type | ||
const isTypeNodeStrict = (checker, typeNode) => { | ||
try { | ||
// Try to resolve TypeNode to Type... it possible to trigger and exception in some weired cases | ||
const type = checker.getTypeFromTypeNode(typeNode); | ||
// Check if TypeNode is resolved to a meaningful Type, not any | ||
// Also can be validated with (type as unknown as { intrinsicName?: string }).intrinsicName === 'error'; | ||
return type.flags !== ts.TypeFlags.Any; | ||
} | ||
catch (e) { | ||
return false; | ||
} | ||
}; | ||
return !isTypeError(type) && !typeArguments.find((node) => !canTypeBeResolved(checker, node)); | ||
return (isTypeNodeStrict(checker, typeNode) && | ||
!typeArguments.find((node) => !canTypeBeResolved(checker, node))); | ||
} | ||
@@ -108,0 +110,0 @@ if (ts.isParenthesizedTypeNode(typeNode)) { |
@@ -1,2 +0,2 @@ | ||
export { getInterfaceByName, getTypeAliasByName, getClassByName, getInterfaceMemberByName, getTypeAliasMemberByName, getClassMemberByName, getTypeNameFromType, getTypeNameFromVariable, isSubtypeOf, getTypeDeclarationFromTypeSymbol, isTypeMatched, } from './tsc-utils.js'; | ||
export { getInterfaceByName, getTypeAliasByName, getClassByName, getInterfaceMemberByName, getTypeAliasMemberByName, getClassMemberByName, getTypeNameFromType, getTypeNameFromVariable, isSubtypeOf, getTypeDeclarationFromTypeSymbol, isTypeMatched, getTSConfigCompilerOptionsCanonical, type TSConfigCompilerOptions, } from './tsc-utils.js'; | ||
export * from './helpers/strings.js'; | ||
@@ -3,0 +3,0 @@ export * from './helpers/typescript-ast.js'; |
@@ -1,2 +0,2 @@ | ||
export { getInterfaceByName, getTypeAliasByName, getClassByName, getInterfaceMemberByName, getTypeAliasMemberByName, getClassMemberByName, getTypeNameFromType, getTypeNameFromVariable, isSubtypeOf, getTypeDeclarationFromTypeSymbol, isTypeMatched, } from './tsc-utils.js'; | ||
export { getInterfaceByName, getTypeAliasByName, getClassByName, getInterfaceMemberByName, getTypeAliasMemberByName, getClassMemberByName, getTypeNameFromType, getTypeNameFromVariable, isSubtypeOf, getTypeDeclarationFromTypeSymbol, isTypeMatched, getTSConfigCompilerOptionsCanonical, } from './tsc-utils.js'; | ||
export * from './helpers/strings.js'; | ||
@@ -3,0 +3,0 @@ export * from './helpers/typescript-ast.js'; |
@@ -1,2 +0,3 @@ | ||
import type { ClassDeclaration, ClassElement, InterfaceDeclaration, Node, SourceFile, Type, TypeAliasDeclaration, TypeChecker, TypeElement } from 'typescript'; | ||
import type { ClassDeclaration, ClassElement, InterfaceDeclaration, Node, SourceFile, Type, TypeAliasDeclaration, TypeChecker, TypeElement, CompilerOptions } from 'typescript'; | ||
export type TSConfigCompilerOptions = CompilerOptions; | ||
export declare function getInterfaceByName(sourceFile: SourceFile, typeName: string): InterfaceDeclaration | undefined; | ||
@@ -13,2 +14,3 @@ export declare function getTypeAliasByName(sourceFile: SourceFile, typeName: string): TypeAliasDeclaration | undefined; | ||
export declare function isTypeMatched(typeString: string, type: Type): boolean; | ||
export declare function getTSConfigCompilerOptionsCanonical(basePath: string, tsConfigPath: string): CompilerOptions; | ||
//# sourceMappingURL=tsc-utils.d.ts.map |
import ts from 'typescript'; | ||
const { isClassDeclaration, isInterfaceDeclaration, isTypeAliasDeclaration, SyntaxKind } = ts; | ||
const { parseJsonConfigFileContent, readConfigFile, sys, isClassDeclaration, isInterfaceDeclaration, isTypeAliasDeclaration, SyntaxKind, } = ts; | ||
export function getInterfaceByName(sourceFile, typeName) { | ||
@@ -105,2 +105,8 @@ if (!typeName) { | ||
} | ||
// returns the singular compilerOptions record from all tsconfig.json including extends | ||
export function getTSConfigCompilerOptionsCanonical(basePath, tsConfigPath) { | ||
const configFile = readConfigFile(tsConfigPath, (filePath, encoding) => sys.readFile(filePath, encoding)); | ||
const { options: compilerOptions } = parseJsonConfigFileContent(configFile.config, ts.sys, basePath, {}, 'tsconfig.json'); | ||
return compilerOptions; | ||
} | ||
//# sourceMappingURL=tsc-utils.js.map |
{ | ||
"name": "@rehearsal/ts-utils", | ||
"version": "2.0.0-beta", | ||
"version": "2.0.0", | ||
"description": "Rehearsal TypeScript Utils", | ||
@@ -33,9 +33,9 @@ "keywords": [ | ||
"devDependencies": { | ||
"@vitest/coverage-c8": "^0.30.1", | ||
"vitest": "^0.29.8" | ||
"@vitest/coverage-c8": "^0.33.0", | ||
"vitest": "^0.30.0" | ||
}, | ||
"peerDependencies": { | ||
"typescript": "^5.0" | ||
"typescript": "^5.1.3" | ||
}, | ||
"packageManager": "pnpm@8.2.0", | ||
"packageManager": "pnpm@8.6.7", | ||
"engines": { | ||
@@ -53,3 +53,2 @@ "node": ">=14.16.0" | ||
"test": "vitest --run --coverage", | ||
"test:slow": "vitest --run", | ||
"test:watch": "vitest --coverage --watch", | ||
@@ -56,0 +55,0 @@ "version": "pnpm version" |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
398
1
79871
24