Evaluate default values of all default parameters, even required (e.g. required named).

Bug: https://github.com/dart-lang/sdk/issues/49596
Change-Id: Id9696a6e93499ec4eca164ccb78c39aec5acaaab
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253705
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index ef918ea..99c6450 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -63,7 +63,7 @@
 
     var library = constant.library as LibraryElementImpl;
     if (constant is ParameterElementImpl) {
-      if (constant.isOptional) {
+      if (constant is ConstVariableElement) {
         var defaultValue = constant.constantInitializer;
         if (defaultValue != null) {
           RecordingErrorListener errorListener = RecordingErrorListener();
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index bc1414f..40c90d5 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -5,10 +5,13 @@
 @deprecated
 library analyzer.test.constant_test;
 
+import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/test_utilities/find_element.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -372,6 +375,46 @@
     await _assertValueInt(-42, "-42");
   }
 
+  /// Even though it is an error to specify a default value for a required
+  /// parameter, we still can evaluate it.
+  test_normalParameter_requiredNamed_hasDefault() async {
+    final a = newFile('$testPackageLibPath/a.dart', r'''
+class A {
+  A({required int x = 42});
+}
+''');
+
+    final unitResult = await _getUnitElement(a);
+    final x = unitResult.findElement.parameter('x');
+    assertDartObjectText(
+      x.computeConstantValue(),
+      r'''
+int 42
+''',
+      libraryElement: unitResult.library,
+    );
+  }
+
+  /// Even though it is an error to specify a default value for a required
+  /// parameter, we still can evaluate it.
+  test_normalParameter_requiredNamed_noDefault() async {
+    final a = newFile('$testPackageLibPath/a.dart', r'''
+class A {
+  A({required int? x});
+}
+''');
+
+    final unitResult = await _getUnitElement(a);
+    final x = unitResult.findElement.parameter('x');
+    assertDartObjectText(
+      x.computeConstantValue(),
+      r'''
+Null null
+''',
+      libraryElement: unitResult.library,
+    );
+  }
+
   test_notEqual_boolean_boolean() async {
     await _assertValueBool(true, "true != false");
   }
@@ -927,12 +970,31 @@
     return evaluator.evaluate(expression);
   }
 
+  Future<_UnitElementResult> _getUnitElement(File file) async {
+    final analysisSession = contextFor(file).currentSession;
+    final unitResult = await analysisSession.getUnitElement(file.path);
+    unitResult as UnitElementResult;
+    return _UnitElementResult(unitResult.element);
+  }
+
   EvaluationResultImpl _topVarConstResult(String name) {
     var element = findElement.topVar(name) as ConstTopLevelVariableElementImpl;
     return element.evaluationResult!;
   }
 }
 
+class _UnitElementResult {
+  final CompilationUnitElement element;
+
+  _UnitElementResult(this.element);
+
+  PartFindElement get findElement {
+    return PartFindElement(element);
+  }
+
+  LibraryElement get library => element.library;
+}
+
 extension on VariableElement {
   EvaluationResultImpl get evaluationResult {
     var constVariable = this as ConstVariableElement;
diff --git a/pkg/analyzer/test/src/dart/resolution/dart_object_printer.dart b/pkg/analyzer/test/src/dart/resolution/dart_object_printer.dart
index ec37e39..40861f1 100644
--- a/pkg/analyzer/test/src/dart/resolution/dart_object_printer.dart
+++ b/pkg/analyzer/test/src/dart/resolution/dart_object_printer.dart
@@ -36,6 +36,8 @@
       } else if (type.isDartCoreInt) {
         sink.write('int ');
         sink.writeln(object.toIntValue());
+      } else if (type.isDartCoreNull) {
+        sink.writeln('Null null');
       } else if (type.isDartCoreString) {
         sink.write('String ');
         sink.writeln(object.toStringValue());
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 4d9ad77..e369510 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -120,11 +120,17 @@
     );
   }
 
-  void assertDartObjectText(DartObject? object, String expected) {
+  void assertDartObjectText(
+    DartObject? object,
+    String expected, {
+    LibraryElement? libraryElement,
+  }) {
+    libraryElement ??= result.libraryElement;
+
     var buffer = StringBuffer();
     DartObjectPrinter(
       sink: buffer,
-      selfUriStr: '${result.libraryElement.source.uri}',
+      selfUriStr: '${libraryElement.source.uri}',
     ).write(object as DartObjectImpl?);
     var actual = buffer.toString();
     if (actual != expected) {