@rushstack/eslint-plugin-packlets
Advanced tools
Comparing version 0.2.1 to 0.2.2
@@ -5,2 +5,14 @@ { | ||
{ | ||
"version": "0.2.2", | ||
"tag": "@rushstack/eslint-plugin-packlets_v0.2.2", | ||
"date": "Mon, 12 Apr 2021 15:10:28 GMT", | ||
"comments": { | ||
"patch": [ | ||
{ | ||
"comment": "Fix an issue where the @rushstack/packlets/circular-deps rule did not work correctly with TypeScript 4.2" | ||
} | ||
] | ||
} | ||
}, | ||
{ | ||
"version": "0.2.1", | ||
@@ -7,0 +19,0 @@ "tag": "@rushstack/eslint-plugin-packlets_v0.2.1", |
# Change Log - @rushstack/eslint-plugin-packlets | ||
This log was last generated on Tue, 06 Apr 2021 15:14:22 GMT and should not be manually modified. | ||
This log was last generated on Mon, 12 Apr 2021 15:10:28 GMT and should not be manually modified. | ||
## 0.2.2 | ||
Mon, 12 Apr 2021 15:10:28 GMT | ||
### Patches | ||
- Fix an issue where the @rushstack/packlets/circular-deps rule did not work correctly with TypeScript 4.2 | ||
## 0.2.1 | ||
@@ -6,0 +13,0 @@ Tue, 06 Apr 2021 15:14:22 GMT |
@@ -22,2 +22,3 @@ import type * as ts from 'typescript'; | ||
* @param refFileMap - the compiler's `refFileMap` data structure describing import relationships | ||
* @param fileIncludeReasonsMap - the compiler's data structure describing import relationships | ||
* @param program - the compiler's `ts.Program` object | ||
@@ -24,0 +25,0 @@ * @param packletsFolderPath - the absolute path of the "src/packlets" folder. |
@@ -13,2 +13,17 @@ "use strict"; | ||
})(RefFileKind || (RefFileKind = {})); | ||
// TypeScript compiler internal: | ||
// Version range: > 4.2.0 | ||
// https://github.com/microsoft/TypeScript/blob/2eca17d7c1a3fb2b077f3a910d5019d74b6f07a0/src/compiler/types.ts#L3693 | ||
var FileIncludeKind; | ||
(function (FileIncludeKind) { | ||
FileIncludeKind[FileIncludeKind["RootFile"] = 0] = "RootFile"; | ||
FileIncludeKind[FileIncludeKind["SourceFromProjectReference"] = 1] = "SourceFromProjectReference"; | ||
FileIncludeKind[FileIncludeKind["OutputFromProjectReference"] = 2] = "OutputFromProjectReference"; | ||
FileIncludeKind[FileIncludeKind["Import"] = 3] = "Import"; | ||
FileIncludeKind[FileIncludeKind["ReferenceFile"] = 4] = "ReferenceFile"; | ||
FileIncludeKind[FileIncludeKind["TypeReferenceDirective"] = 5] = "TypeReferenceDirective"; | ||
FileIncludeKind[FileIncludeKind["LibFile"] = 6] = "LibFile"; | ||
FileIncludeKind[FileIncludeKind["LibReferenceDirective"] = 7] = "LibReferenceDirective"; | ||
FileIncludeKind[FileIncludeKind["AutomaticTypeDirectiveFile"] = 8] = "AutomaticTypeDirectiveFile"; | ||
})(FileIncludeKind || (FileIncludeKind = {})); | ||
class DependencyAnalyzer { | ||
@@ -20,2 +35,3 @@ /** | ||
* @param refFileMap - the compiler's `refFileMap` data structure describing import relationships | ||
* @param fileIncludeReasonsMap - the compiler's data structure describing import relationships | ||
* @param program - the compiler's `ts.Program` object | ||
@@ -26,3 +42,3 @@ * @param packletsFolderPath - the absolute path of the "src/packlets" folder. | ||
*/ | ||
static _walkImports(packletName, startingPackletName, refFileMap, program, packletsFolderPath, visitedPacklets, previousNode) { | ||
static _walkImports(packletName, startingPackletName, refFileMap, fileIncludeReasonsMap, program, packletsFolderPath, visitedPacklets, previousNode) { | ||
visitedPacklets.add(packletName); | ||
@@ -34,32 +50,38 @@ const packletEntryPoint = Path_1.Path.join(packletsFolderPath, packletName, 'index'); | ||
} | ||
const refFiles = refFileMap.get(tsSourceFile.path); | ||
if (!refFiles) { | ||
return undefined; | ||
const referencingFilePaths = []; | ||
if (refFileMap) { | ||
// TypeScript version range: >= 3.6.0, <= 4.2.0 | ||
const refFiles = refFileMap.get(tsSourceFile.path); | ||
if (refFiles) { | ||
for (const refFile of refFiles) { | ||
if (refFile.kind === RefFileKind.Import) { | ||
referencingFilePaths.push(refFile.file); | ||
} | ||
} | ||
} | ||
} | ||
for (const refFile of refFiles) { | ||
if (refFile.kind === RefFileKind.Import) { | ||
const referencingFilePath = refFile.file; | ||
// Is it a reference to a packlet? | ||
if (Path_1.Path.isUnder(referencingFilePath, packletsFolderPath)) { | ||
const referencingRelativePath = Path_1.Path.relative(packletsFolderPath, referencingFilePath); | ||
const referencingPathParts = referencingRelativePath.split(/[\/\\]+/); | ||
const referencingPackletName = referencingPathParts[0]; | ||
// Did we return to where we started from? | ||
if (referencingPackletName === startingPackletName) { | ||
// Ignore the degenerate case where the starting node imports itself, | ||
// since @rushstack/packlets/mechanics will already report that. | ||
if (previousNode) { | ||
// Make a new linked list node to record this step of the traversal | ||
const importListNode = { | ||
previousNode: previousNode, | ||
fromFilePath: referencingFilePath, | ||
packletName: packletName | ||
}; | ||
// The traversal has returned to the packlet that we started from; | ||
// this means we have detected a circular dependency | ||
return importListNode; | ||
else if (fileIncludeReasonsMap) { | ||
// Typescript version range: > 4.2.0 | ||
const fileIncludeReasons = fileIncludeReasonsMap.get(tsSourceFile.path); | ||
if (fileIncludeReasons) { | ||
for (const fileIncludeReason of fileIncludeReasons) { | ||
if (fileIncludeReason.kind === FileIncludeKind.Import) { | ||
if (fileIncludeReason.file) { | ||
referencingFilePaths.push(fileIncludeReason.file); | ||
} | ||
} | ||
// Have we already analyzed this packlet? | ||
if (!visitedPacklets.has(referencingPackletName)) { | ||
} | ||
} | ||
} | ||
for (const referencingFilePath of referencingFilePaths) { | ||
// Is it a reference to a packlet? | ||
if (Path_1.Path.isUnder(referencingFilePath, packletsFolderPath)) { | ||
const referencingRelativePath = Path_1.Path.relative(packletsFolderPath, referencingFilePath); | ||
const referencingPathParts = referencingRelativePath.split(/[\/\\]+/); | ||
const referencingPackletName = referencingPathParts[0]; | ||
// Did we return to where we started from? | ||
if (referencingPackletName === startingPackletName) { | ||
// Ignore the degenerate case where the starting node imports itself, | ||
// since @rushstack/packlets/mechanics will already report that. | ||
if (previousNode) { | ||
// Make a new linked list node to record this step of the traversal | ||
@@ -71,8 +93,20 @@ const importListNode = { | ||
}; | ||
const result = DependencyAnalyzer._walkImports(referencingPackletName, startingPackletName, refFileMap, program, packletsFolderPath, visitedPacklets, importListNode); | ||
if (result) { | ||
return result; | ||
} | ||
// The traversal has returned to the packlet that we started from; | ||
// this means we have detected a circular dependency | ||
return importListNode; | ||
} | ||
} | ||
// Have we already analyzed this packlet? | ||
if (!visitedPacklets.has(referencingPackletName)) { | ||
// Make a new linked list node to record this step of the traversal | ||
const importListNode = { | ||
previousNode: previousNode, | ||
fromFilePath: referencingFilePath, | ||
packletName: packletName | ||
}; | ||
const result = DependencyAnalyzer._walkImports(referencingPackletName, startingPackletName, refFileMap, fileIncludeReasonsMap, program, packletsFolderPath, visitedPacklets, importListNode); | ||
if (result) { | ||
return result; | ||
} | ||
} | ||
} | ||
@@ -109,5 +143,20 @@ } | ||
static checkEntryPointForCircularImport(packletName, packletAnalyzer, program) { | ||
const refFileMap = program.getRefFileMap(); | ||
const programInternals = program; | ||
let refFileMap; | ||
let fileIncludeReasonsMap; | ||
if (programInternals.getRefFileMap) { | ||
// TypeScript version range: >= 3.6.0, <= 4.2.0 | ||
refFileMap = programInternals.getRefFileMap(); | ||
} | ||
else if (programInternals.getFileIncludeReasons) { | ||
// Typescript version range: > 4.2.0 | ||
fileIncludeReasonsMap = programInternals.getFileIncludeReasons(); | ||
} | ||
else { | ||
// If you encounter this error, please report a bug | ||
throw new Error('Your TypeScript compiler version is not supported; please upgrade @rushstack/eslint-plugin-packlets' + | ||
' or report a GitHub issue'); | ||
} | ||
const visitedPacklets = new Set(); | ||
const listNode = DependencyAnalyzer._walkImports(packletName, packletName, refFileMap, program, packletAnalyzer.packletsFolderPath, visitedPacklets, undefined // previousNode | ||
const listNode = DependencyAnalyzer._walkImports(packletName, packletName, refFileMap, fileIncludeReasonsMap, program, packletAnalyzer.packletsFolderPath, visitedPacklets, undefined // previousNode | ||
); | ||
@@ -114,0 +163,0 @@ if (listNode) { |
{ | ||
"name": "@rushstack/eslint-plugin-packlets", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "A lightweight alternative to NPM packages for organizing source files within a single project", | ||
@@ -29,4 +29,4 @@ "license": "MIT", | ||
"devDependencies": { | ||
"@rushstack/heft": "0.23.1", | ||
"@rushstack/heft-node-rig": "0.2.0", | ||
"@rushstack/heft": "0.28.0", | ||
"@rushstack/heft-node-rig": "1.0.8", | ||
"@types/eslint": "7.2.0", | ||
@@ -33,0 +33,0 @@ "@types/estree": "0.0.44", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
127438
1095