d8d7af15ce
As part of deprecating support for native extensions we are also
migrating away from legacy VM-specific `native 'name'` syntax
towards metadata based encoding which does not require any special
syntax.
This CL is a step 1 in migration:
- introduces support for `@pragma('vm:external-name', 'name')`
which serves as a direct replacement for `native 'name'`;
- all core libraries and tests are migrated to use the annotation;
Once this CL lands and rolls we will edit internal and external embedders
to eliminate uses of the native keyword (step 2) and finally remove
support for native keyword across our parsers (step 3).
TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/28791
Change-Id: Id6dea878db82dd4fd81149243c425b5c5dc6df86
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212461
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
73 lines
2.4 KiB
Dart
73 lines
2.4 KiB
Dart
// 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';
|
|
import 'core_types.dart';
|
|
|
|
/// Returns external (native) name of given [Member].
|
|
String? getExternalName(CoreTypes coreTypes, Member procedure) {
|
|
// Native procedures are marked as external and have an annotation,
|
|
// which looks like this:
|
|
//
|
|
// @pragma("vm:external-name", "<name-of-native>")
|
|
// external Object foo(arg0, ...);
|
|
//
|
|
// Previously the following encoding was used, which is still supported
|
|
// until all users are migrated away from it:
|
|
//
|
|
// 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) {
|
|
final String? value = _getExternalNameValue(coreTypes, annotation);
|
|
if (value != null) {
|
|
return value;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
String? _getExternalNameValue(CoreTypes coreTypes, Expression annotation) {
|
|
if (annotation is ConstantExpression) {
|
|
final Constant constant = annotation.constant;
|
|
if (constant is InstanceConstant) {
|
|
if (_isExternalName(constant.classNode)) {
|
|
return (constant.fieldValues.values.single as StringConstant).value;
|
|
} else if (_isPragma(constant.classNode)) {
|
|
final String pragmaName =
|
|
(constant.fieldValues[coreTypes.pragmaName.getterReference]
|
|
as StringConstant)
|
|
.value;
|
|
final Constant? pragmaOptionsValue =
|
|
constant.fieldValues[coreTypes.pragmaOptions.getterReference];
|
|
final String? pragmaOptions = pragmaOptionsValue is StringConstant
|
|
? pragmaOptionsValue.value
|
|
: null;
|
|
if (pragmaName == _externalNamePragma && pragmaOptions != null) {
|
|
return pragmaOptions;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
bool _isExternalName(Class klass) =>
|
|
klass.name == 'ExternalName' &&
|
|
klass.enclosingLibrary.importUri.toString() == 'dart:_internal';
|
|
|
|
bool _isPragma(Class klass) =>
|
|
klass.name == 'pragma' &&
|
|
klass.enclosingLibrary.importUri.toString() == 'dart:core';
|
|
|
|
const String _externalNamePragma = 'vm:external-name';
|