blob: 388051074ce7ec61c9b2598dbda52c8ca75f0b30 [file] [log] [blame]
// Copyright (c) 2023, 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.
/// Recognition and validation of resource identification annotations.
///
/// A static method to be collected as a resource identifier can be annotated
/// with `@ResourceIdentifier('some-id-string')`.
library;
import 'package:kernel/ast.dart';
import '../base/messages.dart'
show
messageResourceIdentifiersNotStatic,
messageResourceIdentifiersMultiple;
import 'constant_evaluator.dart' show ErrorReporter;
/// Get all of the `@ResourceIdentifier` annotations from `package:meta`
/// that are attached to the specified [node].
Iterable<InstanceConstant> findResourceAnnotations(Annotatable node) =>
node.annotations
.whereType<ConstantExpression>()
.map((expression) => expression.constant)
.whereType<InstanceConstant>()
.where((instance) => isResourceIdentifier(instance.classNode))
.toList(growable: false);
final Uri _metaLibraryUri = new Uri(scheme: 'package', path: 'meta/meta.dart');
bool isResourceIdentifier(Class classNode) =>
classNode.name == 'ResourceIdentifier' &&
classNode.enclosingLibrary.importUri == _metaLibraryUri;
/// Report if the resource annotations is placed on anything but a static
/// method.
void validateResourceIdentifierDeclaration(
Annotatable node,
ErrorReporter errorReporter,
Iterable<InstanceConstant> resourceAnnotations,
) {
if (node is! Procedure ||
!node.isStatic ||
node.kind != ProcedureKind.Method) {
errorReporter.report(messageResourceIdentifiersNotStatic.withLocation(
node.location!.file, node.fileOffset, 1));
} else if (resourceAnnotations.length > 1) {
errorReporter.report(messageResourceIdentifiersMultiple.withLocation(
node.location!.file, node.fileOffset, 1));
}
}