Version 0.2.9.2
Cherry pick 16069 and 16079 from bleeding_edge into trunk.
git-svn-id: http://dart.googlecode.com/svn/trunk@16081 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 934490f..5277d97 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2025,6 +2025,11 @@
}
+bool Class::IsFunctionClass() const {
+ return raw() == Type::Handle(Type::Function()).type_class();
+}
+
+
bool Class::IsListClass() const {
return raw() == Isolate::Current()->object_store()->list_class();
}
@@ -2098,16 +2103,42 @@
len,
malformed_error);
}
- // TODO(regis): Check if type S has a call() method of function type T.
- // Check for two function types.
- if (IsSignatureClass() && other.IsSignatureClass()) {
- const Function& fun = Function::Handle(signature_function());
+ const bool other_is_function_class = other.IsFunctionClass();
+ if (other.IsSignatureClass() || other_is_function_class) {
const Function& other_fun = Function::Handle(other.signature_function());
- return fun.TypeTest(test_kind,
- type_arguments,
- other_fun,
- other_type_arguments,
- malformed_error);
+ if (IsSignatureClass()) {
+ if (other_is_function_class) {
+ return true;
+ }
+ // Check for two function types.
+ const Function& fun = Function::Handle(signature_function());
+ return fun.TypeTest(test_kind,
+ type_arguments,
+ other_fun,
+ other_type_arguments,
+ malformed_error);
+ }
+ // Check if type S has a call() method of function type T.
+ const String& function_name = String::Handle(Symbols::Call());
+ Function& function = Function::Handle(LookupDynamicFunction(function_name));
+ if (function.IsNull()) {
+ // Walk up the super_class chain.
+ Class& cls = Class::Handle(SuperClass());
+ while (!cls.IsNull() && function.IsNull()) {
+ function = cls.LookupDynamicFunction(function_name);
+ cls = cls.SuperClass();
+ }
+ }
+ if (!function.IsNull()) {
+ if (other_is_function_class ||
+ function.TypeTest(test_kind,
+ type_arguments,
+ other_fun,
+ other_type_arguments,
+ malformed_error)) {
+ return true;
+ }
+ }
}
// Check for 'direct super type' specified in the implements clause
// and check for transitivity at the same time.
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 367f64c..5864410 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -611,6 +611,9 @@
// Check if this class represents the 'Object' class.
bool IsObjectClass() const { return id() == kInstanceCid; }
+ // Check if this class represents the 'Function' class.
+ bool IsFunctionClass() const;
+
// Check if this class represents the 'List' class.
bool IsListClass() const;
diff --git a/tests/language/callable_test.dart b/tests/language/callable_test.dart
new file mode 100644
index 0000000..be43bfb
--- /dev/null
+++ b/tests/language/callable_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+class X {
+ call() => 42;
+}
+
+class Y {
+ call(int x) => 87;
+}
+
+typedef F(int x);
+typedef G(String y);
+
+main() {
+ X x = new X();
+ Function f = x; // Should pass checked mode test
+ Y y = new Y();
+ Function g = y; // Should pass checked mode test
+ F f0 = y; // Should pass checked mode test
+ F f1 = x; /// 00: dynamic type error, static type warning
+ G g0 = y; /// 01: dynamic type error, static type warning
+}
+
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 0c88a52..be05302 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -53,6 +53,7 @@
factory1_test/00: Fail
factory1_test/01: Fail
type_annotation_test/09: Fail # Named constructors interpreted as a type.
+callable_test/0*: Fail # Issue 7354
[ $compiler == dart2js && $unchecked ]
default_factory2_test/01: Fail # type arguments on redirecting factory not implemented
diff --git a/tools/VERSION b/tools/VERSION
index f2f2502..5e43b49 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
MINOR 2
BUILD 9
-PATCH 1
+PATCH 2
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
index 420952c..01c03bc 100644
--- a/utils/pub/command_lish.dart
+++ b/utils/pub/command_lish.dart
@@ -15,6 +15,7 @@
import 'io.dart';
import 'log.dart' as log;
import 'oauth2.dart' as oauth2;
+import 'path.dart' as path;
import 'pub.dart';
import 'validator.dart';
@@ -164,7 +165,20 @@
// Should instead only make these relative right before generating
// the tree display (which is what really needs them to be).
// Make it relative to the package root.
- return relativeTo(entry, rootDir);
+ entry = relativeTo(entry, rootDir);
+
+ // TODO(rnystrom): dir.list() will include paths with resolved
+ // symlinks. In particular, we'll get paths to symlinked files from
+ // "packages" that reach outside of this package. Since the path
+ // has already been resolved, we don't even see "packages" in that
+ // path anymore.
+ // These should not be included in the archive. As a hack, ignore
+ // any file whose relative path is backing out of the root
+ // directory. Should do something cleaner.
+ var parts = path.split(entry);
+ if (!parts.isEmpty && parts[0] == '..') return null;
+
+ return entry;
});
}));
});