Fixing an issue with output parameters that are of type IntPtr
[castle.git] / Experiments / Generator / src / app / GeneratorFactory.boo
blobe0aafc91b924f6c69dc00159f3665fec00d4174f
1 namespace Generator
3 import System
4 import System.IO
5 import System.Text
6 import System.Reflection
7 import Boo.Lang.Compiler
8 import Boo.Lang.Compiler.IO
9 import Boo.Lang.Compiler.Pipelines
10 import Boo.Lang.Useful.Attributes
11 import Generator.Extentions
13 [Singleton]
14 class GeneratorFactory:
15 [Property(ScriptBasePath)]
16 _scriptBasePath as string
18 def constructor():
19 asmpath = Path.GetDirectoryName(typeof(GeneratorBase).Assembly.Location)
20 _scriptBasePath = Path.Combine(asmpath, "../Generators/".ToPath())
22 def CreateAndRun(argv as (string)) as int:
23 if argv.Length == 0:
24 ListGenerators()
25 return -1
27 name = argv[0].ToClassName()
28 args = argv[1:]
30 try:
31 generator = GetGenerator(name)
32 except ex as Exception:
33 print ex.Message
34 return -1
36 if argv.Length == 1:
37 generator.PrintUsage()
38 return -1
39 try:
40 generator.Init(args)
41 generator.Run()
42 except ex as Exception:
43 print 'An error occured while running the generator:'
44 print ex.Message
45 return -1
46 return 0
48 # Creates a new generator by its name
49 def GetGenerator(name as string) as GeneratorBase:
50 script = GetGeneratorScriptFile(name)
52 raise GeneratorException("Generator ${name} not found") if not File.Exists(script)
54 return Compile(script)
56 # Returns all generators
57 def GetGenerators() as (GeneratorBase):
58 generators = []
59 for d in Directory.GetDirectories(ScriptBasePath):
60 name = DirectoryInfo(d).Name
61 try:
62 generators.Add(GetGenerator(name))
63 except Exception:
64 pass
65 return generators.ToArray(GeneratorBase)
67 private def ListGenerators():
68 print 'usage: generate GeneratorName [Arguments...]'
69 print
70 print 'Available generators:'
71 for gen in GetGenerators():
72 print gen.GeneratorName.PadLeft(10), ':', gen.Help()
74 private def GetGeneratorScriptFile(name as string):
75 return Path.Combine(ScriptBasePath, "${name}/${name}Generator.boo")
77 private def Compile(script as string) as GeneratorBase:
78 code = StringBuilder()
80 # Adds default imports
81 code.Append('import Generator;')
82 code.Append('import Generator.Extentions;')
83 code.Append('import Config;')
85 using reader = StreamReader(script):
86 code.Append(reader.ReadToEnd())
88 compiler = BooCompiler()
89 compiler.Parameters.Input.Add(FileInput("${ScriptBasePath}/Config.boo"))
90 compiler.Parameters.Input.Add(StringInput(script, code.ToString()))
91 compiler.Parameters.References.Add(typeof(GeneratorBase).Assembly)
92 compiler.Parameters.Pipeline = CompileToMemory()
94 ctx = compiler.Run()
96 if len(ctx.Errors) > 1:
97 print "Compilation errors!"
98 for e in ctx.Errors:
99 print e unless e.Code == "BCE0028" #No entry point
101 if ctx.GeneratedAssembly is null:
102 raise GeneratorException("Can't compile generator")
104 genType = ctx.GeneratedAssembly.GetTypes()[1]
105 generator as GeneratorBase = genType()
107 return generator