@@ -196,11 +196,18 @@ func (l *linter) handleImport(
196196 Elaboration : helpersChecker .Elaboration ,
197197 }, nil
198198 default :
199+ // Normalize relative path imports to absolute paths
200+ if l .isPathLocation (importedLocation ) {
201+ importedLocation = l .normalizePathLocation (checker .Location , importedLocation )
202+ }
203+
199204 filepath , err := l .resolveImportFilepath (importedLocation , checker .Location )
200205 if err != nil {
201206 return nil , err
202207 }
203208
209+ fileLocation := common .StringLocation (filepath )
210+
204211 importedChecker , ok := l .checkers [filepath ]
205212 if ! ok {
206213 code , err := l .state .ReadFile (filepath )
@@ -219,7 +226,7 @@ func (l *linter) handleImport(
219226 }
220227 }
221228
222- importedChecker , err = checker .SubChecker (importedProgram , importedLocation )
229+ importedChecker , err = checker .SubChecker (importedProgram , fileLocation )
223230 if err != nil {
224231 return nil , err
225232 }
@@ -237,6 +244,37 @@ func (l *linter) handleImport(
237244 }
238245}
239246
247+ // isPathLocation returns true if the location is a file path (contains .cdc)
248+ func (l * linter ) isPathLocation (location common.Location ) bool {
249+ stringLocation , ok := location .(common.StringLocation )
250+ if ! ok {
251+ return false
252+ }
253+ return strings .Contains (stringLocation .String (), ".cdc" )
254+ }
255+
256+ // normalizePathLocation normalizes a relative path import against a base location
257+ func (l * linter ) normalizePathLocation (base , relative common.Location ) common.Location {
258+ baseString , baseOk := base .(common.StringLocation )
259+ relativeString , relativeOk := relative .(common.StringLocation )
260+
261+ if ! baseOk || ! relativeOk {
262+ return relative
263+ }
264+
265+ basePath := baseString .String ()
266+ relativePath := relativeString .String ()
267+
268+ // If the relative path is absolute, return it as-is
269+ if filepath .IsAbs (relativePath ) {
270+ return relative
271+ }
272+
273+ // Join relative to the parent directory of the base
274+ normalizedPath := filepath .Join (filepath .Dir (basePath ), relativePath )
275+ return common .StringLocation (normalizedPath )
276+ }
277+
240278func (l * linter ) resolveImportFilepath (
241279 location common.Location ,
242280 parentLocation common.Location ,
@@ -246,7 +284,7 @@ func (l *linter) resolveImportFilepath(
246284) {
247285 switch location := location .(type ) {
248286 case common.StringLocation :
249- // If the location is not a cadence file try getting the code by identifier
287+ // Resolve by contract name from flowkit config
250288 if ! strings .Contains (location .String (), ".cdc" ) {
251289 contract , err := l .state .Contracts ().ByName (location .String ())
252290 if err != nil {
@@ -256,14 +294,7 @@ func (l *linter) resolveImportFilepath(
256294 return contract .Location , nil
257295 }
258296
259- // If the location is a cadence file, resolve relative to the parent location
260- parentPath := ""
261- if parentLocation != nil {
262- parentPath = parentLocation .String ()
263- }
264-
265- resolvedPath := filepath .Join (filepath .Dir (parentPath ), location .String ())
266- return resolvedPath , nil
297+ return location .String (), nil
267298 default :
268299 return "" , fmt .Errorf ("unsupported location: %T" , location )
269300 }
0 commit comments