-
Notifications
You must be signed in to change notification settings - Fork 47.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[compiler][wip] Environment option for resolving imported module types
Adds a new Environment config option which allows specifying a function that is called to resolve types of imported modules. The function is passed the name of the imported module (the RHS of the import stmt) and can return a TypeConfig, which is a recursive type of the following form: * Object of valid identifier keys (or "*" for wildcard) and values that are TypeConfigs * Function with various properties, whose return type is a TypeConfig * or a reference to a builtin type using one of a small list (currently Ref, Array, MixedReadonly, Primitive) Rather than have to eagerly supply all known types (most of which may not be used) when creating the config, this function can do so lazily. During InferTypes we call `getGlobalDeclaration()` to resolve global types. Originally this was just for known react modules, but if the new config option is passed we also call it to see if it can resolve a type. For `import {name} from 'module'` syntax, we first resolve the module type and then call `getPropertyType(moduleType, 'name')` to attempt to retrieve the property of the module (the module would obviously have to be typed as an object type for this to have a chance of yielding a result). If the module type is returned as null, or the property doesn't exist, we fall through to the original checking of whether the name was hook-like. TODO: * testing * cache the results of modules so we don't have to re-parse/install their types on each LoadGlobal of the same module * decide what to do if the module types are invalid. probably better to fatal rather than bail out, since this would indicate an invalid configuration. ghstack-source-id: bfdbf67e3dd0cbfd511bed0bd6ba92266cf99ab8 Pull Request resolved: #30771
- Loading branch information
1 parent
0ef00b3
commit 689c6bd
Showing
29 changed files
with
1,190 additions
and
36 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
105 changes: 105 additions & 0 deletions
105
compiler/packages/babel-plugin-react-compiler/src/HIR/TypeSchema.ts
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import {isValidIdentifier} from '@babel/types'; | ||
import {z} from 'zod'; | ||
import {Effect, ValueKind} from '..'; | ||
import {EffectSchema, ValueKindSchema} from './HIR'; | ||
|
||
export type ObjectPropertiesConfig = {[key: string]: TypeConfig}; | ||
export const ObjectPropertiesSchema: z.ZodType<ObjectPropertiesConfig> = z | ||
.record( | ||
z.string(), | ||
z.lazy(() => TypeSchema), | ||
) | ||
.refine(record => { | ||
return Object.keys(record).every( | ||
key => key === '*' || key === 'default' || isValidIdentifier(key), | ||
); | ||
}, 'Expected all "object" property names to be valid identifier, `*` to match any property, of `default` to define a module default export'); | ||
|
||
export type ObjectTypeConfig = { | ||
kind: 'object'; | ||
properties: ObjectPropertiesConfig | null; | ||
}; | ||
export const ObjectTypeSchema: z.ZodType<ObjectTypeConfig> = z.object({ | ||
kind: z.literal('object'), | ||
properties: ObjectPropertiesSchema.nullable(), | ||
}); | ||
|
||
export type FunctionTypeConfig = { | ||
kind: 'function'; | ||
positionalParams: Array<Effect>; | ||
restParam: Effect | null; | ||
calleeEffect: Effect; | ||
returnType: TypeConfig; | ||
returnValueKind: ValueKind; | ||
noAlias?: boolean | null | undefined; | ||
mutableOnlyIfOperandsAreMutable?: boolean | null | undefined; | ||
}; | ||
export const FunctionTypeSchema: z.ZodType<FunctionTypeConfig> = z.object({ | ||
kind: z.literal('function'), | ||
positionalParams: z.array(EffectSchema), | ||
restParam: EffectSchema.nullable(), | ||
calleeEffect: EffectSchema, | ||
returnType: z.lazy(() => TypeSchema), | ||
returnValueKind: ValueKindSchema, | ||
noAlias: z.boolean().nullable().optional(), | ||
mutableOnlyIfOperandsAreMutable: z.boolean().nullable().optional(), | ||
}); | ||
|
||
export type HookTypeConfig = { | ||
kind: 'hook'; | ||
positionalParams?: Array<Effect> | null | undefined; | ||
restParam?: Effect | null | undefined; | ||
returnType: TypeConfig; | ||
returnValueKind?: ValueKind | null | undefined; | ||
noAlias?: boolean | null | undefined; | ||
}; | ||
export const HookTypeSchema: z.ZodType<HookTypeConfig> = z.object({ | ||
kind: z.literal('hook'), | ||
positionalParams: z.array(EffectSchema).nullable().optional(), | ||
restParam: EffectSchema.nullable().optional(), | ||
returnType: z.lazy(() => TypeSchema), | ||
returnValueKind: ValueKindSchema.nullable().optional(), | ||
noAlias: z.boolean().nullable().optional(), | ||
}); | ||
|
||
export type BuiltInTypeConfig = | ||
| 'Any' | ||
| 'Ref' | ||
| 'Array' | ||
| 'Primitive' | ||
| 'MixedReadonly'; | ||
export const BuiltInTypeSchema: z.ZodType<BuiltInTypeConfig> = z.union([ | ||
z.literal('Any'), | ||
z.literal('Ref'), | ||
z.literal('Array'), | ||
z.literal('Primitive'), | ||
z.literal('MixedReadonly'), | ||
]); | ||
|
||
export type TypeReferenceConfig = { | ||
kind: 'type'; | ||
name: BuiltInTypeConfig; | ||
}; | ||
export const TypeReferenceSchema: z.ZodType<TypeReferenceConfig> = z.object({ | ||
kind: z.literal('type'), | ||
name: BuiltInTypeSchema, | ||
}); | ||
|
||
export type TypeConfig = | ||
| ObjectTypeConfig | ||
| FunctionTypeConfig | ||
| HookTypeConfig | ||
| TypeReferenceConfig; | ||
export const TypeSchema: z.ZodType<TypeConfig> = z.union([ | ||
ObjectTypeSchema, | ||
FunctionTypeSchema, | ||
HookTypeSchema, | ||
TypeReferenceSchema, | ||
]); |
This file contains 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
This file contains 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
Oops, something went wrong.