diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart index 2fb0d5df777..e0108096f6c 100644 --- a/runtime/bin/builtin.dart +++ b/runtime/bin/builtin.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. #library("builtin"); +#import("dart:uri"); void print(arg) { _Logger._printString(arg.toString()); diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc index ceb4a7e2729..08641292961 100644 --- a/runtime/vm/class_finalizer.cc +++ b/runtime/vm/class_finalizer.cc @@ -1270,7 +1270,9 @@ void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, va_list args; va_start(args, format); LanguageError& error = LanguageError::Handle(); - if ((finalization == kFinalizeWellFormed) || FLAG_enable_type_checks) { + if (FLAG_enable_type_checks || + !type.HasResolvedTypeClass() || + (finalization == kFinalizeWellFormed)) { const Script& script = Script::Handle(cls.script()); if (prev_error.IsNull()) { error ^= Parser::FormatError( @@ -1283,12 +1285,15 @@ void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, ReportError(error); } } - if (FLAG_enable_type_checks) { - // In checked mode, mark type as malformed. + if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) { + // In check mode, always mark the type as malformed. + // In production mode, mark the type as malformed only if its type class is + // not resolved. type.set_malformed_error(error); } else { - // In production mode, replace malformed type with Dynamic type. - type.set_type_class(Class::Handle(Object::dynamic_class())); + // In production mode, do not mark the type with a resolved type class as + // malformed, but make it raw. + ASSERT(type.HasResolvedTypeClass()); type.set_arguments(AbstractTypeArguments::Handle()); } if (!type.IsFinalized()) { diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index 6151414449e..fbfb674587f 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc @@ -3166,11 +3166,16 @@ RawAbstractTypeArguments* Parser::ParseTypeArguments( do { ConsumeToken(); type = ParseType(finalization); - types.Add(type); // Only keep the error for the first malformed type argument. if (malformed_error->IsNull() && type.IsMalformed()) { *malformed_error = type.malformed_error(); } + // Map a malformed type argument to Dynamic, so that malformed types with + // a resolved type class are handled properly in production mode. + if (type.IsMalformed()) { + type = Type::DynamicType(); + } + types.Add(type); } while (CurrentToken() == Token::kCOMMA); Token::Kind token = CurrentToken(); if ((token == Token::kGT) || (token == Token::kSHR)) { @@ -7217,7 +7222,9 @@ RawAbstractType* Parser::ParseType( } AbstractType& type = AbstractType::Handle( Type::New(type_class, type_arguments, type_name.ident_pos)); - if (!malformed_error.IsNull()) { + // In production mode, malformed type arguments are mapped to Dynamic. + // In checked mode, a type with malformed type arguments is malformed. + if (FLAG_enable_type_checks && !malformed_error.IsNull()) { Type& parameterized_type = Type::Handle(); parameterized_type ^= type.raw(); parameterized_type.set_type_class(Class::Handle(Object::dynamic_class())); diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status index d3fc315916a..359e80e8f05 100644 --- a/tests/co19/co19-runtime.status +++ b/tests/co19/co19-runtime.status @@ -205,7 +205,7 @@ Language/08_Interfaces/3_Factories_and_Constructors_A06_t07: Fail Language/08_Interfaces/3_Factories_and_Constructors_A06_t08: Fail Language/08_Interfaces/4_Superinterfaces/1_Inheritance_and_Overriding_A01_t02: Fail Language/08_Interfaces/4_Superinterfaces_A01_t02: Fail -Language/09_Generics/09_Generics_A04_t06: Fail +Language/09_Generics/09_Generics_A04_t06: Fail # Issue 439 LibTest/core/FallThroughError/FallThroughError_A01_t01: Fail LibTest/core/FallThroughError/toString_A01_t01: Fail LibTest/core/Match/group_A01_t01: Fail # co19 issue 92 @@ -235,7 +235,7 @@ Language/11_Statements/11_Labels_A01_t03: Fail # TODO(vm-team): New failure at r Language/12_Libraries_and_Scripts/1_Imports_A05_t01: Fail # TODO(vm-team): New failure at r164. Please triage. [ $runtime == vm && $unchecked ] -Language/03_Overview/2_Privacy_A01_t06: Fail # TODO(vm-team): New failure at r164. Please triage. +Language/09_Generics/09_Generics_A04_t04: Fail # co19 issue 117 [ $runtime == vm && $arch == ia32 ] diff --git a/tests/language/language-leg.status b/tests/language/language-leg.status index 1633bc3d359..89503bb2673 100644 --- a/tests/language/language-leg.status +++ b/tests/language/language-leg.status @@ -61,6 +61,7 @@ GenericDeepTest: Fail # Expect.isTrue(false) fails. GenericInheritanceTest: Fail # Expect.isTrue(false) fails. GenericParameterizedExtendsTest: Fail # Expect.isTrue(false) fails. Instanceof2Test: Fail # Expect.equals(expected: , actual: ) fails. +Instanceof3Test: Fail # cannot resolve type UndeclaredType. LibraryPrivateInConstructorTest: Fail # Issue 2620. ListDoubleIndexInLoop2Test: Fail # Issue 2564. ListLiteral4Test: Fail # Illegal argument(s): 0 -- checked mode test. diff --git a/tests/language/language.status b/tests/language/language.status index eb191c7dcbd..14817799cab 100644 --- a/tests/language/language.status +++ b/tests/language/language.status @@ -73,7 +73,6 @@ ConstructorRedirectTest/01: Fail # Issue 2103. [ $compiler == none && $unchecked ] -IsNotClass3NegativeTest: Fail # Spec unclear. Prefix16NegativeTest: Fail # Bug 5532534 [ $compiler == none && $mode == debug ] @@ -108,6 +107,7 @@ FunctionTypeAliasNegativeTest: Fail # Bug 5231617. GenericParameterizedExtendsTest: Skip # Bug 5392297 GettersSettersType3Test: Fail # Issue 2351 InstanceCallWrongArgumentCountNegativeTest: Fail +Instanceof3Test: Fail # Issue 2571 Label2NegativeTest: Fail # issue 1658 Library4NegativeTest: Fail # Bug 5406175 ListLiteral4Test: Fail # Issue 1343 @@ -308,6 +308,7 @@ GetterClosureExecutionOrderTest: Pass # TODO(jmesserly): I don't think this is r ImplicitScopeTest: Fail ImpliedInterfaceTest: Fail Instanceof2Test: Fail +Instanceof3Test: Fail # Issue 2571 InterfaceFactory3NegativeTest: Fail IsNotClass4NegativeTest: Fail LabelTest: Fail diff --git a/tests/language/src/Instanceof3Test.dart b/tests/language/src/Instanceof3Test.dart new file mode 100644 index 00000000000..18006e2ff24 --- /dev/null +++ b/tests/language/src/Instanceof3Test.dart @@ -0,0 +1,86 @@ +// Copyright (c) 2012, 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. +// Dart test program for testing the instanceof operation. + +// In the type test 'e is T', it is a run-time error if T does not denote a type +// available in the current lexical scope. + +isCheckedMode() { + try { + var i = 1; + String s = i; + return false; + } catch(var e) { + return true; + } +} + +main() { + { + bool got_type_error = false; + var x = null; + try { + Expect.isFalse(x is UndeclaredType); // x is null. + } catch (TypeError error) { + got_type_error = true; + } + // Type error in production mode and in checked mode. + Expect.isTrue(got_type_error); + } + { + bool got_type_error = false; + var x = 1; + try { + Expect.isFalse(x is UndeclaredType); // x is not null. + } catch (TypeError error) { + got_type_error = true; + } + // Type error in production mode and in checked mode. + Expect.isTrue(got_type_error); + } + { + bool got_type_error = false; + var x = null; + try { + Expect.isFalse(x is List); // x is null. + } catch (TypeError error) { + got_type_error = true; + } + // Type error in checked mode only. + Expect.isTrue(got_type_error == isCheckedMode()); + } + { + bool got_type_error = false; + var x = 1; + try { + Expect.isFalse(x is List); // x is not a List. + } catch (TypeError error) { + got_type_error = true; + } + // Type error in checked mode only. + Expect.isTrue(got_type_error == isCheckedMode()); + } + { + bool got_type_error = false; + var x = new List(); + try { + Expect.isTrue(x is List); // x is a List. + } catch (TypeError error) { + got_type_error = true; + } + // Type error in checked mode only. + Expect.isTrue(got_type_error == isCheckedMode()); + } + { + bool got_type_error = false; + var x = new List(); + try { + Expect.isTrue(x is List); // x is a List. + } catch (TypeError error) { + got_type_error = true; + } + // Type error in checked mode only. + Expect.isTrue(got_type_error == isCheckedMode()); + } +} diff --git a/tests/language/src/IsNotClass3NegativeTest.dart b/tests/language/src/IsNotClass3NegativeTest.dart deleted file mode 100644 index 8b53ba68712..00000000000 --- a/tests/language/src/IsNotClass3NegativeTest.dart +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2011, 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. -// Dart test program for catch that we expect a class after an 'is'. - -class A { - const A(); -} - -class IsNotClass3NegativeTest { - static testMain() { - var a = new A(); - - if (a is B) { - return 0; - } - return 0; - } -} - -main() { - IsNotClass3NegativeTest.testMain(); -}