Skip to content

Commit

Permalink
Elements. Migrate AnnotationVerifier.
Browse files Browse the repository at this point in the history
Change-Id: I73d58d75a4f1e54dc681f32db0ec5393035b5e86
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/395341
Commit-Queue: Konstantin Shcheglov <[email protected]>
Reviewed-by: Phil Quitslund <[email protected]>
  • Loading branch information
scheglov authored and Commit Queue committed Nov 14, 2024
1 parent c5a53ed commit 4475a23
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 44 deletions.
1 change: 0 additions & 1 deletion pkg/analyzer/analyzer_use_new_elements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ lib/src/dart/resolver/typed_literal_resolver.dart
lib/src/dart/resolver/variable_declaration_resolver.dart
lib/src/dart/resolver/yield_statement_resolver.dart
lib/src/diagnostic/diagnostic_factory.dart
lib/src/error/annotation_verifier.dart
lib/src/error/assignment_verifier.dart
lib/src/error/base_or_final_type_verifier.dart
lib/src/error/best_practices_verifier.dart
Expand Down
2 changes: 1 addition & 1 deletion pkg/analyzer/lib/src/dart/element/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4230,7 +4230,7 @@ class FieldElementImpl2 extends PropertyInducingElementImpl2
ElementKind get kind => ElementKind.FIELD;

@override
String get name3 => firstFragment.name;
String? get name3 => firstFragment.name2;

@override
SetterElement? get setter2 => firstFragment.setter?.element as SetterElement?;
Expand Down
22 changes: 22 additions & 0 deletions pkg/analyzer/lib/src/dart/element/extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,28 @@ extension DartTypeExtension on DartType {
}

