From c3b76f784867e6f5ac96cccdef6838c2d65f7805 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 25 Mar 2021 15:35:44 +0100 Subject: [PATCH] Move logic from ClassBody into ClassNode So that it sits in one place and is easier to extend. --- src/ast/nodes/ClassBody.ts | 27 --------------------------- src/ast/nodes/shared/ClassNode.ts | 21 +++++++++++++++------ 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/src/ast/nodes/ClassBody.ts b/src/ast/nodes/ClassBody.ts index 0dc6efa32a5..cd0d21c907e 100644 --- a/src/ast/nodes/ClassBody.ts +++ b/src/ast/nodes/ClassBody.ts @@ -1,8 +1,5 @@ -import { CallOptions } from '../CallOptions'; -import { HasEffectsContext } from '../ExecutionContext'; import ClassBodyScope from '../scopes/ClassBodyScope'; import Scope from '../scopes/Scope'; -import { EMPTY_PATH, ObjectPath } from '../utils/PathTracker'; import MethodDefinition from './MethodDefinition'; import * as NodeType from './NodeType'; import PropertyDefinition from './PropertyDefinition'; @@ -12,31 +9,7 @@ export default class ClassBody extends NodeBase { body!: (MethodDefinition | PropertyDefinition)[]; type!: NodeType.tClassBody; - private classConstructor!: MethodDefinition | null; - createScope(parentScope: Scope) { this.scope = new ClassBodyScope(parentScope); } - - hasEffectsWhenCalledAtPath( - path: ObjectPath, - callOptions: CallOptions, - context: HasEffectsContext - ) { - if (path.length > 0) return true; - return ( - this.classConstructor !== null && - this.classConstructor.hasEffectsWhenCalledAtPath(EMPTY_PATH, callOptions, context) - ); - } - - initialise() { - for (const method of this.body) { - if (method instanceof MethodDefinition && method.kind === 'constructor') { - this.classConstructor = method; - return; - } - } - this.classConstructor = null; - } } diff --git a/src/ast/nodes/shared/ClassNode.ts b/src/ast/nodes/shared/ClassNode.ts index 4323d8c789f..c6fe89cc24d 100644 --- a/src/ast/nodes/shared/ClassNode.ts +++ b/src/ast/nodes/shared/ClassNode.ts @@ -2,15 +2,17 @@ import { CallOptions } from '../../CallOptions'; import { HasEffectsContext } from '../../ExecutionContext'; import ChildScope from '../../scopes/ChildScope'; import Scope from '../../scopes/Scope'; -import { ObjectPath } from '../../utils/PathTracker'; +import { EMPTY_PATH, ObjectPath } from '../../utils/PathTracker'; import ClassBody from '../ClassBody'; import Identifier from '../Identifier'; +import MethodDefinition from '../MethodDefinition'; import { ExpressionNode, NodeBase } from './Node'; export default class ClassNode extends NodeBase { body!: ClassBody; id!: Identifier | null; superClass!: ExpressionNode | null; + private classConstructor!: MethodDefinition | null; createScope(parentScope: Scope) { this.scope = new ChildScope(parentScope); @@ -31,17 +33,24 @@ export default class ClassNode extends NodeBase { callOptions: CallOptions, context: HasEffectsContext ) { - if (!callOptions.withNew) return true; - return ( - this.body.hasEffectsWhenCalledAtPath(path, callOptions, context) || + return !callOptions.withNew || + path.length > 0 || + (this.classConstructor !== null && + this.classConstructor.hasEffectsWhenCalledAtPath(EMPTY_PATH, callOptions, context)) || (this.superClass !== null && - this.superClass.hasEffectsWhenCalledAtPath(path, callOptions, context)) - ); + this.superClass.hasEffectsWhenCalledAtPath(path, callOptions, context)); } initialise() { if (this.id !== null) { this.id.declare('class', this); } + for (const method of this.body.body) { + if (method instanceof MethodDefinition && method.kind === 'constructor') { + this.classConstructor = method; + return; + } + } + this.classConstructor = null; } }