Files
sdk/pkg/kernel/lib/external_name.dart
T
Johnni Winther 5b7968346d [kernel] Add Field.fieldReference
This adds a third reference to Field declaration, so that we know have
three references, one for each use case:

1) fieldReference used for initialization; in FieldInitializer and as
   the key in the InstanceConstant.fieldValues map.
2) getterReference used for reading; in InstanceGet, StaticGet and
   SuperPropertyGet
3) setterReference used for writing; in InstanceSet, StaticSet and
   SuperPropertySet

TEST=existing

Change-Id: I223f130e808e7f19a831c1fe5e3a4725d1bcdc3b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203770
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
2021-09-24 12:01:08 +00:00

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.fieldReference]
as StringConstant)
.value;
final Constant? pragmaOptionsValue =
constant.fieldValues[coreTypes.pragmaOptions.fieldReference];
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';