extension Element2Extension on Element2 {
/// Return `true` if this element is an instance member of a class or mixin.
///
/// Only [MethodElement2]s, [GetterElement]s, and [SetterElement]s are
/// supported.
///
/// We intentionally exclude [ConstructorElement2]s - they can only be
/// invoked in instance creation expressions, and [FieldElement2]s - they
/// cannot be invoked directly and are always accessed using corresponding
/// [GetterElement]s or [SetterElement]s.
bool get isInstanceMember {
assert(this is! PropertyInducingElement2,
'Check the GetterElement or SetterElement instead');
var this_ = this;
var enclosing = this_.enclosingElement2;
if (enclosing is InterfaceElement2) {
return this_ is MethodElement2 && !this_.isStatic ||
this_ is GetterElement && !this_.isStatic ||
this_ is SetterElement && !this_.isStatic;
}
return false;
}

/// Whether this element is a wildcard variable.
bool get isWildcardVariable {
return name3 == '_' &&
Expand Down
79 changes: 41 additions & 38 deletions pkg/analyzer/lib/src/error/annotation_verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
// 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/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/extensions.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/utilities/extensions/ast.dart';
import 'package:analyzer/src/utilities/extensions/object.dart';
import 'package:analyzer/src/utilities/extensions/string.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:meta/meta_meta.dart';
Expand All @@ -17,14 +19,15 @@ class AnnotationVerifier {
final ErrorReporter _errorReporter;

/// The current library.
final LibraryElement _currentLibrary;
final LibraryElement2 _currentLibrary;

/// The [WorkspacePackage] in which [_currentLibrary] is declared.
final WorkspacePackage? _workspacePackage;

/// Whether [_currentLibrary] is part of its containing package's public API.
late final bool _inPackagePublicApi = _workspacePackage != null &&
_workspacePackage.sourceIsInPublicApi(_currentLibrary.source);
_workspacePackage
.sourceIsInPublicApi(_currentLibrary.firstFragment.source);

AnnotationVerifier(
this._errorReporter,
Expand Down Expand Up @@ -115,12 +118,13 @@ class AnnotationVerifier {
/// `@internal` annotation.
void _checkInternal(Annotation node) {
var parent = node.parent;
var parentElement = parent is Declaration ? parent.declaredElement : null;
var parentElement =
parent.ifTypeOrNull<Declaration>()?.declaredFragment?.element;
var parentElementIsPrivate = parentElement?.isPrivate ?? false;
if (parent is TopLevelVariableDeclaration) {
for (var variable in parent.variables.variables) {
var element = variable.declaredElement as TopLevelVariableElement;
if (Identifier.isPrivateName(element.name)) {
var element = variable.declaredTopLevelVariableElement;
if (element.isPrivate) {
_errorReporter.atNode(
variable,
WarningCode.INVALID_INTERNAL_ANNOTATION,
Expand All @@ -129,16 +133,17 @@ class AnnotationVerifier {
}
} else if (parent is FieldDeclaration) {
for (var variable in parent.fields.variables) {
var element = variable.declaredElement as FieldElement;
if (Identifier.isPrivateName(element.name)) {
var element = variable.declaredFieldElement;
if (element.isPrivate) {
_errorReporter.atNode(
variable,
WarningCode.INVALID_INTERNAL_ANNOTATION,
);
}
}
} else if (parent is ConstructorDeclaration) {
var class_ = parent.declaredElement!.enclosingElement3;
var element = parent.declaredFragment!.element;
var class_ = element.enclosingElement2;
if (class_.isPrivate || parentElementIsPrivate) {
_errorReporter.atNode(
node.name,
Expand All @@ -162,10 +167,10 @@ class AnnotationVerifier {
var kinds = element.targetKinds;
if (kinds.isNotEmpty) {
if (!_isValidTarget(parent, kinds)) {
var invokedElement = element.element!;
var name = invokedElement.name;
if (invokedElement is ConstructorElement) {
var className = invokedElement.enclosingElement3.name;
var invokedElement = element.element2!;
var name = invokedElement.name3;
if (invokedElement is ConstructorElement2) {
var className = invokedElement.enclosingElement2.name3;
if (name!.isEmpty) {
name = className;
} else {
Expand Down Expand Up @@ -243,16 +248,16 @@ class AnnotationVerifier {
/// Reports a warning at [node] if its parent is not a valid target for a
/// `@reopen` annotation.
void _checkReopen(Annotation node) {
ClassElement? classElement;
InterfaceElement? superElement;
ClassElement2? classElement;
InterfaceElement2? superElement;

var parent = node.parent;
if (parent is ClassDeclaration) {
classElement = parent.declaredElement;
superElement = classElement?.supertype?.element;
classElement = parent.declaredFragment?.element;
superElement = classElement?.supertype?.element3;
} else if (parent is ClassTypeAlias) {
classElement = parent.declaredElement;
superElement = classElement?.supertype?.element;
classElement = parent.declaredFragment?.element;
superElement = classElement?.supertype?.element3;
} else {
// If `parent` is neither of the above types, then `_checkKinds` will
// report a warning.
Expand All @@ -262,7 +267,7 @@ class AnnotationVerifier {
if (classElement == null) {
return;
}
if (superElement is! ClassElement) {
if (superElement is! ClassElement2) {
return;
}
if (classElement.isFinal ||
Expand All @@ -274,7 +279,7 @@ class AnnotationVerifier {
);
return;
}
if (classElement.library != superElement.library) {
if (classElement.library2 != superElement.library2) {
_errorReporter.atNode(
node.name,
WarningCode.INVALID_REOPEN_ANNOTATION,
Expand Down Expand Up @@ -319,7 +324,7 @@ class AnnotationVerifier {
if (name != null) {
var parameterName = undefinedParameter is SimpleStringLiteral
? undefinedParameter.value
: undefinedParameter.staticParameterElement?.name;
: undefinedParameter.correspondingParameter?.name3;
_errorReporter.atNode(
undefinedParameter,
WarningCode.UNDEFINED_REFERENCED_PARAMETER,
Expand Down Expand Up @@ -354,11 +359,10 @@ class AnnotationVerifier {

if (parent is TopLevelVariableDeclaration) {
for (VariableDeclaration variable in parent.variables.variables) {
var variableElement =
variable.declaredElement as TopLevelVariableElement;
var variableElement = variable.declaredTopLevelVariableElement;

var variableName = variableElement.name;
if (Identifier.isPrivateName(variableName)) {
var variableName = variableElement.name3;
if (variableName != null && Identifier.isPrivateName(variableName)) {
reportInvalidAnnotation(variableName);
}

Expand All @@ -369,25 +373,24 @@ class AnnotationVerifier {
}
} else if (parent is FieldDeclaration) {
for (VariableDeclaration variable in parent.fields.variables) {
var fieldElement = variable.declaredElement as FieldElement;
var fieldElement = variable.declaredFieldElement;
if (parent.isStatic && element.isVisibleForOverriding) {
reportInvalidVisibleForOverriding();
}

var fieldName = fieldElement.name;
if (Identifier.isPrivateName(fieldName)) {
var fieldName = fieldElement.name3;
if (fieldName != null && Identifier.isPrivateName(fieldName)) {
reportInvalidAnnotation(fieldName);
}
}
} else if (parent.declaredElement != null) {
var declaredElement = parent.declaredElement!;
} else if (parent.declaredFragment?.element case var declaredElement?) {
if (element.isVisibleForOverriding &&
(!declaredElement.isInstanceMember ||
declaredElement.enclosingElement3 is ExtensionTypeElement)) {
declaredElement.enclosingElement2 is ExtensionTypeElement2)) {
reportInvalidVisibleForOverriding();
}

var name = declaredElement.name;
var name = declaredElement.name3;
if (name != null && Identifier.isPrivateName(name)) {
reportInvalidAnnotation(name);
}
Expand Down Expand Up @@ -425,14 +428,14 @@ class AnnotationVerifier {
return;
}

InterfaceElement? declaredElement;
InterfaceElement2? declaredElement;
switch (containedDeclaration.parent) {
case ClassDeclaration classDeclaration:
declaredElement = classDeclaration.declaredElement;
declaredElement = classDeclaration.declaredFragment?.element;
case EnumDeclaration enumDeclaration:
declaredElement = enumDeclaration.declaredElement;
declaredElement = enumDeclaration.declaredFragment?.element;
case MixinDeclaration mixinDeclaration:
declaredElement = mixinDeclaration.declaredElement;
declaredElement = mixinDeclaration.declaredFragment?.element;
default:
reportError();
return;
Expand All @@ -443,7 +446,7 @@ class AnnotationVerifier {
return;
}

for (var annotation in declaredElement.metadata) {
for (var annotation in declaredElement.metadata2.annotations) {
if (annotation.isVisibleForTemplate) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/analyzer/lib/src/error/best_practices_verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
final InheritanceManager3 _inheritanceManager;

/// The current library.
final LibraryElement _currentLibrary;
final LibraryElementImpl _currentLibrary;

final AnnotationVerifier _annotationVerifier;

Expand Down
11 changes: 11 additions & 0 deletions pkg/analyzer/lib/src/utilities/extensions/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';

extension AstNodeExtension on AstNode {
/// Returns all tokens, from [beginToken] to [endToken] including.
Expand Down Expand Up @@ -179,3 +180,13 @@ extension CompilationUnitExtension on CompilationUnit {
};
}
}

extension VariableDeclarationExtension on VariableDeclaration {
FieldElementImpl2 get declaredFieldElement {
return declaredFragment!.element as FieldElementImpl2;
}

TopLevelVariableElementImpl2 get declaredTopLevelVariableElement {
return declaredFragment!.element as TopLevelVariableElementImpl2;
}
}
2 changes: 1 addition & 1 deletion pkg/analyzer/test/src/summary/elements/class_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14903,7 +14903,7 @@ library
type: Object
getter: <testLibraryFragment>::@class::C::@getter::a#element
setter: <testLibraryFragment>::@class::C::@setter::a#element

<null-name>
firstFragment: <testLibraryFragment>::@class::C::@field::0
type: Object
getter: <testLibraryFragment>::@class::C::@getter::0#element
Expand Down
2 changes: 1 addition & 1 deletion pkg/analyzer/test/src/summary/elements/enum_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6358,7 +6358,7 @@ library
firstFragment: <testLibraryFragment>::@enum::E::@field::v
type: E
getter: <testLibraryFragment>::@enum::E::@getter::v#element
static const
static const <null-name>
firstFragment: <testLibraryFragment>::@enum::E::@field::0
type: E
getter: <testLibraryFragment>::@enum::E::@getter::0#element
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2524,7 +2524,7 @@ library
primaryConstructor: <testLibraryFragment>::@extensionType::A::@constructor::new#element
typeErasure: InvalidType
fields
final <empty>
final <null-name>
firstFragment: <testLibraryFragment>::@extensionType::A::@field::<empty>
type: InvalidType
getter: <testLibraryFragment>::@extensionType::A::@getter::<empty>#element
Expand Down

0 comments on commit 4475a23

Please sign in to comment.