@@ -15,59 +15,134 @@ namespace Lake
15
15
--------------------------------------------------------------------------------
16
16
17
17
/--
18
- The open type family which maps a module facet's name to its build data
19
- in the Lake build store. For example, a transitive × direct import pair
20
- for the `lean.imports` facet or an active build target for `lean.c`.
18
+ The open type family which maps a Lake data kind to its associated type.
19
+ For example, `LeanLib.facetKind` maps to `LeanLib`.
21
20
22
21
It is an open type, meaning additional mappings can be add lazily
23
- as needed (via `module_data`).
22
+ as needed (via `data_type`).
23
+ -/
24
+ opaque DataType (kind : Name) : Type u
25
+
26
+ /-- A `Name` descriptor of a data type. -/
27
+ class DataKind (α : Type u) where
28
+ /-- The name which describes `α`. -/
29
+ name : Name
30
+ /-- Proof that `α` is the data type described by `name`. -/
31
+ wf : α = DataType name
32
+
33
+ /--
34
+ Tries to synthesize a `Name` descriptor of a data type.
35
+ Otherwise uses `Name.anonymous` to indicate none was found.
24
36
-/
25
- opaque ModuleData (facet : Name) : Type
37
+ class OptDataKind (α : Type u) where
38
+ /-- The name which describes `α` (or `Name.anonymous` if none). -/
39
+ name : Name
40
+ /-- Proof that `α` is the data type described by `name` (if valid). -/
41
+ wf (h : ¬ name.isAnonymous) : α = DataType name
42
+
43
+ @[instance low]
44
+ def OptDataKind.anonymous : OptDataKind α where
45
+ name := .anonymous
46
+ wf h := by simp [Name.isAnonymous] at h
47
+
48
+ @[inline] def OptDataKind.isAnonymous (self : OptDataKind α) : Bool :=
49
+ self.name.isAnonymous
50
+
51
+ theorem OptDataKind.eq_data_type
52
+ {self : OptDataKind α} (h : ¬ self.isAnonymous) : α = DataType self.name
53
+ := self.wf h
54
+
55
+ instance [DataKind α] : OptDataKind α where
56
+ name := DataKind.name α
57
+ wf _ := DataKind.wf
58
+
59
+ instance : CoeOut (OptDataKind α) Lean.Name := ⟨(·.name)⟩
60
+ instance : ToString (OptDataKind α) := ⟨(·.name.toString)⟩
61
+
62
+ @[deprecated DataType (since := "2025-03-26")] abbrev TargetData := DataType
26
63
27
64
/--
28
- The open type family which maps a package facet's name to its build data
29
- in the Lake build store. For example, a transitive dependencies of the package
30
- for the facet `deps`.
65
+ The open type family which maps a Lake facet to its output type.
66
+ For example, a `FilePath` for the `module.olean` facet.
31
67
32
68
It is an open type, meaning additional mappings can be add lazily
33
- as needed (via `package_data `).
69
+ as needed (via `facet_data `).
34
70
-/
35
- opaque PackageData (facet : Name) : Type
71
+ opaque FacetOut (facet : Name) : Type
36
72
37
73
/--
38
- The open type family which maps a (builtin) Lake target's (e.g., `extern_lib`)
39
- facet to its associated build data. For example, an active build target for
40
- the `externLib.static` facet.
74
+ The open type family which maps a Lake facet kind and name to its output type.
75
+ For example, a `FilePath` for the `module` `olean` facet.
41
76
42
77
It is an open type, meaning additional mappings can be add lazily
43
- as needed (via `target_data `).
78
+ as needed (via `facet_data `).
44
79
-/
45
- opaque TargetData ( facet : Name) : Type
80
+ abbrev FacetData (kind facet : Name) := FacetOut (kind ++ facet)
46
81
47
- /-
48
- The open type family which maps a library facet's name to its build data
49
- in the Lake build store. For example, an active build target for the `static`
50
- facet.
82
+ instance [h : FamilyDef FacetOut (kind ++ facet) α] : FamilyDef (FacetData kind) facet α :=
83
+ ⟨h.fam_eq⟩
84
+
85
+ instance [h : FamilyDef (FacetData kind) facet α] : FamilyDef FacetOut (kind ++ facet) α :=
86
+ ⟨h.fam_eq⟩
87
+
88
+ /--
89
+ The open type family which maps a module facet's name to its output type.
90
+ For example, a `FilePath` for the module `olean` facet.
91
+
92
+ It is an open type, meaning additional mappings can be add lazily
93
+ as needed (via `module_data`).
94
+ -/
95
+ abbrev ModuleData := FacetData Module.facetKind
96
+
97
+ /--
98
+ The open type family which maps a package facet's name to output type.
99
+ For example, an `Arrry Package` of direct dependencies for the `deps` facet.
100
+
101
+ It is an open type, meaning additional mappings can be add lazily
102
+ as needed (via `package_data`).
103
+ -/
104
+ abbrev PackageData := FacetData Package.facetKind
105
+
106
+ /-- The kind identifier for facets of a Lean library. -/
107
+ @[match_pattern] abbrev LeanLib.facetKind : Name := `lean_lib
108
+
109
+ /--
110
+ The open type family which maps a Lean library facet's name to its output type.
111
+ For example, the `FilePath` pf the generated static library for the `static` facet.
51
112
52
113
It is an open type, meaning additional mappings can be add lazily
53
114
as needed (via `library_data`).
54
115
-/
55
- abbrev LibraryData (facet : Name) := TargetData ( `leanLib ++ facet)
116
+ abbrev LibraryData := FacetData LeanLib.facetKind
56
117
57
- instance [h : FamilyOut LibraryData facet α] : FamilyDef TargetData ( `leanLib ++ facet) α :=
58
- ⟨ by simp [h.family_key_eq_type]⟩
118
+ @[inherit_doc LibraryData]
119
+ abbrev LeanLibData := LibraryData
59
120
60
- instance [h : FamilyOut TargetData (`leanLib ++ facet) α] : FamilyDef LibraryData facet α :=
61
- ⟨h.family_key_eq_type⟩
121
+ /-- The kind identifier for facets of a Lean executable. -/
122
+ @[match_pattern] abbrev LeanExe.facetKind : Name := `lean_exe
123
+
124
+ /-- The kind identifier for facets of an external library. -/
125
+ @[match_pattern] abbrev ExternLib.facetKind : Name := `extern_lib
126
+
127
+ /--
128
+ The open type family which maps a custom package target
129
+ (package × target name) to its output type.
130
+
131
+ It is an open type, meaning additional mappings can be add lazily
132
+ as needed (via `custom_data`).
133
+ -/
134
+ opaque CustomOut (target : Name × Name) : Type
62
135
63
136
/--
64
- The open type family which maps a custom target (package × target name) to
65
- its build data in the Lake build store.
137
+ The open type family which maps a custom package targetto its output type.
66
138
67
139
It is an open type, meaning additional mappings can be add lazily
68
140
as needed (via `custom_data`).
69
141
-/
70
- opaque CustomData (target : Name × Name) : Type
142
+ abbrev CustomData (package target : Name) := CustomOut (package, target)
143
+
144
+ instance [h : FamilyDef CustomOut (p, t) α] : FamilyDef (CustomData p) t α :=
145
+ ⟨h.fam_eq⟩
71
146
72
147
--------------------------------------------------------------------------------
73
148
/-! ## Build Data -/
@@ -79,55 +154,119 @@ It is a simple type function composed of the separate open type families for
79
154
modules facets, package facets, Lake target facets, and custom targets.
80
155
-/
81
156
abbrev BuildData : BuildKey → Type
82
- | .moduleFacet _ f => ModuleData f
83
- | .packageFacet _ f => PackageData f
84
- | .targetFacet _ _ f => TargetData f
85
- | .customTarget p t => CustomData (p, t)
157
+ | .module _ => DataType Module.facetKind
158
+ | .package _ => DataType Package.facetKind
159
+ | .packageTarget p t => CustomData p t
160
+ | .facet _ f => FacetOut f
161
+
162
+ instance (priority := low) : FamilyDef BuildData (.packageTarget p t) (CustomData p t) := ⟨rfl⟩
163
+ instance (priority := low) : FamilyDef BuildData (.facet t f) (FacetOut f) := ⟨rfl⟩
164
+
165
+ instance [FamilyOut (CustomData p) t α]
166
+ : FamilyDef BuildData (.packageTarget p t) α where
167
+ fam_eq := by unfold BuildData; simp
168
+
169
+ instance [FamilyOut DataType Module.facetKind α]
170
+ : FamilyDef BuildData (.module k) α where
171
+ fam_eq := by unfold BuildData; simp
86
172
87
- instance (priority := low) : FamilyDef BuildData k (BuildData k) := ⟨rfl⟩
88
- instance (priority := low) : FamilyDef BuildData (.moduleFacet m f) (ModuleData f) := ⟨rfl⟩
89
- instance (priority := low) : FamilyDef BuildData (.packageFacet p f) (PackageData f) := ⟨rfl⟩
90
- instance (priority := low) : FamilyDef BuildData (.targetFacet p t f) (TargetData f) := ⟨rfl⟩
91
- instance (priority := low) : FamilyDef BuildData (.customTarget p t) (CustomData (p,t)) := ⟨rfl⟩
173
+ instance [FamilyOut DataType Package.facetKind α]
174
+ : FamilyDef BuildData (.package k) α where
175
+ fam_eq := by unfold BuildData; simp
92
176
93
177
--------------------------------------------------------------------------------
94
178
/-! ## Macros for Declaring Build Data -/
95
179
--------------------------------------------------------------------------------
96
180
181
+ open Parser Command
182
+
183
+ /-- Macro for declaring new `DatayType`. -/
184
+ scoped macro (name := dataTypeDecl)
185
+ doc?:optional(docComment) "data_type " kind:ident " : " ty:term
186
+ : command => do
187
+ let fam := mkCIdentFrom (← getRef) ``DataType
188
+ let kindName := Name.quoteFrom kind kind.getId
189
+ let id := mkIdentFrom kind (canonical := true ) <|
190
+ kind.getId.modifyBase (kind.getId ++ ·)
191
+ `($[$doc?]? family_def $id : $fam $kindName := $ty
192
+ instance : DataKind $ty := ⟨$kindName, by simp⟩)
193
+
194
+ /-- Internal macro for declaring new facet within Lake. -/
195
+ scoped macro (name := builtinFacetCommand)
196
+ doc?:optional(docComment) tk:"builtin_facet "
197
+ id?:optional(atomic(group(ident " @ " ))) name:ident " : " ns:ident " => " ty:term
198
+ : command => withRef tk do
199
+ let fam := mkCIdentFrom tk ``FacetOut
200
+ let kindName ← match ns.getId with
201
+ | `Package => pure Package.facetKind
202
+ | `Module => pure Module.facetKind
203
+ | `LeanLib => pure LeanLib.facetKind
204
+ | `LeanExe => pure LeanExe.facetKind
205
+ | `ExternLib => pure ExternLib.facetKind
206
+ | _ => Macro.throwErrorAt ns "unknown facet kind"
207
+ let nameLit := Name.quoteFrom name name.getId (canonical := id?.isSome)
208
+ let kindLit := Name.quoteFrom ns kindName (canonical := true )
209
+ let facet := kindName ++ name.getId
210
+ let facetId := mkIdentFrom tk facet (canonical := true )
211
+ let facetLit := Name.quoteFrom tk facet
212
+ let id ←
213
+ if let some id := id? then
214
+ let id := id.raw[0 ]
215
+ pure <| mkIdentFrom id (ns.getId ++ id.getId) (canonical := true )
216
+ else
217
+ match name.getId with
218
+ | .str .anonymous n => pure <| mkIdentFrom name (ns.getId.str s! "{ n} Facet" ) (canonical := true )
219
+ | _ => Macro.throwErrorAt name "cannot generate facet declaration name from facet name"
220
+ `(
221
+ $[$doc?]? abbrev $id := $facetLit
222
+ family_def $facetId : $fam $facetLit := $ty
223
+ instance : FamilyDef FacetOut ($kindLit ++ $nameLit) $ty :=
224
+ inferInstanceAs (FamilyDef FacetOut $facetLit $ty)
225
+ )
226
+
227
+ /-- Macro for declaring new `FacetData`. -/
228
+ scoped macro (name := facetDataDecl)
229
+ doc?:optional(docComment) tk:"facet_data " kind:ident name:ident " : " ty:term
230
+ : command => withRef tk do
231
+ let fam := mkCIdentFrom tk ``FacetOut
232
+ let kindLit := Name.quoteFrom kind kind.getId
233
+ let nameLit := Name.quoteFrom name name.getId
234
+ let facet := kind.getId ++ name.getId
235
+ let facetLit := Name.quoteFrom tk facet
236
+ let id := mkIdentFrom tk facet (canonical := true )
237
+ `($[$doc?]? family_def $id : $fam $facetLit := $ty
238
+ instance : FamilyDef FacetOut ($kindLit ++ $nameLit) $ty :=
239
+ inferInstanceAs (FamilyDef FacetOut $facetLit $ty))
240
+
97
241
/-- Macro for declaring new `PackageData`. -/
98
- scoped macro (name := packageDataDecl) doc?:optional(Parser.Command.docComment)
99
- "package_data " id:ident " : " ty:term : command => do
100
- let dty := mkCIdentFrom (← getRef) ``PackageData
101
- let key := Name.quoteFrom id id.getId
102
- `($[$doc?]? family_def $id : $dty $key := $ty)
242
+ scoped macro (name := packageDataDecl)
243
+ doc?:optional(docComment) tk:"package_data " facet:ident " : " ty:term
244
+ : command => `($[$doc?]? facet_data%$tk $(mkIdentFrom tk Package.facetKind) $facet : $ty)
103
245
104
246
/-- Macro for declaring new `ModuleData`. -/
105
- scoped macro (name := moduleDataDecl) doc?:optional(Parser.Command.docComment)
106
- "module_data " id:ident " : " ty:term : command => do
107
- let dty := mkCIdentFrom (← getRef) ``ModuleData
108
- let key := Name.quoteFrom id id.getId
109
- `($[$doc?]? family_def $id : $dty $key := $ty)
110
-
111
- /-- Macro for declaring new `TargetData` for libraries. -/
112
- scoped macro (name := libraryDataDecl) doc?:optional(Parser.Command.docComment)
113
- "library_data " id:ident " : " ty:term : command => do
114
- let dty := mkCIdentFrom (← getRef) ``TargetData
115
- let key := Name.quoteFrom id id.getId
116
- let id := mkIdentFrom id (canonical := true ) <| id.getId.modifyBase (`leanLib ++ ·)
117
- `($[$doc?]? family_def $id : $dty (`leanLib ++ $key) := $ty)
247
+ scoped macro (name := moduleDataDecl)
248
+ doc?:optional(docComment) tk:"module_data " facet:ident " : " ty:term
249
+ : command => `($[$doc?]? facet_data%$tk $(mkIdentFrom tk Module.facetKind) $facet : $ty)
250
+
251
+ /-- Macro for declaring new `LibraryData`. -/
252
+ scoped macro (name := libraryDataDecl)
253
+ doc?:optional(docComment) tk:"library_data " facet:ident " : " ty:term
254
+ : command => `($[$doc?]? facet_data%$tk $(mkIdentFrom tk LeanLib.facetKind) $facet : $ty)
118
255
119
256
/-- Macro for declaring new `TargetData`. -/
120
- scoped macro (name := targetDataDecl) doc?:optional(Parser.Command.docComment)
121
- "target_data " id:ident " : " ty:term : command => do
122
- let dty := mkCIdentFrom (← getRef) ``TargetData
123
- let key := Name.quoteFrom id id.getId
124
- `($[$doc?]? family_def $id : $dty $key := $ty)
257
+ scoped macro (name := targetDataDecl)
258
+ doc?:optional(docComment) tk:"target_data " id:ident " : " ty:term
259
+ : command => withRef tk do
260
+ let fam := mkCIdentFrom (← getRef) ``TargetData
261
+ let idx := Name.quoteFrom id id.getId
262
+ `($[$doc?]? family_def $id : $fam $idx := $ty)
125
263
126
264
/-- Macro for declaring new `CustomData`. -/
127
- scoped macro (name := customDataDecl) doc?:optional(Parser.Command.docComment)
128
- "custom_data " pkg:ident tgt:ident " : " ty:term : command => do
129
- let dty := mkCIdentFrom (← getRef) ``CustomData
265
+ scoped macro (name := customDataDecl)
266
+ doc?:optional(docComment) tk:"custom_data " pkg:ident tgt:ident " : " ty:term
267
+ : command => withRef tk do
268
+ let fam := mkCIdentFrom (← getRef) ``CustomOut
130
269
let id := mkIdentFrom tgt (pkg.getId ++ tgt.getId)
131
270
let pkg := Name.quoteFrom pkg pkg.getId
132
271
let tgt := Name.quoteFrom pkg tgt.getId
133
- `($[$doc?]? family_def $id : $dty ($pkg, $tgt) := $ty)
272
+ `($[$doc?]? family_def $id : $fam ($pkg, $tgt) := $ty)
0 commit comments