mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Specs: pass the current <script> to the module library init()
function, rename it _init(), plumb that through AutomaticMetadata, and move @tagname and Element.tagname to a new frameworks.md file that has stuff that wouldn't actually be part of core Sky Review URL: https://codereview.chromium.org/946513006
This commit is contained in:
parent
484c581d71
commit
01bec1736f
@ -184,19 +184,6 @@ class Attr {
|
||||
final String value; // O(1)
|
||||
}
|
||||
|
||||
// @tagname annotation for registering elements
|
||||
// only useful when placed on classes that inherit from Element
|
||||
class tagname extends AutomaticMetadata {
|
||||
const tagname(this.name);
|
||||
final String name;
|
||||
void init(DeclarationMirror target, Module module) {
|
||||
assert(target is ClassMirror);
|
||||
if (!(target as ClassMirror).isSubclassOf(reflectClass(Element)))
|
||||
throw new UnsupportedError('@tagname can only be used on descendants of Element');
|
||||
module.registerElement(name, (target as ClassMirror).reflectedType);
|
||||
}
|
||||
}
|
||||
|
||||
// @hasShadow annotation for registering elements
|
||||
class _HasShadow {
|
||||
const _HasShadow();
|
||||
@ -222,12 +209,6 @@ abstract class Element extends ParentNode {
|
||||
// children must be Text or Element
|
||||
// if needsShadow is true, creates a shadow tree
|
||||
|
||||
String get tagName { // O(N) in number of annotations on the class
|
||||
// throws a StateError if the class doesn't have an @tagname annotation
|
||||
var tagnameClass = reflectClass(tagname);
|
||||
return (reflectClass(this.runtimeType).metadata.singleWhere((mirror) => mirror.type == tagnameClass).reflectee as tagname).name;
|
||||
}
|
||||
|
||||
external bool hasAttribute(String name); // O(N) in number of attributes
|
||||
external String getAttribute(String name); // O(N) in number of attributes
|
||||
external void setAttribute(String name, [String value = '']); // O(N) in number of attributes
|
||||
|
||||
31
specs/frameworks.md
Normal file
31
specs/frameworks.md
Normal file
@ -0,0 +1,31 @@
|
||||
Frameworks
|
||||
----------
|
||||
|
||||
Sky is intended to support multiple frameworks. Here is one way you
|
||||
could register a custom element using Dart annotations:
|
||||
|
||||
```dart
|
||||
// @tagname annotation for registering elements
|
||||
// only useful when placed on classes that inherit from Element
|
||||
class tagname extends AutomaticMetadata {
|
||||
const tagname(this.name);
|
||||
final String name;
|
||||
void init(DeclarationMirror target, Module module, ScriptElement script) {
|
||||
assert(target is ClassMirror);
|
||||
if (!(target as ClassMirror).isSubclassOf(reflectClass(Element)))
|
||||
throw new UnsupportedError('@tagname can only be used on descendants of Element');
|
||||
module.registerElement(name, (target as ClassMirror).reflectedType);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A framework that used the above code could use the following code to
|
||||
get the tag name of an element:
|
||||
|
||||
```dart
|
||||
String getTagName(Element element) { // O(N) in number of annotations on the class
|
||||
// throws a StateError if the class doesn't have an @tagname annotation
|
||||
var tagnameClass = reflectClass(tagname);
|
||||
return (reflectClass(element.runtimeType).metadata.singleWhere((mirror) => mirror.type == tagnameClass).reflectee as tagname).name;
|
||||
}
|
||||
```
|
||||
@ -71,15 +71,17 @@ the library itself):
|
||||
|
||||
```dart
|
||||
class _ { }
|
||||
void main() {
|
||||
void main(ScriptElement script) {
|
||||
LibraryMirror library = reflectClass(_).owner as LibraryMirror;
|
||||
if (library.declarations.containsKey(#init) && library.declarations[#init] is MethodMirror)
|
||||
init();
|
||||
AutomaticMetadata.runLibrary(library, module);
|
||||
if (library.declarations.containsKey(#_init) && library.declarations[#_init] is MethodMirror)
|
||||
_init(script);
|
||||
AutomaticMetadata.runLibrary(library, module, script);
|
||||
}
|
||||
```
|
||||
|
||||
Then, that ``main()`` function is called.
|
||||
Then, that ``main(script)`` function is called, with ``script`` set to
|
||||
the ``ScriptElement`` object representing the relevant ``<script>``
|
||||
element.
|
||||
|
||||
TODO(ianh): decide what URL and name we should give the libraries, as
|
||||
exposed in MirrorSystem.getName(libraryMirror.qualifiedName) etc
|
||||
|
||||
@ -26,9 +26,9 @@ import 'dart:mirrors';
|
||||
|
||||
abstract class AutomaticMetadata {
|
||||
const AutomaticMetadata();
|
||||
void init(DeclarationMirror target, Module module);
|
||||
void init(DeclarationMirror target, Module module, ScriptElement script);
|
||||
|
||||
static void runLibrary(LibraryMirror library, Module module) {
|
||||
static void runLibrary(LibraryMirror library, Module module, ScriptElement script) {
|
||||
library.declarations.values.toList() /* ..sort((DeclarationMirror a, DeclarationMirror b) {
|
||||
bool aHasLocation;
|
||||
try {
|
||||
@ -55,7 +55,7 @@ abstract class AutomaticMetadata {
|
||||
..forEach((DeclarationMirror d) {
|
||||
d.metadata.forEach((InstanceMirror i) {
|
||||
if (i.reflectee is AutomaticMetadata)
|
||||
i.reflectee.run(d, module);
|
||||
i.reflectee.run(d, module, script);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -63,16 +63,17 @@ abstract class AutomaticMetadata {
|
||||
|
||||
class AutomaticFunction extends AutomaticMetadata {
|
||||
const AutomaticFunction();
|
||||
void init(DeclarationMirror target, Module module) {
|
||||
void init(DeclarationMirror target, Module module, ScriptElement script) {
|
||||
assert(target is MethodMirror);
|
||||
MethodMirror f = target as MethodMirror;
|
||||
assert(!f.isAbstract);
|
||||
assert(f.isRegularMethod);
|
||||
assert(f.isTopLevel);
|
||||
assert(f.isStatic);
|
||||
assert(f.parameters.length == 0);
|
||||
assert(f.parameters.length == 1);
|
||||
assert(f.parameters[0].type == ScriptElement);
|
||||
assert(f.returnType == currentMirrorSystem().voidType);
|
||||
(f.owner as LibraryMirror).invoke(f.simpleName, []);
|
||||
(f.owner as LibraryMirror).invoke(f.simpleName, [script]);
|
||||
}
|
||||
}
|
||||
const autorun = const AutomaticFunction();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user