diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart index 5025840b17a..2b6522811a6 100644 --- a/runtime/lib/growable_array.dart +++ b/runtime/lib/growable_array.dart @@ -47,7 +47,7 @@ class GrowableObjectArray implements List { if (start < 0 || start > this.length) { throw new IndexOutOfRangeException(start); } - if (this.length + length >= backingArray.length) { + if (this.length + length > backingArray.length) { grow(backingArray.length + length); } Arrays.copy(backingArray, @@ -72,8 +72,10 @@ class GrowableObjectArray implements List { return list; } - // The length of this growable array. It is always less than the - // length of the backing array. + // The length of this growable array. It is always less than or equal to the + // length of the backing array, which itself is always greater than 0, so that + // grow() does not have to check for a zero length backing array before + // doubling its size. int _length; GrowableObjectArray() @@ -87,14 +89,6 @@ class GrowableObjectArray implements List { backingArray = new ObjectArray(capacity); } - GrowableObjectArray._usingArray(List array) { - backingArray = array; - _length = array.length; - if (_length == 0) { - grow(4); - } - } - factory GrowableObjectArray.from(Collection other) { List result = new GrowableObjectArray(); result.addAll(other); @@ -106,7 +100,7 @@ class GrowableObjectArray implements List { } void set length(int new_length) { - if (new_length >= backingArray.length) { + if (new_length > backingArray.length) { grow(new_length); } else { for (int i = new_length; i < _length; i++) { diff --git a/runtime/lib/lib_sources.gypi b/runtime/lib/lib_sources.gypi index 5c5abf44328..0ac44c1b148 100644 --- a/runtime/lib/lib_sources.gypi +++ b/runtime/lib/lib_sources.gypi @@ -13,7 +13,7 @@ 'error.cc', 'error.dart', 'error.h', - 'literal_map_factory.dart', + 'literal_factory.dart', 'object.cc', 'object.dart', ], diff --git a/runtime/lib/literal_factory.dart b/runtime/lib/literal_factory.dart new file mode 100644 index 00000000000..d8b4febdc75 --- /dev/null +++ b/runtime/lib/literal_factory.dart @@ -0,0 +1,55 @@ +// 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. + +// Factory class constructing mutable List and Map objects from parser generated +// list and map literals. + +class _LiteralFactory { + // [elements] contains elements that are not yet type checked. + factory List.fromLiteral(int location, + String element_type, + List elements) { + var len = elements.length; + var list = new GrowableObjectArray.withCapacity(len); + for (int i = 0; i < len; i++) { + // In checked mode only, rethrow a potential type error with a more user + // friendly error message. + try { + list.backingArray[i] = elements[i]; + } catch (TypeError error) { + TypeError._throwNew(location, + elements[i], + element_type, + "list literal element at index ${i}"); + } + } + list.length = len; + return list; + } + + // [elements] contains n key-value pairs. + // The keys are at position 2*n and are already type checked by the parser + // in checked mode. + // The values are at position 2*n+1 and are not yet type checked. + factory Map.fromLiteral(int location, + String value_type, + List elements) { + var map = new LinkedHashMap(); + var len = elements.length; + for (int i = 1; i < len; i += 2) { + // The type of the key has been checked in the parser already. + // In checked mode only, rethrow a potential type error with a more user + // friendly error message. + try { + map[elements[i - 1]] = elements[i]; + } catch (TypeError error) { + TypeError._throwNew(location, + elements[i], + value_type, + "map literal value at index ${i ~/ 2}"); + } + } + return map; + } +} diff --git a/runtime/lib/literal_map_factory.dart b/runtime/lib/literal_map_factory.dart deleted file mode 100644 index 9bb4fdeef11..00000000000 --- a/runtime/lib/literal_map_factory.dart +++ /dev/null @@ -1,26 +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. -// Immutable map class for compiler generated map literals. - -class _LiteralMapFactory { - // [elements] contains n key-value pairs. The keys are at position - // 2*n, the values at position 2*n+1. - factory Map.fromLiteral(int location, - String value_type, - List elements) { - var map = new LinkedHashMap(); - var len = elements.length; - for (int i = 1; i < len; i += 2) { - // The type of the key has been checked in the parser already. - if (elements[i] is !V) { - TypeError._throwNew(location, - elements[i], - value_type, - "map literal value at index ${i ~/ 2}"); - } - map[elements[i-1]] = elements[i]; - } - return map; - } -} diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index b67627de01b..1573754814c 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -28,8 +28,6 @@ namespace dart { -DEFINE_FLAG(bool, expose_core_impl, false, - "Enables access to core implementation library (only for testing)."); DEFINE_FLAG(bool, generate_gdb_symbols, false, "Generate symbols of generated dart functions for debugging with GDB"); @@ -4170,10 +4168,6 @@ RawLibrary* Library::NewLibraryHelper(const String& url, Library& core_lib = Library::Handle(Library::CoreLibrary()); ASSERT(!core_lib.IsNull()); result.AddImport(core_lib); - if (FLAG_expose_core_impl) { - // Make implementation corelib visible to Dart code. - result.AddImport(Library::Handle(Library::CoreImplLibrary())); - } } return result.raw(); } diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index f76218a8448..ffc04962060 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc @@ -26,17 +26,14 @@ DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); -DECLARE_FLAG(bool, expose_core_impl); // All references to Dart names are listed here. static const char* kAssertionErrorName = "AssertionError"; static const char* kFallThroughErrorName = "FallThroughError"; static const char* kThrowNewName = "_throwNew"; -static const char* kGrowableObjectArrayFromArrayName = - "GrowableObjectArray._usingArray"; -static const char* kGrowableObjectArrayName = "GrowableObjectArray"; -static const char* kLiteralMapFactoryName = "_LiteralMapFactory"; -static const char* kLiteralMapFactoryFromLiteralName = "Map.fromLiteral"; +static const char* kLiteralFactoryClassName = "_LiteralFactory"; +static const char* kLiteralFactoryListFromLiteralName = "List.fromLiteral"; +static const char* kLiteralFactoryMapFromLiteralName = "Map.fromLiteral"; static const char* kImmutableMapName = "ImmutableMap"; static const char* kImmutableMapConstructorName = "ImmutableMap."; static const char* kStringClassName = "StringBase"; @@ -4436,8 +4433,7 @@ static RawClass* LookupImplClass(const String& class_name) { static RawClass* LookupCoreClass(const String& class_name) { const Library& core_lib = Library::Handle(Library::CoreLibrary()); String& name = String::Handle(class_name.raw()); - if ((class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) && - !FLAG_expose_core_impl) { + if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { // Private identifiers are mangled on a per script basis. name = String::Concat(name, String::Handle(core_lib.private_key())); name = String::NewSymbol(name); @@ -6584,34 +6580,46 @@ void Parser::CheckConstructorCallTypeArguments( // Parse "[" [ expr { "," expr } ["," ] "]". -// Note: if the array literal is empty and the brackets have no whitespace +// Note: if the list literal is empty and the brackets have no whitespace // between them, the scanner recognizes the opening and closing bracket // as one token of type Token::kINDEX. -AstNode* Parser::ParseArrayLiteral(intptr_t type_pos, - bool is_const, - const TypeArguments& type_arguments) { +AstNode* Parser::ParseListLiteral(intptr_t type_pos, + bool is_const, + const TypeArguments& type_arguments) { + TRACE_PARSER("ParseListLiteral"); + ASSERT(type_pos >= 0); ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); const intptr_t literal_pos = token_index_; bool is_empty_literal = CurrentToken() == Token::kINDEX; ConsumeToken(); - // If no type arguments are provided, leave them as null, which is equivalent - // to using Array. See issue 4966724. + Type& element_type = Type::Handle(Type::DynamicType()); + // If no type argument vector is provided, leave it as null, which is + // equivalent to using Dynamic as the type argument for the element type. if (!type_arguments.IsNull()) { - // For now, only check the number of type arguments. See issue 4975876. + ASSERT(type_arguments.Length() > 0); + // List literals take a single type argument. + element_type = type_arguments.TypeAt(0); if (type_arguments.Length() != 1) { - ASSERT(type_pos >= 0); - ErrorMsg(type_pos, "wrong number of type arguments for Array literal"); + ErrorMsg(type_pos, + "a list literal takes one type argument specifying " + "the element type"); + } + if (is_const && !element_type.IsInstantiated()) { + ErrorMsg(type_pos, + "the type argument of a constant list literal cannot include " + "a type variable"); } } + ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); - // Parse the array elements. Note: there may be an optional extra + // Parse the list elements. Note: there may be an optional extra // comma after the last element. - ArrayNode* array = new ArrayNode(token_index_, type_arguments); + ArrayNode* list = new ArrayNode(token_index_, TypeArguments::ZoneHandle()); if (!is_empty_literal) { const bool saved_mode = SetAllowFunctionLiterals(true); while (CurrentToken() != Token::kRBRACK) { - array->AddElement(ParseExpr(is_const)); + list->AddElement(ParseExpr(is_const)); if (CurrentToken() == Token::kCOMMA) { ConsumeToken(); } else if (CurrentToken() != Token::kRBRACK) { @@ -6623,49 +6631,54 @@ AstNode* Parser::ParseArrayLiteral(intptr_t type_pos, } if (is_const) { - // Allocate and initialize the array at compile time. - Array& lit_array = - Array::ZoneHandle(Array::New(array->length(), Heap::kOld)); - if (!type_arguments.IsNull()) { - // TODO(regis): Where should we check the constraints on type parameters? - if (!type_arguments.IsInstantiated()) { - ErrorMsg("type must be constant in const constructor"); - } - lit_array.SetTypeArguments(type_arguments); - } + // Allocate and initialize the const list at compile time. + Array& const_list = + Array::ZoneHandle(Array::New(list->length(), Heap::kOld)); + const_list.SetTypeArguments(type_arguments); - for (int i = 0; i < array->length(); i++) { - AstNode* elem = array->ElementAt(i); + for (int i = 0; i < list->length(); i++) { + AstNode* elem = list->ElementAt(i); // Arguments have been evaluated to a literal value already. ASSERT(elem->IsLiteralNode()); - lit_array.SetAt(i, elem->AsLiteralNode()->literal()); + if (!element_type.IsDynamicType() && + !elem->AsLiteralNode()->literal().Is(element_type)) { + ErrorMsg(elem->AsLiteralNode()->token_index(), + "list literal element at index %d must be " + "a constant of type '%s'", + i, + String::Handle(element_type.Name()).ToCString()); + } + const_list.SetAt(i, elem->AsLiteralNode()->literal()); } - lit_array ^= lit_array.Canonicalize(); - lit_array.MakeImmutable(); - return new LiteralNode(literal_pos, lit_array); + const_list ^= const_list.Canonicalize(); + const_list.MakeImmutable(); + return new LiteralNode(literal_pos, const_list); } else { + // Factory call at runtime. + String& literal_factory_class_name = String::Handle( + String::NewSymbol(kLiteralFactoryClassName)); + const Class& literal_factory_class = + Class::Handle(LookupCoreClass(literal_factory_class_name)); + ASSERT(!literal_factory_class.IsNull()); + const String& literal_list_factory_name = + String::Handle(String::NewSymbol(kLiteralFactoryListFromLiteralName)); + const Function& literal_list_factory = Function::ZoneHandle( + literal_factory_class.LookupFactory(literal_list_factory_name)); + ASSERT(!literal_list_factory.IsNull()); if (!type_arguments.IsNull() && !type_arguments.IsInstantiated() && (current_block_->scope->function_level() > 0)) { // Make sure that the instantiator is captured. CaptureReceiver(); } - - // Make a new growable array from the fixed array. - String& growable_object_array_class_name = String::Handle( - String::NewSymbol(kGrowableObjectArrayName)); - const Class& growable_array_class = Class::Handle( - LookupImplClass(growable_object_array_class_name)); - String& ctor_name = - String::Handle(String::NewSymbol(kGrowableObjectArrayFromArrayName)); - Function& array_ctor = Function::ZoneHandle( - growable_array_class.LookupConstructor(ctor_name)); - ASSERT(!array_ctor.IsNull()); - ArgumentListNode* ctor_args = new ArgumentListNode(literal_pos); - ctor_args->Add(array); - CheckConstructorCallTypeArguments(literal_pos, array_ctor, type_arguments); + ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); + factory_param->Add( + new LiteralNode(literal_pos, Smi::ZoneHandle(Smi::New(literal_pos)))); + factory_param->Add( + new LiteralNode(literal_pos, String::ZoneHandle(element_type.Name()))); + factory_param->Add(list); return new ConstructorCallNode( - literal_pos, type_arguments, array_ctor, ctor_args); + literal_pos, type_arguments, literal_list_factory, factory_param); } } @@ -6704,14 +6717,15 @@ AstNode* Parser::ParseMapLiteral(intptr_t type_pos, const intptr_t literal_pos = token_index_; ConsumeToken(); - Type& value_type_argument = Type::Handle(Type::DynamicType()); + Type& value_type = Type::Handle(Type::DynamicType()); TypeArguments& map_type_arguments = TypeArguments::ZoneHandle(type_arguments.raw()); - // If no type argument is provided, leave it as null, which is equivalent - // to using Dynamic as the type argument for the value type. + // If no type argument vector is provided, leave it as null, which is + // equivalent to using Dynamic as the type argument for the value type. if (!map_type_arguments.IsNull()) { - // Map literals only take one type argument. - value_type_argument = map_type_arguments.TypeAt(0); + ASSERT(map_type_arguments.Length() > 0); + // Map literals take a single type argument. + value_type = map_type_arguments.TypeAt(0); if (map_type_arguments.Length() > 1) { // We temporarily accept two type arguments, as long as the first one is // type String. @@ -6720,21 +6734,21 @@ AstNode* Parser::ParseMapLiteral(intptr_t type_pos, "a map literal takes one type argument specifying " "the value type"); } - if (!value_type_argument.IsStringInterface()) { + if (!value_type.IsStringInterface()) { ErrorMsg(type_pos, "the key type of a map literal is implicitly 'String'"); } Warning(type_pos, "a map literal takes one type argument specifying " "the value type"); - value_type_argument = map_type_arguments.TypeAt(1); + value_type = map_type_arguments.TypeAt(1); } else { TypeArray& type_array = TypeArray::Handle(TypeArray::New(2)); type_array.SetTypeAt(0, Type::Handle(Type::StringInterface())); - type_array.SetTypeAt(1, value_type_argument); + type_array.SetTypeAt(1, value_type); map_type_arguments = type_array.raw(); } - if (is_const && !value_type_argument.IsInstantiated()) { + if (is_const && !value_type.IsInstantiated()) { ErrorMsg(type_pos, "the type argument of a constant map literal cannot include " "a type variable"); @@ -6785,11 +6799,13 @@ AstNode* Parser::ParseMapLiteral(intptr_t type_pos, // Arguments have been evaluated to a literal value already. ASSERT(arg->IsLiteralNode()); if (((i % 2) == 1) && // Check values only, not keys. - !value_type_argument.IsDynamicType() && - !arg->AsLiteralNode()->literal().Is(value_type_argument)) { + !value_type.IsDynamicType() && + !arg->AsLiteralNode()->literal().Is(value_type)) { ErrorMsg(arg->AsLiteralNode()->token_index(), - "map literal entry value must be a constant of type '%s'", - String::Handle(value_type_argument.Name()).ToCString()); + "map literal value at index %d must be " + "a constant of type '%s'", + i >> 1, + String::Handle(value_type.Name()).ToCString()); } key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); } @@ -6821,15 +6837,15 @@ AstNode* Parser::ParseMapLiteral(intptr_t type_pos, } } else { // Factory call at runtime. - String& literal_map_factory_class_name = String::Handle( - String::NewSymbol(kLiteralMapFactoryName)); - const Class& literal_map_factory_class = - Class::Handle(LookupCoreClass(literal_map_factory_class_name)); - ASSERT(!literal_map_factory_class.IsNull()); + String& literal_factory_class_name = String::Handle( + String::NewSymbol(kLiteralFactoryClassName)); + const Class& literal_factory_class = + Class::Handle(LookupCoreClass(literal_factory_class_name)); + ASSERT(!literal_factory_class.IsNull()); const String& literal_map_factory_name = - String::Handle(String::NewSymbol(kLiteralMapFactoryFromLiteralName)); + String::Handle(String::NewSymbol(kLiteralFactoryMapFromLiteralName)); const Function& literal_map_factory = Function::ZoneHandle( - literal_map_factory_class.LookupFactory(literal_map_factory_name)); + literal_factory_class.LookupFactory(literal_map_factory_name)); ASSERT(!literal_map_factory.IsNull()); if (!map_type_arguments.IsNull() && !map_type_arguments.IsInstantiated() && @@ -6841,8 +6857,7 @@ AstNode* Parser::ParseMapLiteral(intptr_t type_pos, factory_param->Add( new LiteralNode(literal_pos, Smi::ZoneHandle(Smi::New(literal_pos)))); factory_param->Add( - new LiteralNode(literal_pos, - String::ZoneHandle(value_type_argument.Name()))); + new LiteralNode(literal_pos, String::ZoneHandle(value_type.Name()))); factory_param->Add(kv_pairs); return new ConstructorCallNode( literal_pos, map_type_arguments, literal_map_factory, factory_param); @@ -6862,7 +6877,7 @@ AstNode* Parser::ParseCompoundLiteral() { AstNode* primary = NULL; if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { - primary = ParseArrayLiteral(type_pos, is_const, type_arguments); + primary = ParseListLiteral(type_pos, is_const, type_arguments); } else if (CurrentToken() == Token::kLBRACE) { primary = ParseMapLiteral(type_pos, is_const, type_arguments); } else { @@ -7307,9 +7322,9 @@ void Parser::SkipFunctionLiteral() { } -void Parser::SkipArrayLiteral() { +void Parser::SkipListLiteral() { if (CurrentToken() == Token::kINDEX) { - // Empty array literal. + // Empty list literal. ConsumeToken(); return; } @@ -7356,7 +7371,7 @@ void Parser::SkipCompoundLiteral() { } if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { - SkipArrayLiteral(); + SkipListLiteral(); } else if (CurrentToken() == Token::kLBRACE) { SkipMapLiteral(); } diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h index 00737bbe298..426cf8eb8b0 100644 --- a/runtime/vm/parser.h +++ b/runtime/vm/parser.h @@ -162,7 +162,7 @@ class Parser : ValueObject { void SkipNewOperator(); void SkipActualParameters(); void SkipMapLiteral(); - void SkipArrayLiteral(); + void SkipListLiteral(); void SkipFunctionLiteral(); void SkipStringLiteral(); @@ -342,9 +342,9 @@ class Parser : ValueObject { AstNode* ParsePrimary(); AstNode* ParseStringLiteral(); AstNode* ParseCompoundLiteral(); - AstNode* ParseArrayLiteral(intptr_t type_pos, - bool is_const, - const TypeArguments& type_arguments); + AstNode* ParseListLiteral(intptr_t type_pos, + bool is_const, + const TypeArguments& type_arguments); AstNode* ParseMapLiteral(intptr_t type_pos, bool is_const, const TypeArguments& type_arguments); diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc index c0f0d15f0bb..46aa59ba179 100644 --- a/runtime/vm/scanner.cc +++ b/runtime/vm/scanner.cc @@ -13,7 +13,6 @@ namespace dart { DEFINE_FLAG(bool, print_tokens, false, "Print scanned tokens."); -DECLARE_FLAG(bool, expose_core_impl); void Scanner::InitKeywordTable() { for (int i = 0; i < Token::numKeywords; i++) { @@ -252,7 +251,7 @@ void Scanner::ScanIdentChars(bool allow_dollar) { current_token_.kind = Token::kIDENT; String& literal = String::ZoneHandle(String::NewSymbol(source_, ident_pos, ident_length)); - if ((ident_char0 == kPrivateIdentifierStart) && !FLAG_expose_core_impl) { + if (ident_char0 == kPrivateIdentifierStart) { // Private identifiers are mangled on a per script basis. literal = String::Concat(literal, private_key_); literal = String::NewSymbol(literal); diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status index 1e9ea63bab4..64f4d6ffe9a 100644 --- a/tests/co19/co19-runtime.status +++ b/tests/co19/co19-runtime.status @@ -301,7 +301,6 @@ LangSpecTest/13_Types/13_8_Parameterized_Types/A02/t01: Fail # Issue 441 # Started failing after changing how @dynamic-type-error is handled. [ $component == vm && $checked ] -LangSpecTest/13_Types/13_2_Dynamic_Type_System/A01/t01: Fail # Issue 220 LibTest/core/List/every/List/every/A01/t04: Fail # Issue co19 - 46 LibTest/core/List/filter/List/filter/A01/t04: Fail # Issue co19 - 46 LibTest/core/List/forEach/List/forEach/A01/t05: Fail # Issue co19 - 46 diff --git a/tests/corelib/src/StringBaseVMTest.dart b/tests/corelib/src/StringBaseVMTest.dart index 1567de71a86..d96702e94f3 100644 --- a/tests/corelib/src/StringBaseVMTest.dart +++ b/tests/corelib/src/StringBaseVMTest.dart @@ -2,8 +2,6 @@ // 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 class 'StringBase' (currently VM specific). -// We use that flag to disable privacy. -// VMOptions=--expose_core_impl #library("StringBaseTest.dart"); #import("dart:coreimpl"); @@ -25,18 +23,14 @@ class StringBaseTest { } static testInterpolation() { - Expect.equals("", StringBase._interpolate([])); - Expect.equals("Hello World", - StringBase._interpolate(["Hello", " ", "World"])); - Expect.equals("Hello StringBase Tester!", - StringBase._interpolate(["Hello ", new StringBaseTest(), "!"])); - var answer = 40 + 2; var s = "The answer is $answer."; Expect.equals("The answer is 42.", s); - int numBottles = 99; + int numBottles = 33; String wall = "wall"; + s = "${numBottles*3} bottles of beer on the $wall."; + Expect.equals("99 bottles of beer on the wall.", s); } static testCreation() { diff --git a/tests/language/language.status b/tests/language/language.status index 4cdd017b5d6..a0cbd649c34 100644 --- a/tests/language/language.status +++ b/tests/language/language.status @@ -118,7 +118,10 @@ ImplicitThisTest/none: Fail # Issue 375 InterfaceFactory3NegativeTest: Fail # Bug 5387405 IsObjectTest: Skip # Hasn't be tested on DartC yet Library4NegativeTest: Fail # Bug 5406175 -ListLiteral3Test: Fail # Bug 4510015. +ListLiteral1NegativeTest: Skip # Issue 220 +ListLiteral2NegativeTest: Fail # Issue 220 +ListLiteral3Test: Fail # Issue 220 +ListLiteral4Test: Fail # Issue 220 ListTest: Fail # Bug 5146975. LocalFunction3Test: Fail # Bug 4202974. LocalFunctionTest: Fail # Bug in test. Bug 4202989 (shadowing). @@ -205,7 +208,6 @@ FactoryImplementationTest: Fail # Issue 523 BitOperationsTest: Fail # relies on big integers not available in JS CallThroughGetterTest: Fail -CanonicalConstTest: Fail # type in const array allocation is erased CharEscapeTest: Fail ClassOverrideNegativeTest: Fail ClosureSharedStateTest: Fail @@ -257,7 +259,10 @@ Library1NegativeTest: Fail # issue with test see #354 Library4NegativeTest: Fail # issue with test see #354 Library5NegativeTest: Fail # issue with test see #354 Library6NegativeTest: Fail # issue with test see #354 -ListLiteral3Test: Fail +ListLiteral1NegativeTest: Fail # Issue 220 +ListLiteral2NegativeTest: Fail # Issue 220 +ListLiteral3Test: Fail # Issue 220 +ListLiteral4Test: Fail # Issue 220 ListTest: Fail # array bound checks not implemented LocalFunction3Test: Fail LocalFunctionTest: Fail diff --git a/tests/language/src/CanonicalConstTest.dart b/tests/language/src/CanonicalConstTest.dart index 640f39af5aa..4fd1df8c5b8 100644 --- a/tests/language/src/CanonicalConstTest.dart +++ b/tests/language/src/CanonicalConstTest.dart @@ -25,7 +25,7 @@ class CanonicalConstTest { Expect.isTrue(const [2,1] !== const[1,2]); Expect.isTrue(const [1,2] === const [1,2]); Expect.isTrue(const [1,2] === const [1,2]); - Expect.isTrue(const [1,2] !== const [1,2]); + Expect.isTrue(const [1,2] !== const [1.0,2.0]); Expect.isTrue(const {"a":1, "b":2} === const {"a":1, "b":2}); Expect.isTrue(const {"a":1, "b":2} !== const {"a":2, "b":2}); } diff --git a/tests/language/src/ListLiteral1NegativeTest.dart b/tests/language/src/ListLiteral1NegativeTest.dart new file mode 100644 index 00000000000..e95522bd2ad --- /dev/null +++ b/tests/language/src/ListLiteral1NegativeTest.dart @@ -0,0 +1,22 @@ +// 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. +// VMOptions=--enable_type_checks +// +// Dart test program testing type checks in list literals. + +class ListLiteral1NegativeTest { + test() { + try { + var m = const [0, 1]; // 0 is not a String. + } catch (TypeError error) { + } + } +} + +main() { + var t = new ListLiteral1NegativeTest(); + t.test(); +} + + diff --git a/tests/language/src/ListLiteral2NegativeTest.dart b/tests/language/src/ListLiteral2NegativeTest.dart new file mode 100644 index 00000000000..23ada38423a --- /dev/null +++ b/tests/language/src/ListLiteral2NegativeTest.dart @@ -0,0 +1,22 @@ +// 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. +// VMOptions=--enable_type_checks +// +// Dart test program const map literals. + +class ListLiteral2NegativeTest { + test() { + try { + var m = const [0, 1]; // Type parameter is not allowed with const. + } catch (TypeError error) { + } + } +} + +main() { + var t = new ListLiteral2NegativeTest(); + t.test(); +} + + diff --git a/tests/language/src/ListLiteral4Test.dart b/tests/language/src/ListLiteral4Test.dart new file mode 100644 index 00000000000..ab22bb10932 --- /dev/null +++ b/tests/language/src/ListLiteral4Test.dart @@ -0,0 +1,53 @@ +// 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. +// VMOptions=--enable_type_checks +// +// Dart test program testing type checks in list literals. + +class ListLiteral4Test { + test() { + int result = 0; + try { + var m = [0, 1]; // 0 is not a String. + } catch (TypeError error) { + result += 1; + } + try { + var m = [0, 1]; + m["0"] = 1; // "0" is not an int. + } catch (TypeError error) { + result += 10; + } + try { + var m = {"a": "b"}; // "b" is not an int. + } catch (TypeError error) { + result += 100; + } + try { + var m = [0, 1]; // OK. + } catch (TypeError error) { + result += 1000; + } + try { + var m = [0, 1]; + m["0"] = 1; // "0" is not an int. + } catch (TypeError error) { + result += 10000; + } + try { + var m = const [0, 1]; + m["0"] = 1; // "0" is not an int. + } catch (TypeError error) { + result += 100000; + } + return result; + } +} + +main() { + var t = new ListLiteral4Test(); + Expect.equals(110111, t.test()); +} + +