Version 2.16.0-85.0.dev
Merge commit '0d98f6ab5d56505033f0b3b29c8bb46f85461011' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index a6ff620..21f5f37 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -7,6 +7,7 @@
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -100,7 +101,9 @@
if (_isEditingNamedArgLabel() ||
_isAppendingToArgList() ||
_isAddingLabelToPositional()) {
- if (requiredCount == 0 || requiredCount < _argCount()) {
+ if (request.featureSet.isEnabled(Feature.named_arguments_anywhere) ||
+ requiredCount == 0 ||
+ requiredCount < _argCount()) {
// If there's a replacement range that starts at the caret, it will be
// for an identifier that is not the named label and therefore it should
// not be replaced.
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index c2e4e39..2e8d400 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -221,7 +221,7 @@
for (var multiGenerator in multiGenerators) {
var multiProducer = multiGenerator();
multiProducer.configure(context);
- for (var producer in multiProducer.producers) {
+ await for (var producer in multiProducer.producers) {
await compute(producer);
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index 0b6145c..4303a94 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -383,7 +383,7 @@
for (var multiGenerator in multiGenerators) {
var multiProducer = multiGenerator();
multiProducer.configure(context);
- for (var producer in multiProducer.producers) {
+ await for (var producer in multiProducer.producers) {
await _generateFix(context, producer, codeName);
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 56442ae..03e3a19 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -302,7 +302,7 @@
/// assists).
abstract class MultiCorrectionProducer extends _AbstractCorrectionProducer {
/// Return each of the individual producers generated by this producer.
- Iterable<CorrectionProducer> get producers;
+ Stream<CorrectionProducer> get producers;
}
/// An object that can compute a correction (fix or assist) in a Dart file.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart
index 1f11731..04adf5d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_missing_parameter.dart
@@ -11,7 +11,7 @@
class AddMissingParameter extends MultiCorrectionProducer {
@override
- Iterable<CorrectionProducer> get producers sync* {
+ Stream<CorrectionProducer> get producers async* {
// node is the unmatched argument.
var argumentList = node.parent;
if (argumentList is! ArgumentList) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart
index fa1537b..86f5968 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_super_constructor_invocation.dart
@@ -13,7 +13,7 @@
class AddSuperConstructorInvocation extends MultiCorrectionProducer {
@override
- Iterable<CorrectionProducer> get producers sync* {
+ Stream<CorrectionProducer> get producers async* {
var targetConstructor = node.parent;
if (targetConstructor is! ConstructorDeclaration) {
return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
index 0442afb..54c57a4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_argument_name.dart
@@ -17,7 +17,7 @@
static const _maxDistance = 4;
@override
- Iterable<CorrectionProducer> get producers sync* {
+ Stream<CorrectionProducer> get producers async* {
var namedContext = _getNamedParameterNames();
if (namedContext == null) {
return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart
index a40ed18..98ac8d5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_super.dart
@@ -12,7 +12,7 @@
class CreateConstructorSuper extends MultiCorrectionProducer {
@override
- Iterable<CorrectionProducer> get producers sync* {
+ Stream<CorrectionProducer> get producers async* {
var targetClassNode = node.thisOrAncestorOfType<ClassDeclaration>();
if (targetClassNode == null) {
return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart b/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
index 9dbbac9..029d157 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart
@@ -21,7 +21,7 @@
static List<TransformSet>? transformSetsForTests;
@override
- Iterable<CorrectionProducer> get producers sync* {
+ Stream<CorrectionProducer> get producers async* {
var importedUris = <Uri>[];
var library = resolvedResult.libraryElement;
for (var importElement in library.imports) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart
index 318a934..94a7a71 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_wrap.dart
@@ -15,7 +15,7 @@
class FlutterWrap extends MultiCorrectionProducer {
@override
- Iterable<CorrectionProducer> get producers sync* {
+ Stream<CorrectionProducer> get producers async* {
var widgetExpr = flutter.identifyWidgetExpression(node);
if (widgetExpr != null) {
var widgetType = widgetExpr.typeOrThrow;
@@ -36,7 +36,7 @@
yield* _wrapMultipleWidgets();
}
- Iterable<CorrectionProducer> _wrapMultipleWidgets() sync* {
+ Stream<CorrectionProducer> _wrapMultipleWidgets() async* {
var selectionRange = SourceRange(selectionOffset, selectionLength);
var analyzer = SelectionAnalyzer(selectionRange);
resolvedResult.unit.accept(analyzer);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
index 4a949c4..4b1ea14 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
@@ -27,7 +27,7 @@
ImportLibrary(this._importKind);
@override
- Iterable<CorrectionProducer> get producers sync* {
+ Stream<CorrectionProducer> get producers async* {
final node = this.node;
if (_importKind == _ImportKind.dartAsync) {
yield* _importLibrary(DartFixKind.IMPORT_ASYNC, Uri.parse('dart:async'));
@@ -42,8 +42,8 @@
} else if (_importKind == _ImportKind.forExtensionMember) {
/// Return producers that will import extensions that apply to the
/// [targetType] and that define a member with the given [memberName].
- Iterable<CorrectionProducer> importMatchingExtensions(
- String memberName, DartType? targetType) sync* {
+ Stream<CorrectionProducer> importMatchingExtensions(
+ String memberName, DartType? targetType) async* {
if (targetType == null) {
return;
}
@@ -151,8 +151,8 @@
return false;
}
- Iterable<CorrectionProducer> _importExtensionInLibrary(
- Uri uri, DartType targetType, String memberName) sync* {
+ Stream<CorrectionProducer> _importExtensionInLibrary(
+ Uri uri, DartType targetType, String memberName) async* {
// Look to see whether the library at the [uri] is already imported. If it
// is, then we can check the extension elements without needing to perform
// additional analysis.
@@ -197,31 +197,33 @@
/// path and a correction with a relative path are returned. If the
/// `prefer_relative_imports` lint rule is enabled, the relative path is
/// returned first.
- Iterable<CorrectionProducer> _importLibrary(
+ Stream<CorrectionProducer> _importLibrary(
FixKind fixKind,
Uri library, {
bool includeRelativeFix = false,
}) {
if (!includeRelativeFix) {
- return [_ImportAbsoluteLibrary(fixKind, library)];
+ return Stream.fromIterable([
+ _ImportAbsoluteLibrary(fixKind, library),
+ ]);
}
if (isLintEnabled(LintNames.prefer_relative_imports)) {
- return [
+ return Stream.fromIterable([
_ImportRelativeLibrary(fixKind, library),
_ImportAbsoluteLibrary(fixKind, library),
- ];
+ ]);
} else {
- return [
+ return Stream.fromIterable([
_ImportAbsoluteLibrary(fixKind, library),
_ImportRelativeLibrary(fixKind, library),
- ];
+ ]);
}
}
- Iterable<CorrectionProducer> _importLibraryForElement(
+ Stream<CorrectionProducer> _importLibraryForElement(
String name,
List<ElementKind> elementKinds,
- List<TopLevelDeclarationKind> kinds2) sync* {
+ List<TopLevelDeclarationKind> kinds2) async* {
// ignore if private
if (name.startsWith('_')) {
return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart b/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart
index 84d8648..87abf94 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/surround_with.dart
@@ -12,7 +12,7 @@
class SurroundWith extends MultiCorrectionProducer {
@override
- Iterable<CorrectionProducer> get producers sync* {
+ Stream<CorrectionProducer> get producers async* {
// If the node is the CompilationUnit, the selected statements must span multiple
// top level items and cannot be surrounded with anything.
if (node is CompilationUnit) {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 26bcfbd..c6fa293 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -1359,7 +1359,7 @@
for (var multiGenerator in multiGenerators) {
var multiProducer = multiGenerator();
multiProducer.configure(context);
- for (var producer in multiProducer.producers) {
+ await for (var producer in multiProducer.producers) {
await compute(producer);
}
}
diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart
index b733540..4cb6d42 100644
--- a/pkg/analysis_server/lib/src/utilities/flutter.dart
+++ b/pkg/analysis_server/lib/src/utilities/flutter.dart
@@ -72,64 +72,20 @@
return null;
}
- void convertChildToChildren(
- InstanceCreationExpression childArg,
- NamedExpression namedExp,
- String eol,
- Function getNodeText,
- Function getLinePrefix,
- Function getIndent,
- Function getText,
- Function _addInsertEdit,
- Function _addRemoveEdit,
- Function _addReplaceEdit,
- Function rangeNode) {
- var childLoc = namedExp.offset + 'child'.length;
- _addInsertEdit(childLoc, 'ren');
- var listLoc = childArg.offset;
- String childArgSrc = getNodeText(childArg);
- if (!childArgSrc.contains(eol)) {
- _addInsertEdit(listLoc, '[');
- _addInsertEdit(listLoc + childArg.length, ']');
- } else {
- var newlineLoc = childArgSrc.lastIndexOf(eol);
- if (newlineLoc == childArgSrc.length) {
- newlineLoc -= 1;
- }
- String indentOld =
- getLinePrefix(childArg.offset + eol.length + newlineLoc);
- var indentNew = '$indentOld${getIndent(1)}';
- // The separator includes 'child:' but that has no newlines.
- String separator =
- getText(namedExp.offset, childArg.offset - namedExp.offset);
- var prefix = separator.contains(eol) ? '' : '$eol$indentNew';
- if (prefix.isEmpty) {
- _addInsertEdit(namedExp.offset + 'child:'.length, ' [');
- _addRemoveEdit(SourceRange(childArg.offset - 2, 2));
- } else {
- _addInsertEdit(listLoc, '[');
- }
- var newChildArgSrc = childArgSrc.replaceAll(
- RegExp('^$indentOld', multiLine: true), '$indentNew');
- newChildArgSrc = '$prefix$newChildArgSrc,$eol$indentOld]';
- _addReplaceEdit(rangeNode(childArg), newChildArgSrc);
- }
- }
-
void convertChildToChildren2(
DartFileEditBuilder builder,
Expression childArg,
NamedExpression namedExp,
String eol,
- Function getNodeText,
- Function getLinePrefix,
- Function getIndent,
- Function getText,
- Function rangeNode) {
+ String Function(Expression) getNodeText,
+ String Function(int) getLinePrefix,
+ String Function(int) getIndent,
+ String Function(int, int) getText,
+ SourceRange Function(Expression) rangeNode) {
var childLoc = namedExp.offset + 'child'.length;
builder.addSimpleInsertion(childLoc, 'ren');
var listLoc = childArg.offset;
- String childArgSrc = getNodeText(childArg);
+ var childArgSrc = getNodeText(childArg);
if (!childArgSrc.contains(eol)) {
builder.addSimpleInsertion(listLoc, '[');
builder.addSimpleInsertion(listLoc + childArg.length, ']');
@@ -138,11 +94,10 @@
if (newlineLoc == childArgSrc.length) {
newlineLoc -= 1;
}
- String indentOld =
- getLinePrefix(childArg.offset + eol.length + newlineLoc);
+ var indentOld = getLinePrefix(childArg.offset + eol.length + newlineLoc);
var indentNew = '$indentOld${getIndent(1)}';
// The separator includes 'child:' but that has no newlines.
- String separator =
+ var separator =
getText(namedExp.offset, childArg.offset - namedExp.offset);
var prefix = separator.contains(eol) ? '' : '$eol$indentNew';
if (prefix.isEmpty) {
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 4c2e182..c2d8833 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -172,6 +172,15 @@
assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'one': 'int'});
}
+ Future<void> test_Annotation_local_constructor_named_param_12() async {
+ addTestSource('''
+class A { const A(int one, int two, int three, {int four, String five:
+ 'defaultValue'}); }
+@A(1, ^, 3) main() { }''');
+ await computeSuggestions();
+ assertSuggestions(['four: ', 'five: ']);
+ }
+
Future<void> test_Annotation_local_constructor_named_param_2() async {
addTestSource('''
class A { const A({int one, String two: 'defaultValue'}); }
@@ -239,6 +248,7 @@
Future<void> test_Annotation_local_constructor_named_param_negative() async {
addTestSource('''
+// @dart = 2.15
class A { const A(int one, int two, int three, {int four, String five:
'defaultValue'}); }
@A(1, ^, 3) main() { }''');
@@ -660,6 +670,7 @@
expect(String arg1, int arg2, {bool arg3}) { }
void baz() { }''');
addTestSource('''
+ // @dart = 2.15
import 'a.dart'
class B { }
String bar() => true;
@@ -676,6 +687,7 @@
expect(String arg1, int arg2, {bool arg3}) { }
void baz() { }''');
addTestSource('''
+ // @dart = 2.15
import 'a.dart'
class B { }
String bar() => true;
@@ -692,6 +704,7 @@
expect(String arg1, int arg2, {bool arg3}) { }
void baz() { }''');
addTestSource('''
+ // @dart = 2.15
import 'a.dart'
class B { }
String bar() => true;
@@ -708,6 +721,7 @@
expect(String arg1, int arg2, {bool arg3}) { }
void baz() { }''');
addTestSource('''
+ // @dart = 2.15
import 'a.dart'
class B { }
String bar() => true;
@@ -987,6 +1001,7 @@
Future<void> test_ArgumentList_local_function_3a() async {
// ArgumentList MethodInvocation ExpressionStatement Block
addTestSource('''
+ // @dart = 2.15
expect(arg1, int arg2, {bool arg3}) { }
class B { }
String bar() => true;
@@ -998,6 +1013,7 @@
Future<void> test_ArgumentList_local_function_3b() async {
// ArgumentList MethodInvocation ExpressionStatement Block
addTestSource('''
+ // @dart = 2.15
expect(arg1, int arg2, {bool arg3}) { }
class B { }
String bar() => true;
@@ -1009,6 +1025,7 @@
Future<void> test_ArgumentList_local_function_3c() async {
// ArgumentList MethodInvocation ExpressionStatement Block
addTestSource('''
+ // @dart = 2.15
expect(arg1, int arg2, {bool arg3}) { }
class B { }
String bar() => true;
@@ -1020,6 +1037,7 @@
Future<void> test_ArgumentList_local_function_3d() async {
// ArgumentList MethodInvocation ExpressionStatement Block
addTestSource('''
+ // @dart = 2.15
expect(arg1, int arg2, {bool arg3}) { }
class B { }
String bar() => true;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index 50411cb..a929b5e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -264,8 +264,7 @@
Future<void> addUnimportedFile(String filePath, String content) async {
addSource(filePath, content);
- var result = await session.getResolvedUnit(convertPath(filePath));
- extensionCache.cacheFromResult(result as ResolvedUnitResult);
+ await cacheExtensionsForFile(filePath);
}
Future<void> assertHasFix(String expected,
@@ -378,6 +377,11 @@
await _assertNoFixAllFix(error);
}
+ Future<void> cacheExtensionsForFile(String path) async {
+ var result = await session.getResolvedUnit(convertPath(path));
+ extensionCache.cacheFromResult(result as ResolvedUnitResult);
+ }
+
List<LinkedEditSuggestion> expectedSuggestions(
LinkedEditSuggestionKind kind, List<String> values) {
return values.map((value) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
index a677f3a..be2de8f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -234,6 +234,48 @@
''');
}
+ @FailingTest(reason: 'We suggest importing src/b.dart')
+ Future<void> test_extension_otherPackage_exported_fromSrc() async {
+ var pkgRootPath = '/.pub-cache/aaa';
+
+ var a = newFile('$pkgRootPath/lib/a.dart', content: r'''
+export 'src/b.dart';
+''');
+
+ var b = newFile('$pkgRootPath/lib/src/b.dart', content: r'''
+extension IntExtension on int {
+ int get foo => 0;
+}
+''');
+
+ writeTestPackageConfig(
+ config: PackageConfigFileBuilder()
+ ..add(name: 'aaa', rootPath: pkgRootPath),
+ );
+
+ updateTestPubspecFile('''
+dependencies:
+ aaa: any
+''');
+
+ await cacheExtensionsForFile(a.path);
+ await cacheExtensionsForFile(b.path);
+
+ await resolveTestCode('''
+void f() {
+ 0.foo;
+}
+''');
+
+ await assertHasFix('''
+import 'package:aaa/a.dart';
+
+void f() {
+ 0.foo;
+}
+''');
+ }
+
Future<void> test_invalidUri_interpolation() async {
addSource('$testPackageLibPath/lib.dart', r'''
class Test {
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index a376881..bf9af56 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -1577,7 +1577,9 @@
/// The declaration of an enumeration.
///
/// enumType ::=
-/// metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier] (',' [SimpleIdentifier])* (',')? '}'
+/// metadata 'enum' [SimpleIdentifier] [TypeParameterList]?
+/// [WithClause]? [ImplementsClause]? '{' [SimpleIdentifier]
+/// (',' [SimpleIdentifier])* (';' [ClassMember]+)? '}'
///
/// Clients may not extend, implement or mix-in this class.
abstract class EnumDeclaration implements NamedCompilationUnitMember {
@@ -1590,6 +1592,10 @@
/// Return the 'enum' keyword.
Token get enumKeyword;
+ /// Returns the `implements` clause for the enumeration, or `null` if the
+ /// enumeration does not implement any interfaces.
+ ImplementsClause? get implementsClause;
+
/// Return the left curly bracket.
Token get leftBracket;
@@ -1601,6 +1607,14 @@
/// Return the right curly bracket.
Token get rightBracket;
+
+ /// Returns the type parameters for the enumeration, or `null` if the
+ /// enumeration does not have any type parameters.
+ TypeParameterList? get typeParameters;
+
+ /// Return the `with` clause for the enumeration, or `null` if the
+ /// enumeration does not have a `with` clause.
+ WithClause? get withClause;
}
/// An export directive.
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index f4c31cb..29187a7 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -301,6 +301,7 @@
/// [comment] and [metadata] can be `null` if the declaration does not have
/// the corresponding attribute. The list of [constants] must contain at least
/// one value.
+ @Deprecated('Use enumDeclaration2() instead')
EnumDeclaration enumDeclaration(
Comment? comment,
List<Annotation>? metadata,
@@ -308,9 +309,26 @@
SimpleIdentifier name,
Token leftBracket,
List<EnumConstantDeclaration> constants,
- List<ClassMember> members,
Token rightBracket);
+ /// Returns a newly created enumeration declaration. Either or both of the
+ /// [comment] and [metadata] can be `null` if the declaration does not have
+ /// the corresponding attribute. The list of [constants] must contain at least
+ /// one value.
+ EnumDeclaration enumDeclaration2({
+ required Comment? comment,
+ required List<Annotation>? metadata,
+ required Token enumKeyword,
+ required SimpleIdentifier name,
+ required TypeParameterList? typeParameters,
+ required WithClause? withClause,
+ required ImplementsClause? implementsClause,
+ required Token leftBracket,
+ required List<EnumConstantDeclaration> constants,
+ required List<ClassMember> members,
+ required Token rightBracket,
+ });
+
/// Returns a newly created export directive. Either or both of the
/// [comment] and [metadata] can be `null` if the directive does not have the
/// corresponding attribute. The list of [combinators] can be `null` if there
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 532447a..2c3364c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -873,7 +873,7 @@
File resource = _resourceProvider.getFile(path);
- var rewrittenUri = rewriteFileToPackageUri(_sourceFactory, uri);
+ var rewrittenUri = rewriteToCanonicalUri(_sourceFactory, uri);
if (rewrittenUri == null) {
return Either2.t1(null);
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index beabb03..ce3f0b2 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -783,7 +783,7 @@
}
var absoluteUri = resolveRelativeUri(_library.uri, relativeUri);
- return rewriteFileToPackageUri(_sourceFactory, absoluteUri);
+ return rewriteToCanonicalUri(_sourceFactory, absoluteUri);
}
/// Return the result of resolve the given [uriContent], reporting errors
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 3ab0730..176f6e4 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -3286,14 +3286,27 @@
/// The declaration of an enumeration.
///
/// enumType ::=
-/// metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier]
-/// (',' [SimpleIdentifier])* (',')? '}'
+/// metadata 'enum' [SimpleIdentifier] [TypeParameterList]?
+/// [WithClause]? [ImplementsClause]? '{' [SimpleIdentifier]
+/// (',' [SimpleIdentifier])* (';' [ClassMember]+)? '}'
class EnumDeclarationImpl extends NamedCompilationUnitMemberImpl
implements EnumDeclaration {
/// The 'enum' keyword.
@override
Token enumKeyword;
+ /// The type parameters, or `null` if the enumeration does not have any
+ /// type parameters.
+ TypeParameterListImpl? _typeParameters;
+
+ /// The `with` clause for the enumeration, or `null` if the class does not
+ /// have a `with` clause.
+ WithClauseImpl? _withClause;
+
+ /// The `implements` clause for the enumeration, or `null` if the enumeration
+ /// does not implement any interfaces.
+ ImplementsClauseImpl? _implementsClause;
+
/// The left curly bracket.
@override
Token leftBracket;
@@ -3317,11 +3330,17 @@
List<Annotation>? metadata,
this.enumKeyword,
SimpleIdentifierImpl name,
+ this._typeParameters,
+ this._withClause,
+ this._implementsClause,
this.leftBracket,
List<EnumConstantDeclaration> constants,
List<ClassMember> members,
this.rightBracket)
: super(comment, metadata, name) {
+ _becomeParentOf(_typeParameters);
+ _becomeParentOf(_withClause);
+ _becomeParentOf(_implementsClause);
_constants._initialize(this, constants);
_members._initialize(this, members);
}
@@ -3331,6 +3350,9 @@
Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(enumKeyword)
..add(_name)
+ ..add(_typeParameters)
+ ..add(_withClause)
+ ..add(_implementsClause)
..add(leftBracket)
..addAll(_constants)
..addAll(_members)
@@ -3349,15 +3371,40 @@
Token get firstTokenAfterCommentAndMetadata => enumKeyword;
@override
+ ImplementsClauseImpl? get implementsClause => _implementsClause;
+
+ set implementsClause(ImplementsClause? implementsClause) {
+ _implementsClause =
+ _becomeParentOf(implementsClause as ImplementsClauseImpl?);
+ }
+
+ @override
NodeListImpl<ClassMember> get members => _members;
@override
+ TypeParameterListImpl? get typeParameters => _typeParameters;
+
+ set typeParameters(TypeParameterList? typeParameters) {
+ _typeParameters = _becomeParentOf(typeParameters as TypeParameterListImpl?);
+ }
+
+ @override
+ WithClauseImpl? get withClause => _withClause;
+
+ set withClause(WithClause? withClause) {
+ _withClause = _becomeParentOf(withClause as WithClauseImpl?);
+ }
+
+ @override
E? accept<E>(AstVisitor<E> visitor) => visitor.visitEnumDeclaration(this);
@override
void visitChildren(AstVisitor visitor) {
super.visitChildren(visitor);
_name.accept(visitor);
+ _typeParameters?.accept(visitor);
+ _withClause?.accept(visitor);
+ _implementsClause?.accept(visitor);
_constants.accept(visitor);
_members.accept(visitor);
}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index b7a9b76..e1f0415 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -383,6 +383,7 @@
EnumConstantDeclarationImpl(
comment as CommentImpl?, metadata, name as SimpleIdentifierImpl);
+ @Deprecated('Use enumDeclaration2() instead')
@override
EnumDeclarationImpl enumDeclaration(
Comment? comment,
@@ -391,17 +392,48 @@
SimpleIdentifier name,
Token leftBracket,
List<EnumConstantDeclaration> constants,
- List<ClassMember> members,
Token rightBracket) =>
- EnumDeclarationImpl(
- comment as CommentImpl?,
- metadata,
- enumKeyword,
- name as SimpleIdentifierImpl,
- leftBracket,
- constants,
- members,
- rightBracket);
+ enumDeclaration2(
+ comment: comment,
+ metadata: metadata,
+ enumKeyword: enumKeyword,
+ name: name,
+ typeParameters: null,
+ withClause: null,
+ implementsClause: null,
+ leftBracket: leftBracket,
+ constants: constants,
+ members: [],
+ rightBracket: rightBracket);
+
+ @override
+ EnumDeclarationImpl enumDeclaration2({
+ required Comment? comment,
+ required List<Annotation>? metadata,
+ required Token enumKeyword,
+ required SimpleIdentifier name,
+ required TypeParameterList? typeParameters,
+ required WithClause? withClause,
+ required ImplementsClause? implementsClause,
+ required Token leftBracket,
+ required List<EnumConstantDeclaration> constants,
+ required List<ClassMember> members,
+ required Token rightBracket,
+ }) {
+ return EnumDeclarationImpl(
+ comment as CommentImpl?,
+ metadata,
+ enumKeyword,
+ name as SimpleIdentifierImpl,
+ typeParameters as TypeParameterListImpl?,
+ withClause as WithClauseImpl?,
+ implementsClause as ImplementsClauseImpl?,
+ leftBracket,
+ constants,
+ members,
+ rightBracket,
+ );
+ }
@override
ExportDirectiveImpl exportDirective(
diff --git a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
index 49dff85..d31ae43 100644
--- a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
@@ -314,8 +314,12 @@
_visitNodeList(node.metadata, separator: ' ', suffix: ' ');
sink.write('enum ');
_visitNode(node.name);
+ _visitNode(node.typeParameters);
+ _visitNode(node.withClause, prefix: ' ');
+ _visitNode(node.implementsClause, prefix: ' ');
sink.write(' {');
_visitNodeList(node.constants, separator: ', ');
+ _visitNodeList(node.members, prefix: '; ', separator: ' ');
sink.write('}');
}
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 3bbe4f6..308fad828 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -2002,8 +2002,19 @@
if (identical(node.name, _oldNode)) {
node.name = _newNode as SimpleIdentifier;
return true;
+ } else if (identical(node.typeParameters, _oldNode)) {
+ node.typeParameters = _newNode as TypeParameterList;
+ return true;
+ } else if (identical(node.withClause, _oldNode)) {
+ node.withClause = _newNode as WithClause;
+ return true;
+ } else if (identical(node.implementsClause, _oldNode)) {
+ node.implementsClause = _newNode as ImplementsClause;
+ return true;
} else if (_replaceInList(node.constants)) {
return true;
+ } else if (_replaceInList(node.members)) {
+ return true;
}
return visitAnnotatedNode(node);
}
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 6cfd05b..dea89e7 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -2813,8 +2813,21 @@
);
}
- declarations.add(enumDeclaration = ast.enumDeclaration(comment, metadata,
- enumKeyword, name, leftBrace, [], [], leftBrace.endGroup!));
+ declarations.add(
+ enumDeclaration = ast.enumDeclaration2(
+ comment: comment,
+ metadata: metadata,
+ enumKeyword: enumKeyword,
+ name: name,
+ typeParameters: typeParameters,
+ withClause: withClause,
+ implementsClause: implementsClause,
+ leftBracket: leftBrace,
+ constants: [],
+ members: [],
+ rightBracket: leftBrace.endGroup!,
+ ),
+ );
}
@override
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index e05cbc0..fec2395 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -458,30 +458,6 @@
static EmptyStatementImpl emptyStatement() => astFactory
.emptyStatement(TokenFactory.tokenFromType(TokenType.SEMICOLON));
- static EnumDeclarationImpl enumDeclaration(
- SimpleIdentifier name, List<EnumConstantDeclaration> constants) =>
- astFactory.enumDeclaration(
- null,
- null,
- TokenFactory.tokenFromKeyword(Keyword.ENUM),
- name,
- TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET),
- constants,
- [],
- TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
-
- static EnumDeclarationImpl enumDeclaration2(
- String name, List<String> constantNames) {
- var constants = constantNames.map((name) {
- return astFactory.enumConstantDeclaration(
- null,
- null,
- identifier3(name),
- );
- }).toList();
- return enumDeclaration(identifier3(name), constants);
- }
-
static ExportDirectiveImpl exportDirective(
List<Annotation> metadata, String uri,
[List<Combinator> combinators = const []]) =>
diff --git a/pkg/analyzer/lib/src/lint/pub.dart b/pkg/analyzer/lib/src/lint/pub.dart
index 8c11a57..be9b149 100644
--- a/pkg/analyzer/lib/src/lint/pub.dart
+++ b/pkg/analyzer/lib/src/lint/pub.dart
@@ -37,6 +37,12 @@
PSGitRepo? _processGitRepo(
YamlScalar key, YamlNode v, ResourceProvider? resourceProvider) {
+ if (v is YamlScalar) {
+ _PSGitRepo repo = _PSGitRepo();
+ repo.token = _PSNode(key, resourceProvider);
+ repo.url = PSEntry(repo.token, _PSNode(v, resourceProvider));
+ return repo;
+ }
if (v is! YamlMap) {
return null;
}
@@ -130,9 +136,44 @@
String toString() => '${key != null ? (key.toString() + ': ') : ''}$value';
}
+/// Representation of git-dependency in `pubspec.yaml`.
+///
+/// **Example** of a git-dependency:
+/// ```yaml
+/// dependencies:
+/// foo:
+/// git: # <-- this is the [token] property
+/// url: https://github.com/example/example
+/// ref: main # ref is optional
+/// ```
+///
+/// This may also be written in the form:
+/// ```yaml
+/// dependencies:
+/// foo:
+/// git: https://github.com/example/example
+/// # ^-token ^--url
+/// # In this case [ref] is `null`.
+/// ```
abstract class PSGitRepo {
+ /// [PSEntry] for `ref: main` where [PSEntry.key] is `ref` and [PSEntry.value]
+ /// is `main`.
PSEntry? get ref;
+
+ /// The `'git'` from the `pubspec.yaml`, this is the key that indicates this
+ /// is a git-dependency.
PSNode? get token;
+
+ /// [PSEntry] for `url: https://...` or `git: https://`, where [PSEntry.key]
+ /// is either `url` or `git`, and [PSEntry.key] is the URL.
+ ///
+ /// If the git-dependency is given in the form:
+ /// ```yaml
+ /// dependencies:
+ /// foo:
+ /// git: https://github.com/example/example
+ /// ```
+ /// Then [token] and [url.key] will be the same object.
PSEntry? get url;
}
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 8d6599b..af3cdb7 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -1009,7 +1009,7 @@
var absoluteUri = resolveRelativeUri(_libraryBuilder.uri, relativeUri);
var sourceFactory = _linker.analysisContext.sourceFactory;
- return rewriteFileToPackageUri(sourceFactory, absoluteUri);
+ return rewriteToCanonicalUri(sourceFactory, absoluteUri);
}
LibraryElement? _selectLibrary(NamespaceDirective node) {
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index 3c22e00..a248815 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -123,6 +123,10 @@
return _node(search, (n) => n is DoubleLiteral);
}
+ EnumConstantDeclaration enumConstantDeclaration(String search) {
+ return _node(search, (n) => n is EnumConstantDeclaration);
+ }
+
EnumDeclaration enumDeclaration(String search) {
return _node(search, (n) => n is EnumDeclaration);
}
diff --git a/pkg/analyzer/lib/src/util/uri.dart b/pkg/analyzer/lib/src/util/uri.dart
index 08e3008..4d60895 100644
--- a/pkg/analyzer/lib/src/util/uri.dart
+++ b/pkg/analyzer/lib/src/util/uri.dart
@@ -13,23 +13,10 @@
return path;
}
-/// If the [absoluteUri] is a `file` URI that has corresponding `package` URI,
-/// return it. If the URI is not valid, e.g. has empty path segments, so
-/// does not represent a valid file path, return `null`.
-Uri? rewriteFileToPackageUri(SourceFactory sourceFactory, Uri absoluteUri) {
- // Only file URIs get rewritten into package URIs.
- if (!absoluteUri.isScheme('file')) {
- return absoluteUri;
- }
-
- // It must be a valid URI, e.g. `file:///home/` is not.
- var pathSegments = absoluteUri.pathSegments;
- if (pathSegments.isEmpty || pathSegments.last.isEmpty) {
- return null;
- }
-
- // We ask for Source only because `restoreUri` needs it.
- // TODO(scheglov) Add more direct way to convert a path to URI.
+/// Return the canonical URI for the given [absoluteUri], for example a `file`
+/// URI to the corresponding `package` URI. If the URI is not valid, so does
+/// not represent a valid file path, return `null`.
+Uri? rewriteToCanonicalUri(SourceFactory sourceFactory, Uri absoluteUri) {
var source = sourceFactory.forUri2(absoluteUri);
if (source == null) {
return null;
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index b4ff551..348bd17 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1649,12 +1649,44 @@
}
void test_enumDeclaration() {
- var node = AstTestFactory.enumDeclaration2("E", ["ONE", "TWO"]);
- node.documentationComment = astFactory.endOfLineComment(EMPTY_TOKEN_LIST);
- node.metadata
- .add(AstTestFactory.annotation(AstTestFactory.identifier3("a")));
- _assertReplace(node, Getter_NodeReplacerTest_test_enumDeclaration());
- _testAnnotatedNode(node);
+ var findNode = _parseStringToFindNode(r'''
+enum E1<T> with M1 implements I1 {one, two}
+enum E2<U> with M2 implements I2 {one, two}
+''');
+ _assertReplace2<EnumDeclaration>(
+ destination: findNode.enumDeclaration('enum E1'),
+ source: findNode.enumDeclaration('enum E2'),
+ getters: [
+ (node) => node.name,
+ (node) => node.typeParameters!,
+ (node) => node.withClause!,
+ (node) => node.implementsClause!,
+ ],
+ );
+ }
+
+ void test_enumDeclaration_constants() {
+ var findNode = _parseStringToFindNode(r'''
+enum E1 {one}
+enum E2 {two}
+''');
+ _assertReplaceInList(
+ destination: findNode.enumDeclaration('enum E1'),
+ child: findNode.enumConstantDeclaration('one'),
+ replacement: findNode.enumConstantDeclaration('two'),
+ );
+ }
+
+ void test_enumDeclaration_members() {
+ var findNode = _parseStringToFindNode(r'''
+enum E1 {one; void foo() {}}
+enum E2 {two; void bar() {}}
+''');
+ _assertReplaceInList(
+ destination: findNode.enumDeclaration('enum E1'),
+ child: findNode.methodDeclaration('foo'),
+ replacement: findNode.methodDeclaration('bar'),
+ );
}
void test_exportDirective() {
@@ -2303,12 +2335,24 @@
}
}
+ void _assertReplaceInList({
+ required AstNode destination,
+ required AstNode child,
+ required AstNode replacement,
+ }) {
+ expect(child.parent, destination);
+
+ NodeReplacer.replace(child, replacement);
+ expect(replacement.parent, destination);
+ }
+
FindNode _parseStringToFindNode(String content) {
var parseResult = parseString(
content: content,
featureSet: FeatureSet.fromEnableFlags2(
sdkLanguageVersion: ExperimentStatus.currentVersion,
flags: [
+ Feature.enhanced_enums.enableString,
Feature.super_parameters.enableString,
],
),
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 252bab2..8568ee0 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -28,12 +28,14 @@
import '../../../util/element_type_matchers.dart';
import '../../../utils.dart';
+import '../resolution/context_collection_resolution.dart';
import 'base.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(AnalysisDriverSchedulerTest);
defineReflectiveTests(AnalysisDriverTest);
+ defineReflectiveTests(AnalysisDriver_BazelWorkspaceTest);
});
}
@@ -50,6 +52,59 @@
}
@reflectiveTest
+class AnalysisDriver_BazelWorkspaceTest extends BazelWorkspaceResolutionTest {
+ void test_nestedLib_notCanonicalUri() async {
+ var outerLibPath = '$workspaceRootPath/my/outer/lib';
+
+ var innerPath = convertPath('$outerLibPath/inner/lib/b.dart');
+ var innerUri = Uri.parse('package:my.outer.lib.inner/b.dart');
+ newFile(innerPath, content: 'class B {}');
+
+ var analysisSession = contextFor(innerPath).currentSession;
+
+ void assertInnerUri(ResolvedUnitResult result) {
+ var innerLibrary = result.libraryElement.importedLibraries
+ .where((e) => e.source.fullName == innerPath)
+ .single;
+ expect(innerLibrary.source.uri, innerUri);
+ }
+
+ // Reference "inner" using a non-canonical URI.
+ {
+ var path = convertPath('$outerLibPath/a.dart');
+ newFile(path, content: r'''
+import 'inner/lib/b.dart';
+''');
+ var result = await analysisSession.getResolvedUnit(path);
+ result as ResolvedUnitResult;
+ assertInnerUri(result);
+ }
+
+ // Reference "inner" using the canonical URI, via relative.
+ {
+ var path = '$outerLibPath/inner/lib/c.dart';
+ newFile(path, content: r'''
+import 'b.dart';
+''');
+ var result = await analysisSession.getResolvedUnit(path);
+ result as ResolvedUnitResult;
+ assertInnerUri(result);
+ }
+
+ // Reference "inner" using the canonical URI, via absolute.
+ {
+ var path = '$outerLibPath/inner/lib/d.dart';
+ newFile(path, content: '''
+import '$innerUri';
+''');
+ var result = await analysisSession.getResolvedUnit(path);
+ result as ResolvedUnitResult;
+ assertInnerUri(result);
+ }
+ }
+}
+
+@reflectiveTest
class AnalysisDriverSchedulerTest with ResourceProviderMixin {
final ByteStore byteStore = MemoryByteStore();
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index f0a3e1f..539ff59 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -92,6 +92,26 @@
expect(generatedFile.path, generatedPath);
expect(writableFile2, same(generatedFile));
}
+
+ void test_getFileForUri_nestedLib_notCanonicalUri() async {
+ var outerPath = convertPath('$workspaceRootPath/my/outer/lib/a.dart');
+ var outerUri = Uri.parse('package:my.outer/a.dart');
+
+ var innerPath = convertPath('/workspace/my/outer/lib/inner/lib/b.dart');
+ var innerUri = Uri.parse('package:my.outer.lib.inner/b.dart');
+
+ var analysisDriver = driverFor(outerPath);
+ var fsState = analysisDriver.fsState;
+
+ // User code might use such relative URI.
+ var innerUri2 = outerUri.resolve('inner/lib/b.dart');
+ expect(innerUri2, Uri.parse('package:my.outer/inner/lib/b.dart'));
+
+ // However the returned file must use the canonical URI.
+ var innerFile = fsState.getFileForUri(innerUri2).t1!;
+ expect(innerFile.path, innerPath);
+ expect(innerFile.uri, innerUri);
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
index 9914458..c686016 100644
--- a/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/to_source_visitor_test.dart
@@ -2,14 +2,17 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/ast/ast_factory.dart';
import 'package:analyzer/src/dart/ast/to_source_visitor.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -765,14 +768,62 @@
_assertSource(";", AstTestFactory.emptyStatement());
}
- void test_visitEnumDeclaration_multiple() {
- _assertSource("enum E {ONE, TWO}",
- AstTestFactory.enumDeclaration2("E", ["ONE", "TWO"]));
+ void test_visitEnumDeclaration_constants_multiple() {
+ var findNode = _parseStringToFindNode(r'''
+enum E {one, two}
+''');
+ _assertSource(
+ 'enum E {one, two}',
+ findNode.enumDeclaration('E'),
+ );
}
- void test_visitEnumDeclaration_single() {
+ void test_visitEnumDeclaration_constants_single() {
+ var findNode = _parseStringToFindNode(r'''
+enum E {one}
+''');
_assertSource(
- "enum E {ONE}", AstTestFactory.enumDeclaration2("E", ["ONE"]));
+ 'enum E {one}',
+ findNode.enumDeclaration('E'),
+ );
+ }
+
+ void test_visitEnumDeclaration_field_constructor() {
+ var findNode = _parseStringToFindNode(r'''
+enum E {
+ one, two;
+ final int field;
+ E(this.field);
+}
+''');
+ _assertSource(
+ 'enum E {one, two; final int field; E(this.field);}',
+ findNode.enumDeclaration('enum E'),
+ );
+ }
+
+ void test_visitEnumDeclaration_method() {
+ var findNode = _parseStringToFindNode(r'''
+enum E {
+ one, two;
+ void myMethod() {}
+ int get myGetter => 0;
+}
+''');
+ _assertSource(
+ 'enum E {one, two; void myMethod() {} int get myGetter => 0;}',
+ findNode.enumDeclaration('enum E'),
+ );
+ }
+
+ void test_visitEnumDeclaration_withoutMembers() {
+ var findNode = _parseStringToFindNode(r'''
+enum E<T> with M1, M2 implements I1, I2 {one, two}
+''');
+ _assertSource(
+ 'enum E<T> with M1, M2 implements I1, I2 {one, two}',
+ findNode.enumDeclaration('E'),
+ );
}
void test_visitExportDirective_combinator() {
@@ -3356,4 +3407,18 @@
node.accept(ToSourceVisitor(buffer));
expect(buffer.toString(), expectedSource);
}
+
+ FindNode _parseStringToFindNode(String content) {
+ var parseResult = parseString(
+ content: content,
+ featureSet: FeatureSet.fromEnableFlags2(
+ sdkLanguageVersion: ExperimentStatus.currentVersion,
+ flags: [
+ Feature.enhanced_enums.enableString,
+ Feature.super_parameters.enableString,
+ ],
+ ),
+ );
+ return FindNode(parseResult.content, parseResult.unit);
+ }
}
diff --git a/pkg/analyzer/test/src/lint/pub_test.dart b/pkg/analyzer/test/src/lint/pub_test.dart
index db3a2d0..b5fbe2a 100644
--- a/pkg/analyzer/test/src/lint/pub_test.dart
+++ b/pkg/analyzer/test/src/lint/pub_test.dart
@@ -48,6 +48,8 @@
dev_dependencies:
markdown: '>=0.7.1+2 <0.8.0'
unittest: '>=0.11.0 <0.12.0'
+ kittens2:
+ git: git://github.com/munificent/kittens2.git
dependency_overrides:
foo: 1.2.0
repository: https://github.com/dart-lang/linter
@@ -148,6 +150,14 @@
testValue(
'url', git.url, equals('git://github.com/munificent/kittens.git'));
});
+
+ group('git (short form)', () {
+ PSDependency dep = findDependency(ps.devDependencies, name: 'kittens2');
+ PSGitRepo git = dep.git!;
+ test('ref', () => expect(git.ref, isNull));
+ testValue(
+ 'url', git.url, equals('git://github.com/munificent/kittens2.git'));
+ });
});
// group('visiting', () {
// test('smoke', () {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 6378283..3c1a267 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -230,7 +230,7 @@
}
var absoluteUri = resolveRelativeUri(source.uri, relativeUri);
- var rewrittenUri = rewriteFileToPackageUri(sourceFactory, absoluteUri);
+ var rewrittenUri = rewriteToCanonicalUri(sourceFactory, absoluteUri);
if (rewrittenUri == null) {
return;
}
diff --git a/tools/VERSION b/tools/VERSION
index c66c69e..b2f9f59 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 84
+PRERELEASE 85
PRERELEASE_PATCH 0
\ No newline at end of file