Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(360)

Unified Diff: sdk/lib/js/dartium/js_dartium.dart

Issue 2158493003: Utility class of static methods to efficiently manipulate typed JSInterop objects in a dynamic mann… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/js/dartium/js_dartium.dart
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index 4d1d6825b58e38abab6547af9af78e91ef51efc2..f184cfb04a7ef1fe21235c74eed2b8eb9b42d1d2 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -106,6 +106,11 @@ import 'cached_patches.dart';
final bool CHECK_JS_INVOCATIONS = true;
final String _DART_RESERVED_NAME_PREFIX = r'JS$';
+// If a private class is defined to use @JS we need to inject a non-private
+// class with a name that will not cause collisions in the library so we can
+// make JSObject implement that interface even though it is in a different
+// library.
+final String escapePrivateClassPrefix = r'$JSImplClass23402893498';
Alan Knight 2016/07/19 16:56:16 Is this a problem if there are two different priva
Jacob 2016/07/19 17:36:40 No because all libraries are imported into the dar
String _stripReservedNamePrefix(String name) =>
name.startsWith(_DART_RESERVED_NAME_PREFIX)
@@ -340,7 +345,7 @@ bool hasDomName(mirrors.DeclarationMirror mirror) {
_getJsMemberName(mirrors.DeclarationMirror mirror) {
var name = _getJsName(mirror);
- return name == null || name.isEmpty ? _getDeclarationName(mirror) : name;
+ return name == null || name.isEmpty ? _stripReservedNamePrefix(_getDeclarationName(mirror)) : name;
}
// TODO(jacobr): handle setters correctyl.
@@ -350,7 +355,7 @@ String _getDeclarationName(mirrors.DeclarationMirror declaration) {
assert(name.endsWith("="));
name = name.substring(0, name.length - 1);
}
- return _stripReservedNamePrefix(name);
+ return name;
}
final _JS_LIBRARY_PREFIX = "js_library";
@@ -524,6 +529,7 @@ _generateLibraryCodegen(uri, library, staticCodegen) {
if (isDom || isJsInterop) {
// TODO(jacobr): verify class implements JavaScriptObject.
var className = mirrors.MirrorSystem.getName(clazz.simpleName);
+ bool isPrivate = className.startsWith('_');
var classNameImpl = '${className}Impl';
var sbPatch = new StringBuffer();
if (isJsInterop) {
@@ -598,6 +604,12 @@ _generateLibraryCodegen(uri, library, staticCodegen) {
if (isDom) {
sbPatch.write(" static Type get instanceRuntimeType => ${classNameImpl};\n");
}
+ if (isPrivate) {
+ sb.write("""
+class ${escapePrivateClassPrefix}${className} implements $className {}
+""");
+ }
+
if (sbPatch.isNotEmpty) {
var typeVariablesClause = '';
if (!clazz.typeVariables.isEmpty) {
@@ -705,8 +717,11 @@ List<String> _generateInteropPatchFiles(List<String> libraryPaths, genCachedPatc
var isArray = typeMirror.isSubtypeOf(listMirror);
var isFunction = typeMirror.isSubtypeOf(functionMirror);
var isJSObject = typeMirror.isSubtypeOf(jsObjectMirror);
+ var className = mirrors.MirrorSystem.getName(typeMirror.simpleName);
+ var isPrivate = className.startsWith('_');
+ if (isPrivate) className = '${escapePrivateClassPrefix}${className}';
var fullName =
- '${prefixName}.${mirrors.MirrorSystem.getName(typeMirror.simpleName)}';
+ '${prefixName}.${className}';
(isArray ? implementsArray : implements).add(fullName);
if (!isArray && !isFunction && !isJSObject) {
// For DOM classes we need to be a bit more conservative at tagging them
@@ -1329,6 +1344,41 @@ class JsNative {
static JSFunction withThis(Function f) native "JsFunction_withThisNoWrap";
}
+/// Utility methods to efficiently manipulate typed JSInterop objects in cases
+/// where the name to call is not known at runtime. You should only use these
+/// methods when the same effect cannot be achieved with @JS annotations.
+/// These methods would be extension methods on JSObject if Dart supported
+/// extension methods.
+class JSNative {
+ /**
+ * WARNING: performance of this method is much worse than other methods
+ * in JSNative. Only use this method as a last resort.
+ *
+ * Recursively converts a JSON-like collection of Dart objects to a
+ * collection of JavaScript objects and returns a [JsObject] proxy to it.
+ *
+ * [object] must be a [Map] or [Iterable], the contents of which are also
+ * converted. Maps and Iterables are copied to a new JavaScript object.
+ * Primitives and other transferrable values are directly converted to their
+ * JavaScript type, and all other objects are proxied.
+ */
+ static jsify(object) {
+ if ((object is! Map) && (object is! Iterable)) {
+ throw new ArgumentError("object must be a Map or Iterable");
+ }
+ return _jsify(object);
+ }
+
+ static _jsify(object) native "JSObject_jsify";
+ static JSObject newObject() native "JSObject_newObject";
+
+ static hasProperty(JSObject o, name) => o._hasProperty(name);
+ static getProperty(JSObject o, name) => o._operator_getter(name);
+ static setProperty(JSObject o, name, value) => o._operator_setter(name, value);
+ static callMethod(JSObject o, String method, List args) => o._callMethod(method, args);
+ static instanceof(JSObject o, Function type) => o._instanceof(type);
+ static callConstructor(JSObject constructor, List args) native "JSNative_callConstructor";
+}
/**
* Proxies a JavaScript Function object.
@@ -1563,5 +1613,3 @@ JSFunction allowInteropCaptureThis(Function f) {
return ret;
}
}
-
-debugPrint(_) {}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698