/// <summary> /// We have a member index like arr.jet[0].muonidnex.Length that has been called. We are called with just the muonidnex. We need to /// do the translation now. /// /// arr.jet[0].muonindex => obj.muonindex[0].Length /// arr.jet.muonindex => obj.muonindex.Length /// /// </summary> /// <param name="memberExpr"></param> /// <param name="attr"></param> /// <returns></returns> private Expression IndexedArrayLengthLookup(MemberExpression memberExpr, IndexToOtherObjectArrayAttribute attr) { /// /// First, we need to find the base class that does the translation for us. /// var classToTranslateTo = TypeUtils.TypeHasAttribute <TranslateToClassAttribute>(attr.BaseType); if (classToTranslateTo == null) { throw new NotImplementedException("Unable to translate '" + memberExpr + "' for an array length because the translation base type '" + attr.BaseType.Name + "' doesn't have a translate class attribute"); } /// /// Now, find, with renames, what the "muonindex" points to, and build access to it from /// a translated root. /// var targetMember = ResolveMemberName(classToTranslateTo.TargetClassType, memberExpr.Member); var root = FindObjectOfType(memberExpr, attr.BaseType); var transRoot = TranslateRootObject(root, classToTranslateTo.TargetClassType); var memberAccess = Expression.MakeMemberAccess(transRoot, targetMember); /// /// See if the "jet" guy has an index on it. /// Expression arrayLength = memberAccess; if (memberExpr.Expression.NodeType == ExpressionType.ArrayIndex) { var oldArrayIndex = memberExpr.Expression as BinaryExpression; arrayLength = Expression.ArrayIndex(arrayLength, oldArrayIndex.Right); if (!arrayLength.Type.IsArray) { throw new NotImplementedException("Unable to translate array length for '" + memberExpr + "' because we saw an index and adding it gave us '" + arrayLength + "' which isn't an array!"); } } arrayLength = Expression.ArrayLength(arrayLength); return(arrayLength); }
/// <summary> /// Given an expression like arr.jet[0].muonindex, which is pointing to obj.muons[obj.jet[0].muonindex], return /// an expression which is obj.muons.Length. /// </summary> /// <param name="memberExpr"></param> /// <param name="attrMemberIsIndex"></param> /// <returns></returns> private Expression TotalLengthOfTargetArray(MemberExpression memberExpr, IndexToOtherObjectArrayAttribute attr) { // Get where we are going, as this will be the basis of what we want here. var classToTranslateTo = TypeUtils.TypeHasAttribute <TranslateToClassAttribute>(attr.BaseType); if (classToTranslateTo == null) { throw new NotImplementedException("Unable to translate '" + memberExpr + "' for an array length because the translation base type '" + attr.BaseType.Name + "' doesn't have a translate class attribute"); } // Get the array we are being redirected to - this is what we have to take the length of. var indexTargetMember = attr.BaseType.GetMember(attr.ArrayName).FirstOrDefault(); if (indexTargetMember == null) { throw new InvalidOperationException(string.Format("Can't find array '{0}' on {1}.", attr.ArrayName, attr.BaseType)); } // Now, build the array up var root = FindObjectOfType(memberExpr, attr.BaseType); var indexTargetAccess = Expression.MakeMemberAccess(root, indexTargetMember); return(VisitExpressionImplemented(Expression.ArrayLength(indexTargetAccess))); }