Version 1.4.0-dev.6.4

svn merge -c 35866 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 36037 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 36038 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@36091 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/docgen/lib/src/models/closure.dart b/pkg/docgen/lib/src/models/closure.dart
new file mode 100644
index 0000000..2fcfa19
--- /dev/null
+++ b/pkg/docgen/lib/src/models/closure.dart
@@ -0,0 +1,35 @@
+// 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.
+
+library docgen.models.closure;
+
+import '../exports/source_mirrors.dart';
+
+import 'doc_gen_type.dart';
+import 'indexable.dart';
+import 'mirror_based.dart';
+import 'model_helpers.dart';
+import 'parameter.dart';
+
+/// A class containing the properties of a function to be called (used in our
+/// case specifically to illustrate evidence of the type of function for a
+/// parameter).
+class Closure extends MirrorBased<FunctionTypeMirror> {
+
+  /// Parameters for this method.
+  final Map<String, Parameter> parameters;
+  final DocGenType returnType;
+  final FunctionTypeMirror mirror;
+
+  Closure(FunctionTypeMirror mirror, Indexable owner)
+    : returnType = new DocGenType(mirror.returnType, owner.owningLibrary),
+      parameters = createParameters(mirror.parameters, owner),
+      mirror = mirror;
+
+  /// Generates a map describing the [Method] object.
+  Map toMap() => {
+    'return': [returnType.toMap()],
+    'parameters': recurseMap(parameters),
+  };
+}
\ No newline at end of file
diff --git a/pkg/docgen/lib/src/models/method.dart b/pkg/docgen/lib/src/models/method.dart
index 9483a37..f25d53b 100644
--- a/pkg/docgen/lib/src/models/method.dart
+++ b/pkg/docgen/lib/src/models/method.dart
@@ -153,4 +153,4 @@
   }
 
   bool isValidMirror(DeclarationMirror mirror) => mirror is MethodMirror;
