5
* LICENSE file in the root directory of this source tree.
6
*/
7
8
-import {CompilerError} from '..';
8
+import {CompilerDiagnostic, CompilerError} from '..';
9
+import {ErrorCategory} from '../CompilerError';
10
+import {Environment} from '../HIR/Environment';
11
import {HIRFunction, IdentifierId, Place} from '../HIR';
12
import {printPlace} from '../HIR/PrintHIR';
13
import {eachInstructionValueLValue, eachPatternOperand} from '../HIR/visitors';
19
*/
20
export function validateContextVariableLValues(fn: HIRFunction): void {
21
const identifierKinds: IdentifierKinds = new Map();
20
- validateContextVariableLValuesImpl(fn, identifierKinds);
22
+ validateContextVariableLValuesImpl(fn, identifierKinds, fn.env);
23
}
24
25
function validateContextVariableLValuesImpl(
26
fn: HIRFunction,
27
identifierKinds: IdentifierKinds,
28
+ env: Environment,
29
): void {
30
for (const [, block] of fn.body.blocks) {
31
for (const instr of block.instructions) {
33
switch (value.kind) {
34
case 'DeclareContext':
35
case 'StoreContext': {
33
- visit(identifierKinds, value.lvalue.place, 'context');
36
+ visit(identifierKinds, value.lvalue.place, 'context', env);
37
break;
38
}
39
case 'LoadContext': {
37
- visit(identifierKinds, value.place, 'context');
40
+ visit(identifierKinds, value.place, 'context', env);
41
break;
42
}
43
case 'StoreLocal':
44
case 'DeclareLocal': {
42
- visit(identifierKinds, value.lvalue.place, 'local');
45
+ visit(identifierKinds, value.lvalue.place, 'local', env);
46
break;
47
}
48
case 'LoadLocal': {
46
- visit(identifierKinds, value.place, 'local');
49
+ visit(identifierKinds, value.place, 'local', env);
50
break;
51
}
52
case 'PostfixUpdate':
53
case 'PrefixUpdate': {
51
- visit(identifierKinds, value.lvalue, 'local');
54
+ visit(identifierKinds, value.lvalue, 'local', env);
55
break;
56
}
57
case 'Destructure': {
58
for (const lvalue of eachPatternOperand(value.lvalue.pattern)) {
56
- visit(identifierKinds, lvalue, 'destructure');
59
+ visit(identifierKinds, lvalue, 'destructure', env);
60
}
61
break;
62
}
65
validateContextVariableLValuesImpl(
66
value.loweredFunc.func,
67
identifierKinds,
68
+ env,
69
);
70
break;
71
}
72
default: {
73
for (const _ of eachInstructionValueLValue(value)) {
70
- CompilerError.throwTodo({
71
- reason:
72
- 'ValidateContextVariableLValues: unhandled instruction variant',
73
- loc: value.loc,
74
- description: `Handle '${value.kind} lvalues`,
75
- suggestions: null,
76
- });
74
+ fn.env.recordError(
75
+ CompilerDiagnostic.create({
76
+ category: ErrorCategory.Todo,
77
+ reason:
78
+ 'ValidateContextVariableLValues: unhandled instruction variant',
79
+ description: `Handle '${value.kind} lvalues`,
80
+ }).withDetails({
81
+ kind: 'error',
82
+ loc: value.loc,
83
+ message: null,
84
+ }),
85
+ );
86
}
87
}
88
}
99
identifiers: IdentifierKinds,
100
place: Place,
101
kind: 'local' | 'context' | 'destructure',
102
+ env: Environment,
103
): void {
104
const prev = identifiers.get(place.identifier.id);
105
if (prev !== undefined) {
107
const isContext = kind === 'context';
108
if (wasContext !== isContext) {
109
if (prev.kind === 'destructure' || kind === 'destructure') {
100
- CompilerError.throwTodo({
101
- reason: `Support destructuring of context variables`,
102
- loc: kind === 'destructure' ? place.loc : prev.place.loc,
103
- description: null,
104
- suggestions: null,
105
- });
110
+ env.recordError(
111
+ CompilerDiagnostic.create({
112
+ category: ErrorCategory.Todo,
113
+ reason: `Support destructuring of context variables`,
114
+ description: null,
115
+ }).withDetails({
116
+ kind: 'error',
117
+ loc: kind === 'destructure' ? place.loc : prev.place.loc,
118
+ message: null,
119
+ }),
120
+ );
121
+ return;
122
}
123
124
CompilerError.invariant(false, {