Skip to content

Commit

Permalink
Version 2.15.0-23.0.dev
Browse files Browse the repository at this point in the history
Merge commit 'f5a3bce734ac8b77e94c255899d65997c4677ace' into 'dev'
  • Loading branch information
Dart CI committed Aug 17, 2021
2 parents 17c9a00 + f5a3bce commit fecde13
Show file tree
Hide file tree
Showing 18 changed files with 389 additions and 113 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
## 2.15.0

### Language

- Annotations on type parameters of classes can no longer refer to class members
without a prefix. For example, this used to be permitted:

```dart
class C<@Annotation(foo) T> {
static void foo() {}
}
```

Now, the reference must be qualified with the class name, i.e.:

```dart
class C<@Annotation(C.foo) T> {
static void foo() {}
}
```

This brings the implementation behavior in line with the spec.

## 2.14.0

### Language
Expand Down
11 changes: 0 additions & 11 deletions pkg/analyzer/lib/src/generated/resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2007,17 +2007,6 @@ class ResolverVisitor extends ResolverBase with ErrorDetectionHelpers {
@override
void visitTypeName(TypeName node) {}

@override
void visitTypeParameter(TypeParameter node) {
var previousThisType = _thisType;
try {
_setupThisType();
super.visitTypeParameter(node);
} finally {
_thisType = previousThisType;
}
}

@override
void visitVariableDeclaration(VariableDeclaration node) {
_variableDeclarationResolver.resolve(node as VariableDeclarationImpl);
Expand Down
155 changes: 82 additions & 73 deletions pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,61 +43,6 @@ void f(int value) {
}

mixin UndefinedIdentifierTestCases on PubPackageResolutionTest {
test_annotation_favors_scope_resolution_over_this_resolution_class() async {
// If an annotation on a class type parameter cannot be resolved using the
// normal scope resolution mechanism, it is resolved via implicit `this`.
// Note: this behavior doesn't match the spec so we may change it - see
// https://github.com/dart-lang/language/issues/1790
await assertNoErrorsInCode('''
class C<@Annotation.function(foo) @Annotation.type(B) T> {
static void foo() {}
static void B() {}
}
class B {}
class Annotation {
const Annotation.function(void Function() f);
const Annotation.type(Type t);
}
''');
}

test_annotation_favors_scope_resolution_over_this_resolution_extension() async {
// If an annotation on an extension type parameter cannot be resolved using
// the normal scope resolution mechanism, it is resolved via implicit
// `this`. Note: this behavior doesn't match the spec so we may change it -
// see https://github.com/dart-lang/language/issues/1790
await assertNoErrorsInCode('''
extension E<@Annotation.function(foo) @Annotation.type(B) T> on C {}
class C {
static void foo() {}
static void B() {}
}
class B {}
class Annotation {
const Annotation.function(void Function() f);
const Annotation.type(Type t);
}
''');
}

test_annotation_favors_scope_resolution_over_this_resolution_mixin() async {
// If an annotation on a mixin type parameter cannot be resolved using the
// normal scope resolution mechanism, it is resolved via implicit `this`.
// Note: this behavior doesn't match the spec so we may change it - see
// https://github.com/dart-lang/language/issues/1790
await assertNoErrorsInCode('''
mixin M<@Annotation.function(foo) @Annotation.type(B) T> {
static void foo() {}
static void B() {}
}
class B {}
class Annotation {
const Annotation.function(void Function() f);
const Annotation.type(Type t);
}
''');
}

test_annotation_references_static_method_in_class() async {
await assertErrorsInCode('''
@Annotation(foo)
Expand All @@ -114,18 +59,19 @@ class Annotation {
}

test_annotation_references_static_method_in_class_from_type_parameter() async {
// It is allowed for an annotation of a class type parameter to refer to
// a method in a class (note: this doesn't match the spec but we currently
// test it to make sure we match CFE behavior - see
// https://github.com/dart-lang/language/issues/1790)
await assertNoErrorsInCode('''
// It not is allowed for an annotation of a class type parameter to refer to
// a method in a class.
await assertErrorsInCode('''
class C<@Annotation(foo) T> {
static void foo() {}
}
class Annotation {
const Annotation(dynamic d);
}
''');
''', [
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 20, 3),
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 20, 3),
]);
}

test_annotation_references_static_method_in_extension() async {
Expand All @@ -144,18 +90,19 @@ class Annotation {
}

test_annotation_references_static_method_in_extension_from_type_parameter() async {
// It is allowed for an annotation of a mixin type parameter to refer to
// a method in a class (note: this doesn't match the spec but we currently
// test it to make sure we match CFE behavior - see
// https://github.com/dart-lang/language/issues/1790)
await assertNoErrorsInCode('''
// It is not allowed for an annotation of an extension type parameter to
// refer to a method in a class.
await assertErrorsInCode('''
extension E<@Annotation(foo) T> on T {
static void foo() {}
}
class Annotation {
const Annotation(dynamic d);
}
''');
''', [
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 24, 3),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 24, 3),
]);
}

test_annotation_references_static_method_in_mixin() async {
Expand All @@ -174,18 +121,80 @@ class Annotation {
}

test_annotation_references_static_method_in_mixin_from_type_parameter() async {
// It is allowed for an annotation of a mixin type parameter to refer to
// a method in a class (note: this doesn't match the spec but we currently
// test it to make sure we match CFE behavior - see
// https://github.com/dart-lang/language/issues/1790)
await assertNoErrorsInCode('''
// It is not allowed for an annotation of a mixin type parameter to refer to
// a method in a class.
await assertErrorsInCode('''
mixin M<@Annotation(foo) T> {
static void foo() {}
}
class Annotation {
const Annotation(dynamic d);
}
''');
''', [
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 20, 3),
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 20, 3),
]);
}

test_annotation_uses_scope_resolution_class() async {
// If an annotation on a class type parameter cannot be resolved using the
// normal scope resolution mechanism, it is not resolved via implicit
// `this`.
await assertErrorsInCode('''
class C<@Annotation.function(foo) @Annotation.type(B) T> {
static void foo() {}
static void B() {}
}
class B {}
class Annotation {
const Annotation.function(void Function() f);
const Annotation.type(Type t);
}
''', [
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 29, 3),
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 29, 3),
]);
}

test_annotation_uses_scope_resolution_extension() async {
// If an annotation on an extension type parameter cannot be resolved using
// the normal scope resolution mechanism, it is not resolved via implicit
// `this`.
await assertErrorsInCode('''
extension E<@Annotation.function(foo) @Annotation.type(B) T> on C {}
class C {
static void foo() {}
static void B() {}
}
class B {}
class Annotation {
const Annotation.function(void Function() f);
const Annotation.type(Type t);
}
''', [
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 33, 3),
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 33, 3),
]);
}

test_annotation_uses_scope_resolution_mixin() async {
// If an annotation on a mixin type parameter cannot be resolved using the
// normal scope resolution mechanism, it is not resolved via implicit
// `this`.
await assertErrorsInCode('''
mixin M<@Annotation.function(foo) @Annotation.type(B) T> {
static void foo() {}
static void B() {}
}
class B {}
class Annotation {
const Annotation.function(void Function() f);
const Annotation.type(Type t);
}
''', [
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 29, 3),
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 29, 3),
]);
}

@failingTest
Expand Down
8 changes: 4 additions & 4 deletions pkg/front_end/lib/src/fasta/builder/class_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -354,12 +354,12 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl
delayedActionPerformers, synthesizedFunctionNodes);
}

MetadataBuilder.buildAnnotations(
isPatch ? origin.cls : cls, metadata, library, this, null, fileUri);
MetadataBuilder.buildAnnotations(isPatch ? origin.cls : cls, metadata,
library, this, null, fileUri, library.scope);
if (typeVariables != null) {
for (int i = 0; i < typeVariables!.length; i++) {
typeVariables![i].buildOutlineExpressions(
library, this, null, coreTypes, delayedActionPerformers);
typeVariables![i].buildOutlineExpressions(library, this, null,
coreTypes, delayedActionPerformers, scope.parent!);
}
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/front_end/lib/src/fasta/builder/field_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,8 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
_fieldEncoding.completeSignature(coreTypes);

for (Annotatable annotatable in _fieldEncoding.annotatables) {
MetadataBuilder.buildAnnotations(
annotatable, metadata, library, classBuilder, this, fileUri);
MetadataBuilder.buildAnnotations(annotatable, metadata, library,
classBuilder, this, fileUri, classBuilder?.scope ?? library.scope);
}

// For modular compilation we need to include initializers of all const
Expand Down
8 changes: 5 additions & 3 deletions pkg/front_end/lib/src/fasta/builder/function_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -486,16 +486,18 @@ abstract class FunctionBuilderImpl extends MemberBuilderImpl
isClassMember || isExtensionMember
? parent as DeclarationBuilder
: null;
MetadataBuilder.buildAnnotations(
member, metadata, library, classOrExtensionBuilder, this, fileUri);
Scope parentScope = classOrExtensionBuilder?.scope ?? library.scope;
MetadataBuilder.buildAnnotations(member, metadata, library,
classOrExtensionBuilder, this, fileUri, parentScope);
if (typeVariables != null) {
for (int i = 0; i < typeVariables!.length; i++) {
typeVariables![i].buildOutlineExpressions(
library,
classOrExtensionBuilder,
this,
coreTypes,
delayedActionPerformers);
delayedActionPerformers,
computeTypeParameterScope(parentScope));
}
}

Expand Down
8 changes: 1 addition & 7 deletions pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,8 @@ class MetadataBuilder {
SourceLibraryBuilder library,
DeclarationBuilder? classOrExtensionBuilder,
MemberBuilder? member,
Uri fileUri) {
Uri fileUri, Scope scope) {
if (metadata == null) return;
Scope scope = parent is Library ||
parent is Class ||
parent is Extension ||
classOrExtensionBuilder == null
? library.scope
: classOrExtensionBuilder.scope;
BodyBuilder bodyBuilder = library.loader
.createBodyBuilderForOutlineExpression(library, classOrExtensionBuilder,
member ?? classOrExtensionBuilder ?? library, scope, fileUri);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import '../fasta_codes.dart'
templateInternalProblemUnfinishedTypeVariable,
templateTypeArgumentsOnTypeVariable;

import '../scope.dart';
import '../source/source_library_builder.dart';
import '../util/helpers.dart';

Expand Down Expand Up @@ -200,9 +201,9 @@ class TypeVariableBuilder extends TypeDeclarationBuilderImpl {
DeclarationBuilder? classOrExtensionBuilder,
MemberBuilder? memberBuilder,
CoreTypes coreTypes,
List<DelayedActionPerformer> delayedActionPerformers) {
List<DelayedActionPerformer> delayedActionPerformers, Scope scope) {
MetadataBuilder.buildAnnotations(parameter, metadata, libraryBuilder,
classOrExtensionBuilder, memberBuilder, fileUri!);
classOrExtensionBuilder, memberBuilder, fileUri!, scope);
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,11 @@ class SourceExtensionBuilder extends ExtensionBuilderImpl {
List<DelayedActionPerformer> delayedActionPerformers,
List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
MetadataBuilder.buildAnnotations(isPatch ? origin.extension : extension,
metadata, library, this, null, fileUri);
metadata, library, this, null, fileUri, library.scope);
if (typeParameters != null) {
for (int i = 0; i < typeParameters!.length; i++) {
typeParameters![i].buildOutlineExpressions(
library, this, null, coreTypes, delayedActionPerformers);
typeParameters![i].buildOutlineExpressions(library, this, null,
coreTypes, delayedActionPerformers, scope.parent!);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2648,7 +2648,7 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
@override
void buildOutlineExpressions() {
MetadataBuilder.buildAnnotations(
library, metadata, this, null, null, fileUri);
library, metadata, this, null, null, fileUri, scope);
}

/// Builds the core AST structures for [declaration] needed for the outline.
Expand Down
Loading

0 comments on commit fecde13

Please sign in to comment.