public override void ProcessAnnotation(AnnotatedItem item) { if (item.ManagedInfo.Type.Name == null) { return; } foreach (var a in item.Annotations) { if (a.Values == null || a.Name != "RequiresPermission") { continue; } for (int i = 0; i < a.Values.Count; i++) { var v = a.Values [i]; if (v.Name != "value") { continue; } var ext = item.GetExtension <RequiresPermissionExtension> (); if (ext == null) { ext = new RequiresPermissionExtension(); item.SetExtension(ext); } // value is quoted by "", so chop them out. string val = v.Val.Substring(1, v.Val.Length - 2); if (!ext.Values.Contains(val)) { ext.Values.Add(val); } } } }
public static string FormatMember(this AnnotatedItem a) { return(string.Format(" [{0}] {1} {2} {3}", a.Arguments == null ? "F" : a.ParameterIndex >= 0 ? ("P" + a.ParameterIndex) : a.MemberName == "#ctor" ? "C" : "M", a.MemberType, a.MemberName, a.Arguments == null ? null : "(" + string.Join(", ", a.Arguments) + ")")); }
static bool IsProperty(AnnotatedItem item, string propertyName) { if (item.Arguments == null) { return(false); } return(item.ManagedInfo.MemberName == "get_" + propertyName && item.Arguments.Length == 0 || item.ManagedInfo.MemberName == "set_" + propertyName && item.Arguments.Length == 1); }
public override IMethodBase GetMethod(IType iType, AnnotatedItem item) { var t = iType.Value(); var list = t.GetMethods().Where(m => item.MemberName == "#ctor" ? m is Ctor : m is Method); var methods = list.Where(m => (item.MemberName == "#ctor" && m is Ctor || m is Method && ((Method)m).JavaName == item.MemberName) && m.Parameters.Count == item.Arguments.Length) .ToArray(); var argTypeLists = methods.Select(m => new { Method = m, Jni = m is Ctor ? ((Ctor)m).JniSignature : ((Method)m).JniSignature }) .Select(p => new { Method = p.Method, Arguments = p.Jni == null ? null : ParseJniMethodArgumentsSignature(p.Jni) }) .ToArray(); // this .Replace() is needed so that T[] can match generic arguments Func <string, string> stripParamSuffix = s => s.Replace("...", "").Replace("[]", ""); Func <string, string> stripGenParams = s => s == null ? s : (s.Contains('<') ? s.Substring(0, s.IndexOf('<')) : s).Replace("...", "[]"); Func <string, string, bool> cmp = (v, w) => stripGenParams(v) == stripGenParams(w); for (int i = 0; i < argTypeLists.Length; i++) { var argTypeListPair = argTypeLists [i]; var argTypeList = argTypeListPair.Arguments; if (argTypeList == null || item.Arguments.Length != argTypeList.Length) { continue; } bool mismatch = false; for (int a = 0; a < argTypeList.Length; a++) { if (cmp(argTypeList [a], item.Arguments [a]) || t.TypeParameters != null && t.TypeParameters.Any(ga => cmp(ga.Name, stripParamSuffix(item.Arguments [a]))) || argTypeListPair.Method.GenericArguments != null && argTypeListPair.Method.GenericArguments.Any(ga => cmp(ga.Name, stripParamSuffix(item.Arguments [a])))) { continue; } mismatch = true; break; } if (mismatch) { continue; } return(methods [i].Wrap()); } Errors.Add("warning: method overload not found: " + t.FullName + " member: " + item.FormatMember()); return(null); }
protected string GetTargetManagedTypeName(AnnotatedItem item) { var contextType = _.GetContextManagedType(item.TypeName); var contextField = item.Arguments == null?_.GetAnnotatedField(contextType, item.MemberName) : null; if (item.Arguments == null) { return(contextField == null ? null :_.GetFieldManagedTypeName(contextField)); } var contextMethod = item.Arguments == null ? null : _.GetMethod(contextType, item); if (contextMethod != null) { return(item.ParameterIndex < 0 ? _.GetMethodReturnManagedTypeName(contextMethod) : _.GetParameterManagedTypeName(contextMethod, item.ParameterIndex)); } return(null); }
public override void ProcessAnnotation(AnnotatedItem item) { if (item.ManagedInfo.Type.Name == null) { return; } foreach (var a in item.Annotations) { if (a.Values == null || a.Name.Contains('.') || !a.Name.EndsWith("Def", StringComparison.Ordinal)) { continue; } for (int i = 0; i < a.Values.Count; i++) { var v = a.Values [i]; if (v.Name != "value") { continue; } ProcessAnnotationValue(item, a, v); } } }
public abstract IMethodBase GetMethod(IType t, AnnotatedItem item);
void ProcessAnnotationValue(AnnotatedItem item, AnnotationData a, AnnotationValue v) { var x = new ConstantDefinitionExtension(); x.ConstantKind = a.Name == "IntDef" ? ConstantKind.IntDef : a.Name == "StringDef" ? ConstantKind.StringDef : ConstantKind.Other; x.TargetManagedTypeName = GetTargetManagedTypeName(item); x.Flag = a.Values.Any(_ => _.Name == "flag"); a.SetExtension(x); x.ManagedConstants = v.ValueAsArray.Select(s => new ManagedMemberInfo()).ToArray(); if (v.ArrayItemCommonPrefix != null) { // Most of the *Def values share the same type as the const fields' declaring type. var vManagedType = _.GetContextManagedType(v.ArrayItemCommonPrefix); if (vManagedType == null) { _.Errors.Add(string.Format("Managed type for '{0}' specified in the annotation '{1}' on '{2}' was not found", v.ArrayItemCommonPrefix, a.Name, item.Name)); } else { var missingConsts = new List <string> (); for (int c = 0; c < x.ManagedConstants.Count; c++) { var m = x.ManagedConstants [c]; var mf = _.GetDefinitionField(vManagedType, v.ValueAsArray [c]); if (mf == null) { // it is most likely removed constants due to enumification. missingConsts.Add(v.ValueAsArray [c]); } else { _.SetName(m, vManagedType); m.MemberName = _.GetDefinitionName(mf); } } if (missingConsts.Count != 0 && /*x.ManagedConstants.Count != missingConsts.Count*/ !x.IsTargetAlreadyEnumified) { _.Errors.Add(string.Format("Warning: For '{0}', managed constants are partially missing in {1}: {2}", item.Name, v.ArrayItemCommonPrefix, string.Join(", ", missingConsts))); } } } else { // Sometimes (namely "PendingIntent flags") have different declaring types and // in that case this lookup is somewhat complicated - we find the "type name . field name" matches. // As of XA 5.3, nothing should matter - the only pattern that falls here is about // wherever PendingIntentFlags apply. for (int c = 0; c < v.ValueAsArray.Count; c++) { var javaConst = v.ValueAsArray [c]; var candidate = _.ContextTypes.Keys.Where(j => !string.IsNullOrEmpty(j) && (javaConst.StartsWith(j, StringComparison.Ordinal))) .Select(j => _.GetContextManagedType(j)) .Select(mn => new { Type = mn, Field = _.GetFields(mn).FirstOrDefault(f => javaConst.EndsWith("." + _.GetJavaName(f), StringComparison.Ordinal)) }) .FirstOrDefault(z => z.Field != null); if (candidate == null) { continue; } var m = x.ManagedConstants [c]; _.SetName(m, candidate.Type); m.MemberName = _.GetDefinitionName(candidate.Field); break; } } }
public abstract void ProcessAnnotation(AnnotatedItem item);
public override IMethodBase GetMethod(IType iType, AnnotatedItem item) { var t = iType.Value(); Func <ICustomAttributeProvider, string> getRegisterAttName = type => { var ca = getRegisterAtt(type); return(ca == null ? null : ca.ConstructorArguments [0].Value as string); }; Func <ICustomAttributeProvider, string> getRegisterAttJni = type => { var ca = getRegisterAtt(type); return(ca == null ? null : ca.ConstructorArguments [1].Value as string); }; var methods = t.GetMethods() .Where(m => (item.MemberName == "#ctor" && m.IsConstructor || getRegisterAttName(m) == item.MemberName) && m.Parameters.Count == item.Arguments.Length) .ToArray(); // First, try loose match just by checking argument count. MethodDefinition candidate = null; bool overloaded = false; foreach (var m in methods) { if (overloaded) { break; } if (candidate != null) { overloaded = true; break; } else { candidate = m; } } if (!overloaded) { if (candidate == null) { Errors.Add("warning: method with matching argument count not found: " + t + " member: " + item.FormatMember()); } return(candidate.Wrap()); } // Second, try strict match. Func <ICustomAttributeProvider, string []> getJavaGenTypesValue = td => { var a = getJavaTypesAtt(td); var arr = a == null ? new string [0] : ((CustomAttributeArgument [])a.ConstructorArguments [0].Value).Select(ca => ca.Value as string); return(arr.Select(s => s.Contains(' ') ? s.Substring(0, s.IndexOf(' ')) : s).ToArray()); }; var typeGenArgs = t.GetSelfAndAncestors().SelectMany(getJavaGenTypesValue).ToArray(); var argTypeLists = methods.Select(m => new { Method = m, Jni = getRegisterAttJni(m) }) .Select(p => new { Method = p.Method, Arguments = p.Jni == null ? null : ParseJniMethodArgumentsSignature(p.Jni) }) .ToArray(); for (int i = 0; i < argTypeLists.Length; i++) { var argTypeListPair = argTypeLists [i]; var argTypeList = argTypeListPair.Arguments; var methodGenArgs = getJavaGenTypesValue(argTypeListPair.Method); if (!AreArgumentsEqualLax(argTypeList, item.Arguments, typeGenArgs.Concat(methodGenArgs))) { continue; } return(methods [i].Wrap()); } Errors.Add("warning: method overload not found: " + t + " member: " + item.FormatMember()); return(null); }