Skip to content

Commit bafc41e

Browse files
committed
extract [Maybe]TransformSubexprs
Makes a bunch of other code quite a bit simpler
1 parent 7bf5a0b commit bafc41e

File tree

4 files changed

+382
-553
lines changed

4 files changed

+382
-553
lines changed

imports/imports.go

Lines changed: 3 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -96,109 +96,6 @@ func LoadWith(cache DhallCache, e Term, ancestors ...Fetchable) (Term, error) {
9696
cache.Save(actualHash, core.QuoteAlphaNormal(exprVal))
9797
}
9898
return expr, nil
99-
case Lambda:
100-
resolvedType, err := LoadWith(cache, e.Type, ancestors...)
101-
if err != nil {
102-
return nil, err
103-
}
104-
resolvedBody, err := LoadWith(cache, e.Body, ancestors...)
105-
if err != nil {
106-
return nil, err
107-
}
108-
return Lambda{
109-
Label: e.Label,
110-
Type: resolvedType,
111-
Body: resolvedBody,
112-
}, nil
113-
case Pi:
114-
resolvedType, err := LoadWith(cache, e.Type, ancestors...)
115-
if err != nil {
116-
return nil, err
117-
}
118-
resolvedBody, err := LoadWith(cache, e.Body, ancestors...)
119-
if err != nil {
120-
return nil, err
121-
}
122-
return Pi{
123-
Label: e.Label,
124-
Type: resolvedType,
125-
Body: resolvedBody,
126-
}, nil
127-
case App:
128-
resolvedFn, err := LoadWith(cache, e.Fn, ancestors...)
129-
if err != nil {
130-
return nil, err
131-
}
132-
resolvedArg, err := LoadWith(cache, e.Arg, ancestors...)
133-
if err != nil {
134-
return nil, err
135-
}
136-
return Apply(
137-
resolvedFn,
138-
resolvedArg,
139-
), nil
140-
case Let:
141-
newBindings := make([]Binding, len(e.Bindings))
142-
for i, binding := range e.Bindings {
143-
var err error
144-
newBindings[i].Variable = binding.Variable
145-
if binding.Annotation != nil {
146-
newBindings[i].Annotation, err = LoadWith(cache, binding.Annotation, ancestors...)
147-
if err != nil {
148-
return nil, err
149-
}
150-
}
151-
newBindings[i].Value, err = LoadWith(cache, binding.Value, ancestors...)
152-
if err != nil {
153-
return nil, err
154-
}
155-
}
156-
resolvedBody, err := LoadWith(cache, e.Body, ancestors...)
157-
if err != nil {
158-
return nil, err
159-
}
160-
return Let{Bindings: newBindings, Body: resolvedBody}, nil
161-
case Annot:
162-
resolvedExpr, err := LoadWith(cache, e.Expr, ancestors...)
163-
if err != nil {
164-
return nil, err
165-
}
166-
resolvedAnnotation, err := LoadWith(cache, e.Annotation, ancestors...)
167-
if err != nil {
168-
return nil, err
169-
}
170-
return Annot{Expr: resolvedExpr, Annotation: resolvedAnnotation}, nil
171-
case TextLit:
172-
var newChunks Chunks
173-
for _, chunk := range e.Chunks {
174-
resolvedExpr, err := LoadWith(cache, chunk.Expr, ancestors...)
175-
if err != nil {
176-
return nil, err
177-
}
178-
newChunks = append(newChunks, Chunk{
179-
Prefix: chunk.Prefix,
180-
Expr: resolvedExpr,
181-
})
182-
}
183-
return TextLit{newChunks, e.Suffix}, nil
184-
case If:
185-
resolvedCond, err := LoadWith(cache, e.Cond, ancestors...)
186-
if err != nil {
187-
return nil, err
188-
}
189-
resolvedT, err := LoadWith(cache, e.T, ancestors...)
190-
if err != nil {
191-
return nil, err
192-
}
193-
resolvedF, err := LoadWith(cache, e.F, ancestors...)
194-
if err != nil {
195-
return nil, err
196-
}
197-
return If{
198-
Cond: resolvedCond,
199-
T: resolvedT,
200-
F: resolvedF,
201-
}, nil
20299
case Op:
203100
if e.OpCode == ImportAltOp {
204101
resolvedL, err := LoadWith(cache, e.L, ancestors...)
@@ -220,112 +117,10 @@ func LoadWith(cache DhallCache, e Term, ancestors ...Fetchable) (Term, error) {
220117
return nil, err
221118
}
222119
return Op{OpCode: e.OpCode, L: resolvedL, R: resolvedR}, nil
223-
case EmptyList:
224-
resolvedType, err := LoadWith(cache, e.Type, ancestors...)
225-
if err != nil {
226-
return nil, err
227-
}
228-
return EmptyList{Type: resolvedType}, nil
229-
case NonEmptyList:
230-
newList := make(NonEmptyList, len(e))
231-
for i, item := range e {
232-
var err error
233-
newList[i], err = LoadWith(cache, item, ancestors...)
234-
if err != nil {
235-
return nil, err
236-
}
237-
}
238-
return newList, nil
239-
case Some:
240-
val, err := LoadWith(cache, e.Val, ancestors...)
241-
if err != nil {
242-
return nil, err
243-
}
244-
return Some{val}, nil
245-
case RecordType:
246-
newRecord := make(RecordType, len(e))
247-
for k, v := range e {
248-
var err error
249-
newRecord[k], err = LoadWith(cache, v, ancestors...)
250-
if err != nil {
251-
return nil, err
252-
}
253-
}
254-
return newRecord, nil
255-
case RecordLit:
256-
newRecord := make(RecordLit, len(e))
257-
for k, v := range e {
258-
var err error
259-
newRecord[k], err = LoadWith(cache, v, ancestors...)
260-
if err != nil {
261-
return nil, err
262-
}
263-
}
264-
return newRecord, nil
265-
case ToMap:
266-
record, err := LoadWith(cache, e.Record, ancestors...)
267-
if err != nil {
268-
return nil, err
269-
}
270-
typ, err := LoadWith(cache, e.Type, ancestors...)
271-
if err != nil {
272-
return nil, err
273-
}
274-
return ToMap{Record: record, Type: typ}, nil
275-
case Field:
276-
newRecord, err := LoadWith(cache, e.Record, ancestors...)
277-
if err != nil {
278-
return nil, err
279-
}
280-
return Field{Record: newRecord, FieldName: e.FieldName}, nil
281-
case Project:
282-
newRecord, err := LoadWith(cache, e.Record, ancestors...)
283-
if err != nil {
284-
return nil, err
285-
}
286-
return Project{Record: newRecord, FieldNames: e.FieldNames}, nil
287-
case ProjectType:
288-
record, err := LoadWith(cache, e.Record, ancestors...)
289-
if err != nil {
290-
return nil, err
291-
}
292-
typ, err := LoadWith(cache, e.Selector, ancestors...)
293-
if err != nil {
294-
return nil, err
295-
}
296-
return ProjectType{Record: record, Selector: typ}, nil
297-
case UnionType:
298-
result := make(UnionType, len(e))
299-
for k, v := range e {
300-
var err error
301-
if v == nil {
302-
result[k] = nil
303-
continue
304-
}
305-
result[k], err = LoadWith(cache, v, ancestors...)
306-
if err != nil {
307-
return nil, err
308-
}
309-
}
310-
return result, nil
311-
case Merge:
312-
handler, err := LoadWith(cache, e.Handler, ancestors...)
313-
if err != nil {
314-
return nil, err
315-
}
316-
union, err := LoadWith(cache, e.Union, ancestors...)
317-
if err != nil {
318-
return nil, err
319-
}
320-
return Merge{Handler: handler, Union: union}, nil
321-
case Assert:
322-
annot, err := LoadWith(cache, e.Annotation, ancestors...)
323-
if err != nil {
324-
return nil, err
325-
}
326-
return Assert{Annotation: annot}, nil
327120
default:
328121
// Const, NaturalLit, etc
329-
return e, nil
122+
return term.MaybeTransformSubexprs(e, func(t Term) (Term, error) {
123+
return LoadWith(cache, t, ancestors...)
124+
})
330125
}
331126
}

