Chromium Code Reviews| 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. |
| +} |