@@ -291,22 +291,79 @@ let validateLoc (loc : Location.t) (backup : Location.t) =
291291 loc_start = {pos_cnum = 0 ; pos_lnum = 1 ; pos_bol = 0 ; pos_fname = " " };
292292 loc_end = {pos_cnum = 0 ; pos_lnum = 1 ; pos_bol = 0 ; pos_fname = " " };
293293 }
294- else backup
294+ else backup
295295 else loc
296296
297- let resolveModuleDefinition ~(file : File.t ) ~package stamp =
298- match Stamps. findModule file.stamps stamp with
297+ let isGhostLoc (loc : Location.t ) =
298+ loc.loc_ghost
299+ || (loc.loc_start.pos_fname = " " && loc.loc_end.pos_fname = " " )
300+ || (loc.loc_start.pos_cnum = 0 && loc.loc_end.pos_cnum = 0 )
301+
302+ let fallbackLocFromSource ~(uri : Uri.t ) ~(tip : Tip.t ) ~(name : string ) =
303+ let path = Uri. toPath uri in
304+ let mk_regexp prefix =
305+ Str. regexp
306+ (Printf. sprintf " ^ *%s +\\ (?:rec +\\ )?\\ (%s\\ )\\ b" prefix (Str. quote name))
307+ in
308+ let regexpOpt =
309+ match tip with
310+ | Value -> Some (mk_regexp " let" )
311+ | Type -> Some (mk_regexp " type" )
312+ | _ -> None
313+ in
314+ match regexpOpt with
299315 | None -> None
300- | Some md -> (
301- match resolveModuleReference ~file ~package md with
316+ | Some regexp -> (
317+ match Files. readFile path with
302318 | None -> None
303- | Some (file , declared ) ->
304- let loc =
305- match declared with
306- | None -> Uri. toTopLevelLoc file.uri
307- | Some declared -> validateLoc declared.name.loc declared.extentLoc
319+ | Some text ->
320+ let lines = String. split_on_char '\n' text in
321+ let rec loop lineNumber = function
322+ | [] -> None
323+ | line :: rest ->
324+ if Str. string_match regexp line 0 then (
325+ let endIdx = Str. match_end () in
326+ let startIdx = endIdx - String. length name in
327+ let loc_start =
328+ {
329+ Lexing. pos_fname = path;
330+ pos_lnum = lineNumber + 1 ;
331+ pos_bol = 0 ;
332+ pos_cnum = startIdx;
333+ }
334+ in
335+ let loc_end =
336+ {
337+ Lexing. pos_fname = path;
338+ pos_lnum = lineNumber + 1 ;
339+ pos_bol = 0 ;
340+ pos_cnum = endIdx;
341+ }
342+ in
343+ Some {Location. loc_start; loc_end; loc_ghost = false }
344+ )
345+ else loop (lineNumber + 1 ) rest
308346 in
309- Some (file.uri, loc))
347+ loop 0 lines)
348+
349+ let resolveModuleDefinition ~(file : File.t ) ~package stamp =
350+ match Stamps. findModule file.stamps stamp with
351+ | None -> None
352+ | Some aliasDeclared -> (
353+ let aliasLoc =
354+ validateLoc aliasDeclared.name.loc aliasDeclared.extentLoc
355+ in
356+ match resolveModuleReference ~file ~package aliasDeclared with
357+ | None ->
358+ Some (file.uri, aliasLoc)
359+ | Some (resolvedFile , declared ) -> (
360+ match declared with
361+ | None ->
362+ (* Alias resolved to a top-level module in another file; surface the alias site. *)
363+ Some (file.uri, aliasLoc)
364+ | Some declared ->
365+ let loc = validateLoc declared.name.loc declared.extentLoc in
366+ Some (resolvedFile.uri, loc)))
310367
311368let definition ~file ~package stamp (tip : Tip.t ) =
312369 match tip with
@@ -323,16 +380,22 @@ let definition ~file ~package stamp (tip : Tip.t) =
323380 match declaredForTip ~stamps: file.stamps stamp tip with
324381 | None -> None
325382 | Some declared ->
326- let fileImpl, declaredImpl =
383+ let fileForLoc, declaredForLoc =
327384 match alternateDeclared ~package ~file declared tip with
328- | Some (fileImpl , _extra , declaredImpl ) when Uri. isInterface file.uri ->
329- (fileImpl, declaredImpl)
330- | _ -> (file, declared)
385+ | Some (fileImpl , _extra , declaredImpl ) -> (fileImpl, declaredImpl)
386+ | None -> (file, declared)
331387 in
332- let loc = validateLoc declaredImpl .name.loc declaredImpl .extentLoc in
333- let env = QueryEnv. fromFile fileImpl in
388+ let loc = validateLoc declaredForLoc .name.loc declaredForLoc .extentLoc in
389+ let env = QueryEnv. fromFile fileForLoc in
334390 let uri =
335- ResolvePath. getSourceUri ~env ~package declaredImpl.modulePath
391+ ResolvePath. getSourceUri ~env ~package declaredForLoc.modulePath
392+ in
393+ let loc =
394+ if isGhostLoc loc || Uri. isInterface uri then
395+ match fallbackLocFromSource ~uri ~tip ~name: declaredForLoc.name.txt with
396+ | None -> loc
397+ | Some foundLoc -> foundLoc
398+ else loc
336399 in
337400 maybeLog (" Inner uri " ^ Uri. toString uri);
338401 Some (uri, loc))
@@ -345,15 +408,15 @@ let definitionForLocItem ~full:{file; package} locItem =
345408 ^ Tip. toString tip);
346409 match declaredForTip ~stamps: file.stamps stamp tip with
347410 | None -> None
348- | Some declared ->
349- maybeLog (" Declared " ^ declared.name.txt);
350- if declared.isExported then (
351- maybeLog (" exported, looking for alternate " ^ file.moduleName);
352- match alternateDeclared ~package ~file declared tip with
353- | None -> None
354- | Some (file , _extra , declared ) ->
355- let loc = validateLoc declared.name.loc declared.extentLoc in
356- Some (file.uri, loc))
411+ | Some declared ->
412+ maybeLog (" Declared " ^ declared.name.txt);
413+ if declared.isExported then (
414+ maybeLog (" exported, looking for alternate " ^ file.moduleName);
415+ match alternateDeclared ~package ~file declared tip with
416+ | None -> None
417+ | Some (file , _extra , declared ) ->
418+ let loc = validateLoc declared.name.loc declared.extentLoc in
419+ Some (file.uri, loc))
357420 else None )
358421 | Typed (_, _, NotFound )
359422 | LModule (NotFound | Definition (_, _))
0 commit comments