public FieldDefinition(ClassDefinition owner, string name, TypeReference fieldType) : this() { Owner = owner; Name = name; Type = fieldType; }
public MethodDefinition(ClassDefinition owner, string name, Prototype prototype) : this() { Owner = owner; Name = name; Prototype = prototype; }
/// <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); }
public void AddClass(ClassDefinition classDef) { classes.Add(classDef); classesByName.Add(classDef.Fullname, classDef); classDef.RegisterDex(this); RegisterInnerClasses(classDef); }
public override void Implement(ClassDefinition declaringClass, DexTargetPackage targetPackage) { if (xField == null) return; dfield.Type = xField.FieldType.GetReference(targetPackage); }
/// <summary> /// Add the given field to its declaring class. /// </summary> protected override void AddFieldToDeclaringClass(ClassDefinition declaringClass, DexLib.FieldDefinition dfield, DexTargetPackage targetPackage) { var generatedCodeClass = targetPackage.GetOrCreateGeneratedCodeClass(); UpdateName(dfield, generatedCodeClass); dfield.Owner = generatedCodeClass; generatedCodeClass.Fields.Add(dfield); }
/// <summary> /// Create the current type as class definition. /// </summary> protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XModel.XTypeDefinition parentXType) { base.CreateClassDefinition(targetPackage, parent, parentType, parentXType); Class.IsFinal = true; Class.IsAbstract = true; Class.IsSynthetic = true; }
/// <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> /// Initializes a mapping. /// </summary> public static AttributeAnnotationMapping CreateMapping( ISourceLocation sequencePoint, AssemblyCompiler compiler, DexTargetPackage targetPackage, TypeDefinition attributeType, ClassDefinition attributeClass) { return new AttributeAnnotationMapping(attributeType, attributeClass); }
/// <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> /// Verify the given class /// </summary> private void VerifyClass(ClassDefinition @class) { foreach (var method in @class.Methods) { VerifyMethod(method); } foreach (var inner in @class.InnerClasses) { VerifyClass(inner); } }
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> /// Create a prototype for the given methods signature /// </summary> internal static Prototype BuildPrototype(AssemblyCompiler compiler, DexTargetPackage targetPackage, ClassDefinition declaringClass, MethodDefinition method) { var result = new Prototype(); var module = compiler.Module; result.ReturnType = method.ReturnType.GetReference(XTypeUsageFlags.ReturnType, targetPackage, module); var paramIndex = 0; foreach (var p in method.Parameters) { var dparameter = new Parameter(p.GetReference(XTypeUsageFlags.ParameterType, targetPackage, module), "p" + paramIndex++); result.Parameters.Add(dparameter); } return result; }
/// <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); } } } }
/// <summary> /// Create the current type as class definition. /// </summary> public void Create(ClassDefinition declaringClass, 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); }
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> /// Ensure that the name of the field is unique. /// </summary> private static void UpdateName(DexLib.FieldDefinition field, ClassDefinition declaringClass) { var baseName = field.Name; var name = field.Name; var postfix = 0; while (true) { if (declaringClass.Fields.All(x => x.Name != name)) { field.Name = name; return; } name = baseName + ++postfix; } }
/// <summary> /// Create the current type as class definition. /// </summary> internal DelegateInstanceTypeBuilder( ISourceLocation sequencePoint, AssemblyCompiler compiler, DexTargetPackage targetPackage, ClassDefinition delegateClass, XMethodDefinition invokeMethod, Prototype invokePrototype, XMethodDefinition calledMethod) { this.sequencePoint = sequencePoint; this.compiler = compiler; this.targetPackage = targetPackage; this.delegateClass = delegateClass; this.invokeMethod = invokeMethod; this.invokePrototype = invokePrototype; this.calledMethod = calledMethod; this.multicastDelegateClass = compiler.GetDot42InternalType("System", "MulticastDelegate").GetClassReference(targetPackage); }
/// <summary> /// Ensure that the name of the field 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; } }
private void AddClass(ClassDefinition @class, bool createMethodLookup = true) { _classesByFullName[@class.Fullname] = @class; if (createMethodLookup) { foreach (var method in @class.Methods) { _methodsBySignature[Tuple.Create(@class.Fullname, method.Name, method.Prototype.ToSignature())] = method; } } foreach(var inner in @class.InnerClasses) AddClass(inner, createMethodLookup); }
/// <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> /// 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 a prototype for the given methods signature /// </summary> internal static Prototype BuildPrototype(AssemblyCompiler compiler, DexTargetPackage targetPackage, ClassDefinition declaringClass, XMethodDefinition method) { var result = new Prototype(); result.ReturnType = method.ReturnType.GetReference(targetPackage); if (method.IsAndroidExtension && !method.IsStatic) { // Add "this" parameter var dparameter = new Parameter(method.DeclaringType.GetReference(targetPackage), "this"); result.Parameters.Add(dparameter); } foreach (var p in method.Parameters) { var dparameter = new Parameter(p.ParameterType.GetReference(targetPackage), p.Name); result.Parameters.Add(dparameter); } AddGenericParameters(compiler, targetPackage, method, result); result.Freeze(); return result; }
/// <summary> /// Create a prototype for the given methods signature /// </summary> internal static Prototype BuildPrototype(AssemblyCompiler compiler, DexTargetPackage targetPackage, ClassDefinition declaringClass, XMethodDefinition method) { var result = new Prototype(); result.ReturnType = method.ReturnType.GetReference(targetPackage); if (method.IsAndroidExtension && !method.IsStatic) { // Add "this" parameter var dparameter = new Parameter(method.DeclaringType.GetReference(targetPackage), "this"); result.Parameters.Add(dparameter); } foreach (var p in method.Parameters) { var dparameter = new Parameter(p.ParameterType.GetReference(targetPackage), p.Name); result.Parameters.Add(dparameter); } if (method.NeedsGenericInstanceTypeParameter) { // Add GenericInstance parameter (to pass the generic instance array of the declaring type) var paramType = FrameworkReferences.ClassArray; var dparameter = new Parameter(paramType, "__$$git"); var annType = compiler.GetDot42InternalType(InternalConstants.GenericTypeParameterAnnotation).GetClassReference(targetPackage); dparameter.Annotations.Add(new Annotation(annType, AnnotationVisibility.Runtime)); result.Parameters.Add(dparameter); result.GenericInstanceTypeParameter = dparameter; } if (method.NeedsGenericInstanceMethodParameter) { // Add GenericInstance parameter var paramType = FrameworkReferences.ClassArray; var dparameter = new Parameter(paramType, "__$$gim"); var annType = compiler.GetDot42InternalType(InternalConstants.GenericMethodParameterAnnotation).GetClassReference(targetPackage); dparameter.Annotations.Add(new Annotation(annType, AnnotationVisibility.Runtime)); result.Parameters.Add(dparameter); result.GenericInstanceMethodParameter = dparameter; } return result; }
/// <summary> /// Default ctor /// </summary> internal AttributeAnnotationInterface(ClassDefinition annotationInterfaceClass) { this.annotationInterfaceClass = annotationInterfaceClass; }
/// <summary> /// Default ctor /// </summary> public DelegateInstanceType(XMethodDefinition calledMethod, ClassDefinition instanceDefinition, Dot42.DexLib.MethodDefinition instanceCtor) { this.calledMethod = calledMethod; this.instanceDefinition = instanceDefinition; this.instanceCtor = instanceCtor; }
public void AddClass(ClassDefinition classDef) { Classes.Add(classDef); }
internal void RegisterInnerClass(ClassDefinition owner, ClassDefinition inner) { innerClassesByName.Add(inner.Fullname, inner); inner.RegisterDex(this); RegisterInnerClasses(inner); }
/// <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> /// Is other equal to this? /// </summary> public bool Equals(ClassDefinition other) { // Should be enough (ownership) return(base.Equals(other)); }
/// <summary> /// Create a unique name for the build method that builds an attribute from an annotation interface. /// </summary> private static string CreateBuildMethodName(ClassDefinition owner) { int index = 0; while (true) { string name = "__build" + index++; if (owner.Methods.All(x => x.Name != name)) return name; } }
/// <summary> /// Create a typename for the annotation interface /// </summary> private static string CreateAnnotationTypeName(ClassDefinition owner) { var i = 1; while (true) { string name = owner.Name + "$annotation" + i++; if (owner.InnerClasses.Any(x => x.Name == name)) continue; return name; } }
/// <summary> /// Create an annotation interface. /// </summary> internal static AttributeAnnotationInterface Create( ISourceLocation sequencePoint, AssemblyCompiler compiler, DexTargetPackage targetPackage, TypeDefinition attributeType, ClassDefinition attributeClass) { // Create class ClassDefinition @interface = new ClassDefinition(); @interface.Name = CreateAnnotationTypeName(attributeClass); @interface.Namespace = attributeClass.Namespace; @interface.AccessFlags = AccessFlags.Public | AccessFlags.Abstract | AccessFlags.Interface | AccessFlags.Annotation; @interface.Owner = attributeClass; attributeClass.AddInnerClass(@interface); // Set super class @interface.SuperClass = FrameworkReferences.Object; // Implement Dot42.Internal.IAttribute @interface.Interfaces.Add(new ClassReference("java/lang/annotation/Annotation")); // Prepare result AttributeAnnotationInterface result = new AttributeAnnotationInterface(@interface); // Add methods from IAttribute XModel.XTypeDefinition baseIntfType = compiler.GetDot42InternalType("IAttribute").Resolve(); foreach (XModel.XMethodDefinition imethod in baseIntfType.Methods) { if (imethod.Parameters.Count > 0) throw new CompilerException(string.Format("Invalid IAttribute method {0}", imethod)); string methodName = NameConverter.GetConvertedName(imethod); TypeReference dfieldType = imethod.ReturnType.GetReference(targetPackage); MethodDefinition method = new MethodDefinition(@interface, methodName, new Prototype(dfieldType)); method.AccessFlags = AccessFlags.Public | AccessFlags.Abstract; @interface.Methods.Add(method); } TypeDefinition currentType = attributeType; while (currentType != null && currentType.FullName != typeof(Attribute).FullName) { // Add field mapping foreach (var field in currentType.Fields.Where(x => x.IsReachable && x.IsPublic)) { string methodName = CreateGetMethodName(NameConverter.GetConvertedName(field), result); MethodDefinition method = new MethodDefinition(@interface, methodName, MakePrototype(field.FieldType, targetPackage, compiler.Module)); method.AccessFlags = AccessFlags.Public | AccessFlags.Abstract; result.FieldToGetMethodMap.Add(field, method); @interface.Methods.Add(method); } // Add property mapping foreach (var property in currentType.Properties.Where( x => x.IsReachable && (x.SetMethod != null) && x.SetMethod.IsPublic && x.SetMethod.IsReachable)) { // ignore properties with same name [might be overriden] if (result.PropertyToGetMethodMap.Keys.Any(k => k.Name == property.Name)) continue; string methodName = CreateGetMethodName(NameConverter.GetConvertedName(property), result); Mono.Cecil.TypeReference propType = property.PropertyType; MethodDefinition method = new MethodDefinition(@interface, methodName, MakePrototype(propType, targetPackage, compiler.Module)); method.AccessFlags = AccessFlags.Public | AccessFlags.Abstract; result.PropertyToGetMethodMap.Add(property, method); @interface.Methods.Add(method); } if (currentType.BaseType == null || currentType.BaseType.IsSystemObject()) break; currentType = currentType.BaseType.Resolve(); } // Add ctor mapping var argIndex = 0; foreach (var ctor in attributeType.Methods.Where(x => (x.Name == ".ctor") && x.IsReachable)) { // Add methods for the ctor arguments List<Tuple<MethodDefinition, Mono.Cecil.TypeReference>> paramGetMethods = new List<Tuple<MethodDefinition, Mono.Cecil.TypeReference>>(); foreach (ParameterDefinition p in ctor.Parameters) { string methodName = CreateGetMethodName("c" + argIndex++, result); MethodDefinition method = new MethodDefinition(@interface, methodName, MakePrototype(p.ParameterType, targetPackage, compiler.Module)); method.AccessFlags = AccessFlags.Public | AccessFlags.Abstract; @interface.Methods.Add(method); paramGetMethods.Add(Tuple.Create(method, p.ParameterType)); } // Add a builder method MethodDefinition buildMethod = CreateBuildMethod(sequencePoint, ctor, paramGetMethods, compiler, targetPackage, attributeClass, result); result.CtorMap.Add(ctor, new AttributeCtorMapping(buildMethod, paramGetMethods.Select(p=>p.Item1).ToList())); } // Create default values annotation Annotation defAnnotation = CreateDefaultAnnotation(result); result.AnnotationInterfaceClass.Annotations.Add(defAnnotation); return result; }