imports/imports_test.go

Lines changed: 4 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
. "github.com/philandstuff/dhall-golang/v4/term"
1111

1212
. "github.com/onsi/ginkgo"
13-
. "github.com/onsi/ginkgo/extensions/table"
1413
. "github.com/onsi/gomega"
1514
"github.com/onsi/gomega/ghttp"
1615
)
@@ -48,13 +47,13 @@ var _ = Describe("Import resolution", func() {
4847

4948
Expect(err).To(HaveOccurred())
5049
})
51-
XIt("Performs import chaining", func() {
50+
It("Performs import chaining", func() {
5251
os.Setenv("CHAIN1", "env:CHAIN2")
5352
os.Setenv("CHAIN2", "2 + 2")
5453
actual, err := Load(NewEnvVarImport("CHAIN1", Code))
5554

5655
Expect(err).ToNot(HaveOccurred())
57-
Expect(actual).To(Equal(NaturalPlus(NaturalLit(2), NaturalLit(2))))
56+
Expect(actual).To(Equal(NaturalLit(4)))
5857
})
5958
It("Rejects import cycles", func() {
6059
result := make(chan error)
@@ -196,11 +195,11 @@ var _ = Describe("Import resolution", func() {
196195

197196
Expect(err).To(HaveOccurred())
198197
})
199-
XIt("Performs import chaining", func() {
198+
It("Performs import chaining", func() {
200199
actual, err := Load(NewLocalImport("./testdata/chain1.dhall", Code))
201200

202201
Expect(err).ToNot(HaveOccurred())
203-
Expect(actual).To(Equal(NaturalPlus(NaturalLit(2), NaturalLit(2))))
202+
Expect(actual).To(Equal(NaturalLit(4)))
204203
})
205204
It("Rejects import cycles", func() {
206205
result := make(chan error)
@@ -213,109 +212,4 @@ var _ = Describe("Import resolution", func() {
213212
Eventually(result).Should(Receive())
214213
})
215214
})
216-
DescribeTable("Other subexpressions", expectResolves,
217-
Entry("Literal expression", NaturalLit(3), NaturalLit(3)),
218-
Entry("Simple import", importFooAsText, resolvedFooAsText),
219-
Entry("Import within lambda type",
220-
Lambda{Type: importFooAsText},
221-
Lambda{Type: resolvedFooAsText},
222-
),
223-
Entry("Import within lambda body",
224-
Lambda{Body: importFooAsText},
225-
Lambda{Body: resolvedFooAsText},
226-
),
227-
Entry("Import within pi type",
228-
Pi{Type: importFooAsText},
229-
Pi{Type: resolvedFooAsText},
230-
),
231-
Entry("Import within pi body",
232-
Pi{Body: importFooAsText},
233-
Pi{Body: resolvedFooAsText},
234-
),
235-
Entry("Import within app fn",
236-
App{Fn: importFooAsText},
237-
App{Fn: resolvedFooAsText},
238-
),
239-
Entry("Import within app arg",
240-
App{Arg: importFooAsText},
241-
App{Arg: resolvedFooAsText},
242-
),
243-
Entry("Import within let binding value",
244-
NewLet(Natural, Binding{Value: importFooAsText}),
245-
NewLet(Natural, Binding{Value: resolvedFooAsText}),
246-
),
247-
Entry("Import within let body",
248-
NewLet(importFooAsText, Binding{}),
249-
NewLet(resolvedFooAsText, Binding{}),
250-
),
251-
Entry("Import within annotated expression",
252-
Annot{importFooAsText, Text},
253-
Annot{resolvedFooAsText, Text},
254-
),
255-
Entry("Import within annotation",
256-
// these don't typecheck but we're just
257-
// checking the imports here
258-
Annot{Natural, importFooAsText},
259-
Annot{Natural, resolvedFooAsText},
260-
),
261-
Entry("Import within TextLit",
262-
TextLit{
263-
Chunks: Chunks{
264-
{
265-
Prefix: "foo",
266-
Expr: importFooAsText,
267-
}},
268-
Suffix: "baz",
269-
},
270-
TextLit{
271-
Chunks: Chunks{
272-
{
273-
Prefix: "foo",
274-
Expr: resolvedFooAsText,
275-
},
276-
},
277-
Suffix: "baz",
278-
},
279-
),
280-
Entry("Import within if condition",
281-
If{Cond: importFooAsText},
282-
If{Cond: resolvedFooAsText},
283-
),
284-
Entry("Import within if true branch",
285-
If{T: importFooAsText},
286-
If{T: resolvedFooAsText},
287-
),
288-
Entry("Import within if false branch",
289-
If{F: importFooAsText},
290-
If{F: resolvedFooAsText},
291-
),
292-
Entry("Import within Operator (left side)",
293-
Op{L: importFooAsText},
294-
Op{L: resolvedFooAsText},
295-
),
296-
Entry("Import within natural plus (right side)",
297-
Op{R: importFooAsText},
298-
Op{R: resolvedFooAsText},
299-
),
300-
Entry("Import within empty list type",
301-
EmptyList{Type: importFooAsText},
302-
EmptyList{Type: resolvedFooAsText},
303-
),
304-
Entry("Import within list",
305-
NewList(importFooAsText),
306-
NewList(resolvedFooAsText),
307-
),
308-
Entry("Import within record type",
309-
RecordType{"foo": importFooAsText},
310-
RecordType{"foo": resolvedFooAsText},
311-
),
312-
Entry("Import within record literal",
313-
RecordLit{"foo": importFooAsText},
314-
RecordLit{"foo": resolvedFooAsText},
315-
),
316-
Entry("Import within field extract",
317-
Field{Record: importFooAsText},
318-
Field{Record: resolvedFooAsText},
319-
),
320-
)
321215
})

0 commit comments

Comments
 (0)