public ClassFactory(Hashtable classFiles, string[] references) { this.classFiles = classFiles; this.references = references; classes = new Hashtable(); // Populate basic types Class.AccessFlag flag = Class.AccessFlag.ACC_PUBLIC; classes["byte"] = new Class("B", "byte", flag); classes["char"] = new Class("C", "char", flag); classes["double"] = new Class("D", "double", flag); classes["float"] = new Class("F", "float", flag); classes["int"] = new Class("I", "int", flag); classes["long"] = new Class("J", "long", flag); classes["short"] = new Class("S", "short", flag); classes["bool"] = new Class("Z", "bool", flag); classes["void"] = new Class("V", "void", flag); }
public Class LoadClass(string name) { if (name == null) { return null; } if (classes.Contains(name)) { return (Class) classes[name]; } Class c = new Class(); c.InternalName = name; classes[name] = c; ClassFile cf = (ClassFile) classFiles[name]; if (cf != null) { // If a type is not resolved (e.g. a class // a missing, or in another jar), we will get // a null class file at this stage. // We will just continue building the tree // during the emit phase, we will find whether // the type is available in one of the user // provided assemblies. cf.BuildClass(c, this); } return c; }
public void AddType(Class c) { //if (c.FullyQualifiedName.CompareTo("internal")>0){ // return; //} /* * we only add public namespace types, inner types get * automatically generated by recursion */ if (c.DeclaringClass != null) { Console.WriteLine("INFO: skipped inner {0}", c.FullyQualifiedName); return; } if (!c.IsPublic) { Console.WriteLine("INFO: skipped non-public {0}", c.FullyQualifiedName); return; } TypeBuilder tBuilder = (TypeBuilder) tpBldCache[c.FullyQualifiedName]; if (tBuilder != null) { throw new ApplicationException("Duplicate type :" + tBuilder.FullName); } /* * FIXME!! * We force all inner types to be public * because we are not parsing the * InnerAttribute in ClassFile. * If we were doing it, we could specifiy the * visibility of the Nested class (Family, * Assembly, Public), and skip Private. * */ TypeAttributes attrs = c.TypeAttributes; if (c.DeclaringClass != null && !c.IsPublic) { attrs |= TypeAttributes.Public; } tBuilder = emitter.BeginType(c.FullyQualifiedName, attrs); tpBldCache[tBuilder.FullName] = tBuilder; Console.WriteLine("DEBUG: Defined type {0}", tBuilder.FullName); // nested types foreach (Class innerClass in c.InnerTypes) { /* * do not generate anonymous types, e.g. x/y/z/A$1 */ if (Char.IsDigit(innerClass.Name[0])) { continue; } /* * FIXME!! * We force all inner types to be public * because we are not parsing the * InnerAttribute in ClassFile. * If we were doing it, we could specifiy the * visibility of the Nested class (Family, * Assembly, Public), and skip Private. * */ attrs = TypeAttributes.NestedPublic | innerClass.TypeAttributes; // as a nested type we don't need the namespace // and parent type, instead of FullName we // simply use the name TypeBuilder nested = tBuilder.DefineNestedType( innerClass.Name, attrs); tpBldCache[nested.FullName] = nested; Console.WriteLine("DEBUG: Defined inner type {0}", nested.FullName); } }
Type GetType(Class c) { object r = typeCache[c.FullyQualifiedName]; if (r != null) { return (Type) r; } return (Type) tpBldCache[c.FullyQualifiedName]; }
void Generate(ref TypeBuilder tBuilder, Class c) { // parent and interfaces foreach (Class baseType in c.BaseTypes) { Type t = GetType(baseType); if (t == null) { // parent, or interface is not // public namespace, or inner Console.WriteLine("WARNING: skipped base type {0} for {1}", baseType, tBuilder.FullName); continue; } if (baseType.IsInterface) { tBuilder.AddInterfaceImplementation(t); } else { tBuilder.SetParent(t); } } }
public void Generate(Class c) { TypeBuilder tBuilder = (TypeBuilder) GetType(c); if (tBuilder == null) { // parent, or interface is not // public namespace, or inner return; } // Parent and implemented interfaces Generate(ref tBuilder, c); // fields foreach (Field f in c.Fields) { Generate(ref tBuilder, f); } // constructors and methods foreach (Method m in c.Methods) { Generate(ref tBuilder, m); } }
public void BuildClass(Class c, ClassFactory factory) { // accessFlags c.AccessFlags = (Class.AccessFlag) accessFlags; // thisClass c.InternalName = GetClassName(thisClass); // superClass c.AddBaseType(factory.LoadClass(GetClassName(superClass))); // interfaces foreach (ushort iface in interfaces) { c.AddBaseType(factory.LoadClass(GetClassName(iface))); } // fields foreach (FieldInfo info in fields) { Field f = new Field(c); f.AccessFlags = (Field.AccessFlag) info.AccessFlags; f.Name = GetUtf8(info.NameIndex); f.Signature = GetUtf8(info.DescriptorIndex); f.Descriptor = ProcessDescriptor(f.Signature, factory); c.AddField(f); } // methods foreach (MethodInfo info in methods) { Method m = new Method(c); m.AccessFlags = (Method.AccessFlag) info.AccessFlags; m.Name = GetUtf8(info.NameIndex); m.Signature = GetUtf8(info.DescriptorIndex); ProcessMethodDescriptorString(m, m.Signature, factory); c.AddMethod(m); } }
public Method(Class parent) { this.parent = parent; arguments = new ArrayList(); }
public void AddInnerClass(Class c) { if (innerClasses.Contains(c)) { // this can happen while processing things like: // javax/swing/text/html/HTMLDocument$HTMLReader$TitleAction return; } innerClasses.Add(c); c.DeclaringClass = this; }
public void AddBaseType(Class typeName) { if (typeName == null) { return; } if (baseTypes.Contains(typeName)) { throw new ApplicationException("Duplicate BaseType: " + typeName); } baseTypes.Add(typeName); }