diff --git a/src/generators/nodes/Attribute.ts b/src/generators/nodes/Attribute.ts index c4d8324598..e1301fcfc8 100644 --- a/src/generators/nodes/Attribute.ts +++ b/src/generators/nodes/Attribute.ts @@ -1,7 +1,6 @@ import deindent from '../../utils/deindent'; import { stringify } from '../../utils/stringify'; import fixAttributeCasing from '../../utils/fixAttributeCasing'; -import getExpressionPrecedence from '../../utils/getExpressionPrecedence'; import addToSet from '../../utils/addToSet'; import { DomGenerator } from '../dom/index'; import Node from './shared/Node'; @@ -85,11 +84,11 @@ export default class Attribute extends Node { return (this.chunks[0].type === 'Text' ? '' : `"" + `) + this.chunks - .map((chunk: Node) => { + .map(chunk => { if (chunk.type === 'Text') { return stringify(chunk.data); } else { - return getExpressionPrecedence(chunk.node) <= 13 ? `(${chunk.snippet})` : chunk.snippet; + return chunk.getPrecedence() <= 13 ? `(${chunk.snippet})` : chunk.snippet; } }) .join(' + '); @@ -183,7 +182,7 @@ export default class Attribute extends Node { allDependencies.add(d); }); - return getExpressionPrecedence(chunk.node) <= 13 ? `(${snippet})` : snippet; + return chunk.getPrecedence() <= 13 ? `(${snippet})` : snippet; } }) .join(' + '); @@ -332,7 +331,7 @@ export default class Attribute extends Node { allDependencies.add(d); }); - return getExpressionPrecedence(chunk.node) <= 13 ? `(${snippet})` : snippet; + return chunk.getPrecedence() <= 13 ? `(${snippet})` : snippet; } }) .join(' + '); diff --git a/src/generators/nodes/Title.ts b/src/generators/nodes/Title.ts index 49efa9b6f0..20e16f763d 100644 --- a/src/generators/nodes/Title.ts +++ b/src/generators/nodes/Title.ts @@ -1,5 +1,4 @@ import { stringify } from '../../utils/stringify'; -import getExpressionPrecedence from '../../utils/getExpressionPrecedence'; import Node from './shared/Node'; import Block from '../dom/Block'; import mapChildren from './shared/mapChildren'; @@ -57,7 +56,7 @@ export default class Title extends Node { allDependencies.add(d); }); - return getExpressionPrecedence(chunk.expression.node) <= 13 ? `(${snippet})` : snippet; + return chunk.expression.getPrecedence() <= 13 ? `(${snippet})` : snippet; } }) .join(' + '); diff --git a/src/generators/nodes/shared/Expression.ts b/src/generators/nodes/shared/Expression.ts index 3a70f8cad2..59ddcba396 100644 --- a/src/generators/nodes/shared/Expression.ts +++ b/src/generators/nodes/shared/Expression.ts @@ -3,6 +3,55 @@ import { walk } from 'estree-walker'; import isReference from 'is-reference'; import flattenReference from '../../../utils/flattenReference'; import { createScopes } from '../../../utils/annotateWithScopes'; +import { Node } from '../../../interfaces'; + +const binaryOperators: Record = { + '**': 15, + '*': 14, + '/': 14, + '%': 14, + '+': 13, + '-': 13, + '<<': 12, + '>>': 12, + '>>>': 12, + '<': 11, + '<=': 11, + '>': 11, + '>=': 11, + 'in': 11, + 'instanceof': 11, + '==': 10, + '!=': 10, + '===': 10, + '!==': 10, + '&': 9, + '^': 8, + '|': 7 +}; + +const logicalOperators: Record = { + '&&': 6, + '||': 5 +}; + +const precedence: Record number> = { + Literal: () => 21, + Identifier: () => 21, + ParenthesizedExpression: () => 20, + MemberExpression: () => 19, + NewExpression: () => 19, // can be 18 (if no args) but makes no practical difference + CallExpression: () => 19, + UpdateExpression: () => 17, + UnaryExpression: () => 16, + BinaryExpression: (node: Node) => binaryOperators[node.operator], + LogicalExpression: (node: Node) => logicalOperators[node.operator], + ConditionalExpression: () => 4, + AssignmentExpression: () => 3, + YieldExpression: () => 2, + SpreadElement: () => 1, + SequenceExpression: () => 0 +}; export default class Expression { compiler: Generator; @@ -117,6 +166,10 @@ export default class Expression { this.indexes = new Set(); // TODO... } + getPrecedence() { + return this.node.type in precedence ? precedence[this.node.type](this.node) : 0; + } + overwriteThis(name) { this.thisReferences.forEach(ref => { this.compiler.code.overwrite(ref.start, ref.end, name, { diff --git a/src/utils/getExpressionPrecedence.ts b/src/utils/getExpressionPrecedence.ts deleted file mode 100644 index 7cd26293af..0000000000 --- a/src/utils/getExpressionPrecedence.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Node } from '../interfaces'; - -const binaryOperators: Record = { - '**': 15, - '*': 14, - '/': 14, - '%': 14, - '+': 13, - '-': 13, - '<<': 12, - '>>': 12, - '>>>': 12, - '<': 11, - '<=': 11, - '>': 11, - '>=': 11, - 'in': 11, - 'instanceof': 11, - '==': 10, - '!=': 10, - '===': 10, - '!==': 10, - '&': 9, - '^': 8, - '|': 7 -}; - -const logicalOperators: Record = { - '&&': 6, - '||': 5 -}; - -const precedence: Record number> = { - Literal: () => 21, - Identifier: () => 21, - ParenthesizedExpression: () => 20, - MemberExpression: () => 19, - NewExpression: () => 19, // can be 18 (if no args) but makes no practical difference - CallExpression: () => 19, - UpdateExpression: () => 17, - UnaryExpression: () => 16, - BinaryExpression: (expression: Node) => binaryOperators[expression.operator], - LogicalExpression: (expression: Node) => logicalOperators[expression.operator], - ConditionalExpression: () => 4, - AssignmentExpression: () => 3, - YieldExpression: () => 2, - SpreadElement: () => 1, - SequenceExpression: () => 0 -}; - -// TODO make this a method of Expression -export default function getExpressionPrecedence(expression: Node) { - return expression.type in precedence ? precedence[expression.type](expression) : 0; -} \ No newline at end of file