OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of polymer; | 5 part of polymer; |
6 | 6 |
7 /** Annotation used to automatically register polymer elements. */ | 7 /** Annotation used to automatically register polymer elements. */ |
8 class CustomTag { | 8 class CustomTag { |
9 final String tagName; | 9 final String tagName; |
10 const CustomTag(this.tagName); | 10 const CustomTag(this.tagName); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // Search top-level functions marked with @initMethod | 83 // Search top-level functions marked with @initMethod |
84 for (var f in lib.functions.values) { | 84 for (var f in lib.functions.values) { |
85 _maybeInvoke(lib, f); | 85 _maybeInvoke(lib, f); |
86 } | 86 } |
87 | 87 |
88 for (var c in lib.classes.values) { | 88 for (var c in lib.classes.values) { |
89 // Search for @CustomTag on classes | 89 // Search for @CustomTag on classes |
90 for (var m in c.metadata) { | 90 for (var m in c.metadata) { |
91 var meta = m.reflectee; | 91 var meta = m.reflectee; |
92 if (meta is CustomTag) { | 92 if (meta is CustomTag) { |
93 Polymer.register(meta.tagName, _getReflectedTypeWorkaround(c)); | 93 Polymer.register(meta.tagName, getReflectedTypeWorkaround(c)); |
94 } | 94 } |
95 } | 95 } |
96 | 96 |
97 // TODO(sigmund): check also static methods marked with @initMethod. | 97 // TODO(sigmund): check also static methods marked with @initMethod. |
98 // This is blocked on two bugs: | 98 // This is blocked on two bugs: |
99 // - dartbug.com/12133 (static methods are incorrectly listed as top-level | 99 // - dartbug.com/12133 (static methods are incorrectly listed as top-level |
100 // in dart2js, so they end up being called twice) | 100 // in dart2js, so they end up being called twice) |
101 // - dartbug.com/12134 (sometimes "method.metadata" throws an exception, | 101 // - dartbug.com/12134 (sometimes "method.metadata" throws an exception, |
102 // we could wrap and hide those exceptions, but it's not ideal). | 102 // we could wrap and hide those exceptions, but it's not ideal). |
103 } | 103 } |
104 } | 104 } |
105 | 105 |
106 // Horrible hack to work around: http://dartbug.com/12607 | |
107 Type _getReflectedTypeWorkaround(ClassMirror cls) { | |
108 // On Dart VM, just return reflectedType. | |
109 if (1.0 is! int) return cls.reflectedType; | |
110 | |
111 var mangledName = reflect(cls).getField(_mangledNameField).reflectee; | |
112 Type type = _jsHelper.invoke(#createRuntimeType, [mangledName]).reflectee; | |
113 return type; | |
114 } | |
115 | |
116 final LibraryMirror _jsHelper = | |
117 currentMirrorSystem().libraries[Uri.parse('dart:_js_helper')]; | |
118 | |
119 final Symbol _mangledNameField = () { | |
120 var jsClassMirrorMirror = reflect(reflectClass(ClassMirror)).type; | |
121 for (var name in jsClassMirrorMirror.variables.keys) { | |
122 if (MirrorSystem.getName(name) == '_mangledName') return name; | |
123 } | |
124 }(); | |
125 | |
126 void _maybeInvoke(ObjectMirror obj, MethodMirror method) { | 106 void _maybeInvoke(ObjectMirror obj, MethodMirror method) { |
127 var annotationFound = false; | 107 var annotationFound = false; |
128 for (var meta in method.metadata) { | 108 for (var meta in method.metadata) { |
129 if (identical(meta.reflectee, initMethod)) { | 109 if (identical(meta.reflectee, initMethod)) { |
130 annotationFound = true; | 110 annotationFound = true; |
131 break; | 111 break; |
132 } | 112 } |
133 } | 113 } |
134 if (!annotationFound) return; | 114 if (!annotationFound) return; |
135 if (!method.isStatic) { | 115 if (!method.isStatic) { |
136 print("warning: methods marked with @initMethod should be static," | 116 print("warning: methods marked with @initMethod should be static," |
137 " ${method.simpleName} is not."); | 117 " ${method.simpleName} is not."); |
138 return; | 118 return; |
139 } | 119 } |
140 if (!method.parameters.where((p) => !p.isOptional).isEmpty) { | 120 if (!method.parameters.where((p) => !p.isOptional).isEmpty) { |
141 print("warning: methods marked with @initMethod should take no " | 121 print("warning: methods marked with @initMethod should take no " |
142 "arguments, ${method.simpleName} expects some."); | 122 "arguments, ${method.simpleName} expects some."); |
143 return; | 123 return; |
144 } | 124 } |
145 obj.invoke(method.simpleName, const []); | 125 obj.invoke(method.simpleName, const []); |
146 } | 126 } |
147 | 127 |
148 class _InitMethodAnnotation { | 128 class _InitMethodAnnotation { |
149 const _InitMethodAnnotation(); | 129 const _InitMethodAnnotation(); |
150 } | 130 } |
OLD | NEW |