/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { dmethod.IsStatic = true; dmethod.IsPublic = true; if (method.IsAbstract || method.IsVirtual) { // generate a warning, since these methods will never be called // as virtual. Do not generate a warning if we know the compiler // will handle the call. if (method.DeclaringType.FullName == "System.Array") { // all array methods should be redirected by the compiler. return; } if (method.DeclaringType.FullName == "System.String" && method.Name.EndsWith("GetEnumerator")) { // IEnumerable.GetEnumerator will actually never be called by the compiler // in foreach loops. Nevertheless Roslyn requires its existence. return; } var intfMethod = method.GetBaseInterfaceMethod(); if (intfMethod != null && intfMethod.DeclaringType.FullName == "System.IFormattable") { // this is handled by the compiler. return; } DLog.Warning(DContext.CompilerCodeGenerator, "Abstract or virtual .NET method '{0}' in DexImport class '{1}'. Unless specially handled by the compiler, this will never be called virtually.", method.Name, method.DeclaringType.FullName); } }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected virtual void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { // subclass accesses have already been fixed on an actual use basis. if (method.IsPrivate) { dmethod.IsPrivate = true; } else if (method.IsFamily || method.IsFamilyOrAssembly) { dmethod.IsProtected = true; } else { dmethod.IsPublic = true; } if (method.DeclaringType.IsInterface) { dmethod.IsAbstract = true; //dmethod. } else { if (method.IsConstructor) { dmethod.IsConstructor = true; dmethod.IsStatic = method.IsStatic; if (method.IsStatic) { // reset access modifiers for static constructors. dmethod.IsPrivate = false; dmethod.IsProtected = false; } } else if (method.IsAbstract) { dmethod.IsAbstract = true; } else if (method.IsVirtual) { dmethod.IsVirtual = true; } else if (method.IsStatic) { dmethod.IsStatic = true; } else { dmethod.IsFinal = true; } //if (method.IsInitOnly) dmethod.IsFinal = true; } if (method.IsCompilerGenerated()) { dmethod.IsSynthetic = true; } }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected virtual void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { if (method.IsPrivate) { if (method.DeclaringType.HasNestedTypes) { dmethod.IsProtected = true; } else { dmethod.IsPrivate = true; } } else if (method.IsFamily) { dmethod.IsProtected = true; } else { dmethod.IsPublic = true; } if (method.DeclaringType.IsInterface) { dmethod.IsAbstract = true; //dmethod. } else { if (method.IsConstructor) { dmethod.IsConstructor = true; } else if (method.IsAbstract) { dmethod.IsAbstract = true; } else if (method.IsVirtual) { dmethod.IsVirtual = true; } else if (method.IsStatic) { dmethod.IsStatic = true; } else { dmethod.IsFinal = true; } //if (method.IsInitOnly) dmethod.IsFinal = true; } }
/// <summary> /// Create the current type as class definition. /// </summary> public void Create(ClassDefinition declaringClass, DexTargetPackage targetPackage) { // Find xMethod xMethod = XBuilder.AsMethodDefinition(compiler.Module, method); // Create method definition dmethod = new DexLib.MethodDefinition(); dmethod.Name = GetMethodName(method, targetPackage); dmethod.MapFileId = compiler.GetNextMapFileId(); AddMethodToDeclaringClass(declaringClass, dmethod, targetPackage); targetPackage.Record(xMethod, dmethod); // Set access flags SetAccessFlags(dmethod, method); // Create prototype dmethod.Prototype = PrototypeBuilder.BuildPrototype(compiler, targetPackage, declaringClass, xMethod); }
/// <summary> /// Create the current type as class definition. /// </summary> public void Create(ClassDefinition declaringClass, DexTargetPackage targetPackage) { // Find xMethod xMethod = XBuilder.AsMethodDefinition(compiler.Module, method); // Create method definition dmethod = new DexLib.MethodDefinition(); dmethod.Name = GetMethodName(method, targetPackage); dmethod.MapFileId = compiler.GetNextMapFileId(); AddMethodToDeclaringClass(declaringClass, dmethod, targetPackage); targetPackage.Record(xMethod, dmethod); // Set access flags SetAccessFlags(dmethod, method); // Create prototype dmethod.Prototype = PrototypeBuilder.BuildPrototype(compiler, targetPackage, declaringClass, xMethod); }
/// <summary> /// Ensure that the name of the method is unique. /// </summary> private static void UpdateName(DexLib.MethodDefinition method, ClassDefinition declaringClass) { var baseName = method.Name; if (baseName == "<init>") { baseName = "NetCtor"; } var name = baseName; var postfix = 0; while (true) { if (declaringClass.Methods.All(x => x.Name != name)) { method.Name = name; return; } name = baseName + ++postfix; } }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { base.SetAccessFlags(dmethod, method); dmethod.IsNative = true; }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected virtual void AddMethodToDeclaringClass(ClassDefinition declaringClass, DexLib.MethodDefinition dmethod, DexTargetPackage targetPackage) { dmethod.Owner = declaringClass; declaringClass.Methods.Add(dmethod); }
public static MethodEntry RecordMapping(TypeEntry typeEntry, XMethodDefinition xMethod, MethodDefinition method, DexLib.MethodDefinition dmethod, CompiledMethod compiledMethod) { var scopeId = xMethod.ScopeId; StringBuilder netSignature = new StringBuilder(); method.MethodSignatureFullName(netSignature); var entry = new MethodEntry(method.OriginalName, netSignature.ToString(), dmethod.Name, dmethod.Prototype.ToSignature(), dmethod.MapFileId, scopeId); typeEntry.Methods.Add(entry); if (compiledMethod != null) { compiledMethod.RecordMapping(entry); } return(entry); }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void AddMethodToDeclaringClass(ClassDefinition declaringClass, DexLib.MethodDefinition dmethod, DexTargetPackage targetPackage) { var generatedCodeClass = targetPackage.GetOrCreateGeneratedCodeClass(); UpdateName(dmethod, generatedCodeClass); dmethod.Owner = generatedCodeClass; generatedCodeClass.Methods.Add(dmethod); }
/// <summary> /// Add the given method to its declaring class. /// </summary> protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method) { dmethod.IsStatic = true; dmethod.IsPublic = true; }