diff --git a/src/Lean/Elab/Import.lean b/src/Lean/Elab/Import.lean index 0503401296..472b3b4dca 100644 --- a/src/Lean/Elab/Import.lean +++ b/src/Lean/Elab/Import.lean @@ -11,9 +11,12 @@ import Lean.CoreM namespace Lean.Elab def headerToImports : TSyntax ``Parser.Module.header → Array Import - | `(Parser.Module.header| $[module%$moduleTk]? $[prelude%$preludeTk]? $[import $ns]*) => + | `(Parser.Module.header| $[module%$moduleTk]? $[prelude%$preludeTk]? $importsStx*) => let imports := if preludeTk.isNone then #[{ module := `Init : Import }] else #[] - imports ++ ns.map ({ module := ·.getId }) + imports ++ importsStx.map fun + | `(Parser.Module.import| import $[private%$privateTk]? $n) => + { module := n.getId, importPrivate := privateTk.isSome } + | _ => unreachable! | _ => unreachable! def processHeader (header : TSyntax ``Parser.Module.header) (opts : Options) (messages : MessageLog) diff --git a/src/Lean/Elab/ParseImportsFast.lean b/src/Lean/Elab/ParseImportsFast.lean index 62d2e1f556..565b9de7ba 100644 --- a/src/Lean/Elab/ParseImportsFast.lean +++ b/src/Lean/Elab/ParseImportsFast.lean @@ -133,8 +133,8 @@ partial def whitespace : Parser := fun input s => else false -def State.pushModule (module : Name) (s : State) : State := - { s with imports := s.imports.push { module } } +def State.pushImport (i : Import) (s : State) : State := + { s with imports := s.imports.push i } @[inline] def isIdRestCold (c : Char) : Bool := c = '_' || c = '\'' || c == '!' || c == '?' || isLetterLike c || isSubScriptAlnum c @@ -142,7 +142,7 @@ def State.pushModule (module : Name) (s : State) : State := @[inline] def isIdRestFast (c : Char) : Bool := c.isAlphanum || (c != '.' && c != '\n' && c != ' ' && isIdRestCold c) -partial def moduleIdent : Parser := fun input s => +partial def moduleIdent (importPrivate : Bool) : Parser := fun input s => let rec parse (module : Name) (s : State) := let i := s.pos if h : input.atEnd i then @@ -162,7 +162,7 @@ partial def moduleIdent : Parser := fun input s => let s := s.next input s.pos parse module s else - whitespace input (s.pushModule module) + whitespace input (s.pushImport { module, importPrivate }) else if isIdFirst curr then let startPart := i let s := takeWhile isIdRestFast input (s.next' input i h) @@ -172,7 +172,7 @@ partial def moduleIdent : Parser := fun input s => let s := s.next input s.pos parse module s else - whitespace input (s.pushModule module) + whitespace input (s.pushImport { module, importPrivate }) else s.mkError "expected identifier" parse .anonymous s @@ -187,8 +187,8 @@ partial def moduleIdent : Parser := fun input s => def main : Parser := keywordCore "module" (fun _ s => { s with isModule := true }) (fun _ s => s) >> - keywordCore "prelude" (fun _ s => s.pushModule `Init) (fun _ s => s) >> - many (keyword "import" >> moduleIdent) + keywordCore "prelude" (fun _ s => s.pushImport `Init) (fun _ s => s) >> + many (keyword "import" >> keywordCore "private" (moduleIdent true) (moduleIdent false)) end ParseImports diff --git a/src/Lean/Environment.lean b/src/Lean/Environment.lean index 14a063c82b..08a2c8cfae 100644 --- a/src/Lean/Environment.lean +++ b/src/Lean/Environment.lean @@ -94,7 +94,11 @@ instance : GetElem? (Array α) ModuleIdx α (fun a i => i.toNat < a.size) where abbrev ConstMap := SMap Name ConstantInfo structure Import where - module : Name + module : Name + /-- `import private`; whether to import and expose all data saved by the module. -/ + importPrivate : Bool := false + /-- Whether to activate this import when the current module itself is imported. -/ + isExported : Bool := false deriving Repr, Inhabited instance : Coe Name Import := ⟨({module := ·})⟩ diff --git a/src/Lean/Parser/Module.lean b/src/Lean/Parser/Module.lean index e574d5e2c3..81b72692df 100644 --- a/src/Lean/Parser/Module.lean +++ b/src/Lean/Parser/Module.lean @@ -13,7 +13,8 @@ namespace Parser namespace Module def moduleTk := leading_parser "module" def «prelude» := leading_parser "prelude" -def «import» := leading_parser "import " >> identWithPartialTrailingDot +def «private» := leading_parser (withAnonymousAntiquot := false) "private" +def «import» := leading_parser "import " >> optional «private» >> identWithPartialTrailingDot def header := leading_parser optional (moduleTk >> ppLine >> ppLine) >> optional («prelude» >> ppLine) >> many («import» >> ppLine) >>