Files
sdk/pkg/kernel/lib/constructor_tearoff_lowering.dart
T
David Morgan f1f188cd96 [macros] Split out modular parts of package:vm into package:vm/modular.
The modular parts in package:vm/modular/** will only depend on

  * package:kernel

  * package:front_end
    => Only for auto-generated error code messages
    => Those error codes can be their own dart_library() in g3

Based on https://dart-review.googlesource.com/c/sdk/+/353980, with
changes:

  * Exclude package:kernel from "no exports" CFE presubmit.
  * Add package:vm/modular to CFE "allowed deps".
  * Fix import in `front_end/tool/perf_common.dart` and various others.

Tested: no code changes, only moves.
Change-Id: I9a44ac6ee05478812a9c8af31f6c4bbcf44b7c42
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/354221
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Morgan :) <davidmorgan@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2024-02-27 13:00:17 +00:00

84 lines
3.1 KiB
Dart

// Copyright (c) 2024, 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/ast.dart';
const String _tearOffNamePrefix = '_#';
const String _tearOffNameSuffix = '#tearOff';
/// Creates the synthesized name to use for the lowering of the tear off of a
/// constructor or factory by the given [name].
String constructorTearOffName(String name) {
return '$_tearOffNamePrefix'
'${name.isEmpty ? 'new' : name}'
'$_tearOffNameSuffix';
}
/// Creates the synthesized name to use for the lowering of the tear off of a
/// constructor or factory by the given [constructorName] through a typedef by
/// the given [typedefName].
String typedefTearOffName(String typedefName, String constructorName) {
return '$_tearOffNamePrefix'
'$typedefName#'
'${constructorName.isEmpty ? 'new' : constructorName}'
'$_tearOffNameSuffix';
}
/// If [name] is the synthesized name of a lowering of a typedef tear off, a
/// list containing the [String] name of the typedef and the [Name] name of the
/// corresponding constructor or factory is returned. Returns `null` otherwise.
List<Object>? extractTypedefNameFromTearOff(Name name) {
if (name.text.startsWith(_tearOffNamePrefix) &&
name.text.endsWith(_tearOffNameSuffix) &&
name.text.length >
_tearOffNamePrefix.length + _tearOffNameSuffix.length) {
String text =
name.text.substring(0, name.text.length - _tearOffNameSuffix.length);
text = text.substring(_tearOffNamePrefix.length);
int hashIndex = text.indexOf('#');
if (hashIndex == -1) {
return null;
}
String typedefName = text.substring(0, hashIndex);
String constructorName = text.substring(hashIndex + 1);
constructorName = constructorName == 'new' ? '' : constructorName;
return [typedefName, new Name(constructorName, name.library)];
}
return null;
}
/// Returns `true` if [member] is a lowered constructor, factory or typedef tear
/// off.
bool isTearOffLowering(Member member) {
return member is Procedure &&
(isConstructorTearOffLowering(member) ||
isTypedefTearOffLowering(member));
}
/// Returns `true` if [procedure] is a lowered typedef tear off.
bool isTypedefTearOffLowering(Procedure procedure) {
return extractTypedefNameFromTearOff(procedure.name) != null;
}
/// Returns `true` if [procedure] is a lowered constructor or factory tear off.
bool isConstructorTearOffLowering(Procedure procedure) {
return extractConstructorNameFromTearOff(procedure.name) != null;
}
String? extractConstructorNameFromTearOff(Name name) {
if (name.text.startsWith(_tearOffNamePrefix) &&
name.text.endsWith(_tearOffNameSuffix) &&
name.text.length >
_tearOffNamePrefix.length + _tearOffNameSuffix.length) {
String text =
name.text.substring(0, name.text.length - _tearOffNameSuffix.length);
text = text.substring(_tearOffNamePrefix.length);
if (text.contains('#')) {
return null;
}
return text == 'new' ? '' : text;
}
return null;
}