[cfe] Add flag for lowering redirecting factories

+ handle constructor tear offs in part files

Change-Id: Id3100ebbabb1c125b18c52cca7cb06871ed0f726
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/206621
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2021-07-19 14:25:39 +00:00 committed by commit-bot@chromium.org
parent d1bf067214
commit 8ea5fc2773
14 changed files with 197 additions and 10 deletions

View file

@ -138,7 +138,7 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
..fileEndOffset = charEndOffset
..isNonNullableByDefault = compilationUnit.isNonNullableByDefault,
_constructorTearOff = createConstructorTearOffProcedure(
name, compilationUnit, charOffset,
name, compilationUnit, compilationUnit.fileUri, charOffset,
forAbstractClassOrEnum: forAbstractClassOrEnum),
super(metadata, modifiers, returnType, name, typeVariables, formals,
compilationUnit, charOffset, nativeMethodName);

View file

@ -20,15 +20,15 @@ Name constructorTearOffName(String constructorName, Library library) {
/// the given [name] in [compilationUnit].
///
/// If constructor tear off lowering is not enabled, `null` is returned.
Procedure? createConstructorTearOffProcedure(
String name, SourceLibraryBuilder compilationUnit, int fileOffset,
Procedure? createConstructorTearOffProcedure(String name,
SourceLibraryBuilder compilationUnit, Uri fileUri, int fileOffset,
{required bool forAbstractClassOrEnum}) {
if (!forAbstractClassOrEnum &&
compilationUnit
.loader.target.backendTarget.isConstructorTearOffLoweringEnabled) {
return new Procedure(constructorTearOffName(name, compilationUnit.library),
ProcedureKind.Method, new FunctionNode(null),
fileUri: compilationUnit.fileUri, isStatic: true)
fileUri: fileUri, isStatic: true)
..startFileOffset = fileOffset
..fileOffset = fileOffset
..fileEndOffset = fileOffset

View file

@ -810,7 +810,7 @@ class KernelTarget extends TargetImplementation {
..isNonNullableByDefault =
enclosingClass.enclosingLibrary.isNonNullableByDefault;
Procedure? constructorTearOff = createConstructorTearOffProcedure(
'', classBuilder.library, constructor.fileOffset,
'', classBuilder.library, classBuilder.fileUri, constructor.fileOffset,
forAbstractClassOrEnum:
enclosingClass.isAbstract || enclosingClass.isEnum);
if (constructorTearOff != null) {

View file

@ -1017,6 +1017,7 @@ remapped
remedy
removal
remover
renames
render
reparse
repeating

View file

@ -0,0 +1,7 @@
// Copyright (c) 2021, 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.
part 'constructor_tear_off_uri_part.dart';
main() {}

View file

@ -0,0 +1,31 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri_part.dart:8:27: Error: A value of type 'Class Function()' can't be assigned to a variable of type 'Class Function(int)'.
// - 'Class' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri.dart'.
// Class Function(int) f = Class.new;
// ^
//
import self as self;
import "dart:core" as core;
part constructor_tear_off_uri_part.dart;
class Class extends core::Object { // from org-dartlang-testcase:///constructor_tear_off_uri_part.dart
synthetic constructor •() → self::Class
: super core::Object::•()
;
static method _#new#tearOff() → self::Class
return new self::Class::•();
}
static method main() → dynamic {}
static method /* from org-dartlang-testcase:///constructor_tear_off_uri_part.dart */ test() → dynamic {
(core::int) → self::Class f = let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri_part.dart:8:27: Error: A value of type 'Class Function()' can't be assigned to a variable of type 'Class Function(int)'.
- 'Class' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri.dart'.
Class Function(int) f = Class.new;
^" in (#C1) as{TypeError,ForNonNullableByDefault} (core::int) → self::Class;
}
constants {
#C1 = tearoff self::Class::_#new#tearOff
}

View file

@ -0,0 +1,31 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri_part.dart:8:27: Error: A value of type 'Class Function()' can't be assigned to a variable of type 'Class Function(int)'.
// - 'Class' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri.dart'.
// Class Function(int) f = Class.new;
// ^
//
import self as self;
import "dart:core" as core;
part constructor_tear_off_uri_part.dart;
class Class extends core::Object { // from org-dartlang-testcase:///constructor_tear_off_uri_part.dart
synthetic constructor •() → self::Class
: super core::Object::•()
;
static method _#new#tearOff() → self::Class
return new self::Class::•();
}
static method main() → dynamic {}
static method /* from org-dartlang-testcase:///constructor_tear_off_uri_part.dart */ test() → dynamic {
(core::int) → self::Class f = let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri_part.dart:8:27: Error: A value of type 'Class Function()' can't be assigned to a variable of type 'Class Function(int)'.
- 'Class' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri.dart'.
Class Function(int) f = Class.new;
^" in (#C1) as{TypeError,ForNonNullableByDefault} (core::int) → self::Class;
}
constants {
#C1 = tearoff self::Class::_#new#tearOff
}

View file

@ -0,0 +1,3 @@
part 'constructor_tear_off_uri_part.dart';
main() {}

View file

@ -0,0 +1,3 @@
part 'constructor_tear_off_uri_part.dart';
main() {}

View file

@ -0,0 +1,31 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri_part.dart:8:27: Error: A value of type 'Class Function()' can't be assigned to a variable of type 'Class Function(int)'.
// - 'Class' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri.dart'.
// Class Function(int) f = Class.new;
// ^
//
import self as self;
import "dart:core" as core;
part constructor_tear_off_uri_part.dart;
class Class extends core::Object { // from org-dartlang-testcase:///constructor_tear_off_uri_part.dart
synthetic constructor •() → self::Class
: super core::Object::•()
;
static method _#new#tearOff() → self::Class
return new self::Class::•();
}
static method main() → dynamic {}
static method /* from org-dartlang-testcase:///constructor_tear_off_uri_part.dart */ test() → dynamic {
(core::int) → self::Class f = let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri_part.dart:8:27: Error: A value of type 'Class Function()' can't be assigned to a variable of type 'Class Function(int)'.
- 'Class' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri.dart'.
Class Function(int) f = Class.new;
^" in (#C1) as{TypeError,ForNonNullableByDefault} (core::int) → self::Class;
}
constants {
#C1 = tearoff self::Class::_#new#tearOff
}

View file

@ -0,0 +1,15 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
part constructor_tear_off_uri_part.dart;
class Class extends core::Object { // from org-dartlang-testcase:///constructor_tear_off_uri_part.dart
synthetic constructor •() → self::Class
;
static method _#new#tearOff() → self::Class
return new self::Class::•();
}
static method main() → dynamic
;
static method /* from org-dartlang-testcase:///constructor_tear_off_uri_part.dart */ test() → dynamic
;

View file

@ -0,0 +1,31 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri_part.dart:8:27: Error: A value of type 'Class Function()' can't be assigned to a variable of type 'Class Function(int)'.
// - 'Class' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri.dart'.
// Class Function(int) f = Class.new;
// ^
//
import self as self;
import "dart:core" as core;
part constructor_tear_off_uri_part.dart;
class Class extends core::Object { // from org-dartlang-testcase:///constructor_tear_off_uri_part.dart
synthetic constructor •() → self::Class
: super core::Object::•()
;
static method _#new#tearOff() → self::Class
return new self::Class::•();
}
static method main() → dynamic {}
static method /* from org-dartlang-testcase:///constructor_tear_off_uri_part.dart */ test() → dynamic {
(core::int) → self::Class f = let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri_part.dart:8:27: Error: A value of type 'Class Function()' can't be assigned to a variable of type 'Class Function(int)'.
- 'Class' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_uri.dart'.
Class Function(int) f = Class.new;
^" in (#C1) as{TypeError,ForNonNullableByDefault} (core::int) → self::Class;
}
constants {
#C1 = tearoff self::Class::_#new#tearOff
}

View file

@ -0,0 +1,23 @@
// Copyright (c) 2021, 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.
part of 'constructor_tear_off_uri.dart';
test() {
Class Function(int) f = Class.new;
}
// Long comment to increase file offset of Class
// Long comment to increase file offset of Class
// Long comment to increase file offset of Class
// Long comment to increase file offset of Class
// Long comment to increase file offset of Class
// Long comment to increase file offset of Class
// Long comment to increase file offset of Class
// Long comment to increase file offset of Class
// Long comment to increase file offset of Class
// Long comment to increase file offset of Class
// Long comment to increase file offset of Class
class Class {}

View file

@ -362,6 +362,14 @@ abstract class Target {
ConstructorTearOffLowering.constructors) !=
0;
/// Returns `true` if lowering of redirecting factory tear offs is enabled.
///
/// This is determined by the [enabledConstructorTearOffLowerings] mask.
bool get isRedirectingFactoryTearOffLoweringEnabled =>
(enabledConstructorTearOffLowerings &
ConstructorTearOffLowering.redirectingFactories) !=
0;
/// Returns `true` if lowering of typedef tear offs is enabled.
///
/// This is determined by the [enabledConstructorTearOffLowerings] mask.
@ -635,13 +643,16 @@ class LateLowering {
}
class ConstructorTearOffLowering {
/// Create top level functions to use as tear offs of constructors.
/// Create static functions to use as tear offs of constructors and.
static const int constructors = 1 << 0;
/// Create top level functions to use as tear offs of non trivial redirecting
/// factory constructors and typedefs.
static const int typedefs = 1 << 1;
/// Create static functions to use as tear offs of redirecting factories.
static const int redirectingFactories = 1 << 1;
/// Create top level functions to use as tear offs of typedefs that are not
/// proper renames.
static const int typedefs = 1 << 2;
static const int none = 0;
static const int all = (1 << 2) - 1;
static const int all = (1 << 3) - 1;
}