Fine. Access specifically constructor ID for dependencies.

Change-Id: Ida8aa508af02a12441a134098f4d147758cc4730
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/424707
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/fine/manifest_context.dart b/pkg/analyzer/lib/src/fine/manifest_context.dart
index 9aa8f4b..1639921 100644
--- a/pkg/analyzer/lib/src/fine/manifest_context.dart
+++ b/pkg/analyzer/lib/src/fine/manifest_context.dart
@@ -305,6 +305,9 @@
     // TODO(scheglov): When implementation is complete, cast unconditionally.
     if (topLevelItem is InstanceItem) {
       var memberName = memberElement.lookupName!.asLookupName;
+      if (element is ConstructorElement) {
+        return topLevelItem.getConstructorId(memberName);
+      }
       var memberId = topLevelItem.getMemberId(memberName);
       // TODO(scheglov): When implementation is complete, null assert.
       return memberId;
diff --git a/pkg/analyzer/lib/src/fine/manifest_item.dart b/pkg/analyzer/lib/src/fine/manifest_item.dart
index 140cfb2..0dd9829 100644
--- a/pkg/analyzer/lib/src/fine/manifest_item.dart
+++ b/pkg/analyzer/lib/src/fine/manifest_item.dart
@@ -78,6 +78,15 @@
     required this.members,
   });
 
