Skip to content

Commit

Permalink
Version 3.6.0-230.0.dev
Browse files Browse the repository at this point in the history
Merge 80057b9 into dev
  • Loading branch information
Dart CI committed Sep 9, 2024
2 parents 60e63a6 + 80057b9 commit 8d865a0
Show file tree
Hide file tree
Showing 24 changed files with 2,057 additions and 1,505 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,15 @@ class VisibilityTracker {
var name = element?.displayName;
if (name == null) {
return false;
} else if (importData?.isNotImported ?? false) {
return !_declaredNames.contains(name);
}
return _declaredNames.add(name);

var isNotImported = importData?.isNotImported ?? false;
var prefix = importData?.prefix;
var qualifiedName = prefix != null ? '$prefix.$name' : name;

if (isNotImported) {
return !_declaredNames.contains(qualifiedName);
}
return _declaredNames.add(qualifiedName);
}
}
5 changes: 4 additions & 1 deletion pkg/analysis_server/test/completion_test_support.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class CompletionTestCase extends AbstractCompletionDomainTest {
.toList();

void assertHasCompletion(String completion,
{ElementKind? elementKind, bool? isDeprecated}) {
{ElementKind? elementKind, bool? isDeprecated, Matcher? libraryUri}) {
var expectedOffset = completion.indexOf(CURSOR_MARKER);
if (expectedOffset >= 0) {
if (completion.contains(CURSOR_MARKER, expectedOffset + 1)) {
Expand Down Expand Up @@ -58,6 +58,9 @@ class CompletionTestCase extends AbstractCompletionDomainTest {
if (isDeprecated != null) {
expect(matchingSuggestion.isDeprecated, isDeprecated);
}
if (libraryUri != null) {
expect(matchingSuggestion.libraryUri, libraryUri);
}
}

void assertHasNoCompletion(String completion) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'location/test_all.dart' as location;
import 'relevance/test_all.dart' as relevance_tests;
import 'shadowing_test.dart' as shadowing_test;
import 'text_expectations.dart';
import 'visibility/test_all.dart' as visibility;

void main() {
defineReflectiveSuite(() {
Expand All @@ -18,6 +19,7 @@ void main() {
location.main();
relevance_tests.main();
shadowing_test.main();
visibility.main();
defineReflectiveTests(UpdateTextExpectations);
}, name: 'dart');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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 'types_test.dart' as types;

void main() {
defineReflectiveSuite(() {
types.main();
}, name: 'visibility');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// 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/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../../../completion_test_support.dart';

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

@reflectiveTest
class CompletionVisibilityTest extends CompletionTestCase {
Future<void> test_imported() async {
newFile(convertPath('$testPackageLibPath/lib.dart'), '''
class C {}
''');
await getTestCodeSuggestions('''
import 'lib.dart';
C^
''');
assertHasCompletion('C');
}

Future<void> test_imported_localAndMultiplePrefixes() async {
newFile(convertPath('$testPackageLibPath/lib.dart'), '''
class C {}
''');
await getTestCodeSuggestions('''
import 'lib.dart' as l1;
import 'lib.dart' as l2;
class C {}
C^
''');
assertHasCompletion('C');
assertHasCompletion('l1.C');
assertHasCompletion('l2.C');
}

Future<void> test_imported_localAndUnprefixed() async {
newFile(convertPath('$testPackageLibPath/lib.dart'), '''
class C {}
''');
await getTestCodeSuggestions('''
import 'lib.dart';
class C {}
C^
''');
// Verify exactly one, and it was the local one.
assertHasCompletion('C', libraryUri: isNull);
}

Future<void> test_imported_multiplePrefixes() async {
newFile(convertPath('$testPackageLibPath/lib.dart'), '''
class C {}
''');
await getTestCodeSuggestions('''
import 'lib.dart' as l1;
import 'lib.dart' as l2;
C^
''');
assertHasCompletion('l1.C');
assertHasCompletion('l2.C');
}

Future<void> test_imported_prefix() async {
newFile(convertPath('$testPackageLibPath/lib.dart'), '''
class C {}
''');
await getTestCodeSuggestions('''
import 'lib.dart' as l;
C^
''');
assertHasCompletion('l.C');
}

Future<void> test_local() async {
await getTestCodeSuggestions('''
class C {}
C^
''');
assertHasCompletion('C');
}

Future<void> test_localAndNotImported() async {
newFile(convertPath('$testPackageLibPath/lib.dart'), '''
class C {}
''');
await getTestCodeSuggestions('''
class C {}
C^
''');
// This verifies exactly one, since we won't suggest the not-imported
// when it matches a local name.
assertHasCompletion('C');
}

Future<void> test_notImported() async {
newFile(convertPath('$testPackageLibPath/lib.dart'), '''
class C {}
''');
await getTestCodeSuggestions('''
C^
''');
assertHasCompletion('C');
}
}
80 changes: 73 additions & 7 deletions pkg/dart2bytecode/lib/bytecode_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class BytecodeGenerator extends RecursiveVisitor {
Map<SwitchCase, Label>? switchCases;
Map<TryCatch, TryBlock>? tryCatches;
Map<TryFinally, List<FinallyBlock>>? finallyBlocks;
TryBlock? asyncTryBlock;
Map<TreeNode, int>? contextLevels;
List<ClosureDeclaration>? closures;
Set<Field> initializedFields = const {};
Expand Down Expand Up @@ -994,6 +995,9 @@ class BytecodeGenerator extends RecursiveVisitor {
late Procedure returnAsyncStar = libraryIndex.getProcedure(
'dart:async', '_SuspendState', '_returnAsyncStar');

late Procedure handleException = libraryIndex.getProcedure(
'dart:async', '_SuspendState', '_handleException');

late Procedure asyncStarStreamControllerAdd = libraryIndex.getProcedure(
'dart:async', '_AsyncStarStreamController', 'add');

Expand Down Expand Up @@ -1603,6 +1607,7 @@ class BytecodeGenerator extends RecursiveVisitor {
switchCases = null;
tryCatches = null;
finallyBlocks = null;
asyncTryBlock = null;
contextLevels = null;
closures = null;
initializedFields = const {}; // Tracked for constructors only.
Expand Down Expand Up @@ -1702,12 +1707,60 @@ class BytecodeGenerator extends RecursiveVisitor {
asm.emitCloneContext(locals.currentContextId, locals.currentContextSize);
asm.emitPopLocal(locals.contextVarIndexInFrame);
}

if (function.dartAsyncMarker == AsyncMarker.Async ||
function.dartAsyncMarker == AsyncMarker.AsyncStar) {
final asyncTryBlock =
this.asyncTryBlock = asm.exceptionsTable.enterTryBlock(asm.offset);
asyncTryBlock.isSynthetic = true;
asyncTryBlock.needsStackTrace = true;
asyncTryBlock.types.add(cp.addType(const DynamicType()));
}
}

void _endSuspendableFunction(FunctionNode? function) {
if (!locals.isSuspendableFunction) {
return;
}
if (function!.dartAsyncMarker == AsyncMarker.Async ||
function.dartAsyncMarker == AsyncMarker.AsyncStar) {
final asyncTryBlock = this.asyncTryBlock!;
asyncTryBlock.endPC = asm.offset;
asyncTryBlock.handlerPC = asm.offset;

// Exception handlers are reachable although there are no labels or jumps.
asm.isUnreachable = false;

asm.emitSetFrame(locals.frameSize);

final rethrowException = Label();
asm.emitPush(locals.suspendStateVarIndexInFrame);
asm.emitJumpIfNull(rethrowException);

asm.emitPush(locals.suspendStateVarIndexInFrame);
final int temp = locals.suspendStateVarIndexInFrame;
asm.emitMoveSpecial(SpecialIndex.exception, temp);
asm.emitPush(temp);
asm.emitMoveSpecial(SpecialIndex.stackTrace, temp);
asm.emitPush(temp);
_genDirectCall(handleException, objectTable.getArgDescHandle(3), 3);
asm.emitReturnTOS();

asm.bind(rethrowException);
asm.emitMoveSpecial(SpecialIndex.exception, temp);
asm.emitPush(temp);
asm.emitMoveSpecial(SpecialIndex.stackTrace, temp);
asm.emitPush(temp);
asm.emitThrow(1);
}
}

void end(Member node, bool hasCode) {
if (!hasErrors) {
Code? code;
if (hasCode) {
_endSuspendableFunction(node.function);

if (options.emitLocalVarInfo) {
// Leave the scopes which were entered in _genPrologue and
// _setupInitialContext.
Expand Down Expand Up @@ -1773,6 +1826,7 @@ class BytecodeGenerator extends RecursiveVisitor {
switchCases = null;
tryCatches = null;
finallyBlocks = null;
asyncTryBlock = null;
contextLevels = null;
closures = null;
initializedFields = const {};
Expand Down Expand Up @@ -2316,6 +2370,8 @@ class BytecodeGenerator extends RecursiveVisitor {
enclosingFunction = function;
final savedLoopDepth = currentLoopDepth;
currentLoopDepth = 0;
final savedAsyncTryBlock = asyncTryBlock;
asyncTryBlock = null;

if (function.typeParameters.isNotEmpty) {
final functionTypeParameters =
Expand Down Expand Up @@ -2347,6 +2403,8 @@ class BytecodeGenerator extends RecursiveVisitor {
asm.emitPushNull();
_genReturnTOS();

_endSuspendableFunction(function);

if (options.emitLocalVarInfo) {
// Leave the scopes which were entered in _genPrologue and
// _setupInitialContext.
Expand All @@ -2364,6 +2422,7 @@ class BytecodeGenerator extends RecursiveVisitor {
parentFunction = savedParentFunction;
isClosure = savedIsClosure;
currentLoopDepth = savedLoopDepth;
asyncTryBlock = savedAsyncTryBlock;

locals.leaveScope();

Expand Down Expand Up @@ -4337,22 +4396,29 @@ class BytecodeGenerator extends RecursiveVisitor {
: asyncStarStreamControllerAdd;
_genDirectCall(addMethod, objectTable.getArgDescHandle(2), 2);

Label ret = Label(allowsBackwardJumps: true);
asm.emitJumpIfTrue(ret);
Label normalReturn = Label(allowsBackwardJumps: true);
asm.emitJumpIfTrue(normalReturn);

Label resume = Label();
asm.emitSuspend(resume);
asm.emitPush(locals.suspendStateVarIndexInFrame);
asm.emitPushNull();
_genDirectCall(yieldAsyncStar, objectTable.getArgDescHandle(2), 2);
asm.emitDrop1();

asm.bind(ret);
asm.emitPushNull();
asm.emitReturnTOS();

asm.bind(normalReturn);
final List<TryFinally> tryFinallyBlocks =
_getEnclosingTryFinallyBlocks(node, null);
_addFinallyBlocks(tryFinallyBlocks, () {
asm.emitPush(locals.suspendStateVarIndexInFrame);
asm.emitPushNull();
asm.emitStoreLocal(locals.suspendStateVarIndexInFrame);
_genDirectCall(returnAsyncStar, objectTable.getArgDescHandle(2), 2);
asm.emitReturnTOS();
});

asm.bind(resume);
asm.emitJumpIfTrue(ret);
asm.emitJumpIfTrue(normalReturn);
} else if (enclosingFunction!.dartAsyncMarker == AsyncMarker.SyncStar) {
Field field = node.isYieldStar
? syncStarIteratorYieldStarIterable
Expand Down
Loading

0 comments on commit 8d865a0

Please sign in to comment.