Skip to content

Commit 1810277

Browse files
authored
Merge pull request #114 from dko-slapdash/master
Fix #113: Make generated function names inside arrow-function deterministic in watch-mode runs and in recompiles
2 parents 1202b01 + 483efdb commit 1810277

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

src/transform-inline/transform-node.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import { sliceMapValues } from './utils';
88
function createArrowFunction(type: ts.Type, rootName: string, optional: boolean, partialVisitorContext: PartialVisitorContext) {
99
const functionMap: VisitorContext['functionMap'] = new Map();
1010
const functionNames: VisitorContext['functionNames'] = new Set();
11-
const visitorContext = { ...partialVisitorContext, functionNames, functionMap };
11+
const typeIdMap: VisitorContext['typeIdMap'] = new Map();
12+
const visitorContext = { ...partialVisitorContext, functionNames, functionMap, typeIdMap };
1213
const functionName = partialVisitorContext.options.shortCircuit
1314
? visitShortCircuit(visitorContext)
1415
: (optional

src/transform-inline/visitor-context.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ interface Options {
1111
export interface VisitorContext extends PartialVisitorContext {
1212
functionNames: Set<string>;
1313
functionMap: Map<string, ts.FunctionDeclaration>;
14+
typeIdMap: Map<string, string>;
1415
}
1516

1617
export interface PartialVisitorContext {

src/transform-inline/visitor-type-name.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,19 @@ function visitArrayObjectType(type: ts.ObjectType, visitorContext: VisitorContex
3939
return `sa_${numberIndexName}_ea`;
4040
}
4141

42-
function visitRegularObjectType(type: ts.ObjectType) {
43-
const id: string = (type as unknown as { id: string }).id;
44-
return `_${id}`;
42+
function getTypeIndexById(type: ts.Type, { typeIdMap }: VisitorContext) {
43+
const id = (type as unknown as { id: string | number }).id.toString();
44+
let index = typeIdMap.get(id);
45+
if (index === undefined) {
46+
index = typeIdMap.size.toString();
47+
typeIdMap.set(id, index);
48+
}
49+
return index;
50+
}
51+
52+
function visitRegularObjectType(type: ts.Type, visitorContext: VisitorContext) {
53+
const index = getTypeIndexById(type, visitorContext);
54+
return `_${index}`;
4555
}
4656

4757
function visitTypeReference(type: ts.TypeReference, visitorContext: VisitorContext, mode: NameMode) {
@@ -71,7 +81,7 @@ function visitObjectType(type: ts.ObjectType, visitorContext: VisitorContext, mo
7181
} else if (checkIsDateClass(type)) {
7282
return '_date';
7383
} else {
74-
return visitRegularObjectType(type);
84+
return visitRegularObjectType(type, visitorContext);
7585
}
7686
}
7787

@@ -98,7 +108,7 @@ function visitIndexedAccessType(type: ts.IndexedAccessType, visitorContext: Visi
98108

99109
export function visitType(type: ts.Type, visitorContext: VisitorContext, mode: NameMode): string {
100110
let name: string;
101-
const id: string = (type as unknown as { id: string }).id;
111+
const index = getTypeIndexById(type, visitorContext);
102112
if ((ts.TypeFlags.Any & type.flags) !== 0) {
103113
name = VisitorUtils.getAnyFunction(visitorContext);
104114
} else if ((ts.TypeFlags.Unknown & type.flags) !== 0) {
@@ -118,25 +128,25 @@ export function visitType(type: ts.Type, visitorContext: VisitorContext, mode: N
118128
} else if ((ts.TypeFlags.String & type.flags) !== 0) {
119129
name = VisitorUtils.getStringFunction(visitorContext);
120130
} else if ((ts.TypeFlags.BooleanLiteral & type.flags) !== 0) {
121-
name = `_${id}`;
131+
name = `_${index}`;
122132
} else if (tsutils.isTypeReference(type) && visitorContext.previousTypeReference !== type) {
123133
name = visitTypeReference(type, visitorContext, mode);
124134
} else if ((ts.TypeFlags.TypeParameter & type.flags) !== 0) {
125135
name = visitTypeParameter(type, visitorContext, mode);
126136
} else if (tsutils.isObjectType(type)) {
127137
name = visitObjectType(type, visitorContext, mode);
128138
} else if (tsutils.isLiteralType(type)) {
129-
name = `_${id}`;
139+
name = `_${index}`;
130140
} else if (tsutils.isUnionOrIntersectionType(type)) {
131141
name = visitUnionOrIntersectionType(type, visitorContext, mode);
132142
} else if ((ts.TypeFlags.NonPrimitive & type.flags) !== 0) {
133-
name = `_${id}`;
143+
name = `_${index}`;
134144
} else if ((ts.TypeFlags.Index & type.flags) !== 0) {
135145
name = visitIndexType(type, visitorContext);
136146
} else if (tsutils.isIndexedAccessType(type)) {
137147
name = visitIndexedAccessType(type, visitorContext);
138148
} else if ((ts.TypeFlags.TemplateLiteral & type.flags) !== 0) {
139-
name = `_${id}`;
149+
name = `_${index}`;
140150
} else {
141151
throw new Error('Could not generate type-check; unsupported type with flags: ' + type.flags);
142152
}
@@ -153,7 +163,8 @@ export function visitType(type: ts.Type, visitorContext: VisitorContext, mode: N
153163
if (tsutils.isTypeReference(type) && type.typeArguments !== undefined) {
154164
for (const typeArgument of type.typeArguments) {
155165
const resolvedType = VisitorUtils.getResolvedTypeParameter(typeArgument, visitorContext) || typeArgument;
156-
name += `_${(resolvedType as unknown as { id: string }).id}`;
166+
const resolvedTypeIndex = getTypeIndexById(resolvedType, visitorContext);
167+
name += `_${resolvedTypeIndex}`;
157168
}
158169
}
159170
return name;

0 commit comments

Comments
 (0)