+  ManifestItemId? getConstructorId(LookupName name) {
+    var baseNameMembers = members[name.asBaseName];
+    if (baseNameMembers == null) {
+      return null;
+    }
+
+    return baseNameMembers.constructorId;
+  }
+
   ManifestItemId? getMemberId(LookupName name) {
     var baseNameMembers = members[name.asBaseName];
     if (baseNameMembers == null) {
@@ -92,8 +101,7 @@
       return baseNameMembers.indexEqId;
     }
 
-    // TODO(scheglov): separate constructors
-    return baseNameMembers.getterOrMethodId ?? baseNameMembers.constructorId;
+    return baseNameMembers.getterOrMethodId;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/fine/requirements.dart b/pkg/analyzer/lib/src/fine/requirements.dart
index 2bf919a..9680b9a 100644
--- a/pkg/analyzer/lib/src/fine/requirements.dart
+++ b/pkg/analyzer/lib/src/fine/requirements.dart
@@ -318,7 +318,7 @@
         var constructors = interfaceEntry.value.constructors;
         for (var constructorEntry in constructors.entries) {
           var constructorName = constructorEntry.key;
-          var constructorId = interfaceItem.getMemberId(constructorName);
+          var constructorId = interfaceItem.getConstructorId(constructorName);
           var expectedId = constructorEntry.value;
           if (expectedId != constructorId) {
             return InterfaceConstructorIdMismatch(
@@ -372,7 +372,7 @@
 
     var (interfaceItem, interface) = interfacePair;
     var constructorName = name.asLookupName;
-    var constructorId = interfaceItem.getMemberId(constructorName);
+    var constructorId = interfaceItem.getConstructorId(constructorName);
     interface.constructors[constructorName] = constructorId;
   }
 
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index a33316e..0251458 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -5454,6 +5454,619 @@
     return super.tearDown();
   }
 
+  test_dependency_class_constructor_named_instanceGetterSetter_u1() async {
+    configuration.withStreamResolvedUnitResults = false;
+    await _runChangeScenarioTA(
+      initialA: r'''
+class A {
+  A.foo(int _);
+  int get foo {}
+  set foo(int _) {}
+}
+''',
+      testCode: r'''
+import 'a.dart';
+void f() {
+  var a = A.foo(0);
+  a.foo;
+  a.foo = 0;
+}
+''',
+      operation: _FineOperationTestFileGetErrors(),
+      expectedInitialEvents: r'''
+[status] working
+[operation] linkLibraryCycle SDK
+[future] getErrors T1
+  ErrorsResult #0
+    path: /home/test/lib/test.dart
+    uri: package:test/test.dart
+    flags: isLibrary
+[operation] linkLibraryCycle
+  package:test/a.dart
+    manifest
+      A: #M0
+        members
+          foo.constructor.declared: #M1
+          foo.getter.declared: #M2
+          foo.setter.declared: #M3
+  requirements
+    topLevels
+      dart:core
+        int: #M4
+[operation] linkLibraryCycle
+  package:test/test.dart
+    manifest
+      f: #M5
+  requirements
+[operation] analyzeFile
+  file: /home/test/lib/test.dart
+  library: /home/test/lib/test.dart
+[operation] analyzedLibrary
+  file: /home/test/lib/test.dart
+  requirements
+    topLevels
+      dart:core
+        A: <null>
+      package:test/a.dart
+        A: #M0
+    interfaces
+      package:test/a.dart
+        A
+          constructors
+            foo: #M1
+          methods
+            foo: #M2
+            foo=: #M3
+[status] idle
+''',
+      updatedA: r'''
+class A {
+  A.foo(double _);
+  int get foo {}
+  set foo(int _) {}
+}
+''',
+      expectedUpdatedEvents: r'''
+[status] working
+[operation] linkLibraryCycle
+  package:test/a.dart
+    manifest
+      A: #M0
+        members
+          foo.constructor.declared: #M6
+          foo.getter.declared: #M2
+          foo.setter.declared: #M3
+  requirements
+    topLevels
+      dart:core
+        double: #M7
+        int: #M4
+[future] getErrors T2
+  ErrorsResult #1
+    path: /home/test/lib/test.dart
+    uri: package:test/test.dart
+    flags: isLibrary
+[operation] readLibraryCycleBundle
+  package:test/test.dart
+[operation] getErrorsCannotReuse
+  interfaceConstructorIdMismatch
+    libraryUri: package:test/a.dart
+    interfaceName: A
+    constructorName: foo
+    expectedId: #M1
+    actualId: #M6
+[operation] analyzeFile
+  file: /home/test/lib/test.dart
+  library: /home/test/lib/test.dart
+[operation] analyzedLibrary
+  file: /home/test/lib/test.dart
+  requirements
+    topLevels
+      dart:core
+        A: <null>
+      package:test/a.dart
+        A: #M0
+    interfaces
+      package:test/a.dart
+        A
+          constructors
+            foo: #M6
+          methods
+            foo: #M2
+            foo=: #M3
+[status] idle
+''',
+    );
+  }
+
+  test_dependency_class_constructor_named_instanceGetterSetter_u2() async {
+    configuration.withStreamResolvedUnitResults = false;
+    await _runChangeScenarioTA(
+      initialA: r'''
+class A {
+  A.foo(int _);
+  int get foo {}
+  set foo(int _) {}
+}
+''',
+      testCode: r'''
+import 'a.dart';
+void f() {
+  var a = A.foo(0);
+  a.foo;
+  a.foo = 0;
+}
+''',
+      operation: _FineOperationTestFileGetErrors(),
+      expectedInitialEvents: r'''
+[status] working
+[operation] linkLibraryCycle SDK
+[future] getErrors T1
+  ErrorsResult #0
+    path: /home/test/lib/test.dart
+    uri: package:test/test.dart
+    flags: isLibrary
+[operation] linkLibraryCycle
+  package:test/a.dart
+    manifest
+      A: #M0
+        members
+          foo.constructor.declared: #M1
+          foo.getter.declared: #M2
+          foo.setter.declared: #M3
+  requirements
+    topLevels
+      dart:core
+        int: #M4
+[operation] linkLibraryCycle
+  package:test/test.dart
+    manifest
+      f: #M5
+  requirements
+[operation] analyzeFile
+  file: /home/test/lib/test.dart
+  library: /home/test/lib/test.dart
+[operation] analyzedLibrary
+  file: /home/test/lib/test.dart
+  requirements
+    topLevels
+      dart:core
+        A: <null>
+      package:test/a.dart
+        A: #M0
+    interfaces
+      package:test/a.dart
+        A
+          constructors
+            foo: #M1
+          methods
+            foo: #M2
+            foo=: #M3
+[status] idle
+''',
+      updatedA: r'''
+class A {
+  A.foo(int _);
+  double get foo {}
+  set foo(int _) {}
+}
+''',
+      expectedUpdatedEvents: r'''
+[status] working
+[operation] linkLibraryCycle
+  package:test/a.dart
+    manifest
+      A: #M0
+        members
+          foo.constructor.declared: #M1
+          foo.getter.declared: #M6
+          foo.setter.declared: #M3
+  requirements
+    topLevels
+      dart:core
+        double: #M7
+        int: #M4
+[future] getErrors T2
+  ErrorsResult #1
+    path: /home/test/lib/test.dart
+    uri: package:test/test.dart
+    flags: isLibrary
+[operation] readLibraryCycleBundle
+  package:test/test.dart
+[operation] getErrorsCannotReuse
+  instanceMethodIdMismatch
+    libraryUri: package:test/a.dart
+    interfaceName: A
+    methodName: foo
+    expectedId: #M2
+    actualId: #M6
+[operation] analyzeFile
+  file: /home/test/lib/test.dart
+  library: /home/test/lib/test.dart
+[operation] analyzedLibrary
+  file: /home/test/lib/test.dart
+  requirements
+    topLevels
+      dart:core
+        A: <null>
+      package:test/a.dart
+        A: #M0
+    interfaces
+      package:test/a.dart
+        A
+          constructors
+            foo: #M1
+          methods
+            foo: #M6
+            foo=: #M3
+[status] idle
+''',
+    );
+  }
+
+  test_dependency_class_constructor_named_instanceGetterSetter_u3() async {
+    configuration.withStreamResolvedUnitResults = false;
+    await _runChangeScenarioTA(
+      initialA: r'''
+class A {
+  A.foo(int _);
+  int get foo {}
+  set foo(int _) {}
+}
+''',
+      testCode: r'''
+import 'a.dart';
+void f() {
+  var a = A.foo(0);
+  a.foo;
+  a.foo = 0;
+}
+''',
+      operation: _FineOperationTestFileGetErrors(),
+      expectedInitialEvents: r'''
+[status] working
+[operation] linkLibraryCycle SDK
+[future] getErrors T1
+  ErrorsResult #0
+    path: /home/test/lib/test.dart
+    uri: package:test/test.dart
+    flags: isLibrary
+[operation] linkLibraryCycle
+  package:test/a.dart
+    manifest
+      A: #M0
+        members
+          foo.constructor.declared: #M1
+          foo.getter.declared: #M2
+          foo.setter.declared: #M3
+  requirements
+    topLevels
+      dart:core
+        int: #M4
+[operation] linkLibraryCycle
+  package:test/test.dart
+    manifest
+      f: #M5
+  requirements
+[operation] analyzeFile
+  file: /home/test/lib/test.dart
+  library: /home/test/lib/test.dart
+[operation] analyzedLibrary
+  file: /home/test/lib/test.dart
+  requirements
+    topLevels
+      dart:core
+        A: <null>
+      package:test/a.dart
+        A: #M0
+    interfaces
+      package:test/a.dart
+        A
+          constructors
+            foo: #M1
+          methods
+            foo: #M2
+            foo=: #M3
+[status] idle
+''',
+      updatedA: r'''
+class A {
+  A.foo(int _);
+  int get foo {}
+  set foo(double _) {}
+}
+''',
+      expectedUpdatedEvents: r'''
+[status] working
+[operation] linkLibraryCycle
+  package:test/a.dart
+    manifest
+      A: #M0
+        members
+          foo.constructor.declared: #M1
+          foo.getter.declared: #M2
+          foo.setter.declared: #M6
+  requirements
+    topLevels
+      dart:core
+        double: #M7
+        int: #M4
+[future] getErrors T2
+  ErrorsResult #1
+    path: /home/test/lib/test.dart
+    uri: package:test/test.dart
+    flags: isLibrary
+[operation] readLibraryCycleBundle
+  package:test/test.dart
+[operation] getErrorsCannotReuse
+  instanceMethodIdMismatch
+    libraryUri: package:test/a.dart
+    interfaceName: A
+    methodName: foo=
+    expectedId: #M3
+    actualId: #M6
+[operation] analyzeFile
+  file: /home/test/lib/test.dart
+  library: /home/test/lib/test.dart
+[operation] analyzedLibrary
+  file: /home/test/lib/test.dart
+  requirements
+    topLevels
+      dart:core
+        A: <null>
+      package:test/a.dart
+        A: #M0
+    interfaces
+      package:test/a.dart
+        A
+          constructors
+            foo: #M1
+          methods
+            foo: #M2
+            foo=: #M6
+[status] idle
+''',
+    );
+  }
+
+  test_dependency_class_constructor_named_instanceMethod_u1() async {
+    configuration.withStreamResolvedUnitResults = false;
+    await _runChangeScenarioTA(
+      initialA: r'''
+class A {
+  A.foo(int _);
+  int foo() {}
+}
+''',
+      testCode: r'''
+import 'a.dart';
+void f() {
+  A.foo(0).foo();
+}
+''',
+      operation: _FineOperationTestFileGetErrors(),
+      expectedInitialEvents: r'''
+[status] working
+[operation] linkLibraryCycle SDK
+[future] getErrors T1
+  ErrorsResult #0
+    path: /home/test/lib/test.dart
+    uri: package:test/test.dart
+    flags: isLibrary
+[operation] linkLibraryCycle
+  package:test/a.dart
+    manifest
+      A: #M0
+        members
+          foo.constructor.declared: #M1
+          foo.method.declared: #M2
+  requirements
+    topLevels
+      dart:core
+        int: #M3
+[operation] linkLibraryCycle
+  package:test/test.dart
+    manifest
+      f: #M4
+  requirements
+[operation] analyzeFile
+  file: /home/test/lib/test.dart
+  library: /home/test/lib/test.dart
+[operation] analyzedLibrary
+  file: /home/test/lib/test.dart
+  requirements
+    topLevels
+      dart:core
+        A: <null>
+      package:test/a.dart
+        A: #M0
+    interfaces
+      package:test/a.dart
+        A
+          constructors
+            foo: #M1
+          methods
+            foo: #M2
+            foo=: <null>
+[status] idle
+''',
+      updatedA: r'''
+class A {
+  A.foo(double _);
+  int foo() {}
+}
+''',
+      expectedUpdatedEvents: r'''
+[status] working
+[operation] linkLibraryCycle
+  package:test/a.dart
+    manifest
+      A: #M0
+        members
+          foo.constructor.declared: #M5
+          foo.method.declared: #M2
+  requirements
+    topLevels
+      dart:core
+        double: #M6
+        int: #M3
+[future] getErrors T2
+  ErrorsResult #1
+    path: /home/test/lib/test.dart
+    uri: package:test/test.dart
+    flags: isLibrary
+[operation] readLibraryCycleBundle
+  package:test/test.dart
+[operation] getErrorsCannotReuse
+  interfaceConstructorIdMismatch
+    libraryUri: package:test/a.dart
+    interfaceName: A
+    constructorName: foo
+    expectedId: #M1
+    actualId: #M5
+[operation] analyzeFile
+  file: /home/test/lib/test.dart
+  library: /home/test/lib/test.dart
+[operation] analyzedLibrary
+  file: /home/test/lib/test.dart
+  requirements
+    topLevels
+      dart:core
+        A: <null>
+      package:test/a.dart
+        A: #M0
+    interfaces
+      package:test/a.dart
+        A
+          constructors
+            foo: #M5
+          methods
+            foo: #M2
+            foo=: <null>
+[status] idle
+''',
+    );
+  }
+
+  test_dependency_class_constructor_named_instanceMethod_u2() async {
+    configuration.withStreamResolvedUnitResults = false;
+    await _runChangeScenarioTA(
+      initialA: r'''
+class A {
+  A.foo(int _);
+  int foo() {}
+}
+''',
+      testCode: r'''
+import 'a.dart';
+void f() {
+  A.foo(0).foo();
+}
+''',
+      operation: _FineOperationTestFileGetErrors(),
+      expectedInitialEvents: r'''
+[status] working
+[operation] linkLibraryCycle SDK
+[future] getErrors T1
+  ErrorsResult #0
+    path: /home/test/lib/test.dart
+    uri: package:test/test.dart
+    flags: isLibrary
+[operation] linkLibraryCycle
+  package:test/a.dart
+    manifest
+      A: #M0
+        members
+          foo.constructor.declared: #M1
+          foo.method.declared: #M2
+  requirements
+    topLevels
+      dart:core
+        int: #M3
+[operation] linkLibraryCycle
+  package:test/test.dart
+    manifest
+      f: #M4
+  requirements
+[operation] analyzeFile
+  file: /home/test/lib/test.dart
+  library: /home/test/lib/test.dart
+[operation] analyzedLibrary
+  file: /home/test/lib/test.dart
+  requirements
+    topLevels
+      dart:core
+        A: <null>
+      package:test/a.dart
+        A: #M0
+    interfaces
+      package:test/a.dart
+        A
+          constructors
+            foo: #M1
+          methods
+            foo: #M2
+            foo=: <null>
+[status] idle
+''',
+      updatedA: r'''
+class A {
+  A.foo(int _);
+  double foo() {}
+}
+''',
+      expectedUpdatedEvents: r'''
+[status] working
+[operation] linkLibraryCycle
+  package:test/a.dart
+    manifest
+      A: #M0
+        members
+          foo.constructor.declared: #M1
+          foo.method.declared: #M5
+  requirements
+    topLevels
+      dart:core
+        double: #M6
+        int: #M3
+[future] getErrors T2
+  ErrorsResult #1
+    path: /home/test/lib/test.dart
+    uri: package:test/test.dart
+    flags: isLibrary
+[operation] readLibraryCycleBundle
+  package:test/test.dart
+[operation] getErrorsCannotReuse
+  instanceMethodIdMismatch
+    libraryUri: package:test/a.dart
+    interfaceName: A
+    methodName: foo
+    expectedId: #M2
+    actualId: #M5
+[operation] analyzeFile
+  file: /home/test/lib/test.dart
+  library: /home/test/lib/test.dart
+[operation] analyzedLibrary
+  file: /home/test/lib/test.dart
+  requirements
+    topLevels
+      dart:core
+        A: <null>
+      package:test/a.dart
+        A: #M0
+    interfaces
+      package:test/a.dart
+        A
+          constructors
+            foo: #M1
+          methods
+            foo: #M5
+            foo=: <null>
+[status] idle
+''',
+    );
+  }
+
   test_dependency_class_constructor_named_invocation() async {
     configuration.withStreamResolvedUnitResults = false;
     await _runChangeScenarioTA(