Skip to content

Commit

Permalink
fix(strict-mutable): working rule
Browse files Browse the repository at this point in the history
  • Loading branch information
d0whc3r committed Sep 19, 2019
1 parent 95e01c7 commit 81f3eae
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 80 deletions.
95 changes: 18 additions & 77 deletions src/rules/strict-mutable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,66 +42,10 @@ const rule: Rule.RuleModule = {
const mutable = parsed && parsed.length && parsed[0].mutable || false;
if (mutable) {
const varName = node.parent.key.name;
mutableProps.set(varName, node.parent);
mutableProps.set(varName, node);
}
}

// function getName(expression: any) {
// if (expression.left && expression.left.name) {
// return expression.left.name;
// }
// return null;
// }
//
// function parseExpression(expression: any): any {
// if (!expression) {
// return null;
// }
// if (expression.expression) {
// return parseExpression(expression.expression);
// }
// if (expression.openingElement) {
// const container = expression.openingElement.attributes && expression.openingElement.attributes.nextContainer;
// if (container) {
// return container.body && container.body.expression ? removeUsedVars(container.body) : parseExpression(container.body);
// } else {
// return null;
// }
// }
// return expression && getName(expression);
// }
//
// function removeUsedVars(statements: any[]) {
// statements
// .map((st) => st.expression && parseExpression(st.expression))
// .filter((name) => !!name)
// .forEach((name) => {
// mutableProps.delete(name.escapedText);
// });
// statements
// .filter((st) => st.thenStatement && st.thenStatement.statements)
// .map((st) => st.thenStatement.statements)
// .forEach((st) => {
// removeUsedVars(st);
// });
// statements
// .filter((st) => st.elseStatement)
// .forEach((st) => {
// const sts = Array.isArray(st.elseStatement) ? st.elseStatement : [st.elseStatement];
// removeUsedVars(sts);
// });
// }

// function getJsonPath(element: any, path: string[]) {
// const name = path[0];
// const value = element[name];
// if (path.length === 1) {
// return value;
// } else {
// return value && getJsonPath(value, path.slice(1));
// }
// }

function removeVar(name: any) {
if (!name) {
return;
Expand All @@ -123,27 +67,24 @@ const rule: Rule.RuleModule = {
return;
}
const { expression, thenStatement, elseStatement } = st;
console.log('kind:', !!expression, st.getText());
[...getArray(thenStatement), ...getArray(elseStatement), expression].filter((ex) => !!ex).forEach(checkExpression);
console.log('statement end');
}

function checkExpression(expr: any) {
if (!expr) {
return;
}
const { expression, left, openingElement, nextContainer, body, statements, thenStatement } = expr;
const { expression, left, openingElement, body, nextContainer, statements, thenStatement } = expr;
if (left && left.name && expr.operatorToken && ASSIGN_TOKENS.includes(expr.operatorToken.kind)) {
removeVar(left.name);
}
if (openingElement) {
getArray(openingElement.attributes).forEach(checkExpression);
}
[...getArray(thenStatement), expression, nextContainer, body].filter((ex) => !!ex).forEach(checkExpression);
[...getArray(thenStatement), expression, body, nextContainer].filter((ex) => !!ex).forEach(checkExpression);
if (statements) {
statements.forEach(checkStatement);
}
console.log('expression');
}

return {
Expand All @@ -167,26 +108,26 @@ const rule: Rule.RuleModule = {
}
stencil.rules['ClassDeclaration:exit'](node);
mutableProps.forEach((varNode, varName) => {
const originalNode = parserServices.esTreeNodeToTSNodeMap.get(varNode);
const originalNode = parserServices.esTreeNodeToTSNodeMap.get(varNode.parent);
const text = originalNode.getFullText();
const parsed = parseDecorator(varNode);
context.report({
node: varNode,
node: varNode.parent,
message: `@Prop() "${varName}" should not be mutable`,
fix(fixer) {
// const options = parsed && parsed.length && parsed[0] || {};
// delete options.mutable;
// let opts = '';
// if (options && Object.keys(options).length) {
// opts = Object.keys(options).map((key) => {
// const value = options[key];
// const val = typeof value === 'string' ? `'${value}'` : value;
// return `${key}: ${val}`;
// }).join(', ');
// opts = `{ ${opts} }`;
// }
// const result = text.replace(/@Prop\((.*)?\)/, `@Prop(${opts})`);
return fixer.replaceText(varNode, text);
const options = parsed && parsed.length && parsed[0] || {};
delete options.mutable;
let opts = '';
if (options && Object.keys(options).length) {
opts = Object.keys(options).map((key) => {
const value = options[key];
const val = typeof value === 'string' ? `'${value}'` : value;
return `${key}: ${val}`;
}).join(', ');
opts = `{ ${opts} }`;
}
const result = text.replace(/@Prop\((.*)?\)/, `@Prop(${opts})`);
return fixer.replaceText(varNode, result);
}
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function getDecorator(node: any, decoratorName?: string): any | any[] {
}

export function parseDecorator(decorator: any) {
if (decorator && decorator.expression.type === 'CallExpression') {
if (decorator && decorator.expression && decorator.expression.type === 'CallExpression') {
return decorator.expression.arguments.map((a: any) => {
const parsed = getStaticValue(a);
return parsed ? parsed.value : undefined;
Expand Down
4 changes: 2 additions & 2 deletions tests/lib/rules/strict-mutable/strict-mutable.good.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ export class SampleTag {

render() {
return (
<div class="odp-button-selector" onClick={(e) => this.mutableInJsx = true}>
<div class="class" onClick={(e) => this.mutableInJsx = true}>
{this.values.map((value, index) => {
return (
<div
onClick={() => (this.mutableInJsx2 = index)}
class={{
'odp-button-selector-label': true,
'label': true,
selected: index === this.selected
}}>
<span>{value}</span>
Expand Down
3 changes: 3 additions & 0 deletions tests/lib/rules/strict-mutable/strict-mutable.wrong.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
export class SampleTag {
@Prop({ mutable: false }) readonly test?: string;
@Prop({ mutable: true }) testMutable?: string;
/**
* Some property comment
*/
@Prop({ mutable: true, attribute: 'some-attr', reflect: true }) testMutable2?: string;

private internalMethod() {
Expand Down

0 comments on commit 81f3eae

Please sign in to comment.