Version 2.10.0-21.0.dev
Merge commit 'a3b15aefcaed10e62444d449394d561b3b12dcb4' into 'dev'
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 e2285a0..fb49ebe 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -3273,6 +3273,7 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageExternalLateField = const MessageCode(
"ExternalLateField",
+ index: 109,
message: r"""External fields cannot be late.""",
tip: r"""Try removing the 'external' or 'late' keyword.""");
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 7d6d0e3..57b0902 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.39.18-dev
+* Added `LibraryElement.featureSet`.
+
## 0.39.17
* Depend on cli_util 0.2.0.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index a2e9d64..8a4d9b9 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -34,6 +34,7 @@
/// representation of the statements in a method body, but if one of those
/// statements declares a local variable then the local variable will be
/// represented by an element.
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -1317,6 +1318,13 @@
/// Return a list containing all of the exports defined in this library.
List<ExportElement> get exports;
+ /// The set of features available to this library.
+ ///
+ /// Determined by the combination of the language version for the enclosing
+ /// package, enabled experiments, and the presence of a `// @dart` language
+ /// version override comment at the top of the file.
+ FeatureSet get featureSet;
+
/// Return `true` if the defining compilation unit of this library contains at
/// least one import directive whose URI uses the "dart-ext" scheme.
bool get hasExtUri;
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 9c7bfac..095f89c 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -172,6 +172,9 @@
CompileTimeErrorCode.EXTENSION_OVERRIDE_ARGUMENT_NOT_ASSIGNABLE,
CompileTimeErrorCode.EXTENSION_OVERRIDE_WITH_CASCADE,
CompileTimeErrorCode.EXTENSION_OVERRIDE_WITHOUT_ACCESS,
+ CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER,
+ CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER,
+ CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER,
CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS,
CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED,
CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
@@ -632,6 +635,7 @@
ParserErrorCode.EXTERNAL_FACTORY_WITH_BODY,
ParserErrorCode.EXTERNAL_FIELD,
ParserErrorCode.EXTERNAL_GETTER_WITH_BODY,
+ ParserErrorCode.EXTERNAL_LATE_FIELD,
ParserErrorCode.EXTERNAL_METHOD_WITH_BODY,
ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY,
ParserErrorCode.EXTERNAL_SETTER_WITH_BODY,
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 81e5485..94b9332 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -91,7 +91,7 @@
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
class AnalysisDriver implements AnalysisDriverGeneric {
/// The version of data format, should be incremented on every format change.
- static const int DATA_VERSION = 108;
+ static const int DATA_VERSION = 109;
/// The length of the list returned by [_computeDeclaredVariablesSignature].
static const int _declaredVariablesSignatureLength = 4;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 2456a92..f40eb69 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4,6 +4,7 @@
import 'dart:collection';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
@@ -5369,6 +5370,9 @@
}
@override
+ FeatureSet get featureSet => (linkedNode as CompilationUnit).featureSet;
+
+ @override
bool get hasExtUri {
if (linkedNode != null) {
var unit = linkedContext.unit_withDirectives;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 57cc394..f55c540 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -303,6 +303,8 @@
correction: "Try removing the body of the getter, or "
"removing the keyword 'external'.");
+ static const ParserErrorCode EXTERNAL_LATE_FIELD = _EXTERNAL_LATE_FIELD;
+
static const ParserErrorCode EXTERNAL_METHOD_WITH_BODY =
_EXTERNAL_METHOD_WITH_BODY;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index 748f18c..8c50c14 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -116,6 +116,7 @@
_EXTERNAL_CONSTRUCTOR_WITH_INITIALIZER,
_ABSTRACT_STATIC_FIELD,
_ABSTRACT_LATE_FIELD,
+ _EXTERNAL_LATE_FIELD,
];
const ParserErrorCode _ABSTRACT_CLASS_MEMBER = ParserErrorCode(
@@ -315,6 +316,10 @@
correction:
"Try removing the keyword 'external', or replacing the field by an external getter and/or setter.");
+const ParserErrorCode _EXTERNAL_LATE_FIELD = ParserErrorCode(
+ 'EXTERNAL_LATE_FIELD', r"External fields cannot be late.",
+ correction: "Try removing the 'external' or 'late' keyword.");
+
const ParserErrorCode _EXTERNAL_METHOD_WITH_BODY = ParserErrorCode(
'EXTERNAL_METHOD_WITH_BODY',
r"An external or native method can't have a body.");
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index b126f7e..a0b721c 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2980,6 +2980,25 @@
correction: "Consider adding an access to an instance member.",
hasPublishedDocs: true);
+ static const CompileTimeErrorCode EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER =
+ CompileTimeErrorCode('EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER',
+ 'External fields cannot have initializers.',
+ correction:
+ "Try removing the field initializer or the 'external' keyword "
+ "from the field declaration.");
+
+ static const CompileTimeErrorCode EXTERNAL_FIELD_INITIALIZER =
+ CompileTimeErrorCode('EXTERNAL_FIELD_INITIALIZER',
+ 'External fields cannot have initializers.',
+ correction:
+ "Try removing the initializer or the 'external' keyword.");
+
+ static const CompileTimeErrorCode EXTERNAL_VARIABLE_INITIALIZER =
+ CompileTimeErrorCode('EXTERNAL_VARIABLE_INITIALIZER',
+ 'External variables cannot have initializers.',
+ correction:
+ "Try removing the initializer or the 'external' keyword.");
+
/**
* Parameters:
* 0: the maximum number of positional arguments
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 8ababeb..839f9a6 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -15,6 +15,7 @@
messageDirectiveAfterDeclaration,
messageExpectedStatement,
messageExternalField,
+ messageExternalLateField,
messageFieldInitializerOutsideConstructor,
messageIllegalAssignmentToNonAssignable,
messageInterpolationInUri,
@@ -866,9 +867,14 @@
}
}
}
- if (externalToken != null && !enableNonNullable) {
- handleRecoverableError(
- messageExternalField, externalToken, externalToken);
+ if (externalToken != null) {
+ if (!enableNonNullable) {
+ handleRecoverableError(
+ messageExternalField, externalToken, externalToken);
+ } else if (lateToken != null) {
+ handleRecoverableError(
+ messageExternalLateField, externalToken, externalToken);
+ }
}
List<VariableDeclaration> variables = popTypedList(count);
@@ -2153,9 +2159,14 @@
assert(optional(';', semicolon));
debugEvent("TopLevelFields");
- if (externalToken != null && !enableNonNullable) {
- handleRecoverableError(
- messageExternalField, externalToken, externalToken);
+ if (externalToken != null) {
+ if (!enableNonNullable) {
+ handleRecoverableError(
+ messageExternalField, externalToken, externalToken);
+ } else if (lateToken != null) {
+ handleRecoverableError(
+ messageExternalLateField, externalToken, externalToken);
+ }
}
List<VariableDeclaration> variables = popTypedList(count);
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 91f08b0..1576546 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -491,7 +491,7 @@
_checkForInvalidField(node, fieldName, staticElement);
if (staticElement is FieldElement) {
_checkForFieldInitializerNotAssignable(node, staticElement);
- _checkForAbstractFieldConstructorInitializer(
+ _checkForAbstractOrExternalFieldConstructorInitializer(
node.fieldName, staticElement);
}
super.visitConstructorFieldInitializer(node);
@@ -605,7 +605,7 @@
if (element is FieldFormalParameterElement) {
FieldElement fieldElement = element.field;
if (fieldElement != null) {
- _checkForAbstractFieldConstructorInitializer(
+ _checkForAbstractOrExternalFieldConstructorInitializer(
node.identifier, fieldElement);
}
}
@@ -1200,7 +1200,7 @@
// do checks
_checkForInvalidAssignment(nameNode, initializerNode);
_checkForImplicitDynamicIdentifier(node, nameNode);
- _checkForAbstractFieldInitializer(node);
+ _checkForAbstractOrExternalVariableInitializer(node);
// visit name
nameNode.accept(this);
// visit initializer
@@ -1294,21 +1294,37 @@
}
}
- void _checkForAbstractFieldConstructorInitializer(
+ void _checkForAbstractOrExternalFieldConstructorInitializer(
AstNode node, FieldElement fieldElement) {
if (fieldElement.isAbstract) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER, node);
}
+ if (fieldElement.isExternal) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, node);
+ }
}
- void _checkForAbstractFieldInitializer(VariableDeclaration node) {
+ void _checkForAbstractOrExternalVariableInitializer(
+ VariableDeclaration node) {
var declaredElement = node.declaredElement;
- if (declaredElement is FieldElement &&
- declaredElement.isAbstract &&
- node.initializer != null) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.ABSTRACT_FIELD_INITIALIZER, node.name);
+ if (node.initializer != null) {
+ if (declaredElement is FieldElement) {
+ if (declaredElement.isAbstract) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.ABSTRACT_FIELD_INITIALIZER, node.name);
+ }
+ if (declaredElement.isExternal) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, node.name);
+ }
+ } else if (declaredElement is TopLevelVariableElement) {
+ if (declaredElement.isExternal) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, node.name);
+ }
+ }
}
}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index f7c6b21..ce3f18b 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -7028,11 +7028,22 @@
return _variantField_33 ??= <String>[];
}
+ @override
+ List<String> get compilationUnit_featureSetStrings {
+ assert(kind == idl.LinkedNodeKind.compilationUnit);
+ return _variantField_33 ??= <String>[];
+ }
+
set comment_tokens(List<String> value) {
assert(kind == idl.LinkedNodeKind.comment);
_variantField_33 = value;
}
+ set compilationUnit_featureSetStrings(List<String> value) {
+ assert(kind == idl.LinkedNodeKind.compilationUnit);
+ _variantField_33 = value;
+ }
+
@override
idl.LinkedNodeCommentType get comment_type {
assert(kind == idl.LinkedNodeKind.comment);
@@ -7749,12 +7760,14 @@
LinkedNodeBuilder.compilationUnit({
List<LinkedNodeBuilder> compilationUnit_declarations,
LinkedNodeBuilder compilationUnit_scriptTag,
+ List<String> compilationUnit_featureSetStrings,
List<LinkedNodeBuilder> compilationUnit_directives,
LinkedLibraryLanguageVersionBuilder compilationUnit_languageVersion,
int informativeId,
}) : _kind = idl.LinkedNodeKind.compilationUnit,
_variantField_2 = compilationUnit_declarations,
_variantField_6 = compilationUnit_scriptTag,
+ _variantField_33 = compilationUnit_featureSetStrings,
_variantField_3 = compilationUnit_directives,
_variantField_40 = compilationUnit_languageVersion,
_variantField_36 = informativeId;
@@ -9378,6 +9391,14 @@
signature.addBool(this.compilationUnit_scriptTag != null);
this.compilationUnit_scriptTag?.collectApiSignature(signature);
signature.addInt(this.flags ?? 0);
+ if (this.compilationUnit_featureSetStrings == null) {
+ signature.addInt(0);
+ } else {
+ signature.addInt(this.compilationUnit_featureSetStrings.length);
+ for (var x in this.compilationUnit_featureSetStrings) {
+ signature.addString(x);
+ }
+ }
signature.addString(this.name ?? '');
signature.addBool(this.compilationUnit_languageVersion != null);
this.compilationUnit_languageVersion?.collectApiSignature(signature);
@@ -12866,6 +12887,14 @@
}
@override
+ List<String> get compilationUnit_featureSetStrings {
+ assert(kind == idl.LinkedNodeKind.compilationUnit);
+ _variantField_33 ??= const fb.ListReader<String>(fb.StringReader())
+ .vTableGet(_bc, _bcOffset, 33, const <String>[]);
+ return _variantField_33;
+ }
+
+ @override
idl.LinkedNodeCommentType get comment_type {
assert(kind == idl.LinkedNodeKind.comment);
_variantField_29 ??= const _LinkedNodeCommentTypeReader()
@@ -13511,6 +13540,10 @@
_result["compilationUnit_scriptTag"] =
compilationUnit_scriptTag.toJson();
}
+ if (compilationUnit_featureSetStrings.isNotEmpty) {
+ _result["compilationUnit_featureSetStrings"] =
+ compilationUnit_featureSetStrings;
+ }
if (compilationUnit_directives.isNotEmpty) {
_result["compilationUnit_directives"] = compilationUnit_directives
.map((_value) => _value.toJson())
@@ -15050,6 +15083,7 @@
return {
"compilationUnit_declarations": compilationUnit_declarations,
"compilationUnit_scriptTag": compilationUnit_scriptTag,
+ "compilationUnit_featureSetStrings": compilationUnit_featureSetStrings,
"compilationUnit_directives": compilationUnit_directives,
"compilationUnit_languageVersion": compilationUnit_languageVersion,
"flags": flags,
@@ -17469,20 +17503,12 @@
class LinkedNodeUnitBuilder extends Object
with _LinkedNodeUnitMixin
implements idl.LinkedNodeUnit {
- bool _isNNBD;
bool _isSynthetic;
LinkedNodeBuilder _node;
String _partUriStr;
String _uriStr;
@override
- bool get isNNBD => _isNNBD ??= false;
-
- set isNNBD(bool value) {
- this._isNNBD = value;
- }
-
- @override
bool get isSynthetic => _isSynthetic ??= false;
set isSynthetic(bool value) {
@@ -17514,13 +17540,11 @@
}
LinkedNodeUnitBuilder(
- {bool isNNBD,
- bool isSynthetic,
+ {bool isSynthetic,
LinkedNodeBuilder node,
String partUriStr,
String uriStr})
- : _isNNBD = isNNBD,
- _isSynthetic = isSynthetic,
+ : _isSynthetic = isSynthetic,
_node = node,
_partUriStr = partUriStr,
_uriStr = uriStr;
@@ -17536,7 +17560,6 @@
signature.addBool(this._node != null);
this._node?.collectApiSignature(signature);
signature.addBool(this._isSynthetic == true);
- signature.addBool(this._isNNBD == true);
signature.addString(this._partUriStr ?? '');
}
@@ -17554,9 +17577,6 @@
offset_uriStr = fbBuilder.writeString(_uriStr);
}
fbBuilder.startTable();
- if (_isNNBD == true) {
- fbBuilder.addBool(3, true);
- }
if (_isSynthetic == true) {
fbBuilder.addBool(2, true);
}
@@ -17564,7 +17584,7 @@
fbBuilder.addOffset(1, offset_node);
}
if (offset_partUriStr != null) {
- fbBuilder.addOffset(4, offset_partUriStr);
+ fbBuilder.addOffset(3, offset_partUriStr);
}
if (offset_uriStr != null) {
fbBuilder.addOffset(0, offset_uriStr);
@@ -17589,19 +17609,12 @@
_LinkedNodeUnitImpl(this._bc, this._bcOffset);
- bool _isNNBD;
bool _isSynthetic;
idl.LinkedNode _node;
String _partUriStr;
String _uriStr;
@override
- bool get isNNBD {
- _isNNBD ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 3, false);
- return _isNNBD;
- }
-
- @override
bool get isSynthetic {
_isSynthetic ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
return _isSynthetic;
@@ -17615,7 +17628,7 @@
@override
String get partUriStr {
- _partUriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 4, '');
+ _partUriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
return _partUriStr;
}
@@ -17630,9 +17643,6 @@
@override
Map<String, Object> toJson() {
Map<String, Object> _result = <String, Object>{};
- if (isNNBD != false) {
- _result["isNNBD"] = isNNBD;
- }
if (isSynthetic != false) {
_result["isSynthetic"] = isSynthetic;
}
@@ -17650,7 +17660,6 @@
@override
Map<String, Object> toMap() => {
- "isNNBD": isNNBD,
"isSynthetic": isSynthetic,
"node": node,
"partUriStr": partUriStr,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 211f5fb..5190610 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1247,15 +1247,13 @@
/// Information about a single library in a [LinkedNodeLibrary].
table LinkedNodeUnit {
- isNNBD:bool (id: 3);
-
isSynthetic:bool (id: 2);
node:LinkedNode (id: 1);
/// If the unit is a part, the URI specified in the `part` directive.
/// Otherwise empty.
- partUriStr:string (id: 4);
+ partUriStr:string (id: 3);
/// The absolute URI.
uriStr:string (id: 0);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 8f6deea..bd5eac0 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -864,6 +864,9 @@
@VariantId(3, variant: LinkedNodeKind.compilationUnit)
List<LinkedNode> get compilationUnit_directives;
+ @VariantId(33, variant: LinkedNodeKind.compilationUnit)
+ List<String> get compilationUnit_featureSetStrings;
+
/// The language version information.
@VariantId(40, variant: LinkedNodeKind.compilationUnit)
LinkedLibraryLanguageVersion get compilationUnit_languageVersion;
@@ -1873,9 +1876,6 @@
/// Information about a single library in a [LinkedNodeLibrary].
abstract class LinkedNodeUnit extends base.SummaryClass {
- @Id(3)
- bool get isNNBD;
-
@Id(2)
bool get isSynthetic;
@@ -1884,7 +1884,7 @@
/// If the unit is a part, the URI specified in the `part` directive.
/// Otherwise empty.
- @Id(4)
+ @Id(3)
String get partUriStr;
/// The absolute URI.
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index f79f45d..0a1f078 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/ast_factory.dart';
import 'package:analyzer/src/dart/element/member.dart';
@@ -363,7 +364,9 @@
directives: _readNodeList(data.compilationUnit_directives),
declarations: _readNodeList(data.compilationUnit_declarations),
endToken: null,
- featureSet: null,
+ featureSet: ExperimentStatus.fromStrings(
+ data.compilationUnit_featureSetStrings,
+ ),
);
LazyCompilationUnit(node, data);
return node;
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 7a71a14..8ec9dd4 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/summary/format.dart';
@@ -286,6 +287,8 @@
var builder = LinkedNodeBuilder.compilationUnit(
compilationUnit_declarations: _writeNodeList(node.declarations),
compilationUnit_directives: _writeNodeList(node.directives),
+ compilationUnit_featureSetStrings:
+ (node.featureSet as ExperimentStatus).toStringList(),
compilationUnit_languageVersion: LinkedLibraryLanguageVersionBuilder(
package: LinkedLanguageVersionBuilder(
major: nodeImpl.languageVersion.package.major,
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 7f7118e..3f34f0d 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
@@ -179,7 +178,6 @@
partUriStr: unitContext.partUriStr,
uriStr: unitContext.uriStr,
node: unitLinkedNode,
- isNNBD: unit.featureSet.isEnabled(Feature.non_nullable),
),
);
}
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 527c5de..0058130 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -79,8 +79,8 @@
/// Return `true` if this unit is a part of a bundle that is being linked.
bool get isLinking => bundleContext.isLinking;
+ /// TODO(scheglov) remove it
bool get isNNBD {
- if (data != null) return data.isNNBD;
return _unit.featureSet.isEnabled(Feature.non_nullable);
}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index be78fcc..92f288c 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.39.17
+version: 0.39.18-dev
description: This package provides a library that performs static analysis of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 7a398a2..6f27e07 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -254,6 +254,40 @@
expect(field.externalKeyword, isNotNull);
}
+ void test_parseField_external_late() {
+ createParser('external late int? i;', featureSet: nonNullable);
+ ClassMember member = parser.parseClassMember('C');
+ expect(member, isNotNull);
+ assertErrors(errors: [
+ expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
+ ]);
+ expect(member, isFieldDeclaration);
+ FieldDeclaration field = member;
+ expect(field.externalKeyword, isNotNull);
+ }
+
+ void test_parseField_external_late_final() {
+ createParser('external late final int? i;', featureSet: nonNullable);
+ ClassMember member = parser.parseClassMember('C');
+ expect(member, isNotNull);
+ assertErrors(errors: [
+ expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
+ ]);
+ expect(member, isFieldDeclaration);
+ FieldDeclaration field = member;
+ expect(field.externalKeyword, isNotNull);
+ }
+
+ void test_parseField_external_static() {
+ createParser('external static int? i;', featureSet: nonNullable);
+ ClassMember member = parser.parseClassMember('C');
+ expect(member, isNotNull);
+ assertNoErrors();
+ expect(member, isFieldDeclaration);
+ FieldDeclaration field = member;
+ expect(field.externalKeyword, isNotNull);
+ }
+
void test_parseField_final_late() {
createParser('final late T f;', featureSet: nonNullable);
ClassMember member = parser.parseClassMember('C');
@@ -4627,6 +4661,26 @@
expect(declaration.externalKeyword, isNotNull);
}
+ void test_parseTopLevelVariable_external_late() {
+ var unit = parseCompilationUnit('external late int? i;',
+ featureSet: nonNullable,
+ errors: [
+ expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
+ ]);
+ var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
+ expect(declaration.externalKeyword, isNotNull);
+ }
+
+ void test_parseTopLevelVariable_external_late_final() {
+ var unit = parseCompilationUnit('external late final int? i;',
+ featureSet: nonNullable,
+ errors: [
+ expectedError(ParserErrorCode.EXTERNAL_LATE_FIELD, 0, 8),
+ ]);
+ var declaration = unit.declarations[0] as TopLevelVariableDeclaration;
+ expect(declaration.externalKeyword, isNotNull);
+ }
+
void test_parseTopLevelVariable_final_late() {
var unit = parseCompilationUnit('final late a;',
featureSet: nonNullable,
diff --git a/pkg/analyzer/test/src/dart/resolution/library_element_test.dart b/pkg/analyzer/test/src/dart/resolution/library_element_test.dart
index 3df95f6..1b4e874 100644
--- a/pkg/analyzer/test/src/dart/resolution/library_element_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/library_element_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:meta/meta.dart';
import 'package:pub_semver/pub_semver.dart';
@@ -12,111 +13,284 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(LibraryElementTest);
+ defineReflectiveTests(LibraryElementTest_featureSet);
+ defineReflectiveTests(LibraryElementTest_scope);
});
}
@reflectiveTest
-class LibraryElementTest extends PubPackageResolutionTest {
- test_languageVersion() async {
- newFile('$testPackageRootPath/.dart_tool/package_config.json', content: '''
-{
- "configVersion": 2,
- "packages": [
- {
- "name": "test",
- "rootUri": "../",
- "packageUri": "lib/",
- "languageVersion": "2.7"
- },
- {
- "name": "aaa",
- "rootUri": "${toUriStr('/aaa')}",
- "packageUri": "lib/"
- }
- ]
-}
-''');
+class LibraryElementTest_featureSet extends PubPackageResolutionTest {
+ test_language205() async {
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ languageVersion: '2.5',
+ );
- newFile('$testPackageLibPath/a.dart', content: r'''
-class A {}
-''');
+ await resolveTestCode('');
- newFile('$testPackageLibPath/b.dart', content: r'''
-// @dart = 2.6
-class A {}
-''');
-
- newFile('$testPackageLibPath/c.dart', content: r'''
-// @dart = 2.9
-class A {}
-''');
-
- newFile('$testPackageLibPath/d.dart', content: r'''
-// @dart = 2.99
-class A {}
-''');
-
- newFile('$testPackageLibPath/e.dart', content: r'''
-// @dart = 3.0
-class A {}
-''');
-
- newFile('$workspaceRootPath/aaa/lib/a.dart', content: r'''
-class A {}
-''');
-
- newFile('$workspaceRootPath/aaa/lib/b.dart', content: r'''
-// @dart = 2.99
-class A {}
-''');
-
- newFile('$workspaceRootPath/aaa/lib/c.dart', content: r'''
-// @dart = 3.0
-class A {}
-''');
-
- // No override.
- await _assertLanguageVersion(
- path: '$testPackageLibPath/a.dart',
- package: Version.parse('2.7.0'),
+ _assertLanguageVersion(
+ package: Version.parse('2.5.0'),
override: null,
);
- // Valid override, less than the latest supported language version.
- await _assertLanguageVersion(
- path: '$testPackageLibPath/b.dart',
- package: Version.parse('2.7.0'),
- override: Version.parse('2.6.0'),
+ _assertFeatureSet([
+ Feature.constant_update_2018,
+ Feature.control_flow_collections,
+ Feature.set_literals,
+ Feature.spread_collections,
+ ]);
+ }
+
+ test_language208() async {
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ languageVersion: '2.8',
);
+ await resolveTestCode('');
+
+ _assertLanguageVersion(
+ package: Version.parse('2.8.0'),
+ override: null,
+ );
+
+ _assertFeatureSet([
+ Feature.constant_update_2018,
+ Feature.control_flow_collections,
+ Feature.extension_methods,
+ Feature.set_literals,
+ Feature.spread_collections,
+ ]);
+ }
+
+ test_language208_experimentNonNullable() async {
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ languageVersion: '2.8',
+ );
+
+ writeTestPackageAnalysisOptionsFile(
+ AnalysisOptionsFileConfig(experiments: [
+ EnableString.non_nullable,
+ ]),
+ );
+
+ await resolveTestCode('');
+
+ _assertLanguageVersion(
+ package: Version.parse('2.8.0'),
+ override: null,
+ );
+
+ _assertFeatureSet([
+ Feature.constant_update_2018,
+ Feature.control_flow_collections,
+ Feature.extension_methods,
+ Feature.set_literals,
+ Feature.spread_collections,
+ ]);
+ }
+
+ test_language208_override205() async {
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ languageVersion: '2.8',
+ );
+
+ await resolveTestCode('// @dart = 2.5');
+
+ // Valid override, less than the latest supported language version.
+ _assertLanguageVersion(
+ package: Version.parse('2.8.0'),
+ override: Version.parse('2.5.0'),
+ );
+
+ _assertFeatureSet([
+ Feature.constant_update_2018,
+ Feature.control_flow_collections,
+ Feature.set_literals,
+ Feature.spread_collections,
+ ]);
+ }
+
+ test_language209() async {
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ languageVersion: '2.9',
+ );
+
+ await resolveTestCode('');
+
+ _assertLanguageVersion(
+ package: Version.parse('2.9.0'),
+ override: null,
+ );
+
+ _assertFeatureSet([
+ Feature.constant_update_2018,
+ Feature.control_flow_collections,
+ Feature.extension_methods,
+ Feature.set_literals,
+ Feature.spread_collections,
+ ]);
+ }
+
+ test_language209_experimentNonNullable_override210() async {
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ languageVersion: '2.9',
+ );
+
+ writeTestPackageAnalysisOptionsFile(
+ AnalysisOptionsFileConfig(experiments: [
+ EnableString.non_nullable,
+ ]),
+ );
+
+ await resolveTestCode('// @dart = 2.10');
+
// Valid override, even if greater than the package language version.
- await _assertLanguageVersion(
- path: '$testPackageLibPath/c.dart',
- package: Version.parse('2.7.0'),
+ _assertLanguageVersion(
+ package: Version.parse('2.9.0'),
+ override: Version.parse('2.10.0'),
+ );
+
+ _assertFeatureSet([
+ Feature.constant_update_2018,
+ Feature.control_flow_collections,
+ Feature.extension_methods,
+ Feature.non_nullable,
+ Feature.set_literals,
+ Feature.spread_collections,
+ ]);
+ }
+
+ test_language209_override299() async {
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ languageVersion: '2.9',
+ );
+
+ await resolveTestCode('// @dart = 2.99');
+
+ // Invalid override: minor is greater than the latest minor.
+ _assertLanguageVersion(
+ package: Version.parse('2.9.0'),
+ override: null,
+ );
+
+ _assertFeatureSet([
+ Feature.constant_update_2018,
+ Feature.control_flow_collections,
+ Feature.extension_methods,
+ Feature.set_literals,
+ Feature.spread_collections,
+ ]);
+ }
+
+ test_language209_override300() async {
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ languageVersion: '2.9',
+ );
+
+ await resolveTestCode('// @dart = 3.00');
+
+ // Invalid override: major is greater than the latest major.
+ _assertLanguageVersion(
+ package: Version.parse('2.9.0'),
+ override: null,
+ );
+
+ _assertFeatureSet([
+ Feature.constant_update_2018,
+ Feature.control_flow_collections,
+ Feature.extension_methods,
+ Feature.set_literals,
+ Feature.spread_collections,
+ ]);
+ }
+
+ test_language210_experimentNonNullable() async {
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ languageVersion: '2.10',
+ );
+
+ writeTestPackageAnalysisOptionsFile(
+ AnalysisOptionsFileConfig(experiments: [
+ EnableString.non_nullable,
+ ]),
+ );
+
+ await resolveTestCode('');
+
+ _assertLanguageVersion(
+ package: Version.parse('2.10.0'),
+ override: null,
+ );
+
+ _assertFeatureSet([
+ Feature.constant_update_2018,
+ Feature.control_flow_collections,
+ Feature.extension_methods,
+ Feature.non_nullable,
+ Feature.set_literals,
+ Feature.spread_collections,
+ ]);
+ }
+
+ test_language210_experimentNonNullable_override209() async {
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ languageVersion: '2.10',
+ );
+
+ writeTestPackageAnalysisOptionsFile(
+ AnalysisOptionsFileConfig(experiments: [
+ EnableString.non_nullable,
+ ]),
+ );
+
+ await resolveTestCode('// @dart = 2.9');
+
+ _assertLanguageVersion(
+ package: Version.parse('2.10.0'),
override: Version.parse('2.9.0'),
);
- // Invalid override: minor is greater than the latest minor.
- await _assertLanguageVersion(
- path: '$testPackageLibPath/d.dart',
- package: Version.parse('2.7.0'),
- override: null,
- );
-
- // Invalid override: major is greater than the latest major.
- await _assertLanguageVersion(
- path: '$testPackageLibPath/e.dart',
- package: Version.parse('2.7.0'),
- override: null,
- );
-
- await _assertLanguageVersionCurrent('$workspaceRootPath/aaa/lib/a.dart');
- await _assertLanguageVersionCurrent('$workspaceRootPath/aaa/lib/b.dart');
- await _assertLanguageVersionCurrent('$workspaceRootPath/aaa/lib/c.dart');
+ _assertFeatureSet([
+ Feature.constant_update_2018,
+ Feature.control_flow_collections,
+ Feature.extension_methods,
+ Feature.set_literals,
+ Feature.spread_collections,
+ ]);
}
- test_scope_lookup2() async {
+ void _assertFeatureSet(List<Feature> expected) {
+ var featureSet = result.libraryElement.featureSet;
+
+ var actual = ExperimentStatus.knownFeatures.values
+ .where(featureSet.isEnabled)
+ .toSet();
+
+ expect(actual, unorderedEquals(expected));
+ }
+
+ void _assertLanguageVersion({
+ @required Version package,
+ @required Version override,
+ }) async {
+ var element = result.libraryElement;
+ expect(element.languageVersion.package, package);
+ expect(element.languageVersion.override, override);
+ }
+}
+
+@reflectiveTest
+class LibraryElementTest_scope extends PubPackageResolutionTest {
+ test_lookup2() async {
await assertNoErrorsInCode(r'''
int foo;
''');
@@ -133,7 +307,7 @@
);
}
- test_scope_lookup2_implicitCoreImport() async {
+ test_lookup2_implicitCoreImport() async {
await assertNoErrorsInCode('');
var scope = result.libraryElement.scope;
@@ -144,7 +318,7 @@
);
}
- test_scope_lookup2_notFound() async {
+ test_lookup2_notFound() async {
await assertNoErrorsInCode('');
var scope = result.libraryElement.scope;
@@ -158,7 +332,7 @@
);
}
- test_scope_lookup2_prefersLocal() async {
+ test_lookup2_prefersLocal() async {
await assertNoErrorsInCode(r'''
// ignore:unused_import
import 'dart:math';
@@ -179,7 +353,7 @@
);
}
- test_scope_lookup2_prefix() async {
+ test_lookup2_prefix() async {
await assertNoErrorsInCode(r'''
// ignore:unused_import
import 'dart:math' as math;
@@ -193,7 +367,7 @@
);
}
- test_scope_lookup2_respectsCombinator_hide() async {
+ test_lookup2_respectsCombinator_hide() async {
await assertNoErrorsInCode(r'''
// ignore:unused_import
import 'dart:math' hide sin;
@@ -216,7 +390,7 @@
);
}
- test_scope_lookup2_respectsCombinator_show() async {
+ test_lookup2_respectsCombinator_show() async {
await assertNoErrorsInCode(r'''
// ignore:unused_import
import 'dart:math' show sin;
@@ -234,7 +408,7 @@
);
}
- test_scope_lookup_implicitCoreImport() async {
+ test_lookup_implicitCoreImport() async {
await assertNoErrorsInCode('');
var scope = result.libraryElement.scope;
@@ -246,7 +420,7 @@
);
}
- test_scope_lookup_lookup() async {
+ test_lookup_lookup() async {
await assertNoErrorsInCode(r'''
int foo;
''');
@@ -265,7 +439,7 @@
);
}
- test_scope_lookup_notFound() async {
+ test_lookup_notFound() async {
await assertNoErrorsInCode('');
var scope = result.libraryElement.scope;
@@ -281,7 +455,7 @@
);
}
- test_scope_lookup_prefersLocal() async {
+ test_lookup_prefersLocal() async {
await assertNoErrorsInCode(r'''
// ignore:unused_import
import 'dart:math';
@@ -304,7 +478,7 @@
);
}
- test_scope_lookup_prefix() async {
+ test_lookup_prefix() async {
await assertNoErrorsInCode(r'''
// ignore:unused_import
import 'dart:math' as math;
@@ -319,7 +493,7 @@
);
}
- test_scope_lookup_respectsCombinator_hide() async {
+ test_lookup_respectsCombinator_hide() async {
await assertNoErrorsInCode(r'''
// ignore:unused_import
import 'dart:math' hide sin;
@@ -345,7 +519,7 @@
);
}
- test_scope_lookup_respectsCombinator_show() async {
+ test_lookup_respectsCombinator_show() async {
await assertNoErrorsInCode(r'''
// ignore:unused_import
import 'dart:math' show sin;
@@ -364,25 +538,4 @@
scope.lookup(id: 'cos', setter: false),
);
}
-
- Future<void> _assertLanguageVersion({
- @required String path,
- @required Version package,
- @required Version override,
- }) async {
- path = convertPath(path);
- var session = contextFor(path).currentSession;
- var file = session.getFile(path);
- var element = await session.getLibraryByUri('${file.uri}');
- expect(element.languageVersion.package, package);
- expect(element.languageVersion.override, override);
- }
-
- Future<void> _assertLanguageVersionCurrent(String path) async {
- await _assertLanguageVersion(
- path: path,
- package: ExperimentStatus.currentVersion,
- override: null,
- );
- }
}
diff --git a/pkg/analyzer/test/src/diagnostics/external_field_constructor_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/external_field_constructor_initializer_test.dart
new file mode 100644
index 0000000..f4939b0
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/external_field_constructor_initializer_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExternalFieldConstructorInitializerTest);
+ });
+}
+
+@reflectiveTest
+class ExternalFieldConstructorInitializerTest extends PubPackageResolutionTest
+ with WithNullSafetyMixin {
+ test_external_field_constructor_initializer() async {
+ await assertErrorsInCode('''
+class A {
+ external int x;
+ A() : x = 0;
+}
+''', [
+ error(CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, 36, 1),
+ ]);
+ }
+
+ test_external_field_final_constructor_initializer() async {
+ await assertErrorsInCode('''
+class A {
+ external final int x;
+ A() : x = 0;
+}
+''', [
+ error(CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, 42, 1),
+ ]);
+ }
+
+ test_external_field_final_initializing_formal() async {
+ await assertErrorsInCode('''
+class A {
+ external final int x;
+ A(this.x);
+}
+''', [
+ error(CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, 43, 1),
+ ]);
+ }
+
+ test_external_field_final_no_initialization() async {
+ await assertNoErrorsInCode('''
+class A {
+ external final int x;
+ A();
+}
+''');
+ }
+
+ test_external_field_initializing_formal() async {
+ await assertErrorsInCode('''
+class A {
+ external int x;
+ A(this.x);
+}
+''', [
+ error(CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, 37, 1),
+ ]);
+ }
+
+ test_external_field_no_initialization() async {
+ await assertNoErrorsInCode('''
+class A {
+ external int x;
+ A();
+}
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/external_field_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/external_field_initializer_test.dart
new file mode 100644
index 0000000..caa8ed8
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/external_field_initializer_test.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExternalFieldInitializerTest);
+ });
+}
+
+@reflectiveTest
+class ExternalFieldInitializerTest extends PubPackageResolutionTest
+ with WithNullSafetyMixin {
+ test_external_field_final_initializer() async {
+ await assertErrorsInCode('''
+class A {
+ external final int x = 0;
+}
+''', [
+ error(CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, 31, 1),
+ ]);
+ }
+
+ test_external_field_final_no_initializer() async {
+ await assertNoErrorsInCode('''
+class A {
+ external final int x;
+}
+''');
+ }
+
+ test_external_field_initializer() async {
+ await assertErrorsInCode('''
+class A {
+ external int x = 0;
+}
+''', [
+ error(CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, 25, 1),
+ ]);
+ }
+
+ test_external_field_no_initializer() async {
+ await assertNoErrorsInCode('''
+class A {
+ external int x;
+}
+''');
+ }
+
+ test_external_static_field_final_initializer() async {
+ await assertErrorsInCode('''
+class A {
+ external static final int x = 0;
+}
+''', [
+ error(CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, 38, 1),
+ ]);
+ }
+
+ test_external_static_field_final_no_initializer() async {
+ await assertNoErrorsInCode('''
+class A {
+ external static final int x;
+}
+''');
+ }
+
+ test_external_static_field_initializer() async {
+ await assertErrorsInCode('''
+class A {
+ external static int x = 0;
+}
+''', [
+ error(CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, 32, 1),
+ ]);
+ }
+
+ test_external_static_field_no_initializer() async {
+ await assertNoErrorsInCode('''
+class A {
+ external static int x;
+}
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/external_variable_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/external_variable_initializer_test.dart
new file mode 100644
index 0000000..54345c8
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/external_variable_initializer_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExternalVariableInitializerTest);
+ });
+}
+
+@reflectiveTest
+class ExternalVariableInitializerTest extends PubPackageResolutionTest
+ with WithNullSafetyMixin {
+ test_external_variable_final_initializer() async {
+ await assertErrorsInCode('''
+external final int x = 0;
+''', [
+ error(CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, 19, 1),
+ ]);
+ }
+
+ test_external_variable_final_no_initializer() async {
+ await assertNoErrorsInCode('''
+external final int x;
+''');
+ }
+
+ test_external_variable_initializer() async {
+ await assertErrorsInCode('''
+external int x = 0;
+''', [
+ error(CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, 13, 1),
+ ]);
+ }
+
+ test_external_variable_no_initializer() async {
+ await assertNoErrorsInCode('''
+external int x;
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 5a35fa8..cbaddcb 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -169,6 +169,11 @@
as extension_override_with_cascade;
import 'extension_override_without_access_test.dart'
as extension_override_without_access;
+import 'external_field_constructor_initializer_test.dart'
+ as external_field_constructor_initializer;
+import 'external_field_initializer_test.dart' as external_field_initializer;
+import 'external_variable_initializer_test.dart'
+ as external_variable_initializer;
import 'extra_annotation_on_struct_field_test.dart'
as extra_annotation_on_struct_field;
import 'extra_positional_arguments_test.dart' as extra_positional_arguments;
@@ -745,6 +750,9 @@
extension_override_argument_not_assignable.main();
extension_override_with_cascade.main();
extension_override_without_access.main();
+ external_field_constructor_initializer.main();
+ external_field_initializer.main();
+ external_variable_initializer.main();
extra_annotation_on_struct_field.main();
extra_positional_arguments.main();
field_in_struct_with_initializer.main();
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index affbc2f..04ff108 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -261,7 +261,6 @@
ExternalFactoryWithBody/script1: Fail
ExternalFieldConstructorInitializer/analyzerCode: Fail
ExternalFieldInitializer/analyzerCode: Fail
-ExternalLateField/analyzerCode: Fail
ExtraneousModifier/part_wrapped_script1: Fail
ExtraneousModifier/part_wrapped_script10: Fail
ExtraneousModifier/part_wrapped_script11: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 084b7c1..d41b3ac 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -805,7 +805,9 @@
- "abstract class C {external var f; C() : this.f = 0;}"
ExternalLateField:
+ index: 109
template: "External fields cannot be late."
+ analyzerCode: ParserErrorCode.EXTERNAL_LATE_FIELD
tip: "Try removing the 'external' or 'late' keyword."
configuration: nnbd-strong
script:
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 92bc408..8b3cc81 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -5528,7 +5528,6 @@
DECLARE_INSTRUCTION(LoadIndexed)
virtual CompileType ComputeType() const;
- virtual bool RecomputeType();
virtual Representation RequiredInputRepresentation(intptr_t idx) const {
ASSERT(idx == 0 || idx == 1);
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index ba9529b..f3fcd25 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1701,61 +1701,6 @@
return CompileType::FromCid(definition_cid_);
}
-static AbstractTypePtr ExtractElementTypeFromArrayType(
- const AbstractType& array_type) {
- if (array_type.IsTypeParameter()) {
- return ExtractElementTypeFromArrayType(
- AbstractType::Handle(TypeParameter::Cast(array_type).bound()));
- }
- if (!array_type.IsType()) {
- return Object::dynamic_type().raw();
- }
- const intptr_t cid = array_type.type_class_id();
- if (cid == kGrowableObjectArrayCid || cid == kArrayCid ||
- cid == kImmutableArrayCid ||
- array_type.type_class() ==
- Isolate::Current()->object_store()->list_class()) {
- const auto& type_args = TypeArguments::Handle(array_type.arguments());
- return type_args.TypeAtNullSafe(Array::kElementTypeTypeArgPos);
- }
- return Object::dynamic_type().raw();
-}
-
-static AbstractTypePtr GetElementTypeFromArray(Value* array) {
- return ExtractElementTypeFromArrayType(*(array->Type()->ToAbstractType()));
-}
-
-static CompileType ComputeArrayElementType(Value* array) {
- // 1. Try to extract element type from array value.
- auto& elem_type = AbstractType::Handle(GetElementTypeFromArray(array));
- if (!elem_type.IsDynamicType()) {
- return CompileType::FromAbstractType(elem_type);
- }
-
- // 2. Array value may be loaded from GrowableObjectArray.data.
- // Unwrap and try again.
- if (auto* load_field = array->definition()->AsLoadField()) {
- if (load_field->slot().IsIdentical(Slot::GrowableObjectArray_data())) {
- array = load_field->instance();
- elem_type = GetElementTypeFromArray(array);
- if (!elem_type.IsDynamicType()) {
- return CompileType::FromAbstractType(elem_type);
- }
- }
- }
-
- // 3. If array was loaded from a Dart field, use field's static type.
- // Unlike propagated type (which could be cid), static type may contain
- // type arguments which can be used to figure out element type.
- if (auto* load_field = array->definition()->AsLoadField()) {
- if (load_field->slot().IsDartField()) {
- elem_type =
- ExtractElementTypeFromArrayType(load_field->slot().static_type());
- }
- }
- return CompileType::FromAbstractType(elem_type);
-}
-
CompileType LoadIndexedInstr::ComputeType() const {
switch (class_id_) {
case kArrayCid:
@@ -1764,7 +1709,7 @@
// The original call knew something.
return *result_type_;
}
- return ComputeArrayElementType(array());
+ return CompileType::Dynamic();
case kTypedDataFloat32ArrayCid:
case kTypedDataFloat64ArrayCid:
@@ -1806,13 +1751,4 @@
}
}
-bool LoadIndexedInstr::RecomputeType() {
- if ((class_id_ == kArrayCid) || (class_id_ == kImmutableArrayCid)) {
- // Array element type computation depends on computed
- // types of other instructions and may change over time.
- return UpdateType(ComputeType());
- }
- return false;
-}
-
} // namespace dart
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 2be3ae6..cc26637 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -9567,9 +9567,6 @@
bool IsImmutable() const { return raw()->GetClassId() == kImmutableArrayCid; }
- // Position of element type in type arguments.
- static const intptr_t kElementTypeTypeArgPos = 0;
-
virtual TypeArgumentsPtr GetTypeArguments() const {
return raw_ptr()->type_arguments_;
}
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 26a5c3a..9683d81 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -335,15 +335,13 @@
}
void ObjectStore::LazyInitCoreTypes() {
- if (list_class_ == Type::null()) {
- ASSERT(non_nullable_list_rare_type_ == Type::null());
+ if (non_nullable_list_rare_type_ == Type::null()) {
ASSERT(non_nullable_map_rare_type_ == Type::null());
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
Class& cls = Class::Handle(zone, core_lib.LookupClass(Symbols::List()));
ASSERT(!cls.IsNull());
- set_list_class(cls);
Type& type = Type::Handle(zone);
type ^= cls.RareType();
set_non_nullable_list_rare_type(type);
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 169161f..7f3c93e 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -82,7 +82,6 @@
RW(Type, string_type) \
RW(Type, legacy_string_type) \
RW(Type, non_nullable_string_type) \
- CW(Class, list_class) /* maybe be null, lazily built */ \
CW(Type, non_nullable_list_rare_type) /* maybe be null, lazily built */ \
CW(Type, non_nullable_map_rare_type) /* maybe be null, lazily built */ \
FW(Type, non_nullable_future_rare_type) /* maybe be null, lazily built */ \
diff --git a/tools/VERSION b/tools/VERSION
index cf7150f..10ca838 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 10
PATCH 0
-PRERELEASE 20
+PRERELEASE 21
PRERELEASE_PATCH 0
\ No newline at end of file