Version 2.17.0-139.0.dev

Merge commit '567834e49993c77911ef5da9cc4030c521be88e1' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart
index 0aa6a8f..6ae7fe4 100644
--- a/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/variable_declaration_resolver.dart
@@ -66,10 +66,7 @@
 
     var callInsertion = _resolver.insertImplicitCallReference(initializer);
     if (callInsertion != null) {
-      var insertedExpression = callInsertion.expression;
-      if (insertedExpression != null) {
-        initializer = callInsertion.expression;
-      }
+      initializer = callInsertion.expression;
     }
 
     // Initializers of top-level variables and fields are already included
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index 38fc6db..7f5aba1 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -106,6 +106,12 @@
       }
     }
 
+    _checkConflictingConstructorAndStatic(
+      classElement: enumElement,
+      staticGetters: staticGetters,
+      staticSetters: staticSetters,
+    );
+
     for (var accessor in enumElement.accessors) {
       var baseName = accessor.displayName;
       if (accessor.isStatic) {
@@ -384,37 +390,17 @@
       }
     }
 
+    _checkConflictingConstructorAndStatic(
+      classElement: element,
+      staticGetters: staticGetters,
+      staticSetters: staticSetters,
+    );
+
     // Check for local static members conflicting with local instance members.
+    // TODO(scheglov) This code is duplicated for enums. But for classes it is
+    // separated also into ErrorVerifier - where we check inherited.
     for (ClassMember member in members) {
-      if (member is ConstructorDeclaration) {
-        var nameNode = member.name;
-        if (nameNode != null) {
-          String name = nameNode.name;
-          var staticMember = staticGetters[name] ?? staticSetters[name];
-          if (staticMember != null) {
-            if (staticMember is PropertyAccessorElement) {
-              CompileTimeErrorCode errorCode;
-              if (staticMember.isSynthetic) {
-                errorCode = CompileTimeErrorCode
-                    .CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD;
-              } else if (staticMember.isGetter) {
-                errorCode = CompileTimeErrorCode
-                    .CONFLICTING_CONSTRUCTOR_AND_STATIC_GETTER;
-              } else {
-                errorCode = CompileTimeErrorCode
-                    .CONFLICTING_CONSTRUCTOR_AND_STATIC_SETTER;
-              }
-              _errorReporter.reportErrorForNode(errorCode, nameNode, [name]);
-            } else {
-              _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
-                nameNode,
-                [name],
-              );
-            }
-          }
-        }
-      } else if (member is FieldDeclaration) {
+      if (member is FieldDeclaration) {
         if (member.isStatic) {
           for (VariableDeclaration field in member.fields.variables) {
             SimpleIdentifier identifier = field.name;
@@ -446,6 +432,37 @@
     }
   }
 
+  void _checkConflictingConstructorAndStatic({
+    required ClassElement classElement,
+    required Map<String, Element> staticGetters,
+    required Map<String, Element> staticSetters,
+  }) {
+    for (var constructor in classElement.constructors) {
+      var name = constructor.name;
+      var staticMember = staticGetters[name] ?? staticSetters[name];
+      if (staticMember is PropertyAccessorElement) {
+        CompileTimeErrorCode errorCode;
+        if (staticMember.isSynthetic) {
+          errorCode =
+              CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD;
+        } else if (staticMember.isGetter) {
+          errorCode =
+              CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_GETTER;
+        } else {
+          errorCode =
+              CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_SETTER;
+        }
+        _errorReporter.reportErrorForElement(errorCode, constructor, [name]);
+      } else if (staticMember is MethodElement) {
+        _errorReporter.reportErrorForElement(
+          CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
+          constructor,
+          [name],
+        );
+      }
+    }
+  }
+
   /// Check whether the given [element] defined by the [identifier] is already
   /// in one of the scopes - [getterScope] or [setterScope], and produce an
   /// error if it is.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index d42e16a..4e32f72 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -81,14 +81,8 @@
 /// Data structure describing the result of inserting an implicit call reference
 /// into the AST.
 class ImplicitCallInsertionResult {
-  /// The expression that was inserted, or `null`, if no expression was
-  /// inserted.
-  ///
-  /// The only reason this might be `null` is that, at the moment, we only
-  /// insert implicit call reference expressions if the 'constructor-tearoffs'
-  /// feature is enabled (to avoid breaking clients).
-  /// TODO(paulberry): make this non-nullable when we change this behavior.
-  final ImplicitCallReferenceImpl? expression;
+  /// The expression that was inserted.
+  final ImplicitCallReferenceImpl expression;
 
   /// The type of the implicit call tear-off.
   final FunctionType staticType;
@@ -862,14 +856,6 @@
       typeArgumentTypes = [];
     }
 
-    if (!isConstructorTearoffsEnabled) {
-      // Temporarily, only create [ImplicitCallReference] nodes under the
-      // 'constructor-tearoffs' feature.
-      // TODO(srawlins, paulberry): When we are ready to make a breaking change
-      // release to the analyzer package, remove this exception.
-      return ImplicitCallInsertionResult(null, callMethodType);
-    }
-
     var callReference = astFactory.implicitCallReference(
       expression: expression,
       staticElement: callMethod,
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_field_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_field_test.dart
index 4bd1277..2447ef9 100644
--- a/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_field_test.dart
@@ -16,7 +16,16 @@
 @reflectiveTest
 class ConflictingConstructorAndStaticFieldTest
     extends PubPackageResolutionTest {
-  test_class_field() async {
+  test_class_instance_field() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  C.foo();
+  int foo = 0;
+}
+''');
+  }
+
+  test_class_static_field() async {
     await assertErrorsInCode(r'''
 class C {
   C.foo();
@@ -28,7 +37,7 @@
     ]);
   }
 
-  test_class_getter() async {
+  test_class_static_getter() async {
     await assertErrorsInCode(r'''
 class C {
   C.foo();
@@ -40,7 +49,7 @@
     ]);
   }
 
-  test_class_OK_notSameClass() async {
+  test_class_static_notSameClass() async {
     await assertNoErrorsInCode(r'''
 class A {
   static int foo = 0;
@@ -51,16 +60,7 @@
 ''');
   }
 
-  test_class_OK_notStatic() async {
-    await assertNoErrorsInCode(r'''
-class C {
-  C.foo();
-  int foo = 0;
-}
-''');
-  }
-
-  test_class_setter() async {
+  test_class_static_setter() async {
     await assertErrorsInCode(r'''
 class C {
   C.foo();
@@ -72,33 +72,64 @@
     ]);
   }
 
-  test_enum_field() async {
+  test_enum_constant() async {
+    await assertErrorsInCode(r'''
+enum E {
+  foo.foo();
+  const E.foo();
+}
+''', [
+      error(
+          CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD, 32, 3),
+    ]);
+  }
+
+  test_enum_instance_field() async {
     await assertNoErrorsInCode(r'''
 enum E {
   v.foo();
-  const E.foo(); // _$foo
+  const E.foo();
+  final int foo = 0;
+}
+''');
+  }
+
+  test_enum_static_field() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v.foo();
+  const E.foo();
   static int foo = 0;
 }
-''');
+''', [
+      error(
+          CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD, 30, 3),
+    ]);
   }
 
-  test_enum_getter() async {
-    await assertNoErrorsInCode(r'''
+  test_enum_static_getter() async {
+    await assertErrorsInCode(r'''
 enum E {
   v.foo();
-  const E.foo(); // _$foo
+  const E.foo();
   static int get foo => 0;
 }
-''');
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_GETTER, 30,
+          3),
+    ]);
   }
 
-  test_enum_setter() async {
-    await assertNoErrorsInCode(r'''
+  test_enum_static_setter() async {
+    await assertErrorsInCode(r'''
 enum E {
   v.foo();
-  const E.foo(); // _$foo
+  const E.foo();
   static void set foo(_) {}
 }
-''');
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_SETTER, 30,
+          3),
+    ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_method_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_method_test.dart
index d962c52..2ce27da 100644
--- a/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_method_test.dart
@@ -16,7 +16,27 @@
 @reflectiveTest
 class ConflictingConstructorAndStaticMethodTest
     extends PubPackageResolutionTest {
-  test_class() async {
+  test_class_instance() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  C.foo();
+  void foo() {}
+}
+''');
+  }
+
+  test_class_notSameClass() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static void foo() {}
+}
+class B extends A {
+  B.foo();
+}
+''');
+  }
+
+  test_class_static() async {
     await assertErrorsInCode(r'''
 class C {
   C.foo();
@@ -28,33 +48,26 @@
     ]);
   }
 
-  test_class_OK_notSameClass() async {
+  test_enum_instance() async {
     await assertNoErrorsInCode(r'''
-class A {
-  static void foo() {}
-}
-class B extends A {
-  B.foo();
-}
-''');
-  }
-
-  test_class_OK_notStatic() async {
-    await assertNoErrorsInCode(r'''
-class C {
-  C.foo();
+enum E {
+  v.foo();
+  const E.foo();
   void foo() {}
 }
 ''');
   }
 
-  test_enum() async {
-    await assertNoErrorsInCode(r'''
+  test_enum_static() async {
+    await assertErrorsInCode(r'''
 enum E {
   v.foo();
-  const E.foo(); // _$foo
+  const E.foo();
   static void foo() {}
 }
-''');
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD, 30,
+          3),
+    ]);
   }
 }
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index d79ce34..ed5ca6e 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -1151,6 +1151,18 @@
   }
 
   @override
+  DecoratedType? visitImplicitCallReference(ImplicitCallReference node) {
+    return _handlePropertyAccessGeneralized(
+        node: node,
+        target: node.expression,
+        propertyName: 'call',
+        isNullAware: false,
+        isCascaded: false,
+        inSetterContext: false,
+        callee: node.staticElement);
+  }
+
+  @override
   DecoratedType? visitIndexExpression(IndexExpression node) {
     DecoratedType? targetType;
     var target = node.target;
@@ -3112,24 +3124,43 @@
 
   DecoratedType? _handlePropertyAccess(Expression node, Expression? target,
       SimpleIdentifier propertyName, bool isNullAware, bool isCascaded) {
-    DecoratedType? targetType;
+    if (!isCascaded && _isPrefix(target)) {
+      return _dispatch(propertyName, skipNullCheckHint: true);
+    }
     var callee = getWriteOrReadElement(propertyName);
+    return _handlePropertyAccessGeneralized(
+        node: node,
+        target: target,
+        propertyName: propertyName.name,
+        isNullAware: isNullAware,
+        isCascaded: isCascaded,
+        inSetterContext: propertyName.inSetterContext(),
+        callee: callee);
+  }
+
+  DecoratedType? _handlePropertyAccessGeneralized(
+      {required Expression node,
+      required Expression? target,
+      required String propertyName,
+      required bool isNullAware,
+      required bool isCascaded,
+      required bool inSetterContext,
+      required Element? callee}) {
+    DecoratedType? targetType;
     bool calleeIsStatic = callee is ExecutableElement && callee.isStatic;
     if (isCascaded) {
       targetType = _currentCascadeTargetType;
-    } else if (_isPrefix(target)) {
-      return _dispatch(propertyName, skipNullCheckHint: true);
     } else if (calleeIsStatic) {
       _dispatch(target);
     } else if (isNullAware) {
       targetType = _dispatch(target);
     } else {
-      targetType = _handleTarget(target, propertyName.name, callee);
+      targetType = _handleTarget(target, propertyName, callee);
     }
     DecoratedType? calleeType;
     if (targetType != null &&
         targetType.type is FunctionType &&
-        propertyName.name == 'call') {
+        propertyName == 'call') {
       // If `X` has a function type, then in the expression `X.call`, the
       // function being torn off is `X` itself, so the callee type is simply the
       // non-nullable counterpart to the type of `X`.
@@ -3148,7 +3179,7 @@
       // Dynamic dispatch.
       return _makeNullableDynamicType(node);
     }
-    if (propertyName.inSetterContext()) {
+    if (inSetterContext) {
       if (isNullAware) {
         _conditionalNodes[node] = targetType!.node;
       }
diff --git a/tools/VERSION b/tools/VERSION
index 029a3c9..4edaf3c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 138
+PRERELEASE 139
 PRERELEASE_PATCH 0
\ No newline at end of file