public void AddClassToDeclaringType(TypeDefinition cilType, JavaClass jclass) { if (jclass.IsInnerClass()) { var outerName = jclass.OuterAndInnerClasses[0].OuterLongName; if (typeMap.TryGetValue(outerName, out var cilOuterTypeRef) && cilOuterTypeRef is TypeDefinition cilOuterType) { foreach (var nestedType in cilOuterType.NestedTypes) { if (nestedType.Name == cilType.Name) { Console.WriteLine($"skipping duplicate class '{nestedType.FullName}'"); return; } } cilOuterType.NestedTypes.Add(cilType); } else { throw new JavaException( $"outer class '{outerName}' not found for inner class", Where); } } else { module.Types.Add(cilType); } }
public bool CreateCilTypeForClass(JavaClass jclass) { var name = jclass.Name; if (typeMap.TryGetValue(name, out _) || jclass.IsInnerClass() && (name.StartsWith("java.lang.Object$") || name.StartsWith("java.lang.String$"))) { Console.WriteLine($"skipping duplicate class '{name}'"); return(false); } string nsName, clsName; TypeAttributes attrs = 0; if (jclass.IsInnerClass()) { nsName = string.Empty; clsName = jclass.OuterAndInnerClasses[0].InnerShortName; if (!string.IsNullOrEmpty(clsName)) { int idx = name.LastIndexOf('$'); if (idx != -1 && idx + 1 < name.Length) { clsName = name.Substring(idx + 1); } } if (string.IsNullOrEmpty(clsName) || (!Char.IsLetter(clsName[0]))) { clsName = "autogenerated_" + jclass.GetHashCode().ToString("X8"); } if ((jclass.Flags & JavaAccessFlags.ACC_PUBLIC) != 0) { attrs = TypeAttributes.NestedPublic; } else if ((jclass.Flags & JavaAccessFlags.ACC_PRIVATE) != 0) { attrs = TypeAttributes.NestedPrivate; } else if ((jclass.Flags & JavaAccessFlags.ACC_PROTECTED) != 0) { attrs = TypeAttributes.NestedFamORAssem; } else { attrs = TypeAttributes.NestedAssembly; } } else { int n = jclass.PackageNameLength; nsName = name.Substring(0, n); if (name[n] == '.') { n++; } clsName = name.Substring(n); if ((jclass.Flags & JavaAccessFlags.ACC_PUBLIC) != 0) { attrs |= TypeAttributes.Public; } } if ((jclass.Flags & JavaAccessFlags.ACC_ABSTRACT) != 0) { attrs |= TypeAttributes.Abstract; } if ((jclass.Flags & JavaAccessFlags.ACC_INTERFACE) != 0) { attrs |= TypeAttributes.Interface; } if ((jclass.Flags & JavaAccessFlags.ACC_FINAL) != 0) { attrs |= TypeAttributes.Sealed; } var newType = new TypeDefinition(nsName, clsName, attrs); newType.CustomAttributes.Add(new CustomAttribute(retainNameAttributeConstructor)); typeMap[name] = newType; return(true); }
public void LinkCilTypesByClass(TypeDefinition cilType, JavaClass jclass) { if (jclass.IsInnerClass()) { var outerName = jclass.OuterAndInnerClasses[0].OuterLongName; if (typeMap.TryGetValue(outerName, out var cilOuterTypeRef) && cilOuterTypeRef is TypeDefinition cilOuterType) { foreach (var nestedType in cilOuterType.NestedTypes) { if (nestedType.Name == cilType.Name) { Console.WriteLine($"skipping duplicate class '{nestedType.FullName}'"); return; } } cilOuterType.NestedTypes.Add(cilType); } else { throw new JavaException( $"outer class '{outerName}' not found for inner class", Where); } } else { module.Types.Add(cilType); } var superName = jclass.Super; if (superName == "java.lang.Enum") { superName = null; } if (superName != null) { if (typeMap.TryGetValue(superName, out var cilSuperTypeRef)) { if (cilType.IsInterface) { if (superName != "java.lang.Object") { cilType.Interfaces.Add( new InterfaceImplementation(cilSuperTypeRef)); } } else { if (jclass.Name == "java.lang.Throwable" && superName == "java.lang.Object") { cilSuperTypeRef = systemException; } cilType.BaseType = cilSuperTypeRef; } CilTypeAddUse(cilSuperTypeRef); } else { throw new JavaException($"super class '{superName}' not found", Where); } } if (jclass.Interfaces != null) { foreach (var interfaceName in jclass.Interfaces) { if (typeMap.TryGetValue(interfaceName, out var cilInterfaceTypeRef)) { if (cilInterfaceTypeRef.Resolve()?.IsInterface == true) { cilType.Interfaces.Add( new InterfaceImplementation(cilInterfaceTypeRef)); CilTypeAddUse(cilInterfaceTypeRef); } } else { throw new JavaException($"interface '{interfaceName}' not found", Where); } } } }