Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[compiler][nocommit] Quick sketch of types on places #31575

Draft
wants to merge 1 commit into
base: gh/josephsavona/60/base
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export function lower(
identifier: builder.resolveBinding(ref),
effect: Effect.Unknown,
reactive: false,
type: makeType(),
loc: ref.loc ?? GeneratedSource,
});
}
Expand Down Expand Up @@ -114,6 +115,7 @@ export function lower(
identifier: binding.identifier,
effect: Effect.Unknown,
reactive: false,
type: makeType(),
loc: param.node.loc ?? GeneratedSource,
};
params.push(place);
Expand All @@ -127,6 +129,7 @@ export function lower(
identifier: builder.makeTemporary(param.node.loc ?? GeneratedSource),
effect: Effect.Unknown,
reactive: false,
type: makeType(),
loc: param.node.loc ?? GeneratedSource,
};
promoteTemporary(place.identifier);
Expand All @@ -145,6 +148,7 @@ export function lower(
identifier: builder.makeTemporary(param.node.loc ?? GeneratedSource),
effect: Effect.Unknown,
reactive: false,
type: makeType(),
loc: param.node.loc ?? GeneratedSource,
};
params.push({
Expand Down Expand Up @@ -463,6 +467,7 @@ function lowerStatement(
identifier: identifier.identifier,
kind: 'Identifier',
reactive: false,
type: makeType(),
loc: id.node.loc ?? GeneratedSource,
};
lowerValueToTemporary(builder, {
Expand Down Expand Up @@ -856,6 +861,7 @@ function lowerStatement(
identifier: binding.identifier,
kind: 'Identifier',
reactive: false,
type: makeType(),
loc: id.node.loc ?? GeneratedSource,
};
if (builder.isContextIdentifier(id)) {
Expand Down Expand Up @@ -1265,6 +1271,7 @@ function lowerStatement(
),
effect: Effect.Unknown,
reactive: false,
type: makeType(),
loc: handlerBindingPath.node.loc ?? GeneratedSource,
};
promoteTemporary(place.identifier);
Expand Down Expand Up @@ -3435,6 +3442,7 @@ function lowerIdentifier(
identifier: binding.identifier,
effect: Effect.Unknown,
reactive: false,
type: makeType(),
loc: exprLoc,
};
return place;
Expand All @@ -3456,6 +3464,7 @@ function buildTemporaryPlace(builder: HIRBuilder, loc: SourceLocation): Place {
identifier: builder.makeTemporary(loc),
effect: Effect.Unknown,
reactive: false,
type: makeType(),
loc,
};
return place;
Expand Down Expand Up @@ -3518,6 +3527,7 @@ function lowerIdentifierForAssignment(
identifier: binding.identifier,
effect: Effect.Unknown,
reactive: false,
type: makeType(),
loc,
};
return place;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
IdentifierId,
InstructionId,
InstructionValue,
makeType,
ReactiveScopeDependency,
ScopeId,
} from './HIR';
Expand Down Expand Up @@ -216,6 +217,7 @@ class PropertyPathRegistry {
optionalProperties: new Map(),
fullPath: {
identifier,
type: makeType(),
path: [],
},
hasOptional: false,
Expand All @@ -239,6 +241,7 @@ class PropertyPathRegistry {
parent: parent,
fullPath: {
identifier: parent.fullPath.identifier,
type: makeType(),
path: parent.fullPath.path.concat(entry),
},
hasOptional: parent.hasOptional || entry.optional,
Expand Down Expand Up @@ -280,6 +283,7 @@ function getMaybeNonNullInInstruction(
if (instr.kind === 'PropertyLoad') {
path = context.temporaries.get(instr.object.identifier.id) ?? {
identifier: instr.object.identifier,
type: makeType(),
path: [],
};
} else if (instr.kind === 'Destructure') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
DependencyPathEntry,
Instruction,
Terminal,
makeType,
} from './HIR';
import {printIdentifier} from './PrintHIR';

Expand Down Expand Up @@ -282,6 +283,7 @@ function traverseOptionalBlock(
);
baseObject = {
identifier: maybeTest.instructions[0].value.place.identifier,
type: maybeTest.instructions[0].value.place.type,
path,
};
test = maybeTest.terminal;
Expand Down Expand Up @@ -383,6 +385,7 @@ function traverseOptionalBlock(
);
const load = {
identifier: baseObject.identifier,
type: makeType(),
path: [
...baseObject.path,
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
DependencyPathEntry,
GeneratedSource,
Identifier,
makeType,
ReactiveScopeDependency,
} from '../HIR';
import {printIdentifier} from '../HIR/PrintHIR';
Expand Down Expand Up @@ -308,7 +309,7 @@ function collectMinimalDependenciesInSubtree(
results: Set<ReactiveScopeDependency>,
): void {
if (isDependency(node.accessType)) {
results.add({identifier: rootIdentifier, path});
results.add({identifier: rootIdentifier, type: makeType(), path});
} else {
for (const [childName, childNode] of node.properties) {
collectMinimalDependenciesInSubtree(
Expand Down
121 changes: 56 additions & 65 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {CompilerError, CompilerErrorDetailOptions} from '../CompilerError';
import {assertExhaustive} from '../Utils/utils';
import {Environment, ReactFunctionType} from './Environment';
import {HookKind} from './ObjectShape';
import {Type, makeType} from './Types';
import {Type} from './Types';
import {z} from 'zod';

/*
Expand Down Expand Up @@ -1108,6 +1108,7 @@ export type Place = {
identifier: Identifier;
effect: Effect;
reactive: boolean;
type: Type;
loc: SourceLocation;
};

Expand Down Expand Up @@ -1211,7 +1212,6 @@ export type Identifier = {
* variables may have the same scope id.
*/
scope: ReactiveScope | null;
type: Type;
loc: SourceLocation;
};

Expand All @@ -1238,7 +1238,6 @@ export function makeTemporaryIdentifier(
declarationId: makeDeclarationId(id),
mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)},
scope: null,
type: makeType(),
loc,
};
}
Expand Down Expand Up @@ -1508,13 +1507,15 @@ export type ReactiveScopeDependencies = Set<ReactiveScopeDependency>;

export type ReactiveScopeDeclaration = {
identifier: Identifier;
type: Type;
scope: ReactiveScope; // the scope in which the variable was originally declared
};

export type DependencyPathEntry = {property: string; optional: boolean};
export type DependencyPath = Array<DependencyPathEntry>;
export type ReactiveScopeDependency = {
identifier: Identifier;
type: Type;
path: DependencyPath;
};

Expand Down Expand Up @@ -1628,110 +1629,92 @@ export function makeInstructionId(id: number): InstructionId {
return id as InstructionId;
}

export function isObjectMethodType(id: Identifier): boolean {
return id.type.kind == 'ObjectMethod';
export function isObjectMethodType(type: Type): boolean {
return type.kind == 'ObjectMethod';
}

export function isObjectType(id: Identifier): boolean {
return id.type.kind === 'Object';
export function isObjectType(type: Type): boolean {
return type.kind === 'Object';
}

export function isPrimitiveType(id: Identifier): boolean {
return id.type.kind === 'Primitive';
export function isPrimitiveType(type: Type): boolean {
return type.kind === 'Primitive';
}

export function isArrayType(id: Identifier): boolean {
return id.type.kind === 'Object' && id.type.shapeId === 'BuiltInArray';
export function isArrayType(type: Type): boolean {
return type.kind === 'Object' && type.shapeId === 'BuiltInArray';
}

export function isRefValueType(id: Identifier): boolean {
return id.type.kind === 'Object' && id.type.shapeId === 'BuiltInRefValue';
export function isRefValueType(type: Type): boolean {
return type.kind === 'Object' && type.shapeId === 'BuiltInRefValue';
}

export function isUseRefType(id: Identifier): boolean {
return id.type.kind === 'Object' && id.type.shapeId === 'BuiltInUseRefId';
export function isUseRefType(type: Type): boolean {
return type.kind === 'Object' && type.shapeId === 'BuiltInUseRefId';
}

export function isUseStateType(id: Identifier): boolean {
return id.type.kind === 'Object' && id.type.shapeId === 'BuiltInUseState';
export function isUseStateType(type: Type): boolean {
return type.kind === 'Object' && type.shapeId === 'BuiltInUseState';
}

export function isRefOrRefValue(id: Identifier): boolean {
return isUseRefType(id) || isRefValueType(id);
export function isRefOrRefValue(type: Type): boolean {
return isUseRefType(type) || isRefValueType(type);
}

export function isSetStateType(id: Identifier): boolean {
return id.type.kind === 'Function' && id.type.shapeId === 'BuiltInSetState';
export function isSetStateType(type: Type): boolean {
return type.kind === 'Function' && type.shapeId === 'BuiltInSetState';
}

export function isUseActionStateType(id: Identifier): boolean {
return (
id.type.kind === 'Object' && id.type.shapeId === 'BuiltInUseActionState'
);
export function isUseActionStateType(type: Type): boolean {
return type.kind === 'Object' && type.shapeId === 'BuiltInUseActionState';
}

export function isStartTransitionType(id: Identifier): boolean {
return (
id.type.kind === 'Function' && id.type.shapeId === 'BuiltInStartTransition'
);
export function isStartTransitionType(type: Type): boolean {
return type.kind === 'Function' && type.shapeId === 'BuiltInStartTransition';
}

export function isSetActionStateType(id: Identifier): boolean {
return (
id.type.kind === 'Function' && id.type.shapeId === 'BuiltInSetActionState'
);
export function isSetActionStateType(type: Type): boolean {
return type.kind === 'Function' && type.shapeId === 'BuiltInSetActionState';
}

export function isUseReducerType(id: Identifier): boolean {
return id.type.kind === 'Function' && id.type.shapeId === 'BuiltInUseReducer';
export function isUseReducerType(type: Type): boolean {
return type.kind === 'Function' && type.shapeId === 'BuiltInUseReducer';
}

export function isDispatcherType(id: Identifier): boolean {
return id.type.kind === 'Function' && id.type.shapeId === 'BuiltInDispatch';
export function isDispatcherType(type: Type): boolean {
return type.kind === 'Function' && type.shapeId === 'BuiltInDispatch';
}

export function isStableType(id: Identifier): boolean {
export function isStableType(type: Type): boolean {
return (
isSetStateType(id) ||
isSetActionStateType(id) ||
isDispatcherType(id) ||
isUseRefType(id) ||
isStartTransitionType(id)
isSetStateType(type) ||
isSetActionStateType(type) ||
isDispatcherType(type) ||
isUseRefType(type) ||
isStartTransitionType(type)
);
}

export function isUseEffectHookType(id: Identifier): boolean {
return (
id.type.kind === 'Function' && id.type.shapeId === 'BuiltInUseEffectHook'
);
export function isUseEffectHookType(type: Type): boolean {
return type.kind === 'Function' && type.shapeId === 'BuiltInUseEffectHook';
}
export function isUseLayoutEffectHookType(id: Identifier): boolean {
export function isUseLayoutEffectHookType(type: Type): boolean {
return (
id.type.kind === 'Function' &&
id.type.shapeId === 'BuiltInUseLayoutEffectHook'
type.kind === 'Function' && type.shapeId === 'BuiltInUseLayoutEffectHook'
);
}
export function isUseInsertionEffectHookType(id: Identifier): boolean {
export function isUseInsertionEffectHookType(type: Type): boolean {
return (
id.type.kind === 'Function' &&
id.type.shapeId === 'BuiltInUseInsertionEffectHook'
type.kind === 'Function' && type.shapeId === 'BuiltInUseInsertionEffectHook'
);
}

export function isUseContextHookType(id: Identifier): boolean {
return (
id.type.kind === 'Function' && id.type.shapeId === 'BuiltInUseContextHook'
);
export function isUseContextHookType(type: Type): boolean {
return type.kind === 'Function' && type.shapeId === 'BuiltInUseContextHook';
}

export function getHookKind(env: Environment, id: Identifier): HookKind | null {
return getHookKindForType(env, id.type);
}

export function isUseOperator(id: Identifier): boolean {
return (
id.type.kind === 'Function' && id.type.shapeId === 'BuiltInUseOperator'
);
export function isUseOperator(type: Type): boolean {
return type.kind === 'Function' && type.shapeId === 'BuiltInUseOperator';
}

export function getHookKindForType(
Expand All @@ -1745,4 +1728,12 @@ export function getHookKindForType(
return null;
}

export function isEffectHook(type: Type): boolean {
return (
isUseEffectHookType(type) ||
isUseLayoutEffectHookType(type) ||
isUseInsertionEffectHookType(type)
);
}

export * from './Types';
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,6 @@ export default class HIRBuilder {
end: makeInstructionId(0),
},
scope: null,
type: makeType(),
loc: node.loc ?? GeneratedSource,
};
this.#bindings.set(name, {node, identifier});
Expand Down Expand Up @@ -896,6 +895,7 @@ export function createTemporaryPlace(
identifier: makeTemporaryIdentifier(env.nextIdentifierId, loc),
reactive: false,
effect: Effect.Unknown,
type: makeType(),
loc: GeneratedSource,
};
}
Expand All @@ -908,7 +908,7 @@ export function createTemporaryPlace(
export function clonePlaceToTemporary(env: Environment, place: Place): Place {
const temp = createTemporaryPlace(env, place.loc);
temp.effect = place.effect;
temp.identifier.type = place.identifier.type;
temp.type = place.type;
temp.reactive = place.reactive;
return temp;
}
Expand Down
Loading
Loading