-
Notifications
You must be signed in to change notification settings - Fork 35
Reflection
Jing Lu edited this page Jun 29, 2013
·
8 revisions
ReoScript provides the ability to get functions and variables information after script is pre-interpreted.
To use this feature you can use the following namespaces:
- Unvell.ReoScript
- Unvell.ReoScript.Reflection
Assuming that we have the following script:
string script = @"
function normal() {
return 'normal function';
}
function outer(p1, p2, p3, p4) {
function inner(key, value) {
var local = 10;
function inner2(param) {
}
}
return function(a, b) { return a + b; } ();
}
var af = function(x, y) { return x * y; };
var result = af(2, 5);
";
Using srm.Compile(script)
to parse this script, it returns a CompiledScript instance.
ScriptRunningMachine srm = new ScriptRunningMachine();
CompiledScript cs = srm.Compile(script);
According to ECMAScript/JavaScript, ReoScript can also handle the nested function, the script construction information returned in a tree-style:
CompiledScript
+- Functions 1
+- Functions 1.1
+- Functions 1.1.1
+- Variables
+- ...
+- Variables
+- Functions 1.2
+- Functions 1.2.1
+- Variables
+- ...
+- Variables
+- ...
Now we enumerate over this construction and output the information in console.
Console.WriteLine("Functions: ");
Console.WriteLine();
foreach (FunctionInfo fi in cs.DeclaredFunctions)
{
IterateFunction(fi, 0);
}
Console.WriteLine("Global Variables: ");
Console.WriteLine();
foreach (VariableInfo vi in cs.DeclaredVariables)
{
PrintOutLine("Variable Name", vi.Name, 0);
PrintOutLine(" Has Initial Value", vi.HasInitialValue.ToString(), 0);
PrintOutLine(" Position", vi.Line + ":" + vi.CharIndex, 0);
Console.WriteLine();
}
private static void IterateFunction(FunctionInfo fi, int indents)
{
PrintOutLine("Function Name", fi.Name, indents);
PrintOutLine(" Is Anonymous", fi.IsAnonymous.ToString(), indents);
PrintOutLine(" Is Nested", fi.IsInner.ToString(), indents);
PrintOutLine(" Position", fi.Line + ":" + fi.CharIndex, indents);
PrintOutLine(" Arguments", string.Join(", ", fi.Args), indents);
PrintOutLine(" Local Variables ", string.Join(", ",
fi.DeclaredLocalVariables.Select(vi => vi.Name).ToArray()), indents);
Console.WriteLine();
indents += 4;
foreach (FunctionInfo innerFun in fi.DeclaredInnerFunctions)
{
IterateFunction(innerFun, indents);
}
indents -= 4;
}
private static void PrintOutLine(string key, string value, int indents)
{
Console.WriteLine(string.Format("{0,-" + indents + "} {1,-20}: {2}", " ", key, value));
}
The construction will be printed out like below:
Functions:
Function Name : normal
Is Anonymous : False
Is Nested : False
Position : 3:4
Arguments :
Local Variables :
Function Name : outer
Is Anonymous : False
Is Nested : False
Position : 7:4
Arguments : p1, p2, p3, p4
Local Variables :
Function Name : inner
Is Anonymous : False
Is Nested : True
Position : 9:5
Arguments : key, value
Local Variables : local
Function Name : inner2
Is Anonymous : False
Is Nested : True
Position : 12:6
Arguments : param
Local Variables :
Function Name : <anonymous>
Is Anonymous : True
Is Nested : False
Position : 16:12
Arguments : a, b
Local Variables :
Function Name : <anonymous>
Is Anonymous : True
Is Nested : False
Position : 19:13
Arguments : x, y
Local Variables :
Global Variables:
Variable Name : af
Has Initial Value : True
Position : 19:8
Variable Name : result
Has Initial Value : True
Position : 21:8