/- Copyright (c) 2019 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura -/ prelude import Init.Lean.Environment namespace Lean def mkProtectedExtension : IO (SimplePersistentEnvExtension Name NameSet) := registerSimplePersistentEnvExtension { name := `protected, addImportedFn := fun as => {}, addEntryFn := fun s n => s.insert n, toArrayFn := fun es => es.toArray.qsort Name.quickLt } @[init mkProtectedExtension] constant protectedExt : SimplePersistentEnvExtension Name NameSet := default _ @[export lean_add_protected] def addProtected (env : Environment) (n : Name) : Environment := protectedExt.addEntry env n @[export lean_is_protected] def isProtected (env : Environment) (n : Name) : Bool := match env.getModuleIdxFor n with | some modIdx => (protectedExt.getModuleEntries env modIdx).binSearchContains n Name.quickLt | none => (protectedExt.getState env).contains n def mkPrivateExtension : IO (EnvExtension Nat) := registerEnvExtension (pure 1) @[init mkPrivateExtension] constant privateExt : EnvExtension Nat := default _ /- Private name support. Suppose the user marks as declaration `n` as private. Then, we create the name: `_private.. ++ n`. We say `_private..` is the "private prefix" where `` comes from the environment extension `privateExt`. We assume that `n` is a valid user name and does not contain `Name.mkNumeral` constructors. Thus, we can easily convert from private internal name to user given name. -/ def privateHeader : Name := `_private @[export lean_mk_private_prefix] def mkPrivatePrefix (env : Environment) : Environment × Name := let idx := privateExt.getState env; let p := Name.mkNumeral (privateHeader ++ env.mainModule) idx; let env := privateExt.setState env (idx+1); (env, p) @[export lean_mk_private_name] def mkPrivateName (env : Environment) (n : Name) : Environment × Name := let (env, p) := mkPrivatePrefix env; (env, p ++ n) def isPrivateName : Name → Bool | n@(Name.mkString p _) => n == privateHeader || isPrivateName p | Name.mkNumeral p _ => isPrivateName p | _ => false @[export lean_is_private_name] def isPrivateNameExport (n : Name) : Bool := isPrivateName n private def privateToUserNameAux : Name → Name | Name.mkString p s => Name.mkString (privateToUserNameAux p) s | _ => Name.anonymous @[export lean_private_to_user_name] def privateToUserName (n : Name) : Option Name := if isPrivateName n then privateToUserNameAux n else none private def privatePrefixAux : Name → Name | Name.mkString p _ => privatePrefixAux p | n => n @[export lean_private_prefix] def privatePrefix (n : Name) : Option Name := if isPrivateName n then privatePrefixAux n else none end Lean