mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
[compiler] Migrate CompilerError.invariant to new CompilerDiagnostic infra (#34403)
Mechanical PR to migrate existing invariants to use the new CompilerDiagnostic infra @josephsavona added. Will tackle the others at a later time. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34403). * #34409 * #34404 * __->__ #34403
This commit is contained in:
parent
1fef581e1a
commit
474f25842a
|
|
@ -37,7 +37,7 @@ export enum ErrorSeverity {
|
||||||
export type CompilerDiagnosticOptions = {
|
export type CompilerDiagnosticOptions = {
|
||||||
category: ErrorCategory;
|
category: ErrorCategory;
|
||||||
reason: string;
|
reason: string;
|
||||||
description: string;
|
description: string | null;
|
||||||
details: Array<CompilerDiagnosticDetail>;
|
details: Array<CompilerDiagnosticDetail>;
|
||||||
suggestions?: Array<CompilerSuggestion> | null | undefined;
|
suggestions?: Array<CompilerSuggestion> | null | undefined;
|
||||||
};
|
};
|
||||||
|
|
@ -49,7 +49,7 @@ export type CompilerDiagnosticDetail =
|
||||||
| {
|
| {
|
||||||
kind: 'error';
|
kind: 'error';
|
||||||
loc: SourceLocation | null;
|
loc: SourceLocation | null;
|
||||||
message: string;
|
message: string | null;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
kind: 'hint';
|
kind: 'hint';
|
||||||
|
|
@ -126,8 +126,8 @@ export class CompilerDiagnostic {
|
||||||
return this.options.category;
|
return this.options.category;
|
||||||
}
|
}
|
||||||
|
|
||||||
withDetail(detail: CompilerDiagnosticDetail): CompilerDiagnostic {
|
withDetails(...details: Array<CompilerDiagnosticDetail>): CompilerDiagnostic {
|
||||||
this.options.details.push(detail);
|
this.options.details.push(...details);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,9 +155,9 @@ export class CompilerDiagnostic {
|
||||||
}
|
}
|
||||||
let codeFrame: string;
|
let codeFrame: string;
|
||||||
try {
|
try {
|
||||||
codeFrame = printCodeFrame(source, loc, detail.message);
|
codeFrame = printCodeFrame(source, loc, detail.message ?? '');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
codeFrame = detail.message;
|
codeFrame = detail.message ?? '';
|
||||||
}
|
}
|
||||||
buffer.push('\n\n');
|
buffer.push('\n\n');
|
||||||
if (loc.filename != null) {
|
if (loc.filename != null) {
|
||||||
|
|
@ -284,15 +284,16 @@ export class CompilerError extends Error {
|
||||||
|
|
||||||
static invariant(
|
static invariant(
|
||||||
condition: unknown,
|
condition: unknown,
|
||||||
options: Omit<CompilerErrorDetailOptions, 'category'>,
|
options: Omit<CompilerDiagnosticOptions, 'category'>,
|
||||||
): asserts condition {
|
): asserts condition {
|
||||||
if (!condition) {
|
if (!condition) {
|
||||||
const errors = new CompilerError();
|
const errors = new CompilerError();
|
||||||
errors.pushErrorDetail(
|
errors.pushDiagnostic(
|
||||||
new CompilerErrorDetail({
|
CompilerDiagnostic.create({
|
||||||
...options,
|
reason: options.reason,
|
||||||
|
description: options.description,
|
||||||
category: ErrorCategory.Invariant,
|
category: ErrorCategory.Invariant,
|
||||||
}),
|
}).withDetails(...options.details),
|
||||||
);
|
);
|
||||||
throw errors;
|
throw errors;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,26 @@ function insertAdditionalFunctionDeclaration(
|
||||||
CompilerError.invariant(originalFnName != null && compiled.id != null, {
|
CompilerError.invariant(originalFnName != null && compiled.id != null, {
|
||||||
reason:
|
reason:
|
||||||
'Expected function declarations that are referenced elsewhere to have a named identifier',
|
'Expected function declarations that are referenced elsewhere to have a named identifier',
|
||||||
loc: fnPath.node.loc ?? null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: fnPath.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
CompilerError.invariant(originalFnParams.length === compiledParams.length, {
|
CompilerError.invariant(originalFnParams.length === compiledParams.length, {
|
||||||
reason:
|
reason:
|
||||||
'Expected React Compiler optimized function declarations to have the same number of parameters as source',
|
'Expected React Compiler optimized function declarations to have the same number of parameters as source',
|
||||||
loc: fnPath.node.loc ?? null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: fnPath.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const gatingCondition = t.identifier(
|
const gatingCondition = t.identifier(
|
||||||
|
|
@ -140,7 +154,13 @@ export function insertGatedFunctionDeclaration(
|
||||||
CompilerError.invariant(compiled.type === 'FunctionDeclaration', {
|
CompilerError.invariant(compiled.type === 'FunctionDeclaration', {
|
||||||
reason: 'Expected compiled node type to match input type',
|
reason: 'Expected compiled node type to match input type',
|
||||||
description: `Got ${compiled.type} but expected FunctionDeclaration`,
|
description: `Got ${compiled.type} but expected FunctionDeclaration`,
|
||||||
loc: fnPath.node.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: fnPath.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
insertAdditionalFunctionDeclaration(
|
insertAdditionalFunctionDeclaration(
|
||||||
fnPath,
|
fnPath,
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,13 @@ export function addImportsToProgram(
|
||||||
reason:
|
reason:
|
||||||
'Encountered conflicting import specifiers in generated program',
|
'Encountered conflicting import specifiers in generated program',
|
||||||
description: `Conflict from import ${loweredImport.module}:(${loweredImport.imported} as ${loweredImport.name}).`,
|
description: `Conflict from import ${loweredImport.module}:(${loweredImport.imported} as ${loweredImport.name}).`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -268,7 +274,13 @@ export function addImportsToProgram(
|
||||||
reason:
|
reason:
|
||||||
'Found inconsistent import specifier. This is an internal bug.',
|
'Found inconsistent import specifier. This is an internal bug.',
|
||||||
description: `Expected import ${moduleName}:${specifierName} but found ${loweredImport.module}:${loweredImport.imported}`,
|
description: `Expected import ${moduleName}:${specifierName} but found ${loweredImport.module}:${loweredImport.imported}`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,13 @@ function insertNewOutlinedFunctionNode(
|
||||||
CompilerError.invariant(insertedFuncDecl.isFunctionDeclaration(), {
|
CompilerError.invariant(insertedFuncDecl.isFunctionDeclaration(), {
|
||||||
reason: 'Expected inserted function declaration',
|
reason: 'Expected inserted function declaration',
|
||||||
description: `Got: ${insertedFuncDecl}`,
|
description: `Got: ${insertedFuncDecl}`,
|
||||||
loc: insertedFuncDecl.node?.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: insertedFuncDecl.node?.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
return insertedFuncDecl;
|
return insertedFuncDecl;
|
||||||
}
|
}
|
||||||
|
|
@ -419,7 +425,14 @@ export function compileProgram(
|
||||||
for (const outlined of compiled.outlined) {
|
for (const outlined of compiled.outlined) {
|
||||||
CompilerError.invariant(outlined.fn.outlined.length === 0, {
|
CompilerError.invariant(outlined.fn.outlined.length === 0, {
|
||||||
reason: 'Unexpected nested outlined functions',
|
reason: 'Unexpected nested outlined functions',
|
||||||
loc: outlined.fn.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: outlined.fn.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const fn = insertNewOutlinedFunctionNode(
|
const fn = insertNewOutlinedFunctionNode(
|
||||||
program,
|
program,
|
||||||
|
|
@ -1407,7 +1420,13 @@ export function getReactCompilerRuntimeModule(
|
||||||
{
|
{
|
||||||
reason: 'Expected target to already be validated',
|
reason: 'Expected target to already be validated',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,14 @@ export function suppressionsToCompilerError(
|
||||||
): CompilerError {
|
): CompilerError {
|
||||||
CompilerError.invariant(suppressionRanges.length !== 0, {
|
CompilerError.invariant(suppressionRanges.length !== 0, {
|
||||||
reason: `Expected at least suppression comment source range`,
|
reason: `Expected at least suppression comment source range`,
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const error = new CompilerError();
|
const error = new CompilerError();
|
||||||
for (const suppressionRange of suppressionRanges) {
|
for (const suppressionRange of suppressionRanges) {
|
||||||
|
|
@ -196,7 +203,7 @@ export function suppressionsToCompilerError(
|
||||||
op: CompilerSuggestionOperation.Remove,
|
op: CompilerSuggestionOperation.Remove,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: suppressionRange.disableComment.loc ?? null,
|
loc: suppressionRange.disableComment.loc ?? null,
|
||||||
message: 'Found React rule suppression',
|
message: 'Found React rule suppression',
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,14 @@ function validateImportSpecifier(
|
||||||
const binding = local.scope.getBinding(local.node.name);
|
const binding = local.scope.getBinding(local.node.name);
|
||||||
CompilerError.invariant(binding != null, {
|
CompilerError.invariant(binding != null, {
|
||||||
reason: 'Expected binding to be found for import specifier',
|
reason: 'Expected binding to be found for import specifier',
|
||||||
loc: local.node.loc ?? null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: local.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
checkFn(binding.referencePaths, state);
|
checkFn(binding.referencePaths, state);
|
||||||
}
|
}
|
||||||
|
|
@ -237,7 +244,14 @@ function validateNamespacedImport(
|
||||||
|
|
||||||
CompilerError.invariant(binding != null, {
|
CompilerError.invariant(binding != null, {
|
||||||
reason: 'Expected binding to be found for import specifier',
|
reason: 'Expected binding to be found for import specifier',
|
||||||
loc: local.node.loc ?? null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: local.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const filteredReferences = new Map<
|
const filteredReferences = new Map<
|
||||||
CheckInvalidReferenceFn,
|
CheckInvalidReferenceFn,
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,14 @@ export function raiseUnificationErrors(
|
||||||
if (errs.length === 0) {
|
if (errs.length === 0) {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Should not have array of zero errors',
|
reason: 'Should not have array of zero errors',
|
||||||
loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
} else if (errs.length === 1) {
|
} else if (errs.length === 1) {
|
||||||
CompilerError.throwInvalidJS({
|
CompilerError.throwInvalidJS({
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,13 @@ export function makeLinearId(id: number): LinearId {
|
||||||
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
||||||
reason: 'Expected LinearId id to be a non-negative integer',
|
reason: 'Expected LinearId id to be a non-negative integer',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return id as LinearId;
|
return id as LinearId;
|
||||||
|
|
@ -167,7 +173,13 @@ export function makeTypeParameterId(id: number): TypeParameterId {
|
||||||
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
||||||
reason: 'Expected TypeParameterId to be a non-negative integer',
|
reason: 'Expected TypeParameterId to be a non-negative integer',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return id as TypeParameterId;
|
return id as TypeParameterId;
|
||||||
|
|
@ -191,7 +203,13 @@ export function makeVariableId(id: number): VariableId {
|
||||||
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
||||||
reason: 'Expected VariableId id to be a non-negative integer',
|
reason: 'Expected VariableId id to be a non-negative integer',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return id as VariableId;
|
return id as VariableId;
|
||||||
|
|
@ -399,7 +417,14 @@ function convertFlowType(flowType: FlowType, loc: string): ResolvedType {
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unsupported property kind ${prop.kind}`,
|
reason: `Unsupported property kind ${prop.kind}`,
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -468,7 +493,14 @@ function convertFlowType(flowType: FlowType, loc: string): ResolvedType {
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unsupported property kind ${prop.kind}`,
|
reason: `Unsupported property kind ${prop.kind}`,
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -487,7 +519,14 @@ function convertFlowType(flowType: FlowType, loc: string): ResolvedType {
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unsupported property kind ${prop.kind}`,
|
reason: `Unsupported property kind ${prop.kind}`,
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -500,7 +539,14 @@ function convertFlowType(flowType: FlowType, loc: string): ResolvedType {
|
||||||
}
|
}
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unsupported class instance type ${flowType.def.type.kind}`,
|
reason: `Unsupported class instance type ${flowType.def.type.kind}`,
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
case 'Fun':
|
case 'Fun':
|
||||||
|
|
@ -559,7 +605,14 @@ function convertFlowType(flowType: FlowType, loc: string): ResolvedType {
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unsupported component props type ${propsType.type.kind}`,
|
reason: `Unsupported component props type ${propsType.type.kind}`,
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -712,7 +765,14 @@ export class FlowTypeEnv implements ITypeEnv {
|
||||||
// TODO: use flow-js only for web environments (e.g. playground)
|
// TODO: use flow-js only for web environments (e.g. playground)
|
||||||
CompilerError.invariant(env.config.flowTypeProvider != null, {
|
CompilerError.invariant(env.config.flowTypeProvider != null, {
|
||||||
reason: 'Expected flowDumpTypes to be defined in environment config',
|
reason: 'Expected flowDumpTypes to be defined in environment config',
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
let stdout: any;
|
let stdout: any;
|
||||||
if (source === lastFlowSource) {
|
if (source === lastFlowSource) {
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,13 @@ export function assertConsistentIdentifiers(fn: HIRFunction): void {
|
||||||
CompilerError.invariant(instr.lvalue.identifier.name === null, {
|
CompilerError.invariant(instr.lvalue.identifier.name === null, {
|
||||||
reason: `Expected all lvalues to be temporaries`,
|
reason: `Expected all lvalues to be temporaries`,
|
||||||
description: `Found named lvalue \`${instr.lvalue.identifier.name}\``,
|
description: `Found named lvalue \`${instr.lvalue.identifier.name}\``,
|
||||||
loc: instr.lvalue.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.lvalue.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
CompilerError.invariant(!assignments.has(instr.lvalue.identifier.id), {
|
CompilerError.invariant(!assignments.has(instr.lvalue.identifier.id), {
|
||||||
|
|
@ -46,7 +52,13 @@ export function assertConsistentIdentifiers(fn: HIRFunction): void {
|
||||||
description: `Found duplicate assignment of '${printPlace(
|
description: `Found duplicate assignment of '${printPlace(
|
||||||
instr.lvalue,
|
instr.lvalue,
|
||||||
)}'`,
|
)}'`,
|
||||||
loc: instr.lvalue.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.lvalue.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
assignments.add(instr.lvalue.identifier.id);
|
assignments.add(instr.lvalue.identifier.id);
|
||||||
|
|
@ -77,7 +89,13 @@ function validate(
|
||||||
CompilerError.invariant(identifier === previous, {
|
CompilerError.invariant(identifier === previous, {
|
||||||
reason: `Duplicate identifier object`,
|
reason: `Duplicate identifier object`,
|
||||||
description: `Found duplicate identifier object for id ${identifier.id}`,
|
description: `Found duplicate identifier object for id ${identifier.id}`,
|
||||||
loc: loc ?? GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: loc ?? GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,13 @@ export function assertTerminalSuccessorsExist(fn: HIRFunction): void {
|
||||||
description: `Block bb${successor} does not exist for terminal '${printTerminal(
|
description: `Block bb${successor} does not exist for terminal '${printTerminal(
|
||||||
block.terminal,
|
block.terminal,
|
||||||
)}'`,
|
)}'`,
|
||||||
loc: (block.terminal as any).loc ?? GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: (block.terminal as any).loc ?? GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return successor;
|
return successor;
|
||||||
|
|
@ -33,14 +39,26 @@ export function assertTerminalPredsExist(fn: HIRFunction): void {
|
||||||
CompilerError.invariant(predBlock != null, {
|
CompilerError.invariant(predBlock != null, {
|
||||||
reason: 'Expected predecessor block to exist',
|
reason: 'Expected predecessor block to exist',
|
||||||
description: `Block ${block.id} references non-existent ${pred}`,
|
description: `Block ${block.id} references non-existent ${pred}`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
CompilerError.invariant(
|
CompilerError.invariant(
|
||||||
[...eachTerminalSuccessor(predBlock.terminal)].includes(block.id),
|
[...eachTerminalSuccessor(predBlock.terminal)].includes(block.id),
|
||||||
{
|
{
|
||||||
reason: 'Terminal successor does not reference correct predecessor',
|
reason: 'Terminal successor does not reference correct predecessor',
|
||||||
description: `Block bb${block.id} has bb${predBlock.id} as a predecessor, but bb${predBlock.id}'s successors do not include bb${block.id}`,
|
description: `Block bb${block.id} has bb${predBlock.id} as a predecessor, but bb${predBlock.id}'s successors do not include bb${block.id}`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,13 @@ export function recursivelyTraverseItems<T, TContext>(
|
||||||
CompilerError.invariant(disjoint || nested, {
|
CompilerError.invariant(disjoint || nested, {
|
||||||
reason: 'Invalid nesting in program blocks or scopes',
|
reason: 'Invalid nesting in program blocks or scopes',
|
||||||
description: `Items overlap but are not nested: ${maybeParentRange.start}:${maybeParentRange.end}(${currRange.start}:${currRange.end})`,
|
description: `Items overlap but are not nested: ${maybeParentRange.start}:${maybeParentRange.end}(${currRange.start}:${currRange.end})`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
if (disjoint) {
|
if (disjoint) {
|
||||||
exit(maybeParent, context);
|
exit(maybeParent, context);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,13 @@ function validateMutableRange(
|
||||||
{
|
{
|
||||||
reason: `Invalid mutable range: [${range.start}:${range.end}]`,
|
reason: `Invalid mutable range: [${range.start}:${range.end}]`,
|
||||||
description: `${printPlace(place)} in ${description}`,
|
description: `${printPlace(place)} in ${description}`,
|
||||||
loc: place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ export function lower(
|
||||||
category: ErrorCategory.Invariant,
|
category: ErrorCategory.Invariant,
|
||||||
reason: 'Could not find binding',
|
reason: 'Could not find binding',
|
||||||
description: `[BuildHIR] Could not find binding for param \`${param.node.name}\`.`,
|
description: `[BuildHIR] Could not find binding for param \`${param.node.name}\`.`,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: param.node.loc ?? null,
|
loc: param.node.loc ?? null,
|
||||||
message: 'Could not find binding',
|
message: 'Could not find binding',
|
||||||
|
|
@ -174,7 +174,7 @@ export function lower(
|
||||||
category: ErrorCategory.Todo,
|
category: ErrorCategory.Todo,
|
||||||
reason: `Handle ${param.node.type} parameters`,
|
reason: `Handle ${param.node.type} parameters`,
|
||||||
description: `[BuildHIR] Add support for ${param.node.type} parameters.`,
|
description: `[BuildHIR] Add support for ${param.node.type} parameters.`,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: param.node.loc ?? null,
|
loc: param.node.loc ?? null,
|
||||||
message: 'Unsupported parameter type',
|
message: 'Unsupported parameter type',
|
||||||
|
|
@ -205,7 +205,7 @@ export function lower(
|
||||||
category: ErrorCategory.Syntax,
|
category: ErrorCategory.Syntax,
|
||||||
reason: `Unexpected function body kind`,
|
reason: `Unexpected function body kind`,
|
||||||
description: `Expected function body to be an expression or a block statement, got \`${body.type}\`.`,
|
description: `Expected function body to be an expression or a block statement, got \`${body.type}\`.`,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: body.node.loc ?? null,
|
loc: body.node.loc ?? null,
|
||||||
message: 'Expected a block statement or expression',
|
message: 'Expected a block statement or expression',
|
||||||
|
|
@ -439,7 +439,13 @@ function lowerStatement(
|
||||||
reason: 'Expected to find binding for hoisted identifier',
|
reason: 'Expected to find binding for hoisted identifier',
|
||||||
description: `Could not find a binding for ${id.node.name}`,
|
description: `Could not find a binding for ${id.node.name}`,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
loc: id.node.loc ?? GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: id.node.loc ?? GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
if (builder.environment.isHoistedIdentifier(binding.identifier)) {
|
if (builder.environment.isHoistedIdentifier(binding.identifier)) {
|
||||||
// Already hoisted
|
// Already hoisted
|
||||||
|
|
@ -481,7 +487,14 @@ function lowerStatement(
|
||||||
CompilerError.invariant(identifier.kind === 'Identifier', {
|
CompilerError.invariant(identifier.kind === 'Identifier', {
|
||||||
reason:
|
reason:
|
||||||
'Expected hoisted binding to be a local identifier, not a global',
|
'Expected hoisted binding to be a local identifier, not a global',
|
||||||
loc: id.node.loc ?? GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: id.node.loc ?? GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const place: Place = {
|
const place: Place = {
|
||||||
effect: Effect.Unknown,
|
effect: Effect.Unknown,
|
||||||
|
|
@ -1014,7 +1027,13 @@ function lowerStatement(
|
||||||
CompilerError.invariant(stmt.get('id').type === 'Identifier', {
|
CompilerError.invariant(stmt.get('id').type === 'Identifier', {
|
||||||
reason: 'function declarations must have a name',
|
reason: 'function declarations must have a name',
|
||||||
description: null,
|
description: null,
|
||||||
loc: stmt.node.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: stmt.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const id = stmt.get('id') as NodePath<t.Identifier>;
|
const id = stmt.get('id') as NodePath<t.Identifier>;
|
||||||
|
|
@ -1114,7 +1133,13 @@ function lowerStatement(
|
||||||
CompilerError.invariant(declarations.length === 1, {
|
CompilerError.invariant(declarations.length === 1, {
|
||||||
reason: `Expected only one declaration in the init of a ForOfStatement, got ${declarations.length}`,
|
reason: `Expected only one declaration in the init of a ForOfStatement, got ${declarations.length}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: left.node.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: left.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const id = declarations[0].get('id');
|
const id = declarations[0].get('id');
|
||||||
|
|
@ -1129,8 +1154,15 @@ function lowerStatement(
|
||||||
test = lowerValueToTemporary(builder, assign);
|
test = lowerValueToTemporary(builder, assign);
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(left.isLVal(), {
|
CompilerError.invariant(left.isLVal(), {
|
||||||
loc: leftLoc,
|
|
||||||
reason: 'Expected ForOf init to be a variable declaration or lval',
|
reason: 'Expected ForOf init to be a variable declaration or lval',
|
||||||
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: leftLoc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const assign = lowerAssignment(
|
const assign = lowerAssignment(
|
||||||
builder,
|
builder,
|
||||||
|
|
@ -1207,7 +1239,13 @@ function lowerStatement(
|
||||||
CompilerError.invariant(declarations.length === 1, {
|
CompilerError.invariant(declarations.length === 1, {
|
||||||
reason: `Expected only one declaration in the init of a ForInStatement, got ${declarations.length}`,
|
reason: `Expected only one declaration in the init of a ForInStatement, got ${declarations.length}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: left.node.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: left.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const id = declarations[0].get('id');
|
const id = declarations[0].get('id');
|
||||||
|
|
@ -1222,8 +1260,15 @@ function lowerStatement(
|
||||||
test = lowerValueToTemporary(builder, assign);
|
test = lowerValueToTemporary(builder, assign);
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(left.isLVal(), {
|
CompilerError.invariant(left.isLVal(), {
|
||||||
loc: leftLoc,
|
|
||||||
reason: 'Expected ForIn init to be a variable declaration or lval',
|
reason: 'Expected ForIn init to be a variable declaration or lval',
|
||||||
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: leftLoc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const assign = lowerAssignment(
|
const assign = lowerAssignment(
|
||||||
builder,
|
builder,
|
||||||
|
|
@ -2202,7 +2247,13 @@ function lowerExpression(
|
||||||
CompilerError.invariant(namePath.isJSXNamespacedName(), {
|
CompilerError.invariant(namePath.isJSXNamespacedName(), {
|
||||||
reason: 'Refinement',
|
reason: 'Refinement',
|
||||||
description: null,
|
description: null,
|
||||||
loc: namePath.node.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: namePath.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const namespace = namePath.node.namespace.name;
|
const namespace = namePath.node.namespace.name;
|
||||||
|
|
@ -2256,8 +2307,14 @@ function lowerExpression(
|
||||||
// This is already checked in builder.resolveIdentifier
|
// This is already checked in builder.resolveIdentifier
|
||||||
CompilerError.invariant(tagIdentifier.kind !== 'Identifier', {
|
CompilerError.invariant(tagIdentifier.kind !== 'Identifier', {
|
||||||
reason: `<${tagName}> tags should be module-level imports`,
|
reason: `<${tagName}> tags should be module-level imports`,
|
||||||
loc: openingIdentifier.node.loc ?? GeneratedSource,
|
|
||||||
description: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: openingIdentifier.node.loc ?? GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -2361,7 +2418,13 @@ function lowerExpression(
|
||||||
reason:
|
reason:
|
||||||
"there should be only one quasi as we don't support interpolations yet",
|
"there should be only one quasi as we don't support interpolations yet",
|
||||||
description: null,
|
description: null,
|
||||||
loc: expr.node.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: expr.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const value = expr.get('quasi').get('quasis').at(0)!.node.value;
|
const value = expr.get('quasi').get('quasis').at(0)!.node.value;
|
||||||
|
|
@ -2759,7 +2822,13 @@ function lowerOptionalMemberExpression(
|
||||||
CompilerError.invariant(object !== null, {
|
CompilerError.invariant(object !== null, {
|
||||||
reason: 'Satisfy type checker',
|
reason: 'Satisfy type checker',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -3327,7 +3396,13 @@ function lowerJsxMemberExpression(
|
||||||
CompilerError.invariant(object.isJSXIdentifier(), {
|
CompilerError.invariant(object.isJSXIdentifier(), {
|
||||||
reason: `TypeScript refinement fail: expected 'JsxIdentifier', got \`${object.node.type}\``,
|
reason: `TypeScript refinement fail: expected 'JsxIdentifier', got \`${object.node.type}\``,
|
||||||
description: null,
|
description: null,
|
||||||
loc: object.node.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: object.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -3369,7 +3444,13 @@ function lowerJsxElement(
|
||||||
CompilerError.invariant(expression.isExpression(), {
|
CompilerError.invariant(expression.isExpression(), {
|
||||||
reason: `(BuildHIR::lowerJsxElement) Expected Expression but found ${expression.type}!`,
|
reason: `(BuildHIR::lowerJsxElement) Expected Expression but found ${expression.type}!`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: expression.node.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: expression.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return lowerExpressionToTemporary(builder, expression);
|
return lowerExpressionToTemporary(builder, expression);
|
||||||
|
|
@ -3770,7 +3851,13 @@ function lowerAssignment(
|
||||||
CompilerError.invariant(kind === InstructionKind.Reassign, {
|
CompilerError.invariant(kind === InstructionKind.Reassign, {
|
||||||
reason: 'MemberExpression may only appear in an assignment expression',
|
reason: 'MemberExpression may only appear in an assignment expression',
|
||||||
description: null,
|
description: null,
|
||||||
loc: lvaluePath.node.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: lvaluePath.node.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const lvalue = lvaluePath as NodePath<t.MemberExpression>;
|
const lvalue = lvaluePath as NodePath<t.MemberExpression>;
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,14 @@ function pushEndScopeTerminal(
|
||||||
const fallthroughId = context.fallthroughs.get(scope.id);
|
const fallthroughId = context.fallthroughs.get(scope.id);
|
||||||
CompilerError.invariant(fallthroughId != null, {
|
CompilerError.invariant(fallthroughId != null, {
|
||||||
reason: 'Expected scope to exist',
|
reason: 'Expected scope to exist',
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
context.rewrites.push({
|
context.rewrites.push({
|
||||||
kind: 'EndScope',
|
kind: 'EndScope',
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,14 @@ class PropertyPathRegistry {
|
||||||
CompilerError.invariant(reactive === rootNode.fullPath.reactive, {
|
CompilerError.invariant(reactive === rootNode.fullPath.reactive, {
|
||||||
reason:
|
reason:
|
||||||
'[HoistablePropertyLoads] Found inconsistencies in `reactive` flag when deduping identifier reads within the same scope',
|
'[HoistablePropertyLoads] Found inconsistencies in `reactive` flag when deduping identifier reads within the same scope',
|
||||||
loc: identifier.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: identifier.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return rootNode;
|
return rootNode;
|
||||||
|
|
@ -498,7 +505,14 @@ function propagateNonNull(
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Bad node ${nodeId}, kind: ${direction}`,
|
reason: `Bad node ${nodeId}, kind: ${direction}`,
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const neighbors = Array.from(
|
const neighbors = Array.from(
|
||||||
|
|
@ -570,7 +584,14 @@ function propagateNonNull(
|
||||||
CompilerError.invariant(i++ < 100, {
|
CompilerError.invariant(i++ < 100, {
|
||||||
reason:
|
reason:
|
||||||
'[CollectHoistablePropertyLoads] fixed point iteration did not terminate after 100 loops',
|
'[CollectHoistablePropertyLoads] fixed point iteration did not terminate after 100 loops',
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
changed = false;
|
changed = false;
|
||||||
|
|
@ -602,7 +623,13 @@ export function assertNonNull<T extends NonNullable<U>, U>(
|
||||||
CompilerError.invariant(value != null, {
|
CompilerError.invariant(value != null, {
|
||||||
reason: 'Unexpected null',
|
reason: 'Unexpected null',
|
||||||
description: source != null ? `(from ${source})` : null,
|
description: source != null ? `(from ${source})` : null,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,13 @@ function matchOptionalTestBlock(
|
||||||
reason:
|
reason:
|
||||||
'[OptionalChainDeps] Inconsistent optional chaining property load',
|
'[OptionalChainDeps] Inconsistent optional chaining property load',
|
||||||
description: `Test=${printIdentifier(terminal.test.identifier)} PropertyLoad base=${printIdentifier(propertyLoad.value.object.identifier)}`,
|
description: `Test=${printIdentifier(terminal.test.identifier)} PropertyLoad base=${printIdentifier(propertyLoad.value.object.identifier)}`,
|
||||||
loc: propertyLoad.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: propertyLoad.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -194,7 +200,14 @@ function matchOptionalTestBlock(
|
||||||
storeLocal.value.identifier.id === propertyLoad.lvalue.identifier.id,
|
storeLocal.value.identifier.id === propertyLoad.lvalue.identifier.id,
|
||||||
{
|
{
|
||||||
reason: '[OptionalChainDeps] Unexpected storeLocal',
|
reason: '[OptionalChainDeps] Unexpected storeLocal',
|
||||||
loc: propertyLoad.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: propertyLoad.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (
|
if (
|
||||||
|
|
@ -211,7 +224,14 @@ function matchOptionalTestBlock(
|
||||||
alternate.instructions[1].value.kind === 'StoreLocal',
|
alternate.instructions[1].value.kind === 'StoreLocal',
|
||||||
{
|
{
|
||||||
reason: 'Unexpected alternate structure',
|
reason: 'Unexpected alternate structure',
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -247,7 +267,14 @@ function traverseOptionalBlock(
|
||||||
if (maybeTest.terminal.kind === 'branch') {
|
if (maybeTest.terminal.kind === 'branch') {
|
||||||
CompilerError.invariant(optional.terminal.optional, {
|
CompilerError.invariant(optional.terminal.optional, {
|
||||||
reason: '[OptionalChainDeps] Expect base case to be always optional',
|
reason: '[OptionalChainDeps] Expect base case to be always optional',
|
||||||
loc: optional.terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: optional.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
/**
|
/**
|
||||||
* Optional base expressions are currently within value blocks which cannot
|
* Optional base expressions are currently within value blocks which cannot
|
||||||
|
|
@ -285,7 +312,14 @@ function traverseOptionalBlock(
|
||||||
maybeTest.instructions.at(-1)!.lvalue.identifier.id,
|
maybeTest.instructions.at(-1)!.lvalue.identifier.id,
|
||||||
{
|
{
|
||||||
reason: '[OptionalChainDeps] Unexpected test expression',
|
reason: '[OptionalChainDeps] Unexpected test expression',
|
||||||
loc: maybeTest.terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: maybeTest.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
baseObject = {
|
baseObject = {
|
||||||
|
|
@ -374,7 +408,14 @@ function traverseOptionalBlock(
|
||||||
reason:
|
reason:
|
||||||
'[OptionalChainDeps] Unexpected instructions an inner optional block. ' +
|
'[OptionalChainDeps] Unexpected instructions an inner optional block. ' +
|
||||||
'This indicates that the compiler may be incorrectly concatenating two unrelated optional chains',
|
'This indicates that the compiler may be incorrectly concatenating two unrelated optional chains',
|
||||||
loc: optional.terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: optional.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const matchConsequentResult = matchOptionalTestBlock(test, context.blocks);
|
const matchConsequentResult = matchOptionalTestBlock(test, context.blocks);
|
||||||
|
|
@ -387,7 +428,13 @@ function traverseOptionalBlock(
|
||||||
{
|
{
|
||||||
reason: '[OptionalChainDeps] Unexpected optional goto-fallthrough',
|
reason: '[OptionalChainDeps] Unexpected optional goto-fallthrough',
|
||||||
description: `${matchConsequentResult.consequentGoto} != ${optional.terminal.fallthrough}`,
|
description: `${matchConsequentResult.consequentGoto} != ${optional.terminal.fallthrough}`,
|
||||||
loc: optional.terminal.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: optional.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const load = {
|
const load = {
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,14 @@ export function computeUnconditionalBlocks(fn: HIRFunction): Set<BlockId> {
|
||||||
CompilerError.invariant(!unconditionalBlocks.has(current), {
|
CompilerError.invariant(!unconditionalBlocks.has(current), {
|
||||||
reason:
|
reason:
|
||||||
'Internal error: non-terminating loop in ComputeUnconditionalBlocks',
|
'Internal error: non-terminating loop in ComputeUnconditionalBlocks',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
unconditionalBlocks.add(current);
|
unconditionalBlocks.add(current);
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,14 @@ export class ReactiveScopeDependencyTreeHIR {
|
||||||
prevAccessType == null || prevAccessType === accessType,
|
prevAccessType == null || prevAccessType === accessType,
|
||||||
{
|
{
|
||||||
reason: 'Conflicting access types',
|
reason: 'Conflicting access types',
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let nextNode = currNode.properties.get(path[i].property);
|
let nextNode = currNode.properties.get(path[i].property);
|
||||||
|
|
@ -90,7 +97,13 @@ export class ReactiveScopeDependencyTreeHIR {
|
||||||
CompilerError.invariant(reactive === rootNode.reactive, {
|
CompilerError.invariant(reactive === rootNode.reactive, {
|
||||||
reason: '[DeriveMinimalDependenciesHIR] Conflicting reactive root flag',
|
reason: '[DeriveMinimalDependenciesHIR] Conflicting reactive root flag',
|
||||||
description: `Identifier ${printIdentifier(identifier)}`,
|
description: `Identifier ${printIdentifier(identifier)}`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return rootNode;
|
return rootNode;
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,13 @@ export class Dominator<T> {
|
||||||
CompilerError.invariant(dominator !== undefined, {
|
CompilerError.invariant(dominator !== undefined, {
|
||||||
reason: 'Unknown node',
|
reason: 'Unknown node',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return dominator === id ? null : dominator;
|
return dominator === id ? null : dominator;
|
||||||
|
|
@ -130,7 +136,13 @@ export class PostDominator<T> {
|
||||||
CompilerError.invariant(dominator !== undefined, {
|
CompilerError.invariant(dominator !== undefined, {
|
||||||
reason: 'Unknown node',
|
reason: 'Unknown node',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return dominator === id ? null : dominator;
|
return dominator === id ? null : dominator;
|
||||||
|
|
@ -175,7 +187,13 @@ function computeImmediateDominators<T>(graph: Graph<T>): Map<T, T> {
|
||||||
CompilerError.invariant(newIdom !== null, {
|
CompilerError.invariant(newIdom !== null, {
|
||||||
reason: `At least one predecessor must have been visited for block ${id}`,
|
reason: `At least one predecessor must have been visited for block ${id}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -750,7 +750,13 @@ export class Environment {
|
||||||
CompilerError.invariant(!this.#globals.has(hookName), {
|
CompilerError.invariant(!this.#globals.has(hookName), {
|
||||||
reason: `[Globals] Found existing definition in global registry for custom hook ${hookName}`,
|
reason: `[Globals] Found existing definition in global registry for custom hook ${hookName}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
this.#globals.set(
|
this.#globals.set(
|
||||||
|
|
@ -783,7 +789,14 @@ export class Environment {
|
||||||
CompilerError.invariant(code != null, {
|
CompilerError.invariant(code != null, {
|
||||||
reason:
|
reason:
|
||||||
'Expected Environment to be initialized with source code when a Flow type provider is specified',
|
'Expected Environment to be initialized with source code when a Flow type provider is specified',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
this.#flowTypeEnvironment.init(this, code);
|
this.#flowTypeEnvironment.init(this, code);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -794,7 +807,14 @@ export class Environment {
|
||||||
get typeContext(): FlowTypeEnv {
|
get typeContext(): FlowTypeEnv {
|
||||||
CompilerError.invariant(this.#flowTypeEnvironment != null, {
|
CompilerError.invariant(this.#flowTypeEnvironment != null, {
|
||||||
reason: 'Flow type environment not initialized',
|
reason: 'Flow type environment not initialized',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
return this.#flowTypeEnvironment;
|
return this.#flowTypeEnvironment;
|
||||||
}
|
}
|
||||||
|
|
@ -1044,7 +1064,13 @@ export class Environment {
|
||||||
CompilerError.invariant(shape !== undefined, {
|
CompilerError.invariant(shape !== undefined, {
|
||||||
reason: `[HIR] Forget internal error: cannot resolve shape ${shapeId}`,
|
reason: `[HIR] Forget internal error: cannot resolve shape ${shapeId}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return shape.properties.get('*') ?? null;
|
return shape.properties.get('*') ?? null;
|
||||||
|
|
@ -1069,7 +1095,13 @@ export class Environment {
|
||||||
CompilerError.invariant(shape !== undefined, {
|
CompilerError.invariant(shape !== undefined, {
|
||||||
reason: `[HIR] Forget internal error: cannot resolve shape ${shapeId}`,
|
reason: `[HIR] Forget internal error: cannot resolve shape ${shapeId}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (typeof property === 'string') {
|
if (typeof property === 'string') {
|
||||||
|
|
@ -1094,7 +1126,13 @@ export class Environment {
|
||||||
CompilerError.invariant(shape !== undefined, {
|
CompilerError.invariant(shape !== undefined, {
|
||||||
reason: `[HIR] Forget internal error: cannot resolve shape ${shapeId}`,
|
reason: `[HIR] Forget internal error: cannot resolve shape ${shapeId}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return shape.functionType;
|
return shape.functionType;
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,13 @@ function handleAssignment(
|
||||||
CompilerError.invariant(valuePath.isLVal(), {
|
CompilerError.invariant(valuePath.isLVal(), {
|
||||||
reason: `[FindContextIdentifiers] Expected object property value to be an LVal, got: ${valuePath.type}`,
|
reason: `[FindContextIdentifiers] Expected object property value to be an LVal, got: ${valuePath.type}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: valuePath.node.loc ?? GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: valuePath.node.loc ?? GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
handleAssignment(currentFn, identifiers, valuePath);
|
handleAssignment(currentFn, identifiers, valuePath);
|
||||||
|
|
@ -192,7 +198,13 @@ function handleAssignment(
|
||||||
CompilerError.invariant(property.isRestElement(), {
|
CompilerError.invariant(property.isRestElement(), {
|
||||||
reason: `[FindContextIdentifiers] Invalid assumptions for babel types.`,
|
reason: `[FindContextIdentifiers] Invalid assumptions for babel types.`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: property.node.loc ?? GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: property.node.loc ?? GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
handleAssignment(currentFn, identifiers, property);
|
handleAssignment(currentFn, identifiers, property);
|
||||||
|
|
|
||||||
|
|
@ -1314,8 +1314,14 @@ export function makeIdentifierName(name: string): ValidatedIdentifier {
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(t.isValidIdentifier(name), {
|
CompilerError.invariant(t.isValidIdentifier(name), {
|
||||||
reason: `Expected a valid identifier name`,
|
reason: `Expected a valid identifier name`,
|
||||||
loc: GeneratedSource,
|
|
||||||
description: `\`${name}\` is not a valid JavaScript identifier`,
|
description: `\`${name}\` is not a valid JavaScript identifier`,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1334,8 +1340,14 @@ export function makeIdentifierName(name: string): ValidatedIdentifier {
|
||||||
export function promoteTemporary(identifier: Identifier): void {
|
export function promoteTemporary(identifier: Identifier): void {
|
||||||
CompilerError.invariant(identifier.name === null, {
|
CompilerError.invariant(identifier.name === null, {
|
||||||
reason: `Expected a temporary (unnamed) identifier`,
|
reason: `Expected a temporary (unnamed) identifier`,
|
||||||
loc: GeneratedSource,
|
|
||||||
description: `Identifier already has a name, \`${identifier.name}\``,
|
description: `Identifier already has a name, \`${identifier.name}\``,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
identifier.name = {
|
identifier.name = {
|
||||||
|
|
@ -1358,8 +1370,14 @@ export function isPromotedTemporary(name: string): boolean {
|
||||||
export function promoteTemporaryJsxTag(identifier: Identifier): void {
|
export function promoteTemporaryJsxTag(identifier: Identifier): void {
|
||||||
CompilerError.invariant(identifier.name === null, {
|
CompilerError.invariant(identifier.name === null, {
|
||||||
reason: `Expected a temporary (unnamed) identifier`,
|
reason: `Expected a temporary (unnamed) identifier`,
|
||||||
loc: GeneratedSource,
|
|
||||||
description: `Identifier already has a name, \`${identifier.name}\``,
|
description: `Identifier already has a name, \`${identifier.name}\``,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
identifier.name = {
|
identifier.name = {
|
||||||
|
|
@ -1527,7 +1545,13 @@ export function isMutableEffect(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Unexpected unknown effect',
|
reason: 'Unexpected unknown effect',
|
||||||
description: null,
|
description: null,
|
||||||
loc: location,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: location,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1660,7 +1684,13 @@ export function makeBlockId(id: number): BlockId {
|
||||||
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
||||||
reason: 'Expected block id to be a non-negative integer',
|
reason: 'Expected block id to be a non-negative integer',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return id as BlockId;
|
return id as BlockId;
|
||||||
|
|
@ -1677,7 +1707,13 @@ export function makeScopeId(id: number): ScopeId {
|
||||||
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
||||||
reason: 'Expected block id to be a non-negative integer',
|
reason: 'Expected block id to be a non-negative integer',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return id as ScopeId;
|
return id as ScopeId;
|
||||||
|
|
@ -1694,7 +1730,13 @@ export function makeIdentifierId(id: number): IdentifierId {
|
||||||
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
||||||
reason: 'Expected identifier id to be a non-negative integer',
|
reason: 'Expected identifier id to be a non-negative integer',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return id as IdentifierId;
|
return id as IdentifierId;
|
||||||
|
|
@ -1711,7 +1753,13 @@ export function makeDeclarationId(id: number): DeclarationId {
|
||||||
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
||||||
reason: 'Expected declaration id to be a non-negative integer',
|
reason: 'Expected declaration id to be a non-negative integer',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return id as DeclarationId;
|
return id as DeclarationId;
|
||||||
|
|
@ -1728,7 +1776,13 @@ export function makeInstructionId(id: number): InstructionId {
|
||||||
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
||||||
reason: 'Expected instruction id to be a non-negative integer',
|
reason: 'Expected instruction id to be a non-negative integer',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return id as InstructionId;
|
return id as InstructionId;
|
||||||
|
|
|
||||||
|
|
@ -507,7 +507,13 @@ export default class HIRBuilder {
|
||||||
{
|
{
|
||||||
reason: 'Mismatched label',
|
reason: 'Mismatched label',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -530,7 +536,13 @@ export default class HIRBuilder {
|
||||||
{
|
{
|
||||||
reason: 'Mismatched label',
|
reason: 'Mismatched label',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -566,7 +578,13 @@ export default class HIRBuilder {
|
||||||
{
|
{
|
||||||
reason: 'Mismatched loops',
|
reason: 'Mismatched loops',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -591,7 +609,13 @@ export default class HIRBuilder {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Expected a loop or switch to be in scope',
|
reason: 'Expected a loop or switch to be in scope',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -612,7 +636,13 @@ export default class HIRBuilder {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Continue may only refer to a labeled loop',
|
reason: 'Continue may only refer to a labeled loop',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -620,7 +650,13 @@ export default class HIRBuilder {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Expected a loop to be in scope',
|
reason: 'Expected a loop to be in scope',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -643,7 +679,13 @@ function _shrink(func: HIR): void {
|
||||||
CompilerError.invariant(block != null, {
|
CompilerError.invariant(block != null, {
|
||||||
reason: `expected block ${blockId} to exist`,
|
reason: `expected block ${blockId} to exist`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
target = getTargetIfIndirection(block);
|
target = getTargetIfIndirection(block);
|
||||||
|
|
@ -775,7 +817,13 @@ function getReversePostorderedBlocks(func: HIR): HIR['blocks'] {
|
||||||
CompilerError.invariant(block != null, {
|
CompilerError.invariant(block != null, {
|
||||||
reason: '[HIRBuilder] Unexpected null block',
|
reason: '[HIRBuilder] Unexpected null block',
|
||||||
description: `expected block ${blockId} to exist`,
|
description: `expected block ${blockId} to exist`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const successors = [...eachTerminalSuccessor(block.terminal)].reverse();
|
const successors = [...eachTerminalSuccessor(block.terminal)].reverse();
|
||||||
const fallthrough = terminalFallthrough(block.terminal);
|
const fallthrough = terminalFallthrough(block.terminal);
|
||||||
|
|
@ -831,7 +879,13 @@ export function markInstructionIds(func: HIR): void {
|
||||||
CompilerError.invariant(!visited.has(instr), {
|
CompilerError.invariant(!visited.has(instr), {
|
||||||
reason: `${printInstruction(instr)} already visited!`,
|
reason: `${printInstruction(instr)} already visited!`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: instr.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
visited.add(instr);
|
visited.add(instr);
|
||||||
|
|
@ -854,7 +908,13 @@ export function markPredecessors(func: HIR): void {
|
||||||
CompilerError.invariant(block != null, {
|
CompilerError.invariant(block != null, {
|
||||||
reason: 'unexpected missing block',
|
reason: 'unexpected missing block',
|
||||||
description: `block ${blockId}`,
|
description: `block ${blockId}`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
if (prevBlock) {
|
if (prevBlock) {
|
||||||
block.preds.add(prevBlock.id);
|
block.preds.add(prevBlock.id);
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,13 @@ export function mergeConsecutiveBlocks(fn: HIRFunction): void {
|
||||||
CompilerError.invariant(predecessor !== undefined, {
|
CompilerError.invariant(predecessor !== undefined, {
|
||||||
reason: `Expected predecessor ${predecessorId} to exist`,
|
reason: `Expected predecessor ${predecessorId} to exist`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (predecessor.terminal.kind !== 'goto' || predecessor.kind !== 'block') {
|
if (predecessor.terminal.kind !== 'goto' || predecessor.kind !== 'block') {
|
||||||
|
|
@ -77,7 +83,13 @@ export function mergeConsecutiveBlocks(fn: HIRFunction): void {
|
||||||
CompilerError.invariant(phi.operands.size === 1, {
|
CompilerError.invariant(phi.operands.size === 1, {
|
||||||
reason: `Found a block with a single predecessor but where a phi has multiple (${phi.operands.size}) operands`,
|
reason: `Found a block with a single predecessor but where a phi has multiple (${phi.operands.size}) operands`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const operand = Array.from(phi.operands.values())[0]!;
|
const operand = Array.from(phi.operands.values())[0]!;
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,13 @@ function parseAliasingSignatureConfig(
|
||||||
CompilerError.invariant(!lifetimes.has(temp), {
|
CompilerError.invariant(!lifetimes.has(temp), {
|
||||||
reason: `Invalid type configuration for module`,
|
reason: `Invalid type configuration for module`,
|
||||||
description: `Expected aliasing signature to have unique names for receiver, params, rest, returns, and temporaries in module '${moduleName}'`,
|
description: `Expected aliasing signature to have unique names for receiver, params, rest, returns, and temporaries in module '${moduleName}'`,
|
||||||
loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const place = signatureArgument(lifetimes.size);
|
const place = signatureArgument(lifetimes.size);
|
||||||
lifetimes.set(temp, place);
|
lifetimes.set(temp, place);
|
||||||
|
|
@ -130,7 +136,13 @@ function parseAliasingSignatureConfig(
|
||||||
CompilerError.invariant(place != null, {
|
CompilerError.invariant(place != null, {
|
||||||
reason: `Invalid type configuration for module`,
|
reason: `Invalid type configuration for module`,
|
||||||
description: `Expected aliasing signature effects to reference known names from receiver/params/rest/returns/temporaries, but '${temp}' is not a known name in '${moduleName}'`,
|
description: `Expected aliasing signature effects to reference known names from receiver/params/rest/returns/temporaries, but '${temp}' is not a known name in '${moduleName}'`,
|
||||||
loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
return place;
|
return place;
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +277,13 @@ function addShape(
|
||||||
CompilerError.invariant(!registry.has(id), {
|
CompilerError.invariant(!registry.has(id), {
|
||||||
reason: `[ObjectShape] Could not add shape to registry: name ${id} already exists.`,
|
reason: `[ObjectShape] Could not add shape to registry: name ${id} already exists.`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
registry.set(id, shape);
|
registry.set(id, shape);
|
||||||
|
|
|
||||||
|
|
@ -596,7 +596,13 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
|
||||||
{
|
{
|
||||||
reason: 'Bad assumption about quasi length.',
|
reason: 'Bad assumption about quasi length.',
|
||||||
description: null,
|
description: null,
|
||||||
loc: instrValue.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instrValue.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -865,8 +871,15 @@ export function printManualMemoDependency(
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(val.root.value.identifier.name?.kind === 'named', {
|
CompilerError.invariant(val.root.value.identifier.name?.kind === 'named', {
|
||||||
reason: 'DepsValidation: expected named local variable in depslist',
|
reason: 'DepsValidation: expected named local variable in depslist',
|
||||||
|
description: null,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
loc: val.root.value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: val.root.value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
rootStr = nameOnly
|
rootStr = nameOnly
|
||||||
? val.root.value.identifier.name.value
|
? val.root.value.identifier.name.value
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,14 @@ export function propagateScopeDependenciesHIR(fn: HIRFunction): void {
|
||||||
const hoistables = hoistablePropertyLoads.get(scope.id);
|
const hoistables = hoistablePropertyLoads.get(scope.id);
|
||||||
CompilerError.invariant(hoistables != null, {
|
CompilerError.invariant(hoistables != null, {
|
||||||
reason: '[PropagateScopeDependencies] Scope not found in tracked blocks',
|
reason: '[PropagateScopeDependencies] Scope not found in tracked blocks',
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
/**
|
/**
|
||||||
* Step 2: Calculate hoistable dependencies.
|
* Step 2: Calculate hoistable dependencies.
|
||||||
|
|
@ -428,7 +435,14 @@ export class DependencyCollectionContext {
|
||||||
const scopedDependencies = this.#dependencies.value;
|
const scopedDependencies = this.#dependencies.value;
|
||||||
CompilerError.invariant(scopedDependencies != null, {
|
CompilerError.invariant(scopedDependencies != null, {
|
||||||
reason: '[PropagateScopeDeps]: Unexpected scope mismatch',
|
reason: '[PropagateScopeDeps]: Unexpected scope mismatch',
|
||||||
loc: scope.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: scope.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
// Restore context of previous scope
|
// Restore context of previous scope
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,14 @@ export function pruneUnusedLabelsHIR(fn: HIRFunction): void {
|
||||||
next.phis.size === 0 && fallthrough.phis.size === 0,
|
next.phis.size === 0 && fallthrough.phis.size === 0,
|
||||||
{
|
{
|
||||||
reason: 'Unexpected phis when merging label blocks',
|
reason: 'Unexpected phis when merging label blocks',
|
||||||
loc: label.terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: label.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -64,7 +71,14 @@ export function pruneUnusedLabelsHIR(fn: HIRFunction): void {
|
||||||
fallthrough.preds.has(nextId),
|
fallthrough.preds.has(nextId),
|
||||||
{
|
{
|
||||||
reason: 'Unexpected block predecessors when merging label blocks',
|
reason: 'Unexpected block predecessors when merging label blocks',
|
||||||
loc: label.terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: label.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -202,8 +202,14 @@ function writeOptionalDependency(
|
||||||
CompilerError.invariant(firstOptional !== -1, {
|
CompilerError.invariant(firstOptional !== -1, {
|
||||||
reason:
|
reason:
|
||||||
'[ScopeDependencyUtils] Internal invariant broken: expected optional path',
|
'[ScopeDependencyUtils] Internal invariant broken: expected optional path',
|
||||||
loc: dep.identifier.loc,
|
|
||||||
description: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: dep.identifier.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (firstOptional === dep.path.length - 1) {
|
if (firstOptional === dep.path.length - 1) {
|
||||||
|
|
@ -239,7 +245,13 @@ function writeOptionalDependency(
|
||||||
CompilerError.invariant(testIdentifier !== null, {
|
CompilerError.invariant(testIdentifier !== null, {
|
||||||
reason: 'Satisfy type checker',
|
reason: 'Satisfy type checker',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,13 @@ export function makeTypeId(id: number): TypeId {
|
||||||
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
||||||
reason: 'Expected instruction id to be a non-negative integer',
|
reason: 'Expected instruction id to be a non-negative integer',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return id as TypeId;
|
return id as TypeId;
|
||||||
|
|
|
||||||
|
|
@ -1233,7 +1233,14 @@ export class ScopeBlockTraversal {
|
||||||
CompilerError.invariant(blockInfo.scope.id === top, {
|
CompilerError.invariant(blockInfo.scope.id === top, {
|
||||||
reason:
|
reason:
|
||||||
'Expected traversed block fallthrough to match top-most active scope',
|
'Expected traversed block fallthrough to match top-most active scope',
|
||||||
loc: block.instructions[0]?.loc ?? block.terminal.id,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: block.instructions[0]?.loc ?? block.terminal.id,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
this.#activeScopes.pop();
|
this.#activeScopes.pop();
|
||||||
}
|
}
|
||||||
|
|
@ -1247,7 +1254,14 @@ export class ScopeBlockTraversal {
|
||||||
!this.blockInfos.has(block.terminal.fallthrough),
|
!this.blockInfos.has(block.terminal.fallthrough),
|
||||||
{
|
{
|
||||||
reason: 'Expected unique scope blocks and fallthroughs',
|
reason: 'Expected unique scope blocks and fallthroughs',
|
||||||
loc: block.terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: block.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.blockInfos.set(block.terminal.block, {
|
this.blockInfos.set(block.terminal.block, {
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,14 @@ function lowerWithMutationAliasing(fn: HIRFunction): void {
|
||||||
case 'Apply': {
|
case 'Apply': {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `[AnalyzeFunctions] Expected Apply effects to be replaced with more precise effects`,
|
reason: `[AnalyzeFunctions] Expected Apply effects to be replaced with more precise effects`,
|
||||||
loc: effect.function.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: effect.function.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
case 'Mutate':
|
case 'Mutate':
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,7 @@ function extractManualMemoizationArgs(
|
||||||
reason: `Expected a callback function to be passed to ${kind}`,
|
reason: `Expected a callback function to be passed to ${kind}`,
|
||||||
description: `Expected a callback function to be passed to ${kind}`,
|
description: `Expected a callback function to be passed to ${kind}`,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: instr.value.loc,
|
loc: instr.value.loc,
|
||||||
message: `Expected a callback function to be passed to ${kind}`,
|
message: `Expected a callback function to be passed to ${kind}`,
|
||||||
|
|
@ -315,7 +315,7 @@ function extractManualMemoizationArgs(
|
||||||
reason: `Unexpected spread argument to ${kind}`,
|
reason: `Unexpected spread argument to ${kind}`,
|
||||||
description: `Unexpected spread argument to ${kind}`,
|
description: `Unexpected spread argument to ${kind}`,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: instr.value.loc,
|
loc: instr.value.loc,
|
||||||
message: `Unexpected spread argument to ${kind}`,
|
message: `Unexpected spread argument to ${kind}`,
|
||||||
|
|
@ -335,7 +335,7 @@ function extractManualMemoizationArgs(
|
||||||
reason: `Expected the dependency list for ${kind} to be an array literal`,
|
reason: `Expected the dependency list for ${kind} to be an array literal`,
|
||||||
description: `Expected the dependency list for ${kind} to be an array literal`,
|
description: `Expected the dependency list for ${kind} to be an array literal`,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: depsListPlace.loc,
|
loc: depsListPlace.loc,
|
||||||
message: `Expected the dependency list for ${kind} to be an array literal`,
|
message: `Expected the dependency list for ${kind} to be an array literal`,
|
||||||
|
|
@ -353,7 +353,7 @@ function extractManualMemoizationArgs(
|
||||||
reason: `Expected the dependency list to be an array of simple expressions (e.g. \`x\`, \`x.y.z\`, \`x?.y?.z\`)`,
|
reason: `Expected the dependency list to be an array of simple expressions (e.g. \`x\`, \`x.y.z\`, \`x?.y?.z\`)`,
|
||||||
description: `Expected the dependency list to be an array of simple expressions (e.g. \`x\`, \`x.y.z\`, \`x?.y?.z\`)`,
|
description: `Expected the dependency list to be an array of simple expressions (e.g. \`x\`, \`x.y.z\`, \`x?.y?.z\`)`,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: dep.loc,
|
loc: dep.loc,
|
||||||
message: `Expected the dependency list to be an array of simple expressions (e.g. \`x\`, \`x.y.z\`, \`x?.y?.z\`)`,
|
message: `Expected the dependency list to be an array of simple expressions (e.g. \`x\`, \`x.y.z\`, \`x?.y?.z\`)`,
|
||||||
|
|
@ -462,7 +462,7 @@ export function dropManualMemoization(
|
||||||
: 'useMemo'
|
: 'useMemo'
|
||||||
} callback doesn't return a value. useMemo is for computing and caching values, not for arbitrary side effects.`,
|
} callback doesn't return a value. useMemo is for computing and caching values, not for arbitrary side effects.`,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: instr.value.loc,
|
loc: instr.value.loc,
|
||||||
message: 'useMemo() callbacks must return a value',
|
message: 'useMemo() callbacks must return a value',
|
||||||
|
|
@ -498,7 +498,7 @@ export function dropManualMemoization(
|
||||||
reason: `Expected the first argument to be an inline function expression`,
|
reason: `Expected the first argument to be an inline function expression`,
|
||||||
description: `Expected the first argument to be an inline function expression`,
|
description: `Expected the first argument to be an inline function expression`,
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: fnPlace.loc,
|
loc: fnPlace.loc,
|
||||||
message: `Expected the first argument to be an inline function expression`,
|
message: `Expected the first argument to be an inline function expression`,
|
||||||
|
|
@ -613,7 +613,14 @@ function findOptionalPlaces(fn: HIRFunction): Set<IdentifierId> {
|
||||||
default: {
|
default: {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected terminal in optional`,
|
reason: `Unexpected terminal in optional`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: `Unexpected ${terminal.kind} in optional`,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -438,7 +438,14 @@ function rewriteSplices(
|
||||||
{
|
{
|
||||||
reason:
|
reason:
|
||||||
'[InferEffectDependencies] Internal invariant broken: expected block instructions to be sorted',
|
'[InferEffectDependencies] Internal invariant broken: expected block instructions to be sorted',
|
||||||
loc: originalInstrs[cursor].loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: originalInstrs[cursor].loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
currBlock.instructions.push(originalInstrs[cursor]);
|
currBlock.instructions.push(originalInstrs[cursor]);
|
||||||
|
|
@ -447,7 +454,14 @@ function rewriteSplices(
|
||||||
CompilerError.invariant(originalInstrs[cursor].id === rewrite.location, {
|
CompilerError.invariant(originalInstrs[cursor].id === rewrite.location, {
|
||||||
reason:
|
reason:
|
||||||
'[InferEffectDependencies] Internal invariant broken: splice location not found',
|
'[InferEffectDependencies] Internal invariant broken: splice location not found',
|
||||||
loc: originalInstrs[cursor].loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: originalInstrs[cursor].loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (rewrite.kind === 'instr') {
|
if (rewrite.kind === 'instr') {
|
||||||
|
|
@ -467,7 +481,14 @@ function rewriteSplices(
|
||||||
{
|
{
|
||||||
reason:
|
reason:
|
||||||
'[InferEffectDependencies] Internal invariant broken: expected entry block to have a fallthrough',
|
'[InferEffectDependencies] Internal invariant broken: expected entry block to have a fallthrough',
|
||||||
loc: entryBlock.terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: entryBlock.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const originalTerminal = currBlock.terminal;
|
const originalTerminal = currBlock.terminal;
|
||||||
|
|
@ -566,7 +587,14 @@ function inferMinimalDependencies(
|
||||||
CompilerError.invariant(hoistableToFnEntry != null, {
|
CompilerError.invariant(hoistableToFnEntry != null, {
|
||||||
reason:
|
reason:
|
||||||
'[InferEffectDependencies] Internal invariant broken: missing entry block',
|
'[InferEffectDependencies] Internal invariant broken: missing entry block',
|
||||||
loc: fnInstr.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: fnInstr.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const dependencies = inferDependencies(
|
const dependencies = inferDependencies(
|
||||||
|
|
@ -622,7 +650,14 @@ function inferDependencies(
|
||||||
CompilerError.invariant(resultUnfiltered != null, {
|
CompilerError.invariant(resultUnfiltered != null, {
|
||||||
reason:
|
reason:
|
||||||
'[InferEffectDependencies] Internal invariant broken: missing scope dependencies',
|
'[InferEffectDependencies] Internal invariant broken: missing scope dependencies',
|
||||||
loc: fn.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: fn.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const fnContext = new Set(fn.context.map(dep => dep.identifier.id));
|
const fnContext = new Set(fn.context.map(dep => dep.identifier.id));
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@ import {
|
||||||
printInstruction,
|
printInstruction,
|
||||||
printInstructionValue,
|
printInstructionValue,
|
||||||
printPlace,
|
printPlace,
|
||||||
printSourceLocation,
|
|
||||||
} from '../HIR/PrintHIR';
|
} from '../HIR/PrintHIR';
|
||||||
import {FunctionSignature} from '../HIR/ObjectShape';
|
import {FunctionSignature} from '../HIR/ObjectShape';
|
||||||
import prettyFormat from 'pretty-format';
|
import prettyFormat from 'pretty-format';
|
||||||
|
|
@ -135,7 +134,13 @@ export function inferMutationAliasingEffects(
|
||||||
reason:
|
reason:
|
||||||
'Expected React component to have not more than two parameters: one for props and for ref',
|
'Expected React component to have not more than two parameters: one for props and for ref',
|
||||||
description: null,
|
description: null,
|
||||||
loc: fn.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: fn.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const [props, ref] = fn.params;
|
const [props, ref] = fn.params;
|
||||||
|
|
@ -202,7 +207,13 @@ export function inferMutationAliasingEffects(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `[InferMutationAliasingEffects] Potential infinite loop`,
|
reason: `[InferMutationAliasingEffects] Potential infinite loop`,
|
||||||
description: `A value, temporary place, or effect was not cached properly`,
|
description: `A value, temporary place, or effect was not cached properly`,
|
||||||
loc: fn.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: fn.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (const [blockId, block] of fn.body.blocks) {
|
for (const [blockId, block] of fn.body.blocks) {
|
||||||
|
|
@ -357,7 +368,14 @@ function inferBlock(
|
||||||
CompilerError.invariant(state.kind(handlerParam) != null, {
|
CompilerError.invariant(state.kind(handlerParam) != null, {
|
||||||
reason:
|
reason:
|
||||||
'Expected catch binding to be intialized with a DeclareLocal Catch instruction',
|
'Expected catch binding to be intialized with a DeclareLocal Catch instruction',
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const effects: Array<AliasingEffect> = [];
|
const effects: Array<AliasingEffect> = [];
|
||||||
for (const instr of block.instructions) {
|
for (const instr of block.instructions) {
|
||||||
|
|
@ -456,7 +474,7 @@ function applySignature(
|
||||||
category: ErrorCategory.Immutability,
|
category: ErrorCategory.Immutability,
|
||||||
reason: 'This value cannot be modified',
|
reason: 'This value cannot be modified',
|
||||||
description: `${reason}.`,
|
description: `${reason}.`,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: effect.value.loc,
|
loc: effect.value.loc,
|
||||||
message: `${variable} cannot be modified`,
|
message: `${variable} cannot be modified`,
|
||||||
|
|
@ -465,7 +483,7 @@ function applySignature(
|
||||||
effect.kind === 'Mutate' &&
|
effect.kind === 'Mutate' &&
|
||||||
effect.reason?.kind === 'AssignCurrentProperty'
|
effect.reason?.kind === 'AssignCurrentProperty'
|
||||||
) {
|
) {
|
||||||
diagnostic.withDetail({
|
diagnostic.withDetails({
|
||||||
kind: 'hint',
|
kind: 'hint',
|
||||||
message: `Hint: If this value is a Ref (value returned by \`useRef()\`), rename the variable to end in "Ref".`,
|
message: `Hint: If this value is a Ref (value returned by \`useRef()\`), rename the variable to end in "Ref".`,
|
||||||
});
|
});
|
||||||
|
|
@ -507,7 +525,14 @@ function applySignature(
|
||||||
) {
|
) {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Expected instruction lvalue to be initialized`,
|
reason: `Expected instruction lvalue to be initialized`,
|
||||||
loc: instruction.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instruction.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return effects.length !== 0 ? effects : null;
|
return effects.length !== 0 ? effects : null;
|
||||||
|
|
@ -536,7 +561,13 @@ function applyEffect(
|
||||||
CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
|
CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
|
||||||
reason: `Cannot re-initialize variable within an instruction`,
|
reason: `Cannot re-initialize variable within an instruction`,
|
||||||
description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
|
description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
|
||||||
loc: effect.into.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: effect.into.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
initialized.add(effect.into.identifier.id);
|
initialized.add(effect.into.identifier.id);
|
||||||
|
|
||||||
|
|
@ -575,7 +606,13 @@ function applyEffect(
|
||||||
CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
|
CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
|
||||||
reason: `Cannot re-initialize variable within an instruction`,
|
reason: `Cannot re-initialize variable within an instruction`,
|
||||||
description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
|
description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
|
||||||
loc: effect.into.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: effect.into.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
initialized.add(effect.into.identifier.id);
|
initialized.add(effect.into.identifier.id);
|
||||||
|
|
||||||
|
|
@ -635,7 +672,13 @@ function applyEffect(
|
||||||
CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
|
CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
|
||||||
reason: `Cannot re-initialize variable within an instruction`,
|
reason: `Cannot re-initialize variable within an instruction`,
|
||||||
description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
|
description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
|
||||||
loc: effect.into.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: effect.into.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
initialized.add(effect.into.identifier.id);
|
initialized.add(effect.into.identifier.id);
|
||||||
|
|
||||||
|
|
@ -709,7 +752,13 @@ function applyEffect(
|
||||||
{
|
{
|
||||||
reason: `Expected destination value to already be initialized within this instruction for Alias effect`,
|
reason: `Expected destination value to already be initialized within this instruction for Alias effect`,
|
||||||
description: `Destination ${printPlace(effect.into)} is not initialized in this instruction`,
|
description: `Destination ${printPlace(effect.into)} is not initialized in this instruction`,
|
||||||
loc: effect.into.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: effect.into.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
/*
|
/*
|
||||||
|
|
@ -768,7 +817,13 @@ function applyEffect(
|
||||||
CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
|
CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
|
||||||
reason: `Cannot re-initialize variable within an instruction`,
|
reason: `Cannot re-initialize variable within an instruction`,
|
||||||
description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
|
description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
|
||||||
loc: effect.into.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: effect.into.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
initialized.add(effect.into.identifier.id);
|
initialized.add(effect.into.identifier.id);
|
||||||
|
|
||||||
|
|
@ -1042,13 +1097,13 @@ function applyEffect(
|
||||||
description: `${variable ?? 'This variable'} is accessed before it is declared, which prevents the earlier access from updating when this value changes over time.`,
|
description: `${variable ?? 'This variable'} is accessed before it is declared, which prevents the earlier access from updating when this value changes over time.`,
|
||||||
});
|
});
|
||||||
if (hoistedAccess != null && hoistedAccess.loc != effect.value.loc) {
|
if (hoistedAccess != null && hoistedAccess.loc != effect.value.loc) {
|
||||||
diagnostic.withDetail({
|
diagnostic.withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: hoistedAccess.loc,
|
loc: hoistedAccess.loc,
|
||||||
message: `${variable ?? 'variable'} accessed before it is declared`,
|
message: `${variable ?? 'variable'} accessed before it is declared`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
diagnostic.withDetail({
|
diagnostic.withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: effect.value.loc,
|
loc: effect.value.loc,
|
||||||
message: `${variable ?? 'variable'} is declared here`,
|
message: `${variable ?? 'variable'} is declared here`,
|
||||||
|
|
@ -1079,7 +1134,7 @@ function applyEffect(
|
||||||
category: ErrorCategory.Immutability,
|
category: ErrorCategory.Immutability,
|
||||||
reason: 'This value cannot be modified',
|
reason: 'This value cannot be modified',
|
||||||
description: `${reason}.`,
|
description: `${reason}.`,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: effect.value.loc,
|
loc: effect.value.loc,
|
||||||
message: `${variable} cannot be modified`,
|
message: `${variable} cannot be modified`,
|
||||||
|
|
@ -1088,7 +1143,7 @@ function applyEffect(
|
||||||
effect.kind === 'Mutate' &&
|
effect.kind === 'Mutate' &&
|
||||||
effect.reason?.kind === 'AssignCurrentProperty'
|
effect.reason?.kind === 'AssignCurrentProperty'
|
||||||
) {
|
) {
|
||||||
diagnostic.withDetail({
|
diagnostic.withDetails({
|
||||||
kind: 'hint',
|
kind: 'hint',
|
||||||
message: `Hint: If this value is a Ref (value returned by \`useRef()\`), rename the variable to end in "Ref".`,
|
message: `Hint: If this value is a Ref (value returned by \`useRef()\`), rename the variable to end in "Ref".`,
|
||||||
});
|
});
|
||||||
|
|
@ -1169,7 +1224,13 @@ class InferenceState {
|
||||||
reason:
|
reason:
|
||||||
'[InferMutationAliasingEffects] Expected all top-level identifiers to be defined as variables, not values',
|
'[InferMutationAliasingEffects] Expected all top-level identifiers to be defined as variables, not values',
|
||||||
description: null,
|
description: null,
|
||||||
loc: value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
this.#values.set(value, kind);
|
this.#values.set(value, kind);
|
||||||
|
|
@ -1180,7 +1241,13 @@ class InferenceState {
|
||||||
CompilerError.invariant(values != null, {
|
CompilerError.invariant(values != null, {
|
||||||
reason: `[InferMutationAliasingEffects] Expected value kind to be initialized`,
|
reason: `[InferMutationAliasingEffects] Expected value kind to be initialized`,
|
||||||
description: `${printPlace(place)}`,
|
description: `${printPlace(place)}`,
|
||||||
loc: place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: 'this is uninitialized',
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return Array.from(values);
|
return Array.from(values);
|
||||||
|
|
@ -1192,7 +1259,13 @@ class InferenceState {
|
||||||
CompilerError.invariant(values != null, {
|
CompilerError.invariant(values != null, {
|
||||||
reason: `[InferMutationAliasingEffects] Expected value kind to be initialized`,
|
reason: `[InferMutationAliasingEffects] Expected value kind to be initialized`,
|
||||||
description: `${printPlace(place)}`,
|
description: `${printPlace(place)}`,
|
||||||
loc: place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: 'this is uninitialized',
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
let mergedKind: AbstractValue | null = null;
|
let mergedKind: AbstractValue | null = null;
|
||||||
|
|
@ -1204,7 +1277,13 @@ class InferenceState {
|
||||||
CompilerError.invariant(mergedKind !== null, {
|
CompilerError.invariant(mergedKind !== null, {
|
||||||
reason: `[InferMutationAliasingEffects] Expected at least one value`,
|
reason: `[InferMutationAliasingEffects] Expected at least one value`,
|
||||||
description: `No value found at \`${printPlace(place)}\``,
|
description: `No value found at \`${printPlace(place)}\``,
|
||||||
loc: place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return mergedKind;
|
return mergedKind;
|
||||||
|
|
@ -1216,7 +1295,13 @@ class InferenceState {
|
||||||
CompilerError.invariant(values != null, {
|
CompilerError.invariant(values != null, {
|
||||||
reason: `[InferMutationAliasingEffects] Expected value for identifier to be initialized`,
|
reason: `[InferMutationAliasingEffects] Expected value for identifier to be initialized`,
|
||||||
description: `${printIdentifier(value.identifier)}`,
|
description: `${printIdentifier(value.identifier)}`,
|
||||||
loc: value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: value.loc,
|
||||||
|
message: 'Expected value for identifier to be initialized',
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
this.#variables.set(place.identifier.id, new Set(values));
|
this.#variables.set(place.identifier.id, new Set(values));
|
||||||
|
|
@ -1227,7 +1312,13 @@ class InferenceState {
|
||||||
CompilerError.invariant(values != null, {
|
CompilerError.invariant(values != null, {
|
||||||
reason: `[InferMutationAliasingEffects] Expected value for identifier to be initialized`,
|
reason: `[InferMutationAliasingEffects] Expected value for identifier to be initialized`,
|
||||||
description: `${printIdentifier(value.identifier)}`,
|
description: `${printIdentifier(value.identifier)}`,
|
||||||
loc: value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: value.loc,
|
||||||
|
message: 'Expected value for identifier to be initialized',
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const prevValues = this.values(place);
|
const prevValues = this.values(place);
|
||||||
|
|
@ -1240,11 +1331,15 @@ class InferenceState {
|
||||||
// Defines (initializing or updating) a variable with a specific kind of value.
|
// Defines (initializing or updating) a variable with a specific kind of value.
|
||||||
define(place: Place, value: InstructionValue): void {
|
define(place: Place, value: InstructionValue): void {
|
||||||
CompilerError.invariant(this.#values.has(value), {
|
CompilerError.invariant(this.#values.has(value), {
|
||||||
reason: `[InferMutationAliasingEffects] Expected value to be initialized at '${printSourceLocation(
|
reason: `[InferMutationAliasingEffects] Expected value to be initialized`,
|
||||||
value.loc,
|
|
||||||
)}'`,
|
|
||||||
description: printInstructionValue(value),
|
description: printInstructionValue(value),
|
||||||
loc: value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: value.loc,
|
||||||
|
message: 'Expected value for identifier to be initialized',
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
this.#variables.set(place.identifier.id, new Set([value]));
|
this.#variables.set(place.identifier.id, new Set([value]));
|
||||||
|
|
@ -2055,7 +2150,7 @@ function computeSignatureForInstruction(
|
||||||
reason:
|
reason:
|
||||||
'Cannot reassign variables declared outside of the component/hook',
|
'Cannot reassign variables declared outside of the component/hook',
|
||||||
description: `Variable ${variable} is declared outside of the component/hook. Reassigning this value during render is a form of side effect, which can cause unpredictable behavior depending on when the component happens to re-render. If this variable is used in rendering, use useState instead. Otherwise, consider updating it in an effect. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)`,
|
description: `Variable ${variable} is declared outside of the component/hook. Reassigning this value during render is a form of side effect, which can cause unpredictable behavior depending on when the component happens to re-render. If this variable is used in rendering, use useState instead. Otherwise, consider updating it in an effect. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)`,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: instr.loc,
|
loc: instr.loc,
|
||||||
message: `${variable} cannot be reassigned`,
|
message: `${variable} cannot be reassigned`,
|
||||||
|
|
@ -2157,7 +2252,7 @@ function computeEffectsForLegacySignature(
|
||||||
? `\`${signature.canonicalName}\` is an impure function. `
|
? `\`${signature.canonicalName}\` is an impure function. `
|
||||||
: '') +
|
: '') +
|
||||||
'Calling an impure function can produce unstable results that update unpredictably when the component happens to re-render. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)',
|
'Calling an impure function can produce unstable results that update unpredictably when the component happens to re-render. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)',
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc,
|
loc,
|
||||||
message: 'Cannot call impure function',
|
message: 'Cannot call impure function',
|
||||||
|
|
@ -2176,7 +2271,7 @@ function computeEffectsForLegacySignature(
|
||||||
'However, you may see issues if values from this API are passed to other components/hooks that are ' +
|
'However, you may see issues if values from this API are passed to other components/hooks that are ' +
|
||||||
'memoized.',
|
'memoized.',
|
||||||
].join(''),
|
].join(''),
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: receiver.loc,
|
loc: receiver.loc,
|
||||||
message: signature.knownIncompatible,
|
message: signature.knownIncompatible,
|
||||||
|
|
@ -2676,7 +2771,13 @@ export function isKnownMutableEffect(effect: Effect): boolean {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Unexpected unknown effect',
|
reason: 'Unexpected unknown effect',
|
||||||
description: null,
|
description: null,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -2785,7 +2886,13 @@ function mergeValueKinds(a: ValueKind, b: ValueKind): ValueKind {
|
||||||
{
|
{
|
||||||
reason: `Unexpected value kind in mergeValues()`,
|
reason: `Unexpected value kind in mergeValues()`,
|
||||||
description: `Found kinds ${a} and ${b}`,
|
description: `Found kinds ${a} and ${b}`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return ValueKind.Primitive;
|
return ValueKind.Primitive;
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,14 @@ export function inferMutationAliasingRanges(
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(effect.kind === 'Freeze', {
|
CompilerError.invariant(effect.kind === 'Freeze', {
|
||||||
reason: `Unexpected '${effect.kind}' effect for MaybeThrow terminal`,
|
reason: `Unexpected '${effect.kind}' effect for MaybeThrow terminal`,
|
||||||
loc: block.terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: block.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -378,7 +385,14 @@ export function inferMutationAliasingRanges(
|
||||||
case 'Apply': {
|
case 'Apply': {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `[AnalyzeFunctions] Expected Apply effects to be replaced with more precise effects`,
|
reason: `[AnalyzeFunctions] Expected Apply effects to be replaced with more precise effects`,
|
||||||
loc: effect.function.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: effect.function.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
case 'MutateTransitive':
|
case 'MutateTransitive':
|
||||||
|
|
@ -525,7 +539,14 @@ export function inferMutationAliasingRanges(
|
||||||
const fromNode = state.nodes.get(from.identifier);
|
const fromNode = state.nodes.get(from.identifier);
|
||||||
CompilerError.invariant(fromNode != null, {
|
CompilerError.invariant(fromNode != null, {
|
||||||
reason: `Expected a node to exist for all parameters and context variables`,
|
reason: `Expected a node to exist for all parameters and context variables`,
|
||||||
loc: into.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: into.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
if (fromNode.lastMutated === mutationIndex) {
|
if (fromNode.lastMutated === mutationIndex) {
|
||||||
if (into.identifier.id === fn.returns.identifier.id) {
|
if (into.identifier.id === fn.returns.identifier.id) {
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,13 @@ export function inferReactivePlaces(fn: HIRFunction): void {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Unexpected unknown effect',
|
reason: 'Unexpected unknown effect',
|
||||||
description: null,
|
description: null,
|
||||||
loc: operand.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: operand.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,14 @@ function evaluatePhi(phi: Phi, constants: Constants): Constant | null {
|
||||||
case 'Primitive': {
|
case 'Primitive': {
|
||||||
CompilerError.invariant(value.kind === 'Primitive', {
|
CompilerError.invariant(value.kind === 'Primitive', {
|
||||||
reason: 'value kind expected to be Primitive',
|
reason: 'value kind expected to be Primitive',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -204,7 +211,14 @@ function evaluatePhi(phi: Phi, constants: Constants): Constant | null {
|
||||||
case 'LoadGlobal': {
|
case 'LoadGlobal': {
|
||||||
CompilerError.invariant(value.kind === 'LoadGlobal', {
|
CompilerError.invariant(value.kind === 'LoadGlobal', {
|
||||||
reason: 'value kind expected to be LoadGlobal',
|
reason: 'value kind expected to be LoadGlobal',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -709,7 +709,14 @@ function createPropsProperties(
|
||||||
const spreadProp = jsxSpreadAttributes[0];
|
const spreadProp = jsxSpreadAttributes[0];
|
||||||
CompilerError.invariant(spreadProp.kind === 'JsxSpreadAttribute', {
|
CompilerError.invariant(spreadProp.kind === 'JsxSpreadAttribute', {
|
||||||
reason: 'Spread prop attribute must be of kind JSXSpreadAttribute',
|
reason: 'Spread prop attribute must be of kind JSXSpreadAttribute',
|
||||||
loc: instr.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
propsProperty = {
|
propsProperty = {
|
||||||
kind: 'ObjectProperty',
|
kind: 'ObjectProperty',
|
||||||
|
|
|
||||||
|
|
@ -78,10 +78,17 @@ export function instructionReordering(fn: HIRFunction): void {
|
||||||
}
|
}
|
||||||
CompilerError.invariant(shared.size === 0, {
|
CompilerError.invariant(shared.size === 0, {
|
||||||
reason: `InstructionReordering: expected all reorderable nodes to have been emitted`,
|
reason: `InstructionReordering: expected all reorderable nodes to have been emitted`,
|
||||||
loc:
|
description: null,
|
||||||
[...shared.values()]
|
details: [
|
||||||
.map(node => node.instruction?.loc)
|
{
|
||||||
.filter(loc => loc != null)[0] ?? GeneratedSource,
|
kind: 'error',
|
||||||
|
loc:
|
||||||
|
[...shared.values()]
|
||||||
|
.map(node => node.instruction?.loc)
|
||||||
|
.filter(loc => loc != null)[0] ?? GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
markInstructionIds(fn.body);
|
markInstructionIds(fn.body);
|
||||||
}
|
}
|
||||||
|
|
@ -302,7 +309,13 @@ function reorderBlock(
|
||||||
node.reorderability === Reorderability.Reorderable,
|
node.reorderability === Reorderability.Reorderable,
|
||||||
{
|
{
|
||||||
reason: `Expected all remaining instructions to be reorderable`,
|
reason: `Expected all remaining instructions to be reorderable`,
|
||||||
loc: node.instruction?.loc ?? block.terminal.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: node.instruction?.loc ?? block.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
description:
|
description:
|
||||||
node.instruction != null
|
node.instruction != null
|
||||||
? `Instruction [${node.instruction.id}] was not emitted yet but is not reorderable`
|
? `Instruction [${node.instruction.id}] was not emitted yet but is not reorderable`
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,13 @@ export function pruneMaybeThrows(fn: HIRFunction): void {
|
||||||
const mappedTerminal = terminalMapping.get(predecessor);
|
const mappedTerminal = terminalMapping.get(predecessor);
|
||||||
CompilerError.invariant(mappedTerminal != null, {
|
CompilerError.invariant(mappedTerminal != null, {
|
||||||
reason: `Expected non-existing phi operand's predecessor to have been mapped to a new terminal`,
|
reason: `Expected non-existing phi operand's predecessor to have been mapped to a new terminal`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
description: `Could not find mapping for predecessor bb${predecessor} in block bb${
|
description: `Could not find mapping for predecessor bb${predecessor} in block bb${
|
||||||
block.id
|
block.id
|
||||||
} for phi ${printPlace(phi.place)}`,
|
} for phi ${printPlace(phi.place)}`,
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,15 @@ function findScopesToMerge(fn: HIRFunction): DisjointSet<ReactiveScope> {
|
||||||
{
|
{
|
||||||
reason:
|
reason:
|
||||||
'Internal error: Expected all ObjectExpressions and ObjectMethods to have non-null scope.',
|
'Internal error: Expected all ObjectExpressions and ObjectMethods to have non-null scope.',
|
||||||
|
description: null,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
mergeScopesBuilder.union([operandScope, lvalueScope]);
|
mergeScopesBuilder.union([operandScope, lvalueScope]);
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,14 @@ export function alignReactiveScopesToBlockScopesHIR(fn: HIRFunction): void {
|
||||||
|
|
||||||
CompilerError.invariant(!valueBlockNodes.has(fallthrough), {
|
CompilerError.invariant(!valueBlockNodes.has(fallthrough), {
|
||||||
reason: 'Expect hir blocks to have unique fallthroughs',
|
reason: 'Expect hir blocks to have unique fallthroughs',
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
valueBlockNodes.set(fallthrough, node);
|
valueBlockNodes.set(fallthrough, node);
|
||||||
|
|
@ -252,7 +259,14 @@ export function alignReactiveScopesToBlockScopesHIR(fn: HIRFunction): void {
|
||||||
// Transition from block->value block, derive the outer block range
|
// Transition from block->value block, derive the outer block range
|
||||||
CompilerError.invariant(fallthrough !== null, {
|
CompilerError.invariant(fallthrough !== null, {
|
||||||
reason: `Expected a fallthrough for value block`,
|
reason: `Expected a fallthrough for value block`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const fallthroughBlock = fn.body.blocks.get(fallthrough)!;
|
const fallthroughBlock = fn.body.blocks.get(fallthrough)!;
|
||||||
const nextId =
|
const nextId =
|
||||||
|
|
|
||||||
|
|
@ -81,10 +81,16 @@ class CheckInstructionsAgainstScopesVisitor extends ReactiveFunctionVisitor<
|
||||||
!this.activeScopes.has(scope.id)
|
!this.activeScopes.has(scope.id)
|
||||||
) {
|
) {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
description: `Instruction [${id}] is part of scope @${scope.id}, but that scope has already completed.`,
|
|
||||||
loc: place.loc,
|
|
||||||
reason:
|
reason:
|
||||||
'Encountered an instruction that should be part of a scope, but where that scope has already completed',
|
'Encountered an instruction that should be part of a scope, but where that scope has already completed',
|
||||||
|
description: `Instruction [${id}] is part of scope @${scope.id}, but that scope has already completed.`,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,14 @@ class Visitor extends ReactiveFunctionVisitor<Set<BlockId>> {
|
||||||
if (terminal.kind === 'break' || terminal.kind === 'continue') {
|
if (terminal.kind === 'break' || terminal.kind === 'continue') {
|
||||||
CompilerError.invariant(seenLabels.has(terminal.target), {
|
CompilerError.invariant(seenLabels.has(terminal.target), {
|
||||||
reason: 'Unexpected break to invalid label',
|
reason: 'Unexpected break to invalid label',
|
||||||
loc: stmt.terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: stmt.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,13 @@ class Driver {
|
||||||
CompilerError.invariant(!this.cx.emitted.has(block.id), {
|
CompilerError.invariant(!this.cx.emitted.has(block.id), {
|
||||||
reason: `Cannot emit the same block twice: bb${block.id}`,
|
reason: `Cannot emit the same block twice: bb${block.id}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
this.cx.emitted.add(block.id);
|
this.cx.emitted.add(block.id);
|
||||||
|
|
@ -130,7 +136,14 @@ class Driver {
|
||||||
if (this.cx.isScheduled(terminal.consequent)) {
|
if (this.cx.isScheduled(terminal.consequent)) {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected 'if' where the consequent is already scheduled`,
|
reason: `Unexpected 'if' where the consequent is already scheduled`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
consequent = this.traverseBlock(
|
consequent = this.traverseBlock(
|
||||||
|
|
@ -143,7 +156,14 @@ class Driver {
|
||||||
if (this.cx.isScheduled(alternateId)) {
|
if (this.cx.isScheduled(alternateId)) {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected 'if' where the alternate is already scheduled`,
|
reason: `Unexpected 'if' where the alternate is already scheduled`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
alternate = this.traverseBlock(this.cx.ir.blocks.get(alternateId)!);
|
alternate = this.traverseBlock(this.cx.ir.blocks.get(alternateId)!);
|
||||||
|
|
@ -196,7 +216,14 @@ class Driver {
|
||||||
if (this.cx.isScheduled(case_.block)) {
|
if (this.cx.isScheduled(case_.block)) {
|
||||||
CompilerError.invariant(case_.block === terminal.fallthrough, {
|
CompilerError.invariant(case_.block === terminal.fallthrough, {
|
||||||
reason: `Unexpected 'switch' where a case is already scheduled and block is not the fallthrough`,
|
reason: `Unexpected 'switch' where a case is already scheduled and block is not the fallthrough`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -255,7 +282,14 @@ class Driver {
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected 'do-while' where the loop is already scheduled`,
|
reason: `Unexpected 'do-while' where the loop is already scheduled`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -316,7 +350,14 @@ class Driver {
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected 'while' where the loop is already scheduled`,
|
reason: `Unexpected 'while' where the loop is already scheduled`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -402,7 +443,14 @@ class Driver {
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected 'for' where the loop is already scheduled`,
|
reason: `Unexpected 'for' where the loop is already scheduled`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -500,7 +548,14 @@ class Driver {
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected 'for-of' where the loop is already scheduled`,
|
reason: `Unexpected 'for-of' where the loop is already scheduled`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -572,7 +627,14 @@ class Driver {
|
||||||
} else {
|
} else {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected 'for-in' where the loop is already scheduled`,
|
reason: `Unexpected 'for-in' where the loop is already scheduled`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -615,7 +677,14 @@ class Driver {
|
||||||
if (this.cx.isScheduled(terminal.alternate)) {
|
if (this.cx.isScheduled(terminal.alternate)) {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected 'branch' where the alternate is already scheduled`,
|
reason: `Unexpected 'branch' where the alternate is already scheduled`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
alternate = this.traverseBlock(
|
alternate = this.traverseBlock(
|
||||||
|
|
@ -653,7 +722,14 @@ class Driver {
|
||||||
if (this.cx.isScheduled(terminal.block)) {
|
if (this.cx.isScheduled(terminal.block)) {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected 'label' where the block is already scheduled`,
|
reason: `Unexpected 'label' where the block is already scheduled`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
block = this.traverseBlock(this.cx.ir.blocks.get(terminal.block)!);
|
block = this.traverseBlock(this.cx.ir.blocks.get(terminal.block)!);
|
||||||
|
|
@ -811,7 +887,14 @@ class Driver {
|
||||||
if (this.cx.isScheduled(terminal.block)) {
|
if (this.cx.isScheduled(terminal.block)) {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected 'scope' where the block is already scheduled`,
|
reason: `Unexpected 'scope' where the block is already scheduled`,
|
||||||
loc: terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
block = this.traverseBlock(this.cx.ir.blocks.get(terminal.block)!);
|
block = this.traverseBlock(this.cx.ir.blocks.get(terminal.block)!);
|
||||||
|
|
@ -837,7 +920,13 @@ class Driver {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Unexpected unsupported terminal',
|
reason: 'Unexpected unsupported terminal',
|
||||||
description: null,
|
description: null,
|
||||||
loc: terminal.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -874,7 +963,13 @@ class Driver {
|
||||||
reason:
|
reason:
|
||||||
'Expected branch block to end in an instruction that sets the test value',
|
'Expected branch block to end in an instruction that sets the test value',
|
||||||
description: null,
|
description: null,
|
||||||
loc: instr.lvalue.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.lvalue.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -906,7 +1001,13 @@ class Driver {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Expected goto value block to have at least one instruction',
|
reason: 'Expected goto value block to have at least one instruction',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
} else if (defaultBlock.instructions.length === 1) {
|
} else if (defaultBlock.instructions.length === 1) {
|
||||||
|
|
@ -1191,14 +1292,27 @@ class Driver {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Expected a break target',
|
reason: 'Expected a break target',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.cx.scopeFallthroughs.has(target.block)) {
|
if (this.cx.scopeFallthroughs.has(target.block)) {
|
||||||
CompilerError.invariant(target.type === 'implicit', {
|
CompilerError.invariant(target.type === 'implicit', {
|
||||||
reason: 'Expected reactive scope to implicitly break to fallthrough',
|
reason: 'Expected reactive scope to implicitly break to fallthrough',
|
||||||
loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -1224,7 +1338,13 @@ class Driver {
|
||||||
CompilerError.invariant(target !== null, {
|
CompilerError.invariant(target !== null, {
|
||||||
reason: `Expected continue target to be scheduled for bb${block}`,
|
reason: `Expected continue target to be scheduled for bb${block}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1299,7 +1419,13 @@ class Context {
|
||||||
CompilerError.invariant(!this.#scheduled.has(block), {
|
CompilerError.invariant(!this.#scheduled.has(block), {
|
||||||
reason: `Break block is already scheduled: bb${block}`,
|
reason: `Break block is already scheduled: bb${block}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
this.#scheduled.add(block);
|
this.#scheduled.add(block);
|
||||||
|
|
@ -1318,7 +1444,13 @@ class Context {
|
||||||
CompilerError.invariant(!this.#scheduled.has(continueBlock), {
|
CompilerError.invariant(!this.#scheduled.has(continueBlock), {
|
||||||
reason: `Continue block is already scheduled: bb${continueBlock}`,
|
reason: `Continue block is already scheduled: bb${continueBlock}`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
this.#scheduled.add(continueBlock);
|
this.#scheduled.add(continueBlock);
|
||||||
|
|
@ -1346,7 +1478,13 @@ class Context {
|
||||||
CompilerError.invariant(last !== undefined && last.id === scheduleId, {
|
CompilerError.invariant(last !== undefined && last.id === scheduleId, {
|
||||||
reason: 'Can only unschedule the last target',
|
reason: 'Can only unschedule the last target',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (last.type !== 'loop' || last.ownsBlock !== null) {
|
if (last.type !== 'loop' || last.ownsBlock !== null) {
|
||||||
|
|
@ -1421,7 +1559,13 @@ class Context {
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Expected a break target',
|
reason: 'Expected a break target',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,14 @@ export function codegenFunction(
|
||||||
CompilerError.invariant(globalGating != null, {
|
CompilerError.invariant(globalGating != null, {
|
||||||
reason:
|
reason:
|
||||||
'Bad config not caught! Expected at least one of gating or globalGating',
|
'Bad config not caught! Expected at least one of gating or globalGating',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
ifTest = globalGating;
|
ifTest = globalGating;
|
||||||
|
|
@ -499,10 +506,16 @@ function codegenBlock(cx: Context, block: ReactiveBlock): t.BlockStatement {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CompilerError.invariant(temp.get(key)! === value, {
|
CompilerError.invariant(temp.get(key)! === value, {
|
||||||
loc: null,
|
|
||||||
reason: 'Expected temporary value to be unchanged',
|
reason: 'Expected temporary value to be unchanged',
|
||||||
description: null,
|
description: null,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
cx.temp = temp;
|
cx.temp = temp;
|
||||||
|
|
@ -670,7 +683,13 @@ function codegenReactiveScope(
|
||||||
description: `Declaration \`${printIdentifier(
|
description: `Declaration \`${printIdentifier(
|
||||||
identifier,
|
identifier,
|
||||||
)}\` is unnamed in scope @${scope.id}`,
|
)}\` is unnamed in scope @${scope.id}`,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -707,7 +726,13 @@ function codegenReactiveScope(
|
||||||
CompilerError.invariant(firstOutputIndex !== null, {
|
CompilerError.invariant(firstOutputIndex !== null, {
|
||||||
reason: `Expected scope to have at least one declaration`,
|
reason: `Expected scope to have at least one declaration`,
|
||||||
description: `Scope '@${scope.id}' has no declarations`,
|
description: `Scope '@${scope.id}' has no declarations`,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
testCondition = t.binaryExpression(
|
testCondition = t.binaryExpression(
|
||||||
|
|
@ -730,7 +755,13 @@ function codegenReactiveScope(
|
||||||
{
|
{
|
||||||
reason: `Expected to not have both change detection enabled and memoization disabled`,
|
reason: `Expected to not have both change detection enabled and memoization disabled`,
|
||||||
description: `Incompatible config options`,
|
description: `Incompatible config options`,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
testCondition = t.logicalExpression(
|
testCondition = t.logicalExpression(
|
||||||
|
|
@ -914,8 +945,14 @@ function codegenReactiveScope(
|
||||||
earlyReturnValue.value.name.kind === 'named',
|
earlyReturnValue.value.name.kind === 'named',
|
||||||
{
|
{
|
||||||
reason: `Expected early return value to be promoted to a named variable`,
|
reason: `Expected early return value to be promoted to a named variable`,
|
||||||
loc: earlyReturnValue.loc,
|
|
||||||
description: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: earlyReturnValue.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -975,7 +1012,13 @@ function codegenTerminal(
|
||||||
CompilerError.invariant(terminal.init.kind === 'SequenceExpression', {
|
CompilerError.invariant(terminal.init.kind === 'SequenceExpression', {
|
||||||
reason: `Expected a sequence expression init for for..in`,
|
reason: `Expected a sequence expression init for for..in`,
|
||||||
description: `Got \`${terminal.init.kind}\` expression instead`,
|
description: `Got \`${terminal.init.kind}\` expression instead`,
|
||||||
loc: terminal.init.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.init.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (terminal.init.instructions.length !== 2) {
|
if (terminal.init.instructions.length !== 2) {
|
||||||
|
|
@ -1010,7 +1053,13 @@ function codegenTerminal(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Expected a StoreLocal or Destructure to be assigned to the collection`,
|
reason: `Expected a StoreLocal or Destructure to be assigned to the collection`,
|
||||||
description: `Found ${iterableItem.value.kind}`,
|
description: `Found ${iterableItem.value.kind}`,
|
||||||
loc: iterableItem.value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: iterableItem.value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1027,7 +1076,13 @@ function codegenTerminal(
|
||||||
reason:
|
reason:
|
||||||
'Destructure should never be Reassign as it would be an Object/ArrayPattern',
|
'Destructure should never be Reassign as it would be an Object/ArrayPattern',
|
||||||
description: null,
|
description: null,
|
||||||
loc: iterableItem.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: iterableItem.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
case InstructionKind.Catch:
|
case InstructionKind.Catch:
|
||||||
|
|
@ -1038,7 +1093,13 @@ function codegenTerminal(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected ${iterableItem.value.lvalue.kind} variable in for..in collection`,
|
reason: `Unexpected ${iterableItem.value.lvalue.kind} variable in for..in collection`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: iterableItem.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: iterableItem.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
|
|
@ -1067,7 +1128,13 @@ function codegenTerminal(
|
||||||
{
|
{
|
||||||
reason: `Expected a single-expression sequence expression init for for..of`,
|
reason: `Expected a single-expression sequence expression init for for..of`,
|
||||||
description: `Got \`${terminal.init.kind}\` expression instead`,
|
description: `Got \`${terminal.init.kind}\` expression instead`,
|
||||||
loc: terminal.init.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.init.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -1076,7 +1143,13 @@ function codegenTerminal(
|
||||||
CompilerError.invariant(terminal.test.kind === 'SequenceExpression', {
|
CompilerError.invariant(terminal.test.kind === 'SequenceExpression', {
|
||||||
reason: `Expected a sequence expression test for for..of`,
|
reason: `Expected a sequence expression test for for..of`,
|
||||||
description: `Got \`${terminal.init.kind}\` expression instead`,
|
description: `Got \`${terminal.init.kind}\` expression instead`,
|
||||||
loc: terminal.test.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.test.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (terminal.test.instructions.length !== 2) {
|
if (terminal.test.instructions.length !== 2) {
|
||||||
|
|
@ -1110,7 +1183,13 @@ function codegenTerminal(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Expected a StoreLocal or Destructure to be assigned to the collection`,
|
reason: `Expected a StoreLocal or Destructure to be assigned to the collection`,
|
||||||
description: `Found ${iterableItem.value.kind}`,
|
description: `Found ${iterableItem.value.kind}`,
|
||||||
loc: iterableItem.value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: iterableItem.value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1131,7 +1210,13 @@ function codegenTerminal(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected ${iterableItem.value.lvalue.kind} variable in for..of collection`,
|
reason: `Unexpected ${iterableItem.value.lvalue.kind} variable in for..of collection`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: iterableItem.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: iterableItem.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
|
|
@ -1272,7 +1357,13 @@ function codegenInstructionNullable(
|
||||||
reason:
|
reason:
|
||||||
'Encountered a destructuring operation where some identifiers are already declared (reassignments) but others are not (declarations)',
|
'Encountered a destructuring operation where some identifiers are already declared (reassignments) but others are not (declarations)',
|
||||||
description: null,
|
description: null,
|
||||||
loc: instr.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
} else if (hasReassign) {
|
} else if (hasReassign) {
|
||||||
|
|
@ -1285,7 +1376,13 @@ function codegenInstructionNullable(
|
||||||
CompilerError.invariant(instr.lvalue === null, {
|
CompilerError.invariant(instr.lvalue === null, {
|
||||||
reason: `Const declaration cannot be referenced as an expression`,
|
reason: `Const declaration cannot be referenced as an expression`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: instr.value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.value.loc,
|
||||||
|
message: `this is ${kind}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return createVariableDeclaration(instr.loc, 'const', [
|
return createVariableDeclaration(instr.loc, 'const', [
|
||||||
|
|
@ -1296,20 +1393,38 @@ function codegenInstructionNullable(
|
||||||
CompilerError.invariant(instr.lvalue === null, {
|
CompilerError.invariant(instr.lvalue === null, {
|
||||||
reason: `Function declaration cannot be referenced as an expression`,
|
reason: `Function declaration cannot be referenced as an expression`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: instr.value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.value.loc,
|
||||||
|
message: `this is ${kind}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const genLvalue = codegenLValue(cx, lvalue);
|
const genLvalue = codegenLValue(cx, lvalue);
|
||||||
CompilerError.invariant(genLvalue.type === 'Identifier', {
|
CompilerError.invariant(genLvalue.type === 'Identifier', {
|
||||||
reason: 'Expected an identifier as a function declaration lvalue',
|
reason: 'Expected an identifier as a function declaration lvalue',
|
||||||
description: null,
|
description: null,
|
||||||
loc: instr.value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
CompilerError.invariant(value?.type === 'FunctionExpression', {
|
CompilerError.invariant(value?.type === 'FunctionExpression', {
|
||||||
reason: 'Expected a function as a function declaration value',
|
reason: 'Expected a function as a function declaration value',
|
||||||
description: `Got ${value == null ? String(value) : value.type} at ${printInstruction(instr)}`,
|
description: `Got ${value == null ? String(value) : value.type} at ${printInstruction(instr)}`,
|
||||||
loc: instr.value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return createFunctionDeclaration(
|
return createFunctionDeclaration(
|
||||||
|
|
@ -1325,7 +1440,13 @@ function codegenInstructionNullable(
|
||||||
CompilerError.invariant(instr.lvalue === null, {
|
CompilerError.invariant(instr.lvalue === null, {
|
||||||
reason: `Const declaration cannot be referenced as an expression`,
|
reason: `Const declaration cannot be referenced as an expression`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: instr.value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.value.loc,
|
||||||
|
message: 'this is const',
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return createVariableDeclaration(instr.loc, 'let', [
|
return createVariableDeclaration(instr.loc, 'let', [
|
||||||
|
|
@ -1336,7 +1457,13 @@ function codegenInstructionNullable(
|
||||||
CompilerError.invariant(value !== null, {
|
CompilerError.invariant(value !== null, {
|
||||||
reason: 'Expected a value for reassignment',
|
reason: 'Expected a value for reassignment',
|
||||||
description: null,
|
description: null,
|
||||||
loc: instr.value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const expr = t.assignmentExpression(
|
const expr = t.assignmentExpression(
|
||||||
|
|
@ -1369,7 +1496,13 @@ function codegenInstructionNullable(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Expected ${kind} to have been pruned in PruneHoistedContexts`,
|
reason: `Expected ${kind} to have been pruned in PruneHoistedContexts`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: instr.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1387,7 +1520,14 @@ function codegenInstructionNullable(
|
||||||
} else if (instr.value.kind === 'ObjectMethod') {
|
} else if (instr.value.kind === 'ObjectMethod') {
|
||||||
CompilerError.invariant(instr.lvalue, {
|
CompilerError.invariant(instr.lvalue, {
|
||||||
reason: 'Expected object methods to have a temp lvalue',
|
reason: 'Expected object methods to have a temp lvalue',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
cx.objectMethods.set(instr.lvalue.identifier.id, instr.value);
|
cx.objectMethods.set(instr.lvalue.identifier.id, instr.value);
|
||||||
|
|
@ -1434,7 +1574,13 @@ function codegenForInit(
|
||||||
(instr.kind === 'let' || instr.kind === 'const'),
|
(instr.kind === 'let' || instr.kind === 'const'),
|
||||||
{
|
{
|
||||||
reason: 'Expected a variable declaration',
|
reason: 'Expected a variable declaration',
|
||||||
loc: init.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: init.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
description: `Got ${instr.type}`,
|
description: `Got ${instr.type}`,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
|
|
@ -1447,7 +1593,13 @@ function codegenForInit(
|
||||||
});
|
});
|
||||||
CompilerError.invariant(declarators.length > 0, {
|
CompilerError.invariant(declarators.length > 0, {
|
||||||
reason: 'Expected a variable declaration',
|
reason: 'Expected a variable declaration',
|
||||||
loc: init.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: init.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
description: null,
|
description: null,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
@ -1768,7 +1920,13 @@ function codegenInstructionValue(
|
||||||
CompilerError.invariant(t.isExpression(optionalValue.callee), {
|
CompilerError.invariant(t.isExpression(optionalValue.callee), {
|
||||||
reason: 'v8 intrinsics are validated during lowering',
|
reason: 'v8 intrinsics are validated during lowering',
|
||||||
description: null,
|
description: null,
|
||||||
loc: optionalValue.callee.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: optionalValue.callee.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
value = t.optionalCallExpression(
|
value = t.optionalCallExpression(
|
||||||
|
|
@ -1784,7 +1942,13 @@ function codegenInstructionValue(
|
||||||
CompilerError.invariant(t.isExpression(property), {
|
CompilerError.invariant(t.isExpression(property), {
|
||||||
reason: 'Private names are validated during lowering',
|
reason: 'Private names are validated during lowering',
|
||||||
description: null,
|
description: null,
|
||||||
loc: property.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: property.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
value = t.optionalMemberExpression(
|
value = t.optionalMemberExpression(
|
||||||
|
|
@ -1800,7 +1964,13 @@ function codegenInstructionValue(
|
||||||
reason:
|
reason:
|
||||||
'Expected an optional value to resolve to a call expression or member expression',
|
'Expected an optional value to resolve to a call expression or member expression',
|
||||||
description: `Got a \`${optionalValue.type}\``,
|
description: `Got a \`${optionalValue.type}\``,
|
||||||
loc: instrValue.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instrValue.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1816,10 +1986,15 @@ function codegenInstructionValue(
|
||||||
t.isOptionalMemberExpression(memberExpr),
|
t.isOptionalMemberExpression(memberExpr),
|
||||||
{
|
{
|
||||||
reason:
|
reason:
|
||||||
'[Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression. ' +
|
'[Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression',
|
||||||
`Got a \`${memberExpr.type}\``,
|
|
||||||
description: null,
|
description: null,
|
||||||
loc: memberExpr.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: memberExpr.loc ?? null,
|
||||||
|
message: `Got: '${memberExpr.type}'`,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -1833,7 +2008,13 @@ function codegenInstructionValue(
|
||||||
'[Codegen] Internal error: Forget should always generate MethodCall::property ' +
|
'[Codegen] Internal error: Forget should always generate MethodCall::property ' +
|
||||||
'as a MemberExpression of MethodCall::receiver',
|
'as a MemberExpression of MethodCall::receiver',
|
||||||
description: null,
|
description: null,
|
||||||
loc: memberExpr.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: memberExpr.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -1878,7 +2059,14 @@ function codegenInstructionValue(
|
||||||
const method = cx.objectMethods.get(property.place.identifier.id);
|
const method = cx.objectMethods.get(property.place.identifier.id);
|
||||||
CompilerError.invariant(method, {
|
CompilerError.invariant(method, {
|
||||||
reason: 'Expected ObjectMethod instruction',
|
reason: 'Expected ObjectMethod instruction',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const loweredFunc = method.loweredFunc;
|
const loweredFunc = method.loweredFunc;
|
||||||
|
|
@ -1949,7 +2137,13 @@ function codegenInstructionValue(
|
||||||
CompilerError.invariant(tagValue.type === 'StringLiteral', {
|
CompilerError.invariant(tagValue.type === 'StringLiteral', {
|
||||||
reason: `Expected JSX tag to be an identifier or string, got \`${tagValue.type}\``,
|
reason: `Expected JSX tag to be an identifier or string, got \`${tagValue.type}\``,
|
||||||
description: null,
|
description: null,
|
||||||
loc: tagValue.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: tagValue.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (tagValue.value.indexOf(':') >= 0) {
|
if (tagValue.value.indexOf(':') >= 0) {
|
||||||
|
|
@ -1969,7 +2163,13 @@ function codegenInstructionValue(
|
||||||
SINGLE_CHILD_FBT_TAGS.has(tagValue.value)
|
SINGLE_CHILD_FBT_TAGS.has(tagValue.value)
|
||||||
) {
|
) {
|
||||||
CompilerError.invariant(instrValue.children != null, {
|
CompilerError.invariant(instrValue.children != null, {
|
||||||
loc: instrValue.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instrValue.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
reason: 'Expected fbt element to have children',
|
reason: 'Expected fbt element to have children',
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
description: null,
|
description: null,
|
||||||
|
|
@ -2271,7 +2471,13 @@ function codegenInstructionValue(
|
||||||
{
|
{
|
||||||
reason: `Unexpected StoreLocal in codegenInstructionValue`,
|
reason: `Unexpected StoreLocal in codegenInstructionValue`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: instrValue.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instrValue.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -2301,7 +2507,13 @@ function codegenInstructionValue(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Unexpected ${instrValue.kind} in codegenInstructionValue`,
|
reason: `Unexpected ${instrValue.kind} in codegenInstructionValue`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: instrValue.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instrValue.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -2447,7 +2659,13 @@ function convertMemberExpressionToJsx(
|
||||||
CompilerError.invariant(expr.property.type === 'Identifier', {
|
CompilerError.invariant(expr.property.type === 'Identifier', {
|
||||||
reason: 'Expected JSX member expression property to be a string',
|
reason: 'Expected JSX member expression property to be a string',
|
||||||
description: null,
|
description: null,
|
||||||
loc: expr.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: expr.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const property = t.jsxIdentifier(expr.property.name);
|
const property = t.jsxIdentifier(expr.property.name);
|
||||||
|
|
@ -2458,7 +2676,13 @@ function convertMemberExpressionToJsx(
|
||||||
reason:
|
reason:
|
||||||
'Expected JSX member expression to be an identifier or nested member expression',
|
'Expected JSX member expression to be an identifier or nested member expression',
|
||||||
description: null,
|
description: null,
|
||||||
loc: expr.object.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: expr.object.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const object = convertMemberExpressionToJsx(expr.object);
|
const object = convertMemberExpressionToJsx(expr.object);
|
||||||
|
|
@ -2482,7 +2706,13 @@ function codegenObjectPropertyKey(
|
||||||
CompilerError.invariant(t.isExpression(expr), {
|
CompilerError.invariant(t.isExpression(expr), {
|
||||||
reason: 'Expected object property key to be an expression',
|
reason: 'Expected object property key to be an expression',
|
||||||
description: null,
|
description: null,
|
||||||
loc: key.name.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: key.name.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return expr;
|
return expr;
|
||||||
|
|
@ -2629,7 +2859,13 @@ function codegenPlace(cx: Context, place: Place): t.Expression | t.JSXText {
|
||||||
description: `Value for '${printPlace(
|
description: `Value for '${printPlace(
|
||||||
place,
|
place,
|
||||||
)}' was not set in the codegen context`,
|
)}' was not set in the codegen context`,
|
||||||
loc: place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
const identifier = convertIdentifier(place.identifier);
|
const identifier = convertIdentifier(place.identifier);
|
||||||
|
|
@ -2642,7 +2878,13 @@ function convertIdentifier(identifier: Identifier): t.Identifier {
|
||||||
identifier.name !== null && identifier.name.kind === 'named',
|
identifier.name !== null && identifier.name.kind === 'named',
|
||||||
{
|
{
|
||||||
reason: `Expected temporaries to be promoted to named identifiers in an earlier pass`,
|
reason: `Expected temporaries to be promoted to named identifiers in an earlier pass`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
description: `identifier ${identifier.id} is unnamed`,
|
description: `identifier ${identifier.id} is unnamed`,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
|
|
@ -2658,7 +2900,14 @@ function compareScopeDependency(
|
||||||
a.identifier.name?.kind === 'named' && b.identifier.name?.kind === 'named',
|
a.identifier.name?.kind === 'named' && b.identifier.name?.kind === 'named',
|
||||||
{
|
{
|
||||||
reason: '[Codegen] Expected named identifier for dependency',
|
reason: '[Codegen] Expected named identifier for dependency',
|
||||||
loc: a.identifier.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: a.identifier.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const aName = [
|
const aName = [
|
||||||
|
|
@ -2682,7 +2931,14 @@ function compareScopeDeclaration(
|
||||||
a.identifier.name?.kind === 'named' && b.identifier.name?.kind === 'named',
|
a.identifier.name?.kind === 'named' && b.identifier.name?.kind === 'named',
|
||||||
{
|
{
|
||||||
reason: '[Codegen] Expected named identifier for declaration',
|
reason: '[Codegen] Expected named identifier for declaration',
|
||||||
loc: a.identifier.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: a.identifier.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const aName = a.identifier.name.value;
|
const aName = a.identifier.name.value;
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,13 @@ export function flattenScopesWithHooksOrUseHIR(fn: HIRFunction): void {
|
||||||
CompilerError.invariant(terminal.kind === 'scope', {
|
CompilerError.invariant(terminal.kind === 'scope', {
|
||||||
reason: `Expected block to have a scope terminal`,
|
reason: `Expected block to have a scope terminal`,
|
||||||
description: `Expected block bb${block.id} to end in a scope terminal`,
|
description: `Expected block bb${block.id} to end in a scope terminal`,
|
||||||
loc: terminal.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const body = fn.body.blocks.get(terminal.block)!;
|
const body = fn.body.blocks.get(terminal.block)!;
|
||||||
if (
|
if (
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,13 @@ export function inferReactiveScopeVariables(fn: HIRFunction): void {
|
||||||
});
|
});
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Invalid mutable range for scope`,
|
reason: `Invalid mutable range for scope`,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
description: `Scope @${scope.id} has range [${scope.range.start}:${
|
description: `Scope @${scope.id} has range [${scope.range.start}:${
|
||||||
scope.range.end
|
scope.range.end
|
||||||
}] but the valid range is [1:${maxInstruction + 1}]`,
|
}] but the valid range is [1:${maxInstruction + 1}]`,
|
||||||
|
|
|
||||||
|
|
@ -159,11 +159,17 @@ class Transform extends ReactiveFunctionTransform<ReactiveScopeDependencies | nu
|
||||||
const merged: Array<MergedScope> = [];
|
const merged: Array<MergedScope> = [];
|
||||||
function reset(): void {
|
function reset(): void {
|
||||||
CompilerError.invariant(current !== null, {
|
CompilerError.invariant(current !== null, {
|
||||||
loc: null,
|
|
||||||
reason:
|
reason:
|
||||||
'MergeConsecutiveScopes: expected current scope to be non-null if reset()',
|
'MergeConsecutiveScopes: expected current scope to be non-null if reset()',
|
||||||
suggestions: null,
|
|
||||||
description: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (current.to > current.from + 1) {
|
if (current.to > current.from + 1) {
|
||||||
merged.push(current);
|
merged.push(current);
|
||||||
|
|
@ -375,10 +381,16 @@ class Transform extends ReactiveFunctionTransform<ReactiveScopeDependencies | nu
|
||||||
}
|
}
|
||||||
const mergedScope = block[entry.from]!;
|
const mergedScope = block[entry.from]!;
|
||||||
CompilerError.invariant(mergedScope.kind === 'scope', {
|
CompilerError.invariant(mergedScope.kind === 'scope', {
|
||||||
loc: null,
|
|
||||||
reason:
|
reason:
|
||||||
'MergeConsecutiveScopes: Expected scope starting index to be a scope',
|
'MergeConsecutiveScopes: Expected scope starting index to be a scope',
|
||||||
description: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
nextInstructions.push(mergedScope);
|
nextInstructions.push(mergedScope);
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,13 @@ function writeTerminal(writer: Writer, terminal: ReactiveTerminal): void {
|
||||||
CompilerError.invariant(block != null, {
|
CompilerError.invariant(block != null, {
|
||||||
reason: 'Expected case to have a block',
|
reason: 'Expected case to have a block',
|
||||||
description: null,
|
description: null,
|
||||||
loc: case_.test?.loc ?? null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: case_.test?.loc ?? null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
writeReactiveInstructions(writer, block);
|
writeReactiveInstructions(writer, block);
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,14 @@ class PromoteInterposedTemporaries extends ReactiveFunctionVisitor<InterState> {
|
||||||
CompilerError.invariant(lval.identifier.name != null, {
|
CompilerError.invariant(lval.identifier.name != null, {
|
||||||
reason:
|
reason:
|
||||||
'PromoteInterposedTemporaries: Assignment targets not expected to be temporaries',
|
'PromoteInterposedTemporaries: Assignment targets not expected to be temporaries',
|
||||||
loc: instruction.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instruction.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -454,7 +461,13 @@ function promoteIdentifier(identifier: Identifier, state: State): void {
|
||||||
reason:
|
reason:
|
||||||
'promoteTemporary: Expected to be called only for temporary variables',
|
'promoteTemporary: Expected to be called only for temporary variables',
|
||||||
description: null,
|
description: null,
|
||||||
loc: GeneratedSource,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (state.tags.has(identifier.declarationId)) {
|
if (state.tags.has(identifier.declarationId)) {
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,14 @@ class Visitor extends ReactiveFunctionTransform<VisitorState> {
|
||||||
if (maybeHoistedFn != null) {
|
if (maybeHoistedFn != null) {
|
||||||
CompilerError.invariant(maybeHoistedFn.kind === 'func', {
|
CompilerError.invariant(maybeHoistedFn.kind === 'func', {
|
||||||
reason: '[PruneHoistedContexts] Unexpected hoisted function',
|
reason: '[PruneHoistedContexts] Unexpected hoisted function',
|
||||||
loc: instruction.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instruction.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
maybeHoistedFn.definition = instruction.value.lvalue.place;
|
maybeHoistedFn.definition = instruction.value.lvalue.place;
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,14 @@ class Visitor extends ReactiveFunctionVisitor<CreateUpdate> {
|
||||||
): void {
|
): void {
|
||||||
CompilerError.invariant(state !== 'Create', {
|
CompilerError.invariant(state !== 'Create', {
|
||||||
reason: "Visiting a terminal statement with state 'Create'",
|
reason: "Visiting a terminal statement with state 'Create'",
|
||||||
loc: stmt.terminal.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: stmt.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
super.visitTerminal(stmt, state);
|
super.visitTerminal(stmt, state);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,13 @@ class State {
|
||||||
CompilerError.invariant(identifierNode !== undefined, {
|
CompilerError.invariant(identifierNode !== undefined, {
|
||||||
reason: 'Expected identifier to be initialized',
|
reason: 'Expected identifier to be initialized',
|
||||||
description: `[${id}] operand=${printPlace(place)} for identifier declaration ${identifier}`,
|
description: `[${id}] operand=${printPlace(place)} for identifier declaration ${identifier}`,
|
||||||
loc: place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
identifierNode.scopes.add(scope.id);
|
identifierNode.scopes.add(scope.id);
|
||||||
|
|
@ -286,7 +292,13 @@ function computeMemoizedIdentifiers(state: State): Set<DeclarationId> {
|
||||||
CompilerError.invariant(node !== undefined, {
|
CompilerError.invariant(node !== undefined, {
|
||||||
reason: `Expected a node for all identifiers, none found for \`${id}\``,
|
reason: `Expected a node for all identifiers, none found for \`${id}\``,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (node.seen) {
|
if (node.seen) {
|
||||||
|
|
@ -328,7 +340,13 @@ function computeMemoizedIdentifiers(state: State): Set<DeclarationId> {
|
||||||
CompilerError.invariant(node !== undefined, {
|
CompilerError.invariant(node !== undefined, {
|
||||||
reason: 'Expected a node for all scopes',
|
reason: 'Expected a node for all scopes',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
if (node.seen) {
|
if (node.seen) {
|
||||||
|
|
@ -977,7 +995,13 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor<
|
||||||
CompilerError.invariant(identifierNode !== undefined, {
|
CompilerError.invariant(identifierNode !== undefined, {
|
||||||
reason: 'Expected identifier to be initialized',
|
reason: 'Expected identifier to be initialized',
|
||||||
description: null,
|
description: null,
|
||||||
loc: stmt.terminal.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: stmt.terminal.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
for (const scope of scopes) {
|
for (const scope of scopes) {
|
||||||
|
|
@ -1002,7 +1026,13 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor<
|
||||||
CompilerError.invariant(identifierNode !== undefined, {
|
CompilerError.invariant(identifierNode !== undefined, {
|
||||||
reason: 'Expected identifier to be initialized',
|
reason: 'Expected identifier to be initialized',
|
||||||
description: null,
|
description: null,
|
||||||
loc: reassignment.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: reassignment.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
for (const scope of scopes) {
|
for (const scope of scopes) {
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,13 @@ class Scopes {
|
||||||
CompilerError.invariant(last === next, {
|
CompilerError.invariant(last === next, {
|
||||||
reason: 'Mismatch push/pop calls',
|
reason: 'Mismatch push/pop calls',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,13 @@ export function eliminateRedundantPhi(
|
||||||
CompilerError.invariant(same !== null, {
|
CompilerError.invariant(same !== null, {
|
||||||
reason: 'Expected phis to be non-empty',
|
reason: 'Expected phis to be non-empty',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
rewrites.set(phi.place.identifier, same);
|
rewrites.set(phi.place.identifier, same);
|
||||||
|
|
@ -149,12 +155,26 @@ export function eliminateRedundantPhi(
|
||||||
for (const phi of block.phis) {
|
for (const phi of block.phis) {
|
||||||
CompilerError.invariant(!rewrites.has(phi.place.identifier), {
|
CompilerError.invariant(!rewrites.has(phi.place.identifier), {
|
||||||
reason: '[EliminateRedundantPhis]: rewrite not complete',
|
reason: '[EliminateRedundantPhis]: rewrite not complete',
|
||||||
loc: phi.place.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: phi.place.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
for (const [, operand] of phi.operands) {
|
for (const [, operand] of phi.operands) {
|
||||||
CompilerError.invariant(!rewrites.has(operand.identifier), {
|
CompilerError.invariant(!rewrites.has(operand.identifier), {
|
||||||
reason: '[EliminateRedundantPhis]: rewrite not complete',
|
reason: '[EliminateRedundantPhis]: rewrite not complete',
|
||||||
loc: phi.place.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: phi.place.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,13 @@ class SSABuilder {
|
||||||
CompilerError.invariant(this.#current !== null, {
|
CompilerError.invariant(this.#current !== null, {
|
||||||
reason: 'we need to be in a block to access state!',
|
reason: 'we need to be in a block to access state!',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
return this.#states.get(this.#current)!;
|
return this.#states.get(this.#current)!;
|
||||||
|
|
@ -253,7 +259,13 @@ function enterSSAImpl(
|
||||||
CompilerError.invariant(!visitedBlocks.has(block), {
|
CompilerError.invariant(!visitedBlocks.has(block), {
|
||||||
reason: `found a cycle! visiting bb${block.id} again`,
|
reason: `found a cycle! visiting bb${block.id} again`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -266,7 +278,13 @@ function enterSSAImpl(
|
||||||
CompilerError.invariant(func.context.length === 0, {
|
CompilerError.invariant(func.context.length === 0, {
|
||||||
reason: `Expected function context to be empty for outer function declarations`,
|
reason: `Expected function context to be empty for outer function declarations`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: func.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: func.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
func.params = func.params.map(param => {
|
func.params = func.params.map(param => {
|
||||||
|
|
@ -295,7 +313,13 @@ function enterSSAImpl(
|
||||||
reason:
|
reason:
|
||||||
'Expected function expression entry block to have zero predecessors',
|
'Expected function expression entry block to have zero predecessors',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
entry.preds.add(blockId);
|
entry.preds.add(blockId);
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,13 @@ export function rewriteInstructionKindsBasedOnReassignment(
|
||||||
{
|
{
|
||||||
reason: `Expected variable not to be defined prior to declaration`,
|
reason: `Expected variable not to be defined prior to declaration`,
|
||||||
description: `${printPlace(lvalue.place)} was already defined`,
|
description: `${printPlace(lvalue.place)} was already defined`,
|
||||||
loc: lvalue.place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: lvalue.place.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
declarations.set(lvalue.place.identifier.declarationId, lvalue);
|
declarations.set(lvalue.place.identifier.declarationId, lvalue);
|
||||||
|
|
@ -77,7 +83,13 @@ export function rewriteInstructionKindsBasedOnReassignment(
|
||||||
{
|
{
|
||||||
reason: `Expected variable not to be defined prior to declaration`,
|
reason: `Expected variable not to be defined prior to declaration`,
|
||||||
description: `${printPlace(lvalue.place)} was already defined`,
|
description: `${printPlace(lvalue.place)} was already defined`,
|
||||||
loc: lvalue.place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: lvalue.place.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
declarations.set(lvalue.place.identifier.declarationId, lvalue);
|
declarations.set(lvalue.place.identifier.declarationId, lvalue);
|
||||||
|
|
@ -101,7 +113,13 @@ export function rewriteInstructionKindsBasedOnReassignment(
|
||||||
description: `other places were \`${kind}\` but '${printPlace(
|
description: `other places were \`${kind}\` but '${printPlace(
|
||||||
place,
|
place,
|
||||||
)}' is const`,
|
)}' is const`,
|
||||||
loc: place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: 'Expected consistent kind for destructuring',
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -114,7 +132,13 @@ export function rewriteInstructionKindsBasedOnReassignment(
|
||||||
CompilerError.invariant(block.kind !== 'value', {
|
CompilerError.invariant(block.kind !== 'value', {
|
||||||
reason: `TODO: Handle reassignment in a value block where the original declaration was removed by dead code elimination (DCE)`,
|
reason: `TODO: Handle reassignment in a value block where the original declaration was removed by dead code elimination (DCE)`,
|
||||||
description: null,
|
description: null,
|
||||||
loc: place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
declarations.set(place.identifier.declarationId, lvalue);
|
declarations.set(place.identifier.declarationId, lvalue);
|
||||||
|
|
@ -125,7 +149,13 @@ export function rewriteInstructionKindsBasedOnReassignment(
|
||||||
description: `Other places were \`${kind}\` but '${printPlace(
|
description: `Other places were \`${kind}\` but '${printPlace(
|
||||||
place,
|
place,
|
||||||
)}' is const`,
|
)}' is const`,
|
||||||
loc: place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: 'Expected consistent kind for destructuring',
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -138,7 +168,13 @@ export function rewriteInstructionKindsBasedOnReassignment(
|
||||||
description: `Other places were \`${kind}\` but '${printPlace(
|
description: `Other places were \`${kind}\` but '${printPlace(
|
||||||
place,
|
place,
|
||||||
)}' is reassigned`,
|
)}' is reassigned`,
|
||||||
loc: place.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: 'Expected consistent kind for destructuring',
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -150,7 +186,13 @@ export function rewriteInstructionKindsBasedOnReassignment(
|
||||||
CompilerError.invariant(kind !== null, {
|
CompilerError.invariant(kind !== null, {
|
||||||
reason: 'Expected at least one operand',
|
reason: 'Expected at least one operand',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
lvalue.kind = kind;
|
lvalue.kind = kind;
|
||||||
|
|
@ -163,7 +205,13 @@ export function rewriteInstructionKindsBasedOnReassignment(
|
||||||
CompilerError.invariant(declaration !== undefined, {
|
CompilerError.invariant(declaration !== undefined, {
|
||||||
reason: `Expected variable to have been defined`,
|
reason: `Expected variable to have been defined`,
|
||||||
description: `No declaration for ${printPlace(lvalue)}`,
|
description: `No declaration for ${printPlace(lvalue)}`,
|
||||||
loc: lvalue.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: lvalue.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
declaration.kind = InstructionKind.Let;
|
declaration.kind = InstructionKind.Let;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -616,7 +616,13 @@ class Unifier {
|
||||||
CompilerError.invariant(type.operands.length > 0, {
|
CompilerError.invariant(type.operands.length > 0, {
|
||||||
reason: 'there should be at least one operand',
|
reason: 'there should be at least one operand',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,13 @@ export default class DisjointSet<T> {
|
||||||
CompilerError.invariant(first != null, {
|
CompilerError.invariant(first != null, {
|
||||||
reason: 'Expected set to be non-empty',
|
reason: 'Expected set to be non-empty',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,13 @@ function parseConfigPragmaEnvironmentForTest(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Internal error, could not parse config from pragma string',
|
reason: 'Internal error, could not parse config from pragma string',
|
||||||
description: `${fromZodError(config.error)}`,
|
description: `${fromZodError(config.error)}`,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -248,7 +254,13 @@ function parseConfigStringAsJS(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Failed to parse config pragma as JavaScript object',
|
reason: 'Failed to parse config pragma as JavaScript object',
|
||||||
description: `Could not parse: ${configString}. Error: ${error}`,
|
description: `Could not parse: ${configString}. Error: ${error}`,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -279,7 +291,13 @@ function parseConfigStringAsJS(
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: 'Invalid environment configuration in config pragma',
|
reason: 'Invalid environment configuration in config pragma',
|
||||||
description: `${fromZodError(validatedEnvironment.error)}`,
|
description: `${fromZodError(validatedEnvironment.error)}`,
|
||||||
loc: null,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,12 +106,19 @@ function visit(
|
||||||
}
|
}
|
||||||
|
|
||||||
CompilerError.invariant(false, {
|
CompilerError.invariant(false, {
|
||||||
reason: `Expected all references to a variable to be consistently local or context references`,
|
reason:
|
||||||
loc: place.loc,
|
'Expected all references to a variable to be consistently local or context references',
|
||||||
description: `Identifier ${printPlace(
|
description: `Identifier ${printPlace(
|
||||||
place,
|
place,
|
||||||
)} is referenced as a ${kind} variable, but was previously referenced as a ${prev} variable`,
|
)} is referenced as a ${kind} variable, but was previously referenced as a ${prev.kind} variable`,
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: place.loc,
|
||||||
|
message: `this is ${prev.kind}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ export function validateLocalsNotReassignedAfterRender(fn: HIRFunction): void {
|
||||||
category: ErrorCategory.Immutability,
|
category: ErrorCategory.Immutability,
|
||||||
reason: 'Cannot reassign variable after render completes',
|
reason: 'Cannot reassign variable after render completes',
|
||||||
description: `Reassigning ${variable} after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead.`,
|
description: `Reassigning ${variable} after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead.`,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: reassignment.loc,
|
loc: reassignment.loc,
|
||||||
message: `Cannot reassign ${variable} after render completes`,
|
message: `Cannot reassign ${variable} after render completes`,
|
||||||
|
|
@ -96,7 +96,7 @@ function getContextReassignment(
|
||||||
reason: 'Cannot reassign variable in async function',
|
reason: 'Cannot reassign variable in async function',
|
||||||
description:
|
description:
|
||||||
'Reassigning a variable in an async function can cause inconsistent behavior on subsequent renders. Consider using state instead',
|
'Reassigning a variable in an async function can cause inconsistent behavior on subsequent renders. Consider using state instead',
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: reassignment.loc,
|
loc: reassignment.loc,
|
||||||
message: `Cannot reassign ${variable}`,
|
message: `Cannot reassign ${variable}`,
|
||||||
|
|
@ -191,7 +191,14 @@ function getContextReassignment(
|
||||||
for (const operand of operands) {
|
for (const operand of operands) {
|
||||||
CompilerError.invariant(operand.effect !== Effect.Unknown, {
|
CompilerError.invariant(operand.effect !== Effect.Unknown, {
|
||||||
reason: `Expected effects to be inferred prior to ValidateLocalsNotReassignedAfterRender`,
|
reason: `Expected effects to be inferred prior to ValidateLocalsNotReassignedAfterRender`,
|
||||||
loc: operand.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: operand.loc,
|
||||||
|
message: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const reassignment = reassigningFunctions.get(
|
const reassignment = reassigningFunctions.get(
|
||||||
operand.identifier.id,
|
operand.identifier.id,
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,14 @@ export function validateNoDerivedComputationsInEffects(fn: HIRFunction): void {
|
||||||
const dependencies: Array<IdentifierId> = deps.elements.map(dep => {
|
const dependencies: Array<IdentifierId> = deps.elements.map(dep => {
|
||||||
CompilerError.invariant(dep.kind === 'Identifier', {
|
CompilerError.invariant(dep.kind === 'Identifier', {
|
||||||
reason: `Dependency is checked as a place above`,
|
reason: `Dependency is checked as a place above`,
|
||||||
loc: value.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: value.loc,
|
||||||
|
message: 'this is checked as a place above',
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
return locals.get(dep.identifier.id) ?? dep.identifier.id;
|
return locals.get(dep.identifier.id) ?? dep.identifier.id;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,12 @@ export function validateNoFreezingKnownMutableFunctions(
|
||||||
reason: 'Cannot modify local variables after render completes',
|
reason: 'Cannot modify local variables after render completes',
|
||||||
description: `This argument is a function which may reassign or mutate ${variable} after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead.`,
|
description: `This argument is a function which may reassign or mutate ${variable} after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead.`,
|
||||||
})
|
})
|
||||||
.withDetail({
|
.withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: operand.loc,
|
loc: operand.loc,
|
||||||
message: `This function may (indirectly) reassign or modify ${variable} after render`,
|
message: `This function may (indirectly) reassign or modify ${variable} after render`,
|
||||||
})
|
})
|
||||||
.withDetail({
|
.withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: effect.value.loc,
|
loc: effect.value.loc,
|
||||||
message: `This modifies ${variable}`,
|
message: `This modifies ${variable}`,
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ export function validateNoImpureFunctionsInRender(
|
||||||
: '') +
|
: '') +
|
||||||
'Calling an impure function can produce unstable results that update unpredictably when the component happens to re-render. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)',
|
'Calling an impure function can produce unstable results that update unpredictably when the component happens to re-render. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)',
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: callee.loc,
|
loc: callee.loc,
|
||||||
message: 'Cannot call impure function',
|
message: 'Cannot call impure function',
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ export function validateNoJSXInTryStatement(
|
||||||
category: ErrorCategory.ErrorBoundaries,
|
category: ErrorCategory.ErrorBoundaries,
|
||||||
reason: 'Avoid constructing JSX within try/catch',
|
reason: 'Avoid constructing JSX within try/catch',
|
||||||
description: `React does not immediately render components when JSX is rendered, so any errors from this component will not be caught by the try/catch. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)`,
|
description: `React does not immediately render components when JSX is rendered, so any errors from this component will not be caught by the try/catch. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)`,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: value.loc,
|
loc: value.loc,
|
||||||
message: 'Avoid constructing JSX within try/catch',
|
message: 'Avoid constructing JSX within try/catch',
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,14 @@ function makeRefId(id: number): RefId {
|
||||||
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
CompilerError.invariant(id >= 0 && Number.isInteger(id), {
|
||||||
reason: 'Expected identifier id to be a non-negative integer',
|
reason: 'Expected identifier id to be a non-negative integer',
|
||||||
description: null,
|
description: null,
|
||||||
loc: null,
|
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
return id as RefId;
|
return id as RefId;
|
||||||
}
|
}
|
||||||
|
|
@ -191,19 +197,40 @@ function tyEqual(a: RefAccessType, b: RefAccessType): boolean {
|
||||||
case 'Guard':
|
case 'Guard':
|
||||||
CompilerError.invariant(b.kind === 'Guard', {
|
CompilerError.invariant(b.kind === 'Guard', {
|
||||||
reason: 'Expected ref value',
|
reason: 'Expected ref value',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
return a.refId === b.refId;
|
return a.refId === b.refId;
|
||||||
case 'RefValue':
|
case 'RefValue':
|
||||||
CompilerError.invariant(b.kind === 'RefValue', {
|
CompilerError.invariant(b.kind === 'RefValue', {
|
||||||
reason: 'Expected ref value',
|
reason: 'Expected ref value',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
return a.loc == b.loc;
|
return a.loc == b.loc;
|
||||||
case 'Structure': {
|
case 'Structure': {
|
||||||
CompilerError.invariant(b.kind === 'Structure', {
|
CompilerError.invariant(b.kind === 'Structure', {
|
||||||
reason: 'Expected structure',
|
reason: 'Expected structure',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const fnTypesEqual =
|
const fnTypesEqual =
|
||||||
(a.fn === null && b.fn === null) ||
|
(a.fn === null && b.fn === null) ||
|
||||||
|
|
@ -242,7 +269,14 @@ function joinRefAccessTypes(...types: Array<RefAccessType>): RefAccessType {
|
||||||
a.kind === 'Structure' && b.kind === 'Structure',
|
a.kind === 'Structure' && b.kind === 'Structure',
|
||||||
{
|
{
|
||||||
reason: 'Expected structure',
|
reason: 'Expected structure',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const fn =
|
const fn =
|
||||||
|
|
@ -471,7 +505,7 @@ function validateNoRefAccessInRenderImpl(
|
||||||
category: ErrorCategory.Refs,
|
category: ErrorCategory.Refs,
|
||||||
reason: 'Cannot access refs during render',
|
reason: 'Cannot access refs during render',
|
||||||
description: ERROR_DESCRIPTION,
|
description: ERROR_DESCRIPTION,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: callee.loc,
|
loc: callee.loc,
|
||||||
message: `This function accesses a ref value`,
|
message: `This function accesses a ref value`,
|
||||||
|
|
@ -708,7 +742,14 @@ function validateNoRefAccessInRenderImpl(
|
||||||
|
|
||||||
CompilerError.invariant(!env.hasChanged(), {
|
CompilerError.invariant(!env.hasChanged(), {
|
||||||
reason: 'Ref type environment did not converge',
|
reason: 'Ref type environment did not converge',
|
||||||
loc: null,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: null,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
return Ok(
|
return Ok(
|
||||||
|
|
@ -734,7 +775,7 @@ function guardCheck(errors: CompilerError, operand: Place, env: Env): void {
|
||||||
category: ErrorCategory.Refs,
|
category: ErrorCategory.Refs,
|
||||||
reason: 'Cannot access refs during render',
|
reason: 'Cannot access refs during render',
|
||||||
description: ERROR_DESCRIPTION,
|
description: ERROR_DESCRIPTION,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: operand.loc,
|
loc: operand.loc,
|
||||||
message: `Cannot access ref value during render`,
|
message: `Cannot access ref value during render`,
|
||||||
|
|
@ -758,7 +799,7 @@ function validateNoRefValueAccess(
|
||||||
category: ErrorCategory.Refs,
|
category: ErrorCategory.Refs,
|
||||||
reason: 'Cannot access refs during render',
|
reason: 'Cannot access refs during render',
|
||||||
description: ERROR_DESCRIPTION,
|
description: ERROR_DESCRIPTION,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: (type.kind === 'RefValue' && type.loc) || operand.loc,
|
loc: (type.kind === 'RefValue' && type.loc) || operand.loc,
|
||||||
message: `Cannot access ref value during render`,
|
message: `Cannot access ref value during render`,
|
||||||
|
|
@ -784,7 +825,7 @@ function validateNoRefPassedToFunction(
|
||||||
category: ErrorCategory.Refs,
|
category: ErrorCategory.Refs,
|
||||||
reason: 'Cannot access refs during render',
|
reason: 'Cannot access refs during render',
|
||||||
description: ERROR_DESCRIPTION,
|
description: ERROR_DESCRIPTION,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: (type.kind === 'RefValue' && type.loc) || loc,
|
loc: (type.kind === 'RefValue' && type.loc) || loc,
|
||||||
message: `Passing a ref to a function may read its value during render`,
|
message: `Passing a ref to a function may read its value during render`,
|
||||||
|
|
@ -806,7 +847,7 @@ function validateNoRefUpdate(
|
||||||
category: ErrorCategory.Refs,
|
category: ErrorCategory.Refs,
|
||||||
reason: 'Cannot access refs during render',
|
reason: 'Cannot access refs during render',
|
||||||
description: ERROR_DESCRIPTION,
|
description: ERROR_DESCRIPTION,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: (type.kind === 'RefValue' && type.loc) || loc,
|
loc: (type.kind === 'RefValue' && type.loc) || loc,
|
||||||
message: `Cannot update ref during render`,
|
message: `Cannot update ref during render`,
|
||||||
|
|
@ -827,7 +868,7 @@ function validateNoDirectRefValueAccess(
|
||||||
category: ErrorCategory.Refs,
|
category: ErrorCategory.Refs,
|
||||||
reason: 'Cannot access refs during render',
|
reason: 'Cannot access refs during render',
|
||||||
description: ERROR_DESCRIPTION,
|
description: ERROR_DESCRIPTION,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: type.loc ?? operand.loc,
|
loc: type.loc ?? operand.loc,
|
||||||
message: `Cannot access ref value during render`,
|
message: `Cannot access ref value during render`,
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ export function validateNoSetStateInEffects(
|
||||||
'Calling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. ' +
|
'Calling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. ' +
|
||||||
'(https://react.dev/learn/you-might-not-need-an-effect)',
|
'(https://react.dev/learn/you-might-not-need-an-effect)',
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: setState.loc,
|
loc: setState.loc,
|
||||||
message:
|
message:
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,14 @@ function validateNoSetStateInRenderImpl(
|
||||||
case 'StartMemoize': {
|
case 'StartMemoize': {
|
||||||
CompilerError.invariant(activeManualMemoId === null, {
|
CompilerError.invariant(activeManualMemoId === null, {
|
||||||
reason: 'Unexpected nested StartMemoize instructions',
|
reason: 'Unexpected nested StartMemoize instructions',
|
||||||
loc: instr.value.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
activeManualMemoId = instr.value.manualMemoId;
|
activeManualMemoId = instr.value.manualMemoId;
|
||||||
break;
|
break;
|
||||||
|
|
@ -113,7 +120,14 @@ function validateNoSetStateInRenderImpl(
|
||||||
{
|
{
|
||||||
reason:
|
reason:
|
||||||
'Expected FinishMemoize to align with previous StartMemoize instruction',
|
'Expected FinishMemoize to align with previous StartMemoize instruction',
|
||||||
loc: instr.value.loc,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: instr.value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
activeManualMemoId = null;
|
activeManualMemoId = null;
|
||||||
|
|
@ -134,7 +148,7 @@ function validateNoSetStateInRenderImpl(
|
||||||
description:
|
description:
|
||||||
'Each time the memo callback is evaluated it will change state. This can cause a memoization dependency to change, running the memo function again and causing an infinite loop. Instead of setting state in useMemo(), prefer deriving the value during render. (https://react.dev/reference/react/useState)',
|
'Each time the memo callback is evaluated it will change state. This can cause a memoization dependency to change, running the memo function again and causing an infinite loop. Instead of setting state in useMemo(), prefer deriving the value during render. (https://react.dev/reference/react/useState)',
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: callee.loc,
|
loc: callee.loc,
|
||||||
message: 'Found setState() within useMemo()',
|
message: 'Found setState() within useMemo()',
|
||||||
|
|
@ -149,7 +163,7 @@ function validateNoSetStateInRenderImpl(
|
||||||
description:
|
description:
|
||||||
'Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)',
|
'Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState)',
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: callee.loc,
|
loc: callee.loc,
|
||||||
message: 'Found setState() in render',
|
message: 'Found setState() in render',
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,14 @@ function validateInferredDep(
|
||||||
CompilerError.invariant(dep.identifier.name?.kind === 'named', {
|
CompilerError.invariant(dep.identifier.name?.kind === 'named', {
|
||||||
reason:
|
reason:
|
||||||
'ValidatePreservedManualMemoization: expected scope dependency to be named',
|
'ValidatePreservedManualMemoization: expected scope dependency to be named',
|
||||||
loc: GeneratedSource,
|
description: null,
|
||||||
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: GeneratedSource,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
normalizedDep = {
|
normalizedDep = {
|
||||||
|
|
@ -303,7 +310,7 @@ function validateInferredDep(
|
||||||
.join('')
|
.join('')
|
||||||
.trim(),
|
.trim(),
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: memoLocation,
|
loc: memoLocation,
|
||||||
message: 'Could not preserve existing manual memoization',
|
message: 'Could not preserve existing manual memoization',
|
||||||
|
|
@ -495,7 +502,13 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
|
||||||
CompilerError.invariant(state.manualMemoState == null, {
|
CompilerError.invariant(state.manualMemoState == null, {
|
||||||
reason: 'Unexpected nested StartMemoize instructions',
|
reason: 'Unexpected nested StartMemoize instructions',
|
||||||
description: `Bad manual memoization ids: ${state.manualMemoState?.manualMemoId}, ${value.manualMemoId}`,
|
description: `Bad manual memoization ids: ${state.manualMemoState?.manualMemoId}, ${value.manualMemoId}`,
|
||||||
loc: value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -540,7 +553,7 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
|
||||||
'React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. ',
|
'React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. ',
|
||||||
'This dependency may be mutated later, which could cause the value to change unexpectedly.',
|
'This dependency may be mutated later, which could cause the value to change unexpectedly.',
|
||||||
].join(''),
|
].join(''),
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc,
|
loc,
|
||||||
message: 'This dependency may be modified later',
|
message: 'This dependency may be modified later',
|
||||||
|
|
@ -556,7 +569,13 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
|
||||||
{
|
{
|
||||||
reason: 'Unexpected mismatch between StartMemoize and FinishMemoize',
|
reason: 'Unexpected mismatch between StartMemoize and FinishMemoize',
|
||||||
description: `Encountered StartMemoize id=${state.manualMemoState?.manualMemoId} followed by FinishMemoize id=${value.manualMemoId}`,
|
description: `Encountered StartMemoize id=${state.manualMemoState?.manualMemoId} followed by FinishMemoize id=${value.manualMemoId}`,
|
||||||
loc: value.loc,
|
details: [
|
||||||
|
{
|
||||||
|
kind: 'error',
|
||||||
|
loc: value.loc,
|
||||||
|
message: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -591,7 +610,7 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
|
||||||
]
|
]
|
||||||
.join('')
|
.join('')
|
||||||
.trim(),
|
.trim(),
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc,
|
loc,
|
||||||
message: 'Could not preserve existing memoization',
|
message: 'Could not preserve existing memoization',
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,12 @@ export function validateStaticComponents(
|
||||||
reason: 'Cannot create components during render',
|
reason: 'Cannot create components during render',
|
||||||
description: `Components created during render will reset their state each time they are created. Declare components outside of render. `,
|
description: `Components created during render will reset their state each time they are created. Declare components outside of render. `,
|
||||||
})
|
})
|
||||||
.withDetail({
|
.withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: value.tag.loc,
|
loc: value.tag.loc,
|
||||||
message: 'This component is created during render',
|
message: 'This component is created during render',
|
||||||
})
|
})
|
||||||
.withDetail({
|
.withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: location,
|
loc: location,
|
||||||
message: 'The component is created during render here',
|
message: 'The component is created during render here',
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ export function validateUseMemo(fn: HIRFunction): Result<void, CompilerError> {
|
||||||
description:
|
description:
|
||||||
'useMemo() callbacks are called by React to cache calculations across re-renders. They should not take parameters. Instead, directly reference the props, state, or local variables needed for the computation.',
|
'useMemo() callbacks are called by React to cache calculations across re-renders. They should not take parameters. Instead, directly reference the props, state, or local variables needed for the computation.',
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc,
|
loc,
|
||||||
message: 'Callbacks with parameters are not supported',
|
message: 'Callbacks with parameters are not supported',
|
||||||
|
|
@ -96,7 +96,7 @@ export function validateUseMemo(fn: HIRFunction): Result<void, CompilerError> {
|
||||||
description:
|
description:
|
||||||
'useMemo() callbacks are called once and must synchronously return a value.',
|
'useMemo() callbacks are called once and must synchronously return a value.',
|
||||||
suggestions: null,
|
suggestions: null,
|
||||||
}).withDetail({
|
}).withDetails({
|
||||||
kind: 'error',
|
kind: 'error',
|
||||||
loc: body.loc,
|
loc: body.loc,
|
||||||
message: 'Async and generator functions are not supported',
|
message: 'Async and generator functions are not supported',
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,13 @@ Found 1 error:
|
||||||
|
|
||||||
Invariant: [InferMutationAliasingEffects] Expected value kind to be initialized
|
Invariant: [InferMutationAliasingEffects] Expected value kind to be initialized
|
||||||
|
|
||||||
<unknown> thunk$14.
|
<unknown> thunk$14
|
||||||
|
|
||||||
error.bug-infer-mutation-aliasing-effects.ts:10:22
|
error.bug-infer-mutation-aliasing-effects.ts:10:22
|
||||||
8 | function thunk(action) {
|
8 | function thunk(action) {
|
||||||
9 | if (typeof action === 'function') {
|
9 | if (typeof action === 'function') {
|
||||||
> 10 | return action(thunk, () => stateRef.current, extraArg);
|
> 10 | return action(thunk, () => stateRef.current, extraArg);
|
||||||
| ^^^^^ [InferMutationAliasingEffects] Expected value kind to be initialized
|
| ^^^^^ this is uninitialized
|
||||||
11 | } else {
|
11 | } else {
|
||||||
12 | dispatch(action);
|
12 | dispatch(action);
|
||||||
13 | return undefined;
|
13 | return undefined;
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,15 @@ const YearsAndMonthsSince = () => {
|
||||||
```
|
```
|
||||||
Found 1 error:
|
Found 1 error:
|
||||||
|
|
||||||
Invariant: [Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression. Got a `Identifier`
|
Invariant: [Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
error.bug-invariant-codegen-methodcall.ts:3:17
|
error.bug-invariant-codegen-methodcall.ts:3:17
|
||||||
1 | const YearsAndMonthsSince = () => {
|
1 | const YearsAndMonthsSince = () => {
|
||||||
2 | const diff = foo();
|
2 | const diff = foo();
|
||||||
> 3 | const months = Math.floor(diff.bar());
|
> 3 | const months = Math.floor(diff.bar());
|
||||||
| ^^^^^^^^^^ [Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression. Got a `Identifier`
|
| ^^^^^^^^^^ Got: 'Identifier'
|
||||||
4 | return <>{months}</>;
|
4 | return <>{months}</>;
|
||||||
5 | };
|
5 | };
|
||||||
6 |
|
6 |
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ Found 1 error:
|
||||||
|
|
||||||
Invariant: Expected consistent kind for destructuring
|
Invariant: Expected consistent kind for destructuring
|
||||||
|
|
||||||
Other places were `Reassign` but 'mutate? #t8$46[7:9]{reactive}' is const.
|
Other places were `Reassign` but 'mutate? #t8$46[7:9]{reactive}' is const
|
||||||
|
|
||||||
error.bug-invariant-expected-consistent-destructuring.ts:9:9
|
error.bug-invariant-expected-consistent-destructuring.ts:9:9
|
||||||
7 |
|
7 |
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,13 @@ Found 1 error:
|
||||||
|
|
||||||
Invariant: Expected all references to a variable to be consistently local or context references
|
Invariant: Expected all references to a variable to be consistently local or context references
|
||||||
|
|
||||||
Identifier <unknown> err$7 is referenced as a context variable, but was previously referenced as a [object Object] variable.
|
Identifier <unknown> err$7 is referenced as a context variable, but was previously referenced as a local variable
|
||||||
|
|
||||||
error.bug-invariant-local-or-context-references.ts:15:13
|
error.bug-invariant-local-or-context-references.ts:15:13
|
||||||
13 | setState(_prevState => ({
|
13 | setState(_prevState => ({
|
||||||
14 | loading: false,
|
14 | loading: false,
|
||||||
> 15 | error: err,
|
> 15 | error: err,
|
||||||
| ^^^ Expected all references to a variable to be consistently local or context references
|
| ^^^ this is local
|
||||||
16 | }));
|
16 | }));
|
||||||
17 | }
|
17 | }
|
||||||
18 | };
|
18 | };
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,13 @@ Found 1 error:
|
||||||
|
|
||||||
Invariant: Unexpected terminal in optional
|
Invariant: Unexpected terminal in optional
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
error.bug-invariant-unexpected-terminal-in-optional.ts:3:16
|
error.bug-invariant-unexpected-terminal-in-optional.ts:3:16
|
||||||
1 | const Foo = ({json}) => {
|
1 | const Foo = ({json}) => {
|
||||||
2 | try {
|
2 | try {
|
||||||
> 3 | const foo = JSON.parse(json)?.foo;
|
> 3 | const foo = JSON.parse(json)?.foo;
|
||||||
| ^^^^ Unexpected terminal in optional
|
| ^^^^ Unexpected maybe-throw in optional
|
||||||
4 | return <span>{foo}</span>;
|
4 | return <span>{foo}</span>;
|
||||||
5 | } catch {
|
5 | } catch {
|
||||||
6 | return null;
|
6 | return null;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ Found 1 error:
|
||||||
|
|
||||||
Invariant: Expected temporaries to be promoted to named identifiers in an earlier pass
|
Invariant: Expected temporaries to be promoted to named identifiers in an earlier pass
|
||||||
|
|
||||||
identifier 15 is unnamed.
|
identifier 15 is unnamed
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -18,11 +18,13 @@ Found 1 error:
|
||||||
|
|
||||||
Invariant: Const declaration cannot be referenced as an expression
|
Invariant: Const declaration cannot be referenced as an expression
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
error.call-args-destructuring-asignment-complex.ts:3:9
|
error.call-args-destructuring-asignment-complex.ts:3:9
|
||||||
1 | function Component(props) {
|
1 | function Component(props) {
|
||||||
2 | let x = makeObject();
|
2 | let x = makeObject();
|
||||||
> 3 | x.foo(([[x]] = makeObject()));
|
> 3 | x.foo(([[x]] = makeObject()));
|
||||||
| ^^^^^ Const declaration cannot be referenced as an expression
|
| ^^^^^ this is Const
|
||||||
4 | return x;
|
4 | return x;
|
||||||
5 | }
|
5 | }
|
||||||
6 |
|
6 |
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,15 @@ export const FIXTURE_ENTRYPOINT = {
|
||||||
```
|
```
|
||||||
Found 1 error:
|
Found 1 error:
|
||||||
|
|
||||||
Invariant: [Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression. Got a `Identifier`
|
Invariant: [Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
error.todo-nested-method-calls-lower-property-load-into-temporary.ts:6:14
|
error.todo-nested-method-calls-lower-property-load-into-temporary.ts:6:14
|
||||||
4 | function Component({}) {
|
4 | function Component({}) {
|
||||||
5 | const items = makeArray(0, 1, 2, null, 4, false, 6);
|
5 | const items = makeArray(0, 1, 2, null, 4, false, 6);
|
||||||
> 6 | const max = Math.max(2, items.push(5), ...other);
|
> 6 | const max = Math.max(2, items.push(5), ...other);
|
||||||
| ^^^^^^^^ [Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression. Got a `Identifier`
|
| ^^^^^^^^ Got: 'Identifier'
|
||||||
7 | return max;
|
7 | return max;
|
||||||
8 | }
|
8 | }
|
||||||
9 |
|
9 |
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,13 @@ Found 1 error:
|
||||||
|
|
||||||
Invariant: [InferMutationAliasingEffects] Expected value kind to be initialized
|
Invariant: [InferMutationAliasingEffects] Expected value kind to be initialized
|
||||||
|
|
||||||
<unknown> hasErrors_0$15:TFunction.
|
<unknown> hasErrors_0$15:TFunction
|
||||||
|
|
||||||
error.todo-repro-named-function-with-shadowed-local-same-name.ts:9:9
|
error.todo-repro-named-function-with-shadowed-local-same-name.ts:9:9
|
||||||
7 | return hasErrors;
|
7 | return hasErrors;
|
||||||
8 | }
|
8 | }
|
||||||
> 9 | return hasErrors();
|
> 9 | return hasErrors();
|
||||||
| ^^^^^^^^^ [InferMutationAliasingEffects] Expected value kind to be initialized
|
| ^^^^^^^^^ this is uninitialized
|
||||||
10 | }
|
10 | }
|
||||||
11 |
|
11 |
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,13 @@ Found 1 error:
|
||||||
|
|
||||||
Invariant: [InferMutationAliasingEffects] Expected value kind to be initialized
|
Invariant: [InferMutationAliasingEffects] Expected value kind to be initialized
|
||||||
|
|
||||||
<unknown> hasErrors_0$15:TFunction.
|
<unknown> hasErrors_0$15:TFunction
|
||||||
|
|
||||||
error.todo-repro-named-function-with-shadowed-local-same-name.ts:10:9
|
error.todo-repro-named-function-with-shadowed-local-same-name.ts:10:9
|
||||||
8 | return hasErrors;
|
8 | return hasErrors;
|
||||||
9 | }
|
9 | }
|
||||||
> 10 | return hasErrors();
|
> 10 | return hasErrors();
|
||||||
| ^^^^^^^^^ [InferMutationAliasingEffects] Expected value kind to be initialized
|
| ^^^^^^^^^ this is uninitialized
|
||||||
11 | }
|
11 | }
|
||||||
12 |
|
12 |
|
||||||
```
|
```
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user