Skip to content

Commit 5e8b31a

Browse files
author
Dart CI
committed
Version 2.10.0-109.0.dev
Merge commit '9181df9d6bf5b3d80e59d0f249c8ff9460b0f28f' into 'dev'
2 parents 16937cf + 9181df9 commit 5e8b31a

File tree

74 files changed

+1371
-532
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1371
-532
lines changed

pkg/analysis_server/test/analysis/get_navigation_test.dart

+23-14
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,29 @@ main() {
4343
assertHasTarget('test = 0');
4444
}
4545

46+
Future<void> test_comment_outsideReference() async {
47+
addTestFile('''
48+
/// Returns a [String].
49+
String main() {
50+
}''');
51+
await waitForTasksFinished();
52+
var search = 'Returns';
53+
await _getNavigation(testFile, testCode.indexOf(search), 1);
54+
expect(regions, hasLength(0));
55+
}
56+
57+
Future<void> test_comment_reference() async {
58+
addTestFile('''
59+
/// Returns a [String].
60+
String main() {
61+
}''');
62+
await waitForTasksFinished();
63+
var search = '[String';
64+
await _getNavigation(testFile, testCode.indexOf(search), 1);
65+
expect(regions, hasLength(1));
66+
assertHasRegion('String]');
67+
}
68+
4669
Future<void> test_fieldType() async {
4770
// This test mirrors test_navigation() from
4871
// test/integration/analysis/get_navigation_test.dart
@@ -101,20 +124,6 @@ main() {
101124
expect(testTargets[0].kind, ElementKind.LIBRARY);
102125
}
103126

104-
Future<void> test_importKeyword() async {
105-
addTestFile('''
106-
import 'dart:math';
107-
108-
main() {
109-
}''');
110-
await waitForTasksFinished();
111-
await _getNavigation(testFile, 0, 1);
112-
expect(regions, hasLength(1));
113-
assertHasRegionString("'dart:math'");
114-
expect(testTargets, hasLength(1));
115-
expect(testTargets[0].kind, ElementKind.LIBRARY);
116-
}
117-
118127
Future<void> test_importUri() async {
119128
addTestFile('''
120129
import 'dart:math';

pkg/analysis_server/test/integration/analysis/get_navigation_test.dart

-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ class Bar {
4141
expect(target.startColumn, 7);
4242
}
4343

44-
@failingTest
4544
Future<void> test_navigation_no_result() async {
46-
// This fails - it returns navigation results for a whitespace area (#28799).
4745
var pathname = sourcePath('test.dart');
4846
var text = r'''
4947
//

pkg/analysis_server/test/lsp/definition_test.dart

+73
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,26 @@ class DefinitionTest extends AbstractLspAnalysisServerTest {
5555
expect(loc.uri, equals(referencedFileUri.toString()));
5656
}
5757

58+
Future<void> test_comment_adjacentReference() async {
59+
/// Computing Dart navigation locates a node at the provided offset then
60+
/// returns all navigation regions inside it. This test ensures we filter
61+
/// out any regions that are in the same target node (the comment) but do
62+
/// not span the requested offset.
63+
final contents = '''
64+
/// Te^st
65+
///
66+
/// References [String].
67+
main() {}
68+
''';
69+
70+
await initialize();
71+
await openFile(mainFileUri, withoutMarkers(contents));
72+
final res = await getDefinitionAsLocation(
73+
mainFileUri, positionFromMarker(contents));
74+
75+
expect(res, hasLength(0));
76+
}
77+
5878
Future<void> test_fromPlugins() async {
5979
final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.foo');
6080
final pluginAnalyzedFileUri = Uri.file(pluginAnalyzedFilePath);
@@ -176,6 +196,59 @@ class DefinitionTest extends AbstractLspAnalysisServerTest {
176196
expect(res, isEmpty);
177197
}
178198

199+
/// Failing due to incorrect range because _DartNavigationCollector._getCodeLocation
200+
/// does not handle parts.
201+
@failingTest
202+
Future<void> test_part() async {
203+
final mainContents = '''
204+
import 'lib.dart';
205+
206+
main() {
207+
Icons.[[ad^d]]();
208+
}
209+
''';
210+
211+
final libContents = '''
212+
part 'part.dart';
213+
''';
214+
215+
final partContents = '''
216+
part of 'lib.dart';
217+
218+
void unrelatedFunction() {}
219+
220+
class Icons {
221+
/// `targetRange` should not include the dartDoc but should include the full
222+
/// function body. `targetSelectionRange` will be just the name.
223+
[[String add = "Test"]];
224+
}
225+
226+
void otherUnrelatedFunction() {}
227+
''';
228+
229+
final libFileUri = Uri.file(join(projectFolderPath, 'lib', 'lib.dart'));
230+
final partFileUri = Uri.file(join(projectFolderPath, 'lib', 'part.dart'));
231+
232+
await initialize(
233+
textDocumentCapabilities:
234+
withLocationLinkSupport(emptyTextDocumentClientCapabilities));
235+
await openFile(mainFileUri, withoutMarkers(mainContents));
236+
await openFile(libFileUri, withoutMarkers(libContents));
237+
await openFile(partFileUri, withoutMarkers(partContents));
238+
final res = await getDefinitionAsLocationLinks(
239+
mainFileUri, positionFromMarker(mainContents));
240+
241+
expect(res, hasLength(1));
242+
var loc = res.single;
243+
expect(loc.originSelectionRange, equals(rangeFromMarkers(mainContents)));
244+
expect(loc.targetUri, equals(partFileUri.toString()));
245+
expect(loc.targetRange, equals(rangeFromMarkers(partContents)));
246+
expect(
247+
loc.targetSelectionRange,
248+
equals(rangeOfString(partContents, 'add')),
249+
);
250+
}
251+
179252
Future<void> test_sameLine() async {
180253
final contents = '''
181254
int plusOne(int [[value]]) => 1 + val^ue;

pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart

+10-51
Original file line numberDiff line numberDiff line change
@@ -100,27 +100,6 @@ class AssignmentExpressionResolver {
100100
_flowAnalysis?.assignmentExpression_afterRight(node);
101101
}
102102

103-
/// Set the static type of [node] to be the least upper bound of the static
104-
/// types [staticType1] and [staticType2].
105-
///
106-
/// TODO(scheglov) this is duplicate
107-
void _analyzeLeastUpperBoundTypes(
108-
Expression node, DartType staticType1, DartType staticType2) {
109-
// TODO(brianwilkerson) Determine whether this can still happen.
110-
staticType1 ??= DynamicTypeImpl.instance;
111-
112-
// TODO(brianwilkerson) Determine whether this can still happen.
113-
staticType2 ??= DynamicTypeImpl.instance;
114-
115-
DartType staticType =
116-
_typeSystem.getLeastUpperBound(staticType1, staticType2) ??
117-
DynamicTypeImpl.instance;
118-
119-
staticType = _resolver.toLegacyTypeIfOptOut(staticType);
120-
121-
_inferenceHelper.recordStaticType(node, staticType);
122-
}
123-
124103
void _checkForInvalidAssignment(
125104
DartType writeType,
126105
Expression right,
@@ -170,17 +149,6 @@ class AssignmentExpressionResolver {
170149
return true;
171150
}
172151

173-
/// Return the non-nullable variant of the [type] if null safety is enabled,
174-
/// otherwise return the type itself.
175-
///
176-
// TODO(scheglov) this is duplicate
177-
DartType _nonNullable(DartType type) {
178-
if (_isNonNullableByDefault) {
179-
return _typeSystem.promoteToNonNull(type);
180-
}
181-
return type;
182-
}
183-
184152
/// Record that the static type of the given node is the given type.
185153
///
186154
/// @param expression the node whose type is to be recorded
@@ -348,29 +316,20 @@ class AssignmentExpressionResolver {
348316
var rightType = node.rightHandSide.staticType;
349317
_inferenceHelper.recordStaticType(node, rightType);
350318
} else if (operator == TokenType.QUESTION_QUESTION_EQ) {
319+
var leftType = node.readType;
320+
321+
// The LHS value will be used only if it is non-null.
351322
if (_isNonNullableByDefault) {
352-
// The static type of a compound assignment using ??= with NNBD is the
353-
// least upper bound of the static types of the LHS and RHS after
354-
// promoting the LHS/ to non-null (as we know its value will not be used
355-
// if null)
356-
_analyzeLeastUpperBoundTypes(
357-
node,
358-
_typeSystem.promoteToNonNull(node.readType),
359-
getReadType(node.rightHandSide),
360-
);
361-
} else {
362-
// The static type of a compound assignment using ??= before NNBD is the
363-
// least upper bound of the static types of the LHS and RHS.
364-
_analyzeLeastUpperBoundTypes(
365-
node,
366-
node.readType,
367-
node.rightHandSide.staticType,
368-
);
323+
leftType = _typeSystem.promoteToNonNull(leftType);
369324
}
325+
326+
var rightType = node.rightHandSide.staticType;
327+
var result = _typeSystem.getLeastUpperBound(leftType, rightType);
328+
329+
_inferenceHelper.recordStaticType(node, result);
370330
} else if (operator == TokenType.AMPERSAND_AMPERSAND_EQ ||
371331
operator == TokenType.BAR_BAR_EQ) {
372-
_inferenceHelper.recordStaticType(
373-
node, _nonNullable(_typeProvider.boolType));
332+
_inferenceHelper.recordStaticType(node, _typeProvider.boolType);
374333
} else {
375334
var rightType = node.rightHandSide.staticType;
376335

pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart

+18-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ NavigationCollector computeDartNavigation(
1919
CompilationUnit unit,
2020
int offset,
2121
int length) {
22-
var dartCollector = _DartNavigationCollector(collector);
22+
var dartCollector = _DartNavigationCollector(collector, offset, length);
2323
var visitor = _DartNavigationComputerVisitor(resourceProvider, dartCollector);
2424
if (offset == null || length == null) {
2525
unit.accept(visitor);
@@ -43,8 +43,11 @@ AstNode _getNodeForRange(CompilationUnit unit, int offset, int length) {
4343
/// A Dart specific wrapper around [NavigationCollector].
4444
class _DartNavigationCollector {
4545
final NavigationCollector collector;
46+
final int requestedOffset;
47+
final int requestedLength;
4648

47-
_DartNavigationCollector(this.collector);
49+
_DartNavigationCollector(
50+
this.collector, this.requestedOffset, this.requestedLength);
4851

4952
void _addRegion(int offset, int length, Element element) {
5053
if (element is FieldFormalParameterElement) {
@@ -56,6 +59,12 @@ class _DartNavigationCollector {
5659
if (element.location == null) {
5760
return;
5861
}
62+
// Discard elements that don't span the offset/range given (if provided).
63+
if (requestedOffset != null &&
64+
(offset > requestedOffset + (requestedLength ?? 0) ||
65+
offset + length < requestedOffset)) {
66+
return;
67+
}
5968
var converter = AnalyzerConverter();
6069
var kind = converter.convertElementKind(element.kind);
6170
var location = converter.locationFromElement(element);
@@ -118,9 +127,13 @@ class _DartNavigationCollector {
118127
}
119128

120129
// Read the declaration so we can get the offset after the doc comments.
121-
final declaration = codeElement.session
122-
.getParsedLibrary(location.file)
123-
.getElementDeclaration(codeElement);
130+
// TODO(dantup): Skip this for parts (getParsedLibrary will throw), but find
131+
// a better solution.
132+
final declaration = !codeElement.session.getFile(location.file).isPart
133+
? codeElement.session
134+
.getParsedLibrary(location.file)
135+
.getElementDeclaration(codeElement)
136+
: null;
124137
var node = declaration?.node;
125138
if (node is VariableDeclaration) {
126139
node = node.parent;

pkg/dartdev/lib/dartdev.dart

+33-14
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import 'src/commands/pub.dart';
2222
import 'src/commands/run.dart';
2323
import 'src/commands/test.dart';
2424
import 'src/core.dart';
25+
import 'src/events.dart';
2526
import 'src/experiments.dart';
2627
import 'src/sdk.dart';
2728
import 'src/utils.dart';
@@ -35,10 +36,6 @@ Future<void> runDartdev(List<String> args, SendPort port) async {
3536
final stopwatch = Stopwatch();
3637
int result;
3738

38-
// The Analytics instance used to report information back to Google Analytics,
39-
// see lib/src/analytics.dart.
40-
Analytics analytics;
41-
4239
// The exit code for the dartdev process, null indicates that it has not yet
4340
// been set yet. The value is set in the catch and finally blocks below.
4441
int exitCode;
@@ -47,7 +44,9 @@ Future<void> runDartdev(List<String> args, SendPort port) async {
4744
Object exception;
4845
StackTrace stackTrace;
4946

50-
analytics =
47+
// The Analytics instance used to report information back to Google Analytics,
48+
// see lib/src/analytics.dart.
49+
Analytics analytics =
5150
createAnalyticsInstance(args.contains('--disable-dartdev-analytics'));
5251

5352
// If we have not printed the analyticsNoticeOnFirstRunMessage to stdout,
@@ -92,11 +91,13 @@ Future<void> runDartdev(List<String> args, SendPort port) async {
9291
// RunCommand.ddsHost = ddsUrl[0];
9392
// RunCommand.ddsPort = ddsUrl[1];
9493
}
94+
9595
String commandName;
9696

9797
try {
9898
stopwatch.start();
9999
final runner = DartdevRunner(args);
100+
100101
// Run can't be called with the '--disable-dartdev-analytics' flag, remove
101102
// it if it is contained in args.
102103
if (args.contains('--disable-dartdev-analytics')) {
@@ -119,14 +120,6 @@ Future<void> runDartdev(List<String> args, SendPort port) async {
119120
)
120121
.toList();
121122

122-
// Before calling to run, send the first ping to analytics to have the first
123-
// ping, as well as the command itself, running in parallel.
124-
if (analytics.enabled) {
125-
commandName = getCommandStr(args, runner.commands.keys.toList());
126-
// ignore: unawaited_futures
127-
analytics.sendEvent(eventCategory, commandName);
128-
}
129-
130123
// If ... help pub ... is in the args list, remove 'help', and add '--help'
131124
// to the end of the list. This will make it possible to use the help
132125
// command to access subcommands of pub such as `dart help pub publish`, see
@@ -135,6 +128,17 @@ Future<void> runDartdev(List<String> args, SendPort port) async {
135128
args = PubUtils.modifyArgs(args);
136129
}
137130

131+
// For the commands format and migrate, dartdev itself sends the
132+
// sendScreenView notification to analytics, for all other
133+
// dartdev commands (instances of DartdevCommand) the commands send this
134+
// to analytics.
135+
commandName = ArgParserUtils.getCommandStr(args);
136+
if (analytics.enabled &&
137+
(commandName == formatCmdName || commandName == migrateCmdName)) {
138+
// ignore: unawaited_futures
139+
analytics.sendScreenView(commandName);
140+
}
141+
138142
// Finally, call the runner to execute the command, see DartdevRunner.
139143
result = await runner.run(args);
140144
} catch (e, st) {
@@ -157,7 +161,22 @@ Future<void> runDartdev(List<String> args, SendPort port) async {
157161

158162
// Send analytics before exiting
159163
if (analytics.enabled) {
160-
analytics.setSessionValue(exitCodeParam, exitCode);
164+
// For commands that are not DartdevCommand instances, we manually create
165+
// and send the UsageEvent from here:
166+
if (commandName == formatCmdName) {
167+
// ignore: unawaited_futures
168+
FormatUsageEvent(
169+
exitCode: exitCode,
170+
args: args,
171+
).send(analyticsInstance);
172+
} else if (commandName == migrateCmdName) {
173+
// ignore: unawaited_futures
174+
MigrateUsageEvent(
175+
exitCode: exitCode,
176+
args: args,
177+
).send(analyticsInstance);
178+
}
179+
161180
// ignore: unawaited_futures
162181
analytics.sendTiming(commandName, stopwatch.elapsedMilliseconds,
163182
category: 'commands');

0 commit comments

Comments
 (0)