Index: mirrors/introspection.dart |
=================================================================== |
--- mirrors/introspection.dart (revision 0) |
+++ mirrors/introspection.dart (revision 0) |
@@ -0,0 +1,469 @@ |
+#library("introspection"); |
ahe
2012/01/02 16:21:14
According to merriam-webster, "introspection" mean
|
+#import("corelib_mirrors.dart"); |
+#import("debug"); |
+ |
+/** |
+The root of the mirror hierarchy. |
+ |
+Should Mirror implement Hashable? |
ahe
2012/01/02 16:21:14
Yes :-)
|
+ |
+ Throughout the mirror API, we use maps to |
+ Maps allow random access to mirrors, looked up by name. |
+ One can always go through their values to look for mirrors with specific properties. |
mattsh
2012/01/03 20:00:15
line too long here and a couple other places
|
+ The keys will often by strings, but this is not required. All we require is that a key |
ahe
2012/01/02 16:21:14
by -> be
|
+ has a toString() method (which all objects have) that yields a string that identifies the desired mirror. |
+ |
+ The reason we do not insist on strings is that: |
+ a. Efficient implementations may use customized representations of source code strings |
+ (e.g., indices into a single source stream), and yet |
+ b. The string interface cannot be implemented by user code. |
+ |
+*/ |
+interface Mirror { |
+ |
+// final reflectee; |
+ // in principle, everything being reflected has some reified representation, but this does not hold at the |
+ // Dart language level |
ahe
2012/01/02 16:21:14
A concrete example: a compiler may provide a mirro
|
+ |
+ /** We need a way of distinguishing different kinds of mirrors for purposes such as |
+ equality, as illustrated by the proposed equality method: |
+ |
+ operator == (other) { return (kind == other.kind) && (reflectee == other.reflectee);} |
+ |
+ */ |
+ final String kind; |
ahe
2012/01/02 16:21:14
I'd prefer having a MirrorKind interface.
|
+} |
+ |
+ |
+/** |
+Return an isolate mirror on the isolate of the argument port p. |
+This is how we start reflecting on another isolate. |
+ |
+This is a synchronous wrapper around an asynchronous message send. I would like to |
+define it as an async function if we have language support for that. Or, we could |
+have it return a future. |
+*/ |
+IsolateMirror isolateMirrorOf(Port p); |
+ |
+ |
+/** |
+The main gateway into the mirror system. |
+Given a mirror on an isolate, one can obtain mirrors on its ports and libraries, |
+and in particular on its root library. One can also suspend it and get a mirror |
+on its stack. |
+*/ |
+interface IsolateMirror extends Mirror { |
+ |
+/** Return a mirror on the root library of the reflectee */ |
+ final LibraryMirror rootLibrary; |
+ |
+/** Return true unless the reflectee is suspended */ |
+ bool isActive(); |
mattsh
2012/01/03 20:00:15
Might be better to reverse this to be isSuspended
|
+ |
+/** Suspend the reflectee and return a mirror on its stack. |
+Do we want to separate this into two calls: suspend and stack? |
+ |
+This call is a synchronous wrapper around an async message send. If we support |
+async, it could be an async method instead. |
+ */ |
+ StackMirror stack(); |
ahe
2012/01/02 16:21:14
I think this name is problematic. The name should
|
+ |
+/** Return an immutable map from library names to mirrors on all libraries loaded |
+by the reflectee. |
+ */ |
+ Map<Object, LibraryMirror> libraries(); |
+ |
+/* Return a list of (mirrors for) all ports of the reflectee */ |
ahe
2012/01/02 16:21:14
Which end of the ports?
|
+ List<ObjectMirror> ports(); |
+} |
+ |
+ |
+ |
+ |
+/** A library mirror reflects a library instance, which includes actual classes and interfaces, |
+distinct from their declarations. |
+ This also leaves an opening for making libraries first class. |
+ |
+By extending ObjectMirror, we get the ability to access a library's state and call its functions. |
+ |
+A library itself has a declaration with access to the interface declarations. |
+ |
+One question is how what class does a generic class declaration G<T1 .. Tn> induce |
+in the library? |
+I'd say G<Dynamic, ..., Dynamic> but I admit it seems weird. TBD. |
ahe
2012/01/02 16:21:14
I'm not sure I understand this. A declaration of t
|
+ |
+There is no constructor in this interface. One would obtain |
+LibraryMirrors from the IsolateMirror. |
+*/ |
+interface LibraryMirror extends ObjectMirror { |
+ |
+/** Returns an immutable map from simple top level class names to mirrors on the classes |
+of the library. |
+*/ |
+ Map<Object, InterfaceMirror> classes(); |
mattsh
2012/01/03 20:00:15
Why do these methods return a Map, rather than sim
|
+ |
+/** Returns an immutable map from simple top level interface names to mirrors on |
+the interfaces of the library. |
+*/ |
+ Map<Object, InterfaceMirror> interfaces(); |
+ |
+/** Returns an immutable map from simple top level names to mirrors for |
+ all top level declarations in the library. |
+ */ |
+ Map<Object, Mirror> members(); |
+ |
+/** The declaration of this library */ |
+ LibraryDeclarationMirror declaration(); |
+ |
+//? Map<Object, LibraryMirror> imports |
+ |
+/** |
+ Lookup s in the scope of the library. Finds top level names and imported ones. |
+*/ |
+ Mirror lookupName(String s); |
ahe
2012/01/02 16:21:14
Doesn't this method lookup a mirror? Using a Strin
|
+} |
+ |
+/** |
+A library declaration represents the logical source of a library. |
+ |
+There is no constructor in this interface. |
+One would obtain LibraryDeclarationMirrors from a LibraryMirror. |
+*/ |
+interface LibraryDeclarationMirror extends Mirror { |
+ |
+/** The name of the library, as given in #library(). |
+*/ |
+ String simpleName(); |
ahe
2012/01/02 16:21:14
Object may be better here.
|
+ |
+/** Returns an immutable map from simple top level class names to mirrors on the |
+class declarations of the library. |
+*/ |
+ Map<Object, InterfaceDeclarationMirror> classes(); |
+ |
+/** Returns an immutable map from simple top level interface names to mirrors on the |
+interface declarations of the library. |
+*/ |
+ Map<Object, InterfaceDeclarationMirror> interfaces(); |
hausner
2011/12/21 21:53:19
Why do you use Object as the first type argument o
gbracha
2011/12/22 18:29:59
Because in some cases, the key should not be a sta
zundel
2012/01/03 19:31:22
IMHO, I don't think using Object as a key is very
|
+ |
+/** Returns an immutable map from simple top level function names to mirrors on the |
+function declarations of the library. |
+*/ |
+ Map<Object, MethodMirror> functions(); |
+ |
+/** Returns a map from simple top level variable names to mirrors on the |
+variable declarations of the library. |
+*/ |
+ Map<Object, VariableMirror> variables(); |
+ |
+/** Returns an immutable map from simple top level names to mirrors on the top level |
+declarations of the library. |
+*/ |
+ Map<Object, Mirror> declarations(); |
ahe
2012/01/02 16:21:14
I think this method is important. Preferably, you'
|
+ |
+/** Returns a list of all import clauses */ |
+ List<String> imports(); |
+ |
+/** Returns the source code for the library (if available). |
+If it isn't. what should it throw? |
+*/ |
+ String source();// multiple files |
+ |
+// Includes? Not semantically meaningful, let's skip for now |
ahe
2012/01/02 16:21:14
Everything in source code is important. Also, I'd
|
+} |
+ |
+ |
+/** A common supertype for interfaces and type variables */ |
+interface TypeMirror extends Mirror{ |
+ |
+} |
+ |
+/** |
+Represents a type variable, which has a name and a bound. |
+*/ |
+ |
+interface TypeVariableMirror extends TypeMirror { |
+ |
+ final String simpleName; |
+ String qualifiedName(); // => '{declaration().qualifiedName()}.{simpleName}'; |
+ String source(); // {return vmMirror.sourceFor(declaringClass.reflectee, simpleName);} |
+ // type variables in same space as anything else |
+ |
+ /** Return a mirror on the class, interface, or typedef that declared the |
+reflectee. */ |
+ Mirror declaration(); |
+ |
+ /** Returns a mirror on the bound of the reflectee */ |
+ TypeMirror bound(); |
+} |
+ |
+/** |
+Represents a class or interface. There is no separate ClassMirror, because a |
+ClassMirror would add very little to this interface (we could elide superclass perhaps). |
+ |
+An interface mirror represents an actual type. This is distinct from an interface |
+declaration, which may have formal type parameters (and in the future, may represent |
+a mixin). |
+ |
+We extend ObjectMirror because we must provide a way to call static methods and access |
+static fields. Not very satisfying. What happens if you ask for the class |
+of these things? Do we raise an exception? Or provide a class (such as DartClass, DartInterface or DartLibrary)? |
ahe
2012/01/02 16:21:14
Return null :-)
|
+*/ |
+interface InterfaceMirror extends ObjectMirror, TypeMirror { |
ahe
2012/01/02 16:21:14
From the perspective of using this library for sta
ahe
2012/01/02 16:21:14
An InterfaceMirror is not a TypeMirror. See commen
|
+ |
+ /** Return a mirror on the library that declared this interface */ |
+ LibraryMirror library(); |
+ |
+ /** Return a mirror on the declaration of this interface */ |
+ InterfaceDeclarationMirror declaration(); |
+ |
+/** Returns an immutable map from interface names to mirrors on the superinterfaces |
+of the reflectee. |
+*/ |
+ Map<Object, InterfaceMirror> superinterfaces(); |
ahe
2012/01/02 16:21:14
See above comments about how to separate applicati
|
+ |
+ /** If the reflectee is a class, return a mirror on its superclass. |
+If the reflectee is an interface, return a mirror on class Object*/ |
+ InterfaceMirror superclass(); |
ahe
2012/01/02 16:21:14
This should return a TypeMirror.
|
+ |
+ /** Returns an immutable map from the names of the formal type parameters of the |
+reflectee's declaration to the actual type arguments of the reflectee. |
+ |
+In contrast, the declaration gives type parameters */ |
+ Map<Object, TypeMirror> typeArguments(); |
ahe
2012/01/02 16:21:14
This does not belong here.
|
+ |
+ /** Return true iff this mirror reflects a class */ |
+ bool isClass; |
+ |
+/** Returns an immutable map from member names to mirrors on |
+all members of this type - including inherited ones */ |
+ Map<Object, Mirror> members(); |
+ |
+/** Return a mirror on the default implementation; returns null if there is none. */ |
+ InterfaceMirror defaultFactory(); |
+} |
+ |
+ |
+// Once we have proper aliases, we would add this: |
+// typedef ClassMirror = InterfaceMirror; |
+ |
+/** |
+An interface declaration is distinct from an interface; the latter describes an actual |
+ type. Many interfaces may correspond to the same interface declaration. |
+For example, List<String> and List<int> both correspond to the same declaration |
+List<T>. |
+ |
+There is no ClassDeclarationMirror, because the only difference would be the superclass clause. |
+*/ |
+interface InterfaceDeclarationMirror extends Mirror { |
+ |
+/** Returns the simple name of this interface */ |
+final String simpleName; |
+ |
+/** Returns the fully qualified name of this interface. |
+//{return '{library.name}{simpleName}';} |
zundel
2012/01/03 19:31:22
{libraryPrefix}.{simpleName}? Surely there is som
|
+ */ |
+String qualifiedName(); |
+ |
+/** Returns a mirror on the declaration of the library in which this type is |
+declared. |
+ */ |
+final LibraryDeclarationMirror library; |
+ |
+/** |
+ Return an immutable map from method names to mirrors on the methods |
+ declared locally within the reflectee. |
+ Inherited ones are a convenience supplied in InterfaceMirror |
+ (though there is a subtlety wrt generics). |
+ We make no distinction between static and instance members here. |
+ Staticness is a property of the mirrors being returned. |
+ Currently no distinction between class and mixin. |
+*/ |
+Map<Object, MethodMirror> methods(); |
+ |
+/** Returns an immutable map from field names to mirrors on any actual fields |
+declared within this interface. Empty unless this is a class. |
+*/ |
+Map<Object, VariableMirror> fields(); |
+ |
+/** |
+Returns an immutable map from names to mirrors on explicitly declared getters that are |
+defined locally by the reflectee. Does not return implicitly defined getters. |
+Reflection shows you what is there, exposing structure hidden at the base level. |
+ */ |
+Map<Object, MethodMirror> getters(); |
+ |
+/** |
+Returns an immutable map from names to mirrors on explicitly declared setters that are |
+defined locally by the reflectee. Does not return implicitly defined setters. |
+ */ |
+Map<Object, MethodMirror> setters(); |
+ |
+/** |
+Returns an immutable map from constructor names to mirrors on the constructors |
+ of the reflectee. |
+This includes generative, redirecting and factory constructors. |
+ */ |
+Map<Object, MethodMirror> constructors(); |
+ |
+ |
+/** Returns an immutable map from interface names to mirrors on the direct |
+superinterfaces of the reflectee. |
+*/ |
+ Map<Object, InterfaceMirror> superinterfaces(); |
+ |
+ /** If the reflectee is a class, return a mirror on the superclass given in the |
+superclass clause. |
+If the reflectee is an interface, return a mirror on class Object. |
+*/ |
+ InterfaceMirror superclass(); |
+ |
+/** Returns an immutable map from the names to the type parameters of the reflectee. |
+If the reflectee is not generic, the map is empty. |
+*/ |
+Map<Object, TypeMirror> typeParameters(); |
+ |
+/** Returns an immutable list of members and constructors. |
+ Includes getters and setters (which is why it cannot be a map) |
+ Does it include implicit ones? |
+*/ |
+List<Mirror> declarations(); |
+ |
+ |
+ |
+} |
+ |
+/** |
+A mirror representing a method (or function?) |
+*/ |
+interface MethodMirror extends Mirror { |
+ |
+/** Return the method name */ |
+ final String simpleName; |
+ |
+/** Return the name of the method, prefixed by the fully qualified name of its |
+immediately enclosing class, interface or library */ |
+ String qualifiedName(); //{return declaringClass.fullyQualifiedName + "." + simpleName;} |
+ |
+/** Return the source code for the reflectee. If unavailable, throw? Or return |
+empty string? |
+*/ |
+ String source(); //{return vmMirror.sourceFor(declaringClass.reflectee, simpleName);} |
hausner
2011/12/21 21:53:19
What's the rationale to have access to the source
gbracha
2011/12/22 18:29:59
IDEs
|
+ |
+ bool isStatic(); |
+ bool isMethod(); |
+ bool isGetter(); |
+ bool isSetter(); |
+ bool isToplevel(); |
+ bool isConstructor(); |
+ |
+ /** only true if a const constructor */ |
+ bool isConst(); |
+ /** only true if redirecting constructor */ |
+ bool isRedirecting(); |
+ /** only true if generative constructor */ |
+ bool isGenerative(); |
+ /** only true if a factory constructor */ |
+ bool isFactory(); |
zundel
2012/01/03 19:31:22
This may be evident from the naming convention, bu
|
+ |
+/** Return a mirror on the declaration immediately surrounding the reflectee. |
+This could be a class, interface, library or another method or function */ |
+*/ |
+ Mirror surroundingDeclaration(); |
+ |
+} |
+ |
+ |
+ |
+/** ObjectMirrors provide reflective access to live objects, and through them, to their classes. |
+ |
+If we supported an async construct in the language, I'd make the methods of this class |
+all be async methods. |
+As it stands, they are synchronous wrappers around asynchronous message sends. |
+ |
+Should this type be removed from introspection and placed in a separate library? |
+Its presence makes it impossible to |
+tree shake code. |
+*/ |
+interface ObjectMirror extends Mirror { |
+/** |
+Get a mirror on the actual class of the reflectee of this mirror. |
+At this point, there is no setClass, but ideally there should be one. |
+*/ |
+ InterfaceMirror getClass(); |
ahe
2012/01/02 16:21:14
This should return a TypeMirror.
|
+ |
+ |
+ /** Invoke the named method/getter/setter, or get the value of a local variable with |
+the supplied arguments. Returns a mirror on the result. |
+The arguments must be object mirrors or values, because we do not support serialization |
+of objects across isolates. I'm not sure how workable that is. |
+We distinguish getetr and setter calls based on the number of arguments (0/1). |
zundel
2012/01/03 19:31:22
getetr -> getter
|
+ */ |
+ ObjectMirror invoke(String memberName, List<Object> positionalArguments, Map<String, Object> namedArguments); |
+ |
+ /** Extract the closure for the function namde as an argument. |
+The optional argument allows us to distingusih between getters and setters. It defaults |
+to false, so that a getter will be returned unless it is set to true. |
+Otherwise, it is ignored. |
+ */ |
+ObjectMirror getProperty(String memberName, [bool setter]); |
+ |
+/** Set the value of a field, bypassing setters. Lets us (re)set final fields |
+reflectively. The argument must be either a value or an ObjectMirror. |
+ */ |
+ void setField(String fieldName, Object value); |
+} |
+ |
+ |
+/** Fields look to be the same as variables, except that the surrounding declaration |
+can be a library, so we can dispense with FieldMirror |
+*/ |
+interface VariableDeclarationMirror extends Mirror { |
+ |
+/** Return the variable name */ |
+ final String simpleName; |
+ |
+/** Return the name of the variable, prefixed by the fully qualified name of its |
+immediately enclosing class or library */ |
+ String qualifiedName();//{return surroundingDeclaration.fullyQualifiedName + "." + simpleName;} |
+ |
+/** Return the source code for the variable declaration. |
+The source would include modifiers, type and initializer */ |
+ String source(); //{return vmMirror.sourceFor(surroundingDeclaration.reflectee, simpleName);} |
+ |
+/** True for static variables */ |
+ bool isStatic; |
+ bool isFinal; |
+ |
+// add isLocal? isParameter? |
+ |
+/** Return a mirror on the declaration immediately surrounding the reflectee. |
+This could be a class, interface, library or another method or function */ |
+*/ |
+ Mirror surroundingDeclaration; |
+ |
+} |
+ |
+/** |
+ A closure mirror reflects a closure. Closures are special, because we do not wish |
+to reflect the internals of a particular closure implementation. And yet, we need |
+access to details of the closure internals - for example, its enclosing context and |
+its source code. |
+ */ |
+interface ClosureMirror { |
+ |
+/** Return the source code for the closure, if available. |
+*/ |
+ String source(); |
+ |
+/** Call the closure. The arguments given in the descriptor need to be ObjectMirrors |
+or values. |
+ */ |
+ ObjectMirror apply(ArgumentDescriptor arguments); |
+ |
+/** Look up the value of name in the scope of the closure. |
+The result is a mirror on that value. |
+*/ |
+ ObjectMirror findInContext(String name); |
+ |
+// As it stands, I cannot get at the activation it came from. |
+} |