Version 2.14.0-51.0.dev
Merge commit '3a0a196fed31cf8c03027ef8f56035a0e2532426' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 95c301c..8365209 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -54,6 +54,44 @@
as an unsigned integer, so `a >>> b` gives the same result as
`a.toUnsigned(32) >>> b` on the VM.
+* Prior to Dart 2.14, metadata (annotations) were not permitted to be
+ specified with generic type arguments. This restriction is lifted in Dart
+ Dart 2.14.
+
+ ```dart
+ class C<T> {
+ const C();
+ }
+ @C(); // Previously permitted.
+ @C<int>(); // Previously an error, now permitted.
+ ```
+
+* Prior to Dart 2.14, generic function types were not permitted as arguments
+ to generic classes or functions, nor to be used as generic bounds. This
+ restriction is lifted in Dart 2.14.
+
+ ```dart
+ T wrapWithLogging<T>(T f) {
+ if (f is void Function<T>(T x)) {
+ return <S>(S x) {
+ print("Call: f<$S>($x)");
+ var r = f<S>(x);
+ print("Return: $x");
+ return r;
+ } as T;
+ } // More cases here
+ return f;
+ }
+ void foo<T>(T x) {
+ print("Foo!");
+ }
+ void main() {
+ // Previously an error, now permitted.
+ var f = wrapWithLogging<void Function<T>(T)>(foo);
+ f<int>(3);
+ }
+ ```
+
## 2.13.0
### Language
diff --git a/pkg/BUILD.gn b/pkg/BUILD.gn
index 173b32f..49581b5 100644
--- a/pkg/BUILD.gn
+++ b/pkg/BUILD.gn
@@ -2,61 +2,6 @@
# 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("../utils/create_timestamp.gni")
-
-template("make_third_party_pkg_files_stamp") {
- assert(defined(invoker.id), "Must define the stamp file id")
- path = rebase_path("../third_party/pkg")
- if (defined(invoker.path)) {
- path = invoker.path
- }
- id = invoker.id
- create_timestamp_file(target_name) {
- if (defined(invoker.pattern)) {
- pattern = invoker.pattern
- }
- path = path
- output = "$target_gen_dir/third_party_pkg_files_$id.stamp"
- }
-}
-
-make_third_party_pkg_files_stamp("make_third_party_pkg_files_0_stamp") {
- path = rebase_path(".")
- id = "0"
-}
-
-make_third_party_pkg_files_stamp("make_third_party_pkg_files_1_stamp") {
- pattern = "[a-k].*"
- id = "1"
-}
-
-make_third_party_pkg_files_stamp("make_third_party_pkg_files_2_stamp") {
- pattern = "[l-r].*"
- id = "2"
-}
-
-make_third_party_pkg_files_stamp("make_third_party_pkg_files_3_stamp") {
- pattern = "[s-z].*"
- id = "3"
-}
-
-action("pkg_files_stamp") {
- deps = [
- ":make_third_party_pkg_files_0_stamp",
- ":make_third_party_pkg_files_1_stamp",
- ":make_third_party_pkg_files_2_stamp",
- ":make_third_party_pkg_files_3_stamp",
- ]
-
- stamp0_outputs = get_target_outputs(":make_third_party_pkg_files_0_stamp")
- stamp1_outputs = get_target_outputs(":make_third_party_pkg_files_1_stamp")
- stamp2_outputs = get_target_outputs(":make_third_party_pkg_files_2_stamp")
- stamp3_outputs = get_target_outputs(":make_third_party_pkg_files_3_stamp")
-
- inputs = stamp0_outputs + stamp1_outputs + stamp2_outputs + stamp3_outputs
-
- outputs = [ "$root_gen_dir/pkg_files.stamp" ]
-
- script = "../tools/create_timestamp_file.py"
- args = [ rebase_path("$root_gen_dir/pkg_files.stamp") ]
+# TODO(flutter): Remove use.
+group("pkg_files_stamp") {
}
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index 25d3548..5e3a9c5 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -9,13 +9,17 @@
import 'package:path/path.dart' as path;
/// Return a protocol [Element] corresponding to the given [engine.Element].
-Element convertElement(engine.Element element) {
+Element convertElement(engine.Element element,
+ {required bool withNullability}) {
var kind = convertElementToElementKind(element);
var name = getElementDisplayName(element);
var elementTypeParameters = _getTypeParametersString(element);
- var aliasedType = getAliasedTypeString(element);
- var elementParameters = _getParametersString(element);
- var elementReturnType = getReturnTypeString(element);
+ var aliasedType =
+ getAliasedTypeString(element, withNullability: withNullability);
+ var elementParameters =
+ _getParametersString(element, withNullability: withNullability);
+ var elementReturnType =
+ getReturnTypeString(element, withNullability: withNullability);
return Element(
kind,
name,
@@ -128,7 +132,8 @@
}
}
-String? _getParametersString(engine.Element element) {
+String? _getParametersString(engine.Element element,
+ {required bool withNullability}) {
// TODO(scheglov) expose the corresponding feature from ExecutableElement
List<engine.ParameterElement> parameters;
if (element is engine.ExecutableElement) {
@@ -171,7 +176,7 @@
} else if (parameter.hasRequired) {
sb.write('@required ');
}
- parameter.appendToWithoutDelimiters(sb, withNullability: false);
+ parameter.appendToWithoutDelimiters(sb, withNullability: withNullability);
}
sb.write(closeOptionalString);
return '(' + sb.toString() + ')';
diff --git a/pkg/analysis_server/lib/src/computer/computer_folding.dart b/pkg/analysis_server/lib/src/computer/computer_folding.dart
index ccfb4e3..4170ab6 100644
--- a/pkg/analysis_server/lib/src/computer/computer_folding.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_folding.dart
@@ -233,6 +233,14 @@
}
@override
+ void visitEnumDeclaration(EnumDeclaration node) {
+ _computer._addRegionForAnnotations(node.metadata);
+ _computer._addRegion(
+ node.leftBracket.end, node.rightBracket.offset, FoldingKind.CLASS_BODY);
+ super.visitEnumDeclaration(node);
+ }
+
+ @override
void visitExportDirective(ExportDirective node) {
_computer._recordDirective(node);
super.visitExportDirective(node);
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index ab3ef83..f40542f 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -5,6 +5,7 @@
import 'package:analysis_server/protocol/protocol_generated.dart'
show HoverInformation;
import 'package:analysis_server/src/computer/computer_overrides.dart';
+import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
@@ -22,10 +23,6 @@
DartUnitHoverComputer(this._dartdocInfo, this._unit, this._offset);
- bool get _isNonNullableByDefault {
- return _unit.declaredElement?.library.isNonNullableByDefault ?? false;
- }
-
/// Returns the computed hover, maybe `null`.
HoverInformation? compute() {
var node = NodeLocator(_offset).searchWithin(_unit);
@@ -135,12 +132,13 @@
String? _elementDisplayString(Element? element) {
return element?.getDisplayString(
- withNullability: _isNonNullableByDefault,
+ withNullability: _unit.isNonNullableByDefault,
);
}
String? _typeDisplayString(DartType? type) {
- return type?.getDisplayString(withNullability: _isNonNullableByDefault);
+ return type?.getDisplayString(
+ withNullability: _unit.isNonNullableByDefault);
}
static String? computeDocumentation(
diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
index b3e7bc3..8bf505e 100644
--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
@@ -4,6 +4,7 @@
import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/protocol_server.dart' as proto;
+import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -57,10 +58,12 @@
var interfaceElements = overridesResult.interfaceElements;
if (superElements.isNotEmpty || interfaceElements.isNotEmpty) {
var superMember = superElements.isNotEmpty
- ? proto.newOverriddenMember_fromEngine(superElements.first)
+ ? proto.newOverriddenMember_fromEngine(superElements.first,
+ withNullability: _unit.isNonNullableByDefault)
: null;
var interfaceMembers = interfaceElements
- .map((member) => proto.newOverriddenMember_fromEngine(member))
+ .map((member) => proto.newOverriddenMember_fromEngine(member,
+ withNullability: _unit.isNonNullableByDefault))
.toList();
_overrides.add(proto.Override(node.offset, node.length,
superclassMember: superMember,
diff --git a/pkg/analysis_server/lib/src/computer/computer_signature.dart b/pkg/analysis_server/lib/src/computer/computer_signature.dart
index 10354b5..9eb563a 100644
--- a/pkg/analysis_server/lib/src/computer/computer_signature.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_signature.dart
@@ -4,6 +4,7 @@
import 'package:analysis_server/src/computer/computer_hover.dart';
import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/element_locator.dart';
@@ -16,9 +17,11 @@
final DartdocDirectiveInfo _dartdocInfo;
final AstNode? _node;
late ArgumentList _argumentList;
+ final bool _isNonNullableByDefault;
DartUnitSignatureComputer(
this._dartdocInfo, CompilationUnit _unit, int _offset)
- : _node = NodeLocator(_offset).searchWithin(_unit);
+ : _node = NodeLocator(_offset).searchWithin(_unit),
+ _isNonNullableByDefault = _unit.isNonNullableByDefault;
/// The [ArgumentList] node located by [compute].
ArgumentList get argumentList => _argumentList;
@@ -72,7 +75,7 @@
? ParameterKind.REQUIRED_NAMED
: ParameterKind.REQUIRED_POSITIONAL,
param.displayName,
- param.type.getDisplayString(withNullability: false),
+ param.type.getDisplayString(withNullability: _isNonNullableByDefault),
defaultValue: param.defaultValueCode);
}
diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
index 353bbc8..d11c738 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
@@ -4,6 +4,7 @@
import 'package:analysis_server/plugin/analysis/occurrences/occurrences_core.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -15,7 +16,8 @@
unit.accept(visitor);
visitor.elementsOffsets.forEach((engineElement, offsets) {
var length = engineElement.nameLength;
- var serverElement = protocol.convertElement(engineElement);
+ var serverElement = protocol.convertElement(engineElement,
+ withNullability: unit.isNonNullableByDefault);
var occurrences = protocol.Occurrences(serverElement, offsets, length);
collector.addOccurrences(occurrences);
});
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
index 99357b7..5a8d94b 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/perform_refactor.dart
@@ -159,6 +159,11 @@
(options != null ? options['name'] : null) ?? 'NewWidget';
return success(refactor);
+ case RefactoringKind.INLINE_LOCAL_VARIABLE:
+ final refactor =
+ InlineLocalRefactoring(server.searchEngine, result, offset);
+ return success(refactor);
+
default:
return error(ServerErrorCodes.InvalidCommandArguments,
'Unknown RefactoringKind $kind was supplied to $commandName');
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 5bbfefc..2d786af 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
@@ -409,6 +409,15 @@
}
}
+ if (shouldIncludeKind(CodeActionKind.RefactorInline)) {
+ // Inline Local Variable
+ if (InlineLocalRefactoring(server.searchEngine, unit, offset)
+ .isAvailable()) {
+ refactorActions.add(createRefactor(CodeActionKind.RefactorInline,
+ 'Inline Local Variable', RefactoringKind.INLINE_LOCAL_VARIABLE));
+ }
+ }
+
return refactorActions;
} on InconsistentAnalysisException {
// If an InconsistentAnalysisException occurs, it's likely the user modified
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index 3725220..cf29def 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -215,10 +215,10 @@
server.getDartdocDirectiveInfoFor(completionRequest.result);
final dartCompletionRequest = await DartCompletionRequestImpl.from(
perf, completionRequest, directiveInfo);
+ final target = dartCompletionRequest.target;
if (triggerCharacter != null) {
- if (!_triggerCharacterValid(
- offset, triggerCharacter, dartCompletionRequest.target)) {
+ if (!_triggerCharacterValid(offset, triggerCharacter, target)) {
return success([]);
}
}
@@ -256,6 +256,13 @@
return cancelled();
}
+ /// completeFunctionCalls should be suppressed if the target is an
+ /// invocation that already has an argument list, otherwise we would
+ /// insert dupes.
+ final completeFunctionCalls = _hasExistingArgList(target.entity)
+ ? false
+ : server.clientConfiguration.completeFunctionCalls;
+
final results = serverSuggestions.map(
(item) {
var itemReplacementOffset =
@@ -286,8 +293,7 @@
// https://github.com/microsoft/vscode-languageserver-node/issues/673
includeCommitCharacters:
server.clientConfiguration.previewCommitCharacters,
- completeFunctionCalls:
- server.clientConfiguration.completeFunctionCalls,
+ completeFunctionCalls: completeFunctionCalls,
);
},
).toList();
@@ -386,8 +392,7 @@
// https://github.com/microsoft/vscode-languageserver-node/issues/673
includeCommitCharacters:
server.clientConfiguration.previewCommitCharacters,
- completeFunctionCalls:
- server.clientConfiguration.completeFunctionCalls,
+ completeFunctionCalls: completeFunctionCalls,
));
results.addAll(setResults);
});
@@ -453,6 +458,27 @@
return success(completionItems);
}
+ /// Returns true if [node] is part of an invocation and already has an argument
+ /// list.
+ bool _hasExistingArgList(Object? node) {
+ // print^('foo');
+ if (node is ast.ExpressionStatement) {
+ node = node.expression;
+ }
+ // super.foo^();
+ if (node is ast.SimpleIdentifier) {
+ node = node.parent;
+ }
+ // new Aaaa.bar^()
+ if (node is ast.ConstructorName) {
+ node = node.parent;
+ }
+ return (node is ast.InvocationExpression &&
+ node.argumentList.length != 0) ||
+ (node is ast.InstanceCreationExpression &&
+ node.argumentList.length != 0);
+ }
+
Iterable<CompletionItem> _pluginResultsToItems(
LspClientCapabilities capabilities,
LineInfo lineInfo,
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 2492df0..c03f74b 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -46,29 +46,32 @@
change.addEdit(file, isNewFile ? -1 : 0, edit);
}
-String? getAliasedTypeString(engine.Element element) {
+String? getAliasedTypeString(engine.Element element,
+ {required bool withNullability}) {
if (element is engine.TypeAliasElement) {
var aliasedType = element.aliasedType;
- return aliasedType.getDisplayString(withNullability: false);
+ return aliasedType.getDisplayString(withNullability: withNullability);
}
return null;
}
-String? getReturnTypeString(engine.Element element) {
+String? getReturnTypeString(engine.Element element,
+ {required bool withNullability}) {
if (element is engine.ExecutableElement) {
if (element.kind == engine.ElementKind.SETTER) {
return null;
} else {
- return element.returnType.getDisplayString(withNullability: false);
+ return element.returnType
+ .getDisplayString(withNullability: withNullability);
}
} else if (element is engine.VariableElement) {
var type = element.type;
- return type.getDisplayString(withNullability: false);
+ return type.getDisplayString(withNullability: withNullability);
} else if (element is engine.TypeAliasElement) {
var aliasedType = element.aliasedType;
if (aliasedType is FunctionType) {
var returnType = aliasedType.returnType;
- return returnType.getDisplayString(withNullability: false);
+ return returnType.getDisplayString(withNullability: withNullability);
}
}
return null;
@@ -209,8 +212,9 @@
}
/// Construct based on an element from the analyzer engine.
-OverriddenMember newOverriddenMember_fromEngine(engine.Element member) {
- var element = convertElement(member);
+OverriddenMember newOverriddenMember_fromEngine(engine.Element member,
+ {required bool withNullability}) {
+ var element = convertElement(member, withNullability: withNullability);
var className = member.enclosingElement!.displayName;
return OverriddenMember(element, className);
}
@@ -259,8 +263,9 @@
element = element.enclosingElement.definingCompilationUnit;
}
+ var withNullability = element.library?.isNonNullableByDefault ?? false;
for (var e in element.withAncestors) {
- path.add(convertElement(e));
+ path.add(convertElement(e, withNullability: withNullability));
}
return path;
}
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index 0ae754c..ac50553 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -46,7 +46,9 @@
var result = protocol.SearchFindElementReferencesResult();
if (element != null) {
result.id = searchId;
- result.element = protocol.convertElement(element);
+ var withNullability = element.library?.isNonNullableByDefault ?? false;
+ result.element =
+ protocol.convertElement(element, withNullability: withNullability);
}
_sendSearchResult(request, result);
// search elements
diff --git a/pkg/analysis_server/lib/src/search/type_hierarchy.dart b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
index 422be2e..d558487 100644
--- a/pkg/analysis_server/lib/src/search/type_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
@@ -45,6 +45,8 @@
}
}
+ bool get _isNonNullableByDefault => _pivotLibrary.isNonNullableByDefault;
+
/// Returns the computed type hierarchy, maybe `null`.
Future<List<TypeHierarchyItem>?> compute() async {
var pivotClass = _pivotClass;
@@ -80,9 +82,11 @@
}
// create a subclass item
var subMemberElement = _findMemberElement(subElement);
- subItem = TypeHierarchyItem(convertElement(subElement),
+ subItem = TypeHierarchyItem(
+ convertElement(subElement, withNullability: _isNonNullableByDefault),
memberElement: subMemberElement != null
- ? convertElement(subMemberElement)
+ ? convertElement(subMemberElement,
+ withNullability: _isNonNullableByDefault)
: null,
superclass: itemId);
var subItemId = _items.length;
@@ -116,15 +120,20 @@
String? displayName;
if (typeArguments != null && typeArguments.isNotEmpty) {
var typeArgumentsStr = typeArguments
- .map((type) => type.getDisplayString(withNullability: false))
+ .map((type) =>
+ type.getDisplayString(withNullability: _isNonNullableByDefault))
.join(', ');
displayName = classElement.displayName + '<' + typeArgumentsStr + '>';
}
var memberElement = _findMemberElement(classElement);
- item = TypeHierarchyItem(convertElement(classElement),
+ item = TypeHierarchyItem(
+ convertElement(classElement,
+ withNullability: _isNonNullableByDefault),
displayName: displayName,
- memberElement:
- memberElement != null ? convertElement(memberElement) : null);
+ memberElement: memberElement != null
+ ? convertElement(memberElement,
+ withNullability: _isNonNullableByDefault)
+ : null);
_elementItemMap[classElement] = item;
itemId = _items.length;
_items.add(item);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index d2ce0e3..a7062c3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -196,6 +196,9 @@
return _cachedContainingMemberName;
}
+ bool get _isNonNullableByDefault =>
+ request.libraryElement?.isNonNullableByDefault ?? false;
+
/// Add a suggestion for an [accessor] declared within a class or extension.
/// If the accessor is being invoked with a target of `super`, then the
/// [containingMemberName] should be the name of the member containing the
@@ -633,9 +636,8 @@
required bool appendComma,
int? replacementLength}) {
var name = parameter.name;
- var type = parameter.type.getDisplayString(
- withNullability:
- request.libraryElement?.isNonNullableByDefault ?? false);
+ var type = parameter.type
+ .getDisplayString(withNullability: _isNonNullableByDefault);
var completion = name;
if (appendColon) {
@@ -688,7 +690,8 @@
replacementLength: replacementLength);
if (parameter is FieldFormalParameterElement) {
_setDocumentation(suggestion, parameter);
- suggestion.element = convertElement(parameter);
+ suggestion.element =
+ convertElement(parameter, withNullability: _isNonNullableByDefault);
}
_add(suggestion);
}
@@ -747,7 +750,8 @@
element.hasDeprecated,
false,
displayText: displayText);
- suggestion.element = protocol.convertElement(element);
+ suggestion.element = protocol.convertElement(element,
+ withNullability: _isNonNullableByDefault);
_add(suggestion);
}
@@ -1016,9 +1020,8 @@
completion.length, 0, element.hasOrInheritsDeprecated, false);
_setDocumentation(suggestion, element);
-
- var suggestedElement =
- suggestion.element = protocol.convertElement(element);
+ var suggestedElement = suggestion.element = protocol.convertElement(element,
+ withNullability: _isNonNullableByDefault);
if (elementKind != null) {
suggestedElement.kind = elementKind;
}
@@ -1026,7 +1029,8 @@
if (enclosingElement is ClassElement) {
suggestion.declaringType = enclosingElement.displayName;
}
- suggestion.returnType = getReturnTypeString(element);
+ suggestion.returnType =
+ getReturnTypeString(element, withNullability: _isNonNullableByDefault);
if (element is ExecutableElement && element is! PropertyAccessorElement) {
suggestion.parameterNames = element.parameters
.map((ParameterElement parameter) => parameter.name)
@@ -1035,8 +1039,7 @@
element.parameters.map((ParameterElement parameter) {
var paramType = parameter.type;
return paramType.getDisplayString(
- withNullability:
- request.libraryElement?.isNonNullableByDefault ?? false);
+ withNullability: _isNonNullableByDefault);
}).toList();
var requiredParameters = element.parameters
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
index 12afe4d..c7577b6 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
@@ -164,6 +164,26 @@
return Future.value(change);
}
+ @override
+ bool isAvailable() {
+ return !_checkOffset().hasFatalError;
+ }
+
+ /// Checks if [offset] is a variable that can be inlined.
+ RefactoringStatus _checkOffset() {
+ var offsetNode = NodeLocator(offset).searchWithin(resolveResult.unit);
+ if (offsetNode is! SimpleIdentifier) {
+ return _noLocalVariableStatus();
+ }
+
+ var element = offsetNode.staticElement;
+ if (element is! LocalVariableElement) {
+ return _noLocalVariableStatus();
+ }
+
+ return RefactoringStatus();
+ }
+
RefactoringStatus _noLocalVariableStatus() {
return RefactoringStatus.fatal(
'Local variable declaration or reference must be selected '
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index 31e5302..23b8552 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -210,6 +210,10 @@
/// Returns the name of the variable being inlined.
String? get variableName;
+
+ /// Return `true` if refactoring is available, possibly without checking all
+ /// initial conditions.
+ bool isAvailable();
}
/// [Refactoring] to inline an [ExecutableElement].
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
index af573e9..97ab036 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
@@ -87,6 +87,14 @@
}
}
+extension CompilationUnitExtension on CompilationUnit {
+ /// Is `true` if library being analyzed is non-nullable by default.
+ ///
+ /// Will return false if the AST structure has not been resolved.
+ bool get isNonNullableByDefault =>
+ declaredElement?.library.isNonNullableByDefault ?? false;
+}
+
extension ExpressionExtensions on Expression {
/// Return `true` if this expression is an invocation of the method `cast`
/// from either Iterable`, `List`, `Map`, or `Set`.
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 07a3194..65eaa13 100644
--- a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
@@ -176,9 +176,8 @@
},
);
- final marker = positionFromMarker(content);
final codeActions = await getCodeActions(mainFileUri.toString(),
- range: Range(start: marker, end: marker));
+ position: positionFromMarker(content));
final assist = findEditAction(
codeActions,
CodeActionKind('refactor.flutter.wrap.generic'),
@@ -238,9 +237,8 @@
withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
);
- final marker = positionFromMarker(content);
final codeActions = await getCodeActions(mainFileUri.toString(),
- range: Range(start: marker, end: marker));
+ position: positionFromMarker(content));
final assist = findEditAction(
codeActions,
CodeActionKind('refactor.flutter.wrap.generic'),
diff --git a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
index 2a9e372..1d62c11 100644
--- a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
@@ -374,10 +374,8 @@
emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
);
- final caretPos = positionFromMarker(content);
-
final codeActions = await getCodeActions(mainFileUri.toString(),
- range: Range(start: caretPos, end: caretPos));
+ position: positionFromMarker(content));
final removeNnaAction = findEditActions(codeActions,
CodeActionKind('quickfix.remove.nonNullAssertion'), "Remove the '!'");
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index 3f8055f..8d87a88 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -18,6 +18,7 @@
defineReflectiveTests(ExtractMethodRefactorCodeActionsTest);
defineReflectiveTests(ExtractWidgetRefactorCodeActionsTest);
defineReflectiveTests(ExtractVariableRefactorCodeActionsTest);
+ defineReflectiveTests(InlineLocalVariableRefactorCodeActionsTest);
});
}
@@ -510,3 +511,37 @@
expect(codeAction, isNull);
}
}
+
+@reflectiveTest
+class InlineLocalVariableRefactorCodeActionsTest
+ extends AbstractCodeActionsTest {
+ final extractVariableTitle = 'Inline Local Variable';
+
+ Future<void> test_appliesCorrectEdits() async {
+ const content = '''
+void main() {
+ var a^ = 1;
+ print(a);
+ print(a);
+ print(a);
+}
+ ''';
+ const expectedContent = '''
+void main() {
+ print(1);
+ print(1);
+ print(1);
+}
+ ''';
+ newFile(mainFilePath, content: withoutMarkers(content));
+ await initialize();
+
+ final codeActions = await getCodeActions(mainFileUri.toString(),
+ position: positionFromMarker(content));
+ final codeAction = findCommand(
+ codeActions, Commands.performRefactor, extractVariableTitle)!;
+
+ await verifyCodeActionEdits(
+ codeAction, withoutMarkers(content), expectedContent);
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index d6ba22e..cb21761 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -24,6 +24,34 @@
@reflectiveTest
class CompletionTest extends AbstractLspAnalysisServerTest
with CompletionTestMixin {
+ Future<void> checkCompleteFunctionCallInsertText(
+ String content, String completion,
+ {required String insertText, InsertTextFormat? insertTextFormat}) async {
+ await provideConfig(
+ () => initialize(
+ textDocumentCapabilities: withCompletionItemSnippetSupport(
+ emptyTextDocumentClientCapabilities),
+ workspaceCapabilities:
+ withConfigurationSupport(emptyWorkspaceClientCapabilities),
+ ),
+ {'completeFunctionCalls': true},
+ );
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+ final item = res.singleWhere(
+ (c) => c.label == completion,
+ orElse: () =>
+ throw 'Did not find $completion in ${res.map((r) => r.label).toList()}',
+ );
+
+ expect(item.insertTextFormat, equals(insertTextFormat));
+ expect(item.insertText, equals(insertText));
+
+ final textEdit = toTextEdit(item.textEdit!);
+ expect(textEdit.newText, equals(item.insertText));
+ expect(textEdit.range, equals(rangeFromMarkers(content)));
+ }
+
void expectAutoImportCompletion(List<CompletionItem> items, String file) {
expect(
items.singleWhereOrNull(
@@ -138,35 +166,93 @@
expect(options.allCommitCharacters, equals(dartCompletionCommitCharacters));
}
- Future<void> test_completeFunctionCalls() async {
- final content = '''
- void myFunction(String a, int b, {String c}) {}
+ Future<void> test_completeFunctionCalls_constructor() =>
+ checkCompleteFunctionCallInsertText(
+ '''
+ class Aaaaa {
+ Aaaaa(int a);
+ }
+ void main(int aaa) {
+ var a = new [[Aaa^]]
+ }
+ ''',
+ 'Aaaaa(…)',
+ insertTextFormat: InsertTextFormat.Snippet,
+ insertText: r'Aaaaa(${0:a})',
+ );
- main() {
- [[myFu^]]
- }
- ''';
+ Future<void> test_completeFunctionCalls_existingArgList_constructor() =>
+ checkCompleteFunctionCallInsertText(
+ '''
+ class Aaaaa {
+ Aaaaa(int a);
+ }
+ void main(int aaa) {
+ var a = new [[Aaa^]]()
+ }
+ ''',
+ 'Aaaaa(…)',
+ insertText: 'Aaaaa',
+ );
- await provideConfig(
- () => initialize(
- textDocumentCapabilities: withCompletionItemSnippetSupport(
- emptyTextDocumentClientCapabilities),
- workspaceCapabilities:
- withConfigurationSupport(emptyWorkspaceClientCapabilities),
- ),
- {'completeFunctionCalls': true},
- );
- await openFile(mainFileUri, withoutMarkers(content));
- final res = await getCompletion(mainFileUri, positionFromMarker(content));
- final item = res.singleWhere((c) => c.label == 'myFunction(…)');
- // Ensure the snippet comes through in the expected format with the expected
- // placeholders.
- expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
- expect(item.insertText, equals(r'myFunction(${1:a}, ${2:b})'));
- final textEdit = toTextEdit(item.textEdit!);
- expect(textEdit.newText, equals(item.insertText));
- expect(textEdit.range, equals(rangeFromMarkers(content)));
- }
+ Future<void> test_completeFunctionCalls_existingArgList_expression() =>
+ checkCompleteFunctionCallInsertText(
+ '''
+ int myFunction(String a, int b, {String c}) {
+ var a = [[myFu^]]()
+ }
+ ''',
+ 'myFunction(…)',
+ insertText: 'myFunction',
+ );
+
+ Future<void> test_completeFunctionCalls_existingArgList_namedConstructor() =>
+ checkCompleteFunctionCallInsertText(
+ '''
+ class Aaaaa {
+ Aaaaa.foo(int a);
+ }
+ void main() {
+ var a = new Aaaaa.[[foo^]]()
+ }
+ ''',
+ 'foo(…)',
+ insertText: 'foo',
+ );
+
+ Future<void> test_completeFunctionCalls_existingArgList_statement() =>
+ checkCompleteFunctionCallInsertText(
+ '''
+ void main(int a) {
+ [[mai^]]()
+ }
+ ''',
+ 'main(…)',
+ insertText: 'main',
+ );
+
+ Future<void> test_completeFunctionCalls_existingArgList_suggestionSets() =>
+ checkCompleteFunctionCallInsertText(
+ '''
+ void main(int a) {
+ [[pri^]]()
+ }
+ ''',
+ 'print(…)',
+ insertText: 'print',
+ );
+
+ Future<void> test_completeFunctionCalls_expression() =>
+ checkCompleteFunctionCallInsertText(
+ '''
+ int myFunction(String a, int b, {String c}) {
+ var a = [[myFu^]]
+ }
+ ''',
+ 'myFunction(…)',
+ insertTextFormat: InsertTextFormat.Snippet,
+ insertText: r'myFunction(${1:a}, ${2:b})',
+ );
Future<void> test_completeFunctionCalls_flutterSetState() async {
// Flutter's setState method has special handling inside SuggestionBuilder
@@ -215,6 +301,21 @@
expect(textEdit.range, equals(rangeFromMarkers(content)));
}
+ Future<void> test_completeFunctionCalls_namedConstructor() =>
+ checkCompleteFunctionCallInsertText(
+ '''
+ class Aaaaa {
+ Aaaaa.foo(int a);
+ }
+ void main() {
+ var a = new Aaaaa.[[foo^]]
+ }
+ ''',
+ 'foo(…)',
+ insertTextFormat: InsertTextFormat.Snippet,
+ insertText: r'foo(${0:a})',
+ );
+
Future<void> test_completeFunctionCalls_noRequiredParameters() async {
final content = '''
void myFunction({int a}) {}
@@ -269,40 +370,29 @@
expect(textEdit.newText, equals(item.insertText));
}
- Future<void> test_completeFunctionCalls_suggestionSets() async {
- final content = '''
- main() {
- [[pri]]^
- }
- ''';
+ Future<void> test_completeFunctionCalls_statement() =>
+ checkCompleteFunctionCallInsertText(
+ '''
+ void main(int a) {
+ [[mai^]]
+ }
+ ''',
+ 'main(…)',
+ insertTextFormat: InsertTextFormat.Snippet,
+ insertText: r'main(${0:a})',
+ );
- final initialAnalysis = waitForAnalysisComplete();
- await provideConfig(
- () => initialize(
- textDocumentCapabilities: withCompletionItemSnippetSupport(
- emptyTextDocumentClientCapabilities),
- workspaceCapabilities: withConfigurationSupport(
- withApplyEditSupport(emptyWorkspaceClientCapabilities)),
- ),
- {'completeFunctionCalls': true},
- );
- await openFile(mainFileUri, withoutMarkers(content));
- await initialAnalysis;
- final res = await getCompletion(mainFileUri, positionFromMarker(content));
- final item = res.singleWhere((c) => c.label == 'print(…)');
- // Ensure the snippet comes through in the expected format with the expected
- // placeholders.
- expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
- expect(item.insertText, equals(r'print(${0:object})'));
- expect(item.textEdit, isNull);
-
- // Ensure the item can be resolved and gets a proper TextEdit.
- final resolved = await resolveCompletion(item);
- expect(resolved.textEdit, isNotNull);
- final textEdit = toTextEdit(resolved.textEdit!);
- expect(textEdit.newText, equals(item.insertText));
- expect(textEdit.range, equals(rangeFromMarkers(content)));
- }
+ Future<void> test_completeFunctionCalls_suggestionSets() =>
+ checkCompleteFunctionCallInsertText(
+ '''
+ void main(int a) {
+ [[pri^]]
+ }
+ ''',
+ 'print(…)',
+ insertTextFormat: InsertTextFormat.Snippet,
+ insertText: r'print(${0:object})',
+ );
Future<void> test_completionKinds_default() async {
newFile(join(projectFolderPath, 'file.dart'));
@@ -2045,4 +2135,23 @@
expect(textEdit.newText, equals(item.insertText));
expect(textEdit.range, equals(rangeFromMarkers(content)));
}
+
+ Future<void> test_nullableTypes() async {
+ final content = '''
+ String? foo(int? a, [int b = 1]) {}
+
+ main() {
+ fo^
+ }
+ ''';
+
+ final initialAnalysis = waitForAnalysisComplete();
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ await initialAnalysis;
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+ final completion = res.singleWhere((c) => c.label.startsWith('foo'));
+ expect(completion.detail, '(int? a, [int b = 1]) → String?');
+ }
}
diff --git a/pkg/analysis_server/test/lsp/folding_test.dart b/pkg/analysis_server/test/lsp/folding_test.dart
index 51b2eef..9d35988 100644
--- a/pkg/analysis_server/test/lsp/folding_test.dart
+++ b/pkg/analysis_server/test/lsp/folding_test.dart
@@ -104,6 +104,32 @@
expect(regions, containsAll(expectedRegions));
}
+ Future<void> test_enum() async {
+ final content = '''
+ enum MyEnum {[[
+ one,
+ two,
+ three
+ ]]}
+ ''';
+
+ final range1 = rangeFromMarkers(content);
+ final expectedRegions = [
+ FoldingRange(
+ startLine: range1.start.line,
+ startCharacter: range1.start.character,
+ endLine: range1.end.line,
+ endCharacter: range1.end.character,
+ )
+ ];
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+
+ final regions = await getFoldingRegions(mainFileUri);
+ expect(regions, unorderedEquals(expectedRegions));
+ }
+
Future<void> test_fromPlugins_dartFile() async {
final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.dart');
final pluginAnalyzedUri = Uri.file(pluginAnalyzedFilePath);
diff --git a/pkg/analysis_server/test/lsp/hover_test.dart b/pkg/analysis_server/test/lsp/hover_test.dart
index 77bb9b5..9abd77a 100644
--- a/pkg/analysis_server/test/lsp/hover_test.dart
+++ b/pkg/analysis_server/test/lsp/hover_test.dart
@@ -13,6 +13,7 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(HoverTest);
+ defineReflectiveTests(HoverWithNullSafetyTest);
});
}
@@ -265,3 +266,31 @@
);
}
}
+
+@reflectiveTest
+class HoverWithNullSafetyTest extends HoverTest {
+ @override
+ String get testPackageLanguageVersion => latestLanguageVersion;
+
+ Future<void> test_nullableTypes() async {
+ final content = '''
+ String? [[a^bc]];
+ ''';
+
+ final expectedHoverContent = '''
+```dart
+String? abc
+```
+*package:test/main.dart*
+ '''
+ .trim();
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ final hover = await getHover(mainFileUri, positionFromMarker(content));
+ expect(hover, isNotNull);
+ expect(hover!.range, equals(rangeFromMarkers(content)));
+ expect(hover.contents, isNotNull);
+ expect(_getStringContents(hover), equals(expectedHoverContent));
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 986d755..e5ce594 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -39,10 +39,6 @@
/// communication to be printed to stdout.
const debugPrintCommunication = false;
-final beginningOfDocument = Range(
- start: Position(line: 0, character: 0),
- end: Position(line: 0, character: 0));
-
abstract class AbstractLspAnalysisServerTest
with
ResourceProviderMixin,
@@ -957,13 +953,17 @@
Future<List<Either2<Command, CodeAction>>> getCodeActions(
String fileUri, {
Range? range,
+ Position? position,
List<CodeActionKind>? kinds,
}) {
+ range ??= position != null
+ ? Range(start: position, end: position)
+ : startOfDocRange;
final request = makeRequest(
Method.textDocument_codeAction,
CodeActionParams(
textDocument: TextDocumentIdentifier(uri: fileUri),
- range: range ?? beginningOfDocument,
+ range: range,
// TODO(dantup): We may need to revise the tests/implementation when
// it's clear how we're supposed to handle diagnostics:
// https://github.com/Microsoft/language-server-protocol/issues/583
diff --git a/pkg/analysis_server/test/lsp/signature_help_test.dart b/pkg/analysis_server/test/lsp/signature_help_test.dart
index 9a6300f..31e1ff3 100644
--- a/pkg/analysis_server/test/lsp/signature_help_test.dart
+++ b/pkg/analysis_server/test/lsp/signature_help_test.dart
@@ -479,12 +479,12 @@
// This test requires support for the "required" keyword.
final content = '''
/// Does foo.
- foo(String s, {bool b = true, required bool a}) {
+ foo(String s, {bool? b = true, required bool a}) {
foo(^);
}
''';
- final expectedLabel = 'foo(String s, {bool b = true, required bool a})';
+ final expectedLabel = 'foo(String s, {bool? b = true, required bool a})';
final expectedDoc = 'Does foo.';
await initialize(
@@ -497,7 +497,7 @@
expectedDoc,
[
ParameterInformation(label: 'String s'),
- ParameterInformation(label: 'bool b = true'),
+ ParameterInformation(label: 'bool? b = true'),
ParameterInformation(label: 'required bool a'),
],
);
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index e802863..ae69a11 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -32,7 +32,7 @@
var engineElement = findElement.constructor('myConstructor');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: false);
expect(element.parameters, '(int a, {@required int c, int b})');
}
@@ -47,7 +47,7 @@
var engineElement = findElement.constructor('myConstructor');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: false);
expect(element.parameters,
'(int a, {@required int d, @required int c, int b})');
}
@@ -64,7 +64,7 @@
var engineElement = findElement.constructor('myConstructor');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: false);
expect(element.parameters,
'(int a, {@required int d, @required int c, int b, int a})');
}
@@ -81,7 +81,7 @@
{
var engineElement = findElement.class_('_A');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.CLASS);
expect(element.name, '_A');
expect(element.typeParameters, isNull);
@@ -103,7 +103,7 @@
{
var engineElement = findElement.class_('B');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.CLASS);
expect(element.name, 'B');
expect(element.typeParameters, '<K, V>');
@@ -118,7 +118,7 @@
}''');
var engineElement = findElement.constructor('myConstructor');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.CONSTRUCTOR);
expect(element.name, 'myConstructor');
expect(element.typeParameters, isNull);
@@ -130,7 +130,7 @@
expect(location.startLine, 2);
expect(location.startColumn, 11);
}
- expect(element.parameters, '(int a, [String b])');
+ expect(element.parameters, '(int a, [String? b])');
expect(element.returnType, 'A');
expect(element.flags, Element.FLAG_CONST);
}
@@ -145,8 +145,8 @@
var engineElement = findElement.constructor('myConstructor');
// create notification Element
- var element = convertElement(engineElement);
- expect(element.parameters, '(int a, {required int c, int b})');
+ var element = convertElement(engineElement, withNullability: true);
+ expect(element.parameters, '(int a, {required int c, int? b})');
}
/// Verify parameter re-ordering for required params
@@ -160,9 +160,9 @@
var engineElement = findElement.constructor('myConstructor');
// create notification Element
- var element = convertElement(engineElement);
- expect(
- element.parameters, '(int a, {required int d, required int c, int b})');
+ var element = convertElement(engineElement, withNullability: true);
+ expect(element.parameters,
+ '(int a, {required int d, required int c, int? b})');
}
/// Verify parameter re-ordering for required params
@@ -177,7 +177,7 @@
var engineElement = findElement.constructor('myConstructor');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.parameters,
'(int a, {required int d, required int c, int b, int a})');
}
@@ -185,7 +185,7 @@
void test_dynamic() {
var engineElement = engine.DynamicElementImpl.instance;
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.UNKNOWN);
expect(element.name, 'dynamic');
expect(element.location, isNull);
@@ -203,7 +203,7 @@
var engineElement = findElement.enum_('_E1');
expect(engineElement.hasDeprecated, isTrue);
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.ENUM);
expect(element.name, '_E1');
expect(element.typeParameters, isNull);
@@ -224,7 +224,7 @@
{
var engineElement = findElement.enum_('E2');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.ENUM);
expect(element.name, 'E2');
expect(element.typeParameters, isNull);
@@ -240,7 +240,7 @@
{
var engineElement = findElement.field('one');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.ENUM_CONSTANT);
expect(element.name, 'one');
{
@@ -264,7 +264,7 @@
{
var engineElement = findElement.field('three');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.ENUM_CONSTANT);
expect(element.name, 'three');
{
@@ -282,7 +282,7 @@
{
var engineElement = findElement.field('index', of: 'E2');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.FIELD);
expect(element.name, 'index');
{
@@ -300,7 +300,7 @@
{
var engineElement = findElement.field('values', of: 'E2');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.FIELD);
expect(element.name, 'values');
{
@@ -324,7 +324,7 @@
}''');
var engineElement = findElement.field('myField');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.FIELD);
expect(element.name, 'myField');
{
@@ -346,7 +346,7 @@
''');
var engineElement = findElement.typeAlias('F');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.TYPE_ALIAS);
expect(element.name, 'F');
expect(element.typeParameters, '<T>');
@@ -369,7 +369,7 @@
''');
var engineElement = findElement.typeAlias('F');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.TYPE_ALIAS);
expect(element.name, 'F');
expect(element.typeParameters, '<out T>');
@@ -393,7 +393,7 @@
''');
var engineElement = findElement.typeAlias('F');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.TYPE_ALIAS);
expect(element.name, 'F');
expect(element.typeParameters, '<T>');
@@ -418,7 +418,7 @@
}''');
var engineElement = findElement.getter('myGetter');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.GETTER);
expect(element.name, 'myGetter');
{
@@ -444,7 +444,7 @@
}''');
var engineElement = findElement.label('myLabel');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.LABEL);
expect(element.name, 'myLabel');
{
@@ -469,7 +469,7 @@
}''');
var engineElement = findElement.method('myMethod');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.METHOD);
expect(element.name, 'myMethod');
{
@@ -480,7 +480,7 @@
expect(location.startLine, 2);
expect(location.startColumn, 23);
}
- expect(element.parameters, '(int a, {String b, int c})');
+ expect(element.parameters, '(int a, {String? b, int? c})');
expect(element.returnType, 'List<String>');
expect(element.flags, Element.FLAG_STATIC);
}
@@ -492,7 +492,7 @@
{
var engineElement = findElement.mixin('A');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.MIXIN);
expect(element.name, 'A');
expect(element.typeParameters, isNull);
@@ -516,7 +516,7 @@
}''');
var engineElement = findElement.setter('mySetter');
// create notification Element
- var element = convertElement(engineElement);
+ var element = convertElement(engineElement, withNullability: true);
expect(element.kind, ElementKind.SETTER);
expect(element.name, 'mySetter');
{
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 497e8c9..b72acd8 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -186,7 +186,6 @@
CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
CompileTimeErrorCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE,
CompileTimeErrorCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
- CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES,
CompileTimeErrorCode.FINAL_NOT_INITIALIZED,
CompileTimeErrorCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1,
CompileTimeErrorCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2,
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 80b996d..83eacb7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -130,9 +130,9 @@
isEnabledByDefault: IsEnabledByDefault.generic_metadata,
isExpired: IsExpired.generic_metadata,
documentation:
- 'Allow annotations to accept type arguments; also allow generic function types as type arguments',
+ 'Allow annotations to accept type arguments; also allow generic function types as type arguments.',
experimentalReleaseVersion: null,
- releaseVersion: null,
+ releaseVersion: Version.parse('2.14.0'),
);
static final non_nullable = ExperimentalFeature(
@@ -225,7 +225,7 @@
static const bool extension_types = false;
/// Default state of the experiment "generic-metadata"
- static const bool generic_metadata = false;
+ static const bool generic_metadata = true;
/// Default state of the experiment "non-nullable"
static const bool non_nullable = true;
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 6cd2625..d70224e 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -3168,8 +3168,8 @@
static const CompileTimeErrorCode DUPLICATE_FIELD_FORMAL_PARAMETER =
CompileTimeErrorCode(
'DUPLICATE_FIELD_FORMAL_PARAMETER',
- "The field '{0}' can't be referenced in multiple initializing "
- "parameters in the same constructor.",
+ "The field '{0}' can't be initialized by multiple parameters in the "
+ "same constructor.",
correction: "Try removing one of the parameters, or "
"using different fields.");
@@ -4654,19 +4654,6 @@
hasPublishedDocs: true);
/**
- * 5 Variables: It is a compile-time error if a final instance variable that
- * has is initialized by means of an initializing formal of a constructor is
- * also initialized elsewhere in the same constructor.
- *
- * Parameters:
- * 0: the name of the field in question
- */
- static const CompileTimeErrorCode FINAL_INITIALIZED_MULTIPLE_TIMES =
- CompileTimeErrorCode('FINAL_INITIALIZED_MULTIPLE_TIMES',
- "'{0}' is a final field and so can only be set once.",
- correction: "Try removing all but one of the initializations.");
-
- /**
* Parameters:
* 0: the name of the uninitialized final variable
*/
diff --git a/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart b/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart
index 260bbb6..b1a079a 100644
--- a/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart
+++ b/pkg/analyzer/lib/src/error/constructor_fields_verifier.dart
@@ -219,13 +219,7 @@
);
}
} else if (state == _InitState.initInFieldFormal) {
- if (fieldElement.isFinal || fieldElement.isConst) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES,
- parameter.identifier,
- [fieldElement.displayName],
- );
- }
+ // Reported in DuplicateDefinitionVerifier._checkDuplicateIdentifier
}
}
}
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index eb3d6c6..f5e4f33 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -384,14 +384,7 @@
var previous = getterScope[name];
if (previous != null) {
- if (_isGetterSetterPair(element, previous)) {
- // OK
- } else if (element is FieldFormalParameterElement &&
- previous is FieldFormalParameterElement &&
- element.field != null &&
- element.field!.isFinal) {
- // Reported as CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES.
- } else {
+ if (!_isGetterSetterPair(element, previous)) {
_errorReporter.reportErrorForNode(
getError(previous, element),
identifier,
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 577424b..d4cd689 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -1346,8 +1346,9 @@
String? docSummary;
void setDartDoc(AnnotatedNode node) {
- if (node.documentationComment != null) {
- var rawText = getCommentNodeRawText(node.documentationComment);
+ var docComment = node.documentationComment;
+ if (docComment != null) {
+ var rawText = getCommentNodeRawText(docComment);
docComplete = getDartDocPlainText(rawText);
docSummary = getDartDocSummary(docComplete);
} else {
diff --git a/pkg/analyzer/lib/src/util/comment.dart b/pkg/analyzer/lib/src/util/comment.dart
index cb295c6..ae3ebf9 100644
--- a/pkg/analyzer/lib/src/util/comment.dart
+++ b/pkg/analyzer/lib/src/util/comment.dart
@@ -8,10 +8,22 @@
String? getCommentNodeRawText(Comment? node) {
if (node == null) return null;
- return node.tokens
- .map((token) => token.lexeme)
- .join('\n')
- .replaceAll('\r\n', '\n');
+ var tokens = node.tokens;
+ var count = tokens.length;
+ if (count == 1) {
+ // The comment might be a block-style doc comment with embedded end-of-line
+ // markers.
+ return tokens[0].lexeme.replaceAll('\r\n', '\n');
+ }
+
+ var buffer = StringBuffer();
+ for (var i = 0; i < count; i++) {
+ if (i > 0) {
+ buffer.write('\n');
+ }
+ buffer.write(tokens[i].lexeme);
+ }
+ return buffer.toString();
}
/// Return the plain text from the given DartDoc [rawText], without delimiters.
@@ -19,11 +31,13 @@
if (rawText == null) return null;
// Remove /** */.
+ var isBlock = false;
if (rawText.startsWith('/**')) {
+ isBlock = true;
rawText = rawText.substring(3);
- }
- if (rawText.endsWith('*/')) {
- rawText = rawText.substring(0, rawText.length - 2);
+ if (rawText.endsWith('*/')) {
+ rawText = rawText.substring(0, rawText.length - 2);
+ }
}
rawText = rawText.trim();
@@ -32,12 +46,12 @@
var lines = rawText.split('\n');
for (var line in lines) {
line = line.trim();
- if (line.startsWith('*')) {
+ if (isBlock && line.startsWith('*')) {
line = line.substring(1);
if (line.startsWith(' ')) {
line = line.substring(1);
}
- } else if (line.startsWith('///')) {
+ } else if (!isBlock && line.startsWith('///')) {
line = line.substring(3);
if (line.startsWith(' ')) {
line = line.substring(1);
@@ -54,12 +68,18 @@
/// Return the DartDoc summary, i.e. the portion before the first empty line.
String? getDartDocSummary(String? completeText) {
- if (completeText == null) return null;
-
- var result = StringBuffer();
+ if (completeText == null) {
+ return null;
+ }
var lines = completeText.split('\n');
- for (var line in lines) {
- if (result.isNotEmpty) {
+ int count = lines.length;
+ if (count == 1) {
+ return lines[0];
+ }
+ var result = StringBuffer();
+ for (var i = 0; i < count; i++) {
+ var line = lines[i];
+ if (i > 0) {
if (line.isEmpty) {
return result.toString();
}
diff --git a/pkg/analyzer/lib/src/workspace/bazel_watcher.dart b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
index 81d20db..50ceb0c 100644
--- a/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
@@ -33,7 +33,7 @@
final List<String> _candidates;
/// The time of last modification of the file under [_validPath].
- int? _lastModified;
+ _TimestampAndLength? _lastModified;
/// The resource provider used for polling the files.
final ResourceProvider _provider;
@@ -47,7 +47,7 @@
/// Checks if the file corresponding to the watched path has changed and
/// returns the event or `null` if nothing changed.
WatchEvent? poll() {
- int? modified;
+ _TimestampAndLength? modified;
if (_validPath == null) {
var info = _pollAll();
if (info != null) {
@@ -72,6 +72,7 @@
} else if (_lastModified != null && modified != _lastModified) {
result = WatchEvent(ChangeType.MODIFY, _validPath!);
}
+
_lastModified = modified;
return result;
}
@@ -107,10 +108,12 @@
/// Returns the modified time of the path or `null` if the file does not
/// exist.
- int? _pollOne(String path) {
+ _TimestampAndLength? _pollOne(String path) {
try {
var file = _provider.getFile(path);
- return file.modificationStamp;
+ var timestamp = file.modificationStamp;
+ var length = file.lengthSync;
+ return _TimestampAndLength(timestamp, length);
} on FileSystemException catch (_) {
// File doesn't exist, so return null.
return null;
@@ -403,7 +406,7 @@
class FileInfo {
String path;
- int modified;
+ _TimestampAndLength modified;
FileInfo(this.path, this.modified);
}
@@ -549,3 +552,36 @@
_PerWorkspaceData(this.trigger, this.pollSubscription);
}
+
+/// Stores the timestamp of a file and its length.
+///
+/// This turns out to be important for tracking files that change a lot, like
+/// the `command.log` that we use to detect the finished build. Bazel writes to
+/// the file continuously and because the resolution of a timestamp is pretty
+/// low, it's quite possible to receive the same timestamp even though the file
+/// has changed. We use its length to remedy that. It's not perfect (for that
+/// we'd have to compute the hash), but it should be reasonable trade-off (to
+/// avoid any performance impact from reading and hashing the file).
+class _TimestampAndLength {
+ final int timestamp;
+ final int length;
+ _TimestampAndLength(this.timestamp, this.length);
+
+ @override
+ int get hashCode =>
+ // We don't really need to compute hashes, just check the equality. But
+ // throw in case someone expects this to work.
+ throw UnimplementedError(
+ '_TimestampAndLength.hashCode has not been implemented yet');
+
+ @override
+ bool operator ==(Object other) {
+ if (other is! _TimestampAndLength) return false;
+ return timestamp == other.timestamp && length == other.length;
+ }
+
+ // For debugging only.
+ @override
+ String toString() =>
+ '_TimestampAndLength(timestamp=$timestamp, length=$length)';
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
index 0cd0ac8..60b6def 100644
--- a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
@@ -194,6 +194,7 @@
test_genericFunctionTypeCannotBeTypeArgument_def_class() async {
await assertErrorsInCode(r'''
+// @dart=2.12
class C<T> {}
typedef G = Function<S>();
@@ -201,23 +202,25 @@
C<G>? x;
''', [
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
- 45, 1),
+ 59, 1),
]);
}
test_genericFunctionTypeCannotBeTypeArgument_literal_class() async {
await assertErrorsInCode(r'''
+// @dart=2.12
class C<T> {}
C<Function<S>()>? x;
''', [
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
- 17, 13),
+ 31, 13),
]);
}
test_genericFunctionTypeCannotBeTypeArgument_literal_function() async {
await assertErrorsInCode(r'''
+// @dart=2.12
void f<T>(T) {}
main() {
@@ -225,12 +228,13 @@
}
''', [
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
- 30, 13),
+ 44, 13),
]);
}
test_genericFunctionTypeCannotBeTypeArgument_literal_functionType() async {
await assertErrorsInCode(r'''
+// @dart=2.12
late T Function<T>(T?) f;
main() {
@@ -238,12 +242,13 @@
}
''', [
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
- 40, 13),
+ 54, 13),
]);
}
test_genericFunctionTypeCannotBeTypeArgument_literal_method() async {
await assertErrorsInCode(r'''
+// @dart=2.12
class C {
void f<T>(T) {}
}
@@ -253,18 +258,19 @@
}
''', [
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
- 52, 13),
+ 66, 13),
]);
}
test_genericFunctionTypeCannotBeTypeArgument_literal_typedef() async {
await assertErrorsInCode(r'''
+// @dart=2.12
typedef T F<T>(T t);
F<Function<S>()>? x;
''', [
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
- 24, 13),
+ 38, 13),
]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart
index 0d10113..586709e 100644
--- a/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart
@@ -37,6 +37,17 @@
]);
}
+ test_optional_positional_final() async {
+ await assertErrorsInCode(r'''
+class A {
+ final x;
+ A([this.x = 1, this.x = 2]) {}
+}
+''', [
+ error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 43, 1),
+ ]);
+ }
+
test_required_named() async {
await assertErrorsInCode(r'''
class A {
@@ -58,4 +69,15 @@
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 36, 1),
]);
}
+
+ test_required_positional_final() async {
+ await assertErrorsInCode(r'''
+class A {
+ final x;
+ A(this.x, this.x) {}
+}
+''', [
+ error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 38, 1),
+ ]);
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/final_initialized_multiple_times_test.dart b/pkg/analyzer/test/src/diagnostics/final_initialized_multiple_times_test.dart
deleted file mode 100644
index d860ffe..0000000
--- a/pkg/analyzer/test/src/diagnostics/final_initialized_multiple_times_test.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019, 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(FinalInitializedMultipleTimesTest);
- });
-}
-
-@reflectiveTest
-class FinalInitializedMultipleTimesTest extends PubPackageResolutionTest {
- test_initializingFormals_withDefaultValues() async {
- await assertErrorsInCode(r'''
-class A {
- final x;
- A([this.x = 1, this.x = 2]) {}
-}
-''', [
- error(CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, 43, 1),
- ]);
- }
-
- test_initializingFormals_withoutDefaultValues() async {
- await assertErrorsInCode(r'''
-class A {
- final x;
- A(this.x, this.x) {}
-}
-''', [
- error(CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, 38, 1),
- ]);
- }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/generic_function_type_cannot_be_bound_test.dart b/pkg/analyzer/test/src/diagnostics/generic_function_type_cannot_be_bound_test.dart
index 583a9a5..02c4641 100644
--- a/pkg/analyzer/test/src/diagnostics/generic_function_type_cannot_be_bound_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/generic_function_type_cannot_be_bound_test.dart
@@ -72,26 +72,29 @@
test_class() async {
await assertErrorsInCode(r'''
+// @dart=2.12
class C<T extends S Function<S>(S)> {
}
''', [
- error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 18, 16),
+ error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 32, 16),
]);
}
test_genericFunction() async {
await assertErrorsInCode(r'''
+// @dart=2.12
late T Function<T extends S Function<S>(S)>(T) fun;
''', [
- error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 26, 16),
+ error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 40, 16),
]);
}
test_genericFunctionTypedef() async {
await assertErrorsInCode(r'''
+// @dart=2.12
typedef foo = T Function<T extends S Function<S>(S)>(T t);
''', [
- error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 35, 16),
+ error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 49, 16),
]);
}
@@ -103,9 +106,10 @@
test_typedef() async {
await assertErrorsInCode(r'''
+// @dart=2.12
typedef T foo<T extends S Function<S>(S)>(T t);
''', [
- error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 24, 16),
+ error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 38, 16),
]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index b3e249e..46d80bd 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -207,8 +207,6 @@
as field_initializing_formal_not_assignable;
import 'final_initialized_in_delcaration_and_constructor_test.dart'
as final_initialized_in_declaration_and_constructor;
-import 'final_initialized_multiple_times_test.dart'
- as final_initialized_multiple_times;
import 'final_not_initialized_constructor_test.dart'
as final_not_initialized_constructor;
import 'final_not_initialized_test.dart' as final_not_initialized;
@@ -820,7 +818,6 @@
final_initialized_in_declaration_and_constructor.main();
field_initialized_in_initializer_and_declaration.main();
field_initialized_in_parameter_and_initializer.main();
- final_initialized_multiple_times.main();
field_initializer_factory_constructor.main();
field_initializer_in_struct.main();
field_initializer_not_assignable.main();
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 767c77a..2ca67b4 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -156,7 +156,7 @@
[definiteAssignmentSpec](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md)
-### Mixin Application
+### Mixin application
A _mixin application_ is the class created when a mixin is applied to a class.
For example, consider the following declarations:
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index b95e8dc..c19400f 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -547,7 +547,7 @@
[definiteAssignmentSpec](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md)
-### Mixin Application
+### Mixin application
A _mixin application_ is the class created when a mixin is applied to a class.
For example, consider the following declarations:
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 4f00c21..7288f48 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -94,6 +94,7 @@
static const String useMultiSourceInfo = '--use-multi-source-info';
static const String useNewSourceInfo = '--use-new-source-info';
static const String useOldRti = '--use-old-rti';
+ static const String useSimpleLoadIds = '--simple-load-ids';
static const String verbose = '--verbose';
static const String verbosity = '--verbosity';
static const String progress = '--show-internal-progress';
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 2a18b23..1dcfde0 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -581,6 +581,7 @@
new OptionHandler(Flags.useMultiSourceInfo, passThrough),
new OptionHandler(Flags.useNewSourceInfo, passThrough),
new OptionHandler(Flags.useOldRti, passThrough),
+ new OptionHandler(Flags.useSimpleLoadIds, passThrough),
new OptionHandler(Flags.testMode, passThrough),
new OptionHandler('${Flags.dumpSsa}=.+', passThrough),
new OptionHandler('${Flags.cfeInvocationModes}=.+', passThrough),
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 974e8a0..f3f6bac 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -670,15 +670,27 @@
}
void _setupImportNames() {
+ // If useSimpleLoadIds is true then we use a monotonically increasing number
+ // to generate loadIds. Otherwise, we will use the user provided names.
+ bool useIds = compiler.options.useSimpleLoadIds;
+ var allDeferredImports = _allDeferredImports.toList();
+ if (useIds) {
+ // Sort for a canonical order of [ImportEntity]s.
+ allDeferredImports.sort(_compareImportEntities);
+ }
+ int nextDeferId = 0;
Set<String> usedImportNames = {};
-
- for (ImportEntity import in _allDeferredImports) {
+ for (ImportEntity import in allDeferredImports) {
String result = computeImportDeferName(import, compiler);
assert(result != null);
- // Note: tools that process the json file to build multi-part initial load
- // bundles depend on the fact that makeUnique appends only digits, or a
- // period followed by digits.
- importDeferName[import] = makeUnique(result, usedImportNames, '.');
+ if (useIds) {
+ importDeferName[import] = (++nextDeferId).toString();
+ } else {
+ // Note: tools that process the json file to build multi-part initial load
+ // bundles depend on the fact that makeUnique appends only digits, or a
+ // period followed by digits.
+ importDeferName[import] = makeUnique(result, usedImportNames, '.');
+ }
}
}
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 43a92cb..f3b99c9 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -352,6 +352,9 @@
/// (experimental)
bool useNewSourceInfo = false;
+ /// Whether or not use simple load ids.
+ bool useSimpleLoadIds = false;
+
/// Enable verbose printing during compilation. Includes a time-breakdown
/// between phases at the end.
bool verbose = false;
@@ -524,6 +527,7 @@
!_hasOption(options, Flags.noFrequencyBasedMinification)
..useMultiSourceInfo = _hasOption(options, Flags.useMultiSourceInfo)
..useNewSourceInfo = _hasOption(options, Flags.useNewSourceInfo)
+ ..useSimpleLoadIds = _hasOption(options, Flags.useSimpleLoadIds)
..verbose = _hasOption(options, Flags.verbose)
..reportPrimaryMetrics = _hasOption(options, Flags.reportMetrics)
..reportSecondaryMetrics = _hasOption(options, Flags.reportAllMetrics)
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
index 42d985f..3a1e2c8 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
@@ -83,7 +83,7 @@
ExperimentalFlag.controlFlowCollections: true,
ExperimentalFlag.extensionMethods: true,
ExperimentalFlag.extensionTypes: false,
- ExperimentalFlag.genericMetadata: false,
+ ExperimentalFlag.genericMetadata: true,
ExperimentalFlag.nonNullable: true,
ExperimentalFlag.nonfunctionTypeAliases: true,
ExperimentalFlag.setLiterals: true,
diff --git a/runtime/vm/experimental_features.cc b/runtime/vm/experimental_features.cc
index 162f8c8..18c32a0 100644
--- a/runtime/vm/experimental_features.cc
+++ b/runtime/vm/experimental_features.cc
@@ -18,7 +18,7 @@
bool GetExperimentalFeatureDefault(ExperimentalFeature feature) {
constexpr bool kFeatureValues[] = {
- true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true, true,
};
ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureValues));
return kFeatureValues[static_cast<int>(feature)];
@@ -26,10 +26,15 @@
const char* GetExperimentalFeatureName(ExperimentalFeature feature) {
constexpr const char* kFeatureNames[] = {
- "nonfunction-type-aliases", "non-nullable",
- "extension-methods", "constant-update-2018",
- "control-flow-collections", "set-literals",
- "spread-collections", "triple-shift",
+ "nonfunction-type-aliases",
+ "non-nullable",
+ "extension-methods",
+ "constant-update-2018",
+ "control-flow-collections",
+ "generic-metadata",
+ "set-literals",
+ "spread-collections",
+ "triple-shift",
};
ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureNames));
return kFeatureNames[static_cast<int>(feature)];
diff --git a/runtime/vm/experimental_features.h b/runtime/vm/experimental_features.h
index 0bb9e50..ba0588d 100644
--- a/runtime/vm/experimental_features.h
+++ b/runtime/vm/experimental_features.h
@@ -19,6 +19,7 @@
extension_methods,
constant_update_2018,
control_flow_collections,
+ generic_metadata,
set_literals,
spread_collections,
triple_shift,
diff --git a/tests/language/constructor/duplicate_initializers_test.dart b/tests/language/constructor/duplicate_initializers_test.dart
index 4f6699e..a521279 100644
--- a/tests/language/constructor/duplicate_initializers_test.dart
+++ b/tests/language/constructor/duplicate_initializers_test.dart
@@ -25,7 +25,7 @@
Class.two_fields(this.field_
, this.field_
// ^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.FINAL_INITIALIZED_MULTIPLE_TIMES
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_FIELD_FORMAL_PARAMETER
// [cfe] 'field_' was already initialized by this constructor.
// ^
// [cfe] Duplicated parameter name 'field_'.
diff --git a/tests/language/generic/function_type_as_type_argument_test.dart b/tests/language/generic/function_type_as_type_argument_test.dart
index c59dce7..e932d53 100644
--- a/tests/language/generic/function_type_as_type_argument_test.dart
+++ b/tests/language/generic/function_type_as_type_argument_test.dart
@@ -4,6 +4,8 @@
//
// VMOptions=--reify-generic-functions
+// @dart=2.12
+
import "package:expect/expect.dart";
T foo<T>(T i) => i;
diff --git a/tests/language/generic/metadata_in_function_body_test.dart b/tests/language/generic/metadata_in_function_body_test.dart
index e6be65f..8b64190 100644
--- a/tests/language/generic/metadata_in_function_body_test.dart
+++ b/tests/language/generic/metadata_in_function_body_test.dart
@@ -2,6 +2,8 @@
// 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.
+// @dart=2.12
+
// Check that annotations inside function bodies cannot use type arguments, but
// can be raw.
diff --git a/tests/language/generic/metadata_test.dart b/tests/language/generic/metadata_test.dart
index a6a5ad8..70156d6 100644
--- a/tests/language/generic/metadata_test.dart
+++ b/tests/language/generic/metadata_test.dart
@@ -2,6 +2,8 @@
// 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.
+// @dart=2.12
+
// Check that annotations cannot use type arguments, but can be raw.
class C<T> {
diff --git a/tests/language/generic_methods/generic_function_result_test.dart b/tests/language/generic_methods/generic_function_result_test.dart
index 41d4742..569c2f9 100644
--- a/tests/language/generic_methods/generic_function_result_test.dart
+++ b/tests/language/generic_methods/generic_function_result_test.dart
@@ -2,6 +2,8 @@
// 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.
+// @dart=2.12
+
// Verify that function type parameter S can be resolved in bar's result type.
// Verify that generic function types are not allowed as type arguments.
diff --git a/tests/language/regress/regress33479_test.dart b/tests/language/regress/regress33479_test.dart
index a825b94..38b558c3 100644
--- a/tests/language/regress/regress33479_test.dart
+++ b/tests/language/regress/regress33479_test.dart
@@ -1,11 +1,9 @@
class Hest<TypeX extends Fisk> {}
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND
-// ^
-// [cfe] Type variables can't have generic function types in their bounds.
typedef Fisk = void Function // don't merge lines
-// [error line 7, column 1, length 346]
+// [error line 5, column 1, length 346]
// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
// ^
// [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
@@ -15,6 +13,4 @@
main() {
Hest hest = new Hest();
-// ^
-// [cfe] Generic function type 'void Function<TypeY>()' inferred as a type argument.
}
diff --git a/tests/language_2/constructor/duplicate_initializers_test.dart b/tests/language_2/constructor/duplicate_initializers_test.dart
index c787657..d98d23d 100644
--- a/tests/language_2/constructor/duplicate_initializers_test.dart
+++ b/tests/language_2/constructor/duplicate_initializers_test.dart
@@ -27,7 +27,7 @@
Class.two_fields(this.field_
, this.field_
// ^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.FINAL_INITIALIZED_MULTIPLE_TIMES
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_FIELD_FORMAL_PARAMETER
// [cfe] 'field_' was already initialized by this constructor.
// ^
// [cfe] Duplicated parameter name 'field_'.
diff --git a/tests/language_2/generic/metadata_in_function_body_test.dart b/tests/language_2/generic/metadata_in_function_body_test.dart
index 1b7fe3c..d98f743 100644
--- a/tests/language_2/generic/metadata_in_function_body_test.dart
+++ b/tests/language_2/generic/metadata_in_function_body_test.dart
@@ -7,6 +7,8 @@
// Check that annotations inside function bodies cannot use type arguments, but
// can be raw.
+// @dart=2.11
+
class C<T> {
const C();
}
diff --git a/tests/language_2/generic/metadata_test.dart b/tests/language_2/generic/metadata_test.dart
index 18d6b86..4a4dcad 100644
--- a/tests/language_2/generic/metadata_test.dart
+++ b/tests/language_2/generic/metadata_test.dart
@@ -6,6 +6,8 @@
// Check that annotations cannot use type arguments, but can be raw.
+// @dart=2.11
+
class C<T> {
const C();
}
diff --git a/tests/language_2/generic_methods/generic_function_result_test.dart b/tests/language_2/generic_methods/generic_function_result_test.dart
index 9e24263..d291d2d 100644
--- a/tests/language_2/generic_methods/generic_function_result_test.dart
+++ b/tests/language_2/generic_methods/generic_function_result_test.dart
@@ -7,6 +7,8 @@
// Verify that function type parameter S can be resolved in bar's result type.
// Verify that generic function types are not allowed as type arguments.
+// @dart=2.11
+
import "package:expect/expect.dart";
int foo
diff --git a/tests/lib/mirrors/metadata_allowed_values_test.dart b/tests/lib/mirrors/metadata_allowed_values_test.dart
index 3204730..85937ff 100644
--- a/tests/lib/mirrors/metadata_allowed_values_test.dart
+++ b/tests/lib/mirrors/metadata_allowed_values_test.dart
@@ -47,11 +47,6 @@
G.named(this.field);
}
-@H<int>() // //# 05: compile-time error
-class H<T> {
- const H();
-}
-
@I[0] // //# 06: compile-time error
class I {}
@@ -187,7 +182,6 @@
reflectClass(E).metadata;
reflectClass(F).metadata;
reflectClass(G).metadata;
- reflectClass(H).metadata;
reflectClass(I).metadata;
reflectClass(J).metadata;
reflectClass(K).metadata;
diff --git a/tools/VERSION b/tools/VERSION
index cc9e6ba..e11b2c9 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 50
+PRERELEASE 51
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index 1881ab6..acc2a15 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -116,9 +116,6 @@
value-class:
help: "Value class"
- generic-metadata:
- help: "Allow annotations to accept type arguments; also allow generic function types as type arguments"
-
extension-types:
help: "Extension Types"
@@ -164,6 +161,12 @@
enabledIn: '2.0.0'
expired: true
+ generic-metadata:
+ help: >-
+ Allow annotations to accept type arguments;
+ also allow generic function types as type arguments.
+ enabledIn: '2.14.0'
+
set-literals:
help: "Set Literals"
enabledIn: '2.0.0'
diff --git a/utils/analysis_server/BUILD.gn b/utils/analysis_server/BUILD.gn
index 29c34d9..d8d0cea 100644
--- a/utils/analysis_server/BUILD.gn
+++ b/utils/analysis_server/BUILD.gn
@@ -4,13 +4,6 @@
import("../application_snapshot.gni")
-analysis_server_files = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../pkg/analysis_server"),
- ],
- "list lines")
-
application_snapshot("analysis_server") {
main_dart = "../../pkg/analysis_server/bin/server.dart"
training_args = [
@@ -19,5 +12,4 @@
# "--sdk=" + rebase_path("../../sdk/"),
# "--train-using=" + rebase_path("../../pkg/analyzer_cli")
]
- inputs = analysis_server_files
}
diff --git a/utils/application_snapshot.gni b/utils/application_snapshot.gni
index 890c108..7ecdf28 100644
--- a/utils/application_snapshot.gni
+++ b/utils/application_snapshot.gni
@@ -85,12 +85,15 @@
deps = extra_deps + [
"$_dart_root/runtime/vm:kernel_platform_files($host_toolchain)",
"$_dart_root/runtime/vm:vm_platform",
+ "$_dart_root/utils/gen_kernel:bootstrap_gen_kernel",
]
- gen_kernel_script = "$_dart_root/pkg/vm/bin/gen_kernel.dart"
+ gen_kernel_kernel =
+ get_label_info("$_dart_root/utils/gen_kernel:bootstrap_gen_kernel",
+ "target_gen_dir") + "/bootstrap_gen_kernel.dill"
platform_dill = "$root_out_dir/vm_platform_strong.dill"
inputs = extra_inputs + [
- gen_kernel_script,
+ gen_kernel_kernel,
platform_dill,
main_dart,
dot_packages,
@@ -99,18 +102,13 @@
outputs = [ output ]
depfile = "$output.d"
- abs_depfile = rebase_path(depfile)
- rebased_output = rebase_path(output, root_build_dir)
vm_args = [
- "--depfile=$abs_depfile",
- "--depfile_output_filename=$rebased_output",
-
# Ensure gen_kernel.dart will use this SDK hash when consuming/producing kernel.
"-Dsdk_hash=$sdk_hash",
]
- script = gen_kernel_script
+ script = gen_kernel_kernel
args = [
"--packages=" + rebase_path(dot_packages),
@@ -118,7 +116,8 @@
"--no-aot",
"--no-embed-sources",
"--no-link-platform",
- "--output=" + rebase_path(output),
+ "--output=" + rebase_path(output, root_build_dir),
+ "--depfile=" + rebase_path(depfile),
# Ensure the compiled appliation (e.g. kernel-service, frontend-server,
# ...) will use this SDK hash when consuming/producing kernel.
diff --git a/utils/bazel/BUILD.gn b/utils/bazel/BUILD.gn
index 774f301..6f6d3da 100644
--- a/utils/bazel/BUILD.gn
+++ b/utils/bazel/BUILD.gn
@@ -7,5 +7,4 @@
application_snapshot("kernel_worker") {
main_dart = "kernel_worker.dart"
training_args = [ "--help" ]
- deps = [ "../../pkg:pkg_files_stamp" ]
}
diff --git a/utils/dartanalyzer/BUILD.gn b/utils/dartanalyzer/BUILD.gn
index 78c84b0..0c007ab 100644
--- a/utils/dartanalyzer/BUILD.gn
+++ b/utils/dartanalyzer/BUILD.gn
@@ -4,6 +4,7 @@
import("../../build/dart/dart_action.gni")
import("../application_snapshot.gni")
+import("../create_timestamp.gni")
group("dartanalyzer") {
deps = [
@@ -12,13 +13,6 @@
]
}
-analyzer_files = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../pkg/analyzer"),
- ],
- "list lines")
-
application_snapshot("generate_dartanalyzer_snapshot") {
main_dart = "../../pkg/analyzer_cli/bin/analyzer.dart"
training_args = [
@@ -31,21 +25,21 @@
name = "dartanalyzer"
}
-sdk_lib_files = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../sdk/lib"),
- ],
- "list lines")
+sdk_root = "../../sdk"
+
+create_timestamp_file("sdk_lib_files") {
+ path = rebase_path("$sdk_root/lib")
+ output = "$target_gen_dir/sdk_lib_files.stamp"
+}
dart_action("generate_summary_strong") {
deps = [
+ ":sdk_lib_files",
"../../sdk:copy_libraries",
"../../sdk:write_version_file",
]
script = "../../pkg/analyzer/tool/summary/build_sdk_summaries.dart"
packages = "../../.packages"
- inputs = sdk_lib_files + analyzer_files
output = "$root_gen_dir/strong.sum"
outputs = [ output ]
vm_args = [ "-Dsdk_hash=$sdk_hash" ]
diff --git a/utils/dartdev/BUILD.gn b/utils/dartdev/BUILD.gn
index c7d8c12..7f33d99 100644
--- a/utils/dartdev/BUILD.gn
+++ b/utils/dartdev/BUILD.gn
@@ -4,13 +4,6 @@
import("../application_snapshot.gni")
-dartdev_files = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../pkg/dartdev"),
- ],
- "list lines")
-
group("dartdev") {
public_deps = [
":copy_dartdev_kernel",
@@ -30,7 +23,6 @@
main_dart = "../../pkg/dartdev/bin/dartdev.dart"
training_args = []
deps = [ "../dds:dds" ]
- inputs = dartdev_files
output = "$root_gen_dir/dartdev.dill"
}
@@ -45,6 +37,5 @@
main_dart = "../../pkg/dartdev/bin/dartdev.dart"
training_args = [ "--help" ]
deps = [ "../dds:dds" ]
- inputs = dartdev_files
output = "$root_gen_dir/dartdev.dart.snapshot"
}
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index 9b9f07c..74c0cc3 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -40,27 +40,6 @@
sdk_root = "../../sdk"
-sdk_lib_files = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("$sdk_root/lib"),
- ],
- "list lines")
-
-compiler_files = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../pkg/compiler"),
- ],
- "list lines")
-
-dev_compiler_files = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../pkg/dev_compiler"),
- ],
- "list lines")
-
template("dart2js_compile") {
assert(defined(invoker.main), "Must specify the main file")
main = invoker.main
@@ -70,12 +49,12 @@
abs_output = rebase_path(out)
prebuilt_dart_action(target_name) {
- deps = [ "../compiler:compile_dart2js_platform" ]
+ deps = invoker.deps + [ "../compiler:compile_dart2js_platform" ]
- inputs = sdk_lib_files + compiler_files + dev_compiler_files + [
- "$root_out_dir/dart2js_platform.dill",
- "$root_out_dir/dart2js_outline.dill",
- ]
+ inputs = [
+ "$root_out_dir/dart2js_platform.dill",
+ "$root_out_dir/dart2js_outline.dill",
+ ]
outputs = [ out ]
script = "../../pkg/compiler/lib/src/dart2js.dart"
@@ -97,6 +76,7 @@
dart2js_compile("stack_trace_mapper") {
main = rebase_path("../../pkg/dev_compiler/web/stack_trace_mapper.dart")
out = "$root_out_dir/dev_compiler/build/web/dart_stack_trace_mapper.js"
+ deps = [ ":dartdevc_files_stamp" ]
}
# Builds everything needed to run dartdevc tests using test.dart.
@@ -180,16 +160,11 @@
deps = [
":dartdevc_files_stamp",
platform_dep,
-
- # TODO(sigmund): depend only on the compiler and the actual files in the
- # package
- "../../pkg:pkg_files_stamp",
]
inputs = [
sdk_outline,
"$target_gen_dir/dartdevc_files.stamp",
- "$root_gen_dir/pkg_files.stamp",
]
outputs = [
@@ -327,17 +302,9 @@
}
prebuilt_dart_action(target_name) {
- deps = [
- ":dartdevc_files_stamp",
- "../../pkg:pkg_files_stamp",
- platform_dep,
- ]
+ deps = [ platform_dep ]
- inputs = [
- "$target_gen_dir/dartdevc_files.stamp",
- "$root_gen_dir/pkg_files.stamp",
- platform_input,
- ]
+ inputs = [ platform_input ]
outputs = [
"$js_gen_dir/amd/dart_sdk.js",
diff --git a/utils/dds/BUILD.gn b/utils/dds/BUILD.gn
index dd76925..2a5d36f 100644
--- a/utils/dds/BUILD.gn
+++ b/utils/dds/BUILD.gn
@@ -4,13 +4,6 @@
import("../application_snapshot.gni")
-dds_files = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../pkg/dds"),
- ],
- "list lines")
-
group("dds") {
public_deps = [ ":copy_dds_snapshot" ]
}
@@ -25,6 +18,5 @@
application_snapshot("generate_dds_snapshot") {
main_dart = "../../pkg/dds/bin/dds.dart"
training_args = []
- inputs = dds_files
output = "$root_gen_dir/dds.dart.snapshot"
}
diff --git a/utils/gen_kernel/BUILD.gn b/utils/gen_kernel/BUILD.gn
index a1417bb..0df5722 100644
--- a/utils/gen_kernel/BUILD.gn
+++ b/utils/gen_kernel/BUILD.gn
@@ -2,6 +2,43 @@
# 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("../../build/dart/dart_action.gni")
+import("../../sdk_args.gni")
+
+_dart_root = get_path_info("../..", "abspath")
+
+prebuilt_dart_action("bootstrap_gen_kernel") {
+ deps = [
+ "$_dart_root/runtime/vm:kernel_platform_files($host_toolchain)",
+ "$_dart_root/runtime/vm:vm_platform",
+ ]
+ gen_kernel_script = "$_dart_root/pkg/vm/bin/gen_kernel.dart"
+ platform_dill = "$root_out_dir/vm_platform_strong.dill"
+ dot_packages = rebase_path("$_dart_root/.packages")
+
+ inputs = [
+ gen_kernel_script,
+ platform_dill,
+ dot_packages,
+ ]
+ output = "$target_gen_dir/bootstrap_gen_kernel.dill"
+ outputs = [ output ]
+
+ depfile = "$output.d"
+ vm_args = [
+ "--snapshot-kind=kernel",
+ "--snapshot=" + rebase_path(output, root_build_dir),
+ "--depfile=" + rebase_path(depfile),
+
+ # Ensure gen_kernel.dart will use this SDK hash when consuming/producing kernel.
+ "-Dsdk_hash=$sdk_hash",
+
+ "--packages=" + rebase_path(dot_packages),
+ ]
+ script = gen_kernel_script
+ args = []
+}
+
import("../application_snapshot.gni")
application_snapshot("gen_kernel") {