FlowLib: Add typed Set wrapper (#1940)#1940
Open
avp wants to merge 24 commits intofacebook:static_hfrom
Open
Conversation
Summary: Add a function that allows users to query for a specific Decorator pattern. This is used later to find specific Decorators during typechecking. Differential Revision: D92850438
Summary: It's convenient to split this function up for future usage and also for readability right now. Differential Revision: D92435458
Summary: We don't want to narrow to a non-single type using the simple version of narrowing we have right now, because that results in a mismatch during IRGen where FlowChecker thinks we have the narrowed type but we emit a checked cast to the single type and then widen it again. This results in types like `Foo | void` getting an IR type of `object` instead of `object|undefined` and the output ends up completely incorrect. So prevent narrowing unless we're looking for a single type, because that still handles the case we care about, where you can read a property from an object even if the object is optional. Differential Revision: D96500084
Summary: Add support for generic methods on typed classes, with both explicit type arguments and type inference at call sites. Add the `Hermes.final` decorator and validate it in FlowChecker. ## Final Methods `Hermes.final` bypasses the home object for dispatch. Instead of loading the closure from the parent object at the call site, a `Variable` is created in the enclosing scope and the closure is stored there. At call sites, the closure is loaded from the `Variable` via `LoadFrameInst`. Non-final non-overridden methods continue to use `TypedLoadParentInst` with a known `Function*` target. ## Generic Methods Generic methods must be annotated `Hermes.final` because they cannot participate in dynamic dispatch. Each call site is specialized to a concrete function, so there is no single function pointer to store in the vtable (home object). ## Decl and Variable storage during IRGen `FlowChecker` creates a new `Decl` for each final method. The callsites for final methods are annotated with the `Decl` in the IdentifierNode, allowing us to find the Variable to load from. At call sites, if the property `IdentifierNode` has a Decl, the closure is loaded from the associated Variable directly, with a known call target Function. NOTE: Generic _private_ methods aren't supported yet because I wrote this diff prior to adding support for private fields/methods, and because this diff is big enough already. Differential Revision: D92426451
Summary: Optional parameters must appear last in the parameter list. Update `canAFlowIntoB` for `TypedFunctionType` to allow flowing between function types with different parameter counts when the extra parameters are optional. Insert an `ImplicitCheckedCast` when the parameter counts differ, because we must prevent the user from casting away an optional parameter then replacing it with an optional parameter of a different type! Differential Revision: D92861947
Summary: Implement typechecking for string property access: - Named `.length` property returns number - Computed index access with number returns string - Error on non-number index or unknown property This doesn't implement any special IRGen for faster reads yet, just the type information. String methods aren't supported yet either, those will be part of however we do our typed JSLib. NOTE: This is somewhat of a hack, but it's temporary while we figure exactly how we want the indexed access JSLib functionality to work. Differential Revision: D90788989
Summary: To avoid dumping useless information from FlowLib, set up the Sema dumper to dump only the relevant information for a given function (and all lexical descendants). This way we can restrict what's printed and avoid printing out the entire FlowLib just because it's in the program. This is very useful in future diffs due to the amount of Sema tests we have and how many changes FlowLib changes will cause. Differential Revision: D94141005
Summary: Avoid dumping unnecessary info. This reduces noise later. Differential Revision: D94141003
Summary:
Add a FlowLib prelude mechanism for typed mode, analogous to
InternalJavaScript for the bytecode VM.
JS source files in `lib/FlowLib/` are sorted by their numeric prefix and
concatenated at build time into a single `FlowLib.js`. The source is
included directly in the compiled C++ code.
When typed mode wraps user code in an IIFE, the FlowLib source is parsed
and prepended as a prelude inside an outer IIFE. The resulting structure
is:
```
(function(){
...prelude...
(function(exports){
...user code...
})({})
})()
```
This way the user code can see the prelude but there won't be any naming
conflicts.
FlowLib is enabled in typed mode when std-globals are enabled.
NOTE: By default, `-dump-sema` now starts the dump from the inner
function (original user code) rather than the full wrapped program, so
tests don't include the FlowLib prelude or the outer IIFE wrapper. This
changed a lot of tests. If there's better ways to handle the tests here,
suggestions welcome.
Differential Revision: D91596589
Summary: These are the first two functions we can add to the FlowLib. `charAt` is an operation on a primitive, while `map` requires adding `Array<T>`. User code don't use these properly yet, that's in the next diff(s). Differential Revision: D94141006
Summary: Record the "builtin" directive for primitive JSLib functionality when running SemanticResolver. This isn't used yet. Differential Revision: D91596590
Summary: Resolve non-generic builtin method calls on primitive types (string, e.g.) during type checking and IRGen. `populateBuiltinMethods` scans functions marked with the "builtin" directive and registers them in a table. MemberExpression visitors for primitives can look up this table and store the resolved Decl. CallExpression then calls resolveBuiltinMethodCall() to parse the function type, set the callee type, and register the call target for IRGen. In IRGen, load the closure from the builtin's variable and emit direct CallInst with the receiver and arguments. NOTE: Right now this only works for `string`, but can be added for the other primitives once they're in the FlowLib. Differential Revision: D91519592
avp
added a commit
to avp/hermes
that referenced
this pull request
Mar 17, 2026
Summary: Pull Request resolved: facebook#1940 Add a generic `Set<T>` to FlowLib that wraps the native Set with typed add/has/delete/clear/forEach methods, allowing typed code to use Set methods directly. Differential Revision: D96520014
avp
added a commit
to avp/hermes
that referenced
this pull request
Mar 17, 2026
Summary: Pull Request resolved: facebook#1940 Add a generic `Set<T>` to FlowLib that wraps the native Set with typed add/has/delete/clear/forEach methods, allowing typed code to use Set methods directly. Differential Revision: D96520014
Summary: Handle `T[]` array types by resolving them to the corresponding `Array<T>` generic class instantiation. Store a mapping from the element type `T` to its `Array<T>` class so we can easily find the relevant class. `ArrayType` has not been completely removed yet to reduce the size of this diff. I'll do that in a subsequent diff. Add a parent/prototype pointer to `AllocFastArrayInst` / `NewFastArray` so that created FastArrays point to the correct home object (the `Array<T>` prototype). This is needed because home objects are different between different generic class specializations (due to copying the AST). Array literals do not literally emit calls to the `Array<T>` constructor. While it's conceptually cleaner in IRGen, that would require varargs support and sophisticated optimizations to ultimately reach `NewFastArray` which is what we want to actually emit without any extra indirections. Instead, we directly generate the IR we want at the callsite. Introduce an `InferencePlaceholder` specifically for arrays, because arrays are the only structural type that can be inferred but is represented by a `ClassType` internally. This avoids regressing any type inference behavior. Differential Revision: D94096273
Differential Revision: D94141004
Summary: Add some more array functions to the FlowLib. Update widgets accordingly. Differential Revision: D94149418
Summary: Add `staticObjectType_` to `ClassType` to represent the static side of a class. Static fields and methods are lowered to `Variable`s rather than object layout slots. FlowChecker resolves member access on `ClassConstructorType` by looking up the static object type, validates static field/ method override compatibility against the superclass, and uses `classConsType` to set the correct `this` type for static methods. IRGen emits static fields/methods as Variables during `genClassDeclaration` and handles private static names via `PrivateNameNode` unwrapping. This diff has to support: * public and private static fields * public and private static methods * generic public static methods * static inheritance NOTE: This doesn't support private static generic methods yet, because generic private methods in general are not supported yet. That will be added in the next diff(s). Differential Revision: D95152702
Summary: Previously, generic private methods were errors. This diff supports them by using the method call handling already in place for public generics. FlowChecker: The duplicated code paths for `ClassType` and `ClassConstructorType` are merged into a single flow that looks up the method via `findPublicField` or `findPrivateField` based on whether the callee is a `PrivateNameNode`. IRGen: private generic methods are skipped during regular private method emission, and `genSpecializedMethods` now handles private keys by generating the correct private name identifier. Differential Revision: D95858239
Summary: This adds default parameter handling in two places: - Marks them as optional in the function type, enabling correct typechecking. - Sets the parameter's declared type (non-optional inside the body) and typechecks the default value expression against the declared type. Differential Revision: D96830016
Summary: When a destructuring pattern has a type annotation pass the resolved type as the constraint to the initializer expression. This lets the checker infer array literals as tuples instead of arrays. Previously the constraint was only extracted for simple identifier declarations, leaving it null for array/object patterns and failing to typecheck. Differential Revision: D96835196
Summary: Add type-checking for destructuring parameters in typed functions. Require type annotations on destructuring patterns, propagate types to leaf identifiers, and refactor tuple/object destructuring expansion into shared helpers. There's not a lot of new code here, but there was some refactoring and function extraction to avoid having too much duplication. Differential Revision: D96961531
Summary: Previously this was unsupported. We can add it, just need to support knowing the actual type of the inherited constructor. Differential Revision: D97012043
Summary: Also update widgets accordingly. Differential Revision: D97124221
Summary: Add a generic `Map<K, V>` to FlowLib that wraps the native Map with typed methods, allowing typed code to use map.get()/map.set() directly instead of using hacks. Update the widgets benchmark and test to use the new typed Map. Removing the mapPrototypeGet/mapPrototypeSet hacks and use proper generic types. Differential Revision: D96520015
Summary: Pull Request resolved: facebook#1940 Add a generic `Set<T>` to FlowLib that wraps the native Set with typed add/has/delete/clear/forEach methods, allowing typed code to use Set methods directly. Differential Revision: D96520014
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Add a generic
Set<T>to FlowLib that wraps the native Setwith typed add/has/delete/clear/forEach methods, allowing
typed code to use Set methods directly.
Differential Revision: D96520014