Version 2.15.0-296.0.dev
Merge commit 'f7af5c5256ee6f3a167f380722b96e8af4360b46' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4a37ecd..eed2f0a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+## 2.16.0
+
+### Tools
+
+#### Dart command line
+
+- **Breaking Change** [#46100][]: The standalone `dartanalyzer` tool has been
+ marked deprecated as previously announced.
+ Its replacement is the `dart analyze` command.
+ Should you find any issues, or missing features, in the replacement
+ command, kindly file [an issue]][].
+
+[an issue]: https://github.com/dart-lang/sdk/issues/new
+
## 2.15.0
### Language
@@ -323,9 +337,12 @@
#### `dart:js_util`
-- The `js_util` methods `getProperty`, `setProperty`, `callMethod`,
- `callConstructor`, and `newObject` now support a generic type argument
- to specify the return type.
+- The `js_util` methods `setProperty`, `callMethod`, and `callConstructor` have
+ been optimized to remove checks on arguments when the checks can be elided.
+ Also, those methods, along with `getProperty` and `newObject`, now support a
+ generic type argument to specify a return type. These two changes make simple
+ `js_util` usage, like reading and writing primitive properties or calling
+ methods with simple arguments, have zero overhead.
#### `dart:web_sql`
@@ -486,6 +503,14 @@
`dart pub get/upgrade/downgrade/add/remove` that will result in the `example/`
folder dependencies to be updated after operating in the current directory.
+### Other libraries
+
+#### `package:js`
+
+- Extensions on JS interop or native `dart:html` classes can now declare
+ members as `external`. These members are equivalent to regular extension
+ members that use `js_util` to expose the underlying JavaScript.
+
## 2.14.4 - 2021-10-14
This is a patch release that fixes:
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 0b96e08..08de605 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -9429,7 +9429,7 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageSuperInitializerNotLast = const MessageCode(
"SuperInitializerNotLast",
- analyzerCodes: <String>["INVALID_SUPER_INVOCATION"],
+ analyzerCodes: <String>["SUPER_INVOCATION_NOT_LAST"],
problemMessage: r"""Can't have initializers after 'super'.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
index c4469ea..c56e634 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
@@ -15,7 +15,9 @@
/// Assists with the same relevance are sorted alphabetically.
static final Comparator<Assist> SORT_BY_RELEVANCE = (Assist a, Assist b) {
if (a.kind.priority != b.kind.priority) {
- return a.kind.priority - b.kind.priority;
+ // A higher priority indicates a higher relevance
+ // and should be sorted before a lower priority.
+ return b.kind.priority - a.kind.priority;
}
return a.change.message.compareTo(b.change.message);
};
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
index 9f7152c..ecc14cc 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
@@ -36,10 +36,11 @@
// CodeAction class).
final codeActionPriorities = Expando<int>();
- /// A comparator that can be used to sort [CodeActions]s using priorties
- /// in [codeActionPriorities]. The highest number priority will be sorted
- /// before lower number priorityies. Items with the same relevance are sorted
- /// alphabetically by their title.
+ /// A comparator that can be used to sort [CodeActions]s using priorities
+ /// in [codeActionPriorities].
+ ///
+ /// The highest number priority will be sorted before lower number priorities.
+ /// Items with the same priority are sorted alphabetically by their title.
late final Comparator<CodeAction> _codeActionComparator =
(CodeAction a, CodeAction b) {
// We should never be sorting actions without priorities.
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 47624e2..c7233ba 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -73,7 +73,7 @@
);
static const CONVERT_INTO_ASYNC_BODY = AssistKind(
'dart.assist.convert.bodyToAsync',
- 29,
+ 31,
'Convert to async function body',
);
static const CONVERT_INTO_BLOCK_BODY = AssistKind(
@@ -222,77 +222,77 @@
// Flutter wrap specific assists
static const FLUTTER_WRAP_GENERIC = AssistKind(
'dart.assist.flutter.wrap.generic',
- 31,
+ 29,
'Wrap with widget...',
);
static const FLUTTER_WRAP_BUILDER = AssistKind(
'dart.assist.flutter.wrap.builder',
- 32,
+ 28,
'Wrap with Builder',
);
static const FLUTTER_WRAP_CENTER = AssistKind(
'dart.assist.flutter.wrap.center',
- 32,
+ 28,
'Wrap with Center',
);
static const FLUTTER_WRAP_COLUMN = AssistKind(
'dart.assist.flutter.wrap.column',
- 32,
+ 28,
'Wrap with Column',
);
static const FLUTTER_WRAP_CONTAINER = AssistKind(
'dart.assist.flutter.wrap.container',
- 32,
+ 28,
'Wrap with Container',
);
static const FLUTTER_WRAP_PADDING = AssistKind(
'dart.assist.flutter.wrap.padding',
- 32,
+ 28,
'Wrap with Padding',
);
static const FLUTTER_WRAP_ROW = AssistKind(
'dart.assist.flutter.wrap.row',
- 32,
+ 28,
'Wrap with Row',
);
static const FLUTTER_WRAP_SIZED_BOX = AssistKind(
'dart.assist.flutter.wrap.sizedBox',
- 32,
+ 28,
'Wrap with SizedBox',
);
static const FLUTTER_WRAP_STREAM_BUILDER = AssistKind(
'dart.assist.flutter.wrap.streamBuilder',
- 32,
+ 28,
'Wrap with StreamBuilder',
);
// Flutter re-order assists
static const FLUTTER_SWAP_WITH_CHILD = AssistKind(
'dart.assist.flutter.swap.withChild',
- 33,
+ 27,
'Swap with child',
);
static const FLUTTER_SWAP_WITH_PARENT = AssistKind(
'dart.assist.flutter.swap.withParent',
- 33,
+ 27,
'Swap with parent',
);
static const FLUTTER_MOVE_DOWN = AssistKind(
'dart.assist.flutter.move.down',
- 34,
+ 26,
'Move widget down',
);
static const FLUTTER_MOVE_UP = AssistKind(
'dart.assist.flutter.move.up',
- 34,
+ 26,
'Move widget up',
);
// Flutter remove assist
static const FLUTTER_REMOVE_WIDGET = AssistKind(
'dart.assist.flutter.removeWidget',
- 35,
+ 25,
'Remove this widget',
);
@@ -334,7 +334,7 @@
static const REMOVE_TYPE_ANNOTATION = AssistKind(
// todo (pq): unify w/ fix
'dart.assist.remove.typeAnnotation',
- 29,
+ 31,
'Remove type annotation',
);
static const REPLACE_CONDITIONAL_WITH_IF_ELSE = AssistKind(
@@ -374,47 +374,47 @@
);
static const SURROUND_WITH_BLOCK = AssistKind(
'dart.assist.surround.block',
- 22,
+ 38,
'Surround with block',
);
static const SURROUND_WITH_DO_WHILE = AssistKind(
'dart.assist.surround.doWhile',
- 27,
+ 33,
"Surround with 'do-while'",
);
static const SURROUND_WITH_FOR = AssistKind(
'dart.assist.surround.forEach',
- 26,
+ 34,
"Surround with 'for'",
);
static const SURROUND_WITH_FOR_IN = AssistKind(
'dart.assist.surround.forIn',
- 25,
+ 35,
"Surround with 'for-in'",
);
static const SURROUND_WITH_IF = AssistKind(
'dart.assist.surround.if',
- 23,
+ 37,
"Surround with 'if'",
);
static const SURROUND_WITH_SET_STATE = AssistKind(
'dart.assist.surround.setState',
- 27,
+ 33,
"Surround with 'setState'",
);
static const SURROUND_WITH_TRY_CATCH = AssistKind(
'dart.assist.surround.tryCatch',
- 28,
+ 32,
"Surround with 'try-catch'",
);
static const SURROUND_WITH_TRY_FINALLY = AssistKind(
'dart.assist.surround.tryFinally',
- 29,
+ 31,
"Surround with 'try-finally'",
);
static const SURROUND_WITH_WHILE = AssistKind(
'dart.assist.surround.while',
- 24,
+ 36,
"Surround with 'while'",
);
static const USE_CURLY_BRACES = AssistKind(
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index f695939..7782757 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -22,12 +22,14 @@
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:analyzer_utilities/check/check.dart';
+import 'package:meta/meta.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'domain_completion_util.dart';
import 'mocks.dart';
import 'src/plugin/plugin_manager_test.dart';
+import 'utils/change_check.dart';
void main() {
defineReflectiveSuite(() {
@@ -43,30 +45,31 @@
Future<void> test_alreadyImported() async {
await _configureWithWorkspaceRoot();
- var validator = await _getTestCodeDetails('''
+ var details = await _getTestCodeDetails('''
import 'dart:math';
void f() {
Rand^
}
''', completion: 'Random', libraryUri: 'dart:math');
- validator
- ..hasCompletion('Random')
- ..hasChange().assertNoFileEdits();
+ check(details)
+ ..completion.isEqualTo('Random')
+ ..change.edits.isEmpty;
}
Future<void> test_import_dart() async {
await _configureWithWorkspaceRoot();
- var validator = await _getTestCodeDetails('''
+ var details = await _getTestCodeDetails('''
void f() {
R^
}
''', completion: 'Random', libraryUri: 'dart:math');
- validator
- ..hasCompletion('Random')
- ..hasChange()
+ check(details)
+ ..completion.isEqualTo('Random')
+ ..change
.hasFileEdit(testFilePathPlatform)
- .whenApplied(testFileContent, r'''
+ .appliedTo(testFileContent)
+ .isEqualTo(r'''
import 'dart:math';
void f() {
@@ -94,16 +97,17 @@
await _configureWithWorkspaceRoot();
- var validator = await _getTestCodeDetails('''
+ var details = await _getTestCodeDetails('''
void f() {
T^
}
''', completion: 'Test', libraryUri: 'package:aaa/a.dart');
- validator
- ..hasCompletion('Test')
- ..hasChange()
+ check(details)
+ ..completion.isEqualTo('Test')
+ ..change
.hasFileEdit(testFilePathPlatform)
- .whenApplied(testFileContent, r'''
+ .appliedTo(testFileContent)
+ .isEqualTo(r'''
import 'package:aaa/a.dart';
void f() {
@@ -119,16 +123,17 @@
await _configureWithWorkspaceRoot();
- var validator = await _getTestCodeDetails('''
+ var details = await _getTestCodeDetails('''
void f() {
T^
}
''', completion: 'Test', libraryUri: 'package:test/a.dart');
- validator
- ..hasCompletion('Test')
- ..hasChange()
+ check(details)
+ ..completion.isEqualTo('Test')
+ ..change
.hasFileEdit(testFilePathPlatform)
- .whenApplied(testFileContent, r'''
+ .appliedTo(testFileContent)
+ .isEqualTo(r'''
import 'package:test/a.dart';
void f() {
@@ -160,7 +165,7 @@
expect(response.error?.code, RequestErrorCode.INVALID_FILE_PATH_FORMAT);
}
- Future<GetSuggestionDetails2Validator> _getCodeDetails({
+ Future<CompletionGetSuggestionDetails2Result> _getCodeDetails({
required String path,
required String content,
required String completion,
@@ -184,7 +189,7 @@
);
}
- Future<GetSuggestionDetails2Validator> _getDetails({
+ Future<CompletionGetSuggestionDetails2Result> _getDetails({
required String path,
required int completionOffset,
required String completion,
@@ -198,11 +203,10 @@
).toRequest('0');
var response = await _handleSuccessfulRequest(request);
- var result = CompletionGetSuggestionDetails2Result.fromResponse(response);
- return GetSuggestionDetails2Validator(result);
+ return CompletionGetSuggestionDetails2Result.fromResponse(response);
}
- Future<GetSuggestionDetails2Validator> _getTestCodeDetails(
+ Future<CompletionGetSuggestionDetails2Result> _getTestCodeDetails(
String content, {
required String completion,
required String libraryUri,
@@ -2548,20 +2552,6 @@
}
}
-class GetSuggestionDetails2Validator {
- final CompletionGetSuggestionDetails2Result result;
-
- GetSuggestionDetails2Validator(this.result);
-
- SourceChangeValidator hasChange() {
- return SourceChangeValidator(result.change);
- }
-
- void hasCompletion(Object completion) {
- expect(result.completion, completion);
- }
-}
-
class PubPackageAnalysisServerTest with ResourceProviderMixin {
late final MockServerChannel serverChannel;
late final AnalysisServer server;
@@ -2739,32 +2729,6 @@
}
}
-class SourceChangeValidator {
- final SourceChange change;
-
- SourceChangeValidator(this.change);
-
- void assertNoFileEdits() {
- expect(change.edits, isEmpty);
- }
-
- SourceFileEditValidator hasFileEdit(String path) {
- var edit = change.edits.singleWhere((e) => e.file == path);
- return SourceFileEditValidator(edit);
- }
-}
-
-class SourceFileEditValidator {
- final SourceFileEdit edit;
-
- SourceFileEditValidator(this.edit);
-
- void whenApplied(String applyTo, Object expected) {
- var actual = SourceEdit.applySequence(applyTo, edit.edits);
- expect(actual, expected);
- }
-}
-
class SuggestionsValidator {
final List<CompletionSuggestion> suggestions;
final List<String>? libraryUrisToImport;
@@ -2853,3 +2817,21 @@
return withKind(CompletionSuggestionKind.IDENTIFIER);
}
}
+
+extension on CheckTarget<CompletionGetSuggestionDetails2Result> {
+ @useResult
+ CheckTarget<String> get completion {
+ return nest(
+ value.completion,
+ (selected) => 'has completion ${valueStr(selected)}',
+ );
+ }
+
+ @useResult
+ CheckTarget<SourceChange> get change {
+ return nest(
+ value.change,
+ (selected) => 'has change ${valueStr(selected)}',
+ );
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
index 2797109..d814a75 100644
--- a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
@@ -393,6 +393,39 @@
}
}
+ Future<void> test_sort() async {
+ const content = '''
+ import 'package:flutter/widgets.dart';
+
+ build() => Contai^ner(child: Container());
+ ''';
+
+ newFile(mainFilePath, content: withoutMarkers(content));
+ await initialize(
+ textDocumentCapabilities: withCodeActionKinds(
+ emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
+ workspaceCapabilities:
+ withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
+ );
+
+ final codeActions = await getCodeActions(mainFileUri.toString(),
+ position: positionFromMarker(content));
+ final names = codeActions.map(
+ (e) => e.map((command) => command.title, (action) => action.title),
+ );
+
+ expect(
+ names,
+ containsAllInOrder([
+ // Check the ordering for two well-known assists that should always be
+ // sorted this way.
+ // https://github.com/Dart-Code/Dart-Code/issues/3646
+ 'Wrap with widget...',
+ 'Remove this widget',
+ ]),
+ );
+ }
+
List<TextDocumentEdit> _extractTextDocumentEdits(
Either2<
List<TextDocumentEdit>,
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index 972198c..c60efba 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -57,7 +57,7 @@
offset: completionOffset,
);
- var directives = request.target.unit.directives;
+ var directives = resolvedUnit.unit.directives;
var imports = request.libraryElement.imports;
expect(imports, hasLength(directives.length + 1));
diff --git a/pkg/analysis_server/test/utils/change_check.dart b/pkg/analysis_server/test/utils/change_check.dart
new file mode 100644
index 0000000..3cd3e2b
--- /dev/null
+++ b/pkg/analysis_server/test/utils/change_check.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, 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:analysis_server/src/protocol_server.dart';
+import 'package:analyzer_utilities/check/check.dart';
+import 'package:meta/meta.dart';
+
+extension SourceChangeExtension on CheckTarget<SourceChange> {
+ @useResult
+ CheckTarget<List<SourceFileEdit>> get edits {
+ return nest(value.edits, (value) => 'has edits ${valueStr(value)}');
+ }
+
+ CheckTarget<SourceFileEdit> hasFileEdit(String path) {
+ return nest(
+ value.edits.singleWhere((e) => e.file == path),
+ (selected) => 'has edit ${valueStr(selected)}',
+ );
+ }
+}
+
+extension SourceFileEditExtension on CheckTarget<SourceFileEdit> {
+ @useResult
+ CheckTarget<String> appliedTo(String applyTo) {
+ var actual = SourceEdit.applySequence(applyTo, value.edits);
+ return nest(
+ actual,
+ (selected) => 'produces ${valueStr(selected)}',
+ );
+ }
+}
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 6e3a83b..950eb5b 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -256,7 +256,6 @@
CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
CompileTimeErrorCode.INVALID_OVERRIDE,
CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS,
- CompileTimeErrorCode.INVALID_SUPER_INVOCATION,
CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST,
CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP,
CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET,
@@ -407,6 +406,7 @@
CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT,
CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT,
+ CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST,
CompileTimeErrorCode.SWITCH_CASE_COMPLETES_NORMALLY,
CompileTimeErrorCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
CompileTimeErrorCode.TEAROFF_OF_GENERATIVE_CONSTRUCTOR_OF_ABSTRACT_CLASS,
diff --git a/pkg/analyzer/lib/src/error/bool_expression_verifier.dart b/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
index 108cc22..6d06e03 100644
--- a/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
+++ b/pkg/analyzer/lib/src/error/bool_expression_verifier.dart
@@ -62,6 +62,17 @@
} else {
_errorReporter.reportErrorForNode(errorCode, expression, arguments);
}
+ } else if (!_resolver.definingLibrary.isNonNullableByDefault) {
+ if (expression is InstanceCreationExpression) {
+ // In pre-null safety code, an implicit cast from a supertype is allowed
+ // unless the expression is an explicit instance creation expression,
+ // with the idea that the cast would likely fail at runtime.
+ var constructor = expression.constructorName.staticElement;
+ if (constructor == null || !constructor.isFactory) {
+ _errorReporter.reportErrorForNode(errorCode, expression, arguments);
+ return;
+ }
+ }
}
}
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index c9e3ac0..2dd25ca 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -7381,51 +7381,6 @@
);
/**
- * No parameters.
- */
- // #### Description
- //
- // The analyzer produces this diagnostic when the initializer list of a
- // constructor contains an invocation of a constructor in the superclass, but
- // the invocation isn't the last item in the initializer list.
- //
- // #### Example
- //
- // The following code produces this diagnostic because the invocation of the
- // superclass' constructor isn't the last item in the initializer list:
- //
- // ```dart
- // class A {
- // A(int x);
- // }
- //
- // class B extends A {
- // B(int x) : [!super!](x), assert(x >= 0);
- // }
- // ```
- //
- // #### Common fixes
- //
- // Move the invocation of the superclass' constructor to the end of the
- // initializer list:
- //
- // ```dart
- // class A {
- // A(int x);
- // }
- //
- // class B extends A {
- // B(int x) : assert(x >= 0), super(x);
- // }
- // ```
- static const CompileTimeErrorCode INVALID_SUPER_INVOCATION =
- CompileTimeErrorCode(
- 'INVALID_SUPER_INVOCATION',
- "The superclass call must be last in an initializer list: '{0}'.",
- hasPublishedDocs: true,
- );
-
- /**
* Parameters:
* 0: the name of the type parameter
*/
@@ -12892,6 +12847,52 @@
);
/**
+ * Parameters:
+ * 0: the superinitializer
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the initializer list of a
+ // constructor contains an invocation of a constructor in the superclass, but
+ // the invocation isn't the last item in the initializer list.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the invocation of the
+ // superclass' constructor isn't the last item in the initializer list:
+ //
+ // ```dart
+ // class A {
+ // A(int x);
+ // }
+ //
+ // class B extends A {
+ // B(int x) : [!super!](x), assert(x >= 0);
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Move the invocation of the superclass' constructor to the end of the
+ // initializer list:
+ //
+ // ```dart
+ // class A {
+ // A(int x);
+ // }
+ //
+ // class B extends A {
+ // B(int x) : assert(x >= 0), super(x);
+ // }
+ // ```
+ static const CompileTimeErrorCode SUPER_INVOCATION_NOT_LAST =
+ CompileTimeErrorCode(
+ 'SUPER_INVOCATION_NOT_LAST',
+ "The superconstructor call must be last in an initializer list: '{0}'.",
+ hasPublishedDocs: true,
+ );
+
+ /**
* No parameters.
*/
// #### Description
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 0159195..6ce8f76 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -191,10 +191,6 @@
_reportByCode(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, message,
offset, length);
return;
- case "INVALID_SUPER_INVOCATION":
- errorReporter?.reportErrorForOffset(
- CompileTimeErrorCode.INVALID_SUPER_INVOCATION, offset, length);
- return;
case "MISSING_DIGIT":
errorReporter?.reportErrorForOffset(
ScannerErrorCode.MISSING_DIGIT, offset, length);
@@ -265,6 +261,10 @@
errorReporter?.reportErrorForOffset(
CompileTimeErrorCode.RETURN_IN_GENERATOR, offset, length);
return;
+ case "SUPER_INVOCATION_NOT_LAST":
+ errorReporter?.reportErrorForOffset(
+ CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST, offset, length);
+ return;
case "SUPER_IN_REDIRECTING_CONSTRUCTOR":
errorReporter?.reportErrorForOffset(
CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index e140ee8..85bde05 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -517,7 +517,7 @@
}
_constructorFieldsVerifier.verify(node);
_checkForRedirectingConstructorErrorCodes(node);
- _checkForMultipleSuperInitializers(node);
+ _checkForConflictingInitializerErrorCodes(node);
_checkForRecursiveConstructorRedirect(node, element);
if (!_checkForRecursiveFactoryRedirect(node, element)) {
_checkForAllRedirectConstructorErrorCodes(node);
@@ -1848,6 +1848,99 @@
}
}
+ /// Check that the given constructor [declaration] has a valid combination of
+ /// redirecting constructor invocation(s), super constructor invocation(s),
+ /// field initializers, and assert initializers.
+ void _checkForConflictingInitializerErrorCodes(
+ ConstructorDeclaration declaration) {
+ // Count and check each redirecting initializer.
+ var redirectingInitializerCount = 0;
+ var superInitializerCount = 0;
+ late SuperConstructorInvocation superInitializer;
+ for (ConstructorInitializer initializer in declaration.initializers) {
+ if (initializer is RedirectingConstructorInvocation) {
+ if (redirectingInitializerCount > 0) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
+ initializer);
+ }
+ if (declaration.factoryKeyword == null) {
+ RedirectingConstructorInvocation invocation = initializer;
+ var redirectingElement = invocation.staticElement;
+ if (redirectingElement == null) {
+ String enclosingNamedType = _enclosingClass!.displayName;
+ String constructorStrName = enclosingNamedType;
+ if (invocation.constructorName != null) {
+ constructorStrName += ".${invocation.constructorName!.name}";
+ }
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
+ invocation,
+ [constructorStrName, enclosingNamedType]);
+ } else {
+ if (redirectingElement.isFactory) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode
+ .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
+ initializer);
+ }
+ }
+ }
+ // [declaration] is a redirecting constructor via a redirecting
+ // initializer.
+ _checkForRedirectToNonConstConstructor(
+ declaration.declaredElement!,
+ initializer.staticElement,
+ initializer.constructorName ?? initializer.thisKeyword,
+ );
+ redirectingInitializerCount++;
+ } else if (initializer is SuperConstructorInvocation) {
+ if (superInitializerCount == 1) {
+ // Only report the second (first illegal) superinitializer.
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer);
+ }
+ superInitializer = initializer;
+ superInitializerCount++;
+ }
+ }
+ // Check for initializers which are illegal when alongside a redirecting
+ // initializer.
+ if (redirectingInitializerCount > 0) {
+ for (ConstructorInitializer initializer in declaration.initializers) {
+ if (initializer is SuperConstructorInvocation) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
+ initializer);
+ }
+ if (initializer is ConstructorFieldInitializer) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
+ initializer);
+ }
+ if (initializer is AssertInitializer) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR,
+ initializer);
+ }
+ }
+ }
+ if (redirectingInitializerCount == 0 &&
+ superInitializerCount == 1 &&
+ superInitializer != declaration.initializers.last) {
+ var superNamedType = _enclosingClass!.supertype!.element.displayName;
+ var constructorStrName = superNamedType;
+ var constructorName = superInitializer.constructorName;
+ if (constructorName != null) {
+ constructorStrName += '.${constructorName.name}';
+ }
+ errorReporter.reportErrorForToken(
+ CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST,
+ superInitializer.superKeyword,
+ [constructorStrName]);
+ }
+ }
+
/// Verify that if the given [constructor] declaration is 'const' then there
/// are no invocations of non-'const' super constructors, and that there are
/// no instance variables mixed in.
@@ -3270,22 +3363,6 @@
}
}
- /// Verify that the given [constructor] has at most one 'super' initializer.
- ///
- /// See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS].
- void _checkForMultipleSuperInitializers(ConstructorDeclaration constructor) {
- bool hasSuperInitializer = false;
- for (ConstructorInitializer initializer in constructor.initializers) {
- if (initializer is SuperConstructorInvocation) {
- if (hasSuperInitializer) {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer);
- }
- hasSuperInitializer = true;
- }
- }
- }
-
/// Checks to ensure that the given native function [body] is in SDK code.
///
/// See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE].
@@ -3728,112 +3805,44 @@
return true;
}
- /// Check that the given constructor [declaration] has a valid combination of
- /// redirected constructor invocation(s), super constructor invocations and
- /// field initializers.
- ///
- /// See [CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR],
- /// [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR],
- /// [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR],
- /// [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS],
- /// [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR], and
- /// [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR].
+ /// Check that the given constructor [declaration] has a valid redirected
+ /// constructor.
void _checkForRedirectingConstructorErrorCodes(
ConstructorDeclaration declaration) {
- // Check for default values in the parameters
+ // Check for default values in the parameters.
var redirectedConstructor = declaration.redirectedConstructor;
- if (redirectedConstructor != null) {
- for (FormalParameter parameter in declaration.parameters.parameters) {
- if (parameter is DefaultFormalParameter &&
- parameter.defaultValue != null) {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode
- .DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
- parameter.identifier!);
- }
- }
- var redirectedElement = redirectedConstructor.staticElement;
- _checkForRedirectToNonConstConstructor(
- declaration.declaredElement!,
- redirectedElement,
- redirectedConstructor,
- );
- var redirectedClass = redirectedElement?.enclosingElement;
- if (redirectedClass is ClassElement &&
- redirectedClass.isAbstract &&
- redirectedElement != null &&
- !redirectedElement.isFactory) {
- String enclosingNamedType = _enclosingClass!.displayName;
- String constructorStrName = enclosingNamedType;
- if (declaration.name != null) {
- constructorStrName += ".${declaration.name!.name}";
- }
+ if (redirectedConstructor == null) {
+ return;
+ }
+ for (FormalParameter parameter in declaration.parameters.parameters) {
+ if (parameter is DefaultFormalParameter &&
+ parameter.defaultValue != null) {
errorReporter.reportErrorForNode(
- CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
- redirectedConstructor,
- [constructorStrName, redirectedClass.name]);
+ CompileTimeErrorCode
+ .DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
+ parameter.identifier!);
}
}
- // check if there are redirected invocations
- int numRedirections = 0;
- for (ConstructorInitializer initializer in declaration.initializers) {
- if (initializer is RedirectingConstructorInvocation) {
- if (numRedirections > 0) {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
- initializer);
- }
- if (declaration.factoryKeyword == null) {
- RedirectingConstructorInvocation invocation = initializer;
- var redirectingElement = invocation.staticElement;
- if (redirectingElement == null) {
- String enclosingNamedType = _enclosingClass!.displayName;
- String constructorStrName = enclosingNamedType;
- if (invocation.constructorName != null) {
- constructorStrName += ".${invocation.constructorName!.name}";
- }
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
- invocation,
- [constructorStrName, enclosingNamedType]);
- } else {
- if (redirectingElement.isFactory) {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode
- .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
- initializer);
- }
- }
- }
- // [declaration] is a redirecting constructor via a redirecting
- // initializer.
- _checkForRedirectToNonConstConstructor(
- declaration.declaredElement!,
- initializer.staticElement,
- initializer.constructorName ?? initializer.thisKeyword,
- );
- numRedirections++;
+ var redirectedElement = redirectedConstructor.staticElement;
+ _checkForRedirectToNonConstConstructor(
+ declaration.declaredElement!,
+ redirectedElement,
+ redirectedConstructor,
+ );
+ var redirectedClass = redirectedElement?.enclosingElement;
+ if (redirectedClass is ClassElement &&
+ redirectedClass.isAbstract &&
+ redirectedElement != null &&
+ !redirectedElement.isFactory) {
+ String enclosingNamedType = _enclosingClass!.displayName;
+ String constructorStrName = enclosingNamedType;
+ if (declaration.name != null) {
+ constructorStrName += ".${declaration.name!.name}";
}
- }
- // check for other initializers
- if (numRedirections > 0) {
- for (ConstructorInitializer initializer in declaration.initializers) {
- if (initializer is SuperConstructorInvocation) {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
- initializer);
- }
- if (initializer is ConstructorFieldInitializer) {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
- initializer);
- }
- if (initializer is AssertInitializer) {
- errorReporter.reportErrorForNode(
- CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR,
- initializer);
- }
- }
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
+ redirectedConstructor,
+ [constructorStrName, redirectedClass.name]);
}
}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3d179d7..ef1119a 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -82,21 +82,14 @@
}
void checkAssignment(Expression expr, DartType to) {
- checkForCast(expr, from: expr.typeOrThrow, to: to);
+ _checkImplicitCast(expr, from: expr.typeOrThrow, to: to);
}
- /// Analyzer checks boolean conversions, but we need to check too, because
- /// it uses the default assignability rules that allow `dynamic` and `Object`
- /// to be assigned to bool with no message.
- void checkBoolean(Expression expr) =>
- checkAssignment(expr, typeProvider.boolType);
-
void checkCollectionElement(
CollectionElement? element, DartType expectedType) {
if (element is ForElement) {
checkCollectionElement(element.body, expectedType);
} else if (element is IfElement) {
- checkBoolean(element.condition);
checkCollectionElement(element.thenElement, expectedType);
checkCollectionElement(element.elseElement, expectedType);
} else if (element is Expression) {
@@ -120,24 +113,11 @@
}
}
- void checkForCast(
- Expression expr, {
- required DartType from,
- required DartType to,
- }) {
- if (expr is ParenthesizedExpression) {
- checkForCast(expr.expression, from: from, to: to);
- } else {
- _checkImplicitCast(expr, from: from, to: to);
- }
- }
-
void checkMapElement(CollectionElement? element, DartType expectedKeyType,
DartType expectedValueType) {
if (element is ForElement) {
checkMapElement(element.body, expectedKeyType, expectedValueType);
} else if (element is IfElement) {
- checkBoolean(element.condition);
checkMapElement(element.thenElement, expectedKeyType, expectedValueType);
checkMapElement(element.elseElement, expectedKeyType, expectedValueType);
} else if (element is MapLiteralEntry) {
@@ -178,17 +158,12 @@
@override
void visitAssignmentExpression(AssignmentExpression node) {
- var left = node.leftHandSide;
- var right = node.rightHandSide;
Token operator = node.operator;
TokenType operatorType = operator.type;
if (operatorType == TokenType.EQ ||
operatorType == TokenType.QUESTION_QUESTION_EQ) {
- checkForCast(right, from: right.typeOrThrow, to: node.writeType!);
- } else if (operatorType == TokenType.AMPERSAND_AMPERSAND_EQ ||
- operatorType == TokenType.BAR_BAR_EQ) {
- checkBoolean(left);
- checkBoolean(right);
+ var right = node.rightHandSide;
+ _checkImplicitCast(right, from: right.typeOrThrow, to: node.writeType!);
} else {
_checkCompoundAssignment(node);
}
@@ -196,28 +171,6 @@
}
@override
- void visitBinaryExpression(BinaryExpression node) {
- var op = node.operator;
- if (!op.isUserDefinableOperator) {
- switch (op.type) {
- case TokenType.AMPERSAND_AMPERSAND:
- case TokenType.BAR_BAR:
- checkBoolean(node.leftOperand);
- checkBoolean(node.rightOperand);
- break;
- case TokenType.BANG_EQ:
- case TokenType.BANG_EQ_EQ:
- case TokenType.EQ_EQ_EQ:
- case TokenType.QUESTION_QUESTION:
- break;
- default:
- assert(false);
- }
- }
- node.visitChildren(this);
- }
-
- @override
void visitComment(Comment node) {
// skip, no need to do typechecking inside comments (they may contain
// comment references which would require resolution).
@@ -231,31 +184,9 @@
@override
void visitConditionalExpression(ConditionalExpression node) {
- checkBoolean(node.condition);
node.visitChildren(this);
}
- /// Check constructor declaration to ensure correct super call placement.
- @override
- void visitConstructorDeclaration(ConstructorDeclaration node) {
- node.visitChildren(this);
-
- final init = node.initializers;
- for (int i = 0, last = init.length - 1; i < last; i++) {
- final initializer = init[i];
- if (initializer is SuperConstructorInvocation) {
- // TODO(srawlins): Don't report this when
- // [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR] or
- // [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS] is reported for
- // this constructor.
- var source = (node.root as CompilationUnit).declaredElement!.source;
- var token = initializer.superKeyword;
- reporter.onError(AnalysisError(source, token.offset, token.length,
- CompileTimeErrorCode.INVALID_SUPER_INVOCATION, [initializer]));
- }
- }
- }
-
@override
void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
var field = node.fieldName;
@@ -281,12 +212,6 @@
}
@override
- void visitDoStatement(DoStatement node) {
- checkBoolean(node.condition);
- node.visitChildren(this);
- }
-
- @override
void visitExpressionFunctionBody(ExpressionFunctionBody node) {
_checkReturnOrYield(node.expression, node);
node.visitChildren(this);
@@ -305,36 +230,12 @@
}
@override
- void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
- var condition = node.condition;
- if (condition != null) {
- checkBoolean(condition);
- }
- node.visitChildren(this);
- }
-
- @override
- void visitForPartsWithExpression(ForPartsWithExpression node) {
- var condition = node.condition;
- if (condition != null) {
- checkBoolean(condition);
- }
- node.visitChildren(this);
- }
-
- @override
void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
_checkFunctionApplication(node);
node.visitChildren(this);
}
@override
- void visitIfStatement(IfStatement node) {
- checkBoolean(node.condition);
- node.visitChildren(this);
- }
-
- @override
void visitIndexExpression(IndexExpression node) {
var element = node.writeOrReadElement;
if (element is MethodElement) {
@@ -403,11 +304,7 @@
@override
void visitPrefixExpression(PrefixExpression node) {
- if (node.operator.type == TokenType.BANG) {
- checkBoolean(node.operand);
- } else {
- _checkUnary(node, node.operand, node.operator, node.staticElement);
- }
+ _checkUnary(node, node.operand, node.operator, node.staticElement);
node.visitChildren(this);
}
@@ -523,7 +420,7 @@
for (VariableDeclaration variable in node.variables) {
var initializer = variable.initializer;
if (initializer != null) {
- checkForCast(initializer,
+ _checkImplicitCast(initializer,
from: initializer.typeOrThrow, to: type.typeOrThrow);
}
}
@@ -533,12 +430,6 @@
}
@override
- void visitWhileStatement(WhileStatement node) {
- checkBoolean(node.condition);
- node.visitChildren(this);
- }
-
- @override
void visitYieldStatement(YieldStatement node) {
_checkReturnOrYield(node.expression, node, yieldStar: node.star != null);
node.visitChildren(this);
@@ -591,11 +482,10 @@
}
}
- /// Given an expression [expr] of type [fromType], returns true if an implicit
- /// downcast is required, false if it is not, or null if the types are
- /// unrelated.
- bool? _checkFunctionTypeCasts(
- Expression expr, FunctionType to, DartType fromType) {
+ /// Returns true if an implicit downcast is required to assign an expression
+ /// of type [fromType] to type [to], false if it is not, or null if the
+ /// types are unrelated.
+ bool? _checkFunctionTypeCasts(FunctionType to, DartType fromType) {
bool callTearoff = false;
FunctionType? from;
if (fromType is FunctionType) {
@@ -640,6 +530,7 @@
return;
}
+ expr = expr.unParenthesized;
if (_needsImplicitCast(expr, to: to, from: from) == true) {
_recordImplicitCast(expr, to,
from: from,
@@ -796,7 +687,7 @@
if (from.isVoid) return null;
if (to is FunctionType) {
- var needsCast = _checkFunctionTypeCasts(expr, to, from);
+ var needsCast = _checkFunctionTypeCasts(to, from);
if (needsCast != null) return needsCast;
}
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 80aab8d..b1868a7 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -6524,46 +6524,6 @@
class C {}
```
- INVALID_SUPER_INVOCATION:
- problemMessage: "The superclass call must be last in an initializer list: '{0}'."
- hasPublishedDocs: true
- comment: No parameters.
- documentation: |-
- #### Description
-
- The analyzer produces this diagnostic when the initializer list of a
- constructor contains an invocation of a constructor in the superclass, but
- the invocation isn't the last item in the initializer list.
-
- #### Example
-
- The following code produces this diagnostic because the invocation of the
- superclass' constructor isn't the last item in the initializer list:
-
- ```dart
- class A {
- A(int x);
- }
-
- class B extends A {
- B(int x) : [!super!](x), assert(x >= 0);
- }
- ```
-
- #### Common fixes
-
- Move the invocation of the superclass' constructor to the end of the
- initializer list:
-
- ```dart
- class A {
- A(int x);
- }
-
- class B extends A {
- B(int x) : assert(x >= 0), super(x);
- }
- ```
INVALID_TYPE_ARGUMENT_IN_CONST_LIST:
sharedName: INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL
problemMessage: "Constant list literals can't include a type parameter as a type argument, such as '{0}'."
@@ -11329,6 +11289,49 @@
7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It
is a compile-time error if a generative constructor of class Object
includes a superinitializer.
+ SUPER_INVOCATION_NOT_LAST:
+ previousName: INVALID_SUPER_INVOCATION
+ problemMessage: "The superconstructor call must be last in an initializer list: '{0}'."
+ hasPublishedDocs: true
+ comment: |-
+ Parameters:
+ 0: the superinitializer
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when the initializer list of a
+ constructor contains an invocation of a constructor in the superclass, but
+ the invocation isn't the last item in the initializer list.
+
+ #### Example
+
+ The following code produces this diagnostic because the invocation of the
+ superclass' constructor isn't the last item in the initializer list:
+
+ ```dart
+ class A {
+ A(int x);
+ }
+
+ class B extends A {
+ B(int x) : [!super!](x), assert(x >= 0);
+ }
+ ```
+
+ #### Common fixes
+
+ Move the invocation of the superclass' constructor to the end of the
+ initializer list:
+
+ ```dart
+ class A {
+ A(int x);
+ }
+
+ class B extends A {
+ B(int x) : assert(x >= 0), super(x);
+ }
+ ```
SUPER_IN_EXTENSION:
problemMessage: "The 'super' keyword can't be used in an extension because an extension doesn't have a superclass."
hasPublishedDocs: true
diff --git a/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart b/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart
index 8147f29..ef8d48e 100644
--- a/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/multiple_super_initializers_test.dart
@@ -15,14 +15,22 @@
@reflectiveTest
class MultipleSuperInitializersTest extends PubPackageResolutionTest {
+ test_oneSuperInitializer() async {
+ await assertNoErrorsInCode('''
+class A {}
+class B extends A {
+ B() : super() {}
+}
+''');
+ }
+
test_twoSuperInitializers() async {
- await assertErrorsInCode(r'''
+ await assertErrorsInCode('''
class A {}
class B extends A {
B() : super(), super() {}
}
''', [
- error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 39, 5),
error(CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, 48, 7),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
index 0e9e5de..d96e7f3 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
@@ -26,6 +26,21 @@
]);
}
+ test_conditional_implicitCast_fromLiteral() async {
+ await assertErrorsInCode('''
+f() { return [1, 2, 3] ? 2 : 1; }
+''', [
+ error(CompileTimeErrorCode.NON_BOOL_CONDITION, 13, 9),
+ ]);
+ }
+
+ test_conditional_implicitCast_fromSupertype() async {
+ await assertNoErrorsInCode('''
+Object o;
+f() { return o ? 2 : 1; }
+''');
+ }
+
test_do() async {
await assertErrorsInCode(r'''
f() {
@@ -36,6 +51,26 @@
]);
}
+ test_do_implicitCast_fromLiteral() async {
+ await assertErrorsInCode('''
+Object o;
+f() {
+ do {} while ([1, 2, 3]);
+}
+''', [
+ error(CompileTimeErrorCode.NON_BOOL_CONDITION, 31, 9),
+ ]);
+ }
+
+ test_do_implicitCast_fromSupertype() async {
+ await assertNoErrorsInCode('''
+Object o;
+f() {
+ do {} while (o);
+}
+''');
+ }
+
test_for() async {
// https://github.com/dart-lang/sdk/issues/24713
await assertErrorsInCode(r'''
@@ -71,6 +106,25 @@
]);
}
+ test_for_implicitCast_fromLiteral() async {
+ await assertErrorsInCode('''
+f() {
+ for (;[1, 2, 3];) {}
+}
+''', [
+ error(CompileTimeErrorCode.NON_BOOL_CONDITION, 14, 9),
+ ]);
+ }
+
+ test_for_implicitCast_fromSupertype() async {
+ await assertNoErrorsInCode('''
+Object o;
+f() {
+ for (;o;) {}
+}
+''');
+ }
+
test_forElement() async {
await assertErrorsInCode('''
var v = [for (; 0;) 1];
@@ -89,6 +143,24 @@
]);
}
+ test_if_implicitCast_fromLiteral() async {
+ await assertErrorsInCode('''
+f() {
+ if ([1, 2, 3]) return 2; else return 1;
+}
+''', [
+ error(CompileTimeErrorCode.NON_BOOL_CONDITION, 12, 9),
+ ]);
+ }
+
+ test_if_implicitCast_fromSupertype() async {
+ await assertNoErrorsInCode('''
+f(Object o) {
+ if (o) return 2; else return 1;
+}
+''');
+ }
+
test_ifElement() async {
await assertErrorsInCode('''
var v = [if (3) 1];
@@ -97,6 +169,21 @@
]);
}
+ test_ifElement_implicitCast_fromLiteral() async {
+ await assertErrorsInCode('''
+var v = [if ([1, 2, 3]) 'x'];
+''', [
+ error(CompileTimeErrorCode.NON_BOOL_CONDITION, 13, 9),
+ ]);
+ }
+
+ test_ifElement_implicitCast_fromSupertype() async {
+ await assertNoErrorsInCode('''
+Object o;
+var v = [if (o) 'x'];
+''');
+ }
+
test_while() async {
await assertErrorsInCode(r'''
f() {
@@ -106,6 +193,24 @@
error(CompileTimeErrorCode.NON_BOOL_CONDITION, 15, 1),
]);
}
+
+ test_while_implicitCast_fromLiteral() async {
+ await assertErrorsInCode('''
+f() {
+ while ([1, 2, 3]) {}
+}
+''', [
+ error(CompileTimeErrorCode.NON_BOOL_CONDITION, 15, 9),
+ ]);
+ }
+
+ test_while_implicitCast_fromSupertype() async {
+ await assertNoErrorsInCode('''
+f(Object o) {
+ while (o) {}
+}
+''');
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
index 2d2c516..6fb1e92 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
@@ -26,6 +26,24 @@
error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 9, 2),
]);
}
+
+ test_nonBool_implicitCast_fromLiteral() async {
+ await assertErrorsInCode('''
+f() {
+ ![1, 2, 3];
+}
+''', [
+ error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 9, 9),
+ ]);
+ }
+
+ test_nonBool_implicitCast_fromSupertype() async {
+ await assertNoErrorsInCode('''
+f(Object o) {
+ !o;
+}
+''');
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
index f3d16b1..ea06d2a 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
@@ -27,6 +27,34 @@
]);
}
+ test_and_left_implicitCast_fromInstanceCreationExpression() async {
+ await assertErrorsInCode('''
+main() {
+ new Object() && true;
+}
+''', [
+ error(CompileTimeErrorCode.NON_BOOL_OPERAND, 11, 12),
+ ]);
+ }
+
+ test_and_left_implicitCast_fromLiteral() async {
+ await assertErrorsInCode('''
+bool f(List<int> left, bool right) {
+ return left && right;
+}
+''', [
+ error(CompileTimeErrorCode.NON_BOOL_OPERAND, 46, 4),
+ ]);
+ }
+
+ test_and_left_implicitCast_fromSupertype() async {
+ await assertNoErrorsInCode('''
+bool f(Object left, bool right) {
+ return left && right;
+}
+''');
+ }
+
test_and_right() async {
await assertErrorsInCode(r'''
bool f(bool left, String right) {
diff --git a/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart
index 9fafaa1..c58d414 100644
--- a/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/super_in_redirecting_constructor_test.dart
@@ -33,7 +33,6 @@
A.name() {}
}
''', [
- error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 18, 5),
error(CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, 18, 7),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_super_invocation_test.dart b/pkg/analyzer/test/src/diagnostics/super_invocation_not_last_test.dart
similarity index 66%
rename from pkg/analyzer/test/src/diagnostics/invalid_super_invocation_test.dart
rename to pkg/analyzer/test/src/diagnostics/super_invocation_not_last_test.dart
index 078fecf..6924087 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_super_invocation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/super_invocation_not_last_test.dart
@@ -9,19 +9,19 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(InvalidSuperInvocationTest);
+ defineReflectiveTests(SuperInvocationNotLastTest);
});
}
@reflectiveTest
-class InvalidSuperInvocationTest extends PubPackageResolutionTest {
+class SuperInvocationNotLastTest extends PubPackageResolutionTest {
test_superBeforeAssert() async {
await assertErrorsInCode(r'''
class A {
A(int? x) : super(), assert(x != null);
}
''', [
- error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 24, 5),
+ error(CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST, 24, 5),
]);
}
@@ -32,7 +32,16 @@
A() : super(), x = 1;
}
''', [
- error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 33, 5),
+ error(CompileTimeErrorCode.SUPER_INVOCATION_NOT_LAST, 33, 5),
]);
}
+
+ test_superIsLast() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ final int x;
+ A() : x = 1, super();
+}
+''');
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 3d245fa..5b02fd3 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -344,7 +344,6 @@
as invalid_required_positional_param;
import 'invalid_sealed_annotation_test.dart' as invalid_sealed_annotation;
import 'invalid_super_in_initializer_test.dart' as invalid_super_in_initializer;
-import 'invalid_super_invocation_test.dart' as invalid_super_invocation;
import 'invalid_type_argument_in_const_list_test.dart'
as invalid_type_argument_in_const_list;
import 'invalid_type_argument_in_const_map_test.dart'
@@ -625,6 +624,7 @@
import 'super_in_redirecting_constructor_test.dart'
as super_in_redirecting_constructor;
import 'super_initializer_in_object_test.dart' as super_initializer_in_object;
+import 'super_invocation_not_last_test.dart' as super_invocation_not_last;
import 'switch_case_completes_normally_test.dart'
as switch_case_completes_normally;
import 'switch_expression_not_assignable_test.dart'
@@ -947,7 +947,6 @@
invalid_required_positional_param.main();
invalid_sealed_annotation.main();
invalid_super_in_initializer.main();
- invalid_super_invocation.main();
invalid_type_argument_in_const_list.main();
invalid_type_argument_in_const_map.main();
invalid_type_argument_in_const_set.main();
@@ -1131,6 +1130,7 @@
super_in_invalid_context.main();
super_in_redirecting_constructor.main();
super_initializer_in_object.main();
+ super_invocation_not_last.main();
switch_case_completes_normally.main();
switch_expression_not_assignable.main();
tearoff_of_generative_constructor_of_abstract_class.main();
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index ce366390..5a33bcb 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -3031,33 +3031,6 @@
]);
}
- test_superCallPlacement() async {
- await assertErrorsInCode('''
-class Base {
- var x;
- Base() : x = 1;
-}
-
-class Derived extends Base {
- var y, z;
- Derived() : y = 1, super(), z = 2;
-}
-
-class Valid extends Base {
- var y, z;
- Valid(): y = 1, z = 2, super();
-}
-
-class AlsoValid extends Base {
- AlsoValid() : super();
-}
-
-main() => new Derived();
-''', [
- error(CompileTimeErrorCode.INVALID_SUPER_INVOCATION, 105, 5),
- ]);
- }
-
test_superclassOverrideOfGrandInterface_interfaceOfAbstractSuperclass() async {
await assertErrorsInCode('''
class A {}
@@ -3416,62 +3389,6 @@
]);
}
- test_unaryOperators() async {
- await assertErrorsInCode('''
-class A {
- A operator ~() => null;
- A operator +(int x) => null;
- A operator -(int x) => null;
- A operator -() => null;
-}
-class B extends A {}
-class C extends B {}
-
-foo() => new A();
-
-test() {
- A a = new A();
- B b = new B();
- var c = foo();
- dynamic d;
-
- ~a;
- (~d);
-
- !a;
- !d;
-
- -a;
- (-d);
-
- ++a;
- --a;
- (++d);
- (--d);
-
- a++;
- a--;
- (d++);
- (d--);
-
- ++b;
- --b;
- b++;
- b--;
-
- takesC(C c) => null;
- takesC(++b);
- takesC(--b);
- takesC(b++);
- takesC(b--);
-}
-''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 201, 1),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 237, 1),
- error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 280, 1),
- ]);
- }
-
test_unboundTypeName() async {
await assertErrorsInCode('''
void main() {
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 94648b5..ba40e44 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -7152,46 +7152,6 @@
}
{% endprettify %}
-### invalid_super_invocation
-
-_The superclass call must be last in an initializer list: '{0}'._
-
-#### Description
-
-The analyzer produces this diagnostic when the initializer list of a
-constructor contains an invocation of a constructor in the superclass, but
-the invocation isn't the last item in the initializer list.
-
-#### Example
-
-The following code produces this diagnostic because the invocation of the
-superclass' constructor isn't the last item in the initializer list:
-
-{% prettify dart tag=pre+code %}
-class A {
- A(int x);
-}
-
-class B extends A {
- B(int x) : [!super!](x), assert(x >= 0);
-}
-{% endprettify %}
-
-#### Common fixes
-
-Move the invocation of the superclass' constructor to the end of the
-initializer list:
-
-{% prettify dart tag=pre+code %}
-class A {
- A(int x);
-}
-
-class B extends A {
- B(int x) : assert(x >= 0), super(x);
-}
-{% endprettify %}
-
### invalid_type_argument_in_const_literal
_Constant list literals can't include a type parameter as a type argument, such
@@ -12846,6 +12806,48 @@
class C extends Object {}
{% endprettify %}
+### super_invocation_not_last
+
+<a id="invalid_super_invocation" aria-hidden="true"></a>_(Previously known as `invalid_super_invocation`)_
+
+_The superconstructor call must be last in an initializer list: '{0}'._
+
+#### Description
+
+The analyzer produces this diagnostic when the initializer list of a
+constructor contains an invocation of a constructor in the superclass, but
+the invocation isn't the last item in the initializer list.
+
+#### Example
+
+The following code produces this diagnostic because the invocation of the
+superclass' constructor isn't the last item in the initializer list:
+
+{% prettify dart tag=pre+code %}
+class A {
+ A(int x);
+}
+
+class B extends A {
+ B(int x) : [!super!](x), assert(x >= 0);
+}
+{% endprettify %}
+
+#### Common fixes
+
+Move the invocation of the superclass' constructor to the end of the
+initializer list:
+
+{% prettify dart tag=pre+code %}
+class A {
+ A(int x);
+}
+
+class B extends A {
+ B(int x) : assert(x >= 0), super(x);
+}
+{% endprettify %}
+
### super_in_extension
_The 'super' keyword can't be used in an extension because an extension doesn't
@@ -14435,7 +14437,7 @@
### undefined_super_member
-<a id="undefined_super_method" aria-hidden="true"></a>_(Previously known as `UNDEFINED_SUPER_METHOD`)_
+<a id="undefined_super_method" aria-hidden="true"></a>_(Previously known as `undefined_super_method`)_
_The getter '{0}' isn't defined in a superclass of '{1}'._
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index f7d094b..9f58663 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -71,9 +71,9 @@
sink.writeln('### ${name.toLowerCase()}');
for (var previousName in previousNames) {
sink.writeln();
- sink.writeln(
- '<a id="${previousName.toLowerCase()}" aria-hidden="true"></a>'
- '_(Previously known as `$previousName`)_');
+ var previousInLowerCase = previousName.toLowerCase();
+ sink.writeln('<a id="$previousInLowerCase" aria-hidden="true"></a>'
+ '_(Previously known as `$previousInLowerCase`)_');
}
for (String message in messages) {
sink.writeln();
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index 2fe6603..bb03fc8 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -69,9 +69,6 @@
///
/// Clients may not extend, implement or mix-in this class.
class CompletionTarget {
- /// The compilation unit in which the completion is occurring.
- final CompilationUnit unit;
-
/// The offset within the source at which the completion is being requested.
final int offset;
@@ -122,14 +119,8 @@
ParameterElement? _parameterElement;
/// Compute the appropriate [CompletionTarget] for the given [offset] within
- /// the [compilationUnit].
- ///
- /// Optionally, start the search from within [entryPoint] instead of using
- /// the [compilationUnit], which is useful for analyzing ASTs that have no
- /// [compilationUnit] such as dart expressions within angular templates.
- factory CompletionTarget.forOffset(
- CompilationUnit compilationUnit, int offset,
- {AstNode? entryPoint}) {
+ /// the [entryPoint].
+ factory CompletionTarget.forOffset(AstNode entryPoint, int offset) {
// The precise algorithm is as follows. We perform a depth-first search of
// all edges in the parse tree (both those that point to AST nodes and
// those that point to tokens), visiting parents before children. The
@@ -144,7 +135,6 @@
// prune the search to the point where no recursion is necessary; at each
// step in the process we know exactly which child node we need to proceed
// to.
- entryPoint ??= compilationUnit;
var containingNode = entryPoint;
outerLoop:
while (true) {
@@ -167,11 +157,10 @@
var commentToken = _getContainingCommentToken(entity, offset);
if (commentToken != null) {
return CompletionTarget._(
- compilationUnit, offset, containingNode, commentToken, true);
+ offset, containingNode, commentToken, true);
}
// Target found.
- return CompletionTarget._(
- compilationUnit, offset, containingNode, entity, false);
+ return CompletionTarget._(offset, containingNode, entity, false);
} else {
// Since entity is a token, we don't need to look inside it; just
// proceed to the next entity.
@@ -198,14 +187,13 @@
_getContainingDocComment(containingNode, commentToken);
if (docComment != null) {
return CompletionTarget._(
- compilationUnit, offset, docComment, commentToken, false);
+ offset, docComment, commentToken, false);
} else {
- return CompletionTarget._(compilationUnit, offset,
- compilationUnit, commentToken, true);
+ return CompletionTarget._(
+ offset, entryPoint, commentToken, true);
}
}
- return CompletionTarget._(
- compilationUnit, offset, containingNode, entity, false);
+ return CompletionTarget._(offset, containingNode, entity, false);
}
// Otherwise, the completion target is somewhere inside the entity,
@@ -228,23 +216,23 @@
assert(identical(containingNode, entryPoint));
// Check for comments on the EOF token (trailing comments in a file).
- var commentToken =
- _getContainingCommentToken(compilationUnit.endToken, offset);
- if (commentToken != null) {
- return CompletionTarget._(
- compilationUnit, offset, compilationUnit, commentToken, true);
+ if (entryPoint is CompilationUnit) {
+ var commentToken =
+ _getContainingCommentToken(entryPoint.endToken, offset);
+ if (commentToken != null) {
+ return CompletionTarget._(offset, entryPoint, commentToken, true);
+ }
}
// Since no completion target was found, we set the completion target
// entity to null and use the entryPoint as the parent.
- return CompletionTarget._(
- compilationUnit, offset, entryPoint, null, false);
+ return CompletionTarget._(offset, entryPoint, null, false);
}
}
/// Create a [CompletionTarget] holding the given [containingNode] and
/// [entity].
- CompletionTarget._(this.unit, this.offset, AstNode containingNode,
+ CompletionTarget._(this.offset, AstNode containingNode,
SyntacticEntity? entity, this.isCommentText)
: containingNode = containingNode,
entity = entity,
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index dea31e3..2110c49 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -7,7 +7,6 @@
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_system.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
@@ -20,22 +19,12 @@
/// suggestions should be made based upon the type of node in which the
/// suggestions were requested.
class OpType {
- /// The [TypeSystem] used during resolution of the current unit.
- TypeSystem? _typeSystem;
-
/// Indicates whether constructor suggestions should be included.
bool includeConstructorSuggestions = false;
/// Indicates whether type names should be suggested.
bool includeTypeNameSuggestions = false;
- /// If [includeTypeNameSuggestions] is set to true, then this function may
- /// be set to a non-default function to filter out potential suggestions
- /// (null) based on their static [DartType], or change the relative relevance
- /// by returning a higher or lower relevance.
- SuggestionsFilter typeNameSuggestionsFilter =
- (DartType _, int relevance) => relevance;
-
/// Indicates whether setters along with methods and functions that
/// have a [void] return type should be suggested.
bool includeVoidReturnSuggestions = false;
@@ -76,10 +65,6 @@
/// An representation of the location at which completion was requested.
String? completionLocation;
- /// The type that is required by the context in which the completion was
- /// activated, or `null` if there is no such type, or it cannot be determined.
- DartType? _requiredType;
-
/// Determine the suggestions that should be made based upon the given
/// [CompletionTarget] and [offset].
factory OpType.forCompletion(CompletionTarget target, int offset) {
@@ -90,8 +75,6 @@
return optype;
}
- optype._typeSystem = target.unit.declaredElement?.library.typeSystem;
-
var targetNode = target.containingNode;
targetNode.accept(_OpTypeAstVisitor(optype, target.entity, offset));
@@ -111,16 +94,9 @@
// If a value should be suggested, suggest also constructors.
if (optype.includeReturnValueSuggestions) {
- // Careful: in angular plugin, `target.unit` may be null!
- var unitElement = target.unit.declaredElement;
- if (unitElement != null) {
- optype.includeConstructorSuggestions = true;
- }
+ optype.includeConstructorSuggestions = true;
}
- // Compute the type required by the context and set filters.
- optype._computeRequiredTypeAndFilters(target);
-
return optype;
}
@@ -142,59 +118,6 @@
!includeReturnValueSuggestions &&
!includeVoidReturnSuggestions;
- /// Try to determine the required context type, and configure filters.
- void _computeRequiredTypeAndFilters(CompletionTarget target) {
- var entity = target.entity;
- AstNode? node = target.containingNode;
-
- if (node is InstanceCreationExpression &&
- node.keyword != null &&
- node.constructorName == entity) {
- entity = node;
- node = node.parent;
- }
-
- if (node is AssignmentExpression &&
- node.operator.type == TokenType.EQ &&
- node.rightHandSide == entity) {
- _requiredType = node.leftHandSide.staticType;
- } else if (node is BinaryExpression &&
- node.operator.type == TokenType.EQ_EQ &&
- node.rightOperand == entity) {
- _requiredType = node.leftOperand.staticType;
- } else if (node is NamedExpression && node.expression == entity) {
- _requiredType = node.staticParameterElement?.type;
- } else if (node is SwitchCase && node.expression == entity) {
- var parent = node.parent;
- if (parent is SwitchStatement) {
- _requiredType = parent.expression.staticType;
- }
- } else if (node is VariableDeclaration && node.initializer == entity) {
- _requiredType = node.declaredElement?.type;
- } else if (entity is Expression && entity.staticParameterElement != null) {
- _requiredType = entity.staticParameterElement?.type;
- }
-
- var requiredType = _requiredType;
- if (requiredType == null) {
- return;
- }
- if (requiredType.isDynamic || requiredType.isDartCoreObject) {
- _requiredType = null;
- return;
- }
- }
-
- /// Return `true` if the [leftType] is a subtype of the [rightType].
- bool _isSubtypeOf(DartType leftType, DartType rightType) {
- var typeSystem = _typeSystem;
- if (typeSystem == null) {
- return false;
- }
-
- return typeSystem.isSubtypeOf(leftType, rightType);
- }
-
/// Return the statement before [entity]
/// where [entity] can be a statement or the `}` closing the given block.
static Statement? getPreviousStatement(Block node, Object? entity) {
@@ -334,17 +257,6 @@
if (identical(entity, node.type)) {
optype.completionLocation = 'AsExpression_type';
optype.includeTypeNameSuggestions = true;
- optype.typeNameSuggestionsFilter = (DartType dartType, int relevance) {
- var staticType = node.expression.staticType;
- if (staticType != null &&
- (staticType.isDynamic ||
- (optype._isSubtypeOf(dartType, staticType) &&
- dartType != staticType))) {
- return relevance;
- } else {
- return null;
- }
- };
}
}
@@ -652,7 +564,6 @@
if (identical(entity, node.superclass2)) {
optype.completionLocation = 'ExtendsClause_superclass';
optype.includeTypeNameSuggestions = true;
- optype.typeNameSuggestionsFilter = _nonMixinClasses;
}
}
@@ -947,17 +858,6 @@
if (identical(entity, node.type)) {
optype.completionLocation = 'IsExpression_type';
optype.includeTypeNameSuggestions = true;
- optype.typeNameSuggestionsFilter = (DartType dartType, int relevance) {
- var staticType = node.expression.staticType;
- if (staticType != null &&
- (staticType.isDynamic ||
- (optype._isSubtypeOf(dartType, staticType) &&
- dartType != staticType))) {
- return relevance;
- } else {
- return null;
- }
- };
}
}
@@ -1473,18 +1373,6 @@
return false;
}
- /// A filter used to disable everything except classes (such as functions and
- /// mixins).
- int? _nonMixinClasses(DartType type, int relevance) {
- if (type is InterfaceType) {
- if (type.element.isMixin) {
- return null;
- }
- return relevance;
- }
- return null;
- }
-
static bool _isParameterOfGenericFunctionType(FormalParameter node) {
var parameterList = node.parent;
if (parameterList is DefaultFormalParameter) {
diff --git a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
index 3e6290b..58791ae 100644
--- a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
+++ b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
@@ -69,7 +69,8 @@
/// for example to allow key-binding specific fixes (or groups of).
final String id;
- /// The priority of this kind of assist for the kind of error being addressed.
+ /// The priority of this kind of assist for the kind of error being addressed
+ /// where a higher integer value indicates a higher priority and relevance.
final int priority;
/// A human-readable description of the changes that will be applied by this
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
index cf0a57b..77cc825 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
@@ -59,8 +59,8 @@
CompletionTarget? target,
OpType? optype,
}) async {
- target ??= CompletionTarget.forOffset(request.result.unit, request.offset,
- entryPoint: entryPoint);
+ entryPoint ??= request.result.unit;
+ target ??= CompletionTarget.forOffset(entryPoint, request.offset);
optype ??= OpType.forCompletion(target, request.offset);
if (!optype.includeIdentifiers) {
return;
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
index a27010c..d88f47a 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
@@ -29,7 +29,7 @@
var containingLibrary = request.result.libraryElement;
// Recompute the target since resolution may have changed it
- var expression = _computeDotTarget(request, null);
+ var expression = _computeDotTarget(request.result.unit, request.offset);
if (expression == null || expression.isSynthetic) {
return;
}
@@ -42,7 +42,7 @@
var containingLibrary = request.result.libraryElement;
// Recompute the target since resolution may have changed it
- var expression = _computeDotTarget(request, entryPoint);
+ var expression = _computeDotTarget(entryPoint, request.offset);
if (expression == null || expression.isSynthetic) {
return;
}
@@ -50,10 +50,8 @@
}
/// Update the completion [target] and [dotTarget] based on the given [unit].
- Expression? _computeDotTarget(
- DartCompletionRequest request, AstNode? entryPoint) {
- var target = CompletionTarget.forOffset(request.result.unit, request.offset,
- entryPoint: entryPoint);
+ Expression? _computeDotTarget(AstNode entryPoint, int offset) {
+ var target = CompletionTarget.forOffset(entryPoint, offset);
return target.dotTarget;
}
diff --git a/pkg/analyzer_utilities/test/check/check_test.dart b/pkg/analyzer_utilities/test/check/check_test.dart
index 532eea7..cc52f80 100644
--- a/pkg/analyzer_utilities/test/check/check_test.dart
+++ b/pkg/analyzer_utilities/test/check/check_test.dart
@@ -150,7 +150,7 @@
group('type', () {
test('isA', () {
check(0).isA<int>();
- _fails(() => check(0.0 as dynamic).isA<int>());
+ _fails(() => check('abc' as dynamic).isA<int>());
});
});
});
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 69a999f..8a48496 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -1397,8 +1397,8 @@
@override
void visitSwitch(js.Switch node) {
- if (!node.cases.any(shouldTransform)) {
- // If only the key has an await, translation can be simplified.
+ if (!shouldTransform(node)) {
+ // TODO(sra): If only the key has an await, translation can be simplified.
bool oldInsideUntranslated = insideUntranslatedBreakable;
insideUntranslatedBreakable = true;
withExpression(node.key, (js.Expression key) {
@@ -2824,10 +2824,9 @@
@override
bool visitSwitch(js.Switch node) {
loopsAndSwitches.add(node);
- // If the key has an `await` expression, do not transform the
- // body of the switch.
- visit(node.key);
- bool result = false;
+ // TODO(sra): If just the key has an `await` expression, do not transform
+ // the body of the switch.
+ bool result = visit(node.key);
for (js.SwitchClause clause in node.cases) {
if (visit(clause)) result = true;
}
diff --git a/pkg/compiler/test/async_await/async_await_js_transform_test.dart b/pkg/compiler/test/async_await/async_await_js_transform_test.dart
index 4ea675b..5897259 100644
--- a/pkg/compiler/test/async_await/async_await_js_transform_test.dart
+++ b/pkg/compiler/test/async_await/async_await_js_transform_test.dart
@@ -1085,20 +1085,116 @@
switch (__goto) {
case 0:
// Function start
- __goto = 2;
- return awaitHelper(l, body);
case 2:
+ // switch
+ __goto = 7;
+ return awaitHelper(l, body);
+ case 7:
// returning from await.
switch (__result) {
case 1:
- print(1);
+ // goto case
+ __goto = 4;
break;
case 2:
- print(1);
+ // goto case
+ __goto = 5;
+ break;
default:
- print(2);
+ // goto default
+ __goto = 6;
break;
}
+ break;
+ case 4:
+ // case
+ print(1);
+ // goto after switch
+ __goto = 3;
+ break;
+ case 5:
+ // case
+ print(1);
+ case 6:
+ // default
+ print(2);
+ // goto after switch
+ __goto = 3;
+ break;
+ case 3:
+ // after switch
+ // implicit return
+ return returnHelper(null, __completer);
+ }
+ });
+ return startHelper(body, __completer);
+}""");
+
+ testAsyncTransform("""
+ // This example is like #47566
+ function(b, l) async {
+ print("start");
+ if (b) {
+ switch(await l) {
+ case 1:
+ print(1);
+ break;
+ default:
+ print(2);
+ break;
+ }
+ }
+ print("end");
+ }""", """
+function(b, l) {
+ var __goto = 0,
+ __completer = NewCompleter(CompleterType);
+ var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
+ if (__errorCode === 1)
+ return rethrowHelper(__result, __completer);
+ while (true)
+ switch (__goto) {
+ case 0:
+ // Function start
+ print("start");
+ __goto = b ? 2 : 3;
+ break;
+ case 2:
+ // then
+ case 4:
+ // switch
+ __goto = 8;
+ return awaitHelper(l, body);
+ case 8:
+ // returning from await.
+ switch (__result) {
+ case 1:
+ // goto case
+ __goto = 6;
+ break;
+ default:
+ // goto default
+ __goto = 7;
+ break;
+ }
+ break;
+ case 6:
+ // case
+ print(1);
+ // goto after switch
+ __goto = 5;
+ break;
+ case 7:
+ // default
+ print(2);
+ // goto after switch
+ __goto = 5;
+ break;
+ case 5:
+ // after switch
+ case 3:
+ // join
+ print("end");
// implicit return
return returnHelper(null, __completer);
}
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 0ef4650..b53dc75 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -939,7 +939,7 @@
SuperInitializerNotLast:
problemMessage: "Can't have initializers after 'super'."
- analyzerCode: INVALID_SUPER_INVOCATION
+ analyzerCode: SUPER_INVOCATION_NOT_LAST
script:
- "class C { int x; C.bad() : super(), x = 5; }"
diff --git a/sdk/bin/dartanalyzer b/sdk/bin/dartanalyzer
index 0574603..6525627 100755
--- a/sdk/bin/dartanalyzer
+++ b/sdk/bin/dartanalyzer
@@ -6,6 +6,8 @@
# Run dartanalyzer.dart on the Dart VM. This script assumes the Dart repo's
# directory structure.
+echo "Warning: 'dartanalyzer' is deprecated. Please use 'dart analyze'." 1>&2
+
function follow_links() {
file="$1"
while [ -h "$file" ]; do
diff --git a/sdk/bin/dartanalyzer.bat b/sdk/bin/dartanalyzer.bat
index efa3a6a..122e9b3 100644
--- a/sdk/bin/dartanalyzer.bat
+++ b/sdk/bin/dartanalyzer.bat
@@ -3,6 +3,8 @@
REM for details. All rights reserved. Use of this source code is governed by a
REM BSD-style license that can be found in the LICENSE file.
+echo Warning: 'dartanalyzer' is deprecated. Please use 'dart analyze'. 1>&2
+
setlocal
rem Handle the case where dart-sdk/bin has been symlinked to.
set DIR_NAME_WITH_SLASH=%~dp0
diff --git a/sdk/lib/convert/ascii.dart b/sdk/lib/convert/ascii.dart
index 9f62c2d..30a9599 100644
--- a/sdk/lib/convert/ascii.dart
+++ b/sdk/lib/convert/ascii.dart
@@ -35,7 +35,7 @@
/// Encoders will not accept invalid (non ASCII) characters.
const AsciiCodec({bool allowInvalid = false}) : _allowInvalid = allowInvalid;
- /// The name of this codec, "us-ascii".
+ /// The name of this codec is "us-ascii".
String get name => "us-ascii";
Uint8List encode(String source) => encoder.convert(source);
@@ -103,7 +103,15 @@
Stream<List<int>> bind(Stream<String> stream) => super.bind(stream);
}
-/// This class converts strings of only ASCII characters to bytes.
+/// Converts strings of only ASCII characters to bytes.
+///
+/// Example:
+/// ```dart import:typed_data
+/// const asciiEncoder = AsciiEncoder();
+/// const sample = 'Dart';
+/// final asciiValues = asciiEncoder.convert(sample);
+/// print(asciiValues); // [68, 97, 114, 116]
+/// ```
class AsciiEncoder extends _UnicodeSubsetEncoder {
const AsciiEncoder() : super(_asciiMask);
}
@@ -195,6 +203,29 @@
Stream<String> bind(Stream<List<int>> stream) => super.bind(stream);
}
+/// Converts ASCII bytes to string.
+///
+/// Example:
+/// ```dart
+/// const asciiDecoder = AsciiDecoder();
+/// final asciiValues = [68, 97, 114, 116];
+/// final result = asciiDecoder.convert(asciiValues);
+/// print(result); // Dart
+/// ```
+/// Throws a [FormatException] if [bytes] contains values that are not
+/// in the range 0 .. 127, and [allowInvalid] is `false` (the default).
+///
+/// If [allowInvalid] is `true`, any byte outside the range 0..127 is replaced
+/// by the Unicode replacement character, U+FFFD ('�').
+///
+/// Example with `allowInvalid` set to true:
+/// ```dart
+/// const asciiDecoder = AsciiDecoder(allowInvalid: true);
+/// final asciiValues = [68, 97, 114, 116, 20, 0xFF];
+/// final result = asciiDecoder.convert(asciiValues);
+/// print(result); // Dart �
+/// print(result.codeUnits.last.toRadixString(16)); // fffd
+/// ```
class AsciiDecoder extends _UnicodeSubsetDecoder {
const AsciiDecoder({bool allowInvalid = false})
: super(allowInvalid, _asciiMask);
diff --git a/sdk/lib/convert/line_splitter.dart b/sdk/lib/convert/line_splitter.dart
index 85f0ab6..2e01ae6 100644
--- a/sdk/lib/convert/line_splitter.dart
+++ b/sdk/lib/convert/line_splitter.dart
@@ -10,12 +10,31 @@
/// A [StreamTransformer] that splits a [String] into individual lines.
///
-/// A line is terminated by either a CR (U+000D), a LF (U+000A), a
-/// CR+LF sequence (DOS line ending),
-/// and a final non-empty line can be ended by the end of the string.
+/// A line is terminated by either:
+/// * a CR, carriage return: U+000D ('\r')
+/// * a LF, line feed (Unix line break): U+000A ('\n') or
+/// * a CR+LF sequence (DOS/Windows line break), and
+/// * a final non-empty line can be ended by the end of the input.
///
-/// The returned lines do not contain the line terminators.
-
+/// The resulting lines do not contain the line terminators.
+///
+/// Example:
+/// ```dart
+/// const splitter = LineSplitter();
+/// const sampleText =
+/// 'Dart is: \r an object-oriented \n class-based \n garbage-collected '
+/// '\r\n language with C-style syntax \r\n';
+///
+/// final sampleTextLines = splitter.convert(sampleText);
+/// for (var i = 0; i < sampleTextLines.length; i++) {
+/// print('$i: ${sampleTextLines[i]}');
+/// }
+/// // 0: Dart is:
+/// // 1: an object-oriented
+/// // 2: class-based
+/// // 3: garbage-collected
+/// // 4: language with C-style syntax
+/// ```
class LineSplitter extends StreamTransformerBase<String, String> {
const LineSplitter();
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index 57a2dac..47f2647 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -40,7 +40,7 @@
const Utf8Codec({bool allowMalformed = false})
: _allowMalformed = allowMalformed;
- /// The name of this codec, "utf-8".
+ /// The name of this codec is "utf-8".
String get name => "utf-8";
/// Decodes the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the
@@ -49,7 +49,7 @@
/// If the [codeUnits] start with the encoding of a
/// [unicodeBomCharacterRune], that character is discarded.
///
- /// If [allowMalformed] is `true` the decoder replaces invalid (or
+ /// If [allowMalformed] is `true`, the decoder replaces invalid (or
/// unterminated) character sequences with the Unicode Replacement character
/// `U+FFFD` (�). Otherwise it throws a [FormatException].
///
@@ -74,6 +74,14 @@
/// This class converts strings to their UTF-8 code units (a list of
/// unsigned 8-bit integers).
+///
+/// Example:
+/// ```dart
+/// final utf8Encoder = utf8.encoder;
+/// const sample = 'Îñţérñåţîöñåļîžåţîờñ';
+/// final encodedSample = utf8Encoder.convert(sample);
+/// print(encodedSample);
+/// ```
class Utf8Encoder extends Converter<String, List<int>> {
const Utf8Encoder();
@@ -148,10 +156,10 @@
/// writes it to [_buffer].
///
/// Returns true if the [nextCodeUnit] was combined with the
- /// [leadingSurrogate]. If it wasn't then nextCodeUnit was not a trailing
+ /// [leadingSurrogate]. If it wasn't, then nextCodeUnit was not a trailing
/// surrogate and has not been written yet.
///
- /// It is safe to pass 0 for [nextCodeUnit] in which case a replacement
+ /// It is safe to pass 0 for [nextCodeUnit], in which case a replacement
/// character is written to represent the unpaired lead surrogate.
bool _writeSurrogate(int leadingSurrogate, int nextCodeUnit) {
if (_isTailSurrogate(nextCodeUnit)) {
@@ -285,6 +293,31 @@
/// This class converts UTF-8 code units (lists of unsigned 8-bit integers)
/// to a string.
+///
+/// Example:
+/// ```dart
+/// final utf8Decoder = utf8.decoder;
+/// const encodedBytes = [
+/// 195, 142, 195, 177, 197, 163, 195, 169, 114, 195, 177, 195, 165, 197,
+/// 163, 195, 174, 195, 182, 195, 177, 195, 165, 196, 188, 195, 174, 197,
+/// 190, 195, 165, 197, 163, 195, 174, 225, 187, 157, 195, 177];
+///
+/// final decodedBytes = utf8Decoder.convert(encodedBytes);
+/// print(decodedBytes); // Îñţérñåţîöñåļîžåţîờñ
+/// ```
+/// Throws a [FormatException] if the encoded input contains
+/// invalid UTF-8 byte sequences and [allowMalformed] is `false` (the default).
+///
+/// If [allowMalformed] is `true`, invalid byte sequences are converted into
+/// one or more Unicode replacement characters, U+FFFD ('�').
+///
+/// Example with `allowMalformed` set to true:
+/// ```dart
+/// const utf8Decoder = Utf8Decoder(allowMalformed: true);
+/// const encodedBytes = [0xFF];
+/// final decodedBytes = utf8Decoder.convert(encodedBytes);
+/// print(decodedBytes); // �
+/// ```
class Utf8Decoder extends Converter<List<int>, String> {
final bool _allowMalformed;
@@ -293,7 +326,7 @@
/// The optional [allowMalformed] argument defines how [convert] deals
/// with invalid or unterminated character sequences.
///
- /// If it is `true` [convert] replaces invalid (or unterminated) character
+ /// If it is `true`, [convert] replaces invalid (or unterminated) character
/// sequences with the Unicode Replacement character `U+FFFD` (�). Otherwise
/// it throws a [FormatException].
const Utf8Decoder({bool allowMalformed = false})
@@ -302,7 +335,7 @@
/// Converts the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the
/// corresponding string.
///
- /// Uses the code units from [start] to, but no including, [end].
+ /// Uses the code units from [start] to, but not including, [end].
/// If [end] is omitted, it defaults to `codeUnits.length`.
///
/// If the [codeUnits] start with the encoding of a
diff --git a/tests/language/regress/regress47566_test.dart b/tests/language/regress/regress47566_test.dart
new file mode 100644
index 0000000..4ba35ae
--- /dev/null
+++ b/tests/language/regress/regress47566_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2021, 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.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/47566
+
+import 'package:expect/expect.dart';
+
+final List trace = [];
+void log(String s) {
+ trace.add(s);
+}
+
+Future<void> test(bool value) async {
+ log('f1');
+
+ if (value) {
+ final result = await bar();
+ switch (result) {
+ case 1:
+ log('sb');
+ break;
+ case 0:
+ return;
+ }
+ log('sc');
+ }
+
+ log('f2');
+}
+
+Future<int> bar() async => 1;
+
+Future<void> main() async {
+ trace.clear();
+ await test(true);
+ Expect.equals('f1,sb,sc,f2', trace.join(','));
+
+ trace.clear();
+ await test(false);
+ Expect.equals('f1,f2', trace.join(','));
+}
diff --git a/tests/language/variable/initializer_super_last_test.dart b/tests/language/variable/initializer_super_last_test.dart
index 7e2b0b8..6bb1022 100644
--- a/tests/language/variable/initializer_super_last_test.dart
+++ b/tests/language/variable/initializer_super_last_test.dart
@@ -40,7 +40,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x;
//^
// [cfe] Can't have initializers after 'super'.
@@ -48,7 +48,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x;
//^
// [cfe] Can't have initializers after 'super'.
@@ -56,7 +56,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -64,7 +64,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -72,7 +72,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x,
//^
// [cfe] Can't have initializers after 'super'.
@@ -83,7 +83,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x,
//^
// [cfe] Can't have initializers after 'super'.
@@ -94,7 +94,7 @@
: x = x,
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -102,7 +102,7 @@
: x = x,
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -133,7 +133,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x;
//^
// [cfe] Can't have initializers after 'super'.
@@ -141,7 +141,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x;
//^
// [cfe] Can't have initializers after 'super'.
@@ -149,7 +149,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -157,7 +157,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -165,7 +165,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x,
//^
// [cfe] Can't have initializers after 'super'.
@@ -176,7 +176,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x,
//^
// [cfe] Can't have initializers after 'super'.
@@ -187,7 +187,7 @@
: x = x,
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -195,7 +195,7 @@
: x = x,
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
diff --git a/tests/language_2/variable/initializer_super_last_test.dart b/tests/language_2/variable/initializer_super_last_test.dart
index a466562..bdc36e7 100644
--- a/tests/language_2/variable/initializer_super_last_test.dart
+++ b/tests/language_2/variable/initializer_super_last_test.dart
@@ -42,7 +42,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x;
//^
// [cfe] Can't have initializers after 'super'.
@@ -50,7 +50,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x;
//^
// [cfe] Can't have initializers after 'super'.
@@ -58,7 +58,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -66,7 +66,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -74,7 +74,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x,
//^
// [cfe] Can't have initializers after 'super'.
@@ -85,7 +85,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x,
//^
// [cfe] Can't have initializers after 'super'.
@@ -96,7 +96,7 @@
: x = x,
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -104,7 +104,7 @@
: x = x,
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -135,7 +135,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x;
//^
// [cfe] Can't have initializers after 'super'.
@@ -143,7 +143,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x;
//^
// [cfe] Can't have initializers after 'super'.
@@ -151,7 +151,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -159,7 +159,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -167,7 +167,7 @@
: //
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x,
//^
// [cfe] Can't have initializers after 'super'.
@@ -178,7 +178,7 @@
: //
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
x = x,
//^
// [cfe] Can't have initializers after 'super'.
@@ -189,7 +189,7 @@
: x = x,
super(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
@@ -197,7 +197,7 @@
: x = x,
super.named(),
// ^^^^^
-// [analyzer] COMPILE_TIME_ERROR.INVALID_SUPER_INVOCATION
+// [analyzer] COMPILE_TIME_ERROR.SUPER_INVOCATION_NOT_LAST
assert(x == x);
// ^
// [cfe] Can't have initializers after 'super'.
diff --git a/tools/VERSION b/tools/VERSION
index a3fcafc..7b162d3 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 295
+PRERELEASE 296
PRERELEASE_PATCH 0
\ No newline at end of file