Skip to content

Commit

Permalink
Simplify ObjectEntity effect handling
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Jun 6, 2022
1 parent 6ac1e91 commit 2deea79
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 112 deletions.
1 change: 0 additions & 1 deletion src/ast/nodes/MemberExpression.ts
Expand Up @@ -88,7 +88,6 @@ function getStringFromPath(path: PathWithPositions): string {
return pathString;
}

// TODO Lukas if we check each access separately, we do not need to check getters when accessing a nested property in MethodBase, verify
export default class MemberExpression extends NodeBase implements DeoptimizableEntity {
declare computed: boolean;
declare object: ExpressionNode | Super;
Expand Down
145 changes: 34 additions & 111 deletions src/ast/nodes/shared/ObjectEntity.ts
Expand Up @@ -2,7 +2,6 @@ import { DeoptimizableEntity } from '../../DeoptimizableEntity';
import { HasEffectsContext } from '../../ExecutionContext';
import {
INTERACTION_ACCESSED,
INTERACTION_ASSIGNED,
INTERACTION_CALLED,
NodeInteraction,
NodeInteractionCalled,
Expand Down Expand Up @@ -255,11 +254,11 @@ export class ObjectEntity extends ExpressionEntity {
if (path.length === 0) {
return UNKNOWN_EXPRESSION;
}
const key = path[0];
const [key, ...subPath] = path;
const expressionAtPath = this.getMemberExpressionAndTrackDeopt(key, origin);
if (expressionAtPath) {
return expressionAtPath.getReturnExpressionWhenCalledAtPath(
path.slice(1),
subPath,
interaction,
recursionTracker,
origin
Expand All @@ -276,130 +275,54 @@ export class ObjectEntity extends ExpressionEntity {
return UNKNOWN_EXPRESSION;
}

// TODO Lukas simplify
hasEffectsOnInteractionAtPath(
path: ObjectPath,
interaction: NodeInteraction,
context: HasEffectsContext
): boolean {
const [key, ...subPath] = path;
switch (interaction.type) {
case INTERACTION_CALLED: {
const expressionAtPath = this.getMemberExpression(key);
if (expressionAtPath) {
return expressionAtPath.hasEffectsOnInteractionAtPath(
path.slice(1),
interaction,
context
);
}
if (this.prototypeExpression) {
return this.prototypeExpression.hasEffectsOnInteractionAtPath(path, interaction, context);
}
return true;
if (subPath.length || interaction.type === INTERACTION_CALLED) {
const expressionAtPath = this.getMemberExpression(key);
if (expressionAtPath) {
return expressionAtPath.hasEffectsOnInteractionAtPath(subPath, interaction, context);
}
case INTERACTION_ACCESSED: {
if (path.length > 1) {
if (typeof key !== 'string') {
return true;
}
const expressionAtPath = this.getMemberExpression(key);
if (expressionAtPath) {
return expressionAtPath.hasEffectsOnInteractionAtPath(subPath, interaction, context);
}
if (this.prototypeExpression) {
return this.prototypeExpression.hasEffectsOnInteractionAtPath(
path,
interaction,
context
);
}
return true;
}

if (this.hasLostTrack) return true;
if (typeof key === 'string') {
if (this.propertiesAndGettersByKey[key]) {
const getters = this.gettersByKey[key];
if (getters) {
for (const getter of getters) {
if (getter.hasEffectsOnInteractionAtPath(subPath, interaction, context))
return true;
}
}
return false;
}
for (const getter of this.unmatchableGetters) {
if (getter.hasEffectsOnInteractionAtPath(subPath, interaction, context)) {
return true;
}
}
} else {
for (const getters of Object.values(this.gettersByKey).concat([
this.unmatchableGetters
])) {
for (const getter of getters) {
if (getter.hasEffectsOnInteractionAtPath(subPath, interaction, context)) return true;
}
if (this.prototypeExpression) {
return this.prototypeExpression.hasEffectsOnInteractionAtPath(path, interaction, context);
}
return true;
}
if (key === UnknownNonAccessorKey) return false;
if (this.hasLostTrack) return true;
const [propertiesAndAccessorsByKey, accessorsByKey, unmatchableAccessors] =
interaction.type === INTERACTION_ACCESSED
? [this.propertiesAndGettersByKey, this.gettersByKey, this.unmatchableGetters]
: [this.propertiesAndSettersByKey, this.settersByKey, this.unmatchableSetters];
if (typeof key === 'string') {
if (propertiesAndAccessorsByKey[key]) {
const accessors = accessorsByKey[key];
if (accessors) {
for (const accessor of accessors) {
if (accessor.hasEffectsOnInteractionAtPath(subPath, interaction, context)) return true;
}
}
if (this.prototypeExpression) {
return this.prototypeExpression.hasEffectsOnInteractionAtPath(path, interaction, context);
}
return false;
}
case INTERACTION_ASSIGNED: {
if (path.length > 1) {
if (typeof key !== 'string') {
return true;
}
const expressionAtPath = this.getMemberExpression(key);
if (expressionAtPath) {
return expressionAtPath.hasEffectsOnInteractionAtPath(subPath, interaction, context);
}
if (this.prototypeExpression) {
return this.prototypeExpression.hasEffectsOnInteractionAtPath(
path,
interaction,
context
);
}
for (const accessor of unmatchableAccessors) {
if (accessor.hasEffectsOnInteractionAtPath(subPath, interaction, context)) {
return true;
}

if (key === UnknownNonAccessorKey) return false;
if (this.hasLostTrack) return true;
if (typeof key === 'string') {
if (this.propertiesAndSettersByKey[key]) {
const setters = this.settersByKey[key];
if (setters) {
for (const setter of setters) {
if (setter.hasEffectsOnInteractionAtPath(subPath, interaction, context))
return true;
}
}
return false;
}
for (const property of this.unmatchableSetters) {
if (property.hasEffectsOnInteractionAtPath(subPath, interaction, context)) {
return true;
}
}
} else {
for (const setters of Object.values(this.settersByKey).concat([
this.unmatchableSetters
])) {
for (const setter of setters) {
if (setter.hasEffectsOnInteractionAtPath(subPath, interaction, context)) return true;
}
}
}
if (this.prototypeExpression) {
return this.prototypeExpression.hasEffectsOnInteractionAtPath(path, interaction, context);
}
} else {
for (const accessors of Object.values(accessorsByKey).concat([unmatchableAccessors])) {
for (const accessor of accessors) {
if (accessor.hasEffectsOnInteractionAtPath(subPath, interaction, context)) return true;
}
return false;
}
}
if (this.prototypeExpression) {
return this.prototypeExpression.hasEffectsOnInteractionAtPath(path, interaction, context);
}
return false;
}

private buildPropertyMaps(properties: readonly ObjectProperty[]): void {
Expand Down

0 comments on commit 2deea79

Please sign in to comment.