#! /usr/bin/env fan
//
// Copyright (c) 2008, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 26 Mar 08 Brian Frank Creation
// 08 Sep 09 Brian Frank Rework fandoc -> example
//
**
** Working with Pod, Type, Slot, Field, Method, and Symbol
** reflection APIs.
**
class Reflection
{
Void main()
{
pods
types
slots
methods
fields
}
Void pods()
{
echo("\n--- pods ---")
p := Pod.find("compiler")
show(Pod.list, "list the pods installed")
show(Pod.find("compiler"), "find a pod (throws err if not found)")
show(Pod.find("bad", false), "find a pod (returns null if not found)")
show(p.name, "pod name")
show(p.version, "pod version")
show(p.meta, "all pod meta name/value metadata pairs")
show(p.meta["build.time"], "lookup a pod metadata key")
show(p.file(`/img/icon.png`, false), "lookup a resource file in myPod")
}
Void types()
{
echo("\n--- types ---")
pod := Pod.find("graphics")
t := pod.type("Point")
show("foo".typeof, "get the type of the an object")
show(pod.types, "list the types in myPod")
show(pod.type("Point"), "find a type in pod by simple name")
show(pod.type("Foo", false), "returns null if type not found")
show(Type.find("graphics::Point"), "lookup a type by its qualified name")
show(Type.find("graphics::Foo", false), "returns null if type not found")
show(Int#, "type literal for sys::Int")
show(Int?[]#, "type literal for sys::Int?[]")
show(t.fits(Num#), "reflective is/instanceof operator")
show(t.pod, "get the pod of a type")
show(t.qname, "qualified name of type")
show(t.name, "simple unqualified name of type")
show(t.base, "type's base class")
show(t.mixins, "type's mixins or empty list")
show(t.inheritance, "all the types inherited")
show(t.signature, "formal type signature")
show(t.make, "make an obj of type t")
show(t.facets, "list of all declared facets")
show(t.facet(Serializable#, false), "lookup facet")
show(t.hasFacet(Serializable#), "check if facet defined")
}
Void slots()
{
echo("\n--- slots ---")
t := Type.find("web::WebClient")
s := t.slot("cookies")
show(t.slot("cookies"), "lookup the slot called xyz on someType")
show(t.slots, "list all the slots on someType")
show(Slot.find("web::WebClient.cookies"), "looukp a slot by its qualified name")
show(Slot.find("web::WebClient..foo", false), "returns null if slot not found")
show(Str#replace, "slot literal")
show(#main, "slot literal (in enclosing class)")
show(s.qname, "qualified name")
show(s.name, "unqualified simple name")
show(s.parent, "declaring type")
show(s.signature, "full signature of field or method")
show(s.facets, "map of all facets")
show(s.facet(Transient#, false), "lookup facet")
show(s.hasFacet(Transient#), "check if facet defined")
}
Void methods()
{
echo("\n--- methods ---")
t := Str#
m := Str#toInt
ms := Str#spaces
show(t.method("split"), "lookup the method called xyz on someType")
show(t.method("foo", false), "returns null if method not found")
show(t.methods, "list all the methods on someType")
show(Slot.findMethod("sys::Str.split"), "looukp a method by its qualified name")
show(Slot.findMethod("sys::Str.foo", false), "returns null if method not found")
show(m.returns, "return type of method")
show(m.params, "list of parameters")
show(ms.callList([3])->toCode, "invoke static method using reflection")
show(ms.call(3)->toCode, "same as above")
show(m.callOn("100", [16]), "invoke instance method using reflection")
show(m.call("100", 16), "same as above")
show(m.func, "the function which implements the method")
}
Void fields()
{
echo("\n--- fields ---")
t := Type.find("web::WebClient")
obj := t.make
f := t.field("followRedirects")
show(t.field("cookies"), "lookup the field called xyz on someType")
show(t.field("x", false), "returns null if field not found")
show(t.fields, "list all the fields on someType")
show(Slot.findField("web::WebClient.cookies"), "looukp a field by its qualified name")
show(Slot.findField("web::WebClient.foo", false), "returns null if field not found")
show(f.type, "type of field")
f.set(obj, true) // set instance field
show(f.get(obj), "get instance field")
show(Float#pi.get, "get static field")
}
Void show(Obj? result, Str what)
{
resultStr := "" + result
if (resultStr.size > 40) resultStr = resultStr[0..40] + "..."
echo(what.padr(40) + " => " + resultStr)
}
}