1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.Rook
.Compiler
.Services
.Passes
18 using System
.Reflection
;
19 using System
.Reflection
.Emit
;
20 using System
.Threading
;
22 using Castle
.Rook
.Compiler
.AST
;
23 using Castle
.Rook
.Compiler
.TypeSystem
;
26 public class CreateBuilderSkeleton
: ICompilerPass
28 private readonly ITypeContainer typeContainer
;
29 private readonly INameResolver resolver
;
30 private readonly IErrorReport errorReport
;
32 public CreateBuilderSkeleton(ITypeContainer typeContainer
,
33 INameResolver resolver
, IErrorReport errorReport
)
35 this.typeContainer
= typeContainer
;
36 this.resolver
= resolver
;
37 this.errorReport
= errorReport
;
40 public void ExecutePass(CompilationUnit unit
)
42 DeclareAndPopulateGlobalSourceUnit(unit
);
44 TypeBuilderSkeletonStep builderVisitor
= CreateAssemblyStructure(unit
);
46 builderVisitor
.VisitNode( unit
);
49 private TypeBuilderSkeletonStep
CreateAssemblyStructure(CompilationUnit unit
)
51 AssemblyName assemblyName
= new AssemblyName();
53 assemblyName
.Name
= "RookGenAssembly";
55 AssemblyBuilder assembly
= Thread
.GetDomain().DefineDynamicAssembly(
56 assemblyName
, AssemblyBuilderAccess
.Save
);
58 ModuleBuilder module
= assembly
.DefineDynamicModule(
59 "RookModule", "RookModule.mod", true);
61 unit
.AssemblyBuilder
= assembly
;
63 unit
.ModuleBuilder
= module
;
65 return new TypeBuilderSkeletonStep( module
, typeContainer
, resolver
, errorReport
);
68 private void DeclareAndPopulateGlobalSourceUnit(CompilationUnit unit
)
70 SourceUnit globalUnit
= new SourceUnit(unit
, "<global>");
72 TypeDefinitionStatement globalType
= new TypeDefinitionStatement( AccessLevel
.Public
, "RookGlobal" );
74 globalUnit
.Statements
.Add( globalType
);
76 MethodDefinitionStatement entryPoint
= new MethodDefinitionStatement( AccessLevel
.Public
);
77 entryPoint
.Name
= "self.main";
79 foreach(SourceUnit sunit
in unit
.SourceUnits
)
81 foreach(IStatement stmt
in sunit
.Statements
)
83 if (stmt
.StatementType
== StatementType
.TypeDefinition
) continue;
85 stmt
.Parent
.RemoveChild( stmt
);
87 if (stmt
.StatementType
== StatementType
.MethodDef
)
89 (stmt
as MethodDefinitionStatement
).IsStatic
= true;
91 if (stmt
.StatementType
== StatementType
.MultipleVarDeclaration
)
93 // TODO: Ensure no instance vars defined
96 if (stmt
.StatementType
== StatementType
.ExpressionStmt
||
97 stmt
.StatementType
== StatementType
.MultipleVarDeclaration
)
99 entryPoint
.Statements
.Add( stmt
);
103 globalType
.Statements
.Add( stmt
);
108 if (entryPoint
.Statements
.Count
!= 0)
110 globalType
.Statements
.Add( entryPoint
);
112 // Might be necessary
113 // unit.EntryPointMethod = entryPoint;
116 unit
.SourceUnits
.Add(globalUnit
);