Skip to content

Commit

Permalink
Merge branch 'facebook:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeychernyshev authored Aug 12, 2024
2 parents c67c056 + 0d7c12c commit 885bf30
Show file tree
Hide file tree
Showing 33 changed files with 1,215 additions and 427 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -452,17 +452,17 @@ function* runWithEnvironment(
value: reactiveFunction,
});

promoteUsedTemporaries(reactiveFunction);
pruneUnusedLValues(reactiveFunction);
yield log({
kind: 'reactive',
name: 'PromoteUsedTemporaries',
name: 'PruneUnusedLValues',
value: reactiveFunction,
});

pruneUnusedLValues(reactiveFunction);
promoteUsedTemporaries(reactiveFunction);
yield log({
kind: 'reactive',
name: 'PruneUnusedLValues',
name: 'PromoteUsedTemporaries',
value: reactiveFunction,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ export const InstrumentationSchema = z

export type ExternalFunction = z.infer<typeof ExternalFunctionSchema>;

export const MacroMethodSchema = z.union([
z.object({type: z.literal('wildcard')}),
z.object({type: z.literal('name'), name: z.string()}),
]);

// Would like to change this to drop the string option, but breaks compatibility with existing configs
export const MacroSchema = z.union([
z.string(),
z.tuple([z.string(), z.array(MacroMethodSchema)]),
]);

export type Macro = z.infer<typeof MacroSchema>;
export type MacroMethod = z.infer<typeof MacroMethodSchema>;

const HookSchema = z.object({
/*
* The effect of arguments to this hook. Describes whether the hook may or may
Expand Down Expand Up @@ -133,7 +147,7 @@ const EnvironmentConfigSchema = z.object({
* plugin since it looks specifically for the name of the function being invoked, not
* following aliases.
*/
customMacros: z.nullable(z.array(z.string())).default(null),
customMacros: z.nullable(z.array(MacroSchema)).default(null),

/**
* Enable a check that resets the memoization cache when the source code of the file changes.
Expand Down Expand Up @@ -490,7 +504,19 @@ export function parseConfigPragma(pragma: string): EnvironmentConfig {
}

if (key === 'customMacros' && val) {
maybeConfig[key] = [val];
const valSplit = val.split('.');
if (valSplit.length > 0) {
const props = [];
for (const elt of valSplit.slice(1)) {
if (elt === '*') {
props.push({type: 'wildcard'});
} else if (elt.length > 0) {
props.push({type: 'name', name: elt});
}
}
console.log([valSplit[0], props.map(x => x.name ?? '*').join('.')]);
maybeConfig[key] = [[valSplit[0], props]];
}
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@ function codegenInstructionNullable(
value = null;
} else {
lvalue = instr.value.lvalue.pattern;
let hasReasign = false;
let hasReassign = false;
let hasDeclaration = false;
for (const place of eachPatternOperand(lvalue)) {
if (
Expand All @@ -1219,18 +1219,18 @@ function codegenInstructionNullable(
cx.temp.set(place.identifier.declarationId, null);
}
const isDeclared = cx.hasDeclared(place.identifier);
hasReasign ||= isDeclared;
hasReassign ||= isDeclared;
hasDeclaration ||= !isDeclared;
}
if (hasReasign && hasDeclaration) {
if (hasReassign && hasDeclaration) {
CompilerError.invariant(false, {
reason:
'Encountered a destructuring operation where some identifiers are already declared (reassignments) but others are not (declarations)',
description: null,
loc: instr.loc,
suggestions: null,
});
} else if (hasReasign) {
} else if (hasReassign) {
kind = InstructionKind.Reassign;
}
value = codegenPlaceToExpression(cx, instr.value.value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Place,
ReactiveValue,
} from '../HIR';
import {Macro, MacroMethod} from '../HIR/Environment';
import {eachReactiveValueOperand} from './visitors';

/**
Expand Down Expand Up @@ -43,15 +44,17 @@ import {eachReactiveValueOperand} from './visitors';
export function memoizeFbtAndMacroOperandsInSameScope(
fn: HIRFunction,
): Set<IdentifierId> {
const fbtMacroTags = new Set([
...FBT_TAGS,
const fbtMacroTags = new Set<Macro>([
...Array.from(FBT_TAGS).map((tag): Macro => [tag, []]),
...(fn.env.config.customMacros ?? []),
]);
const fbtValues: Set<IdentifierId> = new Set();
const macroMethods = new Map<IdentifierId, Array<Array<MacroMethod>>>();
while (true) {
let size = fbtValues.size;
visit(fn, fbtMacroTags, fbtValues);
if (size === fbtValues.size) {
let vsize = fbtValues.size;
let msize = macroMethods.size;
visit(fn, fbtMacroTags, fbtValues, macroMethods);
if (vsize === fbtValues.size && msize === macroMethods.size) {
break;
}
}
Expand All @@ -71,8 +74,9 @@ export const SINGLE_CHILD_FBT_TAGS: Set<string> = new Set([

function visit(
fn: HIRFunction,
fbtMacroTags: Set<string>,
fbtMacroTags: Set<Macro>,
fbtValues: Set<IdentifierId>,
macroMethods: Map<IdentifierId, Array<Array<MacroMethod>>>,
): void {
for (const [, block] of fn.body.blocks) {
for (const instruction of block.instructions) {
Expand All @@ -83,7 +87,7 @@ function visit(
if (
value.kind === 'Primitive' &&
typeof value.value === 'string' &&
fbtMacroTags.has(value.value)
matchesExactTag(value.value, fbtMacroTags)
) {
/*
* We don't distinguish between tag names and strings, so record
Expand All @@ -92,10 +96,38 @@ function visit(
fbtValues.add(lvalue.identifier.id);
} else if (
value.kind === 'LoadGlobal' &&
fbtMacroTags.has(value.binding.name)
matchesExactTag(value.binding.name, fbtMacroTags)
) {
// Record references to `fbt` as a global
fbtValues.add(lvalue.identifier.id);
} else if (
value.kind === 'LoadGlobal' &&
matchTagRoot(value.binding.name, fbtMacroTags) !== null
) {
const methods = matchTagRoot(value.binding.name, fbtMacroTags)!;
macroMethods.set(lvalue.identifier.id, methods);
} else if (
value.kind === 'PropertyLoad' &&
macroMethods.has(value.object.identifier.id)
) {
const methods = macroMethods.get(value.object.identifier.id)!;
const newMethods = [];
for (const method of methods) {
if (
method.length > 0 &&
(method[0].type === 'wildcard' ||
(method[0].type === 'name' && method[0].name === value.property))
) {
if (method.length > 1) {
newMethods.push(method.slice(1));
} else {
fbtValues.add(lvalue.identifier.id);
}
}
}
if (newMethods.length > 0) {
macroMethods.set(lvalue.identifier.id, newMethods);
}
} else if (isFbtCallExpression(fbtValues, value)) {
const fbtScope = lvalue.identifier.scope;
if (fbtScope === null) {
Expand Down Expand Up @@ -167,25 +199,57 @@ function visit(
}
}

function matchesExactTag(s: string, tags: Set<Macro>): boolean {
return Array.from(tags).some(macro =>
typeof macro === 'string'
? s === macro
: macro[1].length === 0 && macro[0] === s,
);
}

function matchTagRoot(
s: string,
tags: Set<Macro>,
): Array<Array<MacroMethod>> | null {
const methods: Array<Array<MacroMethod>> = [];
for (const macro of tags) {
if (typeof macro === 'string') {
continue;
}
const [tag, rest] = macro;
if (tag === s && rest.length > 0) {
methods.push(rest);
}
}
if (methods.length > 0) {
return methods;
} else {
return null;
}
}

function isFbtCallExpression(
fbtValues: Set<IdentifierId>,
value: ReactiveValue,
): boolean {
return (
value.kind === 'CallExpression' && fbtValues.has(value.callee.identifier.id)
(value.kind === 'CallExpression' &&
fbtValues.has(value.callee.identifier.id)) ||
(value.kind === 'MethodCall' && fbtValues.has(value.property.identifier.id))
);
}

function isFbtJsxExpression(
fbtMacroTags: Set<string>,
fbtMacroTags: Set<Macro>,
fbtValues: Set<IdentifierId>,
value: ReactiveValue,
): boolean {
return (
value.kind === 'JsxExpression' &&
((value.tag.kind === 'Identifier' &&
fbtValues.has(value.tag.identifier.id)) ||
(value.tag.kind === 'BuiltinTag' && fbtMacroTags.has(value.tag.name)))
(value.tag.kind === 'BuiltinTag' &&
matchesExactTag(value.tag.name, fbtMacroTags)))
);
}

Expand Down
Loading

0 comments on commit 885bf30

Please sign in to comment.