diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart index 654270685f6..90a059fc075 100644 --- a/pkg/analyzer/lib/src/context/context.dart +++ b/pkg/analyzer/lib/src/context/context.dart @@ -2,9 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analyzer/dart/analysis/declared_variables.dart'; import 'package:analyzer/src/dart/element/type_provider.dart'; import 'package:analyzer/src/dart/element/type_system.dart'; -import 'package:analyzer/src/generated/constant.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/source.dart'; diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart index 16b1d3dd0af..9b42a567f87 100644 --- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart +++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart @@ -4,10 +4,12 @@ import 'dart:collection'; +import 'package:analyzer/dart/analysis/declared_variables.dart'; import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/ast/syntactic_entity.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/ast/visitor.dart'; +import 'package:analyzer/dart/constant/value.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:analyzer/dart/element/type.dart'; @@ -20,6 +22,8 @@ import 'package:analyzer/src/dart/ast/token.dart'; import 'package:analyzer/src/dart/constant/from_environment_evaluator.dart'; import 'package:analyzer/src/dart/constant/has_type_parameter_reference.dart'; import 'package:analyzer/src/dart/constant/potentially_constant.dart'; +import 'package:analyzer/src/dart/constant/utilities.dart'; +import 'package:analyzer/src/dart/constant/value.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/member.dart'; import 'package:analyzer/src/dart/element/type.dart'; @@ -27,7 +31,6 @@ import 'package:analyzer/src/dart/element/type_algebra.dart'; import 'package:analyzer/src/dart/element/type_system.dart' show TypeSystemImpl; import 'package:analyzer/src/diagnostic/diagnostic.dart'; import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/generated/constant.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/java_core.dart'; import 'package:analyzer/src/task/api/model.dart'; diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart index ab6c10534b1..dac6ce854fd 100644 --- a/pkg/analyzer/lib/src/dart/constant/value.dart +++ b/pkg/analyzer/lib/src/dart/constant/value.dart @@ -904,7 +904,7 @@ class DartObjectImpl implements DartObject, Constant { Map? toMapValue() { final state = this.state; if (state is MapState) { - return state._entries; + return state.entries; } return null; } @@ -913,7 +913,7 @@ class DartObjectImpl implements DartObject, Constant { Set? toSetValue() { final state = this.state; if (state is SetState) { - return state._elements; + return state.elements; } return null; } @@ -2491,16 +2491,16 @@ class ListState extends InstanceState { /// The state of an object representing a map. class MapState extends InstanceState { /// The entries in the map. - final Map _entries; + final Map entries; /// Initialize a newly created state to represent a map with the given /// [entries]. - MapState(this._entries); + MapState(this.entries); @override int get hashCode { int value = 0; - for (DartObjectImpl key in _entries.keys.toSet()) { + for (DartObjectImpl key in entries.keys.toSet()) { value = (value << 3) ^ key.hashCode; } return value; @@ -2512,15 +2512,15 @@ class MapState extends InstanceState { @override bool operator ==(Object other) { if (other is MapState) { - Map otherElements = other._entries; - int count = _entries.length; + Map otherElements = other.entries; + int count = entries.length; if (otherElements.length != count) { return false; } else if (count == 0) { return true; } - for (DartObjectImpl key in _entries.keys) { - var value = _entries[key]; + for (DartObjectImpl key in entries.keys) { + var value = entries[key]; var otherValue = otherElements[key]; if (value != otherValue) { return false; @@ -2552,7 +2552,7 @@ class MapState extends InstanceState { StringBuffer buffer = StringBuffer(); buffer.write('{'); bool first = true; - _entries.forEach((DartObjectImpl key, DartObjectImpl value) { + entries.forEach((DartObjectImpl key, DartObjectImpl value) { if (first) { first = false; } else { @@ -2763,16 +2763,16 @@ class RecordState extends InstanceState { /// The state of an object representing a set. class SetState extends InstanceState { /// The elements of the set. - final Set _elements; + final Set elements; /// Initialize a newly created state to represent a set with the given /// [elements]. - SetState(this._elements); + SetState(this.elements); @override int get hashCode { int value = 0; - for (DartObjectImpl element in _elements) { + for (DartObjectImpl element in elements) { value = (value << 3) ^ element.hashCode; } return value; @@ -2784,16 +2784,16 @@ class SetState extends InstanceState { @override bool operator ==(Object other) { if (other is SetState) { - List elements = _elements.toList(); - List otherElements = other._elements.toList(); - int count = elements.length; + List currentElements = elements.toList(); + List otherElements = other.elements.toList(); + int count = currentElements.length; if (otherElements.length != count) { return false; } else if (count == 0) { return true; } for (int i = 0; i < count; i++) { - if (elements[i] != otherElements[i]) { + if (currentElements[i] != otherElements[i]) { return false; } } @@ -2823,7 +2823,7 @@ class SetState extends InstanceState { StringBuffer buffer = StringBuffer(); buffer.write('{'); bool first = true; - for (var element in _elements) { + for (var element in elements) { if (first) { first = false; } else { diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart index ed23922fd76..65a31d4da52 100644 --- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart +++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart @@ -4,10 +4,12 @@ import 'dart:collection'; +import 'package:analyzer/dart/analysis/declared_variables.dart'; import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/ast/syntactic_entity.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/ast/visitor.dart'; +import 'package:analyzer/dart/constant/value.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:analyzer/dart/element/type.dart'; @@ -32,7 +34,6 @@ import 'package:analyzer/src/error/doc_comment_verifier.dart'; import 'package:analyzer/src/error/error_handler_verifier.dart'; import 'package:analyzer/src/error/must_call_super_verifier.dart'; import 'package:analyzer/src/error/null_safe_api_verifier.dart'; -import 'package:analyzer/src/generated/constant.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/lint/linter.dart'; import 'package:analyzer/src/workspace/workspace.dart'; diff --git a/pkg/analyzer/lib/src/error/dead_code_verifier.dart b/pkg/analyzer/lib/src/error/dead_code_verifier.dart index 646303dd77e..abb808957a6 100644 --- a/pkg/analyzer/lib/src/error/dead_code_verifier.dart +++ b/pkg/analyzer/lib/src/error/dead_code_verifier.dart @@ -11,12 +11,13 @@ import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/error/listener.dart'; import 'package:analyzer/source/source_range.dart'; +import 'package:analyzer/src/dart/constant/evaluation.dart'; +import 'package:analyzer/src/dart/constant/value.dart'; import 'package:analyzer/src/dart/element/type_system.dart'; import 'package:analyzer/src/dart/resolver/exit_detector.dart'; import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart'; import 'package:analyzer/src/dart/resolver/scope.dart'; import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/generated/constant.dart'; import 'package:collection/collection.dart'; typedef _CatchClausesVerifierReporter = void Function( diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart deleted file mode 100644 index f01b81b7988..00000000000 --- a/pkg/analyzer/lib/src/generated/constant.dart +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:analyzer/dart/analysis/declared_variables.dart'; -import 'package:analyzer/dart/analysis/features.dart'; -import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer/error/error.dart'; -import 'package:analyzer/error/listener.dart'; -import 'package:analyzer/src/dart/constant/evaluation.dart'; -import 'package:analyzer/src/dart/constant/value.dart'; -import 'package:analyzer/src/dart/element/element.dart'; -import 'package:analyzer/src/generated/source.dart' show Source; - -export 'package:analyzer/dart/analysis/declared_variables.dart'; -export 'package:analyzer/dart/constant/value.dart'; -export 'package:analyzer/src/dart/constant/evaluation.dart'; -export 'package:analyzer/src/dart/constant/utilities.dart'; -export 'package:analyzer/src/dart/constant/value.dart'; - -/// Instances of the class [ConstantEvaluator] evaluate constant expressions to -/// produce their compile-time value. -/// -/// According to the Dart Language Specification: -/// -/// > A constant expression is one of the following: -/// > -/// > * A literal number. -/// > * A literal boolean. -/// > * A literal string where any interpolated expression is a compile-time -/// > constant that evaluates to a numeric, string or boolean value or to -/// > **null**. -/// > * A literal symbol. -/// > * **null**. -/// > * A qualified reference to a static constant variable. -/// > * An identifier expression that denotes a constant variable, class or type -/// > alias. -/// > * A constant constructor invocation. -/// > * A constant list literal. -/// > * A constant map literal. -/// > * A simple or qualified identifier denoting a top-level function or a -/// > static method. -/// > * A parenthesized expression _(e)_ where _e_ is a constant expression. -/// > * -/// > An expression of the form identical(e1, e2) -/// > where e1 and e2 are constant -/// > expressions and identical() is statically bound to the predefined -/// > dart function identical() discussed above. -/// > -/// > * -/// > An expression of one of the forms e1 == e2 -/// > or e1 != e2 where e1 and -/// > e2 are constant expressions that evaluate to a -/// > numeric, string or boolean value. -/// > -/// > * -/// > An expression of one of the forms !e, e1 && -/// > e2 or e1 || e2, where -/// > e, e1 and e2 are constant -/// > expressions that evaluate to a boolean value. -/// > -/// > * -/// > An expression of one of the forms ~e, e1 ^ -/// > e2, e1 & e2, -/// > e1 | e2, e1 >> -/// > e2 or e1 << e2, where -/// > e, e1 and e2 are constant -/// > expressions that evaluate to an integer value or to null. -/// > -/// > * -/// > An expression of one of the forms -e, e1 + -/// > e2, e1 -e2, -/// > e1 * e2, e1 / -/// > e2, e1 ~/ e2, -/// > e1 > e2, e1 < -/// > e2, e1 >= e2, -/// > e1 <= e2 or e1 % -/// > e2, where e, e1 and -/// > e2 are constant expressions that evaluate to a numeric -/// > value or to null. -/// > -/// > * -/// > An expression of the form e1 ? e2 : -/// > e3 where e1, e2 and -/// > e3 are constant expressions, and e1 -/// > evaluates to a boolean value. -/// > -/// -/// The values returned by instances of this class are therefore `null` and -/// instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and -/// `DartObject`. -/// -/// In addition, this class defines several values that can be returned to -/// indicate various conditions encountered during evaluation. These are -/// documented with the static fields that define those values. -class ConstantEvaluator { - /// The source containing the expression(s) that will be evaluated. - final Source _source; - - /// The library containing the expression(s) that will be evaluated. - final LibraryElementImpl _library; - - ConstantEvaluator(this._source, this._library); - - EvaluationResult evaluate(Expression expression) { - RecordingErrorListener errorListener = RecordingErrorListener(); - ErrorReporter errorReporter = ErrorReporter( - errorListener, - _source, - isNonNullableByDefault: _library.isNonNullableByDefault, - ); - var result = expression.accept(ConstantVisitor( - ConstantEvaluationEngine( - declaredVariables: DeclaredVariables(), - isNonNullableByDefault: - _library.featureSet.isEnabled(Feature.non_nullable), - configuration: ConstantEvaluationConfiguration(), - ), - _library, - errorReporter)); - List errors = errorListener.errors; - if (errors.isNotEmpty) { - return EvaluationResult.forErrors(errors); - } - if (result is DartObjectImpl) { - return EvaluationResult.forValue(result); - } - // We should not get here. Either there should be a valid value or there - // should be an error explaining why a value could not be generated. - return EvaluationResult.forErrors(errors); - } -} diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart index d19a4adc60a..e689d81a71e 100644 --- a/pkg/analyzer/lib/src/generated/engine.dart +++ b/pkg/analyzer/lib/src/generated/engine.dart @@ -7,6 +7,7 @@ import 'dart:typed_data'; import 'package:_fe_analyzer_shared/src/scanner/string_canonicalizer.dart'; import 'package:analyzer/dart/analysis/analysis_options.dart'; import 'package:analyzer/dart/analysis/code_style_options.dart'; +import 'package:analyzer/dart/analysis/declared_variables.dart'; import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/instrumentation/instrumentation.dart'; @@ -14,7 +15,6 @@ import 'package:analyzer/source/error_processor.dart'; import 'package:analyzer/src/analysis_options/code_style_options.dart'; import 'package:analyzer/src/dart/analysis/experiments.dart'; import 'package:analyzer/src/dart/sdk/sdk.dart'; -import 'package:analyzer/src/generated/constant.dart'; import 'package:analyzer/src/generated/source.dart'; import 'package:analyzer/src/services/lint.dart'; import 'package:analyzer/src/summary/api_signature.dart'; diff --git a/pkg/analyzer/lib/src/generated/exhaustiveness.dart b/pkg/analyzer/lib/src/generated/exhaustiveness.dart index e2244a33690..1b7eb730da8 100644 --- a/pkg/analyzer/lib/src/generated/exhaustiveness.dart +++ b/pkg/analyzer/lib/src/generated/exhaustiveness.dart @@ -11,17 +11,18 @@ import 'package:_fe_analyzer_shared/src/exhaustiveness/space.dart'; import 'package:_fe_analyzer_shared/src/exhaustiveness/static_type.dart'; import 'package:_fe_analyzer_shared/src/exhaustiveness/types.dart'; import 'package:analyzer/dart/analysis/features.dart'; +import 'package:analyzer/dart/constant/value.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/src/dart/ast/ast.dart'; import 'package:analyzer/src/dart/ast/extensions.dart'; +import 'package:analyzer/src/dart/constant/value.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/replacement_visitor.dart'; import 'package:analyzer/src/dart/element/type_algebra.dart'; import 'package:analyzer/src/dart/element/type_system.dart'; import 'package:analyzer/src/dart/resolver/variance.dart'; -import 'package:analyzer/src/generated/constant.dart'; /// The buffer that accumulates types and elements as is, so that they /// can be written latter into Dart code that considers imports. It also diff --git a/pkg/analyzer/test/dart/analysis/from_environment_evaluator_test.dart b/pkg/analyzer/test/dart/analysis/from_environment_evaluator_test.dart index 44891cf70f2..cb08f4c095c 100644 --- a/pkg/analyzer/test/dart/analysis/from_environment_evaluator_test.dart +++ b/pkg/analyzer/test/dart/analysis/from_environment_evaluator_test.dart @@ -2,10 +2,11 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analyzer/dart/analysis/declared_variables.dart'; import 'package:analyzer/dart/element/type_provider.dart'; import 'package:analyzer/src/dart/constant/from_environment_evaluator.dart'; +import 'package:analyzer/src/dart/constant/value.dart'; import 'package:analyzer/src/dart/element/type_system.dart'; -import 'package:analyzer/src/generated/constant.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart deleted file mode 100644 index 533f4eee520..00000000000 --- a/pkg/analyzer/test/generated/constant_test.dart +++ /dev/null @@ -1,1073 +0,0 @@ -// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -@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/dart/error/syntactic_errors.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'; - -import '../src/dart/resolution/context_collection_resolution.dart'; - -main() { - defineReflectiveSuite(() { - defineReflectiveTests(ConstantEvaluatorTest); - }); -} - -@reflectiveTest -class ConstantEvaluatorTest extends PubPackageResolutionTest { - void assertTypeArguments(DartObject value, List? typeArgumentNames) { - var typeArguments = (value as DartObjectImpl).typeArguments; - if (typeArguments == null) { - expect(typeArguments, typeArgumentNames); - return; - } - expect( - typeArguments.map((arg) => arg.getDisplayString(withNullability: true)), - equals(typeArgumentNames), - ); - } - - test_bitAnd_int_int() async { - await _assertValueInt(74 & 42, "74 & 42"); - } - - test_bitNot() async { - await _assertValueInt(~42, "~42"); - } - - test_bitOr_int_int() async { - await _assertValueInt(74 | 42, "74 | 42"); - } - - test_bitXor_int_int() async { - await _assertValueInt(74 ^ 42, "74 ^ 42"); - } - - /// See https://github.com/dart-lang/sdk/issues/50045 - test_bool_fromEnvironment_dartLibraryJsUtil() async { - await resolveTestCode(''' -const x = bool.fromEnvironment('dart.library.js_util'); -'''); - - _assertTopVarConstValue('x', r''' - bool - variable: self::@variable::x -'''); - } - - test_constructorInvocation_fieldInitializer() async { - var result = await _getExpressionValue("const C(2)", context: ''' -class C { - final int x; - const C(this.x); -} -'''); - expect(result.isValid, isTrue); - DartObject value = result.value!; - assertType(value.type, 'C'); - DartObject x = value.getField('x')!; - assertType(x.type, 'int'); - expect(x.toIntValue(), 2); - } - - test_constructorInvocation_noArgs() async { - var result = await _getExpressionValue( - "const C()", - context: 'class C {const C();}', - ); - expect(result.isValid, isTrue); - DartObject value = result.value!; - assertType(value.type, 'C'); - } - - test_constructorInvocation_noConstConstructor() async { - var result = await _getExpressionValue( - "const C()", - context: 'class C {}', - ); - expect(result.isValid, isFalse); - var value = result.value; - expect(value, isNull); - } - - test_constructorInvocation_simpleArgs() async { - var result = await _getExpressionValue("const C(1)", context: ''' -class C { - const C(int x); -} -'''); - expect(result.isValid, isTrue); - DartObject value = result.value!; - assertType(value.type, 'C'); - } - - test_constructorReference_generic_named() async { - var result = await _getExpressionValue("C.foo", context: ''' -class C { - C.foo(); -} -'''); - expect(result.isValid, isTrue); - DartObject value = result.value!; - assertType(value.type, 'C Function()'); - } - - test_constructorReference_generic_unnamed() async { - var result = await _getExpressionValue("C.new", context: ''' -class C { - C.new(); -} -'''); - expect(result.isValid, isTrue); - DartObject value = result.value!; - assertType(value.type, 'C Function()'); - } - - test_constructorReference_nonGeneric_named() async { - var result = await _getExpressionValue("C.foo", context: ''' -class C { - const C.foo(); -} -'''); - expect(result.isValid, isTrue); - DartObject value = result.value!; - assertType(value.type, 'C Function()'); - } - - test_constructorReference_nonGeneric_unnamed() async { - var result = await _getExpressionValue("C.new", context: ''' -class C { - const C(); -} -'''); - expect(result.isValid, isTrue); - DartObject value = result.value!; - assertType(value.type, 'C Function()'); - } - - test_divide_double_double() async { - await _assertValueDouble(3.2 / 2.3, "3.2 / 2.3"); - } - - test_divide_double_double_byZero() async { - var result = await _getExpressionValue("3.2 / 0.0"); - expect(result.isValid, isTrue); - DartObject value = result.value!; - assertType(value.type, "double"); - expect(value.toDoubleValue()!.isInfinite, isTrue); - } - - test_divide_int_int() async { - await _assertValueDouble(1.5, "3 / 2"); - } - - test_divide_int_int_byZero() async { - var result = await _getExpressionValue("3 / 0"); - expect(result.isValid, isTrue); - } - - test_equal_boolean_boolean() async { - await _assertValueBool(false, "true == false"); - } - - test_equal_int_int() async { - await _assertValueBool(false, "2 == 3"); - } - - test_equal_invalidLeft() async { - var result = await _getExpressionValue("a == 3"); - expect(result.isValid, isFalse); - } - - test_equal_invalidRight() async { - var result = await _getExpressionValue("2 == a"); - expect(result.isValid, isFalse); - } - - test_equal_string_string() async { - await _assertValueBool(false, "'a' == 'b'"); - } - - test_greaterThan_int_int() async { - await _assertValueBool(false, "2 > 3"); - } - - test_greaterThanOrEqual_int_int() async { - await _assertValueBool(false, "2 >= 3"); - } - - @failingTest - test_identifier_class() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - @failingTest - test_identifier_function() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - @failingTest - test_identifier_static() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - @failingTest - test_identifier_staticMethod() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - @failingTest - test_identifier_topLevel() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - @failingTest - test_identifier_typeParameter() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - test_lessThan_int_int() async { - await _assertValueBool(true, "2 < 3"); - } - - test_lessThanOrEqual_int_int() async { - await _assertValueBool(true, "2 <= 3"); - } - - test_literal_boolean_false() async { - await _assertValueBool(false, "false"); - } - - test_literal_boolean_true() async { - await _assertValueBool(true, "true"); - } - - test_literal_list() async { - var result = await _getExpressionValue("const ['a', 'b', 'c']"); - expect(result.isValid, isTrue); - } - - test_literal_list_explicitType() async { - var result = await _getExpressionValue("const ['a', 'b', 'c']"); - expect(result.isValid, isTrue); - } - - test_literal_list_explicitType_functionType() async { - var result = await _getExpressionValue("const []"); - expect(result.isValid, isTrue); - } - - test_literal_list_forElement() async { - var result = await _getExpressionValue(''' -const [for (var i = 0; i < 4; i++) i] -'''); - expect(result.isValid, isFalse); - expect(result.errors, isNotEmpty); - } - - test_literal_map() async { - var result = await _getExpressionValue( - "const {'a' : 'm', 'b' : 'n', 'c' : 'o'}", - ); - expect(result.isValid, isTrue); - var map = result.value!.toMapValue()!; - expect(map.keys.map((k) => k!.toStringValue()), ['a', 'b', 'c']); - } - - test_literal_null() async { - var result = await _getExpressionValue("null"); - expect(result.isValid, isTrue); - DartObject value = result.value!; - expect(value.isNull, isTrue); - } - - test_literal_number_double() async { - await _assertValueDouble(3.45, "3.45"); - } - - test_literal_number_integer() async { - await _assertValueInt(42, "42"); - } - - test_literal_string_adjacent() async { - await _assertValueString("abcdef", "'abc' 'def'"); - } - - test_literal_string_interpolation_invalid() async { - var result = await _getExpressionValue("'a\${f()}c'"); - expect(result.isValid, isFalse); - } - - test_literal_string_interpolation_valid() async { - await _assertValueString("a3c", "'a\${3}c'"); - } - - test_literal_string_simple() async { - await _assertValueString("abc", "'abc'"); - } - - test_logicalAnd() async { - await _assertValueBool(false, "true && false"); - } - - test_logicalNot() async { - await _assertValueBool(false, "!true"); - } - - test_logicalOr() async { - await _assertValueBool(true, "true || false"); - } - - test_minus_double_double() async { - await _assertValueDouble(3.2 - 2.3, "3.2 - 2.3"); - } - - test_minus_int_int() async { - await _assertValueInt(1, "3 - 2"); - } - - test_negated_boolean() async { - var result = await _getExpressionValue("-true"); - expect(result.isValid, isFalse); - } - - test_negated_double() async { - await _assertValueDouble(-42.3, "-42.3"); - } - - test_negated_integer() async { - 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"); - } - - test_notEqual_int_int() async { - await _assertValueBool(true, "2 != 3"); - } - - test_notEqual_invalidLeft() async { - var result = await _getExpressionValue("a != 3"); - expect(result.isValid, isFalse); - } - - test_notEqual_invalidRight() async { - var result = await _getExpressionValue("2 != a"); - expect(result.isValid, isFalse); - } - - test_notEqual_string_string() async { - await _assertValueBool(true, "'a' != 'b'"); - } - - test_object_enum() async { - await resolveTestCode(''' -enum E { v1, v2 } -const x1 = E.v1; -const x2 = E.v2; -'''); - - _assertTopVarConstValue('x1', r''' -E - _name: String v1 - index: int 0 - variable: self::@variable::x1 -'''); - - _assertTopVarConstValue('x2', r''' -E - _name: String v2 - index: int 1 - variable: self::@variable::x2 -'''); - } - - /// Enum constants can reference other constants. - test_object_enum_enhanced_constants() async { - await assertNoErrorsInCode(''' -enum E { - v1(42), v2(v1); - final Object? a; - const E([this.a]); -} -'''); - - assertDartObjectText(findElement.field('v2').evaluationResult.value, r''' -E - _name: String v2 - a: E - _name: String v1 - a: int 42 - index: int 0 - variable: self::@enum::E::@field::v1 - index: int 1 - variable: self::@enum::E::@field::v2 -'''); - } - - test_object_enum_enhanced_named() async { - await resolveTestCode(''' -enum E { - v1.named(10), - v2.named(20); - final T f; - const E.named(this.f); -} - -const x1 = E.v1; -const x2 = E.v2; -'''); - - _assertTopVarConstValue('x1', r''' -E - _name: String v1 - f: double 10.0 - index: int 0 - variable: self::@variable::x1 -'''); - - _assertTopVarConstValue('x2', r''' -E - _name: String v2 - f: int 20 - index: int 1 - variable: self::@variable::x2 -'''); - } - - test_object_enum_enhanced_unnamed() async { - await resolveTestCode(''' -enum E { - v1(10), - v2(20), - v3('abc'); - final T f; - const E(this.f); -} - -const x1 = E.v1; -const x2 = E.v2; -const x3 = E.v3; -'''); - - _assertTopVarConstValue('x1', r''' -E - _name: String v1 - f: int 10 - index: int 0 - variable: self::@variable::x1 -'''); - - _assertTopVarConstValue('x2', r''' -E - _name: String v2 - f: int 20 - index: int 1 - variable: self::@variable::x2 -'''); - - _assertTopVarConstValue('x3', r''' -E - _name: String v3 - f: String abc - index: int 2 - variable: self::@variable::x3 -'''); - } - - test_parenthesizedExpression() async { - await _assertValueString("a", "('a')"); - } - - test_plus_double_double() async { - await _assertValueDouble(2.3 + 3.2, "2.3 + 3.2"); - } - - test_plus_int_int() async { - await _assertValueInt(5, "2 + 3"); - } - - test_plus_string_string() async { - await _assertValueString("ab", "'a' + 'b'"); - } - - @failingTest - test_prefixedIdentifier_invalid() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - @failingTest - test_prefixedIdentifier_valid() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - @failingTest - test_propertyAccess_invalid() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - @failingTest - test_propertyAccess_valid() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - test_record_mixed() async { - await assertNoErrorsInCode(r''' -const x = (0, f1: 10, f2: 2.3); -'''); - - final value = _topVarConstValue('x'); - assertDartObjectText(value, r''' -Record(int, {int f1, double f2}) - positionalFields - $1: int 0 - namedFields - f1: int 10 - f2: double 2.3 - variable: self::@variable::x -'''); - } - - test_record_named() async { - await assertNoErrorsInCode(r''' -const x = (f1: 10, f2: -3); -'''); - - final value = _topVarConstValue('x'); - assertDartObjectText(value, r''' -Record({int f1, int f2}) - namedFields - f1: int 10 - f2: int -3 - variable: self::@variable::x -'''); - } - - test_record_positional() async { - await assertNoErrorsInCode(r''' -const x = (20, 0, 7); -'''); - - final value = _topVarConstValue('x'); - assertDartObjectText(value, r''' -Record(int, int, int) - positionalFields - $1: int 20 - $2: int 0 - $3: int 7 - variable: self::@variable::x -'''); - } - - @failingTest - test_simpleIdentifier_invalid() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - @failingTest - test_simpleIdentifier_valid() async { - var result = await _getExpressionValue("?"); - expect(result.isValid, isTrue); - var value = result.value; - expect(value, null); - } - - test_stringLength_complex() async { - await _assertValueInt(6, "('qwe' + 'rty').length"); - } - - test_stringLength_simple() async { - await _assertValueInt(6, "'Dvorak'.length"); - } - - test_superFormalParameter_explicitSuper_hasNamedArgument_requiredNamed() async { - await assertNoErrorsInCode(''' -class A { - final int a; - final int b; - const A({required this.a, required this.b}); -} - -class B extends A { - final int c; - const B(this.c, {required super.b}) : super(a: 1); -} - -const x = B(3, b: 2); -'''); - - var value = findElement.topVar('x').evaluationResult.value; - assertDartObjectText(value, r''' -B - (super): A - a: int 1 - b: int 2 - c: int 3 - variable: self::@variable::x -'''); - } - - test_superFormalParameter_explicitSuper_hasNamedArgument_requiredPositional() async { - await assertNoErrorsInCode(''' -class A { - final int a; - final int b; - const A(this.a, {required this.b}); -} - -class B extends A { - final int c; - const B(super.a, {required this.c}) : super(b: 2); -} - -const x = B(1, c: 3); -'''); - - var value = findElement.topVar('x').evaluationResult.value; - assertDartObjectText(value, r''' -B - (super): A - a: int 1 - b: int 2 - c: int 3 - variable: self::@variable::x -'''); - } - - test_superFormalParameter_explicitSuper_requiredNamed() async { - await assertNoErrorsInCode(''' -class A { - final int a; - const A({required this.a}); -} - -class B extends A { - final int b; - const B(this.b, {required super.a}) : super(); -} - -const x = B(2, a: 1); -'''); - - var value = findElement.topVar('x').evaluationResult.value; - assertDartObjectText(value, r''' -B - (super): A - a: int 1 - b: int 2 - variable: self::@variable::x -'''); - } - - test_superFormalParameter_explicitSuper_requiredNamed_generic() async { - await assertNoErrorsInCode(''' -class A { - final int a; - const A({required this.a}); -} - -class B extends A { - final int b; - const B(this.b, {required super.a}) : super(); -} - -const x = B(2, a: 1); -'''); - - var value = findElement.topVar('x').evaluationResult.value; - assertDartObjectText(value, r''' -B - (super): A - a: int 1 - b: int 2 - variable: self::@variable::x -'''); - } - - test_superFormalParameter_explicitSuper_requiredPositional() async { - await assertNoErrorsInCode(''' -class A { - final int a; - const A(this.a); -} - -class B extends A { - final int b; - const B(super.a, this.b) : super(); -} - -const x = B(1, 2); -'''); - - var value = findElement.topVar('x').evaluationResult.value; - assertDartObjectText(value, r''' -B - (super): A - a: int 1 - b: int 2 - variable: self::@variable::x -'''); - } - - test_superFormalParameter_explicitSuper_requiredPositional_generic() async { - await assertNoErrorsInCode(''' -class A { - final int a; - const A(this.a); -} - -class B extends A { - final int b; - const B(super.a, this.b) : super(); -} - -const x = B(1, 2); -'''); - - var value = findElement.topVar('x').evaluationResult.value; - assertDartObjectText(value, r''' -B - (super): A - a: int 1 - b: int 2 - variable: self::@variable::x -'''); - } - - test_superFormalParameter_implicitSuper_requiredNamed() async { - await assertNoErrorsInCode(''' -class A { - final int a; - const A({required this.a}); -} - -class B extends A { - final int b; - const B(this.b, {required super.a}); -} - -const x = B(2, a: 1); -'''); - - var value = findElement.topVar('x').evaluationResult.value; - assertDartObjectText(value, r''' -B - (super): A - a: int 1 - b: int 2 - variable: self::@variable::x -'''); - } - - test_superFormalParameter_implicitSuper_requiredNamed_generic() async { - await assertNoErrorsInCode(''' -class A { - final int a; - const A({required this.a}); -} - -class B extends A { - final int b; - const B(this.b, {required super.a}); -} - -const x = B(2, a: 1); -'''); - - var value = findElement.topVar('x').evaluationResult.value; - assertDartObjectText(value, r''' -B - (super): A - a: int 1 - b: int 2 - variable: self::@variable::x -'''); - } - - test_superFormalParameter_implicitSuper_requiredPositional() async { - await assertNoErrorsInCode(''' -class A { - final int a; - const A(this.a); -} - -class B extends A { - final int b; - const B(super.a, this.b); -} - -const x = B(1, 2); -'''); - - var value = findElement.topVar('x').evaluationResult.value; - assertDartObjectText(value, r''' -B - (super): A - a: int 1 - b: int 2 - variable: self::@variable::x -'''); - } - - test_superFormalParameter_implicitSuper_requiredPositional_generic() async { - await assertNoErrorsInCode(''' -class A { - final int a; - const A(this.a); -} - -class B extends A { - final int b; - const B(super.a, this.b); -} - -const x = B(1, 2); -'''); - - var value = findElement.topVar('x').evaluationResult.value; - assertDartObjectText(value, r''' -B - (super): A - a: int 1 - b: int 2 - variable: self::@variable::x -'''); - } - - test_unknownConstuctor() async { - await assertErrorsInCode(''' -class C { - const C.named(); -} - -const x = C.(); -''', [ - // TODO(https://github.com/dart-lang/sdk/issues/50441): This should not be - // reported. - error(CompileTimeErrorCode.CLASS_INSTANTIATION_ACCESS_TO_UNKNOWN_MEMBER, - 45, 8), - error(ParserErrorCode.MISSING_IDENTIFIER, 52, 1), - ]); - - var result = findElement.topVar('x').evaluationResult; - assertDartObjectText(result.value, r''' - -'''); - } - - test_variable_alias() async { - await resolveTestCode(''' -const a = 42; -const b = a; -'''); - - final a_result = findElement.topVar('a').evaluationResult; - assertDartObjectText(a_result.value, r''' -int 42 - variable: self::@variable::a -'''); - - final b_result = findElement.topVar('b').evaluationResult; - assertDartObjectText(b_result.value, r''' -int 42 - variable: self::@variable::b -'''); - } - - test_variable_list_elements() async { - await resolveTestCode(''' -const a = 0; -const b = 2; -const c = [a, 1, b]; -'''); - - final b_result = findElement.topVar('c').evaluationResult; - assertDartObjectText(b_result.value, r''' -List - elementType: int - elements - int 0 - variable: self::@variable::a - int 1 - int 2 - variable: self::@variable::b - variable: self::@variable::c -'''); - } - - void _assertTopVarConstValue(String name, String expected) { - assertDartObjectText(_topVarConstResult(name).value, expected); - } - - Future _assertValueBool(bool expectedValue, String contents) async { - var result = await _getExpressionValue(contents); - DartObject value = result.value!; - assertType(value.type, "bool"); - expect(value.toBoolValue(), expectedValue); - } - - Future _assertValueDouble(double expectedValue, String contents) async { - var result = await _getExpressionValue(contents); - expect(result.isValid, isTrue); - DartObject value = result.value!; - assertType(value.type, "double"); - expect(value.toDoubleValue(), expectedValue); - } - - Future _assertValueInt(int expectedValue, String contents) async { - var result = await _getExpressionValue(contents); - expect(result.isValid, isTrue); - DartObject value = result.value!; - assertType(value.type, "int"); - expect(value.toIntValue(), expectedValue); - } - - Future _assertValueString(String expectedValue, String contents) async { - var result = await _getExpressionValue(contents); - DartObject value = result.value!; - assertType(value.type, 'String'); - } - - Future _getExpressionValue(String expressionCode, - {String context = ''}) async { - await resolveTestCode(''' -var x = $expressionCode; - -$context -'''); - - var expression = findNode.variableDeclaration('x =').initializer!; - - var file = getFile(result.path); - var evaluator = ConstantEvaluator( - file.createSource(result.uri), - result.libraryElement as LibraryElementImpl, - ); - - 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!; - } - - DartObjectImpl _topVarConstValue(String name) { - return _topVarConstResult(name).value!; - } -} - -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; - var evaluationResult = constVariable.evaluationResult; - if (evaluationResult == null) { - fail('Not evaluated: $this'); - } - return evaluationResult; - } -} diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart index 0281d0e025a..931d89ab955 100644 --- a/pkg/analyzer/test/generated/test_all.dart +++ b/pkg/analyzer/test/generated/test_all.dart @@ -9,7 +9,6 @@ import 'class_member_parser_test.dart' as class_member_parser; import 'collection_literal_parser_test.dart' as collection_literal_parser; import 'complex_parser_test.dart' as complex_parser; // ignore: deprecated_member_use_from_same_package -import 'constant_test.dart' as constant_test; import 'element_resolver_test.dart' as element_resolver_test; import 'error_parser_test.dart' as error_parser; import 'error_suppression_test.dart' as error_suppression; @@ -51,7 +50,6 @@ main() { class_member_parser.main(); collection_literal_parser.main(); complex_parser.main(); - constant_test.main(); element_resolver_test.main(); error_parser.main(); error_suppression.main(); diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart index b5630278553..2d96b5ed6c7 100644 --- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart +++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart @@ -2,14 +2,17 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analyzer/dart/analysis/declared_variables.dart'; import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/constant/value.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/error/listener.dart'; +import 'package:analyzer/src/dart/constant/evaluation.dart'; +import 'package:analyzer/src/dart/constant/value.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/error/syntactic_errors.dart'; import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/generated/constant.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -36,6 +39,135 @@ const int x = 'foo'; ]); } + /// Enum constants can reference other constants. + test_enum_enhanced_constants() async { + await assertNoErrorsInCode(''' +enum E { + v1(42), v2(v1); + final Object? a; + const E([this.a]); +} +'''); + assertDartObjectText(_field('v2'), r''' +E + _name: String v2 + a: E + _name: String v1 + a: int 42 + index: int 0 + variable: self::@enum::E::@field::v1 + index: int 1 + variable: self::@enum::E::@field::v2 +'''); + } + + test_enum_enhanced_named() async { + await resolveTestCode(''' +enum E { + v1.named(10), + v2.named(20); + final T f; + const E.named(this.f); +} + +const x1 = E.v1; +const x2 = E.v2; +'''); + assertDartObjectText(_topLevelVar('x1'), r''' +E + _name: String v1 + f: double 10.0 + index: int 0 + variable: self::@variable::x1 +'''); + assertDartObjectText(_topLevelVar('x2'), r''' +E + _name: String v2 + f: int 20 + index: int 1 + variable: self::@variable::x2 +'''); + } + + test_enum_enhanced_unnamed() async { + await resolveTestCode(''' +enum E { + v1(10), + v2(20), + v3('abc'); + final T f; + const E(this.f); +} + +const x1 = E.v1; +const x2 = E.v2; +const x3 = E.v3; +'''); + assertDartObjectText(_topLevelVar('x1'), r''' +E + _name: String v1 + f: int 10 + index: int 0 + variable: self::@variable::x1 +'''); + assertDartObjectText(_topLevelVar('x2'), r''' +E + _name: String v2 + f: int 20 + index: int 1 + variable: self::@variable::x2 +'''); + assertDartObjectText(_topLevelVar('x3'), r''' +E + _name: String v3 + f: String abc + index: int 2 + variable: self::@variable::x3 +'''); + } + + test_enum_simple() async { + await resolveTestCode(''' +enum E { v1, v2 } +const x1 = E.v1; +const x2 = E.v2; +'''); + assertDartObjectText(_topLevelVar('x1'), r''' +E + _name: String v1 + index: int 0 + variable: self::@variable::x1 +'''); + assertDartObjectText(_topLevelVar('x2'), r''' +E + _name: String v2 + index: int 1 + variable: self::@variable::x2 +'''); + } + + test_equalEqual_bool_bool_false() async { + await assertNoErrorsInCode(''' +const v = true == false; +'''); + final result = _topLevelVar('v'); + assertDartObjectText(result, ''' +bool false + variable: self::@variable::v +'''); + } + + test_equalEqual_bool_bool_true() async { + await assertNoErrorsInCode(''' +const v = true == true; +'''); + final result = _topLevelVar('v'); + assertDartObjectText(result, ''' +bool true + variable: self::@variable::v +'''); + } + test_equalEqual_double_object() async { await assertNoErrorsInCode(''' const v = 1.2 == Object(); @@ -107,6 +239,26 @@ bool false '''); } + test_equalEqual_invalidLeft() async { + await assertErrorsInCode(''' +const v = a == 1; +''', [ + error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 10, 1), + error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 10, + 1), + ]); + } + + test_equalEqual_invalidRight() async { + await assertErrorsInCode(''' +const v = 1 == a; +''', [ + error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 15, 1), + error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 15, + 1), + ]); + } + test_equalEqual_null_object() async { await assertNoErrorsInCode(''' const Object? a = null; @@ -573,6 +725,28 @@ const v2 = v1 + v1; _assertNull(result); } + test_visitBinaryExpression_gt_int_int() async { + await assertNoErrorsInCode(''' +const c = 2 > 3; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +bool false + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_gte_int_int() async { + await assertNoErrorsInCode(''' +const c = 2 >= 3; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +bool false + variable: self::@variable::c +'''); + } + test_visitBinaryExpression_gtGtGt_negative_fewerBits() async { await assertNoErrorsInCode(''' const c = 0xFFFFFFFF >>> 8; @@ -685,6 +859,28 @@ int 0xff '''); } + test_visitBinaryExpression_lt_int_int() async { + await assertNoErrorsInCode(''' +const c = 2 < 3; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +bool true + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_lte_int_int() async { + await assertNoErrorsInCode(''' +const c = 2 <= 3; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +bool true + variable: self::@variable::c +'''); + } + test_visitBinaryExpression_questionQuestion_invalid_notNull() async { await assertErrorsInCode(''' final x = 0; @@ -834,6 +1030,40 @@ class A { ]); } + test_visitConstructorReference_generic_named() async { + await assertNoErrorsInCode(''' +class C { + C.foo(); +} +const c = C.foo; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +C Function() + element: self::@class::C::@constructor::foo + typeArguments + int + variable: self::@variable::c +'''); + } + + test_visitConstructorReference_generic_unnamed() async { + await assertNoErrorsInCode(''' +class C { + C(); +} +const c = C.new; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +C Function() + element: self::@class::C::@constructor::new + typeArguments + int + variable: self::@variable::c +'''); + } + test_visitConstructorReference_identical_aliasIsNotGeneric() async { await assertNoErrorsInCode(''' class C {} @@ -1109,6 +1339,40 @@ bool false '''); } + test_visitConstructorReference_nonGeneric_named() async { + await assertNoErrorsInCode(''' +class C { + const C.foo(); +} +const c = C.foo; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +C Function() + element: self::@class::C::@constructor::foo + typeArguments + int + variable: self::@variable::c +'''); + } + + test_visitConstructorReference_nonGeneric_unnamed() async { + await assertNoErrorsInCode(''' +class C { + const C(); +} +const c = C.new; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +C Function() + element: self::@class::C::@constructor::new + typeArguments + int + variable: self::@variable::c +'''); + } + test_visitFunctionReference_defaultConstructorValue() async { await assertErrorsInCode(r''' void f(T t) => t; @@ -1476,6 +1740,61 @@ bool true '''); } + test_visitInstanceCreationExpression_noArgs() async { + await assertNoErrorsInCode(''' +class A { + const A(); +} +const a = A(); +'''); + final result = _topLevelVar('a'); + assertDartObjectText(result, r''' +A + variable: self::@variable::a +'''); + } + + test_visitInstanceCreationExpression_noConstConstructor() async { + await assertErrorsInCode(''' +class A {} +const a = A(); +''', [ + error(CompileTimeErrorCode.CONST_WITH_NON_CONST, 21, 3), + error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 21, + 3), + ]); + } + + test_visitInstanceCreationExpression_simpleArgs() async { + await assertNoErrorsInCode(''' +class A { + const A(int x); +} +const a = A(1); +'''); + final result = _topLevelVar('a'); + assertDartObjectText(result, r''' +A + variable: self::@variable::a +'''); + } + + test_visitInstanceCreationExpression_unknown() async { + await assertErrorsInCode(''' +class C { + const C.named(); +} + +const x = C.(); +''', [ + // TODO(https://github.com/dart-lang/sdk/issues/50441): This should not be + // reported. + error(CompileTimeErrorCode.CLASS_INSTANTIATION_ACCESS_TO_UNKNOWN_MEMBER, + 45, 8), + error(ParserErrorCode.MISSING_IDENTIFIER, 52, 1), + ]); + } + test_visitInterpolationExpression_list() async { await assertErrorsInCode(r''' const x = '${const [2]}'; @@ -1656,6 +1975,70 @@ const x = [1, if (1) 2 else 3, 4]; _assertNull(result); } + test_visitListLiteral_listElement_explicitType() async { + await assertNoErrorsInCode(r''' +const x = ['a', 'b', 'c']; +'''); + final result = _topLevelVar('x'); + assertDartObjectText(result, r''' +List + elementType: String + elements + String a + String b + String c + variable: self::@variable::x +'''); + } + + test_visitListLiteral_listElement_explicitType_functionType() async { + await assertNoErrorsInCode(r''' +const x = []; +'''); + final result = _topLevelVar('x'); + assertDartObjectText(result, r''' +List + elementType: void Function() + variable: self::@variable::x +'''); + } + + test_visitListLiteral_listElement_simple() async { + await assertNoErrorsInCode(r''' +const x = ['a', 'b', 'c']; +'''); + final result = _topLevelVar('x'); + assertDartObjectText(result, r''' +List + elementType: String + elements + String a + String b + String c + variable: self::@variable::x +'''); + } + + test_visitListLiteral_listElement_variableElements() async { + await assertNoErrorsInCode(r''' +const a = 0; +const b = 2; +const c = [a, 1, b]; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +List + elementType: int + elements + int 0 + variable: self::@variable::a + int 1 + int 2 + variable: self::@variable::b + variable: self::@variable::c +'''); + } + test_visitListLiteral_spreadElement() async { await assertErrorsInCode(r''' const dynamic a = 5; @@ -1778,40 +2161,7 @@ void Function(T) '''); } - test_visitPrefixExpression_extensionMethod() async { - await assertErrorsInCode(''' -extension on Object { - int operator -() => 0; -} - -const Object v1 = 1; -const v2 = -v1; -''', [ - error(CompileTimeErrorCode.CONST_EVAL_EXTENSION_METHOD, 82, 3), - ]); - final result = _topLevelVar('v2'); - _assertNull(result); - } - - test_visitPropertyAccess_genericFunction_instantiated() async { - await assertNoErrorsInCode(''' -import '' as self; -class C { - static void f(T a) {} -} -const void Function(int) g = self.C.f; -'''); - final result = _topLevelVar('g'); - assertDartObjectText(result, ''' -void Function(int) - element: self::@class::C::@method::f - typeArguments - int - variable: self::@variable::g -'''); - } - - test_visitPropertyAccess_length_invalidTarget() async { + test_visitPrefixedIdentifier_length_invalidTarget() async { await assertErrorsInCode(''' void main() { const RequiresNonEmptyList([1]); @@ -1834,6 +2184,144 @@ class RequiresNonEmptyList { ]); } + test_visitPrefixExpression_bitNot() async { + await assertNoErrorsInCode(''' +const c = ~42; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, ''' +int -43 + variable: self::@variable::c +'''); + } + + test_visitPrefixExpression_extensionMethod() async { + await assertErrorsInCode(''' +extension on Object { + int operator -() => 0; +} + +const Object v1 = 1; +const v2 = -v1; +''', [ + error(CompileTimeErrorCode.CONST_EVAL_EXTENSION_METHOD, 82, 3), + ]); + final result = _topLevelVar('v2'); + _assertNull(result); + } + + test_visitPrefixExpression_logicalNot() async { + await assertNoErrorsInCode(''' +const c = !true; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +bool false + variable: self::@variable::c +'''); + } + + test_visitPrefixExpression_negated_bool() async { + await assertErrorsInCode(''' +const c = -true; +''', [ + error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 10, 1), + error(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM, 10, 5), + ]); + } + + test_visitPrefixExpression_negated_double() async { + await assertNoErrorsInCode(''' +const c = -42.3; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +double -42.3 + variable: self::@variable::c +'''); + } + + test_visitPrefixExpression_negated_int() async { + await assertNoErrorsInCode(''' +const c = -42; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +int -42 + variable: self::@variable::c +'''); + } + + test_visitPropertyAccess_genericFunction_instantiated() async { + await assertNoErrorsInCode(''' +import '' as self; +class C { + static void f(T a) {} +} +const void Function(int) g = self.C.f; +'''); + final result = _topLevelVar('g'); + assertDartObjectText(result, ''' +void Function(int) + element: self::@class::C::@method::f + typeArguments + int + variable: self::@variable::g +'''); + } + + test_visitPropertyAccess_length_complex() async { + await assertNoErrorsInCode(''' +const x = ('qwe' + 'rty').length; +'''); + final result = _topLevelVar('x'); + assertDartObjectText(result, r''' +int 6 + variable: self::@variable::x +'''); + } + + test_visitPropertyAccess_length_simple() async { + await assertNoErrorsInCode(''' +const x = 'Dvorak'.length; +'''); + final result = _topLevelVar('x'); + assertDartObjectText(result, r''' +int 6 + variable: self::@variable::x +'''); + } + + test_visitRecordLiteral_mixedTypes() async { + await assertNoErrorsInCode(r''' +const x = (0, f1: 10, f2: 2.3); +'''); + final result = _topLevelVar('x'); + assertDartObjectText(result, r''' +Record(int, {int f1, double f2}) + positionalFields + $1: int 0 + namedFields + f1: int 10 + f2: double 2.3 + variable: self::@variable::x +'''); + } + + test_visitRecordLiteral_named() async { + await assertNoErrorsInCode(r''' +const x = (f1: 10, f2: -3); +'''); + final result = _topLevelVar('x'); + assertDartObjectText(result, r''' +Record({int f1, int f2}) + namedFields + f1: int 10 + f2: int -3 + variable: self::@variable::x +'''); + } + test_visitRecordLiteral_objectField_generic() async { await assertNoErrorsInCode(r''' class A { @@ -1854,6 +2342,21 @@ A '''); } + test_visitRecordLiteral_positional() async { + await assertNoErrorsInCode(r''' +const x = (20, 0, 7); +'''); + final result = _topLevelVar('x'); + assertDartObjectText(result, r''' +Record(int, int, int) + positionalFields + $1: int 20 + $2: int 0 + $3: int 7 + variable: self::@variable::x +'''); + } + test_visitRecordLiteral_withoutEnvironment() async { await assertNoErrorsInCode(r''' const a = (1, 'b', c: false); @@ -1870,19 +2373,28 @@ Record(int, String, {bool c}) '''); } - test_visitSetOrMapLiteral_double_zeros() async { + test_visitSetOrMapLiteral_map_complexKey() async { await assertNoErrorsInCode(r''' -class C { - final double x; - const C(this.x); -} - -const cp0 = C(0.0); -const cm0 = C(-0.0); - -main(){ - print(const{cp0, cm0}); +class A { + final int x; + const A(this.x); } +void fn() => 2; +const x = {A(0): 1, fn: 2}; +'''); + final result = _topLevelVar('x'); + assertDartObjectText(result, r''' +Map + entries + entry + key: A + x: int 0 + value: int 1 + entry + key: void Function() + element: self::@function::fn + value: int 2 + variable: self::@variable::x '''); } @@ -1921,6 +2433,53 @@ const c = const {if (nonBool) 'a' : 1}; _assertNull(result); } + test_visitSetOrMapLiteral_map_mapElement() async { + await assertNoErrorsInCode(r''' +const x = {'a' : 'm', 'b' : 'n', 'c' : 'o'}; +'''); + final result = _topLevelVar('x'); + assertDartObjectText(result, ''' +Map + entries + entry + key: String a + value: String m + entry + key: String b + value: String n + entry + key: String c + value: String o + variable: self::@variable::x +'''); + } + + test_visitSetOrMapLiteral_set_double_zeros() async { + await assertNoErrorsInCode(r''' +class C { + final double x; + const C(this.x); +} + +const cp0 = C(0.0); +const cm0 = C(-0.0); + +const a = {cp0, cm0}; +'''); + final result = _topLevelVar('a'); + assertDartObjectText(result, ''' +Set + elements + C + x: double 0.0 + variable: self::@variable::cp0 + C + x: double -0.0 + variable: self::@variable::cm0 + variable: self::@variable::a +'''); + } + test_visitSetOrMapLiteral_set_forElement() async { await assertErrorsInCode(r''' const Set set = {}; @@ -2295,6 +2854,17 @@ const c = {1, ...{2, 3}, 4}; expect(result.toSetValue()!.map((e) => e.toIntValue()), [1, 2, 3, 4]); } + test_visitAdjacentInterpolation_simple() async { + await assertNoErrorsInCode(''' +const c = 'abc' 'def'; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, ''' +String abcdef + variable: self::@variable::c +'''); + } + test_visitAsExpression_instanceOfSameClass() async { await resolveTestCode(''' const a = const A(); @@ -2371,6 +2941,50 @@ class MyClass { '''); } + test_visitBinaryExpression_add_double_double() async { + await assertNoErrorsInCode(''' +const c = 2.3 + 3.2; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +double 5.5 + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_add_int_int() async { + await assertNoErrorsInCode(''' +const c = 2 + 3; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +int 5 + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_add_string_string() async { + await assertNoErrorsInCode(''' +const c = 'a' + 'b'; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +String ab + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_and_bool_bool() async { + await assertNoErrorsInCode(''' +const c = true && false; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +bool false + variable: self::@variable::c +'''); + } + test_visitBinaryExpression_and_bool_false_invalid() async { await assertErrorsInCode(''' final a = false; @@ -2451,11 +3065,14 @@ const c = a & b; } test_visitBinaryExpression_and_int() async { - await resolveTestCode(''' -const c = 3 & 5; + await assertNoErrorsInCode(''' +const c = 74 & 42; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +int 10 + variable: self::@variable::c '''); - DartObjectImpl result = _evaluateConstant('c'); - expect(result.type, typeProvider.intType); } test_visitBinaryExpression_and_mixed() async { @@ -2467,6 +3084,125 @@ const c = 3 & false; ]); } + test_visitBinaryExpression_divide_double_double() async { + await assertNoErrorsInCode(''' +const c = 3.2 / 2.3; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +double 1.3913043478260871 + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_divide_double_double_byZero() async { + await assertNoErrorsInCode(''' +const c = 3.2 / 0.0; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +double Infinity + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_divide_int_int() async { + await assertNoErrorsInCode(''' +const c = 3 / 2; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +double 1.5 + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_divide_int_int_byZero() async { + await assertNoErrorsInCode(''' +const c = 3 / 0; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +double Infinity + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_minus_double_double() async { + await assertNoErrorsInCode(''' +const c = 3.2 - 2.3; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +double 0.9000000000000004 + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_minus_int_int() async { + await assertNoErrorsInCode(''' +const c = 3 - 2; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +int 1 + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_notEqual_bool_bool() async { + await assertNoErrorsInCode(''' +const c = true != false; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +bool true + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_notEqual_int_int() async { + await assertNoErrorsInCode(''' +const c = 2 != 3; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +bool true + variable: self::@variable::c +'''); + } + + test_visitBinaryExpression_notEqual_invalidLeft() async { + await assertErrorsInCode(''' +const c = a != 3; +''', [ + error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 10, 1), + error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 10, + 1), + ]); + } + + test_visitBinaryExpression_notEqual_invalidRight() async { + await assertErrorsInCode(''' +const c = 2 != a; +''', [ + error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 15, 1), + error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 15, + 1), + ]); + } + + test_visitBinaryExpression_notEqual_string_string() async { + await assertNoErrorsInCode(''' +const c = 'a' != 'b'; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +bool true + variable: self::@variable::c +'''); + } + test_visitBinaryExpression_or_bool_false_invalid() async { await assertErrorsInCode(''' final a = false; @@ -2554,6 +3290,19 @@ const c = 3 | 5; expect(result.type, typeProvider.intType); } + test_visitBinaryExpression_or_known_known() async { + await assertErrorsInCode(''' +const c = true || false; +''', [ + error(WarningCode.DEAD_CODE, 15, 8), + ]); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +bool true + variable: self::@variable::c +'''); + } + test_visitBinaryExpression_or_mixed() async { await assertErrorsInCode(''' const c = 3 | false; @@ -2652,6 +3401,30 @@ const c = 3 ^ false; ]); } + test_visitBoolLiteral_false() async { + await assertNoErrorsInCode(''' +const c = false; +'''); + final result = _topLevelVar('c'); + dartObjectPrinterConfiguration.withHexIntegers = true; + assertDartObjectText(result, r''' +bool false + variable: self::@variable::c +'''); + } + + test_visitBoolLiteral_true() async { + await assertNoErrorsInCode(''' +const c = true; +'''); + final result = _topLevelVar('c'); + dartObjectPrinterConfiguration.withHexIntegers = true; + assertDartObjectText(result, r''' +bool true + variable: self::@variable::c +'''); + } + test_visitConditionalExpression_eager_false_int_int() async { await assertErrorsInCode(''' const c = false ? 1 : 0; @@ -2797,7 +3570,18 @@ const c = identical(0, 0.0) ? 1 : new Object(); ]); } - test_visitIntegerLiteral() async { + test_visitDoubleLiteral() async { + await assertNoErrorsInCode(''' +const c = 3.45; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +double 3.45 + variable: self::@variable::c +'''); + } + + test_visitIntegerLiteral_doubleType() async { await resolveTestCode(''' const double d = 3; '''); @@ -2806,6 +3590,17 @@ const double d = 3; expect(result.toDoubleValue(), 3.0); } + test_visitIntegerLiteral_integer() async { + await assertNoErrorsInCode(''' +const c = 3; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +int 3 + variable: self::@variable::c +'''); + } + test_visitIsExpression_is_functionType_badTypes() async { await assertNoErrorsInCode(''' void foo(int a) {} @@ -2931,6 +3726,28 @@ bool true '''); } + test_visitNullLiteral_null() async { + await assertNoErrorsInCode(''' +const c = null; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, ''' +Null null + variable: self::@variable::c +'''); + } + + test_visitParenthesizedExpression_string() async { + await assertNoErrorsInCode(''' +const a = ('a'); +'''); + final result = _topLevelVar('a'); + assertDartObjectText(result, r''' +String a + variable: self::@variable::a +'''); + } + test_visitPropertyAccess_length_extension() async { await assertErrorsInCode(''' extension ExtObject on Object { @@ -3019,6 +3836,18 @@ int 3 '''); } + test_visitSimpleIdentifier_variable() async { + await assertNoErrorsInCode(''' +const a = 42; +const b = a; +'''); + final result = _topLevelVar('b'); + assertDartObjectText(result, ''' +int 42 + variable: self::@variable::b +'''); + } + test_visitSimpleIdentifier_withoutEnvironment() async { await assertNoErrorsInCode(r''' const a = b; @@ -3027,6 +3856,38 @@ const b = 3;'''); assertDartObjectText(result, r''' int 3 variable: self::@variable::a +'''); + } + + test_visitSimpleStringLiteral_valid() async { + await assertNoErrorsInCode(r''' +const c = 'abc'; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, ''' +String abc + variable: self::@variable::c +'''); + } + + test_visitStringInterpolation_invalid() async { + await assertErrorsInCode(r''' +const c = 'a${f()}c'; +''', [ + error(CompileTimeErrorCode.UNDEFINED_FUNCTION, 14, 1), + error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 14, + 3), + ]); + } + + test_visitStringInterpolation_valid() async { + await assertNoErrorsInCode(r''' +const c = 'a${3}c'; +'''); + final result = _topLevelVar('c'); + assertDartObjectText(result, r''' +String a3c + variable: self::@variable::c '''); } } @@ -3456,6 +4317,18 @@ A '''); } + /// See https://github.com/dart-lang/sdk/issues/50045 + test_bool_fromEnvironment_dartLibraryJsUtil() async { + await resolveTestCode(''' +const a = bool.fromEnvironment('dart.library.js_util'); +'''); + + assertDartObjectText(_topLevelVar('a'), ''' + bool + variable: self::@variable::a +'''); + } + test_fieldInitializer_functionReference_withTypeParameter() async { await assertNoErrorsInCode(''' void g(U a) {} @@ -3603,6 +4476,260 @@ A '''); } + test_superInitializer_formalParameter_explicitSuper_hasNamedArgument_requiredNamed() async { + await assertNoErrorsInCode(''' +class A { + final int a; + final int b; + const A({required this.a, required this.b}); +} + +class B extends A { + final int c; + const B(this.c, {required super.b}) : super(a: 1); +} + +const x = B(3, b: 2); +'''); + + var result = _topLevelVar('x'); + assertDartObjectText(result, r''' +B + (super): A + a: int 1 + b: int 2 + c: int 3 + variable: self::@variable::x +'''); + } + + test_superInitializer_formalParameter_explicitSuper_hasNamedArgument_requiredPositional() async { + await assertNoErrorsInCode(''' +class A { + final int a; + final int b; + const A(this.a, {required this.b}); +} + +class B extends A { + final int c; + const B(super.a, {required this.c}) : super(b: 2); +} + +const x = B(1, c: 3); +'''); + + var value = _topLevelVar('x'); + assertDartObjectText(value, r''' +B + (super): A + a: int 1 + b: int 2 + c: int 3 + variable: self::@variable::x +'''); + } + + test_superInitializer_formalParameter_explicitSuper_requiredNamed() async { + await assertNoErrorsInCode(''' +class A { + final int a; + const A({required this.a}); +} + +class B extends A { + final int b; + const B(this.b, {required super.a}) : super(); +} + +const x = B(2, a: 1); +'''); + + var value = _topLevelVar('x'); + assertDartObjectText(value, r''' +B + (super): A + a: int 1 + b: int 2 + variable: self::@variable::x +'''); + } + + test_superInitializer_formalParameter_explicitSuper_requiredNamed_generic() async { + await assertNoErrorsInCode(''' +class A { + final int a; + const A({required this.a}); +} + +class B extends A { + final int b; + const B(this.b, {required super.a}) : super(); +} + +const x = B(2, a: 1); +'''); + + var value = _topLevelVar('x'); + assertDartObjectText(value, r''' +B + (super): A + a: int 1 + b: int 2 + variable: self::@variable::x +'''); + } + + test_superInitializer_formalParameter_explicitSuper_requiredPositional() async { + await assertNoErrorsInCode(''' +class A { + final int a; + const A(this.a); +} + +class B extends A { + final int b; + const B(super.a, this.b) : super(); +} + +const x = B(1, 2); +'''); + + var value = _topLevelVar('x'); + assertDartObjectText(value, r''' +B + (super): A + a: int 1 + b: int 2 + variable: self::@variable::x +'''); + } + + test_superInitializer_formalParameter_explicitSuper_requiredPositional_generic() async { + await assertNoErrorsInCode(''' +class A { + final int a; + const A(this.a); +} + +class B extends A { + final int b; + const B(super.a, this.b) : super(); +} + +const x = B(1, 2); +'''); + + var value = _topLevelVar('x'); + assertDartObjectText(value, r''' +B + (super): A + a: int 1 + b: int 2 + variable: self::@variable::x +'''); + } + + test_superInitializer_formalParameter_implicitSuper_requiredNamed() async { + await assertNoErrorsInCode(''' +class A { + final int a; + const A({required this.a}); +} + +class B extends A { + final int b; + const B(this.b, {required super.a}); +} + +const x = B(2, a: 1); +'''); + + var value = _topLevelVar('x'); + assertDartObjectText(value, r''' +B + (super): A + a: int 1 + b: int 2 + variable: self::@variable::x +'''); + } + + test_superInitializer_formalParameter_implicitSuper_requiredNamed_generic() async { + await assertNoErrorsInCode(''' +class A { + final int a; + const A({required this.a}); +} + +class B extends A { + final int b; + const B(this.b, {required super.a}); +} + +const x = B(2, a: 1); +'''); + + var value = _topLevelVar('x'); + assertDartObjectText(value, r''' +B + (super): A + a: int 1 + b: int 2 + variable: self::@variable::x +'''); + } + + test_superInitializer_formalParameter_implicitSuper_requiredPositional() async { + await assertNoErrorsInCode(''' +class A { + final int a; + const A(this.a); +} + +class B extends A { + final int b; + const B(super.a, this.b); +} + +const x = B(1, 2); +'''); + + var value = _topLevelVar('x'); + assertDartObjectText(value, r''' +B + (super): A + a: int 1 + b: int 2 + variable: self::@variable::x +'''); + } + + test_superInitializer_formalParameter_implicitSuper_requiredPositional_generic() async { + await assertNoErrorsInCode(''' +class A { + final int a; + const A(this.a); +} + +class B extends A { + final int b; + const B(super.a, this.b); +} + +const x = B(1, 2); +'''); + + var value = _topLevelVar('x'); + assertDartObjectText(value, r''' +B + (super): A + a: int 1 + b: int 2 + variable: self::@variable::x +'''); + } + test_superInitializer_paramTypeMismatch_indirect() async { await assertErrorsInCode(''' class C { diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart index bc874e3ba4f..030358055af 100644 --- a/pkg/analyzer/test/src/dart/constant/value_test.dart +++ b/pkg/analyzer/test/src/dart/constant/value_test.dart @@ -6,8 +6,8 @@ import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/dart/element/type_provider.dart'; +import 'package:analyzer/src/dart/constant/value.dart'; import 'package:analyzer/src/dart/element/type_system.dart'; -import 'package:analyzer/src/generated/constant.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; 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 0a242358e5f..9a5811f6749 100644 --- a/pkg/analyzer/test/src/dart/resolution/dart_object_printer.dart +++ b/pkg/analyzer/test/src/dart/resolution/dart_object_printer.dart @@ -48,8 +48,12 @@ class DartObjectPrinter { _writeGenericState(type, state); } else if (state is ListState) { _writeListState(state); + } else if (state is MapState) { + _writeMapState(state); } else if (state is RecordState) { _writeRecordState(type, state); + } else if (state is SetState) { + _writeSetState(state); } else if (state is TypeState) { _sink.write('Type '); _sink.writeln(state); @@ -122,6 +126,30 @@ class DartObjectPrinter { } } + void _writeMapState(MapState state) { + _sink.writeln('Map'); + _sink.withIndent(() { + final entries = state.entries; + if (entries.isNotEmpty) { + _sink.writelnWithIndent('entries'); + _sink.withIndent(() { + for (final entry in entries.entries) { + _sink.writelnWithIndent('entry'); + _sink.withIndent(() { + _sink.writeIndent(); + _sink.write('key: '); + write(entry.key); + + _sink.writeIndent(); + _sink.write('value: '); + write(entry.value); + }); + } + }); + } + }); + } + void _writeRecordState(DartType type, RecordState state) { _sink.write('Record'); _elementPrinter.writeType(type); @@ -154,6 +182,22 @@ class DartObjectPrinter { }); } + void _writeSetState(SetState state) { + _sink.writeln('Set'); + _sink.withIndent(() { + final elements = state.elements; + if (elements.isNotEmpty) { + _sink.writelnWithIndent('elements'); + _sink.withIndent(() { + for (final element in elements) { + _sink.writeIndent(); + write(element); + } + }); + } + }); + } + void _writeString(DartObjectImpl object) { _sink.write('String ');