this is a first step towards porting the code `constructions.cpp` to Lean: It leaves the construction of the `Declaration` untouched, but moves adding the declarations to the environment, and setting various attributes, to the Lean world. This allows the remaining logic (the construction of the `Declaration`) to be implemented in Lean separately and easily compared to the C++ implementation, before we replace that too. To that end, `Declaraion` gains an `BEq` instance. --------- Co-authored-by: Leonardo de Moura <leomoura@amazon.com> Co-authored-by: Arthur Adjedj <arthur.adjedj@ens-paris-saclay.fr>
84 lines
2.3 KiB
Text
84 lines
2.3 KiB
Text
/-
|
|
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 Lean.Environment
|
|
|
|
namespace Lean
|
|
|
|
builtin_initialize protectedExt : TagDeclarationExtension ← mkTagDeclarationExtension
|
|
|
|
def addProtected (env : Environment) (n : Name) : Environment :=
|
|
protectedExt.tag env n
|
|
|
|
def isProtected (env : Environment) (n : Name) : Bool :=
|
|
protectedExt.isTagged env n
|
|
|
|
/-! # Private name support.
|
|
|
|
Suppose the user marks as declaration `n` as private. Then, we create
|
|
the name: `_private.<module_name>.0 ++ n`.
|
|
We say `_private.<module_name>.0` is the "private prefix"
|
|
|
|
We assume that `n` is a valid user name and does not contain
|
|
`Name.num` constructors. Thus, we can easily convert from
|
|
private internal name to the user given name.
|
|
-/
|
|
|
|
def privateHeader : Name := `_private
|
|
|
|
def mkPrivateName (env : Environment) (n : Name) : Name :=
|
|
Name.mkNum (privateHeader ++ env.mainModule) 0 ++ n
|
|
|
|
def isPrivateName : Name → Bool
|
|
| n@(.str p _) => n == privateHeader || isPrivateName p
|
|
| .num p _ => isPrivateName p
|
|
| _ => false
|
|
|
|
@[export lean_is_private_name]
|
|
def isPrivateNameExport (n : Name) : Bool :=
|
|
isPrivateName n
|
|
|
|
/--
|
|
Return `true` if `n` is of the form `_private.<module_name>.0`
|
|
See comment above.
|
|
-/
|
|
def isPrivatePrefix (n : Name) : Bool :=
|
|
match n with
|
|
| .num p 0 => go p
|
|
| _ => false
|
|
where
|
|
go (n : Name) : Bool :=
|
|
n == privateHeader ||
|
|
match n with
|
|
| .str p _ => go p
|
|
| _ => false
|
|
|
|
private def privateToUserNameAux (n : Name) : Name :=
|
|
match n with
|
|
| .str p s => .str (privateToUserNameAux p) s
|
|
| .num p i => if isPrivatePrefix n then .anonymous else .num (privateToUserNameAux p) i
|
|
| _ => .anonymous
|
|
|
|
@[export lean_private_to_user_name]
|
|
def privateToUserName? (n : Name) : Option Name :=
|
|
if isPrivateName n then privateToUserNameAux n
|
|
else none
|
|
|
|
def isPrivateNameFromImportedModule (env : Environment) (n : Name) : Bool :=
|
|
match privateToUserName? n with
|
|
| some userName => mkPrivateName env userName != n
|
|
| _ => false
|
|
|
|
private def privatePrefixAux : Name → Name
|
|
| .str 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
|