From 2bc3bc5d120aafecd3cf1df4e22e9b8b5bd23d5e Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Fri, 22 Jan 2021 16:05:51 +0100 Subject: [PATCH] Improve coverage --- src/ast/nodes/AssignmentExpression.ts | 2 +- src/ast/nodes/ForInStatement.ts | 2 +- src/ast/nodes/ForOfStatement.ts | 2 +- src/ast/nodes/MemberExpression.ts | 5 +--- src/ast/nodes/Property.ts | 7 +++-- src/ast/nodes/VariableDeclaration.ts | 12 +++----- src/ast/nodes/VariableDeclarator.ts | 5 +--- src/ast/nodes/shared/Node.ts | 42 +++++++++++++-------------- src/ast/nodes/shared/Pattern.ts | 5 ++-- 9 files changed, 36 insertions(+), 46 deletions(-) diff --git a/src/ast/nodes/AssignmentExpression.ts b/src/ast/nodes/AssignmentExpression.ts index e30ccf7aa1e..70923632523 100644 --- a/src/ast/nodes/AssignmentExpression.ts +++ b/src/ast/nodes/AssignmentExpression.ts @@ -15,7 +15,7 @@ import { ExpressionNode, IncludeChildren, NodeBase } from './shared/Node'; import { PatternNode } from './shared/Pattern'; export default class AssignmentExpression extends NodeBase { - left!: PatternNode; + left!: ExpressionNode | PatternNode; operator!: | '=' | '+=' diff --git a/src/ast/nodes/ForInStatement.ts b/src/ast/nodes/ForInStatement.ts index 6cfbc481df6..cc96fc0b590 100644 --- a/src/ast/nodes/ForInStatement.ts +++ b/src/ast/nodes/ForInStatement.ts @@ -49,7 +49,7 @@ export default class ForInStatement extends StatementBase { include(context: InclusionContext, includeChildrenRecursively: IncludeChildren) { this.included = true; - this.left.includeWithAllDeclaredVariables(context, includeChildrenRecursively); + this.left.includeAllDeclaredVariables(context, includeChildrenRecursively); this.left.deoptimizePath(EMPTY_PATH); this.right.include(context, includeChildrenRecursively); const { brokenFlow } = context; diff --git a/src/ast/nodes/ForOfStatement.ts b/src/ast/nodes/ForOfStatement.ts index 7ceee3be9c4..78bddb6eb27 100644 --- a/src/ast/nodes/ForOfStatement.ts +++ b/src/ast/nodes/ForOfStatement.ts @@ -34,7 +34,7 @@ export default class ForOfStatement extends StatementBase { include(context: InclusionContext, includeChildrenRecursively: IncludeChildren) { this.included = true; - this.left.includeWithAllDeclaredVariables(context, includeChildrenRecursively); + this.left.includeAllDeclaredVariables(context, includeChildrenRecursively); this.left.deoptimizePath(EMPTY_PATH); this.right.include(context, includeChildrenRecursively); const { brokenFlow } = context; diff --git a/src/ast/nodes/MemberExpression.ts b/src/ast/nodes/MemberExpression.ts index ba0235f5526..413d69c2a1e 100644 --- a/src/ast/nodes/MemberExpression.ts +++ b/src/ast/nodes/MemberExpression.ts @@ -23,7 +23,6 @@ import Identifier from './Identifier'; import Literal from './Literal'; import * as NodeType from './NodeType'; import { ExpressionNode, IncludeChildren, NodeBase } from './shared/Node'; -import { PatternNode } from './shared/Pattern'; import SpreadElement from './SpreadElement'; import Super from './Super'; @@ -70,7 +69,7 @@ function getStringFromPath(path: PathWithPositions): string { return pathString; } -export default class MemberExpression extends NodeBase implements DeoptimizableEntity, PatternNode { +export default class MemberExpression extends NodeBase implements DeoptimizableEntity { computed!: boolean; object!: ExpressionNode | Super; optional!: boolean; @@ -84,8 +83,6 @@ export default class MemberExpression extends NodeBase implements DeoptimizableE private replacement: string | null = null; private wasPathDeoptimizedWhileOptimized = false; - addExportedVariables(): void {} - bind() { if (this.bound) return; this.bound = true; diff --git a/src/ast/nodes/Property.ts b/src/ast/nodes/Property.ts index 0f346060022..a6f7e2c4a5c 100644 --- a/src/ast/nodes/Property.ts +++ b/src/ast/nodes/Property.ts @@ -14,15 +14,16 @@ import { LiteralValueOrUnknown, UNKNOWN_EXPRESSION } from '../values'; import * as NodeType from './NodeType'; import { ExpressionEntity } from './shared/Expression'; import { ExpressionNode, NodeBase } from './shared/Node'; +import { PatternNode } from './shared/Pattern'; -export default class Property extends NodeBase implements DeoptimizableEntity { +export default class Property extends NodeBase implements DeoptimizableEntity, PatternNode { computed!: boolean; key!: ExpressionNode; kind!: 'init' | 'get' | 'set'; method!: boolean; shorthand!: boolean; type!: NodeType.tProperty; - value!: ExpressionNode; + value!: ExpressionNode | (ExpressionNode & PatternNode); private accessorCallOptions!: CallOptions; private declarationInit: ExpressionEntity | null = null; @@ -41,7 +42,7 @@ export default class Property extends NodeBase implements DeoptimizableEntity { declare(kind: string, init: ExpressionEntity) { this.declarationInit = init; - return this.value.declare(kind, UNKNOWN_EXPRESSION); + return (this.value as PatternNode).declare(kind, UNKNOWN_EXPRESSION); } // As getter properties directly receive their values from function expressions that always diff --git a/src/ast/nodes/VariableDeclaration.ts b/src/ast/nodes/VariableDeclaration.ts index 176a4bace79..1e6f7a9a6b6 100644 --- a/src/ast/nodes/VariableDeclaration.ts +++ b/src/ast/nodes/VariableDeclaration.ts @@ -68,14 +68,14 @@ export default class VariableDeclaration extends NodeBase { } } - includeWithAllDeclaredVariables( + includeAllDeclaredVariables( context: InclusionContext, includeChildrenRecursively: IncludeChildren ): void { this.included = true; for (const declarator of this.declarations) { declarator.id.included = true; - declarator.includeWithAllDeclaredVariables(context, includeChildrenRecursively); + declarator.includeAllDeclaredVariables(context, includeChildrenRecursively); } } @@ -109,16 +109,13 @@ export default class VariableDeclaration extends NodeBase { lastSeparatorPos: number | null, actualContentEnd: number, renderedContentEnd: number, - addSemicolon: boolean, systemPatternExports: Variable[], options: RenderOptions ): void { if (code.original.charCodeAt(this.end - 1) === 59 /*";"*/) { code.remove(this.end - 1, this.end); } - if (addSemicolon) { - separatorString += ';'; - } + separatorString += ';'; if (lastSeparatorPos !== null) { if ( code.original.charCodeAt(actualContentEnd - 1) === 10 /*"\n"*/ && @@ -150,7 +147,7 @@ export default class VariableDeclaration extends NodeBase { private renderReplacedDeclarations( code: MagicString, options: RenderOptions, - { start = this.start, end = this.end, isNoStatement }: NodeRenderOptions + { start = this.start, end = this.end }: NodeRenderOptions ): void { const separatedNodes = getCommaSeparatedNodesWithBoundaries( this.declarations, @@ -248,7 +245,6 @@ export default class VariableDeclaration extends NodeBase { lastSeparatorPos, actualContentEnd!, renderedContentEnd, - !isNoStatement, systemPatternExports, options ); diff --git a/src/ast/nodes/VariableDeclarator.ts b/src/ast/nodes/VariableDeclarator.ts index f366d6a2931..3a44d176183 100644 --- a/src/ast/nodes/VariableDeclarator.ts +++ b/src/ast/nodes/VariableDeclarator.ts @@ -39,15 +39,12 @@ export default class VariableDeclarator extends NodeBase { } } - includeWithAllDeclaredVariables( + includeAllDeclaredVariables( context: InclusionContext, includeChildrenRecursively: IncludeChildren ): void { this.included = true; this.id.include(context, includeChildrenRecursively); - if (this.init) { - this.init.include(context, includeChildrenRecursively); - } } render(code: MagicString, options: RenderOptions) { diff --git a/src/ast/nodes/shared/Node.ts b/src/ast/nodes/shared/Node.ts index 9086e1088a6..38e72ee3296 100644 --- a/src/ast/nodes/shared/Node.ts +++ b/src/ast/nodes/shared/Node.ts @@ -15,7 +15,6 @@ import { getAndCreateKeys, keys } from '../../keys'; import ChildScope from '../../scopes/ChildScope'; import { ObjectPath, PathTracker } from '../../utils/PathTracker'; import { LiteralValueOrUnknown, UnknownValue, UNKNOWN_EXPRESSION } from '../../values'; -import LocalVariable from '../../variables/LocalVariable'; import Variable from '../../variables/Variable'; import * as NodeType from '../NodeType'; import SpreadElement from '../SpreadElement'; @@ -42,16 +41,13 @@ export interface Node extends Entity { type: string; variable?: Variable | null; + addExportedVariables(variables: Variable[], exportNamesByVariable: Map): void; + /** * Called once all nodes have been initialised and the scopes have been populated. */ bind(): void; - /** - * Declare a new variable with the optional initialisation. - */ - declare(kind: string, init: ExpressionEntity | null): LocalVariable[]; - /** * Determine if this Node would have an effect on the bundle. * This is usually true for already included nodes. Exceptions are e.g. break statements @@ -72,10 +68,11 @@ export interface Node extends Entity { * declarations to only include nodes for declarators that have an effect. Necessary * for for-loops that do not use a declared loop variable. */ - includeWithAllDeclaredVariables( + includeAllDeclaredVariables( context: InclusionContext, includeChildrenRecursively: IncludeChildren ): void; + render(code: MagicString, options: RenderOptions, nodeRenderOptions?: NodeRenderOptions): void; /** @@ -118,6 +115,11 @@ export class NodeBase implements ExpressionNode { this.context.magicString.addSourcemapLocation(this.end); } + addExportedVariables( + _variables: Variable[], + _exportNamesByVariable: Map + ): void {} + /** * Override this to bind assignments to variables and do any initialisations that * require the scopes to be populated with variables. @@ -143,10 +145,6 @@ export class NodeBase implements ExpressionNode { this.scope = parentScope; } - declare(_kind: string, _init: ExpressionEntity | null): LocalVariable[] { - return []; - } - deoptimizePath(_path: ObjectPath) {} getLiteralValueAtPath( @@ -209,19 +207,19 @@ export class NodeBase implements ExpressionNode { } } - includeCallArguments(context: InclusionContext, args: (ExpressionNode | SpreadElement)[]): void { - for (const arg of args) { - arg.include(context, false); - } - } - - includeWithAllDeclaredVariables( + includeAllDeclaredVariables( context: InclusionContext, includeChildrenRecursively: IncludeChildren ): void { this.include(context, includeChildrenRecursively); } + includeCallArguments(context: InclusionContext, args: (ExpressionNode | SpreadElement)[]): void { + for (const arg of args) { + arg.include(context, false); + } + } + /** * Override to perform special initialisation steps after the scope is initialised */ @@ -274,10 +272,6 @@ export class NodeBase implements ExpressionNode { shouldBeIncluded(context: InclusionContext): boolean { return this.included || (!context.brokenFlow && this.hasEffects(createHasEffectsContext())); } - - toString() { - return this.context.code.slice(this.start, this.end); - } } export { NodeBase as StatementBase }; @@ -290,3 +284,7 @@ export function locateNode(node: Node) { return location; } + +export function logNode(node: Node) { + console.log(node.context.code.slice(node.start, node.end)); +} diff --git a/src/ast/nodes/shared/Pattern.ts b/src/ast/nodes/shared/Pattern.ts index a0015cb185e..ccca00c9e01 100644 --- a/src/ast/nodes/shared/Pattern.ts +++ b/src/ast/nodes/shared/Pattern.ts @@ -1,7 +1,8 @@ import { WritableEntity } from '../../Entity'; -import Variable from '../../variables/Variable'; +import LocalVariable from '../../variables/LocalVariable'; +import { ExpressionEntity } from './Expression'; import { Node } from './Node'; export interface PatternNode extends WritableEntity, Node { - addExportedVariables(variables: Variable[], exportNamesByVariable: Map): void; + declare(kind: string, init: ExpressionEntity | null): LocalVariable[]; }