mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:01:42 +00:00
Include bounds in type literals
Change-Id: Ieb3e5b09e88c98f8943a6e7ca9031c8a6ab776e1 Reviewed-on: https://dart-review.googlesource.com/63820 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
3a1b09dc63
commit
1c673b1046
|
@ -1051,9 +1051,6 @@ class CommonElements {
|
|||
FunctionEntity get getRuntimeTypeArgumentIntercepted =>
|
||||
_findHelperFunction('getRuntimeTypeArgumentIntercepted');
|
||||
|
||||
FunctionEntity get runtimeTypeToString =>
|
||||
_findHelperFunction('runtimeTypeToString');
|
||||
|
||||
FunctionEntity get assertIsSubtype => _findHelperFunction('assertIsSubtype');
|
||||
|
||||
FunctionEntity get checkSubtype => _findHelperFunction('checkSubtype');
|
||||
|
|
|
@ -361,6 +361,9 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
_collectTypeDependencies(type, dependencies);
|
||||
}
|
||||
break;
|
||||
case TypeUseKind.RTI_VALUE:
|
||||
failedAt(element, "Unexpected type use: $typeUse.");
|
||||
break;
|
||||
}
|
||||
}, visitDynamicUse: (DynamicUse dynamicUse) {
|
||||
// TODO(johnniwinther): Use rti need data to skip unneeded type
|
||||
|
|
|
@ -264,8 +264,9 @@ class InterfaceType extends DartType {
|
|||
class TypedefType extends DartType {
|
||||
final TypedefEntity element;
|
||||
final List<DartType> typeArguments;
|
||||
final FunctionType unaliased;
|
||||
|
||||
TypedefType(this.element, this.typeArguments);
|
||||
TypedefType(this.element, this.typeArguments, this.unaliased);
|
||||
|
||||
bool get isTypedef => true;
|
||||
|
||||
|
@ -291,9 +292,11 @@ class TypedefType extends DartType {
|
|||
}
|
||||
List<DartType> newTypeArguments =
|
||||
_substTypes(typeArguments, arguments, parameters);
|
||||
if (!identical(typeArguments, newTypeArguments)) {
|
||||
FunctionType newUnaliased = unaliased.subst(arguments, parameters);
|
||||
if (!identical(typeArguments, newTypeArguments) ||
|
||||
!identical(unaliased, newUnaliased)) {
|
||||
// Create a new type only if necessary.
|
||||
return new TypedefType(element, newTypeArguments);
|
||||
return new TypedefType(element, newTypeArguments, newUnaliased);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -380,6 +380,9 @@ class ResolutionEnqueuer extends EnqueuerImpl {
|
|||
_worldBuilder.registerTypeVariableTypeLiteral(type);
|
||||
}
|
||||
break;
|
||||
case TypeUseKind.RTI_VALUE:
|
||||
failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -448,7 +448,6 @@ class BackendImpacts {
|
|||
return _typeVariableExpression ??= new BackendImpact(staticUses: [
|
||||
_commonElements.setRuntimeTypeInfo,
|
||||
_commonElements.getRuntimeTypeInfo,
|
||||
_commonElements.runtimeTypeToString,
|
||||
_commonElements.createRuntimeType
|
||||
], otherImpacts: [
|
||||
listValues,
|
||||
|
|
|
@ -16,7 +16,6 @@ import '../universe/world_builder.dart';
|
|||
import 'allocator_analysis.dart' show JAllocatorAnalysis;
|
||||
import 'constant_system_javascript.dart';
|
||||
import 'js_backend.dart';
|
||||
import 'namer.dart';
|
||||
import 'runtime_types.dart';
|
||||
|
||||
typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant);
|
||||
|
@ -42,7 +41,6 @@ class ConstantEmitter implements ConstantValueVisitor<jsAst.Expression, Null> {
|
|||
final RuntimeTypesNeed _rtiNeed;
|
||||
final RuntimeTypesEncoder _rtiEncoder;
|
||||
final JAllocatorAnalysis _allocatorAnalysis;
|
||||
final Namer _namer;
|
||||
final CodeEmitterTask _task;
|
||||
final _ConstantReferenceGenerator constantReferenceGenerator;
|
||||
final _ConstantListGenerator makeConstantList;
|
||||
|
@ -59,7 +57,6 @@ class ConstantEmitter implements ConstantValueVisitor<jsAst.Expression, Null> {
|
|||
this._rtiNeed,
|
||||
this._rtiEncoder,
|
||||
this._allocatorAnalysis,
|
||||
this._namer,
|
||||
this._task,
|
||||
this.constantReferenceGenerator,
|
||||
this.makeConstantList);
|
||||
|
@ -280,19 +277,21 @@ class ConstantEmitter implements ConstantValueVisitor<jsAst.Expression, Null> {
|
|||
|
||||
@override
|
||||
jsAst.Expression visitType(TypeConstantValue constant, [_]) {
|
||||
DartType type = constant.representedType;
|
||||
jsAst.Name typeName;
|
||||
Entity element;
|
||||
if (type is InterfaceType) {
|
||||
element = type.element;
|
||||
} else if (type is TypedefType) {
|
||||
element = type.element;
|
||||
} else {
|
||||
assert(type is DynamicType);
|
||||
DartType type = constant.representedType.unaliased;
|
||||
|
||||
jsAst.Expression unexpected(TypeVariableType _variable) {
|
||||
TypeVariableType variable = _variable;
|
||||
throw failedAt(
|
||||
NO_LOCATION_SPANNABLE,
|
||||
"Unexpected type variable '${variable}'"
|
||||
" in constant '${constant.toDartText()}'");
|
||||
}
|
||||
typeName = _namer.runtimeTypeName(element);
|
||||
return new jsAst.Call(getHelperProperty(_commonElements.createRuntimeType),
|
||||
[js.quoteName(typeName)]);
|
||||
|
||||
jsAst.Expression rti =
|
||||
_rtiEncoder.getTypeRepresentation(_emitter, type, unexpected);
|
||||
|
||||
return new jsAst.Call(
|
||||
getHelperProperty(_commonElements.createRuntimeType), [rti]);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -210,6 +210,9 @@ class CodegenEnqueuer extends EnqueuerImpl {
|
|||
_worldBuilder.registerTypeVariableTypeLiteral(type);
|
||||
}
|
||||
break;
|
||||
case TypeUseKind.RTI_VALUE:
|
||||
_worldBuilder.registerTypeArgument(type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -202,6 +202,9 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
|||
}
|
||||
hasTypeLiteral = true;
|
||||
break;
|
||||
case TypeUseKind.RTI_VALUE:
|
||||
failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -250,6 +250,7 @@ class TrivialRuntimeTypesChecksBuilder implements RuntimeTypesChecksBuilder {
|
|||
..checkedInstance = true
|
||||
..typeArgument = true
|
||||
..checkedTypeArgument = true
|
||||
..typeLiteral = true
|
||||
..functionType = _computeFunctionType(_elementEnvironment, cls,
|
||||
strongMode: options.strongMode);
|
||||
classUseMap[cls] = classUse;
|
||||
|
@ -340,10 +341,12 @@ abstract class RuntimeTypesSubstitutionsMixin
|
|||
|
||||
bool isNativeClass = _closedWorld.nativeData.isNativeClass(cls);
|
||||
if (classUse.typeArgument ||
|
||||
classUse.typeLiteral ||
|
||||
(isNativeClass && classUse.checkedInstance)) {
|
||||
Substitution substitution = computeSubstitution(cls, cls);
|
||||
// We need [cls] at runtime - even if [cls] is not instantiated. Either
|
||||
// as a type argument or for an is-test if [cls] is native.
|
||||
// as a type argument, for a type literal or for an is-test if [cls] is
|
||||
// native.
|
||||
checks.add(new TypeCheck(cls, substitution, needsIs: isNativeClass));
|
||||
}
|
||||
|
||||
|
@ -492,7 +495,7 @@ abstract class RuntimeTypesSubstitutionsMixin
|
|||
|
||||
for (ClassEntity cls in classUseMap.keys) {
|
||||
ClassUse classUse = classUseMap[cls] ?? emptyUse;
|
||||
if (classUse.instance || classUse.typeArgument) {
|
||||
if (classUse.instance || classUse.typeArgument || classUse.typeLiteral) {
|
||||
// Add checks only for classes that are live either as instantiated
|
||||
// classes or type arguments passed at runtime.
|
||||
computeChecks(cls);
|
||||
|
@ -1935,54 +1938,69 @@ class RuntimeTypesImpl extends _RuntimeTypesBase
|
|||
Set<FunctionType> checkedFunctionTypes = new Set<FunctionType>();
|
||||
|
||||
TypeVisitor liveTypeVisitor =
|
||||
new TypeVisitor(onClass: (ClassEntity cls, {bool inTypeArgument}) {
|
||||
new TypeVisitor(onClass: (ClassEntity cls, {TypeVisitorState state}) {
|
||||
ClassUse classUse = classUseMap.putIfAbsent(cls, () => new ClassUse());
|
||||
if (inTypeArgument) {
|
||||
classUse.typeArgument = true;
|
||||
switch (state) {
|
||||
case TypeVisitorState.typeArgument:
|
||||
classUse.typeArgument = true;
|
||||
break;
|
||||
case TypeVisitorState.typeLiteral:
|
||||
classUse.typeLiteral = true;
|
||||
break;
|
||||
case TypeVisitorState.direct:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
TypeVisitor testedTypeVisitor =
|
||||
new TypeVisitor(onClass: (ClassEntity cls, {bool inTypeArgument}) {
|
||||
new TypeVisitor(onClass: (ClassEntity cls, {TypeVisitorState state}) {
|
||||
ClassUse classUse = classUseMap.putIfAbsent(cls, () => new ClassUse());
|
||||
if (inTypeArgument) {
|
||||
classUse.typeArgument = true;
|
||||
classUse.checkedTypeArgument = true;
|
||||
} else {
|
||||
classUse.checkedInstance = true;
|
||||
switch (state) {
|
||||
case TypeVisitorState.typeArgument:
|
||||
classUse.typeArgument = true;
|
||||
classUse.checkedTypeArgument = true;
|
||||
break;
|
||||
case TypeVisitorState.typeLiteral:
|
||||
break;
|
||||
case TypeVisitorState.direct:
|
||||
classUse.checkedInstance = true;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
codegenWorldBuilder.instantiatedTypes.forEach((InterfaceType type) {
|
||||
liveTypeVisitor.visitType(type, false);
|
||||
liveTypeVisitor.visitType(type, TypeVisitorState.direct);
|
||||
ClassUse classUse =
|
||||
classUseMap.putIfAbsent(type.element, () => new ClassUse());
|
||||
classUse.instance = true;
|
||||
FunctionType callType = _types.getCallType(type);
|
||||
if (callType != null) {
|
||||
testedTypeVisitor.visitType(callType, false);
|
||||
testedTypeVisitor.visitType(callType, TypeVisitorState.direct);
|
||||
}
|
||||
});
|
||||
|
||||
for (FunctionEntity element
|
||||
in codegenWorldBuilder.staticFunctionsNeedingGetter) {
|
||||
FunctionType functionType = _elementEnvironment.getFunctionType(element);
|
||||
testedTypeVisitor.visitType(functionType, false);
|
||||
testedTypeVisitor.visitType(functionType, TypeVisitorState.direct);
|
||||
}
|
||||
|
||||
for (FunctionEntity element in codegenWorldBuilder.closurizedMembers) {
|
||||
FunctionType functionType = _elementEnvironment.getFunctionType(element);
|
||||
testedTypeVisitor.visitType(functionType, false);
|
||||
testedTypeVisitor.visitType(functionType, TypeVisitorState.direct);
|
||||
}
|
||||
|
||||
void processMethodTypeArguments(_, Set<DartType> typeArguments) {
|
||||
for (DartType typeArgument in typeArguments) {
|
||||
liveTypeVisitor.visit(typeArgument, true);
|
||||
liveTypeVisitor.visit(typeArgument, TypeVisitorState.typeArgument);
|
||||
}
|
||||
}
|
||||
|
||||
codegenWorldBuilder.forEachStaticTypeArgument(processMethodTypeArguments);
|
||||
codegenWorldBuilder.forEachDynamicTypeArgument(processMethodTypeArguments);
|
||||
codegenWorldBuilder.constTypeLiterals.forEach((DartType type) {
|
||||
liveTypeVisitor.visitType(type, TypeVisitorState.typeLiteral);
|
||||
});
|
||||
|
||||
bool isFunctionChecked = false;
|
||||
|
||||
|
@ -1993,7 +2011,7 @@ class RuntimeTypesImpl extends _RuntimeTypesBase
|
|||
isFunctionChecked =
|
||||
isFunctionChecked || t.element == _commonElements.functionClass;
|
||||
}
|
||||
testedTypeVisitor.visitType(t, false);
|
||||
testedTypeVisitor.visitType(t, TypeVisitorState.direct);
|
||||
}
|
||||
|
||||
explicitIsChecks.forEach(processCheckedType);
|
||||
|
@ -2057,7 +2075,7 @@ class RuntimeTypesImpl extends _RuntimeTypesBase
|
|||
DartType bound =
|
||||
_elementEnvironment.getTypeVariableBound(typeVariable.element);
|
||||
processCheckedType(bound);
|
||||
liveTypeVisitor.visit(bound, true);
|
||||
liveTypeVisitor.visit(bound, TypeVisitorState.typeArgument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2334,6 +2352,7 @@ class TypeRepresentationGenerator
|
|||
final NativeBasicData _nativeData;
|
||||
// If true, compile using strong mode.
|
||||
final bool _strongMode;
|
||||
|
||||
OnVariableCallback onVariable;
|
||||
ShouldEncodeTypedefCallback shouldEncodeTypedef;
|
||||
Map<TypeVariableType, jsAst.Expression> typedefBindings;
|
||||
|
@ -2413,7 +2432,7 @@ class TypeRepresentationGenerator
|
|||
jsAst.Expression visitInterfaceType(InterfaceType type, Emitter emitter) {
|
||||
jsAst.Expression name = getJavaScriptClassName(type.element, emitter);
|
||||
jsAst.Expression result;
|
||||
if (type.treatAsRaw) {
|
||||
if ((!_strongMode && type.treatAsRaw) || type.typeArguments.isEmpty) {
|
||||
result = name;
|
||||
} else {
|
||||
// Visit all type arguments. This is done even for jsinterop classes to
|
||||
|
@ -2770,64 +2789,73 @@ class TypeCheck {
|
|||
'TypeCheck(cls=$cls,needsIs=$needsIs,substitution=$substitution)';
|
||||
}
|
||||
|
||||
class TypeVisitor extends DartTypeVisitor<void, bool> {
|
||||
enum TypeVisitorState { direct, typeArgument, typeLiteral }
|
||||
|
||||
class TypeVisitor extends DartTypeVisitor<void, TypeVisitorState> {
|
||||
Set<FunctionTypeVariable> _visitedFunctionTypeVariables =
|
||||
new Set<FunctionTypeVariable>();
|
||||
|
||||
final void Function(ClassEntity entity, {bool inTypeArgument}) onClass;
|
||||
final void Function(TypeVariableEntity entity, {bool inTypeArgument})
|
||||
final void Function(ClassEntity entity, {TypeVisitorState state}) onClass;
|
||||
final void Function(TypeVariableEntity entity, {TypeVisitorState state})
|
||||
onTypeVariable;
|
||||
final void Function(FunctionType type, {bool inTypeArgument}) onFunctionType;
|
||||
final void Function(FunctionType type, {TypeVisitorState state})
|
||||
onFunctionType;
|
||||
|
||||
TypeVisitor({this.onClass, this.onTypeVariable, this.onFunctionType});
|
||||
|
||||
visitType(DartType type, bool inTypeArgument) =>
|
||||
type.accept(this, inTypeArgument);
|
||||
visitType(DartType type, TypeVisitorState state) => type.accept(this, state);
|
||||
|
||||
visitTypes(List<DartType> types, bool inTypeArgument) {
|
||||
visitTypes(List<DartType> types, TypeVisitorState state) {
|
||||
for (DartType type in types) {
|
||||
visitType(type, inTypeArgument);
|
||||
visitType(type, state);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitTypeVariableType(TypeVariableType type, bool inTypeArgument) {
|
||||
void visitTypeVariableType(TypeVariableType type, TypeVisitorState state) {
|
||||
if (onTypeVariable != null) {
|
||||
onTypeVariable(type.element, inTypeArgument: inTypeArgument);
|
||||
onTypeVariable(type.element, state: state);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitInterfaceType(InterfaceType type, bool inTypeArgument) {
|
||||
visitInterfaceType(InterfaceType type, TypeVisitorState state) {
|
||||
if (onClass != null) {
|
||||
onClass(type.element, inTypeArgument: inTypeArgument);
|
||||
onClass(type.element, state: state);
|
||||
}
|
||||
visitTypes(type.typeArguments, true);
|
||||
visitTypes(
|
||||
type.typeArguments,
|
||||
state == TypeVisitorState.typeLiteral
|
||||
? state
|
||||
: TypeVisitorState.typeArgument);
|
||||
}
|
||||
|
||||
@override
|
||||
visitFunctionType(FunctionType type, bool inTypeArgument) {
|
||||
visitFunctionType(FunctionType type, TypeVisitorState state) {
|
||||
if (onFunctionType != null) {
|
||||
onFunctionType(type, inTypeArgument: inTypeArgument);
|
||||
onFunctionType(type, state: state);
|
||||
}
|
||||
// Visit all nested types as type arguments; these types are not runtime
|
||||
// instances but runtime type representations.
|
||||
visitType(type.returnType, true);
|
||||
visitTypes(type.parameterTypes, true);
|
||||
visitTypes(type.optionalParameterTypes, true);
|
||||
visitTypes(type.namedParameterTypes, true);
|
||||
state = state == TypeVisitorState.typeLiteral
|
||||
? state
|
||||
: TypeVisitorState.typeArgument;
|
||||
visitType(type.returnType, state);
|
||||
visitTypes(type.parameterTypes, state);
|
||||
visitTypes(type.optionalParameterTypes, state);
|
||||
visitTypes(type.namedParameterTypes, state);
|
||||
_visitedFunctionTypeVariables.removeAll(type.typeVariables);
|
||||
}
|
||||
|
||||
@override
|
||||
visitTypedefType(TypedefType type, bool inTypeArgument) {
|
||||
visitType(type.unaliased, inTypeArgument);
|
||||
visitTypedefType(TypedefType type, TypeVisitorState state) {
|
||||
visitType(type.unaliased, state);
|
||||
}
|
||||
|
||||
@override
|
||||
visitFunctionTypeVariable(FunctionTypeVariable type, bool inTypeArgument) {
|
||||
visitFunctionTypeVariable(FunctionTypeVariable type, TypeVisitorState state) {
|
||||
if (_visitedFunctionTypeVariables.add(type)) {
|
||||
visitType(type.bound, inTypeArgument);
|
||||
visitType(type.bound, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2914,6 +2942,17 @@ class ClassUse {
|
|||
///
|
||||
bool checkedTypeArgument = false;
|
||||
|
||||
/// Whether the class is used in a constant type literal.
|
||||
///
|
||||
/// For instance `A`, `B` and `C` in:
|
||||
///
|
||||
/// class A {}
|
||||
/// class B<T> {}
|
||||
/// class C {}
|
||||
/// main() => A == B<C>;
|
||||
///
|
||||
bool typeLiteral = false;
|
||||
|
||||
/// The function type of the class, if any.
|
||||
///
|
||||
/// This is only set if the function type is needed at runtime. For instance,
|
||||
|
@ -2942,6 +2981,9 @@ class ClassUse {
|
|||
if (checkedTypeArgument) {
|
||||
properties.add('checkedTypeArgument');
|
||||
}
|
||||
if (typeLiteral) {
|
||||
properties.add('rtiValue');
|
||||
}
|
||||
if (functionType != null) {
|
||||
properties.add('functionType');
|
||||
}
|
||||
|
|
|
@ -167,7 +167,6 @@ class Emitter extends js_emitter.EmitterBase {
|
|||
_closedWorld.rtiNeed,
|
||||
compiler.backend.rtiEncoder,
|
||||
_closedWorld.allocatorAnalysis,
|
||||
namer,
|
||||
task,
|
||||
this.constantReference,
|
||||
constantListGenerator);
|
||||
|
|
|
@ -84,7 +84,6 @@ class ModelEmitter {
|
|||
_closedWorld.rtiNeed,
|
||||
compiler.backend.rtiEncoder,
|
||||
_closedWorld.allocatorAnalysis,
|
||||
namer,
|
||||
task,
|
||||
this.generateConstantReference,
|
||||
constantListGenerator);
|
||||
|
|
|
@ -276,7 +276,9 @@ class TypeConverter implements DartTypeVisitor<DartType, EntityConverter> {
|
|||
@override
|
||||
DartType visitTypedefType(TypedefType type, EntityConverter converter) {
|
||||
return new TypedefType(
|
||||
converter(type.element), visitList(type.typeArguments, converter));
|
||||
converter(type.element),
|
||||
visitList(type.typeArguments, converter),
|
||||
visit(type.unaliased, converter));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -827,7 +827,8 @@ class TypeConverter extends DartTypeVisitor<DartType, Null> {
|
|||
DartType visitTypedefType(TypedefType type, _) {
|
||||
var element = toBackendEntity(type.element);
|
||||
var args = _visitList(type.typeArguments);
|
||||
return new TypedefType(element, args);
|
||||
var unaliased = convert(type.unaliased);
|
||||
return new TypedefType(element, args, unaliased);
|
||||
}
|
||||
|
||||
List<DartType> _visitList(List<DartType> list) =>
|
||||
|
|
|
@ -983,7 +983,8 @@ abstract class ElementCreatorMixin implements KernelToElementMapBase {
|
|||
TypedefType typedefType = new TypedefType(
|
||||
typedef,
|
||||
new List<DartType>.filled(
|
||||
node.typeParameters.length, const DynamicType()));
|
||||
node.typeParameters.length, const DynamicType()),
|
||||
getDartType(node.type));
|
||||
return _typedefs.register(
|
||||
typedef, new TypedefData(node, typedef, typedefType));
|
||||
}
|
||||
|
@ -1820,6 +1821,11 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
elementMap.getTypeVariable(node.parameter));
|
||||
}
|
||||
}
|
||||
if (node.parameter.parent is ir.Typedef) {
|
||||
// Typedefs are only used in type literals so we never need their type
|
||||
// variables.
|
||||
return const DynamicType();
|
||||
}
|
||||
return new TypeVariableType(elementMap.getTypeVariable(node.parameter));
|
||||
}
|
||||
|
||||
|
@ -2319,7 +2325,8 @@ class JsKernelToElementMap extends KernelToElementMapBase
|
|||
new TypedefType(
|
||||
newTypedef,
|
||||
new List<DartType>.filled(
|
||||
data.node.typeParameters.length, const DynamicType()))));
|
||||
data.node.typeParameters.length, const DynamicType()),
|
||||
getDartType(data.node.type))));
|
||||
assert(newTypedef.typedefIndex == oldTypedef.typedefIndex);
|
||||
}
|
||||
for (int memberIndex = 0;
|
||||
|
|
|
@ -2852,15 +2852,9 @@ class KernelSsaGraphBuilder extends ir.Visitor
|
|||
HInstruction value = typeBuilder.analyzeTypeArgument(
|
||||
dartType, sourceElement,
|
||||
sourceInformation: sourceInformation);
|
||||
_pushStaticInvocation(
|
||||
_commonElements.runtimeTypeToString,
|
||||
<HInstruction>[value],
|
||||
abstractValueDomain.stringType,
|
||||
const <DartType>[],
|
||||
sourceInformation: sourceInformation);
|
||||
_pushStaticInvocation(
|
||||
_commonElements.createRuntimeType,
|
||||
<HInstruction>[pop()],
|
||||
<HInstruction>[value],
|
||||
_typeInferenceMap.getReturnTypeOf(_commonElements.createRuntimeType),
|
||||
const <DartType>[],
|
||||
sourceInformation: sourceInformation);
|
||||
|
|
|
@ -2208,6 +2208,11 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
|||
generateConstant(node.constant, node.sourceInformation);
|
||||
|
||||
_registry.registerConstantUse(new ConstantUse.literal(node.constant));
|
||||
if (node.constant.isType) {
|
||||
TypeConstantValue typeConstant = node.constant;
|
||||
_registry.registerTypeUse(
|
||||
new TypeUse.constTypeLiteral(typeConstant.representedType));
|
||||
}
|
||||
}
|
||||
|
||||
visitNot(HNot node) {
|
||||
|
|
|
@ -77,6 +77,9 @@ abstract class CodegenWorldBuilder implements WorldBuilder {
|
|||
/// an ordering that is less sensitive to perturbations in the source code.
|
||||
List<ConstantValue> getConstantsForEmission(
|
||||
[Comparator<ConstantValue> preSortCompare]);
|
||||
|
||||
/// Returns the types that are live as constant type literals.
|
||||
Iterable<DartType> get constTypeLiterals;
|
||||
}
|
||||
|
||||
class CodegenWorldBuilderImpl extends WorldBuilderBase
|
||||
|
@ -162,6 +165,8 @@ class CodegenWorldBuilderImpl extends WorldBuilderBase
|
|||
final KernelToWorldBuilder _elementMap;
|
||||
final GlobalLocalsMap _globalLocalsMap;
|
||||
|
||||
final Set<DartType> _liveTypeArguments = new Set<DartType>();
|
||||
|
||||
CodegenWorldBuilderImpl(
|
||||
this._elementMap,
|
||||
this._globalLocalsMap,
|
||||
|
@ -688,4 +693,10 @@ class CodegenWorldBuilderImpl extends WorldBuilderBase
|
|||
f(member);
|
||||
});
|
||||
}
|
||||
|
||||
void registerTypeArgument(DartType type) {
|
||||
_liveTypeArguments.add(type);
|
||||
}
|
||||
|
||||
Iterable<DartType> get constTypeLiterals => _liveTypeArguments;
|
||||
}
|
||||
|
|
|
@ -582,6 +582,7 @@ enum TypeUseKind {
|
|||
NATIVE_INSTANTIATION,
|
||||
IMPLICIT_CAST,
|
||||
PARAMETER_CHECK,
|
||||
RTI_VALUE,
|
||||
}
|
||||
|
||||
/// Use of a [DartType].
|
||||
|
@ -629,6 +630,9 @@ class TypeUse {
|
|||
case TypeUseKind.PARAMETER_CHECK:
|
||||
sb.write('param:');
|
||||
break;
|
||||
case TypeUseKind.RTI_VALUE:
|
||||
sb.write('typeArg:');
|
||||
break;
|
||||
}
|
||||
sb.write(type);
|
||||
return sb.toString();
|
||||
|
@ -692,6 +696,11 @@ class TypeUse {
|
|||
return new TypeUse.internal(type, TypeUseKind.NATIVE_INSTANTIATION);
|
||||
}
|
||||
|
||||
/// [type] used as a direct RTI value.
|
||||
factory TypeUse.constTypeLiteral(DartType type) {
|
||||
return new TypeUse.internal(type, TypeUseKind.RTI_VALUE);
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
if (identical(this, other)) return true;
|
||||
if (other is! TypeUse) return false;
|
||||
|
|
|
@ -348,8 +348,7 @@ class JSInvocationMirror implements Invocation {
|
|||
int start = _arguments.length - _typeArgumentCount;
|
||||
var list = <Type>[];
|
||||
for (int index = 0; index < _typeArgumentCount; index++) {
|
||||
list.add(
|
||||
createRuntimeType(runtimeTypeToString(_arguments[start + index])));
|
||||
list.add(createRuntimeType(_arguments[start + index]));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
@ -3027,7 +3026,8 @@ class BoundClosure extends TearOffClosure {
|
|||
|
||||
toString() {
|
||||
var receiver = _receiver == null ? _self : _receiver;
|
||||
return "Closure '$_name' of ${Primitives.objectToHumanReadableString(receiver)}";
|
||||
return "Closure '$_name' of "
|
||||
"${Primitives.objectToHumanReadableString(receiver)}";
|
||||
}
|
||||
|
||||
@NoInline()
|
||||
|
@ -3062,8 +3062,8 @@ class BoundClosure extends TearOffClosure {
|
|||
@NoSideEffects()
|
||||
static String computeFieldNamed(String fieldName) {
|
||||
var template = new BoundClosure('self', 'target', 'receiver', 'name');
|
||||
var names = JSArray
|
||||
.markFixedList(JS('', 'Object.getOwnPropertyNames(#)', template));
|
||||
var names = JSArray.markFixedList(
|
||||
JS('', 'Object.getOwnPropertyNames(#)', template));
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
var name = names[i];
|
||||
if (JS('bool', '#[#] === #', template, name, fieldName)) {
|
||||
|
@ -3556,8 +3556,8 @@ class TypeErrorImplementation extends Error implements TypeError {
|
|||
|
||||
/// Normal type error caused by a failed subtype test.
|
||||
TypeErrorImplementation(Object value, String type)
|
||||
: message = "TypeError: ${Error.safeToString(value)}: "
|
||||
"type '${_typeDescription(value)}' is not a subtype of type '$type'";
|
||||
: message = "TypeError: ${Error.safeToString(value)}: type "
|
||||
"'${_typeDescription(value)}' is not a subtype of type '$type'";
|
||||
|
||||
TypeErrorImplementation.fromMessage(String this.message);
|
||||
|
||||
|
@ -3571,8 +3571,8 @@ class CastErrorImplementation extends Error implements CastError {
|
|||
|
||||
/// Normal cast error caused by a failed type cast.
|
||||
CastErrorImplementation(Object value, Object type)
|
||||
: message = "CastError: ${Error.safeToString(value)}: "
|
||||
"type '${_typeDescription(value)}' is not a subtype of type '$type'";
|
||||
: message = "CastError: ${Error.safeToString(value)}: type "
|
||||
"'${_typeDescription(value)}' is not a subtype of type '$type'";
|
||||
|
||||
String toString() => message;
|
||||
}
|
||||
|
|
|
@ -42,26 +42,28 @@
|
|||
|
||||
part of _js_helper;
|
||||
|
||||
Type createRuntimeType(String name) {
|
||||
// Use a 'JS' cast to String. Since this is registered as used by the
|
||||
// backend, type inference assumes the worst (name is dynamic).
|
||||
return new TypeImpl(JS('String', '#', name));
|
||||
/// Called from generated code.
|
||||
Type createRuntimeType(rti) {
|
||||
return new TypeImpl(rti);
|
||||
}
|
||||
|
||||
class TypeImpl implements Type {
|
||||
final String _typeName;
|
||||
final dynamic _rti;
|
||||
String __typeName;
|
||||
String _unmangledName;
|
||||
int _hashCode;
|
||||
|
||||
TypeImpl(this._typeName);
|
||||
TypeImpl(this._rti);
|
||||
|
||||
String get _typeName => __typeName ??= runtimeTypeToString(_rti);
|
||||
|
||||
String toString() {
|
||||
if (_unmangledName != null) return _unmangledName;
|
||||
String unmangledName = unmangleAllIdentifiersIfPreservedAnyways(_typeName);
|
||||
return _unmangledName = unmangledName;
|
||||
return _unmangledName ??=
|
||||
unmangleAllIdentifiersIfPreservedAnyways(_typeName);
|
||||
}
|
||||
|
||||
// TODO(ahe): This is a poor hashCode as it collides with its name.
|
||||
int get hashCode => _typeName.hashCode;
|
||||
int get hashCode => _hashCode ??= _typeName.hashCode;
|
||||
|
||||
bool operator ==(other) {
|
||||
return (other is TypeImpl) && _typeName == other._typeName;
|
||||
|
@ -171,10 +173,10 @@ String getClassName(var object) {
|
|||
* of type 4, the JavaScript array, where the first element represents the class
|
||||
* and the remaining elements represent the type arguments.
|
||||
*/
|
||||
String _getRuntimeTypeAsStringV1(var rti, {String onTypeVariable(int i)}) {
|
||||
String _getRuntimeTypeAsStringV1(var rti) {
|
||||
assert(isJsArray(rti));
|
||||
String className = rawRtiToJsConstructorName(getIndex(rti, 0));
|
||||
return '$className${joinArgumentsV1(rti, 1, onTypeVariable: onTypeVariable)}';
|
||||
return '$className${joinArgumentsV1(rti, 1)}';
|
||||
}
|
||||
|
||||
String _getRuntimeTypeAsStringV2(var rti, List<String> genericContext) {
|
||||
|
@ -186,29 +188,27 @@ String _getRuntimeTypeAsStringV2(var rti, List<String> genericContext) {
|
|||
/// Returns a human-readable representation of the type representation [rti].
|
||||
///
|
||||
/// Called from generated code.
|
||||
///
|
||||
/// [onTypeVariable] is used only from dart:mirrors.
|
||||
@NoInline()
|
||||
String runtimeTypeToString(var rti, {String onTypeVariable(int i)}) {
|
||||
String runtimeTypeToString(var rti) {
|
||||
return JS_GET_FLAG('STRONG_MODE')
|
||||
? runtimeTypeToStringV2(rti, null)
|
||||
: runtimeTypeToStringV1(rti, onTypeVariable: onTypeVariable);
|
||||
: runtimeTypeToStringV1(rti);
|
||||
}
|
||||
|
||||
String runtimeTypeToStringV1(var rti, {String onTypeVariable(int i)}) {
|
||||
String runtimeTypeToStringV1(var rti) {
|
||||
if (rti == null) {
|
||||
return 'dynamic';
|
||||
}
|
||||
if (isJsArray(rti)) {
|
||||
// A list representing a type with arguments.
|
||||
return _getRuntimeTypeAsStringV1(rti, onTypeVariable: onTypeVariable);
|
||||
return _getRuntimeTypeAsStringV1(rti);
|
||||
}
|
||||
if (isJsFunction(rti)) {
|
||||
// A reference to the constructor.
|
||||
return rawRtiToJsConstructorName(rti);
|
||||
}
|
||||
if (rti is int) {
|
||||
return '${onTypeVariable == null ? rti : onTypeVariable(rti)}';
|
||||
return '${rti}';
|
||||
}
|
||||
String functionPropertyName = JS_GET_NAME(JsGetName.FUNCTION_TYPE_TAG);
|
||||
if (JS('bool', 'typeof #[#] != "undefined"', rti, functionPropertyName)) {
|
||||
|
@ -218,9 +218,9 @@ String runtimeTypeToStringV1(var rti, {String onTypeVariable(int i)}) {
|
|||
String typedefPropertyName = JS_GET_NAME(JsGetName.TYPEDEF_TAG);
|
||||
var typedefInfo = JS('', '#[#]', rti, typedefPropertyName);
|
||||
if (typedefInfo != null) {
|
||||
return runtimeTypeToStringV1(typedefInfo, onTypeVariable: onTypeVariable);
|
||||
return runtimeTypeToStringV1(typedefInfo);
|
||||
}
|
||||
return _functionRtiToStringV1(rti, onTypeVariable);
|
||||
return _functionRtiToStringV1(rti);
|
||||
}
|
||||
// We should not get here.
|
||||
return 'unknown-reified-type';
|
||||
|
@ -263,7 +263,7 @@ String runtimeTypeToStringV2(var rti, List<String> genericContext) {
|
|||
return 'unknown-reified-type';
|
||||
}
|
||||
|
||||
String _functionRtiToStringV1(var rti, String onTypeVariable(int i)) {
|
||||
String _functionRtiToStringV1(var rti) {
|
||||
String returnTypeText;
|
||||
String voidTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG);
|
||||
if (JS('bool', '!!#[#]', rti, voidTag)) {
|
||||
|
@ -271,8 +271,7 @@ String _functionRtiToStringV1(var rti, String onTypeVariable(int i)) {
|
|||
} else {
|
||||
String returnTypeTag = JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG);
|
||||
var returnRti = JS('', '#[#]', rti, returnTypeTag);
|
||||
returnTypeText =
|
||||
runtimeTypeToStringV1(returnRti, onTypeVariable: onTypeVariable);
|
||||
returnTypeText = runtimeTypeToStringV1(returnRti);
|
||||
}
|
||||
|
||||
String argumentsText = '';
|
||||
|
@ -285,8 +284,7 @@ String _functionRtiToStringV1(var rti, String onTypeVariable(int i)) {
|
|||
List arguments = JS('JSFixedArray', '#[#]', rti, requiredParamsTag);
|
||||
for (var argument in arguments) {
|
||||
argumentsText += sep;
|
||||
argumentsText +=
|
||||
runtimeTypeToStringV1(argument, onTypeVariable: onTypeVariable);
|
||||
argumentsText += runtimeTypeToStringV1(argument);
|
||||
sep = ', ';
|
||||
}
|
||||
}
|
||||
|
@ -300,8 +298,7 @@ String _functionRtiToStringV1(var rti, String onTypeVariable(int i)) {
|
|||
sep = '';
|
||||
for (var argument in optionalArguments) {
|
||||
argumentsText += sep;
|
||||
argumentsText +=
|
||||
runtimeTypeToStringV1(argument, onTypeVariable: onTypeVariable);
|
||||
argumentsText += runtimeTypeToStringV1(argument);
|
||||
sep = ', ';
|
||||
}
|
||||
argumentsText += ']';
|
||||
|
@ -316,9 +313,8 @@ String _functionRtiToStringV1(var rti, String onTypeVariable(int i)) {
|
|||
sep = '';
|
||||
for (String name in extractKeys(namedArguments)) {
|
||||
argumentsText += sep;
|
||||
argumentsText += runtimeTypeToStringV1(
|
||||
JS('', '#[#]', namedArguments, name),
|
||||
onTypeVariable: onTypeVariable);
|
||||
argumentsText +=
|
||||
runtimeTypeToStringV1(JS('', '#[#]', namedArguments, name));
|
||||
argumentsText += ' $name';
|
||||
sep = ', ';
|
||||
}
|
||||
|
@ -454,8 +450,7 @@ String joinArguments(var types, int startIndex) {
|
|||
: joinArgumentsV1(types, startIndex);
|
||||
}
|
||||
|
||||
String joinArgumentsV1(var types, int startIndex,
|
||||
{String onTypeVariable(int i)}) {
|
||||
String joinArgumentsV1(var types, int startIndex) {
|
||||
if (types == null) return '';
|
||||
assert(isJsArray(types));
|
||||
bool firstArgument = true;
|
||||
|
@ -471,8 +466,7 @@ String joinArgumentsV1(var types, int startIndex,
|
|||
if (argument != null) {
|
||||
allDynamic = false;
|
||||
}
|
||||
buffer
|
||||
.write(runtimeTypeToStringV1(argument, onTypeVariable: onTypeVariable));
|
||||
buffer.write(runtimeTypeToStringV1(argument));
|
||||
}
|
||||
return allDynamic ? '' : '<$buffer>';
|
||||
}
|
||||
|
@ -480,22 +474,19 @@ String joinArgumentsV1(var types, int startIndex,
|
|||
String joinArgumentsV2(var types, int startIndex, List<String> genericContext) {
|
||||
if (types == null) return '';
|
||||
assert(isJsArray(types));
|
||||
bool firstArgument = true;
|
||||
var separator = '';
|
||||
bool allDynamic = true;
|
||||
StringBuffer buffer = new StringBuffer('');
|
||||
for (int index = startIndex; index < getLength(types); index++) {
|
||||
if (firstArgument) {
|
||||
firstArgument = false;
|
||||
} else {
|
||||
buffer.write(', ');
|
||||
}
|
||||
buffer.write(separator);
|
||||
separator = ', ';
|
||||
var argument = getIndex(types, index);
|
||||
if (argument != null) {
|
||||
allDynamic = false;
|
||||
}
|
||||
buffer.write(runtimeTypeToStringV2(argument, genericContext));
|
||||
}
|
||||
return allDynamic ? '' : '<$buffer>';
|
||||
return (!JS_GET_FLAG('STRONG_MODE') && allDynamic) ? '' : '<$buffer>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -519,9 +510,32 @@ String getRuntimeTypeString(var object) {
|
|||
return "$className${joinArguments(rti, 0)}";
|
||||
}
|
||||
|
||||
/// Returns the full type of [o] in the runtime type representation.
|
||||
getRti(o) {
|
||||
if (o is Closure) {
|
||||
// This excludes classes that implement Function via a `call` method, but
|
||||
// includes classes generated to represent closures in closure conversion.
|
||||
var functionRti = extractFunctionTypeObjectFrom(o);
|
||||
if (functionRti != null) return functionRti;
|
||||
}
|
||||
var interceptor = getInterceptor(o);
|
||||
var type = getRawRuntimeType(interceptor);
|
||||
if (o == null) return type;
|
||||
if (JS('bool', 'typeof # != "object"', o)) return type;
|
||||
var rti = getRuntimeTypeInfo(o);
|
||||
if (rti != null) {
|
||||
// If the type has type variables (that is, `rti != null`), make a copy of
|
||||
// the type arguments and insert [o] in the first position to create a
|
||||
// compound type representation.
|
||||
rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy.
|
||||
JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0.
|
||||
type = rti;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
Type getRuntimeType(var object) {
|
||||
String type = getRuntimeTypeString(object);
|
||||
return new TypeImpl(type);
|
||||
return new TypeImpl(getRti(object));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -616,7 +616,6 @@ LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError # Please
|
|||
LayoutTests/fast/dom/Range/range-expand_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/Range/range-insertNode-separate-endContainer_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/SelectorAPI/dumpNodeList-2_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: RuntimeError # Please triage this failure
|
||||
|
@ -662,7 +661,6 @@ LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # Pleas
|
|||
LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/distribution-crash_t01: RuntimeError
|
||||
LayoutTests/fast/dom/shadow/distribution-update-recalcs-style_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/insertion-point-list-menu-crash_t01: RuntimeError
|
||||
LayoutTests/fast/dom/shadow/insertion-point-shadow-crash_t01: RuntimeError
|
||||
LayoutTests/fast/dom/shadow/insertion-point-video-crash_t01: RuntimeError
|
||||
|
@ -1744,7 +1742,6 @@ LayoutTests/fast/dom/Range/range-constructor_t01: RuntimeError # Please triage t
|
|||
LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/Range/range-insertNode-separate-endContainer_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/SelectorAPI/dumpNodeList-2_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/Window/getMatchedCSSRules-with-pseudo-elements-complex_t01: Pass, RuntimeError # Issue 29634
|
||||
|
@ -1771,7 +1768,6 @@ LayoutTests/fast/dom/offset-position-writing-modes_t01: Pass, RuntimeError # Iss
|
|||
LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/content-pseudo-element-css-text_t01: Pass, RuntimeError # Issue 29634
|
||||
LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/host-context-pseudo-class-css-text_t01: Pass, RuntimeError # Issue 29634
|
||||
LayoutTests/fast/dom/shadow/host-pseudo-class-css-text_t01: Pass, RuntimeError # Issue 29634
|
||||
LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: RuntimeError # Please triage this failure
|
||||
|
@ -2713,7 +2709,6 @@ LayoutTests/fast/dom/Range/range-insertNode-assertion_t01: RuntimeError # Please
|
|||
LayoutTests/fast/dom/Range/range-insertNode-separate-endContainer_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/SelectorAPI/caseTagX_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/SelectorAPI/dumpNodeList-2_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/css-insert-import-rule-to-shadow-stylesheets_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: RuntimeError # Please triage this failure
|
||||
|
@ -2810,7 +2805,6 @@ LayoutTests/fast/dom/shadow/distribution-update-recalcs-style_t01: RuntimeError
|
|||
LayoutTests/fast/dom/shadow/elementfrompoint_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/elements-in-frameless-document_t01: RuntimeError # Issue 28983
|
||||
LayoutTests/fast/dom/shadow/event-path-not-in-document_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/form-in-shadow_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/get-distributed-nodes-orphan_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/get-element-by-id-in-shadow-mutation_t01: RuntimeError # Please triage this failure
|
||||
|
@ -4311,7 +4305,6 @@ LayoutTests/fast/dom/Range/range-processing-instructions_t01: RuntimeError # Ple
|
|||
LayoutTests/fast/dom/Selection/getRangeAt_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/SelectorAPI/caseID_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/SelectorAPI/caseTagX_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/SelectorAPI/dumpNodeList-2_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/css-insert-import-rule-to-shadow-stylesheets_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: RuntimeError # Please triage this failure
|
||||
|
@ -4440,7 +4433,6 @@ LayoutTests/fast/dom/shadow/distribution-for-event-path_t01: RuntimeError # Plea
|
|||
LayoutTests/fast/dom/shadow/distribution-update-recalcs-style_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/elementfrompoint_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/elements-in-frameless-document_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/get-distributed-nodes-orphan_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/get-element-by-id-in-shadow-mutation_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/getComputedStyle-composed-parent-dirty_t01: RuntimeError # Please triage this failure
|
||||
|
@ -5885,7 +5877,6 @@ LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Please
|
|||
LayoutTests/fast/dom/Range/range-isPointInRange_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/Range/range-on-detached-node_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/Range/surroundContents-for-detached-node_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/SelectorAPI/dumpNodeList-2_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/css-insert-import-rule-to-shadow-stylesheets_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/StyleSheet/detached-shadow-style_t01: RuntimeError # Please triage this failure
|
||||
|
@ -5961,7 +5952,6 @@ LayoutTests/fast/dom/shadow/distribution-update-recalcs-style_t01: RuntimeError
|
|||
LayoutTests/fast/dom/shadow/elementfrompoint_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/elements-in-frameless-document_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/event-path-not-in-document_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/form-in-shadow_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/get-distributed-nodes-orphan_t01: RuntimeError # Please triage this failure
|
||||
LayoutTests/fast/dom/shadow/get-element-by-id-in-shadow-mutation_t01: RuntimeError # Please triage this failure
|
||||
|
|
52
tests/compiler/dart2js/inference/data/non_null.dart
Normal file
52
tests/compiler/dart2js/inference/data/non_null.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/*element: main:[null]*/
|
||||
main() {
|
||||
nonNullStaticField();
|
||||
nonNullInstanceField1();
|
||||
nonNullInstanceField2();
|
||||
nonNullLocal();
|
||||
}
|
||||
|
||||
/*element: staticField:[null|exact=JSUInt31]*/
|
||||
var staticField;
|
||||
|
||||
/*element: nonNullStaticField:[exact=JSUInt31]*/
|
||||
nonNullStaticField() => staticField ??= 42;
|
||||
|
||||
/*element: Class1.:[exact=Class1]*/
|
||||
class Class1 {
|
||||
/*element: Class1.field:[null|exact=JSUInt31]*/
|
||||
var field;
|
||||
}
|
||||
|
||||
/*element: nonNullInstanceField1:[exact=JSUInt31]*/
|
||||
nonNullInstanceField1() {
|
||||
return new Class1(). /*[exact=Class1]*/ /*update: [exact=Class1]*/ field ??=
|
||||
42;
|
||||
}
|
||||
|
||||
/*element: Class2.:[exact=Class2]*/
|
||||
class Class2 {
|
||||
/*element: Class2.field:[null|exact=JSUInt31]*/
|
||||
var field;
|
||||
|
||||
/*element: Class2.method:[exact=JSUInt31]*/
|
||||
method() {
|
||||
return /*[exact=Class2]*/ /*update: [exact=Class2]*/ field ??= 42;
|
||||
}
|
||||
}
|
||||
|
||||
/*element: nonNullInstanceField2:[exact=JSUInt31]*/
|
||||
nonNullInstanceField2() {
|
||||
return new Class2(). /*invoke: [exact=Class2]*/ method();
|
||||
}
|
||||
|
||||
// TODO(johnniwinther): We should infer that the returned value cannot be null.
|
||||
/*element: nonNullLocal:[null|exact=JSUInt31]*/
|
||||
nonNullLocal() {
|
||||
var local = null;
|
||||
return local ??= 42;
|
||||
}
|
25
tests/compiler/dart2js/inference/data/type_literal.dart
Normal file
25
tests/compiler/dart2js/inference/data/type_literal.dart
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/*element: main:[null]*/
|
||||
main() {
|
||||
typeLiteral();
|
||||
typeLiteralToString();
|
||||
typeLiteralSubstring();
|
||||
}
|
||||
|
||||
/*element: typeLiteral:[exact=TypeImpl]*/
|
||||
typeLiteral() => Object;
|
||||
|
||||
/*kernel.element: typeLiteralToString:[null|subclass=Object]*/
|
||||
/*strong.element: typeLiteralToString:[exact=JSString]*/
|
||||
typeLiteralToString() => (Object). /*invoke: [exact=TypeImpl]*/ toString();
|
||||
|
||||
/*element: typeLiteralSubstring:[exact=JSString]*/
|
||||
typeLiteralSubstring() {
|
||||
String name = (List). /*invoke: [exact=TypeImpl]*/ toString();
|
||||
name = name. /*strong.invoke: [exact=JSString]*/ substring(
|
||||
0, name. /*strong.invoke: [exact=JSString]*/ indexOf('<'));
|
||||
return name;
|
||||
}
|
23
tests/compiler/dart2js/rti/data/indirect_type_literal.dart
Normal file
23
tests/compiler/dart2js/rti/data/indirect_type_literal.dart
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
class A<T> {}
|
||||
|
||||
class B<T extends num> {}
|
||||
|
||||
/*class: Indirect:exp,needsArgs*/
|
||||
class Indirect<T> {
|
||||
Type get type => T;
|
||||
}
|
||||
|
||||
void main() {
|
||||
Expect.equals(A, new Indirect<A>().type);
|
||||
Expect.equals(A, new Indirect<A<dynamic>>().type);
|
||||
Expect.notEquals(A, new Indirect<A<num>>().type);
|
||||
Expect.equals(B, new Indirect<B>().type);
|
||||
Expect.equals(B, new Indirect<B<num>>().type);
|
||||
Expect.notEquals(B, new Indirect<B<int>>().type);
|
||||
}
|
|
@ -10,6 +10,8 @@ test(o) => o is Function;
|
|||
main() {
|
||||
test(
|
||||
/*kernel.checks=[],functionType,instance*/
|
||||
/*strong.checks=[],instance*/ () {});
|
||||
/*strong.checks=[],instance*/
|
||||
/*omit.checks=[],instance*/
|
||||
() {});
|
||||
test(null);
|
||||
}
|
||||
|
|
|
@ -9,5 +9,9 @@ test(o) => o is Function();
|
|||
|
||||
main() {
|
||||
test(/*checks=[],functionType,instance*/ () {});
|
||||
test(/*checks=[],functionType,instance*/ (a) {});
|
||||
test(
|
||||
/*kernel.checks=[],functionType,instance*/
|
||||
/*strong.checks=[],instance*/
|
||||
/*omit.checks=[],instance*/
|
||||
(a) {});
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ class A<T> {
|
|||
return
|
||||
/*kernel.checks=[$signature],instance*/
|
||||
/*strong.checks=[],instance*/
|
||||
/*omit.checks=[],instance*/
|
||||
(T t, String s) {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/*class: global#Type:checks=[],instance,typeLiteral*/
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
void main() {
|
||||
Expect.isTrue(dynamic is Type);
|
||||
Expect.isFalse(dynamic == Type);
|
||||
}
|
|
@ -5,12 +5,14 @@
|
|||
import 'package:expect/expect.dart';
|
||||
import 'package:meta/dart2js.dart';
|
||||
|
||||
/*class: C:checkedInstance,checks=[],instance,typeArgument*/
|
||||
/*strong.class: C:checkedInstance,checks=[],instance,typeArgument*/
|
||||
/*omit.class: C:checks=[],instance,typeArgument*/
|
||||
class C {
|
||||
call(int i) {}
|
||||
}
|
||||
|
||||
/*class: D:checkedInstance,checks=[],instance,typeArgument*/
|
||||
/*strong.class: D:checkedInstance,checks=[],instance,typeArgument*/
|
||||
/*omit.class: D:checks=[],instance,typeArgument*/
|
||||
class D {
|
||||
call(double i) {}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
|
||||
library generic_methods_dynamic_test;
|
||||
|
||||
/*class: A:checkedInstance,checks=[],typeArgument*/
|
||||
/*strong.class: A:checkedInstance,checks=[],typeArgument*/
|
||||
/*omit.class: A:*/
|
||||
class A {}
|
||||
|
||||
/*class: B:checks=[],instance*/
|
||||
/*strong.class: B:checks=[],instance*/
|
||||
/*omit.class: B:*/
|
||||
class B {}
|
||||
|
||||
/*class: C:*/
|
||||
|
|
|
@ -14,6 +14,7 @@ import 'package:js/js.dart';
|
|||
|
||||
/*kernel.class: A:checkedTypeArgument,checks=[],typeArgument*/
|
||||
/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
|
||||
/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
|
||||
@JS()
|
||||
@anonymous
|
||||
class A<T> {
|
||||
|
|
|
@ -6,15 +6,18 @@ import 'package:meta/dart2js.dart';
|
|||
|
||||
/*kernel.class: global#JSArray:checkedInstance,checks=[$isIterable],instance*/
|
||||
/*strong.class: global#JSArray:checkedInstance,checks=[$isIterable,$isList],instance*/
|
||||
/*omit.class: global#JSArray:checkedInstance,checks=[$isIterable],instance*/
|
||||
|
||||
/*class: global#Iterable:checkedInstance*/
|
||||
|
||||
/*kernel.class: A:checkedTypeArgument,checks=[],typeArgument*/
|
||||
/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
|
||||
/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
|
||||
class A {}
|
||||
|
||||
/*kernel.class: B:checks=[],typeArgument*/
|
||||
/*strong.class: B:checkedInstance,checks=[],typeArgument*/
|
||||
/*omit.class: B:checks=[],typeArgument*/
|
||||
class B {}
|
||||
|
||||
@noInline
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
/*class: global#JSArray:checkedInstance,checks=[$isIterable,$isList],instance*/
|
||||
/*strong.class: global#JSArray:checkedInstance,checks=[$isIterable,$isList],instance*/
|
||||
/*omit.class: global#JSArray:checkedInstance,checks=[$isList],instance*/
|
||||
|
||||
@NoInline()
|
||||
method<T>() {
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
main() {
|
||||
/*checks=[],functionType,instance*/
|
||||
/*strong.checks=[],functionType,instance*/
|
||||
/*omit.checks=[],instance*/
|
||||
T id<T>(T t) => t;
|
||||
int Function(int) x = id;
|
||||
print("${x.runtimeType}");
|
||||
|
|
|
@ -4,18 +4,22 @@
|
|||
|
||||
import 'package:meta/dart2js.dart';
|
||||
|
||||
/*class: I1:checkedInstance*/
|
||||
/*strong.class: I1:checkedInstance*/
|
||||
/*omit.class: I1:*/
|
||||
class I1 {}
|
||||
|
||||
/*class: I2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
|
||||
/*strong.class: I2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
|
||||
/*omit.class: I2:checkedTypeArgument,checks=[],typeArgument*/
|
||||
class I2 {}
|
||||
|
||||
// TODO(32954): Exclude $isI1 because foo is only called directly.
|
||||
/*class: A:checks=[$isI1,$isI2],instance*/
|
||||
/*strong.class: A:checks=[$isI1,$isI2],instance*/
|
||||
/*omit.class: A:checks=[$isI2],instance*/
|
||||
class A implements I1, I2 {}
|
||||
|
||||
// TODO(32954): Exclude $isI1 because foo is only called directly.
|
||||
/*class: B:checks=[$isI1,$isI2],instance*/
|
||||
/*strong.class: B:checks=[$isI1,$isI2],instance*/
|
||||
/*omit.class: B:checks=[$isI2],instance*/
|
||||
class B implements I1, I2 {}
|
||||
|
||||
@noInline
|
||||
|
|
18
tests/compiler/dart2js/rti/emission/type_literal.dart
Normal file
18
tests/compiler/dart2js/rti/emission/type_literal.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
/*class: Class1:checks=[],typeLiteral*/
|
||||
class Class1 {}
|
||||
|
||||
/*class: Class2:checks=[],typeLiteral*/
|
||||
class Class2<X> {}
|
||||
|
||||
void main() {
|
||||
String name1 = '${Class1}';
|
||||
String name2 = '${Class2}';
|
||||
Expect.equals('Class1', name1);
|
||||
Expect.equals('Class2<dynamic>', name2);
|
||||
}
|
|
@ -27,6 +27,7 @@ main(List<String> args) {
|
|||
dataDir,
|
||||
const RtiEmissionDataComputer(),
|
||||
args: args,
|
||||
testOmit: true,
|
||||
skipForStrong: [
|
||||
// Dart 1 semantics:
|
||||
'call.dart',
|
||||
|
@ -50,6 +51,7 @@ class Tags {
|
|||
static const String checkedInstance = 'checkedInstance';
|
||||
static const String typeArgument = 'typeArgument';
|
||||
static const String checkedTypeArgument = 'checkedTypeArgument';
|
||||
static const String typeLiteral = 'typeLiteral';
|
||||
static const String functionType = 'functionType';
|
||||
}
|
||||
|
||||
|
@ -87,6 +89,9 @@ abstract class ComputeValueMixin {
|
|||
if (classUse.checkedTypeArgument) {
|
||||
features.add(Tags.checkedTypeArgument);
|
||||
}
|
||||
if (classUse.typeLiteral) {
|
||||
features.add(Tags.typeLiteral);
|
||||
}
|
||||
}
|
||||
return features.getText();
|
||||
}
|
||||
|
|
|
@ -187,9 +187,11 @@ main() {
|
|||
// List<E>
|
||||
expect(elementEnvironment.getThisType(List_), '[$List_rep, $List_E_rep]');
|
||||
// List
|
||||
expect(elementEnvironment.getRawType(List_), '$List_rep');
|
||||
expect(elementEnvironment.getRawType(List_),
|
||||
strongMode ? '[$List_rep,,]' : '$List_rep');
|
||||
// List<dynamic>
|
||||
expect(instantiate(List_, [dynamic_]), '$List_rep');
|
||||
expect(instantiate(List_, [dynamic_]),
|
||||
strongMode ? '[$List_rep,,]' : '$List_rep');
|
||||
// List<int>
|
||||
expect(instantiate(List_, [int_]), '[$List_rep, $int_rep]');
|
||||
// List<Typedef1>
|
||||
|
@ -263,9 +265,11 @@ main() {
|
|||
expect(elementEnvironment.getThisType(Map_),
|
||||
'[$Map_rep, $Map_K_rep, $Map_V_rep]');
|
||||
// Map
|
||||
expect(elementEnvironment.getRawType(Map_), '$Map_rep');
|
||||
expect(elementEnvironment.getRawType(Map_),
|
||||
strongMode ? '[$Map_rep,,,]' : '$Map_rep');
|
||||
// Map<dynamic,dynamic>
|
||||
expect(instantiate(Map_, [dynamic_, dynamic_]), '$Map_rep');
|
||||
expect(instantiate(Map_, [dynamic_, dynamic_]),
|
||||
strongMode ? '[$Map_rep,,,]' : '$Map_rep');
|
||||
// Map<int,String>
|
||||
expect(
|
||||
instantiate(Map_, [int_, String_]), '[$Map_rep, $int_rep, $String_rep]');
|
||||
|
|
|
@ -37,7 +37,7 @@ foo<Y>(int x) {
|
|||
|
||||
void main() {
|
||||
var name = '${Wrap}';
|
||||
if (name.length < 4) return; // minified.
|
||||
if ('$Object' != 'Object') return; // minified
|
||||
|
||||
Expect.equals(
|
||||
'Wrap<(int) => ((int) => void) => (int) => void>',
|
||||
|
|
27
tests/compiler/dart2js_extra/bounded_type_literal_test.dart
Normal file
27
tests/compiler/dart2js_extra/bounded_type_literal_test.dart
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// dart2jsOptions=--strong
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
class Foo<T extends num> {}
|
||||
|
||||
main() {
|
||||
var a = new Foo();
|
||||
var b = Foo;
|
||||
Expect.equals(a.runtimeType, b);
|
||||
|
||||
var runtimeTypeToString = "${a.runtimeType}";
|
||||
var typeLiteralToString = "${b}";
|
||||
Expect.equals(runtimeTypeToString, typeLiteralToString);
|
||||
|
||||
if ('$Object' == 'Object') {
|
||||
// `true` if non-minified.
|
||||
Expect.equals("Foo<num>", runtimeTypeToString);
|
||||
Expect.equals("Foo<num>", typeLiteralToString);
|
||||
}
|
||||
print(runtimeTypeToString);
|
||||
print(typeLiteralToString);
|
||||
}
|
|
@ -101,6 +101,7 @@ generic_method_dynamic_type_test: Fail, OK # Tests expected output of Type.toStr
|
|||
mirrors_used_warning_test/minif: Fail, OK # Tests warning that minified code will be broken.
|
||||
runtime_type_test: Fail, OK # Tests extected output of Type.toString().
|
||||
to_string_test: Fail # Issue 7179.
|
||||
type_literal_test: Fail, OK # Tests expected output of Type.toString().
|
||||
typevariable_typedef_test: Fail, OK # Tests expected output of Type.toString().
|
||||
|
||||
[ $compiler == dart2js && !$strong ]
|
||||
|
|
14
tests/compiler/dart2js_extra/dynamic_type_literal_test.dart
Normal file
14
tests/compiler/dart2js_extra/dynamic_type_literal_test.dart
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// dart2jsOptions=--strong --omit-implicit-checks
|
||||
|
||||
// Test generation of 'dynamic' type literals.
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
void main() {
|
||||
Expect.isTrue(dynamic is Type);
|
||||
Expect.isFalse(dynamic == Type);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// dart2jsOptions=--strong
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
class Foo<T extends num> {}
|
||||
|
||||
class Bar<T extends num> {}
|
||||
|
||||
main() {
|
||||
test(new Foo(), Foo, expectTypeArguments: false);
|
||||
test(new Bar() as Bar<num>, Bar, expectTypeArguments: true);
|
||||
}
|
||||
|
||||
void test(dynamic object, Type type, {bool expectTypeArguments}) {
|
||||
bool caught = false;
|
||||
try {
|
||||
print(type);
|
||||
object as List<String>;
|
||||
} catch (e) {
|
||||
String expected = '$type';
|
||||
if (!expectTypeArguments) {
|
||||
expected = expected.substring(0, expected.indexOf('<'));
|
||||
}
|
||||
expected = "'$expected'";
|
||||
Expect.isTrue(e.toString().contains(expected),
|
||||
'Expected "$expected" in the message: $e');
|
||||
caught = true;
|
||||
print(e);
|
||||
}
|
||||
Expect.isTrue(caught);
|
||||
}
|
24
tests/compiler/dart2js_extra/indirect_type_literal_test.dart
Normal file
24
tests/compiler/dart2js_extra/indirect_type_literal_test.dart
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// dart2jsOptions=--strong
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
class A<T> {}
|
||||
|
||||
class B<T extends num> {}
|
||||
|
||||
class Indirect<T> {
|
||||
Type get type => T;
|
||||
}
|
||||
|
||||
void main() {
|
||||
Expect.equals(A, new Indirect<A>().type);
|
||||
Expect.equals(A, new Indirect<A<dynamic>>().type);
|
||||
Expect.notEquals(A, new Indirect<A<num>>().type);
|
||||
Expect.equals(B, new Indirect<B>().type);
|
||||
Expect.equals(B, new Indirect<B<num>>().type);
|
||||
Expect.notEquals(B, new Indirect<B<int>>().type);
|
||||
}
|
|
@ -14,7 +14,7 @@ main() {
|
|||
// `true` if non-minified.
|
||||
// The signature of `id` is not otherwise needed so the instantiation
|
||||
// wrapper doesn't have a function type.
|
||||
Expect.equals("Instantiation1", toString);
|
||||
Expect.equals("Instantiation1<dynamic>", toString);
|
||||
}
|
||||
print(toString);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// 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.
|
||||
|
||||
// dart2jsOptions=--strong
|
||||
|
||||
// Test that Type.toString returns nice strings for native classes with
|
||||
// reserved names and for raw types.
|
||||
|
||||
|
@ -14,17 +16,18 @@ class D<X, Y, Z> {}
|
|||
class Class$With$Dollar {}
|
||||
|
||||
void main() {
|
||||
Expect.equals('C', new C().runtimeType.toString());
|
||||
Expect.equals('C<dynamic>', new C().runtimeType.toString());
|
||||
Expect.equals('C<int>', new C<int>().runtimeType.toString());
|
||||
Expect.equals('C<double>', new C<double>().runtimeType.toString());
|
||||
Expect.equals('C<num>', new C<num>().runtimeType.toString());
|
||||
Expect.equals('C<bool>', new C<bool>().runtimeType.toString());
|
||||
Expect.equals('D', new D().runtimeType.toString());
|
||||
Expect.equals('D<dynamic, dynamic, dynamic>', new D().runtimeType.toString());
|
||||
Expect.equals('D<dynamic, int, dynamic>',
|
||||
new D<dynamic, int, dynamic>().runtimeType.toString());
|
||||
D d = new D<dynamic, D, D<dynamic, dynamic, int>>();
|
||||
Expect.equals(
|
||||
'D<dynamic, D, D<dynamic, dynamic, int>>', d.runtimeType.toString());
|
||||
'D<dynamic, D<dynamic, dynamic, dynamic>, D<dynamic, dynamic, int>>',
|
||||
d.runtimeType.toString());
|
||||
Expect.equals(r'C<Class$With$Dollar>',
|
||||
new C<Class$With$Dollar>().runtimeType.toString());
|
||||
}
|
||||
|
|
|
@ -11,6 +11,11 @@ class Class<T> {
|
|||
}
|
||||
|
||||
main() {
|
||||
Expect.equals((Class).toString(), new Class().runtimeType.toString());
|
||||
Expect.equals((Class).toString(), new Class<int>().runtimeType.toString());
|
||||
// Since the type argument of `Class` is only needed for
|
||||
// `.runtimeType.toString()`, it is not reified, and the toString is therefore
|
||||
// only 'Class'.
|
||||
String className = (Class).toString();
|
||||
className = className.substring(0, className.indexOf('<'));
|
||||
Expect.equals(className, new Class().runtimeType.toString());
|
||||
Expect.equals(className, new Class<int>().runtimeType.toString());
|
||||
}
|
||||
|
|
|
@ -25,12 +25,16 @@ main() {
|
|||
C<String, String> x = (new C<C<int, String>, String>()) as dynamic;
|
||||
} catch (e) {
|
||||
String nameOfC = (C).toString();
|
||||
if (nameOfC.contains('<')) {
|
||||
nameOfC = nameOfC.substring(0, nameOfC.indexOf('<'));
|
||||
}
|
||||
String nameOfInt = (int).toString();
|
||||
String nameOfString = (String).toString();
|
||||
String expected =
|
||||
'$nameOfC<$nameOfC<$nameOfInt, $nameOfString>, $nameOfString>';
|
||||
"'$nameOfC<$nameOfC<$nameOfInt, $nameOfString>, $nameOfString>'";
|
||||
Expect.isTrue(e.toString().contains(expected),
|
||||
'Expected "$expected" in the message');
|
||||
'Expected "$expected" in the message: $e');
|
||||
print(e);
|
||||
caught = true;
|
||||
}
|
||||
Expect.isTrue(caught);
|
||||
|
|
18
tests/compiler/dart2js_extra/type_literal_test.dart
Normal file
18
tests/compiler/dart2js_extra/type_literal_test.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// dart2jsOptions=--strong
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
class Class1 {}
|
||||
|
||||
class Class2<X> {}
|
||||
|
||||
void main() {
|
||||
String name1 = '${Class1}';
|
||||
String name2 = '${Class2}';
|
||||
Expect.equals('Class1', name1);
|
||||
Expect.equals('Class2<dynamic>', name2);
|
||||
}
|
|
@ -19,9 +19,13 @@ class Derived2<U, V>
|
|||
|
||||
main() {
|
||||
var d = new Derived1<Derived1, Derived2>();
|
||||
Expect.equals("Derived1<Derived1, Derived2>", d.u.toString());
|
||||
Expect.equals(
|
||||
"Derived1<Derived2<Derived2, Derived1>, Derived2>", d.v.toString());
|
||||
"Derived1<Derived1<dynamic, dynamic>, Derived2<dynamic, dynamic>>",
|
||||
d.u.toString());
|
||||
Expect.equals(
|
||||
"Derived1<Derived2<Derived2<dynamic, dynamic>, "
|
||||
"Derived1<dynamic, dynamic>>, Derived2<dynamic, dynamic>>",
|
||||
d.v.toString());
|
||||
Expect.isTrue(d is Derived1<Derived1, Derived2>);
|
||||
Expect.isFalse(d is Derived1<Derived1, Derived1>);
|
||||
Expect.isTrue(d is Base<Derived1<Derived1, Derived2>,
|
||||
|
|
|
@ -552,10 +552,7 @@ partial_tearoff_instantiation_test/05: Pass # for the wrong reason.
|
|||
partial_tearoff_instantiation_test/06: Pass # for the wrong reason.
|
||||
partial_tearoff_instantiation_test/07: Pass # for the wrong reason.
|
||||
partial_tearoff_instantiation_test/08: Pass # for the wrong reason.
|
||||
type_alias_equality_test/01: RuntimeError # Issue 32784
|
||||
type_alias_equality_test/02: RuntimeError # Issue 32784
|
||||
type_alias_equality_test/03: RuntimeError # Issue 32784
|
||||
type_alias_equality_test/04: RuntimeError # Issue 32784
|
||||
|
||||
[ $compiler == dart2js && $fasta && $host_checked && $strong ]
|
||||
abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
|
||||
|
@ -939,6 +936,7 @@ wrong_number_type_arguments_test/none: Pass
|
|||
[ $compiler == dart2js && $minified ]
|
||||
cyclic_type2_test: RuntimeError # Issue 31054
|
||||
cyclic_type_test/0*: RuntimeError # Issue 31054
|
||||
f_bounded_quantification4_test: RuntimeError # Issue 31054
|
||||
f_bounded_quantification5_test: RuntimeError # Issue 31054
|
||||
generic_closure_test/01: RuntimeError # Uses runtimeType.toString()
|
||||
mixin_mixin2_test: RuntimeError # Issue 31054
|
||||
|
@ -989,10 +987,6 @@ constructor_redirect_test/01: Crash # Assertion failure: Cannot find value Insta
|
|||
covariance_type_parameter_test/02: RuntimeError
|
||||
covariant_subtyping_test: Crash
|
||||
ct_const_test: RuntimeError
|
||||
cyclic_type_test/00: RuntimeError
|
||||
cyclic_type_test/02: RuntimeError
|
||||
cyclic_type_test/03: RuntimeError
|
||||
cyclic_type_test/04: RuntimeError
|
||||
deferred_inheritance_constraints_test/extends: MissingCompileTimeError
|
||||
deferred_inheritance_constraints_test/implements: MissingCompileTimeError
|
||||
deferred_inheritance_constraints_test/mixin: MissingCompileTimeError
|
||||
|
@ -1012,7 +1006,6 @@ external_test/13: MissingRuntimeError
|
|||
external_test/20: MissingRuntimeError
|
||||
external_test/21: CompileTimeError
|
||||
external_test/24: CompileTimeError
|
||||
f_bounded_quantification4_test: RuntimeError
|
||||
field_initialization_order_test/01: MissingCompileTimeError
|
||||
field_initialization_order_test/none: RuntimeError
|
||||
flatten_test/05: MissingRuntimeError
|
||||
|
@ -1102,7 +1095,6 @@ mixin_illegal_superclass_test/27: MissingCompileTimeError
|
|||
mixin_illegal_superclass_test/28: MissingCompileTimeError
|
||||
mixin_illegal_superclass_test/29: MissingCompileTimeError
|
||||
mixin_illegal_superclass_test/30: MissingCompileTimeError
|
||||
mixin_mixin6_test: RuntimeError
|
||||
mixin_of_mixin_test/none: CompileTimeError
|
||||
mixin_super_2_test/none: CompileTimeError
|
||||
mixin_super_constructor_named_test/01: MissingCompileTimeError
|
||||
|
|
Loading…
Reference in a new issue