11private import javascript
2- private import semmle.javascript.TSConfig
32private import semmle.javascript.internal.paths.PackageJsonEx
43private import semmle.javascript.internal.paths.JSPaths
4+ private import semmle.javascript.internal.paths.PathMapping
55private import semmle.javascript.internal.paths.PathConcatenation
66private import semmle.javascript.dataflow.internal.DataFlowNode
77
@@ -81,28 +81,11 @@ module ResolveExpr<exprSig/1 shouldResolveExpr> {
8181 }
8282
8383 /**
84- * Gets a tsconfig file to use as fallback for handling paths in `c`.
85- *
86- * This holds for files and folders where no tsconfig seems to include it,
87- * but it has one or more tsconfig files in parent directories.
88- */
89- private TSConfig getFallbackTSConfig ( Container c ) {
90- not c = any ( TSConfig t ) .getAnIncludedContainer ( ) and
91- (
92- c = result .getFolder ( )
93- or
94- result = getFallbackTSConfig ( c .getParentContainer ( ) )
95- )
96- }
97-
98- /**
99- * Gets the TSConfig file relevant for resolving `expr`.
84+ * Gets a path mapping relevant for resolving `expr`.
10085 */
10186 pragma [ nomagic]
102- private TSConfig getTSConfigFromPathExpr ( RelevantExpr expr ) {
103- result .getAnIncludedContainer ( ) = expr .getFile ( )
104- or
105- result = getFallbackTSConfig ( expr .getFile ( ) )
87+ private PathMapping getAPathMappingFromPathExpr ( RelevantExpr expr ) {
88+ result .getAnAffectedFile ( ) = expr .getFile ( )
10689 }
10790
10891 /**
@@ -126,23 +109,23 @@ module ResolveExpr<exprSig/1 shouldResolveExpr> {
126109 */
127110 pragma [ nomagic]
128111 private predicate resolveViaPathMapping ( RelevantExpr expr , Container base , string newPath ) {
129- // Handle tsconfig mappings such as `{ "paths": { "@/*": "./src/*" }}`
130- exists ( TSConfig config , string value |
131- config = getTSConfigFromPathExpr ( expr ) .getExtendedTSConfig * ( ) and
132- value = expr .getValue ( ) and
133- base = config .getBaseUrlFolderOrOwnFolder ( )
112+ // Handle path mappings such as `{ "paths": { "@/*": "./src/*" }}` in a tsconfig.json file
113+ exists ( PathMapping mapping , string value |
114+ mapping = getAPathMappingFromPathExpr ( expr ) and
115+ value = expr .getValue ( )
134116 |
135- config .hasExactPathMapping ( value , newPath )
117+ mapping .hasExactPathMapping ( value , base , newPath )
136118 or
137119 exists ( string pattern , string suffix , string mappedPath |
138- config .hasPrefixPathMapping ( pattern , mappedPath ) and
120+ mapping .hasPrefixPathMapping ( pattern , base , mappedPath ) and
139121 value = pattern + suffix and
140122 newPath = mappedPath + suffix
141123 )
142124 )
143125 or
144126 // Handle imports referring to a package by name, where we have a package.json
145- // file for that package in the codebase.
127+ // file for that package in the codebase. This is treated separately from PathMapping for performance
128+ // reasons, as there can be a large number of packages which affect all files in the project.
146129 //
147130 // This part only handles the "exports" property of package.json. "main" and "modules" are
148131 // handled further down because their semantics are easier to handle there.
@@ -197,7 +180,7 @@ module ResolveExpr<exprSig/1 shouldResolveExpr> {
197180 // Resolve from baseUrl of relevant tsconfig.json file
198181 path = expr .getValue ( ) and
199182 not isRelativePath ( path ) and
200- base = getTSConfigFromPathExpr ( expr ) .getBaseUrlFolder ( )
183+ getAPathMappingFromPathExpr ( expr ) .hasBaseUrl ( base )
201184 or
202185 // If the path starts with the name of a package, but did not match any path mapping,
203186 // resolve relative to the enclosing directory of that package.
@@ -242,10 +225,6 @@ module ResolveExpr<exprSig/1 shouldResolveExpr> {
242225
243226 query PathExprToDebug pathExprs ( ) { any ( ) }
244227
245- query TSConfig getTSConfigFromPathExpr_ ( PathExprToDebug expr ) {
246- result = getTSConfigFromPathExpr ( expr )
247- }
248-
249228 query string getPackagePrefixFromPathExpr_ ( PathExprToDebug expr ) {
250229 result = getPackagePrefixFromPathExpr ( expr )
251230 }
0 commit comments