Index: pkg/compiler/lib/src/resolution/semantic_visitor.dart |
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor.dart b/pkg/compiler/lib/src/resolution/semantic_visitor.dart |
index 8ed55d3d2046f92af7f59fb535e4f5a71ce83771..6ef3a4bbf21363ea60a27fb7ffc2b1e6c375a48b 100644 |
--- a/pkg/compiler/lib/src/resolution/semantic_visitor.dart |
+++ b/pkg/compiler/lib/src/resolution/semantic_visitor.dart |
@@ -2189,6 +2189,705 @@ abstract class SemanticSendVisitor<R, A> { |
Node rhs, |
A arg); |
+ /// If-null assignment expression of [rhs] to the [name] property on |
+ /// [receiver]. That is, [rhs] is only evaluated and assigned, if the value |
+ /// of [name] on [receiver] is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// m(receiver, rhs) => receiver.foo ??= rhs; |
+ /// |
+ R visitDynamicPropertySetIfNull( |
+ Send node, |
+ Node receiver, |
+ Name name, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the [name] property on |
+ /// [receiver] if not null. That is, [rhs] is only evaluated and assigned, |
+ /// if the value of [receiver] is _not_ `null` and the value of [name] on |
+ /// [receiver] is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// m(receiver, rhs) => receiver?.foo ??= rhs; |
+ /// |
+ R visitIfNotNullDynamicPropertySetIfNull( |
+ Send node, |
+ Node receiver, |
+ Name name, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the [name] property on `this`. |
+ /// That is, [rhs] is only evaluated and assigned, if the value of [name] on |
+ /// `this` is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class C { |
+ /// m(rhs) => this.foo ??= rhs; |
+ /// } |
+ /// |
+ /// or |
+ /// |
+ /// class C { |
+ /// m(rhs) => foo ??= rhs; |
+ /// } |
+ /// |
+ R visitThisPropertySetIfNull( |
+ Send node, |
+ Name name, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to [parameter]. That is, [rhs] is |
+ /// only evaluated and assigned, if the value of the [parameter] is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// m(parameter, rhs) => parameter ??= rhs; |
+ /// |
+ R visitParameterSetIfNull( |
+ Send node, |
+ ParameterElement parameter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the final [parameter]. That is, |
+ /// [rhs] is only evaluated and assigned, if the value of the [parameter] is |
+ /// `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// m(final parameter, rhs) => parameter ??= rhs; |
+ /// |
+ R visitFinalParameterSetIfNull( |
+ Send node, |
+ ParameterElement parameter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the local [variable]. That is, |
+ /// [rhs] is only evaluated and assigned, if the value of the [variable] is |
+ /// `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// m(rhs) { |
+ /// var variable; |
+ /// variable ??= rhs; |
+ /// } |
+ /// |
+ R visitLocalVariableSetIfNull( |
+ Send node, |
+ LocalVariableElement variable, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the final local [variable]. That |
+ /// is, [rhs] is only evaluated and assigned, if the value of the [variable] |
+ /// is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// m(rhs) { |
+ /// final variable = 0; |
+ /// variable ??= rhs; |
+ /// } |
+ /// |
+ R visitFinalLocalVariableSetIfNull( |
+ Send node, |
+ LocalVariableElement variable, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the local [function]. That is, |
+ /// [rhs] is only evaluated and assigned, if the value of the [function] is |
+ /// `null`. The behavior is thus equivalent to a closurization of [function]. |
+ /// |
+ /// For instance: |
+ /// |
+ /// m(rhs) { |
+ /// function() {} |
+ /// function ??= rhs; |
+ /// } |
+ /// |
+ R visitLocalFunctionSetIfNull( |
+ Send node, |
+ LocalFunctionElement function, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the static [field]. That is, |
+ /// [rhs] is only evaluated and assigned, if the value of the [field] is |
+ /// `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class C { |
+ /// static var field; |
+ /// m(rhs) => field ??= rhs; |
+ /// } |
+ /// |
+ R visitStaticFieldSetIfNull( |
+ Send node, |
+ FieldElement field, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the final static [field]. That |
+ /// is, [rhs] is only evaluated and assigned, if the value of the [field] is |
+ /// `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class C { |
+ /// static final field = 0; |
+ /// m(rhs) => field ??= rhs; |
+ /// } |
+ /// |
+ R visitFinalStaticFieldSetIfNull( |
+ Send node, |
+ FieldElement field, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the static property defined by |
+ /// [getter] and [setter]. That is, [rhs] is only evaluated and assigned to |
+ /// the [setter], if the value of the [getter] is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class C { |
+ /// static get o => 0; |
+ /// static set o(_) {} |
+ /// m(rhs) => o ??= rhs; |
+ /// } |
+ /// |
+ R visitStaticGetterSetterSetIfNull( |
+ Send node, |
+ FunctionElement getter, |
+ FunctionElement setter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the static property defined by |
+ /// [method] and [setter]. That is, [rhs] is only evaluated and assigned to |
+ /// the [setter], if the value of the [method] is `null`. The behavior is thus |
+ /// equivalent to a closurization of [method]. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class C { |
+ /// static o() {} |
+ /// static set o(_) {} |
+ /// m(rhs) => o ??= rhs; |
+ /// } |
+ /// |
+ R visitStaticMethodSetterSetIfNull( |
+ Send node, |
+ MethodElement method, |
+ MethodElement setter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the static [method]. That is, |
+ /// [rhs] is only evaluated and assigned, if the value of the [method] is |
+ /// `null`. The behavior is thus equivalent to a closurization of [method]. |
+ /// |
+ /// For instance: |
+ /// |
+ /// o() {} |
+ /// m(rhs) => o ??= rhs; |
+ /// |
+ R visitStaticMethodSetIfNull( |
+ Send node, |
+ FunctionElement method, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the top level [field]. That is, |
+ /// [rhs] is only evaluated and assigned, if the value of the [field] is |
+ /// `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// var field; |
+ /// m(rhs) => field ??= rhs; |
+ /// |
+ R visitTopLevelFieldSetIfNull( |
+ Send node, |
+ FieldElement field, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the final top level [field]. |
+ /// That is, [rhs] is only evaluated and assigned, if the value of the [field] |
+ /// is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// final field = 0; |
+ /// m(rhs) => field ??= rhs; |
+ /// |
+ R visitFinalTopLevelFieldSetIfNull( |
+ Send node, |
+ FieldElement field, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the top level property defined |
+ /// by [getter] and [setter]. That is, [rhs] is only evaluated and assigned to |
+ /// the [setter], if the value of the [getter] is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// get o => 0; |
+ /// set o(_) {} |
+ /// m(rhs) => o ??= rhs; |
+ /// |
+ R visitTopLevelGetterSetterSetIfNull( |
+ Send node, |
+ FunctionElement getter, |
+ FunctionElement setter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the top level property defined |
+ /// by [method] and [setter]. That is, [rhs] is only evaluated and assigned to |
+ /// the [setter], if the value of the [method] is `null`. The behavior is thus |
+ /// equivalent to a closurization of [method]. |
+ /// |
+ /// For instance: |
+ /// |
+ /// o() {} |
+ /// set o(_) {} |
+ /// m(rhs) => o ??= rhs; |
+ /// |
+ R visitTopLevelMethodSetterSetIfNull( |
+ Send node, |
+ FunctionElement method, |
+ FunctionElement setter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the top level [method]. That is, |
+ /// [rhs] is only evaluated and assigned, if the value of the [method] is |
+ /// `null`. The behavior is thus equivalent to a closurization of [method]. |
+ /// |
+ /// For instance: |
+ /// |
+ /// o() {} |
+ /// m(rhs) => o ??= rhs; |
+ /// |
+ R visitTopLevelMethodSetIfNull( |
+ Send node, |
+ FunctionElement method, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the super [field]. That is, |
+ /// [rhs] is only evaluated and assigned, if the value of the [field] is |
+ /// `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class B { |
+ /// var field; |
+ /// } |
+ /// class C extends B { |
+ /// m(rhs) => super.field ??= rhs; |
+ /// } |
+ /// |
+ R visitSuperFieldSetIfNull( |
+ Send node, |
+ FieldElement field, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the final super [field]. That |
+ /// is, [rhs] is only evaluated and assigned, if the value of the [field] is |
+ /// `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class B { |
+ /// final field = 42; |
+ /// } |
+ /// class C extends B { |
+ /// m(rhs) => super.field ??= rhs; |
+ /// } |
+ /// |
+ R visitFinalSuperFieldSetIfNull( |
+ Send node, |
+ FieldElement field, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the super property defined |
+ /// by [readField] and [writtenField]. That is, [rhs] is only evaluated and |
+ /// assigned to the [writtenField], if the value of the [readField] is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class A { |
+ /// var field; |
+ /// } |
+ /// class B extends A { |
+ /// final field; |
+ /// } |
+ /// class C extends B { |
+ /// m() => super.field ??= rhs; |
+ /// } |
+ /// |
+ R visitSuperFieldFieldSetIfNull( |
+ Send node, |
+ FieldElement readField, |
+ FieldElement writtenField, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the super property defined |
+ /// by [getter] and [setter]. That is, [rhs] is only evaluated and assigned to |
+ /// the [setter], if the value of the [getter] is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class B { |
+ /// get o => 0; |
+ /// set o(_) {} |
+ /// } |
+ /// class C extends B { |
+ /// m(rhs) => super.o ??= rhs; |
+ /// } |
+ /// |
+ R visitSuperGetterSetterSetIfNull( |
+ Send node, |
+ FunctionElement getter, |
+ FunctionElement setter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the super property defined |
+ /// by [method] and [setter]. That is, [rhs] is only evaluated and assigned to |
+ /// the [setter], if the value of the [method] is `null`. The behavior is thus |
+ /// equivalent to a closurization of [method]. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class B { |
+ /// o() {} |
+ /// set o(_) {} |
+ /// } |
+ /// class C extends B { |
+ /// m(rhs) => super.o ??= rhs; |
+ /// } |
+ /// |
+ R visitSuperMethodSetterSetIfNull( |
+ Send node, |
+ FunctionElement method, |
+ FunctionElement setter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the super [method]. |
+ /// That is, [rhs] is only evaluated and assigned, if the value of |
+ /// the [method] is `null`. The behavior is thus equivalent to a closurization |
+ /// of [method]. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class B { |
+ /// o() {} |
+ /// } |
+ /// class C extends B { |
+ /// m(rhs) => super.o ??= rhs; |
+ /// } |
+ /// |
+ R visitSuperMethodSetIfNull( |
+ Send node, |
+ FunctionElement method, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the super property defined |
+ /// by [setter] with no corresponding getter. That is, [rhs] is only evaluated |
+ /// and assigned to the [setter], if the value of the unresolved getter is |
+ /// `null`. The behavior is thus equivalent to a no such method error. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class B { |
+ /// set o(_) {} |
+ /// } |
+ /// class C extends B { |
+ /// m(rhs) => super.o ??= rhs; |
+ /// } |
+ /// |
+ R visitUnresolvedSuperGetterSetIfNull( |
+ Send node, |
+ Element element, |
+ MethodElement setter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the super property defined |
+ /// by [getter] with no corresponding setter. That is, [rhs] is only evaluated |
+ /// and assigned to the unresolved setter, if the value of the [getter] is |
+ /// `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class B { |
+ /// get o => 42; |
+ /// } |
+ /// class C extends B { |
+ /// m(rhs) => super.o ??= rhs; |
+ /// } |
+ /// |
+ R visitUnresolvedSuperSetterSetIfNull( |
+ Send node, |
+ MethodElement getter, |
+ Element element, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the top level property defined |
+ /// by [field] and [setter]. That is, [rhs] is only evaluated and assigned to |
+ /// the [setter], if the value of the [field] is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class A { |
+ /// var o; |
+ /// } |
+ /// class B extends A { |
+ /// set o(_) {} |
+ /// } |
+ /// class C extends B { |
+ /// m(rhs) => super.o ??= rhs; |
+ /// } |
+ /// |
+ R visitSuperFieldSetterSetIfNull( |
+ Send node, |
+ FieldElement field, |
+ FunctionElement setter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the top level property defined |
+ /// by [getter] and [field]. That is, [rhs] is only evaluated and assigned to |
+ /// the [field], if the value of the [getter] is `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class A { |
+ /// var o; |
+ /// } |
+ /// class B extends A { |
+ /// get o => 0; |
+ /// } |
+ /// class C extends B { |
+ /// m(rhs) => super.o ??= rhs; |
+ /// } |
+ /// |
+ R visitSuperGetterFieldSetIfNull( |
+ Send node, |
+ FunctionElement getter, |
+ FieldElement field, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to an unresolved super property. |
+ /// That is, [rhs] is only evaluated and assigned, if the value of the |
+ /// unresolved property is `null`. The behavior is thus equivalent to a no |
+ /// such method error. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class B { |
+ /// } |
+ /// class C extends B { |
+ /// m(rhs) => super.unresolved ??= rhs; |
+ /// } |
+ /// |
+ R visitUnresolvedSuperSetIfNull( |
+ Send node, |
+ Element element, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the static property defined |
+ /// by [setter] with no corresponding getter. That is, [rhs] is only evaluated |
+ /// and assigned to the [setter], if the value of the unresolved |
+ /// getter is `null`. The behavior is thus equivalent to a no such method |
+ /// error. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class C { |
+ /// set foo(_) {} |
+ /// } |
+ /// m1() => C.foo ??= 42; |
+ /// |
+ R visitUnresolvedStaticGetterSetIfNull( |
+ Send node, |
+ Element element, |
+ MethodElement setter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the top level property defined |
+ /// by [setter] with no corresponding getter. That is, [rhs] is only evaluated |
+ /// and assigned to the [setter], if the value of the unresolved getter is |
+ /// `null`. The behavior is thus equivalent to a no such method error. |
+ /// |
+ /// For instance: |
+ /// |
+ /// set foo(_) {} |
+ /// m1() => foo ??= 42; |
+ /// |
+ R visitUnresolvedTopLevelGetterSetIfNull( |
+ Send node, |
+ Element element, |
+ MethodElement setter, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the static property defined |
+ /// by [getter] with no corresponding setter. That is, [rhs] is only evaluated |
+ /// and assigned to the unresolved setter, if the value of the [getter] is |
+ /// `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class C { |
+ /// get foo => 42; |
+ /// } |
+ /// m1() => C.foo ??= 42; |
+ /// |
+ R visitUnresolvedStaticSetterSetIfNull( |
+ Send node, |
+ MethodElement getter, |
+ Element element, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the top level property defined |
+ /// by [getter] with no corresponding setter. That is, [rhs] is only evaluated |
+ /// and assigned to the unresolved setter, if the value of the [getter] is |
+ /// `null`. |
+ /// |
+ /// For instance: |
+ /// |
+ /// get foo => 42; |
+ /// m1() => foo ??= 42; |
+ /// |
+ R visitUnresolvedTopLevelSetterSetIfNull( |
+ Send node, |
+ MethodElement getter, |
+ Element element, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to an unresolved property. |
+ /// That is, [rhs] is only evaluated and assigned, if the value of the |
+ /// unresolved property is `null`. The behavior is thus equivalent to a no |
+ /// such method error. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class C {} |
+ /// m1() => unresolved ??= 42; |
+ /// m2() => C.unresolved ??= 42; |
+ /// |
+ // TODO(johnniwinther): Split the cases in which a prefix is resolved. |
+ R visitUnresolvedSetIfNull( |
+ Send node, |
+ Element element, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to an invalid expression. |
+ /// |
+ /// For instance: |
+ /// |
+ /// import 'foo.dart' as p; |
+ /// |
+ /// m() => p ??= 42; |
+ /// |
+ R errorInvalidSetIfNull( |
+ Send node, |
+ ErroneousElement error, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the class type literal |
+ /// [contant]. That is, [rhs] is only evaluated and assigned, if the value |
+ /// is of the [constant] is `null`. The behavior is thus equivalent to a type |
+ /// literal access. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class C {} |
+ /// m(rhs) => C ??= rhs; |
+ /// |
+ R visitClassTypeLiteralSetIfNull( |
+ Send node, |
+ ConstantExpression constant, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the typedef type literal |
+ /// [constant]. That is, [rhs] is only evaluated and assigned, if the value |
+ /// is of the [constant] is `null`. The behavior is thus equivalent to a type |
+ /// literal access. |
+ /// |
+ /// For instance: |
+ /// |
+ /// typedef F(); |
+ /// m(rhs) => F ??= rhs; |
+ /// |
+ R visitTypedefTypeLiteralSetIfNull( |
+ Send node, |
+ ConstantExpression constant, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the type literal for the type |
+ /// variable [element]. That is, [rhs] is only evaluated and assigned, if |
+ /// the value is of the [element] is `null`. The behavior is thus equivalent to |
+ /// a type literal access. |
+ /// |
+ /// For instance: |
+ /// |
+ /// class C<T> { |
+ /// m(rhs) => T ??= rhs; |
+ /// } |
+ /// |
+ R visitTypeVariableTypeLiteralSetIfNull( |
+ Send node, |
+ TypeVariableElement element, |
+ Node rhs, |
+ A arg); |
+ |
+ /// If-null assignment expression of [rhs] to the dynamic type literal |
+ /// [constant]. That is, [rhs] is only evaluated and assigned, if the value |
+ /// is of the [constant] is `null`. The behavior is thus equivalent to a type |
+ /// literal access. |
+ /// |
+ /// For instance: |
+ /// |
+ /// m(rhs) => dynamic ??= rhs; |
+ /// |
+ R visitDynamicTypeLiteralSetIfNull( |
+ Send node, |
+ ConstantExpression constant, |
+ Node rhs, |
+ A arg); |
+ |
/// Prefix expression with [operator] on a final super [field]. |
/// |
/// For instance: |