Version 2.18.0-57.0.dev Merge commit '76387a9c5b3d89035be13a84b5303e2780e94e6e' into 'dev'
diff --git a/OWNERS b/OWNERS index 911f0bb..b179edd 100644 --- a/OWNERS +++ b/OWNERS
@@ -17,7 +17,7 @@ per-file CONTRIBUTING.md,LICENSE,PATENT_GRANT,README.*,SECURITY.md=file:/tools/OWNERS_PRODUCT # Top level build files -per-file .clang-format,BUILD.gn,sdk_args.gni=file:/tools/OWNERS_VM +per-file .clang-format,BUILD.gn,sdk_args.gni=file:/tools/OWNERS_BUILD # Generated file per-file .packages=*
diff --git a/benchmarks/Startup/dart/Startup.dart b/benchmarks/Startup/dart/Startup.dart index 7beaede..03bd22e 100644 --- a/benchmarks/Startup/dart/Startup.dart +++ b/benchmarks/Startup/dart/Startup.dart
@@ -76,7 +76,7 @@ print(ends.toList()); throw '$name is missing or ambiguous'; } - print('Startup.$name(RunTimeRaw): $micros us.'); + print('Startup.$name(StartupTime): $micros us.'); } report('CreateIsolateGroupAndSetupHelper', null);
diff --git a/benchmarks/Startup/dart2/Startup.dart b/benchmarks/Startup/dart2/Startup.dart index 3220928..b79e3a3 100644 --- a/benchmarks/Startup/dart2/Startup.dart +++ b/benchmarks/Startup/dart2/Startup.dart
@@ -78,7 +78,7 @@ print(ends.toList()); throw '$name is missing or ambiguous'; } - print('Startup.$name(RunTimeRaw): $micros us.'); + print('Startup.$name(StartupTime): $micros us.'); } report('CreateIsolateGroupAndSetupHelper', null);
diff --git a/build/OWNERS b/build/OWNERS index 2b67506..24995df 100644 --- a/build/OWNERS +++ b/build/OWNERS
@@ -1 +1 @@ -file:/tools/OWNERS_ENG +file:/tools/OWNERS_BUILD
diff --git a/pkg/analyzer/lib/src/summary2/kernel_compilation_service.dart b/pkg/analyzer/lib/src/summary2/kernel_compilation_service.dart index e7ed68c..36caada 100644 --- a/pkg/analyzer/lib/src/summary2/kernel_compilation_service.dart +++ b/pkg/analyzer/lib/src/summary2/kernel_compilation_service.dart
@@ -36,11 +36,7 @@ } final executablePath = io.Platform.resolvedExecutable; - final binPath = package_path.dirname(executablePath); - final sdkPath = package_path.dirname(binPath); - - final frontEndSnapshotPath = package_path.join( - binPath, 'snapshots', 'frontend_server.dart.snapshot'); + final sdkPaths = _computeSdkPaths(); final socketCompleter = Completer<io.Socket>(); final serverSocket = await _loopbackServerSocket(); @@ -52,7 +48,7 @@ final addressStr = '$host:${serverSocket.port}'; final process = await io.Process.start(executablePath, [ - frontEndSnapshotPath, + sdkPaths.frontEndSnapshot, '--binary-protocol-address=$addressStr', ]); @@ -66,8 +62,7 @@ final requestChannel = RequestChannel(socket); // Put the platform dill. - final platformDillPath = package_path.join( - sdkPath, 'lib', '_internal', 'vm_platform_strong.dill'); + final platformDillPath = sdkPaths.platformDill; final platformDillBytes = io.File(platformDillPath).readAsBytesSync(); await requestChannel.sendRequest<void>('dill.put', { 'uri': 'dill:vm', @@ -149,6 +144,30 @@ }); } + static _SdkPaths _computeSdkPaths() { + // Check for google3. + final runFiles = io.Platform.environment['RUNFILES']; + if (runFiles != null) { + final frontServerPath = io.Platform.environment['FRONTEND_SERVER_PATH']!; + final platformDillPath = io.Platform.environment['PLATFORM_DILL_PATH']!; + return _SdkPaths( + frontEndSnapshot: package_path.join(runFiles, frontServerPath), + platformDill: package_path.join(runFiles, platformDillPath), + ); + } + + final executablePath = io.Platform.resolvedExecutable; + final binPath = package_path.dirname(executablePath); + final sdkPath = package_path.dirname(binPath); + + return _SdkPaths( + frontEndSnapshot: package_path.join( + binPath, 'snapshots', 'frontend_server.dart.snapshot'), + platformDill: package_path.join( + sdkPath, 'lib', '_internal', 'vm_platform_strong.dill'), + ); + } + static Future<io.ServerSocket> _loopbackServerSocket() async { try { return await io.ServerSocket.bind(io.InternetAddress.loopbackIPv6, 0); @@ -199,3 +218,13 @@ } } } + +class _SdkPaths { + final String frontEndSnapshot; + final String platformDill; + + _SdkPaths({ + required this.frontEndSnapshot, + required this.platformDill, + }); +}
diff --git a/pkg/analyzer_utilities/lib/package_root.dart b/pkg/analyzer_utilities/lib/package_root.dart index aa3d27c..61a3c96 100644 --- a/pkg/analyzer_utilities/lib/package_root.dart +++ b/pkg/analyzer_utilities/lib/package_root.dart
@@ -25,5 +25,13 @@ if (pkgIndex != -1) { return pathos.joinAll(parts.sublist(0, pkgIndex + 1)) + pathos.separator; } + // Try google3 environment. We expect that all packages that will be + // accessed via this root are configured in the BUILD file, and located + // inside this single root. + final runFiles = Platform.environment['RUNFILES']; + final analyzerPackagesRoot = Platform.environment['ANALYZER_PACKAGES_ROOT']; + if (runFiles != null && analyzerPackagesRoot != null) { + return pathos.join(runFiles, analyzerPackagesRoot); + } throw StateError('Unable to find sdk/pkg/ in $scriptPath'); }
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart index 1d9aefd..462b6c3 100644 --- a/pkg/compiler/lib/src/ir/impact_data.dart +++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -575,6 +575,12 @@ @override void handleConstantExpression(ir.ConstantExpression node) { + // Evaluate any [ir.UnevaluatedConstant]s to ensure they are processed for + // impacts correctly. + // TODO(joshualitt): Remove this when we have CFE constants. + if (node.constant is ir.UnevaluatedConstant) { + _elementMap.constantEvaluator.evaluate(staticTypeContext, node); + } ir.LibraryDependency import = getDeferredImport(node); ConstantImpactVisitor(this, import, node, staticTypeContext) .visitConstant(node.constant);
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml index 6a45f08..cb44cf3 100644 --- a/pkg/compiler/pubspec.yaml +++ b/pkg/compiler/pubspec.yaml
@@ -67,6 +67,8 @@ path: ../meta dart2js_info: path: ../dart2js_info + smith: + path: ../smith # Packages brought in via DEPS args:
diff --git a/pkg/compiler/test/impact/data/issue230108748.dart b/pkg/compiler/test/impact/data/issue230108748.dart new file mode 100644 index 0000000..ea16c2f --- /dev/null +++ b/pkg/compiler/test/impact/data/issue230108748.dart
@@ -0,0 +1,75 @@ +class B { + /*member: B.x: + static=[ + Rti._bind(1), + Rti._eval(1), + _arrayInstanceType(1), + _asBool(1), + _asBoolQ(1), + _asBoolS(1), + _asDouble(1), + _asDoubleQ(1), + _asDoubleS(1), + _asInt(1), + _asIntQ(1), + _asIntS(1), + _asNum(1), + _asNumQ(1), + _asNumS(1), + _asObject(1), + _asString(1), + _asStringQ(1), + _asStringS(1), + _asTop(1), + _generalAsCheckImplementation(1), + _generalIsTestImplementation(1), + _generalNullableAsCheckImplementation(1), + _generalNullableIsTestImplementation(1), + _installSpecializedAsCheck(1), + _installSpecializedIsTest(1), + _instanceType(1), + _isBool(1), + _isInt(1), + _isNum(1), + _isObject(1), + _isString(1), + _isTop(1), + findType(1), + instanceType(1)], + type=[ + inst:Closure, + inst:JSBool, + inst:JSNull, + param:int] + */ + final int x; + const B(this.x); +} + +/*member: case3: + static=[B.x=IntConstant(1)], + type=[ + const:B, + inst:JSInt, + inst:JSNull, + inst:JSNumNotInt, + inst:JSNumber, + inst:JSPositiveInt, + inst:JSUInt31, + inst:JSUInt32] +*/ +int case3() { + switch (null as dynamic) { + case B(const bool.fromEnvironment('x') ? 0 : 1): + return 1; + default: + return 2; + } +} + +/*member: main:static=[ + case3(0), + print(1)]*/ +void main() { + print(case3()); +}
diff --git a/pkg/dart2wasm/lib/class_info.dart b/pkg/dart2wasm/lib/class_info.dart index c94c023..27986fc 100644 --- a/pkg/dart2wasm/lib/class_info.dart +++ b/pkg/dart2wasm/lib/class_info.dart
@@ -25,6 +25,7 @@ static const hashBaseData = 4; static const closureContext = 2; static const closureFunction = 3; + static const typeTypeArguments = 3; static const typedListBaseLength = 2; static const typedListArray = 3; static const typedListViewTypedData = 3; @@ -50,6 +51,7 @@ check(translator.hashFieldBaseClass, "_index", FieldIndex.hashBaseIndex); check(translator.hashFieldBaseClass, "_data", FieldIndex.hashBaseData); check(translator.functionClass, "context", FieldIndex.closureContext); + check(translator.typeClass, "typeArguments", FieldIndex.typeTypeArguments); } }
diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart index d12efbd..2489dfb 100644 --- a/pkg/dart2wasm/lib/code_generator.dart +++ b/pkg/dart2wasm/lib/code_generator.dart
@@ -9,6 +9,7 @@ import 'package:dart2wasm/param_info.dart'; import 'package:dart2wasm/reference_extensions.dart'; import 'package:dart2wasm/translator.dart'; +import 'package:dart2wasm/types.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/type_environment.dart'; @@ -77,6 +78,8 @@ w.ValueType get voidMarker => translator.voidMarker; + Types get types => translator.types; + w.ValueType translateType(DartType type) => translator.translateType(type); w.Local addLocal(w.ValueType type) { @@ -87,7 +90,7 @@ return exp.getStaticType(typeContext); } - void _unimplemented( + void unimplemented( TreeNode node, Object message, List<w.ValueType> expectedTypes) { final text = "Not implemented: $message at ${node.location}"; print(text); @@ -99,18 +102,18 @@ @override void defaultInitializer(Initializer node) { - _unimplemented(node, node.runtimeType, const []); + unimplemented(node, node.runtimeType, const []); } @override w.ValueType defaultExpression(Expression node, w.ValueType expectedType) { - _unimplemented(node, node.runtimeType, [expectedType]); + unimplemented(node, node.runtimeType, [expectedType]); return expectedType; } @override void defaultStatement(Statement node) { - _unimplemented(node, node.runtimeType, const []); + unimplemented(node, node.runtimeType, const []); } /// Generate code for the body of the member. @@ -460,7 +463,8 @@ b.ref_as_non_null(); } for (TypeParameter typeParam in cls.typeParameters) { - _makeType(TypeParameterType(typeParam, Nullability.nonNullable), node); + types.makeType( + this, TypeParameterType(typeParam, Nullability.nonNullable), node); } _visitArguments(node.arguments, node.targetReference, 1); _call(node.targetReference); @@ -478,7 +482,7 @@ b.ref_as_non_null(); } for (DartType typeArg in supertype!.typeArguments) { - _makeType(typeArg, node); + types.makeType(this, typeArg, node); } _visitArguments(node.arguments, node.targetReference, 1 + supertype.typeArguments.length); @@ -594,8 +598,8 @@ // Only emit the type test if the guard is not [Object]. if (guard != translator.coreTypes.objectNonNullableRawType) { b.local_get(thrownException); - emitTypeTest( - guard, translator.coreTypes.objectNonNullableRawType, node); + types.emitTypeTest( + this, guard, translator.coreTypes.objectNonNullableRawType, node); b.i32_eqz(); b.br_if(catchBlock); } @@ -982,10 +986,10 @@ @override w.ValueType visitThisExpression( ThisExpression node, w.ValueType expectedType) { - return _visitThis(expectedType); + return visitThis(expectedType); } - w.ValueType _visitThis(w.ValueType expectedType) { + w.ValueType visitThis(w.ValueType expectedType) { w.ValueType thisType = thisLocal!.type.withNullability(false); w.ValueType preciseThisType = preciseThisLocal!.type.withNullability(false); if (!thisType.isSubtypeOf(expectedType) && @@ -1049,7 +1053,7 @@ _lookupSuperTarget(node.interfaceTarget!, setter: false).reference; w.BaseFunction targetFunction = translator.functions.getFunction(target); w.ValueType receiverType = targetFunction.type.inputs.first; - w.ValueType thisType = _visitThis(receiverType); + w.ValueType thisType = visitThis(receiverType); translator.convertType(function, thisType, receiverType); _visitArguments(node.arguments, target, 1); return _call(target); @@ -1080,7 +1084,7 @@ b.end(); return resultType; default: - _unimplemented(node, "Nullable invocation of ${target.name.text}", + unimplemented(node, "Nullable invocation of ${target.name.text}", [if (expectedType != voidMarker) expectedType]); return expectedType; } @@ -1103,7 +1107,7 @@ w.ValueType visitDynamicInvocation( DynamicInvocation node, w.ValueType expectedType) { if (node.name.text != "call") { - _unimplemented(node, "Dynamic invocation of ${node.name.text}", + unimplemented(node, "Dynamic invocation of ${node.name.text}", [if (expectedType != voidMarker) expectedType]); return expectedType; } @@ -1460,7 +1464,7 @@ wrap(ConstantExpression(TypeLiteralConstant(NullType())), resultType); break; default: - _unimplemented( + unimplemented( node, "Nullable get of ${target.name.text}", [resultType]); break; } @@ -1773,7 +1777,7 @@ final w.FunctionType signature = translator.signatureFor(target); final ParameterInfo paramInfo = translator.paramInfoFor(target); for (int i = 0; i < node.types.length; i++) { - _makeType(node.types[i], node); + types.makeType(this, node.types[i], node); } signatureOffset += node.types.length; for (int i = 0; i < node.positional.length; i++) { @@ -1812,7 +1816,7 @@ @override w.ValueType visitStringConcatenation( StringConcatenation node, w.ValueType expectedType) { - _makeList( + makeList( node.expressions, translator.fixedLengthListClass, InterfaceType(translator.stringBaseClass, Nullability.nonNullable), @@ -1884,11 +1888,11 @@ @override w.ValueType visitListLiteral(ListLiteral node, w.ValueType expectedType) { - return _makeList(node.expressions, translator.growableListClass, + return makeList(node.expressions, translator.growableListClass, node.typeArgument, node); } - w.ValueType _makeList(List<Expression> expressions, Class cls, + w.ValueType makeList(List<Expression> expressions, Class cls, DartType typeArg, TreeNode node) { ClassInfo info = translator.classInfo[cls]!; translator.functions.allocateClass(info.classId); @@ -1899,7 +1903,7 @@ b.i32_const(info.classId); b.i32_const(initialIdentityHash); - _makeType(typeArg, node); + types.makeType(this, typeArg, node); b.i64_const(length); if (options.lazyConstants) { // Avoid array.init instruction in lazy constants mode @@ -1935,8 +1939,8 @@ w.BaseFunction mapFactory = translator.functions.getFunction(translator.mapFactory.reference); w.ValueType factoryReturnType = mapFactory.type.outputs.single; - _makeType(node.keyType, node); - _makeType(node.valueType, node); + types.makeType(this, node.keyType, node); + types.makeType(this, node.valueType, node); b.call(mapFactory); if (node.entries.isEmpty) { return factoryReturnType; @@ -1962,167 +1966,16 @@ @override w.ValueType visitTypeLiteral(TypeLiteral node, w.ValueType expectedType) { - return _makeType(node.type, node); - } - - w.ValueType _makeType(DartType type, TreeNode node) { - w.ValueType typeType = - translator.classInfo[translator.typeClass]!.nullableType; - if (_isTypeConstant(type)) { - return wrap(ConstantExpression(TypeLiteralConstant(type)), typeType); - } - if (type is TypeParameterType) { - if (type.parameter.parent is FunctionNode) { - // Type argument to function - w.Local? local = typeLocals[type.parameter]; - if (local != null) { - b.local_get(local); - return local.type; - } else { - _unimplemented( - node, "Type parameter access inside lambda", [typeType]); - return typeType; - } - } - // Type argument of class - Class cls = type.parameter.parent as Class; - ClassInfo info = translator.classInfo[cls]!; - int fieldIndex = translator.typeParameterIndex[type.parameter]!; - w.ValueType thisType = _visitThis(info.nullableType); - translator.convertType(function, thisType, info.nullableType); - b.struct_get(info.struct, fieldIndex); - return typeType; - } - ClassInfo info = translator.classInfo[translator.typeClass]!; - translator.functions.allocateClass(info.classId); - if (type is FutureOrType) { - // TODO(askesc): Have an actual representation of FutureOr types - b.ref_null(info.nullableType.heapType); - return info.nullableType; - } - if (type is! InterfaceType) { - _unimplemented(node, type, [info.nullableType]); - return info.nullableType; - } - ClassInfo typeInfo = translator.classInfo[type.classNode]!; - w.ValueType typeListExpectedType = info.struct.fields[3].type.unpacked; - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); - b.i64_const(typeInfo.classId); - if (type.typeArguments.isEmpty) { - b.global_get(translator.constants.emptyTypeList); - translator.convertType(function, - translator.constants.emptyTypeList.type.type, typeListExpectedType); - } else if (type.typeArguments.every(_isTypeConstant)) { - ListConstant typeArgs = ListConstant( - InterfaceType(translator.typeClass, Nullability.nonNullable), - type.typeArguments.map((t) => TypeLiteralConstant(t)).toList()); - translator.constants - .instantiateConstant(function, b, typeArgs, typeListExpectedType); - } else { - w.ValueType listType = _makeList( - type.typeArguments.map((t) => TypeLiteral(t)).toList(), - translator.fixedLengthListClass, - InterfaceType(translator.typeClass, Nullability.nonNullable), - node); - translator.convertType(function, listType, typeListExpectedType); - } - translator.struct_new(b, info); - return info.nullableType; - } - - bool _isTypeConstant(DartType type) { - return type is DynamicType || - type is VoidType || - type is NeverType || - type is NullType || - type is FunctionType || - type is InterfaceType && type.typeArguments.every(_isTypeConstant); + return types.makeType(this, node.type, node); } @override w.ValueType visitIsExpression(IsExpression node, w.ValueType expectedType) { wrap(node.operand, translator.topInfo.nullableType); - emitTypeTest(node.type, dartTypeOf(node.operand), node); + types.emitTypeTest(this, node.type, dartTypeOf(node.operand), node); return w.NumType.i32; } - /// Test value against a Dart type. Expects the value on the stack as a - /// (ref null #Top) and leaves the result on the stack as an i32. - void emitTypeTest(DartType type, DartType operandType, TreeNode node) { - if (type is! InterfaceType) { - // TODO(askesc): Implement type test for remaining types - print("Not implemented: Type test with non-interface type $type" - " at ${node.location}"); - b.drop(); - b.i32_const(1); - return; - } - bool isNullable = operandType.isPotentiallyNullable; - w.Label? resultLabel; - if (isNullable) { - // Store operand in a temporary variable, since Binaryen does not support - // block inputs. - w.Local operand = addLocal(translator.topInfo.nullableType); - b.local_set(operand); - resultLabel = b.block(const [], const [w.NumType.i32]); - w.Label nullLabel = b.block(const [], const []); - b.local_get(operand); - b.br_on_null(nullLabel); - } - if (type.typeArguments.any((t) => t is! DynamicType)) { - // If the tested-against type as an instance of the static operand type - // has the same type arguments as the static operand type, it is not - // necessary to test the type arguments. - Class cls = translator.classForType(operandType); - InterfaceType? base = translator.hierarchy - .getTypeAsInstanceOf(type, cls, member.enclosingLibrary) - ?.withDeclaredNullability(operandType.declaredNullability); - if (base != operandType) { - print("Not implemented: Type test with type arguments" - " at ${node.location}"); - } - } - List<Class> concrete = translator.subtypes - .getSubtypesOf(type.classNode) - .where((c) => !c.isAbstract) - .toList(); - if (type.classNode == translator.coreTypes.functionClass) { - ClassInfo functionInfo = translator.classInfo[translator.functionClass]!; - translator.ref_test(b, functionInfo); - } else if (concrete.isEmpty) { - b.drop(); - b.i32_const(0); - } else if (concrete.length == 1) { - ClassInfo info = translator.classInfo[concrete.single]!; - b.struct_get(translator.topInfo.struct, FieldIndex.classId); - b.i32_const(info.classId); - b.i32_eq(); - } else { - w.Local idLocal = addLocal(w.NumType.i32); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); - b.local_set(idLocal); - w.Label done = b.block(const [], const [w.NumType.i32]); - b.i32_const(1); - for (Class cls in concrete) { - ClassInfo info = translator.classInfo[cls]!; - b.i32_const(info.classId); - b.local_get(idLocal); - b.i32_eq(); - b.br_if(done); - } - b.drop(); - b.i32_const(0); - b.end(); // done - } - if (isNullable) { - b.br(resultLabel!); - b.end(); // nullLabel - b.i32_const(type.declaredNullability == Nullability.nullable ? 1 : 0); - b.end(); // resultLabel - } - } - @override w.ValueType visitAsExpression(AsExpression node, w.ValueType expectedType) { w.Label asCheckBlock = b.block(); @@ -2132,10 +1985,10 @@ // We lower an `as` expression to a type test, throwing a [TypeError] if // the type test fails. - emitTypeTest(node.type, dartTypeOf(node.operand), node); + types.emitTypeTest(this, node.type, dartTypeOf(node.operand), node); b.br_if(asCheckBlock); b.local_get(operand); - _makeType(node.type, node); + types.makeType(this, node.type, node); _call(translator.stackTraceCurrent.reference); _call(translator.throwAsCheckError.reference); b.unreachable();
diff --git a/pkg/dart2wasm/lib/constants.dart b/pkg/dart2wasm/lib/constants.dart index 2744ea7..7a1a84a 100644 --- a/pkg/dart2wasm/lib/constants.dart +++ b/pkg/dart2wasm/lib/constants.dart
@@ -670,7 +670,8 @@ translator.functions.allocateClass(info.classId); return createConstant(constant, info.nonNullableType, (function, b) { ClassInfo typeInfo = translator.classInfo[type.classNode]!; - w.ValueType typeListExpectedType = info.struct.fields[3].type.unpacked; + w.ValueType typeListExpectedType = + info.struct.fields[FieldIndex.typeTypeArguments].type.unpacked; b.i32_const(info.classId); b.i32_const(initialIdentityHash);
diff --git a/pkg/dart2wasm/lib/intrinsics.dart b/pkg/dart2wasm/lib/intrinsics.dart index 7fb0cf5..bb31c61 100644 --- a/pkg/dart2wasm/lib/intrinsics.dart +++ b/pkg/dart2wasm/lib/intrinsics.dart
@@ -976,7 +976,8 @@ w.Local receiver = paramLocals[0]; ClassInfo info = translator.classInfo[translator.typeClass]!; translator.functions.allocateClass(info.classId); - w.ValueType typeListExpectedType = info.struct.fields[3].type.unpacked; + w.ValueType typeListExpectedType = + info.struct.fields[FieldIndex.typeTypeArguments].type.unpacked; b.i32_const(info.classId); b.i32_const(initialIdentityHash);
diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart index ecb5a41..d6711a2 100644 --- a/pkg/dart2wasm/lib/translator.dart +++ b/pkg/dart2wasm/lib/translator.dart
@@ -13,6 +13,7 @@ import 'package:dart2wasm/globals.dart'; import 'package:dart2wasm/param_info.dart'; import 'package:dart2wasm/reference_extensions.dart'; +import 'package:dart2wasm/types.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/class_hierarchy.dart' @@ -113,6 +114,7 @@ late final DispatchTable dispatchTable; late final Globals globals; late final Constants constants; + late final Types types; late final FunctionCollector functions; // Information about the program used and updated by the various phases. @@ -259,6 +261,7 @@ globals = Globals(this); constants = Constants(this); + types = Types(this); dispatchTable.build();
diff --git a/pkg/dart2wasm/lib/types.dart b/pkg/dart2wasm/lib/types.dart new file mode 100644 index 0000000..f9ee6a4 --- /dev/null +++ b/pkg/dart2wasm/lib/types.dart
@@ -0,0 +1,179 @@ +// Copyright (c) 2022, 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:dart2wasm/class_info.dart'; +import 'package:dart2wasm/code_generator.dart'; +import 'package:dart2wasm/translator.dart'; + +import 'package:kernel/ast.dart'; + +import 'package:wasm_builder/wasm_builder.dart' as w; + +/// Helper class for building runtime types. +class Types { + final Translator translator; + + Types(this.translator); + + List<Class> _getConcreteSubtypes(Class cls) => translator.subtypes + .getSubtypesOf(cls) + .where((c) => !c.isAbstract) + .toList(); + + bool _isTypeConstant(DartType type) { + return type is DynamicType || + type is VoidType || + type is NeverType || + type is NullType || + type is FunctionType || + type is InterfaceType && type.typeArguments.every(_isTypeConstant); + } + + /// Makes a `_Type` object on the stack. + w.ValueType makeType(CodeGenerator codeGen, DartType type, TreeNode node) { + w.ValueType typeType = + translator.classInfo[translator.typeClass]!.nullableType; + w.Instructions b = codeGen.b; + if (_isTypeConstant(type)) { + translator.constants.instantiateConstant( + codeGen.function, b, TypeLiteralConstant(type), typeType); + return typeType; + } + if (type is TypeParameterType) { + if (type.parameter.parent is FunctionNode) { + // Type argument to function + w.Local? local = codeGen.typeLocals[type.parameter]; + if (local != null) { + b.local_get(local); + return local.type; + } else { + codeGen.unimplemented( + node, "Type parameter access inside lambda", [typeType]); + return typeType; + } + } + // Type argument of class + Class cls = type.parameter.parent as Class; + ClassInfo info = translator.classInfo[cls]!; + int fieldIndex = translator.typeParameterIndex[type.parameter]!; + w.ValueType thisType = codeGen.visitThis(info.nullableType); + translator.convertType(codeGen.function, thisType, info.nullableType); + b.struct_get(info.struct, fieldIndex); + return typeType; + } + ClassInfo info = translator.classInfo[translator.typeClass]!; + translator.functions.allocateClass(info.classId); + if (type is FutureOrType) { + // TODO(askesc): Have an actual representation of FutureOr types + b.ref_null(info.nullableType.heapType); + return info.nullableType; + } + if (type is! InterfaceType) { + codeGen.unimplemented(node, type, [info.nullableType]); + return info.nullableType; + } + ClassInfo typeInfo = translator.classInfo[type.classNode]!; + w.ValueType typeListExpectedType = + info.struct.fields[FieldIndex.typeTypeArguments].type.unpacked; + b.i32_const(info.classId); + b.i32_const(initialIdentityHash); + b.i64_const(typeInfo.classId); + w.DefinedFunction function = codeGen.function; + if (type.typeArguments.isEmpty) { + b.global_get(translator.constants.emptyTypeList); + translator.convertType(function, + translator.constants.emptyTypeList.type.type, typeListExpectedType); + } else if (type.typeArguments.every(_isTypeConstant)) { + ListConstant typeArgs = ListConstant( + InterfaceType(translator.typeClass, Nullability.nonNullable), + type.typeArguments.map((t) => TypeLiteralConstant(t)).toList()); + translator.constants + .instantiateConstant(function, b, typeArgs, typeListExpectedType); + } else { + w.ValueType listType = codeGen.makeList( + type.typeArguments.map((t) => TypeLiteral(t)).toList(), + translator.fixedLengthListClass, + InterfaceType(translator.typeClass, Nullability.nonNullable), + node); + translator.convertType(function, listType, typeListExpectedType); + } + translator.struct_new(b, info); + return info.nullableType; + } + + /// Test value against a Dart type. Expects the value on the stack as a + /// (ref null #Top) and leaves the result on the stack as an i32. + void emitTypeTest(CodeGenerator codeGen, DartType type, DartType operandType, + TreeNode node) { + w.Instructions b = codeGen.b; + if (type is! InterfaceType) { + // TODO(askesc): Implement type test for remaining types + print("Not implemented: Type test with non-interface type $type" + " at ${node.location}"); + b.drop(); + b.i32_const(1); + return; + } + bool isNullable = operandType.isPotentiallyNullable; + w.Label? resultLabel; + if (isNullable) { + // Store operand in a temporary variable, since Binaryen does not support + // block inputs. + w.Local operand = codeGen.addLocal(translator.topInfo.nullableType); + b.local_set(operand); + resultLabel = b.block(const [], const [w.NumType.i32]); + w.Label nullLabel = b.block(const [], const []); + b.local_get(operand); + b.br_on_null(nullLabel); + } + if (type.typeArguments.any((t) => t is! DynamicType)) { + // If the tested-against type as an instance of the static operand type + // has the same type arguments as the static operand type, it is not + // necessary to test the type arguments. + Class cls = translator.classForType(operandType); + InterfaceType? base = translator.hierarchy + .getTypeAsInstanceOf(type, cls, codeGen.member.enclosingLibrary) + ?.withDeclaredNullability(operandType.declaredNullability); + if (base != operandType) { + print("Not implemented: Type test with type arguments" + " at ${node.location}"); + } + } + List<Class> concrete = _getConcreteSubtypes(type.classNode); + if (type.classNode == translator.coreTypes.functionClass) { + ClassInfo functionInfo = translator.classInfo[translator.functionClass]!; + translator.ref_test(b, functionInfo); + } else if (concrete.isEmpty) { + b.drop(); + b.i32_const(0); + } else if (concrete.length == 1) { + ClassInfo info = translator.classInfo[concrete.single]!; + b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.i32_const(info.classId); + b.i32_eq(); + } else { + w.Local idLocal = codeGen.addLocal(w.NumType.i32); + b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.local_set(idLocal); + w.Label done = b.block(const [], const [w.NumType.i32]); + b.i32_const(1); + for (Class cls in concrete) { + ClassInfo info = translator.classInfo[cls]!; + b.i32_const(info.classId); + b.local_get(idLocal); + b.i32_eq(); + b.br_if(done); + } + b.drop(); + b.i32_const(0); + b.end(); // done + } + if (isNullable) { + b.br(resultLabel!); + b.end(); // nullLabel + b.i32_const(type.declaredNullability == Nullability.nullable ? 1 : 0); + b.end(); // resultLabel + } + } +}
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart index 9b497f6..3645c43 100644 --- a/pkg/dartdev/lib/src/commands/compile.dart +++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -349,9 +349,9 @@ abbr: 'p', valueHelp: 'path', help: - '''Get package locations from the specified file instead of .packages. + '''Get package locations from the specified file instead of .dart_tool/package_config.json. <path> can be relative or absolute. -For example: dart compile $name --packages=/tmp/pkgs main.dart'''), +For example: dart compile $name --packages=/tmp/pkgs.json main.dart'''), super(name, description, verbose, hidden: hidden); }
diff --git a/pkg/dds/lib/src/devtools/handler.dart b/pkg/dds/lib/src/devtools/handler.dart index d323f9d..817ff17 100644 --- a/pkg/dds/lib/src/devtools/handler.dart +++ b/pkg/dds/lib/src/devtools/handler.dart
@@ -3,8 +3,11 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; import 'package:devtools_shared/devtools_server.dart'; +import 'package:path/path.dart' as path; import 'package:shelf/shelf.dart'; import 'package:shelf_static/shelf_static.dart'; import 'package:sse/server/sse_handler.dart'; @@ -29,21 +32,51 @@ ClientManager? clientManager, Handler? notFoundHandler, }) { - // Serves the web assets for DevTools. - final devtoolsAssetHandler = createStaticHandler( + // When served through DDS, the app root is /devtools/. + // This variable is used in base href and must start and end with `/`. + var appRoot = dds != null ? '/devtools/' : '/'; + if (dds?.authCodesEnabled ?? false) { + appRoot = '/${dds!.authCode}$appRoot'; + } + + const defaultDocument = 'index.html'; + final indexFile = File(path.join(buildDir, defaultDocument)); + + // Serves the static web assets for DevTools. + final devtoolsStaticAssetHandler = createStaticHandler( buildDir, - defaultDocument: 'index.html', + defaultDocument: defaultDocument, ); + /// A wrapper around [devtoolsStaticAssetHandler] that handles serving + /// index.html up for / and non-file requests like /memory, /inspector, etc. + /// with the correct base href for the DevTools root. + final devtoolsAssetHandler = (Request request) { + // To avoid hard-coding a set of page names here (or needing access to one + // from DevTools, assume any single-segment path with no extension is a + // DevTools page that needs to serve up index.html). + final pathSegments = request.url.pathSegments; + final isValidRootPage = pathSegments.isEmpty || + (pathSegments.length == 1 && !pathSegments[0].contains('.')); + if (isValidRootPage) { + return _serveStaticFile( + request, + indexFile, + 'text/html', + baseHref: appRoot, + ); + } + + return devtoolsStaticAssetHandler(request); + }; + // Support DevTools client-server interface via SSE. // Note: the handler path needs to match the full *original* path, not the // current request URL (we remove '/devtools' in the initial router but we // need to include it here). - final devToolsSseHandlerPath = dds != null ? '/devtools/api/sse' : '/api/sse'; + final devToolsSseHandlerPath = '${appRoot}api/sse'; final devToolsApiHandler = SseHandler( - (dds?.authCodesEnabled ?? false) - ? Uri.parse('/${dds!.authCode}$devToolsSseHandlerPath') - : Uri.parse(devToolsSseHandlerPath), + Uri.parse(devToolsSseHandlerPath), keepAlive: sseKeepAlive, ); @@ -78,7 +111,7 @@ return ServerApi.handle(request); }; - return (request) { + return (Request request) { if (notFoundHandler != null) { final pathSegments = request.url.pathSegments; if (pathSegments.isEmpty || pathSegments.first != 'devtools') { @@ -90,3 +123,30 @@ return devtoolsHandler(request); }; } + +/// Serves [file] for all requests. +/// +/// If [baseHref] is provided, any existing `<base href="">` tag will be +/// rewritten with this path. +Future<Response> _serveStaticFile( + Request request, + File file, + String contentType, { + String? baseHref, +}) async { + final headers = {HttpHeaders.contentTypeHeader: contentType}; + var contents = file.readAsStringSync(); + + if (baseHref != null) { + assert(baseHref.startsWith('/')); + assert(baseHref.endsWith('/')); + // Replace the base href to match where the app is being served from. + final baseHrefPattern = RegExp(r'<base href="\/"\s?\/?>'); + contents = contents.replaceFirst( + baseHrefPattern, + '<base href="${htmlEscape.convert(baseHref)}">', + ); + } + + return Response.ok(contents, headers: headers); +}
diff --git a/pkg/dds/test/devtools_server/devtools_server_path_strategy_dds_test.dart b/pkg/dds/test/devtools_server/devtools_server_path_strategy_dds_test.dart new file mode 100644 index 0000000..78baa0c --- /dev/null +++ b/pkg/dds/test/devtools_server/devtools_server_path_strategy_dds_test.dart
@@ -0,0 +1,77 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:path/path.dart' as path; +import 'package:test/test.dart'; + +import 'utils/server_driver.dart'; + +late final DevToolsServerTestController testController; + +void main() { + const testScriptContents = + 'Future<void> main() => Future.delayed(const Duration(minutes: 10));'; + final tempDir = Directory.systemTemp.createTempSync('devtools_server.'); + final devToolsBannerRegex = + RegExp(r'DevTools[\w\s]+at: (https?:.*\/devtools\/)'); + + test('serves index.html contents for /token/devtools/inspector', () async { + final testFile = File(path.join(tempDir.path, 'foo.dart')); + testFile.writeAsStringSync(testScriptContents); + + final proc = await Process.start( + Platform.resolvedExecutable, ['--observe=0', testFile.path]); + try { + final completer = Completer<String>(); + proc.stderr + .transform(utf8.decoder) + .transform(LineSplitter()) + .listen(print); + proc.stdout.transform(utf8.decoder).transform(LineSplitter()).listen( + (String line) { + print(line); + final match = devToolsBannerRegex.firstMatch(line); + if (match != null) { + completer.complete(match.group(1)); + } + }, + onDone: () { + if (!completer.isCompleted) { + completer.completeError( + 'Process ended without emitting DevTools banner'); + } + }, + onError: (e) { + if (!completer.isCompleted) { + completer.completeError(e); + } + }, + ); + + final devToolsUrl = Uri.parse(await completer.future); + final httpClient = HttpClient(); + late HttpClientResponse resp; + try { + final req = await httpClient.get( + devToolsUrl.host, devToolsUrl.port, '${devToolsUrl.path}inspector'); + resp = await req.close(); + expect(resp.statusCode, 200); + final bodyContent = await resp.transform(utf8.decoder).join(); + expect(bodyContent, contains('Dart DevTools')); + final expectedBaseHref = htmlEscape.convert(devToolsUrl.path); + expect(bodyContent, contains('<base href="$expectedBaseHref">')); + } finally { + httpClient.close(); + } + } finally { + proc.kill(); + } + // TODO(dantup): Unskip this test once DevTools has rolled into + // the SDK so that contains the (newly-added) base href tag. + }, timeout: const Timeout.factor(10), skip: true); +}
diff --git a/pkg/dds/test/devtools_server/devtools_server_path_strategy_test.dart b/pkg/dds/test/devtools_server/devtools_server_path_strategy_test.dart new file mode 100644 index 0000000..9185c15 --- /dev/null +++ b/pkg/dds/test/devtools_server/devtools_server_path_strategy_test.dart
@@ -0,0 +1,72 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert'; +import 'dart:io'; + +import 'package:test/test.dart'; + +import 'utils/server_driver.dart'; + +late final DevToolsServerTestController testController; + +void main() { + testController = DevToolsServerTestController(); + + setUp(() async { + await testController.setUp(); + }); + + tearDown(() async { + await testController.tearDown(); + }); + + test('serves index.html contents for /inspector', () async { + final server = await DevToolsServerDriver.create(); + final httpClient = HttpClient(); + late HttpClientResponse resp; + try { + final startedEvent = (await server.stdout.firstWhere( + (map) => map!['event'] == 'server.started', + ))!; + final host = startedEvent['params']['host']; + final port = startedEvent['params']['port']; + + final req = await httpClient.get(host, port, '/inspector'); + resp = await req.close(); + expect(resp.statusCode, 200); + final bodyContent = await resp.transform(utf8.decoder).join(); + expect(bodyContent, contains('Dart DevTools')); + final expectedBaseHref = htmlEscape.convert('/'); + expect(bodyContent, contains('<base href="$expectedBaseHref">')); + } finally { + httpClient.close(); + server.kill(); + } + // TODO(dantup): Unskip this test once DevTools has rolled into + // the SDK so that contains the (newly-added) base href tag. + }, timeout: const Timeout.factor(10), skip: true); + + test('serves 404 contents for requests that are not pages', () async { + final server = await DevToolsServerDriver.create(); + final httpClient = HttpClient(); + late HttpClientResponse resp; + try { + final startedEvent = (await server.stdout.firstWhere( + (map) => map!['event'] == 'server.started', + ))!; + final host = startedEvent['params']['host']; + final port = startedEvent['params']['port']; + + // The index page is only served up for extension-less requests. + final req = await httpClient.get(host, port, '/inspector.html'); + resp = await req.close(); + expect(resp.statusCode, 404); + } finally { + httpClient.close(); + await resp.drain(); + server.kill(); + } + }, timeout: const Timeout.factor(10)); +}
diff --git a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart index 1edef57..77159ce 100644 --- a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart +++ b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
@@ -159,22 +159,41 @@ reference); } -/// Creates the parameters and body for [tearOff] based on [constructor] in -/// [enclosingClass]. -void buildConstructorTearOffProcedure(Procedure tearOff, Member constructor, - Class enclosingClass, SourceLibraryBuilder libraryBuilder) { +/// Creates the parameters and body for [tearOff] based on +/// [declarationConstructor] in [enclosingClass]. +/// +/// The [declarationConstructor] is the origin constructor and +/// [implementationConstructor] is the patch constructor, if patched, otherwise +/// it is the [declarationConstructor]. +void buildConstructorTearOffProcedure( + {required Procedure tearOff, + required Member declarationConstructor, + required Member implementationConstructor, + required Class enclosingClass, + required SourceLibraryBuilder libraryBuilder}) { assert( - constructor is Constructor || - (constructor is Procedure && constructor.isFactory) || - (constructor is Procedure && constructor.isStatic), - "Unexpected constructor tear off target $constructor " - "(${constructor.runtimeType})."); + declarationConstructor is Constructor || + (declarationConstructor is Procedure && + declarationConstructor.isFactory) || + (declarationConstructor is Procedure && + declarationConstructor.isStatic), + "Unexpected constructor tear off target $declarationConstructor " + "(${declarationConstructor.runtimeType})."); + assert( + declarationConstructor is Constructor || + (declarationConstructor is Procedure && + declarationConstructor.isFactory) || + (declarationConstructor is Procedure && + declarationConstructor.isStatic), + "Unexpected constructor tear off target $declarationConstructor " + "(${declarationConstructor.runtimeType})."); + + FunctionNode function = implementationConstructor.function!; int fileOffset = tearOff.fileOffset; - FunctionNode function = constructor.function!; List<TypeParameter> classTypeParameters; - if (constructor is Constructor) { + if (declarationConstructor is Constructor) { // Generative constructors implicitly have the type parameters of the // enclosing class. classTypeParameters = enclosingClass.typeParameters; @@ -189,37 +208,54 @@ List<DartType> typeArguments = freshTypeParameters.freshTypeArguments; Substitution substitution = freshTypeParameters.substitution; - _createParameters(tearOff, constructor, substitution, libraryBuilder); + _createParameters(tearOff, implementationConstructor, function, substitution, + libraryBuilder); Arguments arguments = _createArguments(tearOff, typeArguments, fileOffset); - _createTearOffBody(tearOff, constructor, arguments); + _createTearOffBody(tearOff, declarationConstructor, arguments); tearOff.function.fileOffset = tearOff.fileOffset; tearOff.function.fileEndOffset = tearOff.fileOffset; updatePrivateMemberName(tearOff, libraryBuilder); } /// Creates the parameters and body for [tearOff] for a typedef tearoff of -/// [constructor] in [enclosingClass] with [typeParameters] as the typedef -/// parameters and [typeArguments] as the arguments passed to the +/// [declarationConstructor] in [enclosingClass] with [typeParameters] as the +/// typedef parameters and [typeArguments] as the arguments passed to the /// [enclosingClass]. +/// +/// The [declarationConstructor] is the origin constructor and +/// [implementationConstructor] is the patch constructor, if patched, otherwise +/// it is the [declarationConstructor]. void buildTypedefTearOffProcedure( - Procedure tearOff, - Member constructor, - Class enclosingClass, - List<TypeParameter> typeParameters, - List<DartType> typeArguments, - SourceLibraryBuilder libraryBuilder) { + {required Procedure tearOff, + required Member declarationConstructor, + required Member implementationConstructor, + required Class enclosingClass, + required List<TypeParameter> typeParameters, + required List<DartType> typeArguments, + required SourceLibraryBuilder libraryBuilder}) { assert( - constructor is Constructor || - (constructor is Procedure && constructor.isFactory) || - (constructor is Procedure && constructor.isStatic), - "Unexpected constructor tear off target $constructor " - "(${constructor.runtimeType})."); + declarationConstructor is Constructor || + (declarationConstructor is Procedure && + declarationConstructor.isFactory) || + (declarationConstructor is Procedure && + declarationConstructor.isStatic), + "Unexpected constructor tear off target $declarationConstructor " + "(${declarationConstructor.runtimeType})."); + assert( + implementationConstructor is Constructor || + (implementationConstructor is Procedure && + implementationConstructor.isFactory) || + (implementationConstructor is Procedure && + implementationConstructor.isStatic), + "Unexpected constructor tear off target $implementationConstructor " + "(${declarationConstructor.runtimeType})."); + + FunctionNode function = implementationConstructor.function!; int fileOffset = tearOff.fileOffset; - FunctionNode function = constructor.function!; List<TypeParameter> classTypeParameters; - if (constructor is Constructor) { + if (declarationConstructor is Constructor) { // Generative constructors implicitly have the type parameters of the // enclosing class. classTypeParameters = enclosingClass.typeParameters; @@ -242,37 +278,43 @@ } _createParameters( tearOff, - constructor, + implementationConstructor, + function, Substitution.fromPairs(classTypeParameters, typeArguments), libraryBuilder); Arguments arguments = _createArguments(tearOff, typeArguments, fileOffset); - _createTearOffBody(tearOff, constructor, arguments); + _createTearOffBody(tearOff, declarationConstructor, arguments); tearOff.function.fileOffset = tearOff.fileOffset; tearOff.function.fileEndOffset = tearOff.fileOffset; updatePrivateMemberName(tearOff, libraryBuilder); } /// Creates the parameters for the redirecting factory [tearOff] based on the -/// [redirectingConstructor] declaration. +/// [declarationConstructor] declaration. +/// +/// The [declarationConstructor] is the [Procedure] for the origin constructor +/// and [implementationConstructorFunctionNode] is the [FunctionNode] for the +/// implementation constructor. If the constructor is patched, these are not +/// connected until [Builder.finishPatch]. FreshTypeParameters buildRedirectingFactoryTearOffProcedureParameters( - Procedure tearOff, - Procedure redirectingConstructor, - SourceLibraryBuilder libraryBuilder) { - assert(redirectingConstructor.isRedirectingFactory); - FunctionNode function = redirectingConstructor.function; + {required Procedure tearOff, + required Procedure implementationConstructor, + required SourceLibraryBuilder libraryBuilder}) { + assert(implementationConstructor.isRedirectingFactory); + FunctionNode function = implementationConstructor.function; FreshTypeParameters freshTypeParameters = _createFreshTypeParameters(function.typeParameters, tearOff.function); Substitution substitution = freshTypeParameters.substitution; - _createParameters( - tearOff, redirectingConstructor, substitution, libraryBuilder); + _createParameters(tearOff, implementationConstructor, function, substitution, + libraryBuilder); tearOff.function.fileOffset = tearOff.fileOffset; tearOff.function.fileEndOffset = tearOff.fileOffset; updatePrivateMemberName(tearOff, libraryBuilder); return freshTypeParameters; } -/// Creates the body for the redirecting factory [tearOff] with the target -/// [constructor] and [typeArguments]. +/// Creates the body for the redirecting factory [tearOff] with the [target] +/// constructor and [typeArguments]. /// /// Returns the [DelayedDefaultValueCloner] object need to perform default value /// computation. @@ -355,9 +397,12 @@ /// Creates the parameters for the [tearOff] lowering based of the parameters /// in [constructor] and using the [substitution] to compute the parameter and /// return types. -void _createParameters(Procedure tearOff, Member constructor, - Substitution substitution, SourceLibraryBuilder libraryBuilder) { - FunctionNode function = constructor.function!; +void _createParameters( + Procedure tearOff, + Member constructor, + FunctionNode function, + Substitution substitution, + SourceLibraryBuilder libraryBuilder) { for (VariableDeclaration constructorParameter in function.positionalParameters) { VariableDeclaration tearOffParameter = new VariableDeclaration(
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart index 75a94cf..ffbbab7 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_helper.dart
@@ -300,3 +300,39 @@ _hasBeenInferred = true; } } + +/// Copies properties, function parameters and body from the [patch] constructor +/// to its [origin]. +void finishConstructorPatch(Constructor origin, Constructor patch) { + // TODO(ahe): restore file-offset once we track both origin and patch file + // URIs. See https://github.com/dart-lang/sdk/issues/31579 + origin.fileUri = patch.fileUri; + origin.startFileOffset = patch.startFileOffset; + origin.fileOffset = patch.fileOffset; + origin.fileEndOffset = patch.fileEndOffset; + origin.annotations.forEach((m) => m.fileOffset = patch.fileOffset); + + origin.isExternal = patch.isExternal; + origin.function = patch.function; + origin.function.parent = origin; + origin.initializers = patch.initializers; + setParents(origin.initializers, origin); +} + +/// Copies properties, function parameters and body from the [patch] procedure +/// to its [origin]. +void finishProcedurePatch(Procedure origin, Procedure patch) { + // TODO(ahe): restore file-offset once we track both origin and patch file + // URIs. See https://github.com/dart-lang/sdk/issues/31579 + origin.fileUri = patch.fileUri; + origin.startFileOffset = patch.startFileOffset; + origin.fileOffset = patch.fileOffset; + origin.fileEndOffset = patch.fileEndOffset; + origin.annotations.forEach((m) => m.fileOffset = patch.fileOffset); + + origin.isAbstract = patch.isAbstract; + origin.isExternal = patch.isExternal; + origin.function = patch.function; + origin.function.parent = origin; + origin.isRedirectingFactory = patch.isRedirectingFactory; +}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart index 5794d25..c80faa19 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -1092,8 +1092,12 @@ forAbstractClassOrEnum: classBuilder.isAbstract); if (constructorTearOff != null) { - buildConstructorTearOffProcedure(constructorTearOff, constructor, - classBuilder.cls, classBuilder.libraryBuilder); + buildConstructorTearOffProcedure( + tearOff: constructorTearOff, + declarationConstructor: constructor, + implementationConstructor: constructor, + enclosingClass: classBuilder.cls, + libraryBuilder: classBuilder.libraryBuilder); } SyntheticSourceConstructorBuilder constructorBuilder = new SyntheticSourceConstructorBuilder( @@ -1170,8 +1174,12 @@ forAbstractClassOrEnum: enclosingClass.isAbstract || enclosingClass.isEnum); if (constructorTearOff != null) { - buildConstructorTearOffProcedure(constructorTearOff, constructor, - classBuilder.cls, classBuilder.libraryBuilder); + buildConstructorTearOffProcedure( + tearOff: constructorTearOff, + declarationConstructor: constructor, + implementationConstructor: constructor, + enclosingClass: classBuilder.cls, + libraryBuilder: classBuilder.libraryBuilder); } return new SyntheticSourceConstructorBuilder( classBuilder, constructor, constructorTearOff);
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart index 3aa7702..c0dadf6 100644 --- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -27,7 +27,11 @@ import '../kernel/expression_generator_helper.dart'; import '../kernel/hierarchy/class_member.dart' show ClassMember; import '../kernel/kernel_helper.dart' - show DelayedDefaultValueCloner, TypeDependency; + show + DelayedDefaultValueCloner, + TypeDependency, + finishConstructorPatch, + finishProcedurePatch; import '../kernel/utils.dart' show isRedirectingGenerativeConstructorImplementation; import '../messages.dart' @@ -202,8 +206,12 @@ updatePrivateMemberName(_constructor, libraryBuilder); if (_constructorTearOff != null) { - buildConstructorTearOffProcedure(_constructorTearOff!, _constructor, - classBuilder.cls, libraryBuilder); + buildConstructorTearOffProcedure( + tearOff: _constructorTearOff!, + declarationConstructor: constructor, + implementationConstructor: _constructor, + enclosingClass: classBuilder.cls, + libraryBuilder: libraryBuilder); } _hasBeenBuilt = true; @@ -660,20 +668,11 @@ } void _finishPatch() { - // TODO(ahe): restore file-offset once we track both origin and patch file - // URIs. See https://github.com/dart-lang/sdk/issues/31579 - origin.constructor.fileUri = fileUri; - origin.constructor.startFileOffset = _constructor.startFileOffset; - origin.constructor.fileOffset = _constructor.fileOffset; - origin.constructor.fileEndOffset = _constructor.fileEndOffset; - origin.constructor.annotations - .forEach((m) => m.fileOffset = _constructor.fileOffset); + finishConstructorPatch(origin.constructor, _constructor); - origin.constructor.isExternal = _constructor.isExternal; - origin.constructor.function = _constructor.function; - origin.constructor.function.parent = origin.constructor; - origin.constructor.initializers = _constructor.initializers; - setParents(origin.constructor.initializers, origin.constructor); + if (_constructorTearOff != null) { + finishProcedurePatch(origin._constructorTearOff!, _constructorTearOff!); + } } @override
diff --git a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart index cef67f3..09523b6 100644 --- a/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
@@ -151,8 +151,12 @@ _procedureInternal.isStatic = isStatic; if (_factoryTearOff != null) { - buildConstructorTearOffProcedure(_factoryTearOff!, _procedureInternal, - classBuilder!.cls, libraryBuilder); + buildConstructorTearOffProcedure( + tearOff: _factoryTearOff!, + declarationConstructor: _procedure, + implementationConstructor: _procedureInternal, + enclosingClass: classBuilder!.cls, + libraryBuilder: libraryBuilder); } return _procedureInternal; } @@ -224,21 +228,11 @@ } void _finishPatch() { - // TODO(ahe): restore file-offset once we track both origin and patch file - // URIs. See https://github.com/dart-lang/sdk/issues/31579 - origin._procedure.fileUri = fileUri; - origin._procedure.startFileOffset = _procedureInternal.startFileOffset; - origin._procedure.fileOffset = _procedureInternal.fileOffset; - origin._procedure.fileEndOffset = _procedureInternal.fileEndOffset; - origin._procedure.annotations - .forEach((m) => m.fileOffset = _procedureInternal.fileOffset); + finishProcedurePatch(origin._procedure, _procedureInternal); - origin._procedure.isAbstract = _procedureInternal.isAbstract; - origin._procedure.isExternal = _procedureInternal.isExternal; - origin._procedure.function = _procedureInternal.function; - origin._procedure.function.parent = origin._procedure; - origin._procedure.isRedirectingFactory = - _procedureInternal.isRedirectingFactory; + if (_factoryTearOff != null) { + finishProcedurePatch(origin._factoryTearOff!, _factoryTearOff!); + } } @override @@ -373,7 +367,9 @@ if (_factoryTearOff != null) { _tearOffTypeParameters = buildRedirectingFactoryTearOffProcedureParameters( - _factoryTearOff!, _procedureInternal, libraryBuilder); + tearOff: _factoryTearOff!, + implementationConstructor: _procedureInternal, + libraryBuilder: libraryBuilder); } return _procedureInternal; }
diff --git a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart index 89731b6..1a7fe1f 100644 --- a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
@@ -16,6 +16,7 @@ import '../builder/type_variable_builder.dart'; import '../kernel/hierarchy/class_member.dart'; import '../kernel/hierarchy/members_builder.dart'; +import '../kernel/kernel_helper.dart'; import '../kernel/member_covariance.dart'; import '../source/name_scheme.dart'; import '../source/source_library_builder.dart' show SourceLibraryBuilder; @@ -470,20 +471,7 @@ int finishPatch() { if (!isPatch) return 0; - // TODO(ahe): restore file-offset once we track both origin and patch file - // URIs. See https://github.com/dart-lang/sdk/issues/31579 - origin.procedure.fileUri = fileUri; - origin.procedure.startFileOffset = _procedure.startFileOffset; - origin.procedure.fileOffset = _procedure.fileOffset; - origin.procedure.fileEndOffset = _procedure.fileEndOffset; - origin.procedure.annotations - .forEach((m) => m.fileOffset = _procedure.fileOffset); - - origin.procedure.isAbstract = _procedure.isAbstract; - origin.procedure.isExternal = _procedure.isExternal; - origin.procedure.function = _procedure.function; - origin.procedure.function.parent = origin.procedure; - origin.procedure.isRedirectingFactory = _procedure.isRedirectingFactory; + finishProcedurePatch(origin.procedure, _procedure); return 1; }
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart index 720a1b4..c24455e 100644 --- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -4,7 +4,6 @@ library fasta.source_type_alias_builder; -import 'package:front_end/src/fasta/kernel/expression_generator_helper.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/class_hierarchy.dart'; import 'package:kernel/type_environment.dart'; @@ -24,6 +23,7 @@ import '../fasta_codes.dart' show noLength, templateCyclicTypedef, templateTypeArgumentMismatch; import '../kernel/constructor_tearoff_lowering.dart'; +import '../kernel/expression_generator_helper.dart'; import '../kernel/kernel_helper.dart'; import '../problems.dart' show unhandled; import '../scope.dart'; @@ -275,14 +275,14 @@ Map<Procedure, Member>? _tearOffDependencies; void buildTypedefTearOffs( - SourceLibraryBuilder library, void Function(Procedure) f) { + SourceLibraryBuilder libraryBuilder, void Function(Procedure) f) { TypeDeclarationBuilder? declaration = unaliasDeclaration(null); DartType? targetType = typedef.type; if (declaration is ClassBuilder && targetType is InterfaceType && typedef.typeParameters.isNotEmpty && - !isProperRenameForClass( - library.loader.typeEnvironment, typedef, library.library)) { + !isProperRenameForClass(libraryBuilder.loader.typeEnvironment, typedef, + libraryBuilder.library)) { tearOffs = {}; _tearOffDependencies = {}; declaration @@ -295,19 +295,31 @@ Name targetName = new Name(constructorName, declaration.libraryBuilder.library); Reference? tearOffReference; - if (library.referencesFromIndexed != null) { - tearOffReference = library.referencesFromIndexed! + if (libraryBuilder.referencesFromIndexed != null) { + tearOffReference = libraryBuilder.referencesFromIndexed! .lookupGetterReference(typedefTearOffName(name, constructorName, - library.referencesFromIndexed!.library)); + libraryBuilder.referencesFromIndexed!.library)); } Procedure tearOff = tearOffs![targetName] = - createTypedefTearOffProcedure(name, constructorName, library, - target.fileUri, target.fileOffset, tearOffReference); + createTypedefTearOffProcedure( + name, + constructorName, + libraryBuilder, + target.fileUri, + target.fileOffset, + tearOffReference); _tearOffDependencies![tearOff] = target; - buildTypedefTearOffProcedure(tearOff, target, declaration.cls, - typedef.typeParameters, targetType.typeArguments, library); + buildTypedefTearOffProcedure( + tearOff: tearOff, + declarationConstructor: target, + // TODO(johnniwinther): Handle patched constructors. + implementationConstructor: target, + enclosingClass: declaration.cls, + typeParameters: typedef.typeParameters, + typeArguments: targetType.typeArguments, + libraryBuilder: libraryBuilder); f(tearOff); } });
diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart b/pkg/front_end/testcases/dart2js/issue48776.dart new file mode 100644 index 0000000..5bad3b1 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart
@@ -0,0 +1,7 @@ +// Copyright (c) 2022, 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. + +main() { + BigInt.from; +}
diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.strong.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.strong.expect new file mode 100644 index 0000000..7fd42484 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.strong.expect
@@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method main() → dynamic { + #C1; +} + +constants { + #C1 = static-tearoff core::BigInt::_#from#tearOff +}
diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.strong.transformed.expect new file mode 100644 index 0000000..7fd42484 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.strong.transformed.expect
@@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method main() → dynamic { + #C1; +} + +constants { + #C1 = static-tearoff core::BigInt::_#from#tearOff +}
diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline.expect new file mode 100644 index 0000000..bae895a --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline.expect
@@ -0,0 +1 @@ +main() {}
diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline_modelled.expect new file mode 100644 index 0000000..bae895a --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@ +main() {}
diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.weak.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.expect new file mode 100644 index 0000000..7fd42484 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.expect
@@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method main() → dynamic { + #C1; +} + +constants { + #C1 = static-tearoff core::BigInt::_#from#tearOff +}
diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.weak.modular.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.modular.expect new file mode 100644 index 0000000..7fd42484 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.modular.expect
@@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method main() → dynamic { + #C1; +} + +constants { + #C1 = static-tearoff core::BigInt::_#from#tearOff +}
diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.outline.expect new file mode 100644 index 0000000..e2cba6b --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.outline.expect
@@ -0,0 +1,5 @@ +library /*isNonNullableByDefault*/; +import self as self; + +static method main() → dynamic + ;
diff --git a/pkg/front_end/testcases/dart2js/issue48776.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.transformed.expect new file mode 100644 index 0000000..7fd42484 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/issue48776.dart.weak.transformed.expect
@@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method main() → dynamic { + #C1; +} + +constants { + #C1 = static-tearoff core::BigInt::_#from#tearOff +}
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/libraries.json b/pkg/front_end/testcases/dart2js/tear_off_patch/libraries.json new file mode 100644 index 0000000..154c73c --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/libraries.json
@@ -0,0 +1,12 @@ +{ + "none": { + "libraries": { + "test": { + "patches": [ + "patch_lib.dart" + ], + "uri": "origin_lib.dart" + } + } + } +}
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart new file mode 100644 index 0000000..676f68a --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart
@@ -0,0 +1,20 @@ +// Copyright (c) 2022, 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 'dart:test'; + +main() { + Class.new; + Class.fact; + Class.redirect; + Class.redirect2; + ClassImpl.new; + ClassImpl.patched; + Alias.new; + Alias.fact; + Alias.redirect; + Alias.redirect2; + AliasImpl.new; + AliasImpl.patched; +}
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.expect new file mode 100644 index 0000000..3ba9f86 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.expect
@@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias<T extends core::num> = test::Class<T>; +typedef AliasImpl<T extends core::num> = test::ClassImpl<T>; +@#C13 +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class<test::Class::T%> + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class<test::Class::_#new#tearOff::T%> + return new test::Class::•<test::Class::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class<test::Class::fact::T%> + return new test::ClassImpl::•<test::Class::fact::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class<test::Class::_#fact#tearOff::T%> + return test::Class::fact<test::Class::_#fact#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class<test::Class::redirect::T%> + return new test::ClassImpl::•<test::Class::redirect::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect#tearOff::T%> + return new test::ClassImpl::•<test::Class::_#redirect#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class<test::Class::redirect2::T%> + return new test::ClassImpl::patched<test::Class::redirect2::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect2#tearOff::T%> + return new test::ClassImpl::patched<test::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#new#tearOff::T%> + return new test::ClassImpl::•<test::ClassImpl::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#patched#tearOff::T%> + return new test::ClassImpl::patched<test::ClassImpl::_#patched#tearOff::T%>(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class<test::_#Alias#new#tearOff::T> + return new test::Class::•<test::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class<test::_#Alias#fact#tearOff::T> + return test::Class::fact<test::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect#tearOff::T> + return test::Class::_#redirect#tearOff<test::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect2#tearOff::T> + return test::Class::_#redirect2#tearOff<test::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#new#tearOff::T> + return new test::ClassImpl::•<test::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#patched#tearOff::T> + return new test::ClassImpl::patched<test::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +}
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.transformed.expect new file mode 100644 index 0000000..3ba9f86 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.strong.transformed.expect
@@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias<T extends core::num> = test::Class<T>; +typedef AliasImpl<T extends core::num> = test::ClassImpl<T>; +@#C13 +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class<test::Class::T%> + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class<test::Class::_#new#tearOff::T%> + return new test::Class::•<test::Class::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class<test::Class::fact::T%> + return new test::ClassImpl::•<test::Class::fact::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class<test::Class::_#fact#tearOff::T%> + return test::Class::fact<test::Class::_#fact#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class<test::Class::redirect::T%> + return new test::ClassImpl::•<test::Class::redirect::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect#tearOff::T%> + return new test::ClassImpl::•<test::Class::_#redirect#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class<test::Class::redirect2::T%> + return new test::ClassImpl::patched<test::Class::redirect2::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect2#tearOff::T%> + return new test::ClassImpl::patched<test::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#new#tearOff::T%> + return new test::ClassImpl::•<test::ClassImpl::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#patched#tearOff::T%> + return new test::ClassImpl::patched<test::ClassImpl::_#patched#tearOff::T%>(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class<test::_#Alias#new#tearOff::T> + return new test::Class::•<test::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class<test::_#Alias#fact#tearOff::T> + return test::Class::fact<test::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect#tearOff::T> + return test::Class::_#redirect#tearOff<test::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect2#tearOff::T> + return test::Class::_#redirect2#tearOff<test::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#new#tearOff::T> + return new test::ClassImpl::•<test::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#patched#tearOff::T> + return new test::ClassImpl::patched<test::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +}
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline.expect new file mode 100644 index 0000000..3c9c90e --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@ +import 'dart:test'; + +main() {}
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline_modelled.expect new file mode 100644 index 0000000..3c9c90e --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@ +import 'dart:test'; + +main() {}
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.expect new file mode 100644 index 0000000..3ba9f86 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.expect
@@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias<T extends core::num> = test::Class<T>; +typedef AliasImpl<T extends core::num> = test::ClassImpl<T>; +@#C13 +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class<test::Class::T%> + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class<test::Class::_#new#tearOff::T%> + return new test::Class::•<test::Class::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class<test::Class::fact::T%> + return new test::ClassImpl::•<test::Class::fact::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class<test::Class::_#fact#tearOff::T%> + return test::Class::fact<test::Class::_#fact#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class<test::Class::redirect::T%> + return new test::ClassImpl::•<test::Class::redirect::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect#tearOff::T%> + return new test::ClassImpl::•<test::Class::_#redirect#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class<test::Class::redirect2::T%> + return new test::ClassImpl::patched<test::Class::redirect2::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect2#tearOff::T%> + return new test::ClassImpl::patched<test::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#new#tearOff::T%> + return new test::ClassImpl::•<test::ClassImpl::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#patched#tearOff::T%> + return new test::ClassImpl::patched<test::ClassImpl::_#patched#tearOff::T%>(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class<test::_#Alias#new#tearOff::T> + return new test::Class::•<test::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class<test::_#Alias#fact#tearOff::T> + return test::Class::fact<test::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect#tearOff::T> + return test::Class::_#redirect#tearOff<test::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect2#tearOff::T> + return test::Class::_#redirect2#tearOff<test::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#new#tearOff::T> + return new test::ClassImpl::•<test::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#patched#tearOff::T> + return new test::ClassImpl::patched<test::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +}
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.modular.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.modular.expect new file mode 100644 index 0000000..3ba9f86 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.modular.expect
@@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias<T extends core::num> = test::Class<T>; +typedef AliasImpl<T extends core::num> = test::ClassImpl<T>; +@#C13 +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class<test::Class::T%> + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class<test::Class::_#new#tearOff::T%> + return new test::Class::•<test::Class::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class<test::Class::fact::T%> + return new test::ClassImpl::•<test::Class::fact::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class<test::Class::_#fact#tearOff::T%> + return test::Class::fact<test::Class::_#fact#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class<test::Class::redirect::T%> + return new test::ClassImpl::•<test::Class::redirect::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect#tearOff::T%> + return new test::ClassImpl::•<test::Class::_#redirect#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class<test::Class::redirect2::T%> + return new test::ClassImpl::patched<test::Class::redirect2::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect2#tearOff::T%> + return new test::ClassImpl::patched<test::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#new#tearOff::T%> + return new test::ClassImpl::•<test::ClassImpl::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#patched#tearOff::T%> + return new test::ClassImpl::patched<test::ClassImpl::_#patched#tearOff::T%>(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class<test::_#Alias#new#tearOff::T> + return new test::Class::•<test::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class<test::_#Alias#fact#tearOff::T> + return test::Class::fact<test::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect#tearOff::T> + return test::Class::_#redirect#tearOff<test::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect2#tearOff::T> + return test::Class::_#redirect2#tearOff<test::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#new#tearOff::T> + return new test::ClassImpl::•<test::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#patched#tearOff::T> + return new test::ClassImpl::patched<test::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +}
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.outline.expect new file mode 100644 index 0000000..49786e9 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.outline.expect
@@ -0,0 +1,77 @@ +library /*isNonNullableByDefault*/; +import self as self; + +import "dart:test"; + +static method main() → dynamic + ; + +library /*isNonNullableByDefault*/; +import self as self2; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias<T extends core::num> = self2::Class<T>; +typedef AliasImpl<T extends core::num> = self2::ClassImpl<T>; +@_js::patch +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[self2::Class::redirect, self2::Class::redirect2]/*isLegacy*/; + @_js::patch + external constructor •({core::bool defaultValue = true, required self2::Class::T% value = null}) → self2::Class<self2::Class::T%> + ; + static method _#new#tearOff<T extends core::Object? = dynamic>({has-declared-initializer core::bool defaultValue, required self2::Class::_#new#tearOff::T% value}) → self2::Class<self2::Class::_#new#tearOff::T%> + return new self2::Class::•<self2::Class::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + @_js::patch + external static factory fact<T extends core::Object? = dynamic>({has-declared-initializer core::bool defaultValue, required self2::Class::fact::T% value}) → self2::Class<self2::Class::fact::T%>; + static method _#fact#tearOff<T extends core::Object? = dynamic>({has-declared-initializer core::bool defaultValue, required self2::Class::_#fact#tearOff::T% value}) → self2::Class<self2::Class::_#fact#tearOff::T%> + return self2::Class::fact<self2::Class::_#fact#tearOff::T%>(defaultValue: defaultValue, value: value); + @_js::patch + external static factory redirect<T extends core::Object? = dynamic>({core::bool defaultValue, required self2::Class::redirect::T% value}) → self2::Class<self2::Class::redirect::T%> + return new self2::ClassImpl::•<self2::Class::redirect::T%>(defaultValue: defaultValue, value: value); + static method _#redirect#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue, required self2::Class::_#redirect#tearOff::T% value}) → self2::Class<self2::Class::_#redirect#tearOff::T%> + return self2::Class::redirect<self2::Class::_#redirect#tearOff::T%>(defaultValue: defaultValue, value: value); + @_js::patch + external static factory redirect2<T extends core::Object? = dynamic>({core::bool defaultValue, required self2::Class::redirect2::T% value}) → self2::Class<self2::Class::redirect2::T%> + return new self2::ClassImpl::patched<self2::Class::redirect2::T%>(defaultValue: defaultValue, value: value); + static method _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue, required self2::Class::_#redirect2#tearOff::T% value}) → self2::Class<self2::Class::_#redirect2#tearOff::T%> + return self2::Class::redirect2<self2::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value); +} +@_js::patch +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements self2::Class<self2::ClassImpl::T%> { + constructor •({core::bool defaultValue = true, required self2::ClassImpl::T% value = null}) → self2::ClassImpl<self2::ClassImpl::T%> + ; + @_js::patch + external constructor patched({core::bool defaultValue = true, required self2::ClassImpl::T% value = null}) → self2::ClassImpl<self2::ClassImpl::T%> + ; + static method _#new#tearOff<T extends core::Object? = dynamic>({has-declared-initializer core::bool defaultValue, required self2::ClassImpl::_#new#tearOff::T% value}) → self2::ClassImpl<self2::ClassImpl::_#new#tearOff::T%> + return new self2::ClassImpl::•<self2::ClassImpl::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + static method _#patched#tearOff<T extends core::Object? = dynamic>({has-declared-initializer core::bool defaultValue, required self2::ClassImpl::_#patched#tearOff::T% value}) → self2::ClassImpl<self2::ClassImpl::_#patched#tearOff::T%> + return new self2::ClassImpl::patched<self2::ClassImpl::_#patched#tearOff::T%>(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff<T extends core::num>({has-declared-initializer core::bool defaultValue, required self2::_#Alias#new#tearOff::T value}) → self2::Class<self2::_#Alias#new#tearOff::T> + return new self2::Class::•<self2::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({has-declared-initializer core::bool defaultValue, required self2::_#Alias#fact#tearOff::T value}) → self2::Class<self2::_#Alias#fact#tearOff::T> + return self2::Class::fact<self2::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue, required self2::_#Alias#redirect#tearOff::T value}) → self2::Class<self2::_#Alias#redirect#tearOff::T> + return self2::Class::_#redirect#tearOff<self2::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue, required self2::_#Alias#redirect2#tearOff::T value}) → self2::Class<self2::_#Alias#redirect2#tearOff::T> + return self2::Class::_#redirect2#tearOff<self2::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({has-declared-initializer core::bool defaultValue, required self2::_#AliasImpl#new#tearOff::T value}) → self2::ClassImpl<self2::_#AliasImpl#new#tearOff::T> + return new self2::ClassImpl::•<self2::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({has-declared-initializer core::bool defaultValue, required self2::_#AliasImpl#patched#tearOff::T value}) → self2::ClassImpl<self2::_#AliasImpl#patched#tearOff::T> + return new self2::ClassImpl::patched<self2::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + + +Extra constant evaluation status: +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:6:47 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:7:10 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:8:29 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:12:22 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:15:12 -> InstanceConstant(const _Patch{}) +Evaluated: ConstructorTearOff @ org-dartlang-testcase:///origin_lib.dart:5:7 -> ConstructorTearOffConstant(Class.redirect) +Evaluated: ConstructorTearOff @ org-dartlang-testcase:///origin_lib.dart:5:7 -> ConstructorTearOffConstant(Class.redirect2) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:18:39 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:19:48 -> InstanceConstant(const _Patch{}) +Extra constant evaluation: evaluated: 52, effectively constant: 9
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.transformed.expect new file mode 100644 index 0000000..3ba9f86 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/main.dart.weak.transformed.expect
@@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias<T extends core::num> = test::Class<T>; +typedef AliasImpl<T extends core::num> = test::ClassImpl<T>; +@#C13 +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class<test::Class::T%> + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class<test::Class::_#new#tearOff::T%> + return new test::Class::•<test::Class::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class<test::Class::fact::T%> + return new test::ClassImpl::•<test::Class::fact::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class<test::Class::_#fact#tearOff::T%> + return test::Class::fact<test::Class::_#fact#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class<test::Class::redirect::T%> + return new test::ClassImpl::•<test::Class::redirect::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect#tearOff::T%> + return new test::ClassImpl::•<test::Class::_#redirect#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class<test::Class::redirect2::T%> + return new test::ClassImpl::patched<test::Class::redirect2::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect2#tearOff::T%> + return new test::ClassImpl::patched<test::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#new#tearOff::T%> + return new test::ClassImpl::•<test::ClassImpl::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#patched#tearOff::T%> + return new test::ClassImpl::patched<test::ClassImpl::_#patched#tearOff::T%>(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class<test::_#Alias#new#tearOff::T> + return new test::Class::•<test::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class<test::_#Alias#fact#tearOff::T> + return test::Class::fact<test::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect#tearOff::T> + return test::Class::_#redirect#tearOff<test::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect2#tearOff::T> + return test::Class::_#redirect2#tearOff<test::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#new#tearOff::T> + return new test::ClassImpl::•<test::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#patched#tearOff::T> + return new test::ClassImpl::patched<test::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +}
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/origin_lib.dart b/pkg/front_end/testcases/dart2js/tear_off_patch/origin_lib.dart new file mode 100644 index 0000000..c29cf6f --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/origin_lib.dart
@@ -0,0 +1,19 @@ +// Copyright (c) 2022, 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. + +class Class<T> { + external Class({bool defaultValue: true, required T value}); + external factory Class.fact({bool defaultValue: true, required T value}); + external factory Class.redirect({bool defaultValue, required T value}); + external factory Class.redirect2({bool defaultValue, required T value}); +} + +class ClassImpl<T> implements Class<T> { + ClassImpl({bool defaultValue: true, required T value}); + + external ClassImpl.patched({bool defaultValue: true, required T value}); +} + +typedef Alias<T extends num> = Class<T>; +typedef AliasImpl<T extends num> = ClassImpl<T>;
diff --git a/pkg/front_end/testcases/dart2js/tear_off_patch/patch_lib.dart b/pkg/front_end/testcases/dart2js/tear_off_patch/patch_lib.dart new file mode 100644 index 0000000..77fdfb0 --- /dev/null +++ b/pkg/front_end/testcases/dart2js/tear_off_patch/patch_lib.dart
@@ -0,0 +1,33 @@ +// Copyright (c) 2022, 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. + +// ignore: import_internal_library +import 'dart:_js_helper'; + +@patch +class Class<T> { + @patch + Class({bool defaultValue: true, required T value}) { + print('patch Class'); + } + + @patch + factory Class.fact({bool defaultValue: true, required T value}) => + new ClassImpl<T>(defaultValue: defaultValue, value: value); + + @patch + factory Class.redirect({bool defaultValue, required T value}) = ClassImpl<T>; + + @patch + factory Class.redirect2({bool defaultValue, required T value}) = + ClassImpl<T>.patched; +} + +@patch +class ClassImpl<T> implements Class<T> { + @patch + ClassImpl.patched({bool defaultValue: true, required T value}) { + print('patch ClassImpl'); + } +}
diff --git a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.expect b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.expect index 3eaf932..af74037 100644 --- a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.expect +++ b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.expect
@@ -24,12 +24,12 @@ @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C3}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); - static method _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::fact(defaultValue: defaultValue); @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ constFact({core::bool defaultValue = #C3}) → test::Class return throw "unsupported"; - static method _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::constFact(defaultValue: defaultValue); static method /* from org-dartlang-testcase:///patch_lib.dart */ _#_internal#tearOff({core::bool defaultValue = #C2}) → test::Class return new test::Class::_internal(defaultValue: defaultValue);
diff --git a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.transformed.expect index 3eaf932..af74037 100644 --- a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.strong.transformed.expect
@@ -24,12 +24,12 @@ @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C3}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); - static method _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::fact(defaultValue: defaultValue); @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ constFact({core::bool defaultValue = #C3}) → test::Class return throw "unsupported"; - static method _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::constFact(defaultValue: defaultValue); static method /* from org-dartlang-testcase:///patch_lib.dart */ _#_internal#tearOff({core::bool defaultValue = #C2}) → test::Class return new test::Class::_internal(defaultValue: defaultValue);
diff --git a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.expect b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.expect index 3eaf932..af74037 100644 --- a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.expect +++ b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.expect
@@ -24,12 +24,12 @@ @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C3}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); - static method _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::fact(defaultValue: defaultValue); @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ constFact({core::bool defaultValue = #C3}) → test::Class return throw "unsupported"; - static method _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::constFact(defaultValue: defaultValue); static method /* from org-dartlang-testcase:///patch_lib.dart */ _#_internal#tearOff({core::bool defaultValue = #C2}) → test::Class return new test::Class::_internal(defaultValue: defaultValue);
diff --git a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.modular.expect b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.modular.expect index 3eaf932..af74037 100644 --- a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.modular.expect +++ b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.modular.expect
@@ -24,12 +24,12 @@ @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C3}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); - static method _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::fact(defaultValue: defaultValue); @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ constFact({core::bool defaultValue = #C3}) → test::Class return throw "unsupported"; - static method _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::constFact(defaultValue: defaultValue); static method /* from org-dartlang-testcase:///patch_lib.dart */ _#_internal#tearOff({core::bool defaultValue = #C2}) → test::Class return new test::Class::_internal(defaultValue: defaultValue);
diff --git a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.transformed.expect b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.transformed.expect index 3eaf932..af74037 100644 --- a/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/dartdevc/factory_patch/main.dart.weak.transformed.expect
@@ -24,12 +24,12 @@ @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact({core::bool defaultValue = #C3}) → test::Class return new test::Class::_internal(defaultValue: defaultValue); - static method _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::fact(defaultValue: defaultValue); @#C1 static factory /* from org-dartlang-testcase:///patch_lib.dart */ constFact({core::bool defaultValue = #C3}) → test::Class return throw "unsupported"; - static method _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#constFact#tearOff({core::bool defaultValue = #C3}) → test::Class return test::Class::constFact(defaultValue: defaultValue); static method /* from org-dartlang-testcase:///patch_lib.dart */ _#_internal#tearOff({core::bool defaultValue = #C2}) → test::Class return new test::Class::_internal(defaultValue: defaultValue);
diff --git a/pkg/front_end/testcases/general/tear_off_patch/libraries.json b/pkg/front_end/testcases/general/tear_off_patch/libraries.json new file mode 100644 index 0000000..154c73c --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/libraries.json
@@ -0,0 +1,12 @@ +{ + "none": { + "libraries": { + "test": { + "patches": [ + "patch_lib.dart" + ], + "uri": "origin_lib.dart" + } + } + } +}
diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart b/pkg/front_end/testcases/general/tear_off_patch/main.dart new file mode 100644 index 0000000..676f68a --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart
@@ -0,0 +1,20 @@ +// Copyright (c) 2022, 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 'dart:test'; + +main() { + Class.new; + Class.fact; + Class.redirect; + Class.redirect2; + ClassImpl.new; + ClassImpl.patched; + Alias.new; + Alias.fact; + Alias.redirect; + Alias.redirect2; + AliasImpl.new; + AliasImpl.patched; +}
diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.expect new file mode 100644 index 0000000..3ba9f86 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.expect
@@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias<T extends core::num> = test::Class<T>; +typedef AliasImpl<T extends core::num> = test::ClassImpl<T>; +@#C13 +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class<test::Class::T%> + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class<test::Class::_#new#tearOff::T%> + return new test::Class::•<test::Class::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class<test::Class::fact::T%> + return new test::ClassImpl::•<test::Class::fact::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class<test::Class::_#fact#tearOff::T%> + return test::Class::fact<test::Class::_#fact#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class<test::Class::redirect::T%> + return new test::ClassImpl::•<test::Class::redirect::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect#tearOff::T%> + return new test::ClassImpl::•<test::Class::_#redirect#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class<test::Class::redirect2::T%> + return new test::ClassImpl::patched<test::Class::redirect2::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect2#tearOff::T%> + return new test::ClassImpl::patched<test::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#new#tearOff::T%> + return new test::ClassImpl::•<test::ClassImpl::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#patched#tearOff::T%> + return new test::ClassImpl::patched<test::ClassImpl::_#patched#tearOff::T%>(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class<test::_#Alias#new#tearOff::T> + return new test::Class::•<test::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class<test::_#Alias#fact#tearOff::T> + return test::Class::fact<test::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect#tearOff::T> + return test::Class::_#redirect#tearOff<test::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect2#tearOff::T> + return test::Class::_#redirect2#tearOff<test::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#new#tearOff::T> + return new test::ClassImpl::•<test::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#patched#tearOff::T> + return new test::ClassImpl::patched<test::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +}
diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.transformed.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.transformed.expect new file mode 100644 index 0000000..3ba9f86 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.strong.transformed.expect
@@ -0,0 +1,104 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_js_helper" as _js; + +import "dart:_js_helper"; + +typedef Alias<T extends core::num> = test::Class<T>; +typedef AliasImpl<T extends core::num> = test::ClassImpl<T>; +@#C13 +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class<test::Class::T%> + : super core::Object::•() { + core::print("patch Class"); + } + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#new#tearOff::T% value = #C17}) → test::Class<test::Class::_#new#tearOff::T%> + return new test::Class::•<test::Class::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class<test::Class::fact::T%> + return new test::ClassImpl::•<test::Class::fact::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#fact#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#fact#tearOff::T% value = #C17}) → test::Class<test::Class::_#fact#tearOff::T%> + return test::Class::fact<test::Class::_#fact#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class<test::Class::redirect::T%> + return new test::ClassImpl::•<test::Class::redirect::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect#tearOff::T%> + return new test::ClassImpl::•<test::Class::_#redirect#tearOff::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class<test::Class::redirect2::T%> + return new test::ClassImpl::patched<test::Class::redirect2::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#redirect2#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::_#redirect2#tearOff::T% value = #C17}) → test::Class<test::Class::_#redirect2#tearOff::T%> + return new test::ClassImpl::patched<test::Class::_#redirect2#tearOff::T%>(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() { + core::print("patch ClassImpl"); + } + static method _#new#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#new#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#new#tearOff::T%> + return new test::ClassImpl::•<test::ClassImpl::_#new#tearOff::T%>(defaultValue: defaultValue, value: value); + static method /* from org-dartlang-testcase:///patch_lib.dart */ _#patched#tearOff<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::ClassImpl::_#patched#tearOff::T% value = #C17}) → test::ClassImpl<test::ClassImpl::_#patched#tearOff::T%> + return new test::ClassImpl::patched<test::ClassImpl::_#patched#tearOff::T%>(defaultValue: defaultValue, value: value); +} +static method _#Alias#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class<test::_#Alias#new#tearOff::T> + return new test::Class::•<test::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class<test::_#Alias#fact#tearOff::T> + return test::Class::fact<test::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect#tearOff::T> + return test::Class::_#redirect#tearOff<test::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue = #C17, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect2#tearOff::T> + return test::Class::_#redirect2#tearOff<test::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#new#tearOff::T> + return new test::ClassImpl::•<test::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#patched#tearOff::T> + return new test::ClassImpl::patched<test::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + +constants { + #C1 = static-tearoff test::Class::_#new#tearOff + #C2 = static-tearoff test::Class::_#fact#tearOff + #C3 = static-tearoff test::Class::_#redirect#tearOff + #C4 = static-tearoff test::Class::_#redirect2#tearOff + #C5 = static-tearoff test::ClassImpl::_#new#tearOff + #C6 = static-tearoff test::ClassImpl::_#patched#tearOff + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _js::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +}
diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline.expect new file mode 100644 index 0000000..3c9c90e --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@ +import 'dart:test'; + +main() {}
diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline_modelled.expect new file mode 100644 index 0000000..3c9c90e --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@ +import 'dart:test'; + +main() {}
diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.expect new file mode 100644 index 0000000..7663f6b --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.expect
@@ -0,0 +1,92 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_internal" as _in; + +import "dart:_internal"; + +typedef Alias<T extends core::num> = test::Class<T>; +typedef AliasImpl<T extends core::num> = test::ClassImpl<T>; +@#C13 +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class<test::Class::T%> + : super core::Object::•() { + core::print("patch Class"); + } + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class<test::Class::fact::T%> + return new test::ClassImpl::•<test::Class::fact::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class<test::Class::redirect::T%> + return new test::ClassImpl::•<test::Class::redirect::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class<test::Class::redirect2::T%> + return new test::ClassImpl::patched<test::Class::redirect2::T%>(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() { + core::print("patch ClassImpl"); + } +} +static method _#Alias#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class<test::_#Alias#new#tearOff::T> + return new test::Class::•<test::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class<test::_#Alias#fact#tearOff::T> + return test::Class::fact<test::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect#tearOff::T> + return test::Class::redirect<test::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect2#tearOff::T> + return test::Class::redirect2<test::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#new#tearOff::T> + return new test::ClassImpl::•<test::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#patched#tearOff::T> + return new test::ClassImpl::patched<test::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + +constants { + #C1 = constructor-tearoff test::Class::• + #C2 = constructor-tearoff test::Class::fact + #C3 = redirecting-factory-tearoff test::Class::redirect + #C4 = redirecting-factory-tearoff test::Class::redirect2 + #C5 = constructor-tearoff test::ClassImpl::• + #C6 = constructor-tearoff test::ClassImpl::patched + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _in::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +}
diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.modular.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.modular.expect new file mode 100644 index 0000000..7663f6b --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.modular.expect
@@ -0,0 +1,92 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_internal" as _in; + +import "dart:_internal"; + +typedef Alias<T extends core::num> = test::Class<T>; +typedef AliasImpl<T extends core::num> = test::ClassImpl<T>; +@#C13 +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class<test::Class::T%> + : super core::Object::•() { + core::print("patch Class"); + } + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class<test::Class::fact::T%> + return new test::ClassImpl::•<test::Class::fact::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class<test::Class::redirect::T%> + return new test::ClassImpl::•<test::Class::redirect::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class<test::Class::redirect2::T%> + return new test::ClassImpl::patched<test::Class::redirect2::T%>(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() { + core::print("patch ClassImpl"); + } +} +static method _#Alias#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class<test::_#Alias#new#tearOff::T> + return new test::Class::•<test::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class<test::_#Alias#fact#tearOff::T> + return test::Class::fact<test::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect#tearOff::T> + return test::Class::redirect<test::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect2#tearOff::T> + return test::Class::redirect2<test::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#new#tearOff::T> + return new test::ClassImpl::•<test::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#patched#tearOff::T> + return new test::ClassImpl::patched<test::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + +constants { + #C1 = constructor-tearoff test::Class::• + #C2 = constructor-tearoff test::Class::fact + #C3 = redirecting-factory-tearoff test::Class::redirect + #C4 = redirecting-factory-tearoff test::Class::redirect2 + #C5 = constructor-tearoff test::ClassImpl::• + #C6 = constructor-tearoff test::ClassImpl::patched + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _in::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +}
diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.outline.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.outline.expect new file mode 100644 index 0000000..40d29d3 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.outline.expect
@@ -0,0 +1,65 @@ +library /*isNonNullableByDefault*/; +import self as self; + +import "dart:test"; + +static method main() → dynamic + ; + +library /*isNonNullableByDefault*/; +import self as self2; +import "dart:core" as core; +import "dart:_internal" as _in; + +import "dart:_internal"; + +typedef Alias<T extends core::num> = self2::Class<T>; +typedef AliasImpl<T extends core::num> = self2::ClassImpl<T>; +@_in::patch +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[self2::Class::redirect, self2::Class::redirect2]/*isLegacy*/; + @_in::patch + external constructor •({core::bool defaultValue = true, required self2::Class::T% value = null}) → self2::Class<self2::Class::T%> + ; + @_in::patch + external static factory fact<T extends core::Object? = dynamic>({has-declared-initializer core::bool defaultValue, required self2::Class::fact::T% value}) → self2::Class<self2::Class::fact::T%>; + @_in::patch + external static factory redirect<T extends core::Object? = dynamic>({core::bool defaultValue, required self2::Class::redirect::T% value}) → self2::Class<self2::Class::redirect::T%> + return new self2::ClassImpl::•<self2::Class::redirect::T%>(defaultValue: defaultValue, value: value); + @_in::patch + external static factory redirect2<T extends core::Object? = dynamic>({core::bool defaultValue, required self2::Class::redirect2::T% value}) → self2::Class<self2::Class::redirect2::T%> + return new self2::ClassImpl::patched<self2::Class::redirect2::T%>(defaultValue: defaultValue, value: value); +} +@_in::patch +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements self2::Class<self2::ClassImpl::T%> { + constructor •({core::bool defaultValue = true, required self2::ClassImpl::T% value = null}) → self2::ClassImpl<self2::ClassImpl::T%> + ; + @_in::patch + external constructor patched({core::bool defaultValue = true, required self2::ClassImpl::T% value = null}) → self2::ClassImpl<self2::ClassImpl::T%> + ; +} +static method _#Alias#new#tearOff<T extends core::num>({has-declared-initializer core::bool defaultValue, required self2::_#Alias#new#tearOff::T value}) → self2::Class<self2::_#Alias#new#tearOff::T> + return new self2::Class::•<self2::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({has-declared-initializer core::bool defaultValue, required self2::_#Alias#fact#tearOff::T value}) → self2::Class<self2::_#Alias#fact#tearOff::T> + return self2::Class::fact<self2::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue, required self2::_#Alias#redirect#tearOff::T value}) → self2::Class<self2::_#Alias#redirect#tearOff::T> + return self2::Class::redirect<self2::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue, required self2::_#Alias#redirect2#tearOff::T value}) → self2::Class<self2::_#Alias#redirect2#tearOff::T> + return self2::Class::redirect2<self2::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({has-declared-initializer core::bool defaultValue, required self2::_#AliasImpl#new#tearOff::T value}) → self2::ClassImpl<self2::_#AliasImpl#new#tearOff::T> + return new self2::ClassImpl::•<self2::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({has-declared-initializer core::bool defaultValue, required self2::_#AliasImpl#patched#tearOff::T value}) → self2::ClassImpl<self2::_#AliasImpl#patched#tearOff::T> + return new self2::ClassImpl::patched<self2::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + + +Extra constant evaluation status: +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:6:46 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:7:9 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:8:28 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:12:21 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:15:11 -> InstanceConstant(const _Patch{}) +Evaluated: ConstructorTearOff @ org-dartlang-testcase:///origin_lib.dart:5:7 -> ConstructorTearOffConstant(Class.redirect) +Evaluated: ConstructorTearOff @ org-dartlang-testcase:///origin_lib.dart:5:7 -> ConstructorTearOffConstant(Class.redirect2) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:18:38 -> InstanceConstant(const _Patch{}) +Evaluated: StaticGet @ org-dartlang-testcase:///origin_lib.dart:19:47 -> InstanceConstant(const _Patch{}) +Extra constant evaluation: evaluated: 34, effectively constant: 9
diff --git a/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.transformed.expect b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.transformed.expect new file mode 100644 index 0000000..7663f6b --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/main.dart.weak.transformed.expect
@@ -0,0 +1,92 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:test" as test; + +import "dart:test"; + +static method main() → dynamic { + #C1; + #C2; + #C3; + #C4; + #C5; + #C6; + #C7; + #C8; + #C9; + #C10; + #C11; + #C12; +} + +library /*isNonNullableByDefault*/; +import self as test; +import "dart:core" as core; +import "dart:_internal" as _in; + +import "dart:_internal"; + +typedef Alias<T extends core::num> = test::Class<T>; +typedef AliasImpl<T extends core::num> = test::ClassImpl<T>; +@#C13 +class Class<T extends core::Object? = dynamic> extends core::Object { + static final field dynamic _redirecting# = <dynamic>[#C14, #C15]/*isLegacy*/; + @#C13 + constructor •({core::bool defaultValue = #C16, required test::Class::T% value = #C17}) → test::Class<test::Class::T%> + : super core::Object::•() { + core::print("patch Class"); + } + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ fact<T extends core::Object? = dynamic>({core::bool defaultValue = #C16, required test::Class::fact::T% value = #C17}) → test::Class<test::Class::fact::T%> + return new test::ClassImpl::•<test::Class::fact::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect::T% value = #C17}) → test::Class<test::Class::redirect::T%> + return new test::ClassImpl::•<test::Class::redirect::T%>(defaultValue: defaultValue, value: value); + @#C13 + static factory /* from org-dartlang-testcase:///patch_lib.dart */ redirect2<T extends core::Object? = dynamic>({core::bool defaultValue = #C17, required test::Class::redirect2::T% value = #C17}) → test::Class<test::Class::redirect2::T%> + return new test::ClassImpl::patched<test::Class::redirect2::T%>(defaultValue: defaultValue, value: value); +} +@#C13 +class ClassImpl<T extends core::Object? = dynamic> extends core::Object implements test::Class<test::ClassImpl::T%> { + constructor •({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() + ; + @#C13 + constructor patched({core::bool defaultValue = #C16, required test::ClassImpl::T% value = #C17}) → test::ClassImpl<test::ClassImpl::T%> + : super core::Object::•() { + core::print("patch ClassImpl"); + } +} +static method _#Alias#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#new#tearOff::T value = #C17}) → test::Class<test::_#Alias#new#tearOff::T> + return new test::Class::•<test::_#Alias#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#fact#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#fact#tearOff::T value = #C17}) → test::Class<test::_#Alias#fact#tearOff::T> + return test::Class::fact<test::_#Alias#fact#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#redirect#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect#tearOff::T> + return test::Class::redirect<test::_#Alias#redirect#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#Alias#redirect2#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#Alias#redirect2#tearOff::T value = #C17}) → test::Class<test::_#Alias#redirect2#tearOff::T> + return test::Class::redirect2<test::_#Alias#redirect2#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#new#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#new#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#new#tearOff::T> + return new test::ClassImpl::•<test::_#AliasImpl#new#tearOff::T>(defaultValue: defaultValue, value: value); +static method _#AliasImpl#patched#tearOff<T extends core::num>({core::bool defaultValue = #C16, required test::_#AliasImpl#patched#tearOff::T value = #C17}) → test::ClassImpl<test::_#AliasImpl#patched#tearOff::T> + return new test::ClassImpl::patched<test::_#AliasImpl#patched#tearOff::T>(defaultValue: defaultValue, value: value); + +constants { + #C1 = constructor-tearoff test::Class::• + #C2 = constructor-tearoff test::Class::fact + #C3 = redirecting-factory-tearoff test::Class::redirect + #C4 = redirecting-factory-tearoff test::Class::redirect2 + #C5 = constructor-tearoff test::ClassImpl::• + #C6 = constructor-tearoff test::ClassImpl::patched + #C7 = static-tearoff test::_#Alias#new#tearOff + #C8 = static-tearoff test::_#Alias#fact#tearOff + #C9 = static-tearoff test::_#Alias#redirect#tearOff + #C10 = static-tearoff test::_#Alias#redirect2#tearOff + #C11 = static-tearoff test::_#AliasImpl#new#tearOff + #C12 = static-tearoff test::_#AliasImpl#patched#tearOff + #C13 = _in::_Patch {} + #C14 = constructor-tearoff test::Class::redirect + #C15 = constructor-tearoff test::Class::redirect2 + #C16 = true + #C17 = null +}
diff --git a/pkg/front_end/testcases/general/tear_off_patch/origin_lib.dart b/pkg/front_end/testcases/general/tear_off_patch/origin_lib.dart new file mode 100644 index 0000000..c29cf6f --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/origin_lib.dart
@@ -0,0 +1,19 @@ +// Copyright (c) 2022, 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. + +class Class<T> { + external Class({bool defaultValue: true, required T value}); + external factory Class.fact({bool defaultValue: true, required T value}); + external factory Class.redirect({bool defaultValue, required T value}); + external factory Class.redirect2({bool defaultValue, required T value}); +} + +class ClassImpl<T> implements Class<T> { + ClassImpl({bool defaultValue: true, required T value}); + + external ClassImpl.patched({bool defaultValue: true, required T value}); +} + +typedef Alias<T extends num> = Class<T>; +typedef AliasImpl<T extends num> = ClassImpl<T>;
diff --git a/pkg/front_end/testcases/general/tear_off_patch/patch_lib.dart b/pkg/front_end/testcases/general/tear_off_patch/patch_lib.dart new file mode 100644 index 0000000..7265272 --- /dev/null +++ b/pkg/front_end/testcases/general/tear_off_patch/patch_lib.dart
@@ -0,0 +1,33 @@ +// Copyright (c) 2022, 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. + +// ignore: import_internal_library +import 'dart:_internal'; + +@patch +class Class<T> { + @patch + Class({bool defaultValue: true, required T value}) { + print('patch Class'); + } + + @patch + factory Class.fact({bool defaultValue: true, required T value}) => + new ClassImpl<T>(defaultValue: defaultValue, value: value); + + @patch + factory Class.redirect({bool defaultValue, required T value}) = ClassImpl<T>; + + @patch + factory Class.redirect2({bool defaultValue, required T value}) = + ClassImpl<T>.patched; +} + +@patch +class ClassImpl<T> implements Class<T> { + @patch + ClassImpl.patched({bool defaultValue: true, required T value}) { + print('patch ClassImpl'); + } +}
diff --git a/sdk/lib/core/duration.dart b/sdk/lib/core/duration.dart index 11fc5c8..bd73e56 100644 --- a/sdk/lib/core/duration.dart +++ b/sdk/lib/core/duration.dart
@@ -331,6 +331,7 @@ /// ``` String toString() { var microseconds = inMicroseconds; + var sign = (microseconds < 0) ? "-" : ""; var hours = microseconds ~/ microsecondsPerHour; microseconds = microseconds.remainder(microsecondsPerHour); @@ -348,7 +349,7 @@ var secondsPadding = seconds < 10 ? "0" : ""; var paddedMicroseconds = microseconds.toString().padLeft(6, "0"); - return "$hours:" + return "$sign${hours.abs()}:" "$minutesPadding$minutes:" "$secondsPadding$seconds.$paddedMicroseconds"; }
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart index 9dccd22..a9990a3 100644 --- a/sdk/lib/developer/timeline.dart +++ b/sdk/lib/developer/timeline.dart
@@ -4,6 +4,9 @@ part of dart.developer; +// Examples can assume: +// void doSomething() {} + const bool _hasTimeline = const bool.fromEnvironment("dart.developer.timeline", defaultValue: true);
diff --git a/sdk/lib/ffi/dynamic_library.dart b/sdk/lib/ffi/dynamic_library.dart index 3f740d5..5106021 100644 --- a/sdk/lib/ffi/dynamic_library.dart +++ b/sdk/lib/ffi/dynamic_library.dart
@@ -9,7 +9,7 @@ /// A dynamically loaded library is a mapping from symbols to memory addresses. /// These memory addresses can be accessed through [lookup]. class DynamicLibrary { - /// Creates a dynamic library holding all global symbols. + /// Creates a [DynamicLibrary] holding all global symbols. /// /// Any symbol in a library currently loaded with global visibility /// (including the executable itself) may be resolved through this library. @@ -17,8 +17,10 @@ /// This feature is not available on Windows. external factory DynamicLibrary.process(); - /// Creates a dynamic library containing all the symbols of the running + /// Creates a [DynamicLibrary] containing all the symbols of the running /// executable. + /// + /// This is useful for using dart:ffi with static libraries. external factory DynamicLibrary.executable(); /// Loads a library file and provides access to its symbols.
diff --git a/sdk/lib/js_util/js_util.dart b/sdk/lib/js_util/js_util.dart index d0db609..081bcb8 100644 --- a/sdk/lib/js_util/js_util.dart +++ b/sdk/lib/js_util/js_util.dart
@@ -17,6 +17,10 @@ import 'dart:_js_helper' show convertDartClosureToJS, assertInterop, assertInteropArgs; +// Examples can assume: +// class JS { const JS(); } +// class Promise<T> {} + /// Recursively converts a JSON-like collection to JavaScript compatible /// representation. /// @@ -305,9 +309,11 @@ /// @JS() /// external Promise<num> get threePromise; // Resolves to 3 /// -/// final Future<num> threeFuture = promiseToFuture(threePromise); +/// void main() async { +/// final Future<num> threeFuture = promiseToFuture(threePromise); /// -/// final three = await threeFuture; // == 3 +/// final three = await threeFuture; // == 3 +/// } /// ``` Future<T> promiseToFuture<T>(Object jsPromise) { final completer = Completer<T>();
diff --git a/tests/corelib/duration_test.dart b/tests/corelib/duration_test.dart index 7080723..e60efb8 100644 --- a/tests/corelib/duration_test.dart +++ b/tests/corelib/duration_test.dart
@@ -298,4 +298,21 @@ Expect.equals(d2, -d1); Expect.equals(d1, -d2); + + // Regression test for http://dartbug.com/48841 + d = const Duration(minutes: -1); + Expect.equals("-0:01:00.000000", d.toString()); + d = const Duration(seconds: -1); + Expect.equals("-0:00:01.000000", d.toString()); + d = const Duration(milliseconds: -1); + Expect.equals("-0:00:00.001000", d.toString()); + d = const Duration(microseconds: -1); + Expect.equals("-0:00:00.000001", d.toString()); + d = const Duration(microseconds: -9223372036854775808); // Min 64-bit int. + // Not checking precise values, because they will be off on the web. + Expect.equals("-2562047788:00:54.775808", d.toString()); + Expect.isTrue(d.toString().startsWith("-")); + Expect.isFalse(d.toString().startsWith("--")); + d = const Duration(minutes: -0); // is -0.0 on web. + Expect.equals("0:00:00.000000", d.toString()); }
diff --git a/tests/corelib_2/duration_test.dart b/tests/corelib_2/duration_test.dart index fb80464..33ebf1f 100644 --- a/tests/corelib_2/duration_test.dart +++ b/tests/corelib_2/duration_test.dart
@@ -300,4 +300,21 @@ Expect.equals(d2, -d1); Expect.equals(d1, -d2); + + // Regression test for http://dartbug.com/48841 + d = const Duration(minutes: -1); + Expect.equals("-0:01:00.000000", d.toString()); + d = const Duration(seconds: -1); + Expect.equals("-0:00:01.000000", d.toString()); + d = const Duration(milliseconds: -1); + Expect.equals("-0:00:00.001000", d.toString()); + d = const Duration(microseconds: -1); + Expect.equals("-0:00:00.000001", d.toString()); + d = const Duration(microseconds: -9223372036854775808); // Min 64-bit int. + // Not checking precise values, because they will be off on the web. + Expect.equals("-2562047788:00:54.775808", d.toString()); + Expect.isTrue(d.toString().startsWith("-")); + Expect.isFalse(d.toString().startsWith("--")); + d = const Duration(minutes: -0); // is -0.0 on web. + Expect.equals("0:00:00.000000", d.toString()); }
diff --git a/tests/language/constructor/patch_tear_off_test.dart b/tests/language/constructor/patch_tear_off_test.dart new file mode 100644 index 0000000..632a208 --- /dev/null +++ b/tests/language/constructor/patch_tear_off_test.dart
@@ -0,0 +1,10 @@ +// Copyright (c) 2022, 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. + +// Regression test for https://github.com/dart-lang/sdk/issues/48776 + +main() { + /// BigInt.from is a patched constructor. + BigInt.from; +}
diff --git a/tests/web/regress/issue/230108748_test.dart b/tests/web/regress/issue/230108748_test.dart new file mode 100644 index 0000000..c90c6b6 --- /dev/null +++ b/tests/web/regress/issue/230108748_test.dart
@@ -0,0 +1,64 @@ +// Copyright (c) 2022, 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. +// SharedOptions=-Da=true -Db=false + +import 'package:expect/expect.dart'; + +class Base { + final int x; + const Base(this.x); +} + +class Child extends Base { + static const Child A = Child._(const bool.fromEnvironment('a') ? 0 : 1); + static const Child B = Child._(const bool.fromEnvironment('b') ? 0 : 2); + + const Child._(int x) : super(x); +} + +int case1() { + switch (null as dynamic) { + case Child.A: + return 1; + default: + return 2; + } +} + +class A { + final int x; + const A(this.x); + + static const A a1 = A(const bool.fromEnvironment('x') ? 0 : 1); + static const A a2 = A(const bool.fromEnvironment('x') ? 0 : 2); +} + +int case2() { + switch (null as dynamic) { + case A.a1: + return 1; + default: + return 2; + } +} + +class B { + final int x; + const B(this.x); +} + +int case3() { + switch (null as dynamic) { + case B(const bool.fromEnvironment('x') ? 0 : 1): + return 1; + default: + return 2; + } +} + +void main() { + Expect.equals(case1(), 2); + Expect.equals(case2(), 2); + Expect.equals(case3(), 2); +}
diff --git a/tools/OWNERS b/tools/OWNERS index 8d66888..fa2dc56 100644 --- a/tools/OWNERS +++ b/tools/OWNERS
@@ -2,6 +2,7 @@ # Groups administrate themselves. per-file OWNERS_ANALYZER=file:OWNERS_ANALYZER +per-file OWNERS_BUILD=file:OWNERS_BUILD per-file OWNERS_CFE=file:OWNERS_CFE per-file OWNERS_ECOSYSTEM=file:OWNERS_ECOSYSTEM per-file OWNERS_FOUNDATION=file:OWNERS_FOUNDATION @@ -11,3 +12,6 @@ per-file OWNERS_PUB=file:OWNERS_PUB per-file OWNERS_VM=file:OWNERS_VM per-file OWNERS_WEB=file:OWNERS_WEB + +# Changed along with build files +per-file *.py=file:OWNERS_BUILD
diff --git a/tools/OWNERS_BUILD b/tools/OWNERS_BUILD new file mode 100644 index 0000000..2d5cb00 --- /dev/null +++ b/tools/OWNERS_BUILD
@@ -0,0 +1,2 @@ +file:OWNERS_INFRA +file:OWNERS_VM
diff --git a/tools/VERSION b/tools/VERSION index 2648abd..a15f79a 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 2 MINOR 18 PATCH 0 -PRERELEASE 56 +PRERELEASE 57 PRERELEASE_PATCH 0 \ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json index 459362c..7bab851 100644 --- a/tools/bots/test_matrix.json +++ b/tools/bots/test_matrix.json
@@ -3682,14 +3682,17 @@ "script": "out/ReleaseX64/dart-sdk/bin/dart", "arguments": [ "tools/verify_docs/bin/verify_docs.dart", - "sdk/lib/_http", - "sdk/lib/_internal", - "sdk/lib/cli", - "sdk/lib/convert", - "sdk/lib/ffi", - "sdk/lib/js", - "sdk/lib/math", - "sdk/lib/mirrors" + "dart:_http", + "dart:_internal", + "dart:cli", + "dart:convert", + "dart:developer", + "dart:ffi", + "dart:js", + "dart:js_util", + "dart:math", + "dart:mirrors", + "dart:wasm" ] }, {