Check that const-map keys don't override equals.
BUG= http://dartbug.com/17123 R=karlklose@google.com Review URL: https://codereview.chromium.org//179293005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@33201 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
@@ -3098,11 +3098,32 @@ class ResolverVisitor extends MappingVisitor<Element> {
|
||||
return null;
|
||||
}
|
||||
|
||||
void checkConstMapKeysDontOverrideEquals(Spannable spannable,
|
||||
MapConstant map) {
|
||||
for (Constant key in map.keys.entries) {
|
||||
if (!key.isObject()) continue;
|
||||
ObjectConstant objectConstant = key;
|
||||
DartType keyType = objectConstant.type;
|
||||
ClassElement cls = keyType.element;
|
||||
if (cls == compiler.stringClass) continue;
|
||||
Element equals = cls.lookupMember('==');
|
||||
if (equals.getEnclosingClass() != compiler.objectClass) {
|
||||
compiler.reportError(spannable,
|
||||
MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS,
|
||||
{'type': keyType});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void analyzeConstant(Node node, {bool isConst: true}) {
|
||||
addDeferredAction(enclosingElement, () {
|
||||
Constant constant = compiler.constantHandler.compileNodeWithDefinitions(
|
||||
node, mapping, isConst: isConst);
|
||||
|
||||
if (isConst && constant != null && constant.isMap()) {
|
||||
checkConstMapKeysDontOverrideEquals(node, constant);
|
||||
}
|
||||
|
||||
// The type constant that is an argument to JS_INTERCEPTOR_CONSTANT names
|
||||
// a class that will be instantiated outside the program by attaching a
|
||||
// native class dispatch record referencing the interceptor.
|
||||
|
||||
@@ -556,8 +556,9 @@ main() => new C<String>();
|
||||
static const MessageKind CONSTRUCTOR_IS_NOT_CONST = const MessageKind(
|
||||
"Constructor is not a 'const' constructor.");
|
||||
|
||||
static const MessageKind KEY_NOT_A_STRING_LITERAL = const MessageKind(
|
||||
"Map-literal key not a string literal.");
|
||||
static const MessageKind CONST_MAP_KEY_OVERRIDES_EQUALS =
|
||||
const MessageKind(
|
||||
"Const-map key type '#{type}' overrides 'operator =='.");
|
||||
|
||||
static const MessageKind NO_SUCH_LIBRARY_MEMBER = const MessageKind(
|
||||
"'#{libraryName}' has no member named '#{memberName}'.");
|
||||
|
||||
@@ -260,6 +260,7 @@ LibTest/math/cos_A01_t01: Fail # co19 issue 44
|
||||
[ $compiler == dart2js ]
|
||||
Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: RuntimeError # compiler cancelled: cannot resolve type T
|
||||
Language/07_Classes/3_Setters_A04_t03: RuntimeError # http://dartbug.com/5023
|
||||
Language/12_Expressions/07_Maps_A11_t01: CompileTimeError # Maybe ok. Issue 17207
|
||||
|
||||
[ $compiler == dart2js && $jscl ]
|
||||
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: RuntimeError # IllegalJSRegExpException: '\c(' 'SyntaxError: Invalid regular expression: /\c(/: Unterminated group'
|
||||
@@ -638,7 +639,6 @@ Language/07_Classes/6_Constructors/2_Factories_A10_t02: fail # co19-roll r587: P
|
||||
Language/07_Classes/6_Constructors/2_Factories_A10_t03: fail # co19-roll r587: Please triage this failure
|
||||
Language/10_Generics/09_Generics_A01_t17: fail # co19-roll r587: Please triage this failure
|
||||
Language/12_Expressions/06_Symbols_A01_t02: CompileTimeError # co19-roll r623: Please triage this failure
|
||||
Language/12_Expressions/07_Maps_A13_t01: MissingCompileTimeError # co19-roll r607: Please triage this failure
|
||||
Language/12_Expressions/12_Instance_Creation/1_New_A06_t15: CompileTimeError # co19-roll r651: Please triage this failure
|
||||
Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
|
||||
Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2014, 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 {
|
||||
const factory A() = B;
|
||||
}
|
||||
|
||||
class B implements A {
|
||||
const B();
|
||||
|
||||
operator ==(o) => true; /// 00: compile-time error
|
||||
}
|
||||
|
||||
confuse(x) {
|
||||
if (new DateTime.now() == 42) return confuse(2);
|
||||
return x;
|
||||
}
|
||||
|
||||
main() {
|
||||
// It is a compile-time error if the key type overrides operator ==.
|
||||
var m = const { const A(): 42 };
|
||||
Expect.equals(42, m[confuse(const B())]);
|
||||
|
||||
m = const { "foo": 99, const A(): 499 };
|
||||
Expect.equals(499, m[confuse(const B())]);
|
||||
}
|
||||
@@ -27,6 +27,9 @@ deferred_duplicate_prefix1_test/01: Fail
|
||||
deferred_duplicate_prefix2_test/01: Fail
|
||||
deferred_duplicate_prefix3_test/01: Fail
|
||||
|
||||
[ $compiler == dartanalyzer ]
|
||||
const_map2_test/00: MissingCompileTimeError # Issue 17209
|
||||
|
||||
[ $compiler == none && $runtime == vm ]
|
||||
class_keyword_test/02: MissingCompileTimeError # Issue 13627
|
||||
override_inheritance_mixed_test/08: MissingCompileTimeError # Issue 16137
|
||||
|
||||
Reference in New Issue
Block a user