blob: a13c56a7dd2f92b55da6ade5520517fd6796698a [file] [log] [blame]
// Copyright (c) 2017, 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:kernel/kernel.dart';
/// Returns the enclosing library for reference [r].
Library getLibrary(NamedNode n) {
while (n != null && n is! Library) {
n = n.parent;
}
return n;
}
String getTopLevelName(NamedNode n) {
if (n is Procedure) return n.name.name;
if (n is Class) return n.name;
if (n is Typedef) return n.name;
if (n is Field) return n.name.name;
return n.canonicalName?.name;
}
/// Given an annotated [node] and a [test] function, returns the first matching
/// constant valued annotation.
///
/// For example if we had the ClassDeclaration node for `FontElement`:
///
/// @js.JS('HTMLFontElement')
/// @deprecated
/// class FontElement { ... }
///
/// We could match `@deprecated` with a test function like:
///
/// (v) => v.type.name == 'Deprecated' && v.type.element.library.isDartCore
///
Expression findAnnotation(NamedNode node, bool test(Expression value)) {
List<Expression> annotations;
if (node is Class) {
annotations = node.annotations;
} else if (node is Typedef) {
annotations = node.annotations;
} else if (node is Procedure) {
annotations = node.annotations;
} else {
return null;
}
return annotations.firstWhere(test, orElse: () => null);
}
/// If [node] has annotation matching [test] and the first argument is a
/// string, this returns the string value.
///
/// For example
///
/// class MyAnnotation {
/// final String name;
/// // ...
/// const MyAnnotation(this.name/*, ... other params ... */);
/// }
///
/// @MyAnnotation('FooBar')
/// main() { ... }
///
/// If we match the annotation for the `@MyAnnotation('FooBar')` this will
/// return the string `'FooBar'`.
String getAnnotationName(NamedNode node, bool test(Expression value)) {
var match = findAnnotation(node, test);
if (match is ConstructorInvocation && match.arguments.positional.isNotEmpty) {
var first = match.arguments.positional[0];
if (first is StringLiteral) {
return first.value;
}
}
return null;
}