Skip to content

Commit

Permalink
chore: improve member expression computed typechecking (#5157)
Browse files Browse the repository at this point in the history
  • Loading branch information
cardoso authored Jan 22, 2025
1 parent a88ebeb commit ad9a492
Showing 1 changed file with 38 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,60 +25,67 @@ function validateWireId(id: NodePath | undefined, path: NodePath, state: LwcBabe
);
}

const isMemberExpression = id.isMemberExpression();
let adapter: NodePath<types.Identifier>;

if (!id.isIdentifier() && !isMemberExpression) {
throw generateError(
id,
{
errorInfo: DecoratorErrors.FUNCTION_IDENTIFIER_SHOULD_BE_FIRST_PARAMETER,
},
state
);
}
if (id.isIdentifier()) {
// @wire(adapter)
adapter = id;
} else if (id.isMemberExpression()) {
if (id.node.computed) {
// @wire(adapter[computed])
throw generateError(
id,
{
errorInfo: DecoratorErrors.FUNCTION_IDENTIFIER_CANNOT_HAVE_COMPUTED_PROPS,
},
state
);
}

if (id.isMemberExpression({ computed: true })) {
throw generateError(
id,
{
errorInfo: DecoratorErrors.FUNCTION_IDENTIFIER_CANNOT_HAVE_COMPUTED_PROPS,
},
state
);
}
const object = id.get('object');

// TODO [#3444]: improve member expression computed typechecking
// @ts-expect-error type narrowing incorrectly reduces id to `never`
if (isMemberExpression && !id.get('object').isIdentifier()) {
if (object.isIdentifier()) {
// @wire(adapter.foo)
adapter = object;
} else {
// @wire(adapter.foo.bar)
throw generateError(
id,
{
errorInfo:
DecoratorErrors.FUNCTION_IDENTIFIER_CANNOT_HAVE_NESTED_MEMBER_EXRESSIONS,
},
state
);
}
} else {
// @wire(1), @wire('adapter'), @wire(function adapter() {}), etc.
throw generateError(
id,
{
errorInfo: DecoratorErrors.FUNCTION_IDENTIFIER_CANNOT_HAVE_NESTED_MEMBER_EXRESSIONS,
errorInfo: DecoratorErrors.FUNCTION_IDENTIFIER_SHOULD_BE_FIRST_PARAMETER,
},
state
);
}

// TODO [#3444]: improve member expression computed typechecking
// Ensure wire adapter is imported (check for member expression or identifier)
// @ts-expect-error type narrowing incorrectly reduces id to `never`
const wireBinding = isMemberExpression ? id.node.object.name : id.node.name;
if (!path.scope.getBinding(wireBinding)) {
const adapterBinding = path.scope.getBinding(adapter.node.name);
if (!adapterBinding) {
throw generateError(
id,
{
errorInfo: DecoratorErrors.WIRE_ADAPTER_SHOULD_BE_IMPORTED,
messageArgs: [id.node.name],
messageArgs: [adapter.node.name],
},
state
);
}

// ensure wire adapter is a first parameter
if (
wireBinding &&
!path.scope.getBinding(wireBinding)!.path.isImportSpecifier() &&
!path.scope.getBinding(wireBinding)!.path.isImportDefaultSpecifier()
!adapterBinding.path.isImportSpecifier() &&
!adapterBinding.path.isImportDefaultSpecifier()
) {
throw generateError(
id,
Expand Down

0 comments on commit ad9a492

Please sign in to comment.