Skip to content

Commit

Permalink
Version 3.5.0-93.0.dev
Browse files Browse the repository at this point in the history
Merge 778a413 into dev
  • Loading branch information
Dart CI committed Apr 24, 2024
2 parents cf91449 + 778a413 commit 60cb97a
Show file tree
Hide file tree
Showing 19 changed files with 497 additions and 56 deletions.
4 changes: 2 additions & 2 deletions pkg/analysis_server_plugin/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ There are more documents on our [wiki][]. Once set up to build the SDK, run:

## Coding style

The analyzer packages are coded with a styled specified in our [coding style
The analyzer packages are coded with a style specified in our [coding style
document][coding style].

[building]: https://github.com/dart-lang/sdk/wiki/Building
[coding style]: https://github.com/dart-lang/sdk/blob/main/pkg/analyzer/doc/implementation/coding_style.md
[contributing]: https://github.com/dart-lang/sdk/wiki/Contributing
[wiki]: https://github.com/dart-lang/sdk/wiki
[wiki]: https://github.com/dart-lang/sdk/wiki
29 changes: 19 additions & 10 deletions pkg/dartdev/lib/src/native_assets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,26 @@ Future<bool> warnOnNativeAssets() async {
// If `pub get` hasn't run, we can't know, so don't error.
return false;
}
final packageLayout =
await PackageLayout.fromRootPackageRoot(workingDirectory);
final packagesWithNativeAssets = await packageLayout.packagesWithNativeAssets;
if (packagesWithNativeAssets.isEmpty) {
return false;
try {
final packageLayout =
await PackageLayout.fromRootPackageRoot(workingDirectory);
final packagesWithNativeAssets =
await packageLayout.packagesWithNativeAssets;
if (packagesWithNativeAssets.isEmpty) {
return false;
}
final packageNames = packagesWithNativeAssets.map((p) => p.name).join(' ');
log.stderr(
'Package(s) $packageNames require the native assets feature to be enabled. '
'Enable native assets with `--enable-experiment=native-assets`.',
);
} on FormatException catch (e) {
// This can be thrown if the package_config.json is malformed or has
// duplicate entries.
log.stderr(
'Error encountered while parsing package_config.json: ${e.message}',
);
}
final packageNames = packagesWithNativeAssets.map((p) => p.name).join(' ');
log.stderr(
'Package(s) $packageNames require the native assets feature to be enabled. '
'Enable native assets with `--enable-experiment=native-assets`.',
);
return true;
}

Expand Down
28 changes: 28 additions & 0 deletions pkg/dartdev/test/commands/run_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,34 @@ void main(List<String> args) => print("$b $args");
expect(result.exitCode, 0);
});

test('Handles invalid package_config.json', () async {
// Regression test for https://github.com/dart-lang/sdk/issues/55490
p = project(mainSrc: "void main() { print('Hello World'); }");
final packageConfig = File(p.packageConfigPath);
final contents = jsonDecode(packageConfig.readAsStringSync());
// Fail fast if the config version changes to make sure this test is kept
// up to date with package config format changes.
expect(contents['configVersion'], 2);

// Duplicate an entry from the package config's package list and overwrite
// the existing config.
final packages = contents['packages'] as List;
expect(packages, isNotEmpty);
final duplicatePackage = packages.first;
packages.add(duplicatePackage);
packageConfig.writeAsStringSync(jsonEncode(contents));

final result = await p.run(['run', p.relativeFilePath]);
expect(result.stdout, isEmpty);
expect(
result.stderr,
contains(
'Error encountered while parsing package_config.json: Duplicate package name',
),
);
expect(result.exitCode, 255);
});

