Skip to content

Commit 494c393

Browse files
committed
chore(typeEvaluator): rename mapConcrete to mapNode
1 parent 41679a3 commit 494c393

File tree

3 files changed

+52
-54
lines changed

3 files changed

+52
-54
lines changed

src/typeEvaluator/functions.ts

+31-31
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import type {FuncCallNode} from '../nodeTypes'
33
import {Scope} from './scope'
44
import {walk} from './typeEvaluate'
5-
import {mapConcrete, nullUnion} from './typeHelpers'
5+
import {mapNode, nullUnion} from './typeHelpers'
66
import type {NullTypeNode, TypeNode} from './types'
77

88
function unionWithoutNull(unionTypeNode: TypeNode): TypeNode {
@@ -21,15 +21,15 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
2121
case 'array.compact': {
2222
const arg = walk({node: node.args[0], scope})
2323

24-
return mapConcrete(arg, scope, (arg) => {
24+
return mapNode(arg, scope, (arg) => {
2525
if (arg.type === 'unknown') {
2626
return nullUnion({type: 'array', of: {type: 'unknown'}})
2727
}
2828
if (arg.type !== 'array') {
2929
return {type: 'null'}
3030
}
3131

32-
const of = mapConcrete(arg.of, scope, (of) => of)
32+
const of = mapNode(arg.of, scope, (of) => of)
3333
return {
3434
type: 'array',
3535
of: unionWithoutNull(of),
@@ -41,16 +41,16 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
4141
const arrayArg = walk({node: node.args[0], scope})
4242
const sepArg = walk({node: node.args[1], scope})
4343

44-
return mapConcrete(arrayArg, scope, (arrayArg) =>
45-
mapConcrete(sepArg, scope, (sepArg) => {
44+
return mapNode(arrayArg, scope, (arrayArg) =>
45+
mapNode(sepArg, scope, (sepArg) => {
4646
if (arrayArg.type === 'unknown' || sepArg.type === 'unknown') {
4747
return nullUnion({type: 'string'})
4848
}
4949
if (arrayArg.type !== 'array' || sepArg.type !== 'string') {
5050
return {type: 'null'}
5151
}
5252

53-
return mapConcrete(arrayArg.of, scope, (of) => {
53+
return mapNode(arrayArg.of, scope, (of) => {
5454
if (of.type === 'unknown') {
5555
return nullUnion({type: 'string'})
5656
}
@@ -68,7 +68,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
6868
case 'array.unique': {
6969
const arg = walk({node: node.args[0], scope})
7070

71-
return mapConcrete(arg, scope, (arg) => {
71+
return mapNode(arg, scope, (arg) => {
7272
if (arg.type === 'unknown') {
7373
return nullUnion({type: 'array', of: {type: 'unknown'}})
7474
}
@@ -83,7 +83,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
8383
case 'global.lower': {
8484
const arg = walk({node: node.args[0], scope})
8585

86-
return mapConcrete(arg, scope, (arg) => {
86+
return mapNode(arg, scope, (arg) => {
8787
if (arg.type === 'unknown') {
8888
return nullUnion({type: 'string'})
8989
}
@@ -103,7 +103,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
103103
case 'global.upper': {
104104
const arg = walk({node: node.args[0], scope})
105105

106-
return mapConcrete(arg, scope, (arg) => {
106+
return mapNode(arg, scope, (arg) => {
107107
if (arg.type === 'unknown') {
108108
return nullUnion({type: 'string'})
109109
}
@@ -130,7 +130,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
130130
}
131131
case 'global.path': {
132132
const arg = walk({node: node.args[0], scope})
133-
return mapConcrete(arg, scope, (arg) => {
133+
return mapNode(arg, scope, (arg) => {
134134
if (arg.type === 'unknown') {
135135
return nullUnion({type: 'string'})
136136
}
@@ -168,7 +168,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
168168
case 'global.count': {
169169
const arg = walk({node: node.args[0], scope})
170170

171-
return mapConcrete(arg, scope, (arg) => {
171+
return mapNode(arg, scope, (arg) => {
172172
if (arg.type === 'unknown') {
173173
return nullUnion({type: 'string'})
174174
}
@@ -184,7 +184,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
184184
case 'global.dateTime': {
185185
const arg = walk({node: node.args[0], scope})
186186

187-
return mapConcrete(arg, scope, (arg) => {
187+
return mapNode(arg, scope, (arg) => {
188188
if (arg.type === 'unknown') {
189189
return nullUnion({type: 'string'})
190190
}
@@ -200,7 +200,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
200200
case 'global.length': {
201201
const arg = walk({node: node.args[0], scope})
202202

203-
return mapConcrete(arg, scope, (arg) => {
203+
return mapNode(arg, scope, (arg) => {
204204
if (arg.type === 'unknown') {
205205
return nullUnion({type: 'number'})
206206
}
@@ -219,7 +219,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
219219
case 'global.round': {
220220
const numNode = walk({node: node.args[0], scope})
221221

222-
return mapConcrete(numNode, scope, (num) => {
222+
return mapNode(numNode, scope, (num) => {
223223
if (num.type === 'unknown') {
224224
return nullUnion({type: 'number'})
225225
}
@@ -229,7 +229,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
229229
}
230230
if (node.args.length === 2) {
231231
const precisionNode = walk({node: node.args[1], scope})
232-
return mapConcrete(precisionNode, scope, (precision) => {
232+
return mapNode(precisionNode, scope, (precision) => {
233233
if (precision.type === 'unknown') {
234234
return nullUnion({type: 'number'})
235235
}
@@ -248,7 +248,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
248248

249249
case 'global.string': {
250250
const arg = walk({node: node.args[0], scope})
251-
return mapConcrete(arg, scope, (node) => {
251+
return mapNode(arg, scope, (node) => {
252252
if (node.type === 'unknown') {
253253
return nullUnion({type: 'string'})
254254
}
@@ -272,8 +272,8 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
272272

273273
case 'math.sum': {
274274
const values = walk({node: node.args[0], scope})
275-
// use mapConcrete to get concrete resolved value, it will also handle cases where the value is a union
276-
return mapConcrete(values, scope, (node) => {
275+
// use mapNode to get concrete resolved value, it will also handle cases where the value is a union
276+
return mapNode(values, scope, (node) => {
277277
if (node.type === 'unknown') {
278278
return nullUnion({type: 'number'})
279279
}
@@ -284,7 +284,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
284284
}
285285

286286
// Resolve the concrete type of the array elements
287-
return mapConcrete(node.of, scope, (node) => {
287+
return mapNode(node.of, scope, (node) => {
288288
if (node.type === 'unknown') {
289289
return nullUnion({type: 'number'})
290290
}
@@ -300,8 +300,8 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
300300

301301
case 'math.avg': {
302302
const values = walk({node: node.args[0], scope})
303-
// use mapConcrete to get concrete resolved value, it will also handle cases where the value is a union
304-
return mapConcrete(values, scope, (node) => {
303+
// use mapNode to get concrete resolved value, it will also handle cases where the value is a union
304+
return mapNode(values, scope, (node) => {
305305
if (node.type === 'unknown') {
306306
return nullUnion({type: 'number'})
307307
}
@@ -311,7 +311,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
311311
return {type: 'null'}
312312
}
313313
// Resolve the concrete type of the array elements
314-
return mapConcrete(node.of, scope, (node) => {
314+
return mapNode(node.of, scope, (node) => {
315315
if (node.type === 'unknown') {
316316
return nullUnion({type: 'number'})
317317
}
@@ -328,8 +328,8 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
328328
case 'math.max':
329329
case 'math.min': {
330330
const values = walk({node: node.args[0], scope})
331-
// use mapConcrete to get concrete resolved value, it will also handle cases where the value is a union
332-
return mapConcrete(values, scope, (node) => {
331+
// use mapNode to get concrete resolved value, it will also handle cases where the value is a union
332+
return mapNode(values, scope, (node) => {
333333
if (node.type === 'unknown') {
334334
return nullUnion({type: 'number'})
335335
}
@@ -340,7 +340,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
340340
}
341341

342342
// Resolve the concrete type of the array elements
343-
return mapConcrete(node.of, scope, (node) => {
343+
return mapNode(node.of, scope, (node) => {
344344
if (node.type === 'unknown') {
345345
return nullUnion({type: 'number'})
346346
}
@@ -366,8 +366,8 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
366366
case 'string.startsWith': {
367367
const strTypeNode = walk({node: node.args[0], scope})
368368
const prefixTypeNode = walk({node: node.args[1], scope})
369-
return mapConcrete(strTypeNode, scope, (strNode) => {
370-
return mapConcrete(prefixTypeNode, scope, (prefixNode) => {
369+
return mapNode(strTypeNode, scope, (strNode) => {
370+
return mapNode(prefixTypeNode, scope, (prefixNode) => {
371371
if (strNode.type === 'unknown' || prefixNode.type === 'unknown') {
372372
return nullUnion({type: 'boolean'})
373373
}
@@ -383,8 +383,8 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
383383
case 'string.split': {
384384
const strTypeNode = walk({node: node.args[0], scope})
385385
const sepTypeNode = walk({node: node.args[1], scope})
386-
return mapConcrete(strTypeNode, scope, (strNode) => {
387-
return mapConcrete(sepTypeNode, scope, (sepNode) => {
386+
return mapNode(strTypeNode, scope, (strNode) => {
387+
return mapNode(sepTypeNode, scope, (sepNode) => {
388388
if (strNode.type === 'unknown' || sepNode.type === 'unknown') {
389389
return nullUnion({type: 'array', of: {type: 'string'}})
390390
}
@@ -399,7 +399,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
399399
}
400400
case 'sanity.versionOf': {
401401
const typeNode = walk({node: node.args[0], scope})
402-
return mapConcrete(typeNode, scope, (typeNode) => {
402+
return mapNode(typeNode, scope, (typeNode) => {
403403
if (typeNode.type === 'unknown') {
404404
return nullUnion({type: 'array', of: {type: 'string'}})
405405
}
@@ -411,7 +411,7 @@ export function handleFuncCallNode(node: FuncCallNode, scope: Scope): TypeNode {
411411
}
412412
case 'sanity.documentsOf': {
413413
const typeNode = walk({node: node.args[0], scope})
414-
return mapConcrete(typeNode, scope, (typeNode) => {
414+
return mapNode(typeNode, scope, (typeNode) => {
415415
if (typeNode.type === 'unknown') {
416416
return nullUnion({type: 'array', of: {type: 'string'}})
417417
}

src/typeEvaluator/typeEvaluate.ts

+17-17
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {handleFuncCallNode} from './functions'
3232
import {match} from './matching'
3333
import {optimizeUnions} from './optimizations'
3434
import {Context, Scope} from './scope'
35-
import {isFuncCall, mapConcrete, nullUnion, resolveInline} from './typeHelpers'
35+
import {isFuncCall, mapNode, nullUnion, resolveInline} from './typeHelpers'
3636
import type {
3737
ArrayTypeNode,
3838
BooleanTypeNode,
@@ -123,7 +123,7 @@ function handleObjectSplatNode(
123123
): TypeNode {
124124
const value = walk({node: attr.value, scope})
125125
$trace('object.splat.value %O', value)
126-
return mapConcrete(value, scope, (node) => {
126+
return mapNode(value, scope, (node) => {
127127
// splatting over unknown is unknown, we can't know what the attributes are
128128
if (node.type === 'unknown') {
129129
return {type: 'unknown'}
@@ -258,7 +258,7 @@ function handleObjectNode(node: ObjectNode, scope: Scope): TypeNode {
258258
}
259259
}
260260

261-
const variant = mapConcrete(attributeNode, scope, (attributeNode) => {
261+
const variant = mapNode(attributeNode, scope, (attributeNode) => {
262262
$trace('object.conditional.splat.result.concrete %O', attributeNode)
263263
if (attributeNode.type !== 'object') {
264264
return {type: 'unknown'}
@@ -462,9 +462,9 @@ function handleOpCallNode(node: OpCallNode, scope: Scope): TypeNode {
462462
$trace('opcall.node %O', node)
463463
const lhs = walk({node: node.left, scope})
464464
const rhs = walk({node: node.right, scope})
465-
return mapConcrete(lhs, scope, (left) =>
465+
return mapNode(lhs, scope, (left) =>
466466
// eslint-disable-next-line complexity, max-statements
467-
mapConcrete(rhs, scope, (right) => {
467+
mapNode(rhs, scope, (right) => {
468468
$trace('opcall.node.concrete "%s" %O', node.op, {left, right})
469469

470470
switch (node.op) {
@@ -562,7 +562,7 @@ function handleOpCallNode(node: OpCallNode, scope: Scope): TypeNode {
562562
value: false,
563563
} satisfies BooleanTypeNode
564564
}
565-
return mapConcrete(right.of, scope, (arrayTypeNode) => {
565+
return mapNode(right.of, scope, (arrayTypeNode) => {
566566
if (arrayTypeNode.type === 'unknown') {
567567
return nullUnion({type: 'boolean'})
568568
}
@@ -773,7 +773,7 @@ function handleFlatMap(node: FlatMapNode, scope: Scope): TypeNode {
773773
return mapArray(base, scope, (base) => {
774774
const inner = walk({node: node.expr, scope: scope.createHidden([base.of])})
775775

776-
return mapConcrete(
776+
return mapNode(
777777
inner,
778778
scope,
779779
(inner) => {
@@ -835,7 +835,7 @@ function handleFilterNode(node: FilterNode, scope: Scope): TypeNode {
835835
const base = walk({node: node.base, scope})
836836
$trace('filter.base %O', base)
837837

838-
return mapConcrete(base, scope, (base) => {
838+
return mapNode(base, scope, (base) => {
839839
$trace('filter.resolving %O', base)
840840
if (base.type === 'null') {
841841
return base
@@ -988,7 +988,7 @@ function handleParentNode({n}: ParentNode, scope: Scope): TypeNode {
988988

989989
function handleNotNode(node: NotNode, scope: Scope): TypeNode {
990990
const base = walk({node: node.base, scope})
991-
return mapConcrete(base, scope, (base) => {
991+
return mapNode(base, scope, (base) => {
992992
if (base.type === 'unknown') {
993993
return nullUnion({type: 'boolean'})
994994
}
@@ -1006,7 +1006,7 @@ function handleNotNode(node: NotNode, scope: Scope): TypeNode {
10061006

10071007
function handleNegNode(node: NegNode, scope: Scope): TypeNode {
10081008
const base = walk({node: node.base, scope})
1009-
return mapConcrete(base, scope, (base) => {
1009+
return mapNode(base, scope, (base) => {
10101010
if (base.type === 'unknown') {
10111011
return nullUnion({type: 'number'})
10121012
}
@@ -1022,7 +1022,7 @@ function handleNegNode(node: NegNode, scope: Scope): TypeNode {
10221022
}
10231023
function handlePosNode(node: PosNode, scope: Scope): TypeNode {
10241024
const base = walk({node: node.base, scope})
1025-
return mapConcrete(base, scope, (base) => {
1025+
return mapNode(base, scope, (base) => {
10261026
if (base.type === 'unknown') {
10271027
return nullUnion({type: 'number'})
10281028
}
@@ -1051,8 +1051,8 @@ function handleEverythingNode(_: EverythingNode, scope: Scope): TypeNode {
10511051
function handleAndNode(node: AndNode, scope: Scope): TypeNode {
10521052
const left = walk({node: node.left, scope})
10531053
const right = walk({node: node.right, scope})
1054-
return mapConcrete(left, scope, (lhs) =>
1055-
mapConcrete(right, scope, (rhs) => {
1054+
return mapNode(left, scope, (lhs) =>
1055+
mapNode(right, scope, (rhs) => {
10561056
const value = booleanAnd(booleanValue(lhs, scope), booleanValue(rhs, scope))
10571057

10581058
return booleanInterpretationToTypeNode(value)
@@ -1063,8 +1063,8 @@ function handleAndNode(node: AndNode, scope: Scope): TypeNode {
10631063
function handleOrNode(node: OrNode, scope: Scope): TypeNode {
10641064
const left = walk({node: node.left, scope})
10651065
const right = walk({node: node.right, scope})
1066-
return mapConcrete(left, scope, (lhs) =>
1067-
mapConcrete(right, scope, (rhs) => {
1066+
return mapNode(left, scope, (lhs) =>
1067+
mapNode(right, scope, (rhs) => {
10681068
const value = booleanOr(booleanValue(lhs, scope), booleanValue(rhs, scope))
10691069

10701070
return booleanInterpretationToTypeNode(value)
@@ -1266,7 +1266,7 @@ function mapArray(
12661266
scope: Scope,
12671267
mapper: (node: ArrayTypeNode) => TypeNode,
12681268
): TypeNode {
1269-
return mapConcrete(node, scope, (base) => {
1269+
return mapNode(node, scope, (base) => {
12701270
if (base.type === 'unknown') {
12711271
return base
12721272
}
@@ -1282,7 +1282,7 @@ function mapObject(
12821282
scope: Scope,
12831283
mapper: (node: ObjectTypeNode) => TypeNode,
12841284
): TypeNode {
1285-
return mapConcrete(node, scope, (base) => {
1285+
return mapNode(node, scope, (base) => {
12861286
if (base.type === 'unknown') {
12871287
return base
12881288
}

src/typeEvaluator/typeHelpers.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,12 @@ export function resolveInline(node: TypeNode, scope: Scope): Exclude<TypeNode, I
9696
}
9797

9898
/**
99-
* mapConcrete extracts a _concrete type_ OR an _unknown type node_ from a type node, applies the mapping
99+
* mapNode extracts either a _concrete type_ OR an _unknown type_ from a type node, applies the mapping
100100
* function to it and returns. Most notably, this will work through unions
101101
* (applying the mapping function for each variant) and inline (resolving the
102102
* reference).
103-
* This method should _only_ be used if you need to handle unknown types, ie when resolving two sides of an and node, and we don't want to abort if one side is unknown.
104-
* In most cases, you should use `mapConcrete` instead.
105103
**/
106-
export function mapConcrete<T extends TypeNode = TypeNode>(
104+
export function mapNode<T extends TypeNode = TypeNode>(
107105
node: TypeNode,
108106
scope: Scope,
109107
mapper: (node: ConcreteTypeNode | UnknownTypeNode) => T,
@@ -120,10 +118,10 @@ export function mapConcrete<T extends TypeNode = TypeNode>(
120118
case 'unknown':
121119
return mapper(node)
122120
case 'union':
123-
return mergeUnions(node.of.map((inner) => mapConcrete(inner, scope, mapper), mergeUnions))
121+
return mergeUnions(node.of.map((inner) => mapNode(inner, scope, mapper), mergeUnions))
124122
case 'inline': {
125123
const resolvedInline = resolveInline(node, scope)
126-
return mapConcrete(resolvedInline, scope, mapper, mergeUnions)
124+
return mapNode(resolvedInline, scope, mapper, mergeUnions)
127125
}
128126
default:
129127
// @ts-expect-error - all types should be handled

0 commit comments

Comments
 (0)