public static Type GenerateClass(string className,
Type superClass,
ISeq interfaces, // of Types
ISeq ctors,
ISeq ctorTypes,
ISeq methods,
IPersistentMap exposesFields,
IPersistentMap exposesMethods,
string prefix,
bool hasMain,
string factoryName,
string stateName,
string initName,
string postInitName,
string implCname,
string implNamespace,
bool loadImplNamespace)
{
className = className.Replace('-', '_');
string path = (string)Compiler.CompilePathVar.deref();
if ( path == null)
throw new InvalidOperationException("*compile-path* not set");
string extension = hasMain ? ".exe" : ".dll";
GenContext context = GenContext.CreateWithExternalAssembly(Compiler.munge(path=="." ? className : path + "/" + className), extension, true);
// define the class
List<Type> interfaceTypes = new List<Type>();
for (ISeq s = interfaces; s != null; s = s.next())
interfaceTypes.Add((Type)s.first());
TypeBuilder proxyTB = context.ModuleBuilder.DefineType(
className,
TypeAttributes.Class | TypeAttributes.Public,
superClass,
interfaceTypes.ToArray());
List<MethodSignature> sigs = GetAllSignatures(superClass,interfaceTypes,methods);
Dictionary<string,List<MethodSignature>> overloads = ComputeOverloads(sigs);
HashSet<string> varNames = ComputeOverloadNames(overloads);
foreach ( MethodSignature sig in sigs )
varNames.Add(sig.Name);
if (!String.IsNullOrEmpty(initName)) varNames.Add(initName);
if (!String.IsNullOrEmpty(postInitName)) varNames.Add(postInitName);
if (hasMain) varNames.Add(_mainName);
Dictionary<string, FieldBuilder> varMap = DefineStaticFields(proxyTB, varNames);
FieldBuilder stateFB = String.IsNullOrEmpty(stateName) ? null : DefineStateField(proxyTB, stateName);
DefineStaticCtor(proxyTB,prefix,varMap,loadImplNamespace,implNamespace,implCname);
FieldBuilder initFB = null;
FieldBuilder postInitFB = null;
FieldBuilder mainFB = null;
varMap.TryGetValue(initName, out initFB);
varMap.TryGetValue(postInitName, out postInitFB);
varMap.TryGetValue(_mainName, out mainFB);
DefineCtors(proxyTB, superClass,
implNamespace + "." + prefix + initName,
implNamespace + "." + prefix + postInitName,
ctorTypes, initFB, postInitFB, stateFB, factoryName);
EmitMethods(proxyTB, sigs, overloads, varMap, exposesMethods);
EmitExposers(proxyTB, superClass, exposesFields);
if (hasMain)
EmitMain(context, proxyTB, implNamespace + "." + prefix + _mainName, mainFB);
Type t = proxyTB.CreateType();
context.SaveAssembly();
return t;
}