Skip to content

Commit

Permalink
Version 3.2.0-109.0.dev
Browse files Browse the repository at this point in the history
Merge 33fb1e3 into dev
  • Loading branch information
Dart CI committed Aug 25, 2023
2 parents 292bb1e + 33fb1e3 commit abced95
Show file tree
Hide file tree
Showing 48 changed files with 336 additions and 141 deletions.
14 changes: 10 additions & 4 deletions pkg/analysis_server/lib/src/lsp/mapping.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ final diagnosticTagsForErrorCode = <String, List<lsp.DiagnosticTag>>{
],
};

/// A regex used for splitting the display text in a completion so that
/// filterText only includes the symbol name and not any additional text (such
/// as parens, ` => `).
final _completionFilterTextSplitPattern = RegExp(r'[ \(]');

/// A regex to extract the type name from the parameter string of a setter
/// completion item.
final _completionSetterTypePattern = RegExp(r'^\((\S+)\s+\S+\)$');
Expand Down Expand Up @@ -855,12 +860,13 @@ lsp.CompletionItem toCompletionItem(
required bool completeFunctionCalls,
CompletionItemResolutionInfo? resolutionData,
}) {
// Build separate display and filter labels. Displayed labels may have additional
// info appended (for example '(...)' on callables) that should not be included
// in filterText.
var label = suggestion.displayText ?? suggestion.completion;
assert(label.isNotEmpty);
final filterText = label;

// Displayed labels may have additional info appended (for example '(...)' on
// callables and ` => ` on getters) that should not be included in filterText,
// so strip anything from the first paren/space.
final filterText = label.split(_completionFilterTextSplitPattern).first;

// Trim any trailing comma from the (displayed) label.
if (label.endsWith(',')) {
Expand Down
93 changes: 57 additions & 36 deletions pkg/analysis_server/test/lsp/completion_dart_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1093,33 +1093,74 @@ import 'package:^';
Future<void> test_dartDocPreference_unset() =>
assertDocumentation(null, includesSummary: true, includesFull: true);

Future<void> test_filterTextNotIncludeAdditionalText() async {
Future<void> test_filterText_constructorParens() async {
// Constructor parens should not be included in filterText.
final content = '''
class MyClass {}
void f() {
MyClass a = new MyCla^
}
''';

await initialize();
await openFile(mainFileUri, withoutMarkers(content));
final res = await getCompletion(mainFileUri, positionFromMarker(content));
expect(res.any((c) => c.label == 'MyClass()'), isTrue);
final item = res.singleWhere((c) => c.label == 'MyClass()');

// filterText is set explicitly because it's not the same as label.
expect(item.filterText, 'MyClass');

// The text in the edit should also not contain the parens.
final textEdit = toTextEdit(item.textEdit!);
expect(textEdit.newText, 'MyClass');
}

Future<void> test_filterText_override_getter() async {
// Some completions (eg. overrides) have additional text that is not part
// of the label. That text should _not_ appear in filterText as it will
// affect the editors relevance ranking as the user types.
// https://github.com/dart-lang/sdk/issues/45157
final content = '''
abstract class Person {
String get name;
}
abstract class Person {
String get name;
}
class Student extends Person {
nam^
}
class Student extends Person {
nam^
}
''';

await initialize();
await openFile(mainFileUri, withoutMarkers(content));
final res = await getCompletion(mainFileUri, positionFromMarker(content));
final item = res.singleWhereOrNull((c) => c.label.startsWith('name =>'));
expect(item, isNotNull);
expect(item!.label, equals('name => …'));
expect(item.filterText, isNull); // Falls back to label
expect(item.insertText, isNull);
final textEdit = toTextEdit(item.textEdit!);
expect(textEdit.newText, equals('''@override
// TODO: implement name
String get name => throw UnimplementedError();'''));
final item = res.singleWhere((c) => c.label == 'name => …');
// filterText is set explicitly because it's not the same as label.
expect(item.filterText, 'name');
}

Future<void> test_filterText_override_method() async {
// Some completions (eg. overrides) have additional text that is not part
// of the label. That text should _not_ appear in filterText as it will
// affect the editors relevance ranking as the user types.
// https://github.com/dart-lang/sdk/issues/45157
final content = '''
abstract class Base {
void myMethod() {};
}
class BaseImpl extends Base {
myMet^
}
''';

await initialize();
await openFile(mainFileUri, withoutMarkers(content));
final res = await getCompletion(mainFileUri, positionFromMarker(content));
final item = res.singleWhere((c) => c.label == 'myMethod() { … }');
// filterText is set explicitly because it's not the same as label.
expect(item.filterText, 'myMethod');
}

Future<void> test_fromPlugin_dartFile() async {
Expand Down Expand Up @@ -2136,26 +2177,6 @@ void f() { }
expect(completion.detail, '(int? a, [int b = 1]) → String?');
}

Future<void> test_parensNotInFilterTextOrEditText() async {
final content = '''
class MyClass {}
void f() {
MyClass a = new MyCla^
}
''';

await initialize();
await openFile(mainFileUri, withoutMarkers(content));
final res = await getCompletion(mainFileUri, positionFromMarker(content));
expect(res.any((c) => c.label == 'MyClass()'), isTrue);
final item = res.singleWhere((c) => c.label == 'MyClass()');
expect(item.filterText, 'MyClass');
expect(item.insertText, isNull);
final textEdit = toTextEdit(item.textEdit!);
expect(textEdit.newText, 'MyClass');
}

Future<void> test_plainText() async {
final content = '''
class MyClass {
Expand Down
2 changes: 0 additions & 2 deletions pkg/dart2native/lib/dart2native.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,13 @@ Future generateAotSnapshot(
String kernelFile,
String snapshotFile,
String? debugFile,
bool enableAsserts,
List<String> extraGenSnapshotOptions) {
return Process.run(genSnapshot, [
'--snapshot-kind=app-aot-elf',
'--elf=$snapshotFile',
if (debugFile != null) '--save-debugging-info=$debugFile',
if (debugFile != null) '--dwarf-stack-traces',
if (debugFile != null) '--strip',
if (enableAsserts) '--enable-asserts',
...extraGenSnapshotOptions,
kernelFile
]);
Expand Down
5 changes: 2 additions & 3 deletions pkg/dart2native/lib/generate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ Future<void> generateNative({
String? targetOS,
required List<String> defines,
String enableExperiment = '',
bool enableAsserts = false,
bool soundNullSafety = true,
bool verbose = false,
String verbosity = 'all',
Expand Down Expand Up @@ -95,8 +94,8 @@ Future<void> generateNative({
final String snapshotFile = (outputKind == Kind.aot
? outputPath
: path.join(tempDir.path, 'snapshot.aot'));
final snapshotResult = await generateAotSnapshot(genSnapshot, kernelFile,
snapshotFile, debugPath, enableAsserts, extraAotOptions);
final snapshotResult = await generateAotSnapshot(
genSnapshot, kernelFile, snapshotFile, debugPath, extraAotOptions);

if (verbose || snapshotResult.exitCode != 0) {
await _forwardOutput(snapshotResult);
Expand Down
7 changes: 0 additions & 7 deletions pkg/dartdev/lib/src/commands/compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,6 @@ class CompileNativeCommand extends CompileSubcommandCommand {
abbr: defineOption.abbr,
valueHelp: defineOption.valueHelp,
);
if (commandName != exeCmdName) {
// dart compile exe creates a product mode binary, which doesn't support asserts.
argParser.addFlag('enable-asserts',
negatable: false, help: 'Enable assert statements.');
}
argParser
..addOption(
packagesOption.flag,
Expand Down Expand Up @@ -349,8 +344,6 @@ Remove debugging information from the output and save it separately to the speci
outputFile: args['output'],
defines: args['define'],
packages: args['packages'],
enableAsserts:
commandName != exeCmdName ? args['enable-asserts'] : false,
enableExperiment: args.enabledExperiments.join(','),
soundNullSafety: args['sound-null-safety'],
debugFile: args['save-debugging-info'],
Expand Down
2 changes: 2 additions & 0 deletions pkg/linter/lib/src/rules/await_only_futures.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';

import '../analyzer.dart';
Expand Down Expand Up @@ -70,6 +71,7 @@ class _Visitor extends SimpleAstVisitor<void> {

var type = node.expression.staticType;
if (!(type == null ||
type.element is ExtensionTypeElement ||
type.isDartAsyncFuture ||
type is DynamicType ||
type is InvalidType ||
Expand Down
6 changes: 6 additions & 0 deletions pkg/linter/lib/src/rules/camel_case_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class CamelCaseTypes extends LintRule {
registry.addClassTypeAlias(this, visitor);
registry.addFunctionTypeAlias(this, visitor);
registry.addEnumDeclaration(this, visitor);
registry.addExtensionTypeDeclaration(this, visitor);
}
}

Expand Down Expand Up @@ -89,6 +90,11 @@ class _Visitor extends SimpleAstVisitor<void> {
check(node.name);
}

@override
void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) {
check(node.name);
}

@override
void visitFunctionTypeAlias(FunctionTypeAlias node) {
check(node.name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,18 @@ class _RecursiveVisitor extends RecursiveAstVisitor<void> {
super.visitExtensionOverride(node);
}

@override
void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) {
_deprecatedVerifier
.pushInDeprecatedValue(node.declaredElement?.hasDeprecated ?? false);

try {
super.visitExtensionTypeDeclaration(node);
} finally {
_deprecatedVerifier.popInDeprecated();
}
}

@override
void visitFieldDeclaration(FieldDeclaration node) {
_deprecatedVerifier.pushInDeprecatedMetadata(node.metadata);
Expand Down
2 changes: 1 addition & 1 deletion pkg/linter/test/rule_test_support.dart
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class PubPackageResolutionTest extends _ContextResolutionTest {

bool get dumpAstOnFailures => true;

List<String> get experiments => [];
List<String> get experiments => ['inline-class', 'macros'];

/// The path that is not in [workspaceRootPath], contains external packages.
String get packagesRootPath => '/packages';
Expand Down
2 changes: 2 additions & 0 deletions pkg/linter/test/rules/all.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import 'avoid_unused_constructor_parameters_test.dart'
import 'avoid_void_async_test.dart' as avoid_void_async;
import 'await_only_futures_test.dart' as await_only_futures;
import 'camel_case_extensions_test.dart' as camel_case_extensions;
import 'camel_case_types_test.dart' as camel_case_types;
import 'cancel_subscriptions_test.dart' as cancel_subscriptions;
import 'cast_nullable_to_non_nullable_test.dart'
as cast_nullable_to_non_nullable;
Expand Down Expand Up @@ -251,6 +252,7 @@ void main() {
avoid_void_async.main();
await_only_futures.main();
camel_case_extensions.main();
camel_case_types.main();
cancel_subscriptions.main();
cast_nullable_to_non_nullable.main();
collection_methods_unrelated_type.main();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ main() {

@reflectiveTest
class AvoidShadowingTypeParametersTest extends LintRuleTest {
@override
List<String> get experiments => ['inline-class'];

@override
String get lintRule => 'avoid_shadowing_type_parameters';

Expand Down
23 changes: 23 additions & 0 deletions pkg/linter/test/rules/await_only_futures_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,29 @@ class AwaitOnlyFuturesTest extends LintRuleTest {
@override
String get lintRule => 'await_only_futures';

test_extensionType_implementingFuture() async {
await assertNoDiagnostics(r'''
extension type E(Future f) implements Future { }
void f() async {
await E(Future.value());
}
''');
}

test_extensionType_notImplementingFuture() async {
await assertDiagnostics(r'''
extension type E(int c) { }
void f() async {
await E(1);
}
''', [
// No lint
error(CompileTimeErrorCode.AWAIT_OF_EXTENSION_TYPE_NOT_FUTURE, 48, 5),
]);
}

test_undefinedClass() async {
await assertDiagnostics(r'''
Undefined f() async => await f();
Expand Down
35 changes: 35 additions & 0 deletions pkg/linter/test/rules/camel_case_types_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../rule_test_support.dart';

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

@reflectiveTest
class CamelCaseTypesTest extends LintRuleTest {
@override
String get lintRule => 'camel_case_types';

test_extensionType_lowerCase() async {
// No need to test all the variations. Name checking is shared with other
// declaration types.
await assertDiagnostics(r'''
extension type fooBar(int i) {}
''', [
lint(15, 6),
]);
}

test_extensionType_wellFormed() async {
await assertNoDiagnostics(r'''
extension type FooBar(int i) {}
''');
}
}
Loading

0 comments on commit abced95

Please sign in to comment.