/// <summary> /// Called in the finalize phase of the type builder. /// </summary> public void Finalize(TargetFramework target, MethodRenamer methodRenamer) { FixOverridenProperties(methodRenamer, target); RemoveDuplicateProperties(); RemoveClashingProperties(); FixPropertyFinalState(); }
public override void ModifyMethodName(NetMethodDefinition method, MethodRenamer renamer) { if(method.Name == "GetTitle") renamer.Rename(method, "JavaGetTitle"); else base.ModifyMethodName(method, renamer); }
/// <summary> /// Gets the name of the given method /// </summary> public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); switch (method.Name) { case "Format": renamer.RenameMethodOnly(method, "JavaFormat"); method.EditorBrowsableState = EditorBrowsableState.Advanced; break; case "Substring": renamer.Rename(method, "JavaSubstring"); method.EditorBrowsableState = EditorBrowsableState.Advanced; break; case "ToLowerCase": renamer.Rename(method, "ToLower"); break; case "Length": method.SetExplicitImplementation(method.Overrides.First(),method.Overrides.First().DeclaringType); break; case "CharAt": method.SetExplicitImplementation(method.Overrides.First(), method.Overrides.First().DeclaringType); break; case "ToUpperCase": renamer.Rename(method, "ToUpper"); break; } }
/// <summary> /// Modify the name of the given method to another name. /// By calling renamer.Rename, all methods in the same group are also updated. /// </summary> public override void ModifyMethodName(NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); if (method.OriginalJavaName == "getMessage") { method.EditorBrowsableState = EditorBrowsableState.Never; } }
/// <summary> /// Gets the name of the given method /// </summary> public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); if (method.Name == "ParseLong") { renamer.Rename(method, "Parse"); } }
/// <summary> /// Implement interface members /// </summary> public void FinalizeProperties(TargetFramework target, MethodRenamer methodRenamer) { if (propertyBuilder != null) { propertyBuilder.Finalize(target, methodRenamer); } nestedTypeBuilders.ForEach(n => n.FinalizeProperties(target, methodRenamer)); }
public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); if (method.Name == "CurrentThread") { renamer.Rename(method, "GetCurrentThread"); } }
public override void ModifyMethodName(NetMethodDefinition method, MethodRenamer renamer) { if (method.OriginalJavaName == "getLayoutParams") renamer.Rename(method, "GetLayoutParameters"); else if (method.OriginalJavaName == "setLayoutParams") renamer.Rename(method, "SetLayoutParameters"); else base.ModifyMethodName(method, renamer); }
/// <summary> /// Gets the name of the given method /// </summary> public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); if ((method.Name == "Next") && (method.Parameters.Count == 1)) { renamer.Rename(method, "JavaNext"); method.EditorBrowsableState = EditorBrowsableState.Never; } }
/// <summary> /// Gets the name of the given method /// </summary> public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); if (method.Name == "IsLowerCase") renamer.Rename(method, "IsLower"); if (method.Name == "IsUpperCase") renamer.Rename(method, "IsUpper"); }
/// <summary> /// Implement and finalize types /// </summary> public static void Implement(List <TypeBuilder> typeBuilders, TargetFramework target) { typeBuilders.ForEach(x => x.Implement(target)); typeBuilders.ForEach(x => x.Finalize(target, FinalizeStates.AddRemoveMembers)); typeBuilders.ForEach(x => x.Finalize(target, FinalizeStates.FixTypes)); var methodRenamer = new MethodRenamer(target); typeBuilders.ForEach(x => x.FinalizeNames(target, methodRenamer)); typeBuilders.ForEach(x => x.FinalizeProperties(target)); typeBuilders.ForEach(x => x.FinalizeVisibility(target)); }
public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); switch (method.Name) { case "Wait": renamer.Rename(method, "JavaWait"); break; case "GetClass": renamer.Rename(method, "GetType"); break; } }
/// <summary> /// Gets the name of the given method /// </summary> public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); switch (method.Name) { case "ParseDouble": renamer.Rename(method, "Parse"); break; case "IsInfinite": if(method.IsStatic) renamer.Rename(method, "IsInfinity"); break; } }
/// <summary> /// Update names where needed /// </summary> public override void FinalizeNames(TargetFramework target, MethodRenamer methodRenamer) { // Make sure there is no name class with other members var prefix = "Java"; var postfix = 0; while ((typeDef.DeclaringType != null) && (typeDef.DeclaringType.Methods.Any(x => x.Name == typeDef.Name))) { typeDef.Name = prefix + typeDef.Name; if (postfix > 0) typeDef.Name += postfix; prefix = ""; postfix++; } FinalizeNames(typeDef, target, methodRenamer); }
/// <summary> /// Gets the name of the given method /// </summary> public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); switch (method.Name) { case "Append": if (method.JavaDescriptor == "(Ljava/lang/CharSequence;II)Ljava/lang/StringBuilder;") { renamer.Rename(method, "JavaAppend"); method.EditorBrowsableState = EditorBrowsableState.Advanced; } break; case "Delete": if (method.JavaDescriptor == "(II)Ljava/lang/StringBuilder;") { renamer.Rename(method, "JavaDelete"); method.EditorBrowsableState = EditorBrowsableState.Advanced; } break; case "Insert": if (method.JavaDescriptor == "(ILjava/lang/CharSequence;II)Ljava/lang/StringBuilder;") { renamer.Rename(method, "JavaInsert"); method.EditorBrowsableState = EditorBrowsableState.Advanced; } break; case "Substring": if (method.JavaDescriptor == "(II)Ljava/lang/String;") { renamer.Rename(method, "JavaSubstring"); method.EditorBrowsableState = EditorBrowsableState.Advanced; } break; case "Length": method.SetExplicitImplementation(method.Overrides.First(), method.Overrides.First().DeclaringType); break; case "CharAt": method.SetExplicitImplementation(method.Overrides.First(), method.Overrides.First().DeclaringType); break; case "SetLength": renamer.RenameMethodOnly(method, "JavaSetLength"); method.EditorBrowsableState = EditorBrowsableState.Advanced; break; } }
/// <summary> /// Called in the finalize phase of the type builder. /// </summary> public void FinalizeNames(TargetFramework target, MethodRenamer methodRenamer) { if (method == null) { return; } if (addJavaPrefix && (!method.Name.StartsWith("Java"))) { methodRenamer.Rename(method, "Java" + method.Name); } if (!method.IsConstructor) { declaringTypeBuilder.ModifyMethodName(method, methodRenamer); } // Fix visiblity FixVisibility(); }
/// <summary> /// Update names where needed /// </summary> public override void FinalizeNames(TargetFramework target, MethodRenamer methodRenamer) { // Make sure there is no name class with other members var prefix = "Java"; var postfix = 0; while ((typeDef.DeclaringType != null) && (typeDef.DeclaringType.Methods.Any(x => x.Name == typeDef.Name))) { typeDef.Name = prefix + typeDef.Name; if (postfix > 0) { typeDef.Name += postfix; } prefix = ""; postfix++; } FinalizeNames(typeDef, target, methodRenamer); }
/// <summary> /// Gets the name of the given method /// </summary> public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); switch (method.Name) { case "GetConstructor": renamer.Rename(method, "JavaGetConstructor"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetConstructors": renamer.Rename(method, "JavaGetConstructors"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetField": renamer.Rename(method, "JavaGetField"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetFields": renamer.Rename(method, "JavaGetFields"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetInterfaces": renamer.Rename(method, "JavaGetInterfaces"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetMethod": renamer.Rename(method, "JavaGetMethod"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetMethods": renamer.Rename(method, "JavaGetMethods"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetName": renamer.Rename(method, "JavaGetName"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetComponentType": renamer.Rename(method, "GetElementType"); break; } }
/// <summary> /// Modify the name of the given method to another name. /// By calling renamer.Rename, all methods in the same group are also updated. /// </summary> public virtual void ModifyMethodName(NetMethodDefinition method, MethodRenamer renamer) { var name = method.Name; var newName = name; if (name.IndexOf('$') >= 0) { newName = name.Replace('$', '_'); } var typeDef = method.DeclaringType; if ((typeDef != null) && ((name == typeDef.Name) || typeDef.GenericParameters.Any(x => x.Name == name))) { // Name conflict with generic parameter newName = "Java" + name; } if (newName != name) { renamer.Rename(method, newName); } }
/// <summary> /// Implement and finalize types /// </summary> public static void Implement(List <TypeBuilder> typeBuilders, TargetFramework target) { typeBuilders.ForEach(x => x.Implement(target)); // order by inheritance, since the properties need information from their parents. var otherBuilders = typeBuilders.Where(b => !(b is StandardTypeBuilder)); var standardBuilders = typeBuilders.OfType <StandardTypeBuilder>(); standardBuilders = TopologicalSort.Sort(standardBuilders, b => b.TypeDefinition.GetBaseTypes(true), b => b.TypeDefinition, new NetTypeReferenceEqualityComparer()) .ToList(); typeBuilders = otherBuilders.Concat(standardBuilders).ToList(); // finialize. typeBuilders.ForEach(x => x.Finalize(target, FinalizeStates.AddRemoveMembers)); typeBuilders.ForEach(x => x.Finalize(target, FinalizeStates.FixTypes)); var methodRenamer = new MethodRenamer(target); typeBuilders.ForEach(x => x.FinalizeNames(target, methodRenamer)); typeBuilders.ForEach(x => x.FinalizeProperties(target, methodRenamer)); typeBuilders.ForEach(x => x.FinalizeVisibility(target)); }
/// <summary> /// Gets the name of the given method /// </summary> public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); if (method.Name == "Ceil") { renamer.Rename(method, "Ceiling"); } else if (method.Name == "IEEEremainder") { renamer.Rename(method, "IEEERemainder"); } else if (method.Name == "Abs") { renamer.Rename(method, "JavaAbs"); } else if (method.Name == "Round") { renamer.Rename(method, "JavaRound"); } else if (method.Name == "Pow") { renamer.Rename(method, "JavaPow"); } }
/// <summary> /// Remove all properties that override / implement a property that does not exist. /// /// Will also fix property visibility. /// </summary> private void FixOverridenProperties(MethodRenamer methodRenamer, TargetFramework target) { if (!typeDef.Properties.Any()) { return; } // handle overiding properties var allBaseTypes = typeDef.GetBaseTypes(true); var allBaseProperties = allBaseTypes.SelectMany(x => x.GetElementType().Properties).ToList(); var overridingProperties = typeDef.Properties.Where(x => IsAnyOverride(x) && !DoNotFixOverridenProperty(x)).ToList(); for (int i = 0; i < overridingProperties.Count; ++i) { var prop = overridingProperties[i]; NetPropertyDefinition matchingBaseProp = null; if (prop.Getter != null) { // Note: this logic might need to be also applied for the "lone" setter logic below. foreach (var baseProp in allBaseProperties.Where(p => p.Name == prop.Name)) { var basePropType = GenericParameters.Resolve(baseProp.PropertyType, prop.DeclaringType, target.TypeNameMap); if (!prop.PropertyType.AreSame(basePropType)) { continue; } matchingBaseProp = baseProp; break; } // Check for existing property in base class if (matchingBaseProp == null) { // implement as normal method. RemoveProperty(prop); continue; } // Check for base property with setter if (prop.Setter != null) { if (matchingBaseProp.Setter == null) { // Remove setter prop.Setter.Property = null; prop.Setter = null; continue; } } } else { // this is a "lone" setter. for boolean setters, the name might have changed. // try to match all base properties, update the name if neccessary. foreach (var baseProp in allBaseProperties.Where(g => g.Getter != null && g.Setter != null)) { if (FindSetter(baseProp.Getter, new[] { prop.Setter }, true) != null) { if (baseProp.Setter.IsVirtual) { if (matchingBaseProp == null || prop.Name == baseProp.Name) { matchingBaseProp = baseProp; } } } } if (matchingBaseProp == null) { // remove the property alltogether prop.Setter.Property = null; typeDef.Properties.Remove(prop); continue; } prop.Name = matchingBaseProp.Name; } // We must implement the property, since we inherited it. // Fix up any clashes. // clashes with explicit implementations should not occur. if ((prop.Getter ?? prop.Setter).InterfaceType != null) { continue; } var propName = prop.Name; if (propName == typeDef.Name) { if (!matchingBaseProp.DeclaringType.IsInterface) { Console.Error.WriteLine("Warning: Inherited property {0}::{1} clashes with type name. Skipping generation of property and methods.", typeDef.FullName, propName); typeDef.Properties.Remove(prop); typeDef.Methods.Remove(prop.Getter); typeDef.Methods.Remove(prop.Setter); continue; } // make this an explicit interface implementtion. // TODO: We might also want to keep a renamed property in this case, // too allow access to the property from the class. // Also, the explicit implementation does not need a "JavaImport" attribute. Console.Error.WriteLine("Warning: Inherited property {0}::{1} clashes with type name. Generating explicit implementation.", typeDef.FullName, propName); if (prop.Getter != null) { if (matchingBaseProp.Getter != null) { prop.Getter.SetExplicitImplementation(matchingBaseProp.Getter, matchingBaseProp.DeclaringType); } else { prop.Getter = null; } } if (prop.Setter != null) { if (matchingBaseProp.Setter != null) { prop.Setter.SetExplicitImplementation(matchingBaseProp.Setter, matchingBaseProp.DeclaringType); } else { prop.Setter = null; } } continue; } if (typeDef.NestedTypes.Any(x => x.Name == propName)) { Console.Error.WriteLine("Warning: Inherited property {0}::{1} clashes with nested type. Renaming nested type, but consider renaming the property instead.", typeDef.FullName, propName); typeDef.NestedTypes.Where(x => x.Name == propName).ForEach(t => t.Name += "FixMe"); } foreach (var clash in typeDef.Properties.Where(x => x != prop && x.Name == propName).ToList()) { if (clash.Parameters.Count != prop.Parameters.Count) { continue; } if ((clash.Getter ?? clash.Setter).InterfaceType != null) { continue; } if (prop.PropertyType.AreSame(clash.PropertyType) && prop.MainMethod.CreateReason == "TypeBuilder.AddAbstractInterfaceMethods") { // it appears that the method does have an implementation! typeDef.Properties.Remove(prop); typeDef.Methods.Remove(prop.Getter); typeDef.Methods.Remove(prop.Setter); overridingProperties.RemoveAt(i); i -= 1; goto continue_outer; } if (overridingProperties.Contains(clash)) { // This would have probably been removed later anyways. //Console.Error.WriteLine("Warning: duplicate property names {0}::{1}. Not generating property for one of the clashes.", typeDef.FullName, propName); RemoveProperty(clash); overridingProperties.Remove(clash); // this must come after us. continue; } // else remove other property RemoveProperty(clash); } if (typeDef.Methods.Any(x => x != prop.Setter && x != prop.Getter && x.Name == propName)) { Console.Error.WriteLine("Warning: Inherited property {0}::{1} clashes with methods. Prepending \"Invoke\" prefix to methods.", typeDef.FullName, propName); typeDef.Methods.Where(x => x != prop.Setter && x != prop.Getter && x.Name == propName) .ForEach(m => methodRenamer.Rename(m, "Invoke" + m.Name)); } continue_outer :; } }
/// <summary> /// Called in the finalize phase of the type builder. /// </summary> public void FinalizeNames(TargetFramework target, MethodRenamer methodRenamer) { if (method == null) return; if (addJavaPrefix && (!method.Name.StartsWith("Java"))) { methodRenamer.Rename(method, "Java" + method.Name); } if (!method.IsConstructor) { declaringTypeBuilder.ModifyMethodName(method, methodRenamer); } // Fix visiblity FixVisibility(); }
/// <summary> /// Update names where needed /// </summary> public override void FinalizeNames(TargetFramework target, MethodRenamer methodRenamer) { FinalizeNames(typeDef, target, methodRenamer); }
/// <summary> /// Build properties for the given type /// </summary> internal void BuildProperties(TargetFramework target, MethodRenamer methodRenamer) { var getters = typeDef.Methods.Where(IsGetter).ToList(); var setters = typeDef.Methods.Where(IsSetter).ToList(); foreach (var getMethod in getters) { // Get the name of the property var name = GetPropertyName(getMethod); // other clashes must be handled later. if (getMethod.InterfaceType == null) { typeDef.Fields.Where(x => x.Name == name).ForEach(RenameClashingField); } // Create property var prop = new NetPropertyDefinition { Name = name, Getter = getMethod, Description = getMethod.Description, }; AddCustomAttributes(getMethod, prop.CustomAttributes); // Clone parameters if (getMethod.Parameters.Any()) { prop.Parameters.AddRange(getMethod.Parameters.Select(x => new NetParameterDefinition(x.Name, x.ParameterType, false))); prop.Name = "this"; } getMethod.Property = prop; // Find setter var setMethod = FindSetter(getMethod, setters); if (setMethod != null) { prop.Setter = setMethod; setMethod.Property = prop; setters.Remove(setMethod); } // Add property typeDef.Properties.Add(prop); } // create properties for lone setters that override a base setter foreach (var setMethod in setters.Where(s => s.IsOverride)) { var name = GetPropertyName(setMethod); // other clashes must be handled in FixOverrides if (setMethod.InterfaceType == null) { typeDef.Fields.Where(x => x.Name == name).ForEach(RenameClashingField); } // Create property var prop = new NetPropertyDefinition { Name = name, Setter = setMethod, Description = setMethod.Description }; setMethod.Property = prop; AddCustomAttributes(setMethod, prop.CustomAttributes); // Clone parameters if (setMethod.Parameters.Skip(1).Any()) { prop.Parameters.AddRange(setMethod.Parameters.Skip(1).Select(x => new NetParameterDefinition(x.Name, x.ParameterType, false))); prop.Name = "this"; } typeDef.Properties.Add(prop); } }
/// <summary> /// Gets the name of the given method /// </summary> public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); switch (method.Name) { case "GetConstructor": renamer.Rename(method, "JavaGetConstructor"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetConstructors": renamer.Rename(method, "JavaGetConstructors"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetField": renamer.Rename(method, "JavaGetField"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetFields": renamer.Rename(method, "JavaGetFields"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetInterfaces": renamer.Rename(method, "JavaGetInterfaces"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetMethod": renamer.Rename(method, "JavaGetMethod"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetMethods": renamer.Rename(method, "JavaGetMethods"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetDeclaredConstructor": renamer.Rename(method, "JavaGetDeclaredConstructor"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetDeclaredConstructors": renamer.Rename(method, "JavaGetDeclaredConstructors"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetDeclaredField": renamer.Rename(method, "JavaGetDeclaredField"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetDeclaredFields": renamer.Rename(method, "JavaGetDeclaredFields"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetDeclaredInterfaces": renamer.Rename(method, "JavaGetDeclaredInterfaces"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetDeclaredMethod": renamer.Rename(method, "JavaGetDeclaredMethod"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetDeclaredMethods": renamer.Rename(method, "JavaGetDeclaredMethods"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetName": renamer.Rename(method, "JavaGetName"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "IsEnum": renamer.Rename(method, "JavaGetIsEnum"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "GetComponentType": renamer.Rename(method, "JavaGetComponentType"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "IsAssignableFrom": renamer.Rename(method, "JavaIsAssignableFrom"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "IsInterface": renamer.Rename(method, "JavaIsInterface"); method.EditorBrowsableState = EditorBrowsableState.Never; break; case "IsInstance": renamer.Rename(method, "JavaIsInstance"); method.EditorBrowsableState = EditorBrowsableState.Never; break; } }
/// <summary> /// Build properties for the given type /// </summary> internal void BuildProperties(TargetFramework target, MethodRenamer methodRenamer) { if (typeDef.IsInterface) return; var getters = typeDef.Methods.Where(IsGetter).ToList(); var setters = typeDef.Methods.Where(IsSetter).ToList(); var generatedNames = new HashSet<string>(); foreach (var getMethod in getters) { // Get the name of the property var name = GetPropertyName(getMethod); // If there are other methods with same name, we do not create a property if (typeDef.Methods.Any(x => (x != getMethod) && (x.Name == name))) continue; if (typeDef.NestedTypes.Any(x => x.Name == name)) continue; if (typeDef.Name == name) continue; if (typeDef.Fields.Any(x => x.Name == name)) continue; if (!generatedNames.Add(name + "_" + getMethod.Parameters.Count)) continue; // Create property var prop = new NetPropertyDefinition { Name = name, Getter = getMethod, Description = getMethod.Description }; AddCustomAttributes(getMethod, prop.CustomAttributes); // Clone parameters if (getMethod.Parameters.Any()) { prop.Parameters.AddRange(getMethod.Parameters.Select(x => new NetParameterDefinition(x.Name, x.ParameterType, false))); prop.Name = "this"; } // Rename getMethod if needed if (getMethod.Name == prop.Name) { methodRenamer.Rename(getMethod, "Get" + getMethod.Name); } // Find setter var setMethod = FindSetter(getMethod, setters); if (setMethod != null) { prop.Setter = setMethod; // Rename setMethod if needed if (setMethod.Name == prop.Name) { methodRenamer.Rename(setMethod, "Set" + setMethod.Name); } } // Add property typeDef.Properties.Add(prop); } }
/// <summary> /// Build properties for the given type /// </summary> internal void BuildProperties(TargetFramework target, MethodRenamer methodRenamer) { if (typeDef.IsInterface) { return; } var getters = typeDef.Methods.Where(IsGetter).ToList(); var setters = typeDef.Methods.Where(IsSetter).ToList(); var generatedNames = new HashSet <string>(); foreach (var getMethod in getters) { // Get the name of the property var name = GetPropertyName(getMethod); // If there are other methods with same name, we do not create a property if (typeDef.Methods.Any(x => (x != getMethod) && (x.Name == name))) { continue; } if (typeDef.NestedTypes.Any(x => x.Name == name)) { continue; } if (typeDef.Name == name) { continue; } if (typeDef.Fields.Any(x => x.Name == name)) { continue; } if (!generatedNames.Add(name + "_" + getMethod.Parameters.Count)) { continue; } // Create property var prop = new NetPropertyDefinition { Name = name, Getter = getMethod, Description = getMethod.Description }; AddCustomAttributes(getMethod, prop.CustomAttributes); // Clone parameters if (getMethod.Parameters.Any()) { prop.Parameters.AddRange(getMethod.Parameters.Select(x => new NetParameterDefinition(x.Name, x.ParameterType, false))); prop.Name = "this"; } // Rename getMethod if needed if (getMethod.Name == prop.Name) { methodRenamer.Rename(getMethod, "Get" + getMethod.Name); } // Find setter var setMethod = FindSetter(getMethod, setters); if (setMethod != null) { prop.Setter = setMethod; // Rename setMethod if needed if (setMethod.Name == prop.Name) { methodRenamer.Rename(setMethod, "Set" + setMethod.Name); } } // Add property typeDef.Properties.Add(prop); } }
/// <summary> /// Update names where needed /// </summary> public abstract void FinalizeNames(TargetFramework target, MethodRenamer methodRenamer);
/// <summary> /// Update names where needed /// </summary> protected void FinalizeNames(NetTypeDefinition typeDef, TargetFramework target, MethodRenamer methodRenamer) { if (methodBuilders != null) { methodBuilders.ForEach(x => x.FinalizeNames(target, methodRenamer)); } nestedTypeBuilders.ForEach(x => x.FinalizeNames(target, methodRenamer)); //FixMemberNames(typeDef, typeDef.Methods, typeDef.NestedTypes, (m, n) => methodRenamer.Rename(m, n)); FixMemberNames(typeDef, typeDef.Fields, typeDef.NestedTypes, (m, n) => m.Name = n); FixMemberNames(typeDef, typeDef.Fields, typeDef.Methods, (m, n) => m.Name = n); FixMemberNames(typeDef, typeDef.Fields, typeDef.Fields, (m, n) => m.Name = n); // Build properties propertyBuilder = CreatePropertyBuilder(typeDef); propertyBuilder.BuildProperties(target, methodRenamer); typeDef.EnsureVisibility(); }
/// <summary> /// Implement and finalize types /// </summary> public static void Implement(List<TypeBuilder> typeBuilders, TargetFramework target) { typeBuilders.ForEach(x => x.Implement(target)); typeBuilders.ForEach(x => x.Finalize(target, FinalizeStates.AddRemoveMembers)); typeBuilders.ForEach(x => x.Finalize(target, FinalizeStates.FixTypes)); var methodRenamer = new MethodRenamer(target); typeBuilders.ForEach(x => x.FinalizeNames(target, methodRenamer)); typeBuilders.ForEach(x => x.FinalizeProperties(target)); typeBuilders.ForEach(x => x.FinalizeVisibility(target)); }
/// <summary> /// Remove all properties that override / implement a property that does not exist. /// /// Will also fix property visibility. /// </summary> private void FixOverridenProperties(MethodRenamer methodRenamer, TargetFramework target) { if (!typeDef.Properties.Any()) return; // handle overiding properties var allBaseTypes = typeDef.GetBaseTypes(true); var allBaseProperties = allBaseTypes.SelectMany(x => x.GetElementType().Properties).ToList(); var overridingProperties = typeDef.Properties.Where(x => IsAnyOverride(x) && !DoNotFixOverridenProperty(x)).ToList(); for (int i = 0; i < overridingProperties.Count; ++i) { var prop = overridingProperties[i]; NetPropertyDefinition matchingBaseProp = null; if (prop.Getter != null) { // Note: this logic might need to be also applied for the "lone" setter logic below. foreach (var baseProp in allBaseProperties.Where(p=>p.Name == prop.Name)) { var basePropType = GenericParameters.Resolve(baseProp.PropertyType, prop.DeclaringType, target.TypeNameMap); if(!prop.PropertyType.AreSame(basePropType)) continue; matchingBaseProp = baseProp; break; } // Check for existing property in base class if (matchingBaseProp == null) { // implement as normal method. RemoveProperty(prop); continue; } // Check for base property with setter if (prop.Setter != null) { if (matchingBaseProp.Setter == null) { // Remove setter prop.Setter.Property = null; prop.Setter = null; continue; } } } else { // this is a "lone" setter. for boolean setters, the name might have changed. // try to match all base properties, update the name if neccessary. foreach (var baseProp in allBaseProperties.Where(g => g.Getter != null && g.Setter != null)) { if (FindSetter(baseProp.Getter, new[] {prop.Setter}, true) != null) { if (baseProp.Setter.IsVirtual) { if (matchingBaseProp == null || prop.Name == baseProp.Name) matchingBaseProp = baseProp; } } } if(matchingBaseProp == null) { // remove the property alltogether prop.Setter.Property = null; typeDef.Properties.Remove(prop); continue; } prop.Name = matchingBaseProp.Name; } // We must implement the property, since we inherited it. // Fix up any clashes. // clashes with explicit implementations should not occur. if ((prop.Getter ?? prop.Setter).InterfaceType != null) continue; var propName = prop.Name; if (propName == typeDef.Name) { if (!matchingBaseProp.DeclaringType.IsInterface) { Console.Error.WriteLine("Warning: Inherited property {0}::{1} clashes with type name. Skipping generation of property and methods.", typeDef.FullName, propName); typeDef.Properties.Remove(prop); typeDef.Methods.Remove(prop.Getter); typeDef.Methods.Remove(prop.Setter); continue; } // make this an explicit interface implementtion. // TODO: We might also want to keep a renamed property in this case, // too allow access to the property from the class. // Also, the explicit implementation does not need a "JavaImport" attribute. Console.Error.WriteLine("Warning: Inherited property {0}::{1} clashes with type name. Generating explicit implementation.", typeDef.FullName, propName); if (prop.Getter != null) { if (matchingBaseProp.Getter != null) prop.Getter.SetExplicitImplementation(matchingBaseProp.Getter, matchingBaseProp.DeclaringType); else prop.Getter = null; } if (prop.Setter != null) { if (matchingBaseProp.Setter != null) prop.Setter.SetExplicitImplementation(matchingBaseProp.Setter, matchingBaseProp.DeclaringType); else prop.Setter = null; } continue; } if (typeDef.NestedTypes.Any(x => x.Name == propName)) { Console.Error.WriteLine("Warning: Inherited property {0}::{1} clashes with nested type. Renaming nested type, but consider renaming the property instead.", typeDef.FullName, propName); typeDef.NestedTypes.Where(x => x.Name == propName).ForEach(t=>t.Name += "FixMe"); } foreach (var clash in typeDef.Properties.Where(x => x != prop && x.Name == propName).ToList()) { if (clash.Parameters.Count != prop.Parameters.Count) continue; if ((clash.Getter ?? clash.Setter).InterfaceType != null) continue; if (prop.PropertyType.AreSame(clash.PropertyType) && prop.MainMethod.CreateReason == "TypeBuilder.AddAbstractInterfaceMethods") { // it appears that the method does have an implementation! typeDef.Properties.Remove(prop); typeDef.Methods.Remove(prop.Getter); typeDef.Methods.Remove(prop.Setter); overridingProperties.RemoveAt(i); i -= 1; goto continue_outer; } if (overridingProperties.Contains(clash)) { // This would have probably been removed later anyways. //Console.Error.WriteLine("Warning: duplicate property names {0}::{1}. Not generating property for one of the clashes.", typeDef.FullName, propName); RemoveProperty(clash); overridingProperties.Remove(clash); // this must come after us. continue; } // else remove other property RemoveProperty(clash); } if (typeDef.Methods.Any(x => x != prop.Setter && x != prop.Getter && x.Name == propName)) { Console.Error.WriteLine("Warning: Inherited property {0}::{1} clashes with methods. Prepending \"Invoke\" prefix to methods.", typeDef.FullName, propName); typeDef.Methods.Where(x => x != prop.Setter && x != prop.Getter && x.Name == propName) .ForEach(m => methodRenamer.Rename(m, "Invoke" + m.Name)); } continue_outer:; } }
/// <summary> /// Build properties for the given type /// </summary> internal void BuildProperties(TargetFramework target, MethodRenamer methodRenamer) { var getters = typeDef.Methods.Where(IsGetter).ToList(); var setters = typeDef.Methods.Where(IsSetter).ToList(); foreach (var getMethod in getters) { // Get the name of the property var name = GetPropertyName(getMethod); // other clashes must be handled later. if(getMethod.InterfaceType == null) typeDef.Fields.Where(x => x.Name == name).ForEach(RenameClashingField); // Create property var prop = new NetPropertyDefinition { Name = name, Getter = getMethod, Description = getMethod.Description, }; AddCustomAttributes(getMethod, prop.CustomAttributes); // Clone parameters if (getMethod.Parameters.Any()) { prop.Parameters.AddRange(getMethod.Parameters.Select(x => new NetParameterDefinition(x.Name, x.ParameterType, false))); prop.Name = "this"; } getMethod.Property = prop; // Find setter var setMethod = FindSetter(getMethod, setters); if (setMethod != null) { prop.Setter = setMethod; setMethod.Property = prop; setters.Remove(setMethod); } // Add property typeDef.Properties.Add(prop); } // create properties for lone setters that override a base setter foreach (var setMethod in setters.Where(s => s.IsOverride)) { var name = GetPropertyName(setMethod); // other clashes must be handled in FixOverrides if (setMethod.InterfaceType == null) typeDef.Fields.Where(x => x.Name == name).ForEach(RenameClashingField); // Create property var prop = new NetPropertyDefinition { Name = name, Setter = setMethod, Description = setMethod.Description }; setMethod.Property = prop; AddCustomAttributes(setMethod, prop.CustomAttributes); // Clone parameters if (setMethod.Parameters.Skip(1).Any()) { prop.Parameters.AddRange(setMethod.Parameters.Skip(1).Select(x => new NetParameterDefinition(x.Name, x.ParameterType, false))); prop.Name = "this"; } typeDef.Properties.Add(prop); } }
/// <summary> /// Modify the name of the given method to another name. /// By calling renamer.Rename, all methods in the same group are also updated. /// </summary> public override void ModifyMethodName(ImportJarLib.Model.NetMethodDefinition method, MethodRenamer renamer) { base.ModifyMethodName(method, renamer); if (method.OriginalJavaName == "get") renamer.Rename(method, "GetValue"); }