/// <summary> /// Get's the namespace of the given type after conversion. /// </summary> public string GetConvertedNamespace(XTypeDefinition type) { if (type.IsNested) { return GetConvertedNamespace(type.DeclaringType); } var ns = type.Namespace; return ConvertNamespace(ns); }
/// <summary> /// Create the current type as class definition. /// </summary> protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XTypeDefinition parentXType) { base.CreateClassDefinition(targetPackage, parent, parentType, parentXType); Class.AccessFlags &= ~AccessFlags.Final; Class.IsAbstract = true; //Class.IsInterface = true; // Record in compiler Compiler.Record(new DelegateType(Compiler, XType, Class, targetPackage.DexFile, targetPackage.NameConverter)); }
/// <summary> /// Default ctor /// </summary> public DelegateType(AssemblyCompiler compiler, XTypeDefinition delegateType, ClassDefinition interfaceClass, Dex target, NameConverter nsConverter) { this.compiler = compiler; this.delegateType = delegateType; this.interfaceClass = interfaceClass; // Build invoke prototype invokeMethod = delegateType.Methods.First(x => x.EqualsName("Invoke")); }
/// <summary> /// Is the given type a struct? /// </summary> public static bool IsStruct(this XTypeReference type, out XTypeDefinition typeDef) { typeDef = null; if (type == null) { return(false); } return(type.TryResolve(out typeDef) && typeDef.IsStruct); }
/// <summary> /// .NET ctor /// </summary> public DecompilerContext(XMethodDefinition currentMethod) { if (currentMethod == null) throw new ArgumentNullException("currentMethod"); name = currentMethod.Name; declaringTypeName = currentMethod.DeclaringType.Name; declaringType = currentMethod.DeclaringType; returnType = currentMethod.ReturnType; currentModule = currentMethod.Module; }
/// <summary> /// Default ctor /// </summary> public AstBuilder(XModule module, MethodDefinition methodDef, XTypeDefinition declaringType, bool optimize) { this.module = module; typeSystem = module.TypeSystem; this.methodDef = methodDef; this.declaringType = declaringType; this.optimize = optimize; codeAttr = methodDef.Attributes.OfType<CodeAttribute>().FirstOrDefault(); validExceptionHandlers = (codeAttr != null) ? codeAttr.ExceptionHandlers.Where(IsValid).ToList() : null; }
/// <summary> /// Is the given type an enum? /// </summary> public static bool IsEnum(this XTypeReference type, out XTypeDefinition typeDef) { typeDef = null; if (type == null) { return(false); } type = type.GetWithoutModifiers(); return(type.TryResolve(out typeDef) && typeDef.IsEnum); }
public override void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage) { if (_baseFieldBuilder.dfield == null) return; // can't create udater for static fields. if (field.IsStatic) return; var updaterType = GetAtomicFieldUpdaterType(field.FieldType); if (updaterType == null) return; var fullUpdateTypeName = "Java.Util.Concurrent.Atomic." + updaterType; // create matching xField. Note: this seems to be a hack. what to do? var objType = new ObjectTypeReference(fullUpdateTypeName, new TypeArgument[0]); var javaTypeReference = new XBuilder.JavaTypeReference(Compiler.Module, objType, objType.ClassName); var basexField = _baseFieldBuilder.xField; var basedField = _baseFieldBuilder.dfield; var fieldName = basedField.Name + NameConstants.Atomic.FieldUpdaterPostfix; var xflags = XSyntheticFieldFlags.Static | XSyntheticFieldFlags.ReadOnly; if (basedField.IsProtected) xflags |= XSyntheticFieldFlags.Protected; if (basedField.IsPrivate) xflags |= XSyntheticFieldFlags.Private; var xAtomicField = XSyntheticFieldDefinition.Create(basexField.DeclaringType, xflags, fieldName, javaTypeReference); xField = xAtomicField; // create dfield. dfield = new DexLib.FieldDefinition { Name = fieldName, IsStatic = true, IsFinal = true, IsSynthetic = true, // same access as the original field. IsPublic = basedField.IsPublic, IsPrivate = basedField.IsPrivate, IsProtected = basedField.IsProtected, }; AddFieldToDeclaringClass(declaringClass, dfield, targetPackage); targetPackage.NameConverter.Record(xField, dfield); }
/// <summary> /// Gets the type with the given namespace and name. /// </summary> public bool TryGetType(string fullName, out XTypeDefinition type) { FullNameCacheEntry e; if (fullNameCache.TryGetValue(fullName, out e)) { type = e.Type; return(true); } type = null; return(false); }
/// <summary> /// Create the current type as class definition. /// </summary> public virtual void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage) { // Find xfield xField = XBuilder.AsFieldDefinition(compiler.Module, field); // Create field definition dfield = new Dot42.DexLib.FieldDefinition(); dfield.Name = NameConverter.GetConvertedName(field); AddFieldToDeclaringClass(declaringClass, dfield, targetPackage); targetPackage.NameConverter.Record(xField, dfield); // Set access flags SetAccessFlags(dfield, field); // Give warning if static in generic class. // This could of cause also be handled automagically be the compiler, // with mixture of whats done in the Interlocked converter and whats // done in the GenericInstanceConverter. if (field.IsStatic && declaringType.IsGenericClass) { if (!field.HasSuppressMessageAttribute("StaticFieldInGenericType") && !field.DeclaringType.HasSuppressMessageAttribute("StaticFieldInGenericType")) { string msg; if (field.Name.Contains("CachedAnonymousMethodDelegate")) msg = "The compiler generated a static field '{0}' in generic type '{1}'. This is not supported " + "in Dot42 if the anonymous delegate accesses a generic class parameter. A workaround " + "is to convert the anonymous static delegate to a normal method.\n"; else msg = "Static field '{0}' in generic type {1}: All generic instances will share " + "the same static field, contrary on how CLR operates. A workaround is to " + "use ConcurrentDictionaries to access the values dependent on the type.\n"; msg += "You can suppress this warning with a [SuppressMessage(\"dot42\"," + " \"StaticFieldInGenericType\")] attribute, either on the field or on the class."; var body = field.DeclaringType.Methods.Select(m => m.Body) .FirstOrDefault(m => m != null && m.Instructions.Any(i => i.SequencePoint != null)); if (body != null) { var seqPoint = body.Instructions.Select(i=>i.SequencePoint).First(i => i != null); DLog.Warning(DContext.CompilerILConverter, seqPoint.Document.Url, seqPoint.StartColumn, seqPoint.StartLine, msg, field.Name, declaringType.FullName); } else { DLog.Warning(DContext.CompilerILConverter, msg, field.Name, declaringType.FullName); } } } }
protected override XTypeDefinition CreateXType(XTypeDefinition parentXType) { var typeDef = (XBuilder.ILTypeDefinition)XBuilder.AsTypeReference(Compiler.Module, Type) .Resolve(); string name = NameConverter.GetNullableClassName(typeDef.Name); XSyntheticTypeFlags xflags = default(XSyntheticTypeFlags); return XSyntheticTypeDefinition.Create(Compiler.Module, parentXType, xflags, typeDef.Namespace, name, Compiler.Module.TypeSystem.Object, string.Join(":", Type.Scope.Name, Type.MetadataToken.ToScopeId(), "Nullable")); }
protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XTypeDefinition parentXType) { base.CreateClassDefinition(targetPackage, parent, parentType, parentXType); if (IsDot42InternalApplication()) { // FixUp Visiblility. Class.IsPublic = true; Class.IsProtected = false; Class.IsPrivate = false; } }
/// <summary> /// Create the current type as class definition. /// </summary> public void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage) { // Find xfield xField = XBuilder.AsFieldDefinition(compiler.Module, field); // Create field definition dfield = new Dot42.DexLib.FieldDefinition(); dfield.Name = NameConverter.GetConvertedName(field); AddFieldToDeclaringClass(declaringClass, dfield, targetPackage); targetPackage.NameConverter.Record(xField, dfield); // Set access flags SetAccessFlags(dfield, field); }
private XMethodDefinition FindMethod(XTypeDefinition delegateType, string methodName) { while (true) { var ret = delegateType.Methods.FirstOrDefault(x => x.EqualsName(methodName)); if (ret != null) return ret; var baseType = delegateType.BaseType; if (baseType == null) return null; delegateType = baseType.Resolve(); } }
/// <summary> /// Resolve this reference to it's definition. /// </summary> public virtual bool TryResolve(out XTypeDefinition type) { if (resolvedType != null) { type = resolvedType; return(true); } if (!Module.TryGetType(FullName, out type)) { return(false); } // Cache for later resolvedType = type; type.AddFlushAction(() => resolvedType = null); return(true); }
/// <summary> /// Try to get a type definition (me or one of my nested typed) by the given full name. /// </summary> public virtual bool TryGet(string fullName, bool noImports, out XTypeDefinition type) { if (FullName == fullName) { type = this; return(true); } foreach (var nested in NestedTypes) { if (nested.TryGet(fullName, noImports, out type)) { return(true); } } type = null; return(false); }
/// <summary> /// Default ctor /// </summary> public DelegateType(AssemblyCompiler compiler, XTypeDefinition delegateType, ClassDefinition interfaceClass, Dex target, NameConverter nsConverter) { this.compiler = compiler; this.delegateType = delegateType; this.interfaceClass = interfaceClass; // Build invoke prototype invokeMethod = delegateType.Methods.First(x => x.EqualsName("Invoke")); XTypeDefinition baseType = delegateType; while ((null != baseType) && !baseType.Methods.Any(x => x.EqualsName("Equals"))) { baseType = baseType.BaseType as XTypeDefinition; } if (null != baseType) { equalsMethod = baseType.Methods.First(x => x.EqualsName("Equals")); } }
/// <summary> /// Add the given type to my list. /// </summary> internal void Register(XTypeDefinition type, string overrideFullName = null) { Register(type, overrideFullName, false); string className; if (type.TryGetDexImportNames(out className)) { var typeRef = Java.XBuilder.AsTypeReference(this, className, XTypeUsageFlags.DeclaringType); Register(type, typeRef.FullName, true); } if (type.TryGetJavaImportNames(out className)) { var typeRef = Java.XBuilder.AsTypeReference(this, className, XTypeUsageFlags.DeclaringType); Register(type, typeRef.FullName, true); } }
/// <summary> /// Does the given type extend from System.MulticastDelegate? /// </summary> public static bool IsDelegate(this XTypeDefinition type) { while (true) { var baseType = type.BaseType; if (baseType == null) { break; } if (!baseType.TryResolve(out type)) { break; } if (type.FullName == typeof(System.MulticastDelegate).FullName) { return(true); } } return(false); }
/// <summary> /// Is the given type a base class of the given child? /// </summary> public static bool IsBaseOf(this XTypeDefinition type, XTypeDefinition child) { while (child != null) { if (child.BaseType == null) { return(false); } XTypeDefinition baseType; if (!child.BaseType.TryResolve(out baseType)) { return(false); } if (baseType.IsSame(type)) { return(true); } child = baseType; } return(false); }
private void Register(XTypeDefinition type, string overridenName, bool isImport) { // scopeId must be unique if (scopeIdCache.ContainsKey(type.ScopeId) && scopeIdCache[type.ScopeId] != type) { if (type is XBuilder.JavaTypeDefinition) { // FixMe. Java TypeDefinitions get created multiple times. //Debugger.Break(); } else { throw new Exception("scopeId not unique for " + type.ScopeId); } } scopeIdCache[type.ScopeId] = type; var fullname = overridenName ?? type.FullName; FullNameCacheEntry e; if (fullNameCache.TryGetValue(fullname, out e)) { if (e.Priority < type.Priority) { return; } // new priority is higher or equal, // but we must not override a non-import type. if (isImport && !e.IsImport) { return; } } fullNameCache[fullname] = new FullNameCacheEntry(type, type.Priority, isImport); }
/// <summary> /// Gets the type with the given namespace and name. /// </summary> public bool TryGetType(string fullName, out XTypeDefinition type) { if (fullNameCache.TryGetValue(fullName, out type)) { return(true); } for (var attempt = 0; attempt < 2; attempt++) { var noImports = (attempt == 0); sortedTypes = sortedTypes ?? types.OrderBy(x => x.Priority).ToList(); foreach (var t in sortedTypes) { if (t.TryGet(fullName, noImports, out type)) { fullNameCache[fullName] = type; return(true); } } } type = null; return(false); }
/// <summary> /// Create the classname for the Nullable base class for the given type. /// </summary> public static string GetNullableBaseClassName(XTypeDefinition type) { return type.Name + "__Nullable"; }
/// <summary> /// Resolve this reference to it's definition. /// </summary> public override bool TryResolve(out XTypeDefinition type) { type = null; return(false); }
/// <summary> /// Create the classname for the Nullable base class for the given type. /// </summary> public static string GetNullableClassName(XTypeDefinition type) { return GetNullableClassName(type.Name); }
public FullNameCacheEntry(XTypeDefinition type, int priority, bool isImport) { Type = type; Priority = priority; IsImport = isImport; }
/// <summary> /// Default ctor /// </summary> protected XTypeDefinition(XModule module, XTypeDefinition declaringType, bool isValueType, IEnumerable<string> genericParameterNames) : base(module, declaringType, isValueType, genericParameterNames) { }
/// <summary> /// Create the current type as class definition. /// </summary> protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XTypeDefinition parentXType) { base.CreateClassDefinition(targetPackage, parent, parentType, parentXType); XType.SetDexClass(Class, targetPackage); }
/// <summary> /// Gets the default constructor of the given value type. /// Throws an exception if not found. /// </summary> internal static XMethodDefinition GetDefaultValueCtor(XTypeDefinition valueType) { var defaultCtor = valueType.Methods.FirstOrDefault(x => x.IsConstructor && !x.IsStatic && (x.Parameters.Count == 0)); if (defaultCtor == null) throw new NotImplementedException(string.Format("Value type {0} has no default ctor", valueType.FullName)); return defaultCtor; }
/// <summary> /// Resolve this reference to it's definition. /// </summary> public override bool TryResolve(out XTypeDefinition type) { return ElementType.TryResolve(out type); }
/// <summary> /// Convert an argument or a numeric operation to int/long. /// </summary> private static void ConvertNumericOpArgument(AstExpression node, int argumentIndex, XTypeDefinition enumType, bool isWide, XTypeReference enumNumericType) { var module = enumType.Module; var argument = node.Arguments[argumentIndex]; switch (argument.Code) { case AstCode.Ldc_I4: // Keep numeric value argument.SetType(module.TypeSystem.Int); break; case AstCode.Ldc_I8: // Keep numeric value argument.SetType(module.TypeSystem.Long); break; default: // Convert enum to numeric var numericValue = new AstExpression(argument); argument.SetCode(isWide ? AstCode.Enum_to_long : AstCode.Enum_to_int) .SetType(enumNumericType) .SetArguments(numericValue); break; } }
/// <summary> /// Convert the given node that holds a numeric value and convert it to it's enum instance. /// </summary> private static void ConvertNumericToEnum(AstExpression node, XTypeDefinition enumType, XTypeReference enumNumericType) { // Call Enum.GetValue(enumType, value) var enumValue = new AstExpression(node); node.SetCode(enumNumericType.IsWide() ? AstCode.Long_to_enum : AstCode.Int_to_enum).SetArguments(enumValue).SetType(enumType); node.Operand = null; }
/// <summary> /// Convert a integer compare operation (bge, bgt, ble, blt) with enum argument. /// </summary> private static void ConvertICmpArgument(AstExpression node, int argIndex, XTypeDefinition enumType, AssemblyCompiler compiler) { Debug.Assert(node.Arguments.Count == 2); var isWide = enumType.GetEnumUnderlyingType().IsWide(); var module = compiler.Module; var retType = isWide ? module.TypeSystem.Long : module.TypeSystem.Int; // Convert arguments ConvertNumericOpArgument(node, argIndex, enumType, isWide, retType); }
/// <summary> /// Convert a binary operation (Add, Sub, Mul, Div, Rem, And, Or, Xor) resulting in an enum. /// </summary> private static void ConvertBinOp(AstExpression node, XTypeDefinition enumType, AssemblyCompiler compiler) { Debug.Assert(node.Arguments.Count == 2); var isWide = enumType.GetEnumUnderlyingType().IsWide(); var module = compiler.Module; var retType = isWide ? module.TypeSystem.Long : module.TypeSystem.Int; // Convert arguments ConvertNumericOpArgument(node, 0, enumType, isWide, retType); ConvertNumericOpArgument(node, 1, enumType, isWide, retType); // Convert return value if ((node.ExpectedType == null) || (!node.ExpectedType.IsPrimitive)) { ConvertNumericToEnum(node, enumType, retType); } else { node.InferredType = retType; } }
/// <summary> /// Add the given type to my list. /// </summary> private void Add(XTypeDefinition type) { types.Add(type); sortedTypes = null; }
/// <summary> /// Gets a formatted full classname for the given type. /// </summary> private string FormatClassName(XTypeDefinition typeDef) { string className; if (typeDef.TryGetDexImportNames(out className)) return FormatImportedClassName(className); if (typeDef.TryGetJavaImportNames(out className)) return FormatImportedClassName(className); return nsConverter.GetConvertedFullName(typeDef); }
/// <summary> /// Gets the struct $CopyFrom method of the given value type. /// Throws an exception if not found. /// </summary> private static XMethodDefinition GetCopyFromMethod(XTypeDefinition valueType) { var method = valueType.Methods.FirstOrDefault(x => !x.IsStatic && (x.Parameters.Count == 1) && (x.Name == NameConstants.Struct.CopyFromMethodName)); if (method == null) throw new NotImplementedException(string.Format("Value type {0} has no struct copyFrom method", valueType.FullName)); return method; }
/// <summary> /// Resolve this reference to it's definition. /// </summary> public override bool TryResolve(out XTypeDefinition type) { return(ElementType.TryResolve(out type)); }
/// <summary> /// Mark is as an annotation /// </summary> protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XTypeDefinition parentXType) { base.CreateClassDefinition(targetPackage, parent, parentType, parentXType); Class.AccessFlags |= AccessFlags.Annotation; }
/// <summary> /// Resolve this reference to it's definition. /// </summary> public override bool TryResolve(out XTypeDefinition type) { type = this; return true; }
/// <summary> /// Create the current type as class definition. /// </summary> protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XTypeDefinition parentXType) { // Do not create a class. // It already exists in the framework. }
/// <summary> /// Create the XType for this builder. /// </summary> protected override XTypeDefinition CreateXType(XTypeDefinition parentXType) { var baseType = Compiler.GetDot42InternalType("EnumInfo"); return XSyntheticTypeDefinition.Create(Compiler.Module, parentXType, XSyntheticTypeFlags.Private, null, ClassName, baseType, parentXType.ScopeId + ":Info"); }
/// <summary> /// Default ctor /// </summary> protected XMethodDefinition(XTypeDefinition declaringType) : base(declaringType) { }
/// <summary> /// Get's the full name of the given type after conversion. /// </summary> public string GetConvertedFullName(XTypeDefinition type) { if (type.IsNested) { var declaringTypeName = GetConvertedFullName(type.DeclaringType); return declaringTypeName + Dex.NestedClassSeparator + GetConvertedName(type); } var ns = GetConvertedNamespace(type); return ns + '.' + GetConvertedName(type); }
/// <summary> /// Default ctor /// </summary> protected XTypeDefinition(XModule module, XTypeDefinition declaringType, bool isValueType, IEnumerable <string> genericParameterNames) : base(module, declaringType, isValueType, genericParameterNames) { }
/// <summary> /// Resolve this reference to it's definition. /// </summary> public override bool TryResolve(out XTypeDefinition type) { type = this; return(true); }
/// <summary> /// Gets the recorded delegate type for the given .NET delegate type. /// </summary> internal DelegateType GetDelegateType(XTypeDefinition type) { DelegateType result; if (delegateTypes.TryGetValue(type, out result)) return result; throw new ArgumentException(string.Format("No delegate type found for {0}", type.FullName)); }