Skip to content

Commit

Permalink
Version 3.5.0-8.0.dev
Browse files Browse the repository at this point in the history
Merge aced052 into dev
  • Loading branch information
Dart CI committed Apr 2, 2024
2 parents e6e6d5f + aced052 commit 8aa6cd5
Show file tree
Hide file tree
Showing 10 changed files with 304 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,44 @@ void f() {
assertHasTarget('foo', targetFile: aFile);
}

Future<void>
test_class_constructor_annotationConstructor_importPrefix() async {
final a = newFile('$testPackageLibPath/a.dart', r'''
class A {
const A();
const A.named();
}
''');

addTestFile('''
library augment 'b.dart';
import 'a.dart' as prefix;
class B {
@prefix.A()
@prefix.A.named()
B().foo();
}
''');

await prepareNavigation();

assertHasRegion('prefix.A()');
assertHasTarget('prefix;');

assertHasRegion('A()');
assertHasTarget('A();', targetFile: a);

assertHasRegion('prefix.A.named()');
assertHasTarget('prefix;');

assertHasRegion('A.named()');
assertHasTarget('named()', targetFile: a);

assertHasRegion('named()');
assertHasTarget('named()', targetFile: a);
}

Future<void> test_class_constructor_named() async {
addTestFile('''
class A {
Expand Down Expand Up @@ -1381,6 +1419,35 @@ library my.lib;
assertHasTargetString('my.lib');
}

Future<void>
test_libraryAugmentation_topLevelFunction_annotationConstructor_importPrefix() async {
final a = newFile('$testPackageLibPath/a.dart', r'''
class A {
const A();
}
''');

newFile('$testPackageLibPath/b.dart', r'''
import augment 'test.dart';
''');

addTestFile('''
library augment 'b.dart';
import 'a.dart' as prefix;
@prefix.A()
external B().foo();
''');

await prepareNavigation();

assertHasRegion('prefix.A()');
assertHasTarget('prefix;');

assertHasRegion('A()');
assertHasTarget('A();', targetFile: a);
}

Future<void> test_multiplyDefinedElement() async {
newFile('$testPackageLibPath/libA.dart', 'library A; int TEST = 1;');
newFile('$testPackageLibPath/libB.dart', 'library B; int TEST = 2;');
Expand Down
69 changes: 41 additions & 28 deletions pkg/analyzer/lib/src/fasta/ast_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5251,34 +5251,47 @@ class AstBuilder extends StackListener {
var prefix = pop(NullValues.Prefix) as SimpleIdentifierImpl?;
var configurations = pop() as List<ConfigurationImpl>?;

final directive = directives.last as ImportDirectiveImpl;

// TODO(scheglov): This code would be easier if we used one object.
var mergedAsKeyword = directive.asKeyword;
var mergedPrefix = directive.prefix;
if (directive.asKeyword == null && asKeyword != null) {
mergedAsKeyword = asKeyword;
mergedPrefix = prefix;
}

directives.last = ImportDirectiveImpl(
comment: directive.documentationComment,
metadata: directive.metadata,
importKeyword: directive.importKeyword,
uri: directive.uri,
configurations: [
...directive.configurations,
...?configurations,
],
deferredKeyword: directive.deferredKeyword ?? deferredKeyword,
asKeyword: mergedAsKeyword,
prefix: mergedPrefix,
combinators: [
...directive.combinators,
...?combinators,
],
semicolon: semicolon ?? directive.semicolon,
);
final directive = directives.last;
switch (directive) {
case AugmentationImportDirectiveImpl():
directives.last = AugmentationImportDirectiveImpl(
comment: directive.documentationComment,
metadata: directive.metadata,
importKeyword: directive.importKeyword,
augmentKeyword: directive.augmentKeyword,
uri: directive.uri,
semicolon: semicolon ?? directive.semicolon,
);
case ImportDirectiveImpl():
// TODO(scheglov): This code would be easier if we used one object.
var mergedAsKeyword = directive.asKeyword;
var mergedPrefix = directive.prefix;
if (directive.asKeyword == null && asKeyword != null) {
mergedAsKeyword = asKeyword;
mergedPrefix = prefix;
}

directives.last = ImportDirectiveImpl(
comment: directive.documentationComment,
metadata: directive.metadata,
importKeyword: directive.importKeyword,
uri: directive.uri,
configurations: [
...directive.configurations,
...?configurations,
],
deferredKeyword: directive.deferredKeyword ?? deferredKeyword,
asKeyword: mergedAsKeyword,
prefix: mergedPrefix,
combinators: [
...directive.combinators,
...?combinators,
],
semicolon: semicolon ?? directive.semicolon,
);
default:
throw UnimplementedError('${directive.runtimeType}');
}
}

@override
Expand Down
3 changes: 3 additions & 0 deletions pkg/analyzer/lib/src/test_utilities/find_node.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class FindNode {

AssignmentExpression get singleAssignmentExpression => _single();

AugmentationImportDirective get singleAugmentationImportDirective =>
_single();

AwaitExpression get singleAwaitExpression => _single();

BinaryExpression get singleBinaryExpression => _single();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// 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:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../diagnostics/parser_diagnostics.dart';

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

@reflectiveTest
class AugmentationImportDirectiveParserTest extends ParserDiagnosticsTest {
test_it() {
final parseResult = parseStringWithErrors(r'''
import augment 'a.dart';
''');
parseResult.assertNoErrors();

final node = parseResult.findNode.singleAugmentationImportDirective;
assertParsedNodeText(node, r'''
AugmentationImportDirective
importKeyword: import
augmentKeyword: augment
uri: SimpleStringLiteral
literal: 'a.dart'
semicolon: ;
''');
}

test_noSemicolon() {
final parseResult = parseStringWithErrors(r'''
import augment 'a.dart'
''');
parseResult.assertErrors([
error(ParserErrorCode.EXPECTED_TOKEN, 15, 8),
]);

final node = parseResult.findNode.singleAugmentationImportDirective;
assertParsedNodeText(node, r'''
AugmentationImportDirective
importKeyword: import
augmentKeyword: augment
uri: SimpleStringLiteral
literal: 'a.dart'
semicolon: ; <synthetic>
''');
}

test_noUri_hasSemicolon() {
final parseResult = parseStringWithErrors(r'''
import augment ;
''');
parseResult.assertErrors([
error(ParserErrorCode.EXPECTED_STRING_LITERAL, 15, 1),
]);

final node = parseResult.findNode.singleAugmentationImportDirective;
assertParsedNodeText(node, r'''
AugmentationImportDirective
importKeyword: import
augmentKeyword: augment
uri: SimpleStringLiteral
literal: "" <synthetic>
semicolon: ;
''');
}

test_noUri_noSemicolon() {
final parseResult = parseStringWithErrors(r'''
import augment
''');
parseResult.assertErrors([
error(ParserErrorCode.EXPECTED_TOKEN, 7, 7),
error(ParserErrorCode.EXPECTED_STRING_LITERAL, 15, 0),
]);

final node = parseResult.findNode.singleAugmentationImportDirective;
assertParsedNodeText(node, r'''
AugmentationImportDirective
importKeyword: import
augmentKeyword: augment
uri: SimpleStringLiteral
literal: "" <synthetic>
semicolon: ; <synthetic>
''');
}
}
88 changes: 88 additions & 0 deletions pkg/analyzer/test/src/dart/parser/import_directive_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// 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:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../diagnostics/parser_diagnostics.dart';

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

@reflectiveTest
class ImportDirectiveParserTest extends ParserDiagnosticsTest {
test_it() {
final parseResult = parseStringWithErrors(r'''
import 'a.dart';
''');
parseResult.assertNoErrors();

final node = parseResult.findNode.singleImportDirective;
assertParsedNodeText(node, r'''
ImportDirective
importKeyword: import
uri: SimpleStringLiteral
literal: 'a.dart'
semicolon: ;
''');
}

test_noSemicolon() {
final parseResult = parseStringWithErrors(r'''
import 'a.dart'
''');
parseResult.assertErrors([
error(ParserErrorCode.EXPECTED_TOKEN, 7, 8),
]);

final node = parseResult.findNode.singleImportDirective;
assertParsedNodeText(node, r'''
ImportDirective
importKeyword: import
uri: SimpleStringLiteral
literal: 'a.dart'
semicolon: ; <synthetic>
''');
}

test_noUri_hasSemicolon() {
final parseResult = parseStringWithErrors(r'''
import ;
''');
parseResult.assertErrors([
error(ParserErrorCode.EXPECTED_STRING_LITERAL, 7, 1),
]);

final node = parseResult.findNode.singleImportDirective;
assertParsedNodeText(node, r'''
ImportDirective
importKeyword: import
uri: SimpleStringLiteral
literal: "" <synthetic>
semicolon: ;
''');
}

test_noUri_noSemicolon() {
final parseResult = parseStringWithErrors(r'''
import
''');
parseResult.assertErrors([
error(ParserErrorCode.EXPECTED_TOKEN, 0, 6),
error(ParserErrorCode.EXPECTED_STRING_LITERAL, 7, 0),
]);

final node = parseResult.findNode.singleImportDirective;
assertParsedNodeText(node, r'''
ImportDirective
importKeyword: import
uri: SimpleStringLiteral
literal: "" <synthetic>
semicolon: ; <synthetic>
''');
}
}
5 changes: 5 additions & 0 deletions pkg/analyzer/test/src/dart/parser/test_all.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'augmentation_import_directive_test.dart'
as augmentation_import_directive;
import 'class_test.dart' as class_;
import 'doc_comment_test.dart' as doc_comment;
import 'extension_test.dart' as extension_;
import 'extension_type_test.dart' as extension_type;
import 'import_directive_test.dart' as import_directive;
import 'mixin_test.dart' as mixin_;
import 'top_level_function_test.dart' as top_level_function;
import 'top_level_variable_test.dart' as top_level_variable;
Expand All @@ -17,10 +20,12 @@ import 'variable_declaration_statement_test.dart'
/// Utility for manually running all tests.
main() {
defineReflectiveSuite(() {
augmentation_import_directive.main();
class_.main();
doc_comment.main();
extension_.main();
extension_type.main();
import_directive.main();
mixin_.main();
top_level_function.main();
top_level_variable.main();
Expand Down
5 changes: 3 additions & 2 deletions pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,11 @@ extension ElementExtensions on analyzer.Element? {
if (currentElement is analyzer.CompilationUnitElement) {
return currentElement;
}
if (currentElement?.enclosingElement is analyzer.LibraryElement) {
if (currentElement?.enclosingElement
is analyzer.LibraryOrAugmentationElement) {
currentElement = currentElement?.enclosingElement;
}
if (currentElement is analyzer.LibraryElement) {
if (currentElement is analyzer.LibraryOrAugmentationElement) {
return currentElement.definingCompilationUnit;
}
for (;
Expand Down
Loading

0 comments on commit 8aa6cd5

Please sign in to comment.