group('DDS', () {
group('disable', () {
test('dart run simple', () async {
Expand Down
6 changes: 6 additions & 0 deletions pkg/dartdev/test/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ class TestProject {

String get mainPath => path.join(dirPath, relativeFilePath);

String get packageConfigPath => path.join(
dirPath,
'.dart_tool',
'package_config.json',
);

final String name;

String get relativeFilePath => 'lib/main.dart';
Expand Down
45 changes: 43 additions & 2 deletions pkg/linter/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,53 @@ possibly guide you. Coordinating up front makes it much easier to avoid
frustration later on.

### Code reviews

All submissions, including submissions by project members, require review.

#### Connecting a code review with an issue

When submitting a code review that fixes an issue in the [linter issue
tracker], you can use the [usual keywords that GitHub supports][Linking a pull
request] in order to link the code review to the issue. After the code review
is submitted, it will appear on any linked issue page's timeline as an event,
but the issue will not actually be closed (because the issue tracker is
attached to a different git repository from the Dart SDK). The issue must be
closed manually.

It is easy to miss the step of manually closing a GitHub issue, so open issues
can be periodically reviewed by querying GitHub's REST API:

```none
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
'/repos/dart-lang/linter/issues/events?per_page=100' \
--paginate \
-q '.[] | select(.actor.login == "copybara-service[bot]") | select(.issue.state == "open") | .issue.html_url'
```

This command prints a list of open issues that have been referenced by a
submitted code review, not necessarily issues that should be closed. Each issue
needs to be reviewed individually.


### Coding style

The analyzer packages, including this one, are coded with a style specified in
our [coding style document][coding style].

### File headers

All files in the project must start with the following header.

// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// Copyright (c) 2024, 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.

### Mechanics

Contributing code is easy and follows the
[Dart SDK Contributing guidelines](../../CONTRIBUTING.md).
[Dart SDK Contributing guidelines][contributing].

Please note that a few kinds of changes additionally require a `CHANGELOG`
entry. Notably, any change that:
Expand All @@ -50,6 +85,12 @@ questions in your PR.
**Thank you!**

### The small print

Contributions made by corporations are covered by a different agreement than the
one above, the
[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).

[linter issue tracker]: https://github.com/dart-lang/linter/issues
[Linking a pull request]: https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue
[coding style]: https://github.com/dart-lang/sdk/blob/main/pkg/analyzer/doc/implementation/coding_style.md
[contributing]: https://github.com/dart-lang/sdk/wiki/Contributing
16 changes: 16 additions & 0 deletions pkg/linter/lib/src/rules/avoid_annotating_with_dynamic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/type.dart';

import '../analyzer.dart';
import '../extensions.dart';

const _desc = r'Avoid annotating with dynamic when not required.';

Expand Down Expand Up @@ -82,8 +83,23 @@ class _Visitor extends SimpleAstVisitor<void> {
}

void _checkNode(NormalFormalParameter node, TypeAnnotation? type) {
if (node.inAugmentation) return;

if (type is NamedType && type.type is DynamicType) {
rule.reportLint(node);
}
}
}

extension on AstNode {
bool get inAugmentation {
AstNode? target = this;
while (target != null) {
if (target.isAugmentation) return true;
if (target is Block) return false;
if (target is Declaration) return false;
target = target.parent;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';

import '../analyzer.dart';
import '../extensions.dart';

const _desc = r'Prefer typing uninitialized variables and fields.';

Expand Down Expand Up @@ -88,16 +89,13 @@ class _Visitor extends SimpleAstVisitor<void> {

@override
void visitVariableDeclarationList(VariableDeclarationList node) {
if (node.type != null) {
return;
}

var code = node.parent is FieldDeclaration
? PreferTypingUninitializedVariables.forField
: PreferTypingUninitializedVariables.forVariable;
if (node.type != null) return;

for (var v in node.variables) {
if (v.initializer == null) {
if (v.initializer == null && !v.isAugmentation) {
var code = node.parent is FieldDeclaration
? PreferTypingUninitializedVariables.forField
: PreferTypingUninitializedVariables.forVariable;
rule.reportLint(v, errorCode: code);
}
}
Expand Down
140 changes: 140 additions & 0 deletions pkg/linter/test/rules/avoid_annotating_with_dynamic_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,146 @@ class AvoidAnnotatingWithDynamicTest extends LintRuleTest {
@override
String get lintRule => 'avoid_annotating_with_dynamic';

test_augmentationClass() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
class A { }
''');

var b = newFile('$testPackageLibPath/b.dart', r'''
augment library 'a.dart';
augment class A {
void f(dynamic o) { }
}
''');

result = await resolveFile(a.path);
await assertNoDiagnosticsIn(errors);

result = await resolveFile(b.path);
await assertDiagnosticsIn(errors, [
lint(54, 9),
]);
}

test_augmentationTopLevelFunction() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
''');

var b = newFile('$testPackageLibPath/b.dart', r'''
augment library 'a.dart';
void f(dynamic o) { }
''');

result = await resolveFile(a.path);
await assertNoDiagnosticsIn(errors);

result = await resolveFile(b.path);
await assertDiagnosticsIn(errors, [
lint(34, 9),
]);
}

test_augmentationTopLevelFunction_localDynamic() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
void f(int i) {}
''');

var b = newFile('$testPackageLibPath/b.dart', r'''
augment library 'a.dart';
augment void f(int i) {
var g = (dynamic x) {};
g(i);
}
''');

result = await resolveFile(a.path);
await assertNoDiagnosticsIn(errors);

result = await resolveFile(b.path);
await assertDiagnosticsIn(errors, [
lint(62, 9),
]);
}

test_augmentedMethod() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
class A {
void f(dynamic o) { }
}
''');

var b = newFile('$testPackageLibPath/b.dart', r'''
augment library 'a.dart';
augment class A {
augment void f(dynamic o) { }
}
''');

result = await resolveFile(a.path);
await assertDiagnosticsIn(errors, [
lint(45, 9),
]);

result = await resolveFile(b.path);
await assertNoDiagnosticsIn(errors);
}

test_augmentedTopLevelFunction() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
void f(dynamic o) { }
''');

var b = newFile('$testPackageLibPath/b.dart', r'''
augment library 'a.dart';
augment void f(dynamic o) { }
''');

result = await resolveFile(a.path);
await assertDiagnosticsIn(errors, [
lint(33, 9),
]);

result = await resolveFile(b.path);
await assertNoDiagnosticsIn(errors);
}

test_augmentedTopLevelFunction_multiple() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
void f(dynamic o) { }
''');

var b = newFile('$testPackageLibPath/b.dart', r'''
augment library 'a.dart';
augment void f(dynamic o) { }
augment void f(dynamic o) { }
''');

result = await resolveFile(a.path);
await assertDiagnosticsIn(errors, [
lint(33, 9),
]);

result = await resolveFile(b.path);
await assertNoDiagnosticsIn(errors);
}

// TODO(srawlins): Test parameter of function-typed typedef (both old and
// new style).
// Test parameter of function-typed parameter (`f(void g(dynamic x))`).
Expand Down
Loading

0 comments on commit 60cb97a

Please sign in to comment.