feat(ivy): support array and object literals in binding expressions (#22336)
PR Close #22336
This commit is contained in:

committed by
Alex Eagle

parent
ec445b5c73
commit
49f074f61d
@ -144,6 +144,11 @@ export abstract class Expression {
|
||||
*/
|
||||
abstract isEquivalent(e: Expression): boolean;
|
||||
|
||||
/**
|
||||
* Return true if the expression is constant.
|
||||
*/
|
||||
abstract isConstant(): boolean;
|
||||
|
||||
prop(name: string, sourceSpan?: ParseSourceSpan|null): ReadPropExpr {
|
||||
return new ReadPropExpr(this, name, null, sourceSpan);
|
||||
}
|
||||
@ -250,10 +255,13 @@ export class ReadVarExpr extends Expression {
|
||||
this.builtin = <BuiltinVar>name;
|
||||
}
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof ReadVarExpr && this.name === e.name && this.builtin === e.builtin;
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitReadVarExpr(this, context);
|
||||
}
|
||||
@ -274,10 +282,13 @@ export class WriteVarExpr extends Expression {
|
||||
super(type || value.type, sourceSpan);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof WriteVarExpr && this.name === e.name && this.value.isEquivalent(e.value);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitWriteVarExpr(this, context);
|
||||
}
|
||||
@ -296,10 +307,14 @@ export class WriteKeyExpr extends Expression {
|
||||
super(type || value.type, sourceSpan);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof WriteKeyExpr && this.receiver.isEquivalent(e.receiver) &&
|
||||
this.index.isEquivalent(e.index) && this.value.isEquivalent(e.value);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitWriteKeyExpr(this, context);
|
||||
}
|
||||
@ -314,10 +329,14 @@ export class WritePropExpr extends Expression {
|
||||
super(type || value.type, sourceSpan);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof WritePropExpr && this.receiver.isEquivalent(e.receiver) &&
|
||||
this.name === e.name && this.value.isEquivalent(e.value);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitWritePropExpr(this, context);
|
||||
}
|
||||
@ -344,10 +363,14 @@ export class InvokeMethodExpr extends Expression {
|
||||
this.builtin = <BuiltinMethod>method;
|
||||
}
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof InvokeMethodExpr && this.receiver.isEquivalent(e.receiver) &&
|
||||
this.name === e.name && this.builtin === e.builtin && areAllEquivalent(this.args, e.args);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitInvokeMethodExpr(this, context);
|
||||
}
|
||||
@ -360,10 +383,14 @@ export class InvokeFunctionExpr extends Expression {
|
||||
sourceSpan?: ParseSourceSpan|null) {
|
||||
super(type, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof InvokeFunctionExpr && this.fn.isEquivalent(e.fn) &&
|
||||
areAllEquivalent(this.args, e.args);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitInvokeFunctionExpr(this, context);
|
||||
}
|
||||
@ -376,10 +403,14 @@ export class InstantiateExpr extends Expression {
|
||||
sourceSpan?: ParseSourceSpan|null) {
|
||||
super(type, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof InstantiateExpr && this.classExpr.isEquivalent(e.classExpr) &&
|
||||
areAllEquivalent(this.args, e.args);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitInstantiateExpr(this, context);
|
||||
}
|
||||
@ -392,9 +423,13 @@ export class LiteralExpr extends Expression {
|
||||
sourceSpan?: ParseSourceSpan|null) {
|
||||
super(type, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof LiteralExpr && this.value === e.value;
|
||||
}
|
||||
|
||||
isConstant() { return true; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitLiteralExpr(this, context);
|
||||
}
|
||||
@ -407,10 +442,14 @@ export class ExternalExpr extends Expression {
|
||||
sourceSpan?: ParseSourceSpan|null) {
|
||||
super(type, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof ExternalExpr && this.value.name === e.value.name &&
|
||||
this.value.moduleName === e.value.moduleName && this.value.runtime === e.value.runtime;
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitExternalExpr(this, context);
|
||||
}
|
||||
@ -424,16 +463,21 @@ export class ExternalReference {
|
||||
|
||||
export class ConditionalExpr extends Expression {
|
||||
public trueCase: Expression;
|
||||
|
||||
constructor(
|
||||
public condition: Expression, trueCase: Expression, public falseCase: Expression|null = null,
|
||||
type?: Type|null, sourceSpan?: ParseSourceSpan|null) {
|
||||
super(type || trueCase.type, sourceSpan);
|
||||
this.trueCase = trueCase;
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof ConditionalExpr && this.condition.isEquivalent(e.condition) &&
|
||||
this.trueCase.isEquivalent(e.trueCase) && nullSafeIsEquivalent(this.falseCase, e.falseCase);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitConditionalExpr(this, context);
|
||||
}
|
||||
@ -444,9 +488,13 @@ export class NotExpr extends Expression {
|
||||
constructor(public condition: Expression, sourceSpan?: ParseSourceSpan|null) {
|
||||
super(BOOL_TYPE, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof NotExpr && this.condition.isEquivalent(e.condition);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitNotExpr(this, context);
|
||||
}
|
||||
@ -456,9 +504,13 @@ export class AssertNotNull extends Expression {
|
||||
constructor(public condition: Expression, sourceSpan?: ParseSourceSpan|null) {
|
||||
super(condition.type, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof AssertNotNull && this.condition.isEquivalent(e.condition);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitAssertNotNullExpr(this, context);
|
||||
}
|
||||
@ -468,9 +520,13 @@ export class CastExpr extends Expression {
|
||||
constructor(public value: Expression, type?: Type|null, sourceSpan?: ParseSourceSpan|null) {
|
||||
super(type, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof CastExpr && this.value.isEquivalent(e.value);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitCastExpr(this, context);
|
||||
}
|
||||
@ -490,10 +546,14 @@ export class FunctionExpr extends Expression {
|
||||
sourceSpan?: ParseSourceSpan|null, public name?: string|null) {
|
||||
super(type, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof FunctionExpr && areAllEquivalent(this.params, e.params) &&
|
||||
areAllEquivalent(this.statements, e.statements);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitFunctionExpr(this, context);
|
||||
}
|
||||
@ -513,10 +573,14 @@ export class BinaryOperatorExpr extends Expression {
|
||||
super(type || lhs.type, sourceSpan);
|
||||
this.lhs = lhs;
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof BinaryOperatorExpr && this.operator === e.operator &&
|
||||
this.lhs.isEquivalent(e.lhs) && this.rhs.isEquivalent(e.rhs);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitBinaryOperatorExpr(this, context);
|
||||
}
|
||||
@ -529,13 +593,18 @@ export class ReadPropExpr extends Expression {
|
||||
sourceSpan?: ParseSourceSpan|null) {
|
||||
super(type, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof ReadPropExpr && this.receiver.isEquivalent(e.receiver) &&
|
||||
this.name === e.name;
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitReadPropExpr(this, context);
|
||||
}
|
||||
|
||||
set(value: Expression): WritePropExpr {
|
||||
return new WritePropExpr(this.receiver, this.name, value, null, this.sourceSpan);
|
||||
}
|
||||
@ -548,13 +617,18 @@ export class ReadKeyExpr extends Expression {
|
||||
sourceSpan?: ParseSourceSpan|null) {
|
||||
super(type, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof ReadKeyExpr && this.receiver.isEquivalent(e.receiver) &&
|
||||
this.index.isEquivalent(e.index);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitReadKeyExpr(this, context);
|
||||
}
|
||||
|
||||
set(value: Expression): WriteKeyExpr {
|
||||
return new WriteKeyExpr(this.receiver, this.index, value, null, this.sourceSpan);
|
||||
}
|
||||
@ -567,6 +641,9 @@ export class LiteralArrayExpr extends Expression {
|
||||
super(type, sourceSpan);
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
isConstant() { return this.entries.every(e => e.isConstant()); }
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof LiteralArrayExpr && areAllEquivalent(this.entries, e.entries);
|
||||
}
|
||||
@ -591,9 +668,13 @@ export class LiteralMapExpr extends Expression {
|
||||
this.valueType = type.valueType;
|
||||
}
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof LiteralMapExpr && areAllEquivalent(this.entries, e.entries);
|
||||
}
|
||||
|
||||
isConstant() { return this.entries.every(e => e.value.isConstant()); }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitLiteralMapExpr(this, context);
|
||||
}
|
||||
@ -603,9 +684,13 @@ export class CommaExpr extends Expression {
|
||||
constructor(public parts: Expression[], sourceSpan?: ParseSourceSpan|null) {
|
||||
super(parts[parts.length - 1].type, sourceSpan);
|
||||
}
|
||||
|
||||
isEquivalent(e: Expression): boolean {
|
||||
return e instanceof CommaExpr && areAllEquivalent(this.parts, e.parts);
|
||||
}
|
||||
|
||||
isConstant() { return false; }
|
||||
|
||||
visitExpression(visitor: ExpressionVisitor, context: any): any {
|
||||
return visitor.visitCommaExpr(this, context);
|
||||
}
|
||||
|
Reference in New Issue
Block a user