Skip to content

Commit

Permalink
fix(babel-plugin-component): correct class member decorator validation (
Browse files Browse the repository at this point in the history
#1122)

* fix(babel-plugin-component): improve class member decorator validation
  • Loading branch information
apapko authored Mar 20, 2019
1 parent 1f12803 commit 22ec3d5
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,121 @@ describe('Transform property', () => {
}
);

pluginTest(
'single @api getter on one class member should not conflict with @api setter on another',
`
import { api } from 'lwc';
export default class Test {
@api
get first() { return null; }
get second() {
return this.s;
}
@api
set second(value) {
this.s = value;
}
}
`,
{
output: {
code: `
import { registerDecorators as _registerDecorators } from "lwc";
import _tmpl from "./test.html";
import { registerComponent as _registerComponent } from "lwc";
class Test {
get first() {
return null;
}
get second() {
return this.s;
}
set second(value) {
this.s = value;
}
}
_registerDecorators(Test, {
publicProps: {
first: {
config: 1
},
second: {
config: 3
}
}
});
export default _registerComponent(Test, {
tmpl: _tmpl
});
`,
},
}
);

pluginTest(
'@api setter on one class member should not conflict with @api getter on another',
`
import { api } from 'lwc';
export default class Test {
@api
set first(value) {}
get first() {}
@api
get second() {
return this.s;
}
set second (value) {
this.s = value;
}
}
`,
{
output: {
code: `
import { registerDecorators as _registerDecorators } from "lwc";
import _tmpl from "./test.html";
import { registerComponent as _registerComponent } from "lwc";
class Test {
set first(value) {}
get first() {}
get second() {
return this.s;
}
set second(value) {
this.s = value;
}
}
_registerDecorators(Test, {
publicProps: {
first: {
config: 3
},
second: {
config: 3
}
}
});
export default _registerComponent(Test, {
tmpl: _tmpl
});
`,
},
}
);

pluginTest(
'transform pairs of setter and getter',
`
Expand Down
38 changes: 21 additions & 17 deletions packages/@lwc/babel-plugin-component/src/decorators/api/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,26 +81,30 @@ function validatePropertyName(property) {
}

function validateSingleApiDecoratorOnSetterGetterPair(decorators) {
decorators
.filter(decorator => isApiDecorator(decorator) && decorator.type === DECORATOR_TYPES.SETTER)
.forEach(({ path }) => {
const parentPath = path.parentPath;
const name = parentPath.get('key.name').node;

const associatedGetter = decorators.find(
decorator =>
isApiDecorator(decorator) &&
decorator.type === DECORATOR_TYPES.GETTER &&
parentPath.get('key.name').node === name
);

if (associatedGetter) {
throw generateError(parentPath, {
// keep track of visited class methods
const visitedMethods = new Set();

decorators.forEach(decorator => {
const { path, type } = decorator;

// since we are validating get/set we only look at @api methods
if (
isApiDecorator(decorator) &&
(type === DECORATOR_TYPES.GETTER || type === DECORATOR_TYPES.SETTER)
) {
const methodPath = path.parentPath;
const methodName = methodPath.get('key.name').node;

if (visitedMethods.has(methodName)) {
throw generateError(methodPath, {
errorInfo: DecoratorErrors.SINGLE_DECORATOR_ON_SETTER_GETTER_PAIR,
messageArgs: [name],
messageArgs: [methodName],
});
}
});

visitedMethods.add(methodName);
}
});
}

function validateUniqueness(decorators) {
Expand Down

0 comments on commit 22ec3d5

Please sign in to comment.