@@ -407,26 +407,26 @@ Returns `(path, inputCtx, imports, endPos)` where `imports` is the `Lean.Parser.
407407and `endPos` is the position of the end of the header.
408408-/
409409def parseHeaderFromString (text path : String) :
410- IO (System.FilePath × Parser.InputContext ×
411- TSyntax ``Parser.Module.header × String.Pos.Raw ) := do
410+ IO (System.FilePath × (ictx : Parser.InputContext) ×
411+ TSyntax ``Parser.Module.header × String.Pos ictx.fileMap.source ) := do
412412 let inputCtx := Parser.mkInputContext text path
413413 let (header, parserState, msgs) ← Parser.parseHeader inputCtx
414414 if !msgs.toList.isEmpty then -- skip this file if there are parse errors
415415 msgs.forM fun msg => msg.toString >>= IO.println
416416 throw <| .userError "parse errors in file"
417417 -- the insertion point for `add` is the first newline after the imports
418418 let insertion := header.raw.getTailPos?.getD parserState.pos
419- let insertion := text .pos! insertion |>.find (· == '\n ' ) |>.next!
420- pure ( path, inputCtx, header, insertion.offset)
419+ let insertion := inputCtx.fileMap.source .pos! insertion |>.find (· == '\n ' ) |>.next!
420+ pure ⟨ path, inputCtx, header, insertion⟩
421421
422422/-- Parse a source file to extract the location of the import lines, for edits and error messages.
423423
424424Returns `(path, inputCtx, imports, endPos)` where `imports` is the `Lean.Parser.Module.import` list
425425and `endPos` is the position of the end of the header.
426426-/
427427def parseHeader (srcSearchPath : SearchPath) (mod : Name) :
428- IO (System.FilePath × Parser.InputContext ×
429- TSyntax ``Parser.Module.header × String.Pos.Raw ) := do
428+ IO (System.FilePath × (ictx : Parser.InputContext) ×
429+ TSyntax ``Parser.Module.header × String.Pos ictx.fileMap.source ) := do
430430 -- Parse the input file
431431 let some path ← srcSearchPath.findModuleWithExt "lean" mod
432432 | throw <| .userError s! "error: failed to find source file for { mod} "
@@ -465,12 +465,12 @@ def visitModule (pkg : Name) (srcSearchPath : SearchPath)
465465 return
466466
467467 let (module?, prelude ?, imports) := decodeHeader headerStx
468- if module?.any (·.raw.getTrailing?.any (·.toString.toSlice. contains "shake: keep-downstream" )) then
468+ if module?.any (·.raw.getTrailing?.any (·.toString.contains "shake: keep-downstream" )) then
469469 modify fun s => { s with preserve := s.preserve.union .pub {i} }
470470
471471 let s ← get
472472
473- let addOnly := addOnly || module?.any (·.raw.getTrailing?.any (·.toString.toSlice. contains "shake: keep-all" ))
473+ let addOnly := addOnly || module?.any (·.raw.getTrailing?.any (·.toString.contains "shake: keep-all" ))
474474 let mut deps := needs
475475
476476 -- Add additional preserved imports
@@ -480,7 +480,7 @@ def visitModule (pkg : Name) (srcSearchPath : SearchPath)
480480 let k := NeedsKind.ofImport imp
481481 if addOnly ||
482482 args.keepPublic && imp.isExported ||
483- impStx.raw.getTrailing?.any (·.toString.toSlice. contains "shake: keep" ) then
483+ impStx.raw.getTrailing?.any (·.toString.contains "shake: keep" ) then
484484 deps := deps.union k {j}
485485 for j in [0 :s.mods.size] do
486486 for k in NeedsKind.all do
@@ -503,14 +503,14 @@ def visitModule (pkg : Name) (srcSearchPath : SearchPath)
503503
504504 -- Accumulate `transDeps` which is the non-reflexive transitive closure of the still-live imports
505505 let mut transDeps := Needs.empty
506- let mut alwaysAdd : Array Import := #[]
506+ let mut alwaysAdd : Array Import := #[] -- to be added even if implied by other imports
507507 for imp in s.mods[i]!.imports do
508508 let j := s.env.getModuleIdx? imp.module |>.get!
509509 let k := NeedsKind.ofImport imp
510510 if deps.has k j || imp.importAll then
511511 transDeps := addTransitiveImps transDeps imp j s.transDeps[j]!
512512 deps := deps.union k {j}
513- -- skip folder-nested `public import`s but remove `meta`
513+ -- skip folder-nested `public (meta)? import`s but remove `meta`
514514 else if s.modNames[i]!.isPrefixOf imp.module then
515515 let imp := { imp with isMeta := false }
516516 let k := { k with isMeta := false }
@@ -523,7 +523,7 @@ def visitModule (pkg : Name) (srcSearchPath : SearchPath)
523523
524524 -- If `transDeps` does not cover `deps`, then we have to add back some imports until it does.
525525 -- To minimize new imports we pick only new imports which are not transitively implied by
526- -- another new import
526+ -- another new import, so we visit module indices in descending order.
527527 let mut keptPrefix := false
528528 let mut newTransDeps := transDeps
529529 let mut toAdd : Array Import := #[]
@@ -537,6 +537,7 @@ def visitModule (pkg : Name) (srcSearchPath : SearchPath)
537537 if args.trace then
538538 IO.eprintln s! "`{ imp} ` is needed"
539539 if args.addPublic && !k.isExported &&
540+ -- also add as public if previously `public meta`, which could be from automatic porting
540541 (s.transDepsOrig[i]!.has { k with isExported := true } j || s.transDepsOrig[i]!.has { k with isExported := true , isMeta := true } j) then
541542 k := { k with isExported := true }
542543 imp := { imp with isExported := true }
@@ -565,8 +566,8 @@ def visitModule (pkg : Name) (srcSearchPath : SearchPath)
565566 newTransDeps := addTransitiveImps newTransDeps imp j s.transDeps[j]!
566567
567568 if keptPrefix then
568- -- if an import was replaced by `--keep-prefix`, we did not visit the modules in dependency
569- -- order anymore and so we have to redo the transitive closure checking
569+ -- if an import was replaced by `--keep-prefix`, we did not necessarily visit the modules in
570+ -- dependency order anymore and so we have to redo the transitive closure checking
570571 newTransDeps := transDeps
571572 for j in (0 ...s.mods.size).toArray.reverse do
572573 for k in NeedsKind.all do
@@ -617,7 +618,7 @@ def visitModule (pkg : Name) (srcSearchPath : SearchPath)
617618
618619 if args.githubStyle then
619620 try
620- let ( path, inputCtx, stx, endHeader) ← parseHeader srcSearchPath s.modNames[i]!
621+ let ⟨ path, inputCtx, stx, endHeader⟩ ← parseHeader srcSearchPath s.modNames[i]!
621622 let (_, _, imports) := decodeHeader stx
622623 for stx in imports do
623624 if toRemove.any fun imp => imp == decodeImport stx then
@@ -626,7 +627,7 @@ def visitModule (pkg : Name) (srcSearchPath : SearchPath)
626627 (use `lake exe shake --fix` to fix this, or `lake exe shake --update` to ignore)"
627628 if !toAdd.isEmpty then
628629 -- we put the insert message on the beginning of the last import line
629- let pos := inputCtx.fileMap.toPosition endHeader
630+ let pos := inputCtx.fileMap.toPosition endHeader.offset
630631 println! "{path}:{pos.line-1}:1: warning: \
631632 add {toAdd} instead"
632633 catch _ => pure ()
@@ -753,7 +754,7 @@ public def main (args : List String) : IO UInt32 := do
753754 -- Parse headers in parallel
754755 let headers ← s.mods.mapIdxM fun i _ =>
755756 if !pkg.isPrefixOf s.modNames[i]! then
756- pure <| Task.pure <| .ok default
757+ pure <| Task.pure <| .ok ⟨ default, default, default, default⟩
757758 else
758759 BaseIO.asTask (parseHeader srcSearchPath s.modNames[i]! |>.toBaseIO)
759760
@@ -763,8 +764,8 @@ public def main (args : List String) : IO UInt32 := do
763764 -- Check all selected modules
764765 for i in [0 :s.mods.size], t in needs, header in headers do
765766 match header.get with
766- | .ok ( _, _, stx, _) =>
767- visitModule (addOnly := false ) pkg srcSearchPath i t.get stx args
767+ | .ok ⟨ _, _, stx, _⟩ =>
768+ visitModule pkg srcSearchPath i t.get stx args
768769 | .error e =>
769770 println! e.toString
770771
@@ -779,27 +780,27 @@ public def main (args : List String) : IO UInt32 := do
779780 let add : Array Import := add.qsortOrd
780781
781782 -- Parse the input file
782- let .ok ( path, inputCtx, stx, insertion) := header?.get | continue
783+ let .ok ⟨ path, inputCtx, stx, insertion⟩ := header?.get | continue
783784 let (_, _, imports) := decodeHeader stx
784785 let text := inputCtx.fileMap.source
785786
786787 -- Calculate the edit result
787- let mut pos : String.Pos.Raw := 0
788+ let mut pos : String.Pos text := text.startPos
788789 let mut out : String := ""
789790 let mut seen : Std.HashSet Import := {}
790791 for stx in imports do
791792 let mod := decodeImport stx
792793 if remove.contains mod || seen.contains mod then
793- out := out ++ pos.extract text stx.raw.getPos?.get!
794+ out := out ++ pos.extract ( text.pos! stx.raw.getPos?.get!)
794795 -- We use the end position of the syntax, but include whitespace up to the first newline
795- pos := text.findAux (· == ' \n ' ) text.rawEndPos stx.raw.getTailPos?.get! + '\n '
796+ pos := text.pos! stx.raw.getTailPos?.get! |>.find '\n ' |>.next!
796797 seen := seen.insert mod
797- out := out ++ pos.extract text insertion
798+ out := out ++ pos.extract insertion
798799 for mod in add do
799800 if !seen.contains mod then
800801 seen := seen.insert mod
801802 out := out ++ s! "{ mod} \n "
802- out := out ++ insertion.extract text text.rawEndPos
803+ out := out ++ insertion.extract text.endPos
803804
804805 IO.FS.writeFile path out
805806 count := count + 1
0 commit comments