Skip to content

Commit

Permalink
Version 3.4.0-207.0.dev
Browse files Browse the repository at this point in the history
Merge 3786c5e into dev
  • Loading branch information
Dart CI committed Mar 7, 2024
2 parents 227dbfd + 3786c5e commit 2cdf8f2
Show file tree
Hide file tree
Showing 13 changed files with 329 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,14 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {

@override
void visitAsExpression(AsExpression node) {
if (offset <= node.expression.end) {
declarationHelper(
mustBeNonVoid: true,
mustBeStatic: node.inStaticContext,
).addLexicalDeclarations(node);
return;
}

if (node.asOperator.coversOffset(offset)) {
if (node.expression is ParenthesizedExpression) {
// If the user has typed `as` after something that could be either a
Expand All @@ -326,6 +334,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
}
return;
}

var type = node.type;
if (type.isFullySynthetic || type.beginToken.coversOffset(offset)) {
collector.completionLocation = 'AsExpression_type';
Expand Down Expand Up @@ -784,7 +793,9 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
// returning the expression as the completion node and moving the following
// conditions into the visit methods for the respective classes.
var expression = node.expression;
if (expression is AssignmentExpression) {
if (expression is AsExpression) {
expression.accept(this);
} else if (expression is AssignmentExpression) {
var leftHandSide = expression.leftHandSide;
if (leftHandSide is SimpleIdentifier && offset <= leftHandSide.end) {
_forStatement(node);
Expand Down Expand Up @@ -1426,6 +1437,12 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
void visitMethodInvocation(MethodInvocation node) {
var operator = node.operator;
if (operator == null) {
if (node.coversOffset(offset)) {
// TODO(keertip): Also check for more cases, RHS of assignment operator,
// a field in record literal, an operand to an operator.
var mustBeNonVoid = node.parent is ArgumentList;
_forExpression(node, mustBeNonVoid: mustBeNonVoid);
}
return;
}
if ((node.isCascaded && offset == operator.offset + 1) ||
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// 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.

import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../../../client/completion_driver_test.dart';

void main() {
defineReflectiveSuite(() {
defineReflectiveTests(AsExpressionTest);
});
}

@reflectiveTest
class AsExpressionTest extends AbstractCompletionDriverTest {
Future<void> test_expression() async {
await computeSuggestions('''
void f(Object v01) {
^ as int;
}
''');
includeKeywords = false;
assertResponse(r'''
suggestions
v01
kind: parameter
''');
}

Future<void> test_expression_partial() async {
await computeSuggestions('''
void f(Object v01) {
v0^ as int;
}
''');
assertResponse(r'''
replacement
left: 2
suggestions
v01
kind: parameter
''');
}

Future<void> test_type_partial() async {
await computeSuggestions('''
class A01 {}
void f(Object x) {
x as A0^;
}
''');
assertResponse(r'''
replacement
left: 2
suggestions
A01
kind: class
''');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,33 @@ suggestions
''');
}

Future<void>
test_afterLeftBrace_beforeRightBrace_withImportedTopLevelFunctionInvocation() async {
allowedIdentifiers = {'wrapper'};
newFile('$testPackageLibPath/a.dart', '''
String? wrapper(String? value) => value;
''');
await computeSuggestions('''
import 'a.dart';
class A {
final String? first;
const A(this.first);
}
void f() {
A(w^())
}
''');
assertResponse(r'''
replacement
left: 1
suggestions
wrapper
kind: functionInvocation
''');
}

Future<void>
test_afterLeftBrace_beforeRightBrace_withImportedTopLevelFunctions() async {
allowedIdentifiers = {'aa0', 'aa1234'};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'argument_list_test.dart' as argument_list;
import 'as_expression_test.dart' as as_expression;
import 'assignment_expression_test.dart' as assignment_expression;
import 'block_test.dart' as block;
import 'case_clause_test.dart' as case_clause;
Expand Down Expand Up @@ -77,6 +78,7 @@ import 'with_clause_test.dart' as with_clause;
void main() {
defineReflectiveSuite(() {
argument_list.main();
as_expression.main();
assignment_expression.main();
block.main();
case_clause.main();
Expand Down
33 changes: 21 additions & 12 deletions pkg/analyzer/doc/implementation/coding_style.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ that can't reasonably be enforced automatically.

This section documents the styles we have agreed to follow.

### Effective Dart

We follow the styles laid out by [Effective Dart][effective dart], the Dart style
guide, unless otherwise noted below. Most of the rules in Effective Dart have
lint rules that keep us honest, but not all.

### Lint rules

- `flutter_style_todos` - Keeps our todo format canonical.
Expand All @@ -42,22 +48,25 @@ run on save, at least within our packages.

### Naming conventions

We generally follow the naming conventions from the Dart style guide. We do have
some legacy code that uses screaming caps for constant names, but newer code
doesn't use that style for constants.
We generally follow the naming conventions from the Dart style guide. We do
have some legacy code that uses screaming caps for constant names, but newer
code doesn't use that style.

#### Import prefixes

The Dart style guide doesn't explicitly specify a naming convention for import
prefixes beyond the guidance to use snake case. (See
https://dart.dev/effective-dart/style#do-name-import-prefixes-using-lowercase_with_underscores).

However, the examples in the style guide all use the name of the file with the
`.dart` suffix removed. That's the standard we follow, with the exception that
we also drop `_test.dart` for test files. That includes using the prefix `path`
for the path package, even though it's a commonly used variable name. In code
where there's a conflict, we prefix the variable name with an adjective to form
a unique name, such as `filePath`.
prefixes beyond the guidance to use snake case. (See [DO name import prefixes
using lowercase_with_underscores][do name import prefixes].)

[effective dart]: https://dart.dev/effective-dart
[do name import prefixes]: https://dart.dev/effective-dart/style#do-name-import-prefixes-using-lowercase_with_underscores

However, the examples in the Dart style guide all use the name of the file with
the `.dart` suffix removed. That's the standard we follow, with the exception
that we also drop `_test.dart` for test files. That includes using the prefix
`path` for the path package, even though it's a commonly used variable name. In
code where there would be a conflict, we prefix the variable name with a
qualifying noun to form a unique name, such as `filePath`.

#### Extensions

Expand Down
1 change: 1 addition & 0 deletions pkg/dds/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# 3.3.0-unreleased
- **Breaking change:** [DAP] Several signatures in DAP debug adapter classes have been updated to use `Uri`s where they previously used `String path`s. This is to support communicating with the DAP client using URIs instead of file paths. URIs may be used only when the client sets the custom `supportsDartUris` client capability during initialization.
- Fixed issue where DDS would fail to initialize when an isolate in the target process was unable to handle service requests (b/323386606).
- Updated `package:dap` version to 1.2.0.

# 3.2.1
Expand Down
109 changes: 58 additions & 51 deletions pkg/dds/lib/src/dds_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,28 +107,45 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
},
),
);

try {
// Setup stream event handling.
await streamManager.listen();

// Populate initial isolate state.
await _isolateManager.initialize();

// Once we have a connection to the VM service, we're ready to spawn the intermediary.
await _startDDSServer();
_initializationComplete = true;
} on StateError {
// Handle json-rpc state errors.
//
// It's possible that ordering of events on the event queue can result in
// the cleanup code above being called after this function has returned,
// resulting in an invalid DDS instance being released into the wild.
//
// If initialization hasn't completed and the error hasn't already been
// set, set it now.
error ??= DartDevelopmentServiceException.failedToStart();
}
// Run in an error Zone to ensure that asynchronous exceptions encountered
// during request handling are handled, as exceptions thrown during request
// handling shouldn't take down the entire service.
await runZonedGuarded(
() async {
try {
// Setup stream event handling.
await streamManager.listen();

// Populate initial isolate state.
await _isolateManager.initialize();

// Once we have a connection to the VM service, we're ready to spawn
// the intermediary.
await _startDDSServer();
_initializationComplete = true;
} on StateError {
// Handle json-rpc state errors.
//
// It's possible that ordering of events on the event queue can
// result in the cleanup code above being called after this function
// has returned,
// resulting in an invalid DDS instance being released into the wild.
//
// If initialization hasn't completed and the error hasn't already
// been set, set it now.
error ??= DartDevelopmentServiceException.failedToStart();
} on DartDevelopmentServiceException catch (e) {
// Forward any DartDevelopmentServiceExceptions thrown when starting
// the server.
error = e;
}
},
(error, stack) {
if (shouldLogRequests) {
print('Asynchronous error: $error\n$stack');
}
},
);

// Check if we encountered any errors during startup, cleanup, and throw.
if (error != null) {
Expand All @@ -155,38 +172,28 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
}
pipeline = pipeline.addMiddleware(_authCodeMiddleware);
final handler = pipeline.addHandler(_handlers().handler);
// Start the DDS server. Run in an error Zone to ensure that asynchronous
// exceptions encountered during request handling are handled, as exceptions
// thrown during request handling shouldn't take down the entire service.
// Start the DDS server.
late String errorMessage;
final tmpServer = await runZonedGuarded(
() async {
Future<HttpServer?> startServer() async {
try {
return await io.serve(handler, host, port);
} on SocketException catch (e) {
if (_enableServicePortFallback && port != 0) {
// Try again, this time with a random port.
port = 0;
return await startServer();
}
errorMessage = e.message;
if (e.osError != null) {
errorMessage += ' (${e.osError!.message})';
}
errorMessage += ': ${e.address?.host}:${e.port}';
return null;
}
Future<HttpServer?> startServer() async {
try {
return await io.serve(handler, host, port);
} on SocketException catch (e) {
if (_enableServicePortFallback && port != 0) {
// Try again, this time with a random port.
port = 0;
return await startServer();
}

return await startServer();
},
(error, stack) {
if (shouldLogRequests) {
print('Asynchronous error: $error\n$stack');
errorMessage = e.message;
if (e.osError != null) {
errorMessage += ' (${e.osError!.message})';
}
},
);
errorMessage += ': ${e.address?.host}:${e.port}';
return null;
}
}

final tmpServer = await startServer();

if (tmpServer == null) {
throw DartDevelopmentServiceException.connectionIssue(errorMessage);
}
Expand Down
Loading

0 comments on commit 2cdf8f2

Please sign in to comment.