-}
+}
\ No newline at end of file
diff --git a/pkg/docgen/lib/src/models/model_helpers.dart b/pkg/docgen/lib/src/models/model_helpers.dart
index 48babc9..e5e55a0e 100644
--- a/pkg/docgen/lib/src/models/model_helpers.dart
+++ b/pkg/docgen/lib/src/models/model_helpers.dart
@@ -28,15 +28,15 @@
 /// Expand the method map [mapToExpand] into a more detailed map that
 /// separates out setters, getters, constructors, operators, and methods.
 Map expandMethodMap(Map<String, Method> mapToExpand) => {
-  'setters': recurseMap(filterMap(mapToExpand,
+  'setters': recurseMap(_filterMap(mapToExpand,
       (key, val) => val.mirror.isSetter)),
-  'getters': recurseMap(filterMap(mapToExpand,
+  'getters': recurseMap(_filterMap(mapToExpand,
       (key, val) => val.mirror.isGetter)),
-  'constructors': recurseMap(filterMap(mapToExpand,
+  'constructors': recurseMap(_filterMap(mapToExpand,
       (key, val) => val.mirror.isConstructor)),
-  'operators': recurseMap(filterMap(mapToExpand,
+  'operators': recurseMap(_filterMap(mapToExpand,
       (key, val) => val.mirror.isOperator)),
-  'methods': recurseMap(filterMap(mapToExpand,
+  'methods': recurseMap(_filterMap(mapToExpand,
       (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator))
 };
 
@@ -105,7 +105,7 @@
 
 /// Transforms the map by calling toMap on each value in it.
 Map recurseMap(Map inputMap) {
-  var outputMap = new SplayTreeMap();
+  var outputMap = new LinkedHashMap();
   inputMap.forEach((key, value) {
     if (value is Map) {
       outputMap[key] = recurseMap(value);
@@ -116,14 +116,6 @@
   return outputMap;
 }
 
-Map filterMap(Map map, Function test) {
-  var exported = new Map();
-  map.forEach((key, value) {
-    if (test(key, value)) exported[key] = value;
-  });
-  return exported;
-}
-
 /// Read a pubspec and return the library name given a [LibraryMirror].
 String getPackageName(LibraryMirror mirror) {
   if (mirror.uri.scheme != 'file') return '';
@@ -149,9 +141,9 @@
 Map<String, Map<String, DeclarationMirror>> calcExportedItems(
     LibrarySourceMirror library) {
   var exports = {};
-  exports['classes'] = {};
-  exports['methods'] = {};
-  exports['variables'] = {};
+  exports['classes'] = new SplayTreeMap();
+  exports['methods'] = new SplayTreeMap();
+  exports['variables'] = new SplayTreeMap();
 
   // Determine the classes, variables and methods that are exported for a
   // specific dependency.
@@ -220,7 +212,7 @@
 /// purposes).
 Map<String, Variable> createVariables(Iterable<VariableMirror> mirrors,
     Indexable owner) {
-  var data = {};
+  var data = new SplayTreeMap<String, Variable>();
   // TODO(janicejl): When map to map feature is created, replace the below
   // with a filter. Issue(#9590).
   mirrors.forEach((dart2js_mirrors.Dart2JsFieldMirror mirror) {
@@ -238,7 +230,7 @@
 /// purposes).
 Map<String, Method> createMethods(Iterable<MethodMirror> mirrors,
     Indexable owner) {
-  var group = new Map<String, Method>();
+  var group = new SplayTreeMap<String, Method>();
   mirrors.forEach((MethodMirror mirror) {
     if (includePrivateMembers || !mirror.isPrivate) {
       group[dart2js_util.nameOf(mirror)] = new Method(mirror, owner);
@@ -265,6 +257,14 @@
       value: (e) => new Generic(e));
 }
 
+Map _filterMap(Map map, bool test(k, v)) {
+  var exported = new SplayTreeMap();
+  map.forEach((key, value) {
+    if (test(key, value)) exported[key] = value;
+  });
+  return exported;
+}
+
 /// Annotations that we do not display in the viewer.
 const List<String> _SKIPPED_ANNOTATIONS = const [
   'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates',
diff --git a/pkg/docgen/lib/src/models/parameter.dart b/pkg/docgen/lib/src/models/parameter.dart
index 2f8798c..ef9d9ab 100644
--- a/pkg/docgen/lib/src/models/parameter.dart
+++ b/pkg/docgen/lib/src/models/parameter.dart
@@ -8,6 +8,7 @@
 import '../exports/source_mirrors.dart';
 
 import 'annotation.dart';
+import 'closure.dart';
 import 'doc_gen_type.dart';
 import 'library.dart';
 import 'mirror_based.dart';
@@ -25,6 +26,9 @@
   final String defaultValue;
   /// List of the meta annotations on the parameter.
   final List<Annotation> annotations;
+  final Library owningLibrary;
+  // Only non-null if this parameter is a function declaration.
+  Closure functionDeclaration;
 
   Parameter(ParameterMirror mirror, Library owningLibrary)
       : this.mirror = mirror,
@@ -34,16 +38,28 @@
         hasDefaultValue = mirror.hasDefaultValue,
         defaultValue = getDefaultValue(mirror),
         type = new DocGenType(mirror.type, owningLibrary),
-        annotations = createAnnotations(mirror, owningLibrary);
+        annotations = createAnnotations(mirror, owningLibrary),
+        owningLibrary = owningLibrary {
+    if (mirror.type is FunctionTypeMirror) {
+      functionDeclaration =
+          new Closure(mirror.type as FunctionTypeMirror, owningLibrary);
+    }
+  }
 
   /// Generates a map describing the [Parameter] object.
-  Map toMap() => {
-    'name': name,
-    'optional': isOptional,
-    'named': isNamed,
-    'default': hasDefaultValue,
-    'type': new List.filled(1, type.toMap()),
-    'value': defaultValue,
-    'annotations': annotations.map((a) => a.toMap()).toList()
-  };
-}
+  Map toMap() {
+    var map = {
+      'name': name,
+      'optional': isOptional,
+      'named': isNamed,
+      'default': hasDefaultValue,
+      'type': new List.filled(1, type.toMap()),
+      'value': defaultValue,
+      'annotations': annotations.map((a) => a.toMap()).toList()
+    };
+    if (functionDeclaration != null) {
+      map['functionDeclaration'] = functionDeclaration.toMap();
+    }
+    return map;
+  }
+}
\ No newline at end of file
diff --git a/pkg/docgen/test/constant_argument_test.dart b/pkg/docgen/test/constant_argument_test.dart
index ca735f4..6380fdd 100644
--- a/pkg/docgen/test/constant_argument_test.dart
+++ b/pkg/docgen/test/constant_argument_test.dart
@@ -42,6 +42,9 @@
 
       var params = functionDef['parameters'] as Map<String, dynamic>;
 
+      expect(params.keys, orderedEquals(_PARAM_NAME_ORDER),
+          reason: 'parameter order  must be maintained');
+
       var vals = {};
       params.forEach((paramName, paramHash) {
         expect(_PARAM_VALUES, contains(paramName));
@@ -53,10 +56,19 @@
 }
 
 final _PARAM_VALUES = {
-  "boolConst": "true",
   "intConst": "42",
+  "boolConst": "true",
   "listConst": '[true, 42, "Shanna", null, 3.14, []]',
+  "stringConst": "\"Shanna\"",
   "mapConst": startsWith("Map"),
-  "emptyMap": '{}',
-  "stringConst": "\"Shanna\""
+  "emptyMap": '{}'
 };
+
+const _PARAM_NAME_ORDER = const [
+  "intConst",
+  "boolConst",
+  "listConst",
+  "stringConst",
+  "mapConst",
+  "emptyMap"
+];
diff --git a/pkg/docgen/test/method_param_test.dart b/pkg/docgen/test/method_param_test.dart
new file mode 100644
index 0000000..a12840e
--- /dev/null
+++ b/pkg/docgen/test/method_param_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+library docgen.test.method_param;
+
+import 'package:path/path.dart' as path;
+import 'package:scheduled_test/scheduled_test.dart';
+
+import 'util.dart';
+import '../lib/docgen.dart' as gen;
+
+void main() {
+  test('method function parameters', () {
+    var lib_file = path.toUri(path.join(getMultiLibraryCodePath(), 'lib',
+        'test_lib2.dart'));
+    return gen.getMirrorSystem([lib_file], false)
+      .then((mirrorSystem) {
+        var library = new gen.Library(mirrorSystem.libraries[lib_file]);
+
+        // Test that libraries do recursive exports correctly.
+        var funcParams = library.functions['fooFunc'].parameters;
+        expect('Symbol("dart.core.int")', library.functions['fooFunc']
+            .parameters['fooFuncParam'].functionDeclaration.parameters['x']
+            .type.mirror.qualifiedName.toString());
+      });
+  });
+}
\ No newline at end of file
diff --git a/pkg/docgen/test/multi_library_code/lib/test_lib2.dart b/pkg/docgen/test/multi_library_code/lib/test_lib2.dart
index d9fa7ee..b28f6d8 100644
--- a/pkg/docgen/test/multi_library_code/lib/test_lib2.dart
+++ b/pkg/docgen/test/multi_library_code/lib/test_lib2.dart
@@ -5,3 +5,5 @@
 library test_lib2;
 
 export 'test_lib2_foo.dart';
+
+String fooFunc(bool fooFuncParam(int x)) => 'hi';
\ No newline at end of file
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index 1b19fbf..2592a72 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -1097,16 +1097,19 @@
 class JsCache {
   /// Returns a JavaScript object suitable for use as a cache.
   static allocate() {
-    var result = JS('=Object', '{x:0}');
+    var result = JS('=Object', 'Object.create(null)');
     // Deleting a property makes V8 assume that it shouldn't create a hidden
     // class for [result] and map transitions. Although these map transitions
     // pay off if there are many cache hits for the same keys, it becomes
     // really slow when there aren't many repeated hits.
+    JS('void', '#.x=0', result);
     JS('void', 'delete #.x', result);
     return result;
   }
 
-  static fetch(cache, String key) => JS('', '#[#]', cache, key);
+  static fetch(cache, String key) {
+    return JS('', '#[#]', cache, key);
+  }
 
   static void update(cache, String key, value) {
     JS('void', '#[#] = #', cache, key, value);
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index e7ebddb..fdf7393 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -1064,7 +1064,7 @@
     var cache = _getterCache;
     if (isMissingCache(cache)) {
       if ((_getterCache = --cache) != 0) return result;
-      cache = _getterCache = JS('=Object', '({})');
+      cache = _getterCache = JS('=Object', 'Object.create(null)');
     }
 
     // Make sure that symbol [fieldName] has a cache probing function ($p).
diff --git a/tests/lib/mirrors/get_field_cache_test.dart b/tests/lib/mirrors/get_field_cache_test.dart
new file mode 100644
index 0000000..4c71dbc
--- /dev/null
+++ b/tests/lib/mirrors/get_field_cache_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+@MirrorsUsed(targets: const ["A", "B"])
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A {
+  toString() => "A";
+}
+
+class B {
+  int x = 99;
+  toString() => "B";
+}
+
+void main() {
+  var a = new A();
+  var am = reflect(a);
+  for (int i = 0; i < 10; i++) {
+    // Adds a probe function on the symbol.
+    am.getField(#toString);
+  }
+  var b = new B();
+  var bm = reflect(b);
+  for (int i = 0; i < 10; i++) {
+    // Adds a field-cache on the mirror.
+    bm.getField(#x);
+  }
+  // There is a cache now, but the cache should not contain 'toString' from
+  // JavaScript's Object.prototype.
+  var toString = bm.getField(#toString).reflectee;
+  Expect.equals("B", toString());
+}
diff --git a/tests/lib/mirrors/invocation_cache_test.dart b/tests/lib/mirrors/invocation_cache_test.dart
new file mode 100644
index 0000000..0d9624a
--- /dev/null
+++ b/tests/lib/mirrors/invocation_cache_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+@MirrorsUsed(targets: const ["A"])
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A {
+  toString() => "A";
+}
+
+main() {
+  // The invocation cache must not find the 'toString' from JavaScript's
+  // Object.prototype.
+  var toString = reflect(new A()).getField(#toString).reflectee;
+  Expect.equals("A", Function.apply(toString, [], {}));
+}
diff --git a/tools/VERSION b/tools/VERSION
index 962d60b..423c53d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 4
 PATCH 0
 PRERELEASE 6
-PRERELEASE_PATCH 4
+PRERELEASE_PATCH 5