Skip to content

Commit

Permalink
Version 3.2.0-123.0.dev
Browse files Browse the repository at this point in the history
Merge 2ee7f1f into dev
  • Loading branch information
Dart CI committed Aug 30, 2023
2 parents 0cea73a + 2ee7f1f commit 96d3a79
Show file tree
Hide file tree
Showing 46 changed files with 764 additions and 587 deletions.
8 changes: 4 additions & 4 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ group("most") {
":create_sdk",
":dart2js",
":dartanalyzer",
":dartdevc",
":ddc",
":runtime",
]
}
Expand Down Expand Up @@ -135,13 +135,13 @@ group("dartanalyzer") {
deps = [ "utils/dartanalyzer" ]
}

# TODO(nshahan): Delete after updating the Flutter engine build.
group("dartdevc") {
deps = [ "utils/dartdevc" ]
deps = [ "utils/dartdevc:dartdevc_files_stamp" ]
}

group("ddc") {
# TODO(nshahan): Update to the dartdevc snapshot target when it gets moved.
deps = [ "utils/ddc:ddc_stable_test" ]
deps = [ "utils/ddc:dartdevc" ]
}

group("analysis_server") {
Expand Down
9 changes: 5 additions & 4 deletions pkg/analysis_server/lib/src/g3/utilities.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ String format(String content) {
/// Returns a [ParseStringResult]. If successful, the result contains the sorted
/// code. On failure, the result contains the unsorted original code, and the
/// cause of the failure, a list of [AnalysisError]'s.
ParseStringResult sortDirectives(String contents) {
var (unit, errors) = _parse(contents);
ParseStringResult sortDirectives(String contents, {String? fileName}) {
var (unit, errors) = _parse(contents, fullName: fileName);
var hasParseErrors = errors.any((error) =>
error.errorCode is ScannerErrorCode ||
error.errorCode is ParserErrorCode);
Expand All @@ -43,8 +43,9 @@ ParseStringResult sortDirectives(String contents) {
return ParseStringResultImpl(sorter.code, unit, errors);
}

(CompilationUnit, List<AnalysisError>) _parse(String contents) {
var source = StringSource(contents, null);
(CompilationUnit, List<AnalysisError>) _parse(String contents,
{String? fullName}) {
var source = StringSource(contents, fullName);
var errorListener = RecordingErrorListener();
var reader = CharSequenceReader(contents);
var featureSet = FeatureSet.fromEnableFlags2(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,8 @@ CompileTimeErrorCode.PRIVATE_SETTER:
status: noFix
CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL:
status: noFix
CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR:
status: noFix
CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT:
status: noFix
CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ base class E {
class _E {
static const _E c = _E();
// ignore: unused_element
// ignore: unused_element, recursive_constant_constructor
const _E({_E e = const _E()});
}
''');
Expand Down
13 changes: 13 additions & 0 deletions pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/constant/evaluation.dart';
import 'package:analyzer/src/dart/constant/has_type_parameter_reference.dart';
Expand Down Expand Up @@ -164,6 +165,18 @@ class ConstantVerifier extends RecursiveAstVisitor<void> {
void visitConstructorDeclaration(ConstructorDeclaration node) {
var constKeyword = node.constKeyword;
if (constKeyword != null) {
// Check and report cycles.
// Factory cycles are reported in elsewhere in
// [ErrorVerifier._checkForRecursiveFactoryRedirect].
final element = node.declaredElement;
if (element is ConstructorElementImpl &&
!element.isCycleFree &&
!element.isFactory) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR,
node.returnType, []);
}

_validateConstructorInitializers(node);
if (node.factoryKeyword == null) {
_validateFieldInitializers(
Expand Down
14 changes: 9 additions & 5 deletions pkg/analyzer/lib/src/dart/constant/evaluation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,11 @@ class ConstantEvaluationEngine {
(constant as VariableElementImpl).evaluationResult =
EvaluationResultImpl(null, errorListener.errors);
} else if (constant is ConstructorElement) {
// We don't report cycle errors on constructor declarations since there
// is nowhere to put the error information.
// We don't report cycle errors on constructor declarations here since
// there is nowhere to put the error information.
//
// Instead we will report an error at each constructor in
// [ConstantVerifier.visitConstructorDeclaration].
} else {
// Should not happen. Formal parameter defaults and annotations should
// never appear as part of a cycle because they can't be referred to.
Expand Down Expand Up @@ -3094,9 +3097,10 @@ class _InstanceCreationEvaluator {

if (!(constructor.declaration as ConstructorElementImpl).isCycleFree) {
// It's not safe to evaluate this constructor, so bail out.
// TODO(paulberry): ensure that a reasonable error message is produced
// in this case, as well as other cases involving constant expression
// cycles (e.g. "compile-time constant expression depends on itself").
//
// Instead of reporting an error at the call-sites, we will report an
// error at each constructor in
// [ConstantVerifier.visitConstructorDeclaration].
return DartObjectImpl.validWithUnknownValue(
library.typeSystem,
constructor.returnType,
Expand Down
7 changes: 7 additions & 0 deletions pkg/analyzer/lib/src/error/codes.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4306,6 +4306,13 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
hasPublishedDocs: true,
);

/// No parameters.
static const CompileTimeErrorCode RECURSIVE_CONSTANT_CONSTRUCTOR =
CompileTimeErrorCode(
'RECURSIVE_CONSTANT_CONSTRUCTOR',
"The constant constructor depends on itself.",
);

/// No parameters.
///
/// TODO(scheglov) review this later, there are no explicit "it is a
Expand Down
1 change: 1 addition & 0 deletions pkg/analyzer/lib/src/error/error_code_values.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ const List<ErrorCode> errorCodeValues = [
CompileTimeErrorCode.PRIVATE_SETTER,
CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL,
CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR,
CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT,
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
Expand Down
2 changes: 1 addition & 1 deletion pkg/analyzer/lib/src/lint/linter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import 'package:glob/glob.dart';
import 'package:path/path.dart' as p;

export 'package:analyzer/src/lint/linter_visitor.dart' show NodeLintRegistry;
export 'package:analyzer/src/lint/state.dart' show dart3, State;
export 'package:analyzer/src/lint/state.dart' show dart2_12, dart3, State;

typedef Printer = void Function(String msg);

Expand Down
3 changes: 3 additions & 0 deletions pkg/analyzer/messages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13321,6 +13321,9 @@ CompileTimeErrorCode:
const secondsPerHour = minutesPerHour * 60;
const minutesPerHour = 60;
```
RECURSIVE_CONSTANT_CONSTRUCTOR:
problemMessage: "The constant constructor depends on itself."
comment: No parameters.
RECURSIVE_CONSTRUCTOR_REDIRECT:
problemMessage: "Constructors can't redirect to themselves either directly or indirectly."
correctionMessage: Try changing one of the constructors in the loop to not redirect.
Expand Down
61 changes: 61 additions & 0 deletions pkg/analyzer/test/src/dart/constant/evaluation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,29 @@ bool true
''');
}

test_instanceCreation_generic_noTypeArguments_inferred_imported() async {
newFile('$testPackageLibPath/a.dart', r'''
class A<T> {
final T t;
const A(this.t);
}
const Object a = const A(0);
''');

await assertNoErrorsInCode('''
import 'a.dart';

const b = a;
''');

final result = _topLevelVar('b');
assertDartObjectText(result, r'''
A<int>
t: int 0
variable: self::@variable::b
''');
}

/// https://github.com/dart-lang/sdk/issues/53029
/// Dependencies of map patterns should be considered.
test_mapPattern_dependencies() async {
Expand Down Expand Up @@ -741,6 +764,44 @@ const x = kIsWeb ? a : b;
_assertNull(result);
}

test_visitConstructorDeclaration_cycle() async {
await assertErrorsInCode('''
class A {
final A a;
const A() : a = const A();
}

''', [
error(CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR, 31, 1),
]);
}

test_visitConstructorDeclaration_cycle_subclass_issue46735() async {
await assertErrorsInCode('''
void main() {
const EmptyInjector();
}

abstract class BaseInjector {
final BaseInjector parent;

const BaseInjector([BaseInjector? parent])
: parent = parent ?? const EmptyInjector();
}

abstract class Injector implements BaseInjector {
const Injector();
}

class EmptyInjector extends BaseInjector implements Injector {
const EmptyInjector();
}
''', [
error(CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR, 110, 12),
error(CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR, 344, 13),
]);
}

test_visitConstructorDeclaration_field_asExpression_nonConst() async {
await assertErrorsInCode(r'''
dynamic y = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,6 @@ enum E {
]);
}

test_field() async {
await assertErrorsInCode(r'''
class A {
const A();
final m = const A();
}
''', [
error(CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT, 31, 1),
]);
}

test_fromMapLiteral() async {
newFile(
'$testPackageLibPath/constants.dart',
Expand All @@ -87,18 +76,6 @@ final z = {x: 0, y: 1};
''');
}

test_initializer_after_toplevel_var() async {
await assertErrorsInCode('''
const y = const C();
class C {
const C() : x = y;
final x;
}
''', [
error(CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT, 6, 1),
]);
}

test_singleVariable() async {
await assertErrorsInCode(r'''
const x = x;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (c) 2023, 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/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../dart/resolution/context_collection_resolution.dart';

main() {
defineReflectiveSuite(() {
defineReflectiveTests(RecursiveConstantConstructorTest);
});
}

@reflectiveTest
class RecursiveConstantConstructorTest extends PubPackageResolutionTest {
test_field() async {
await assertErrorsInCode('''
class A {
const A();
final m = const A();
}
''', [
error(CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR, 18, 1),
error(CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT, 31, 1),
]);
}

test_initializer_after_toplevel_var() async {
await assertErrorsInCode('''
const y = const C();
class C {
const C() : x = y;
final x;
}
''', [
error(CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT, 6, 1),
error(CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR, 39, 1),
]);
}

test_initializer_field() async {
await assertErrorsInCode('''
class A {
final A a;
const A() : a = const A();
}
''', [
error(CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR, 31, 1),
]);
}

test_initializer_field_multipleClasses() async {
await assertErrorsInCode('''
class B {
final A a;
const B() : a = const A();
}
class A {
final B b;
const A() : b = const B();
}
''', [
error(CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR, 31, 1),
error(CompileTimeErrorCode.RECURSIVE_CONSTANT_CONSTRUCTOR, 85, 1),
]);
}
}
3 changes: 3 additions & 0 deletions pkg/analyzer/test/src/diagnostics/test_all.dart
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,8 @@ import 'record_literal_one_positional_no_trailing_comma_test.dart'
as record_literal_one_positional_no_trailing_comma;
import 'recursive_compile_time_constant_test.dart'
as recursive_compile_time_constant;
import 'recursive_constant_constructor_test.dart'
as recursive_constant_constructor;
import 'recursive_constructor_redirect_test.dart'
as recursive_constructor_redirect;
import 'recursive_factory_redirect_test.dart' as recursive_factory_redirect;
Expand Down Expand Up @@ -1346,6 +1348,7 @@ main() {
receiver_of_type_never.main();
record_literal_one_positional_no_trailing_comma.main();
recursive_compile_time_constant.main();
recursive_constant_constructor.main();
recursive_constructor_redirect.main();
recursive_factory_redirect.main();
recursive_interface_inheritance_extends.main();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/analysis_options/error/option_codes.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/options_rule_validator.dart';
import 'package:analyzer/src/lint/state.dart';
import 'package:analyzer/src/string_source.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:pub_semver/pub_semver.dart';
Expand Down
Loading

0 comments on commit 96d3a79

Please sign in to comment.