| // Copyright (c) 2018, 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. | |
| library kernel.external_name; | |
| import 'ast.dart'; | |
| /// Returns external (native) name of given [Member]. | |
| String getExternalName(Member procedure) { | |
| // Native procedures are marked as external and have an annotation, | |
| // which looks like this: | |
| // | |
| // import 'dart:_internal' as internal; | |
| // | |
| // @internal.ExternalName("<name-of-native>") | |
| // external Object foo(arg0, ...); | |
| // | |
| if (!procedure.isExternal) { | |
| return null; | |
| } | |
| for (final Expression annotation in procedure.annotations) { | |
| if (annotation is ConstructorInvocation) { | |
| if (_isExternalName(annotation.target.enclosingClass)) { | |
| return (annotation.arguments.positional.single as StringLiteral).value; | |
| } | |
| } else if (annotation is ConstantExpression) { | |
| final constant = annotation.constant; | |
| if (constant is InstanceConstant) { | |
| if (_isExternalName(constant.classNode)) { | |
| return (constant.fieldValues.values.single as StringConstant).value; | |
| } | |
| } | |
| } | |
| } | |
| return null; | |
| } | |
| bool _isExternalName(Class klass) => | |
| klass.name == 'ExternalName' && | |
| klass.enclosingLibrary.importUri.toString() == 'dart:_internal'; |