예제 #1
0
 public override void VisitMemberReferenceExpression(MemberReferenceExpression p)
 {
     // Check to see whether this is on the owner of the ProcessCell method.
     if (p.Target is ThisReferenceExpression)
     {
         // Replace the AST node with the current value.
         var prop = this.Algorithm.GetType().GetProperties().Where(v => v.Name == p.MemberName).DefaultIfEmpty(null).First();
         if (prop == null)
         {
             throw new NotSupportedException("Unable to inline ProcessCell methods that invoke other methods on this algorithm.");
         }
         var value = prop.GetGetMethod().Invoke(this.Algorithm, null);
         if (value is Enum)
         {
             p.ReplaceWith(new PrimitiveExpression(value, value.GetType().FullName.Replace("+", ".") + "." + value));
         }
         else
         {
             p.ReplaceWith(new PrimitiveExpression(value));
         }
     }
     else if (p.Target is IdentifierExpression && (p.Target as IdentifierExpression).Identifier == ParameterContextName)
     {
         // This is a reference to the runtime context, which we replace with this.
         p.Target.ReplaceWith(new ThisReferenceExpression());
     }
 }
예제 #2
0
        /// <summary>
        /// Removes all occurrences of transparent identifiers
        /// </summary>
        void RemoveTransparentIdentifierReferences(AstNode node, Dictionary <string, object> fromOrLetIdentifiers)
        {
            foreach (AstNode child in node.Children)
            {
                RemoveTransparentIdentifierReferences(child, fromOrLetIdentifiers);
            }
            MemberReferenceExpression mre = node as MemberReferenceExpression;

            if (mre != null)
            {
                IdentifierExpression ident = mre.Target as IdentifierExpression;
                if (ident != null && IsTransparentIdentifier(ident.Identifier))
                {
                    IdentifierExpression newIdent = new IdentifierExpression(mre.MemberName);
                    mre.TypeArguments.MoveTo(newIdent.TypeArguments);
                    newIdent.CopyAnnotationsFrom(mre);
                    newIdent.RemoveAnnotations <Semantics.MemberResolveResult>();                    // remove the reference to the property of the anonymous type
                    if (fromOrLetIdentifiers.TryGetValue(mre.MemberName, out var annotation))
                    {
                        newIdent.AddAnnotation(annotation);
                    }
                    mre.ReplaceWith(newIdent);
                    return;
                }
            }
        }
예제 #3
0
        public override bool VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
        {
            bool result = base.VisitMemberReferenceExpression(memberReferenceExpression);
            UnaryOperatorExpression uoe = memberReferenceExpression.Target as UnaryOperatorExpression;

            if (uoe != null && uoe.Operator == UnaryOperatorType.Dereference)
            {
                PointerReferenceExpression pre = new PointerReferenceExpression();
                pre.Target     = uoe.Expression.Detach();
                pre.MemberName = memberReferenceExpression.MemberName;
                memberReferenceExpression.TypeArguments.MoveTo(pre.TypeArguments);
                pre.CopyAnnotationsFrom(uoe);
                pre.RemoveAnnotations <ResolveResult>();                // only copy the ResolveResult from the MRE
                pre.CopyAnnotationsFrom(memberReferenceExpression);
                memberReferenceExpression.ReplaceWith(pre);
            }
            var rr = memberReferenceExpression.GetResolveResult();

            if (rr != null)
            {
                if (IsUnsafeType(rr.Type))
                {
                    return(true);
                }
            }

            return(result);
        }
예제 #4
0
		public override bool VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
		{
			bool result = base.VisitMemberReferenceExpression(memberReferenceExpression);
			UnaryOperatorExpression uoe = memberReferenceExpression.Target as UnaryOperatorExpression;
			if (uoe != null && uoe.Operator == UnaryOperatorType.Dereference) {
				PointerReferenceExpression pre = new PointerReferenceExpression();
				pre.Target = uoe.Expression.Detach();
				pre.MemberName = memberReferenceExpression.MemberName;
				memberReferenceExpression.TypeArguments.MoveTo(pre.TypeArguments);
				pre.CopyAnnotationsFrom(uoe);
				pre.RemoveAnnotations<ResolveResult>(); // only copy the ResolveResult from the MRE
				pre.CopyAnnotationsFrom(memberReferenceExpression);
				memberReferenceExpression.ReplaceWith(pre);
			}
			var rr = memberReferenceExpression.GetResolveResult();
			if (rr != null) {
				if (rr.Type is PointerType)
					return true;
				if (rr is MemberResolveResult mrr && mrr.Member.ReturnType.Kind == TypeKind.Delegate) {
					var method = mrr.Member.ReturnType.GetDefinition()?.GetDelegateInvokeMethod();
					if (method != null && (method.ReturnType is PointerType || method.Parameters.Any(p => p.Type is PointerType)))
						return true;
				}
			}

			return result;
		}
예제 #5
0
        public override bool VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
        {
            bool result = base.VisitMemberReferenceExpression(memberReferenceExpression, data);
            UnaryOperatorExpression uoe = memberReferenceExpression.Target as UnaryOperatorExpression;

            if (uoe != null && uoe.Operator == UnaryOperatorType.Dereference)
            {
                PointerReferenceExpression pre = new PointerReferenceExpression();
                pre.Target     = uoe.Expression.Detach();
                pre.MemberName = memberReferenceExpression.MemberName;
                memberReferenceExpression.TypeArguments.MoveTo(pre.TypeArguments);
                pre.CopyAnnotationsFrom(uoe);
                pre.CopyAnnotationsFrom(memberReferenceExpression);
                memberReferenceExpression.ReplaceWith(pre);
            }
            return(result);
        }
예제 #6
0
            /// <summary>
            /// Removes all occurrences of transparent identifiers
            /// </summary>
            void RemoveTransparentIdentifierReferences(AstNode node)
            {
                foreach (AstNode child in node.Children)
                {
                    RemoveTransparentIdentifierReferences(child);
                }
                MemberReferenceExpression mre = node as MemberReferenceExpression;

                if (mre != null)
                {
                    IdentifierExpression ident = mre.Target as IdentifierExpression;
                    if (ident != null && IsTransparentIdentifier(ident.Identifier))
                    {
                        IdentifierExpression newIdent = new IdentifierExpression(mre.MemberName);
                        mre.TypeArguments.MoveTo(newIdent.TypeArguments);
                        mre.ReplaceWith(newIdent);
                        return;
                    }
                }
            }
예제 #7
0
        /// <summary>
        /// Removes all occurrences of transparent identifiers
        /// </summary>
        void RemoveTransparentIdentifierReferences(AstNode node)
        {
            foreach (AstNode child in node.Children)
            {
                RemoveTransparentIdentifierReferences(child);
            }
            MemberReferenceExpression mre = node as MemberReferenceExpression;

            if (mre != null)
            {
                IdentifierExpression ident = mre.Target as IdentifierExpression;
                if (ident != null && IsTransparentIdentifier(ident.Identifier))
                {
                    IdentifierExpression newIdent = new IdentifierExpression(mre.MemberName);
                    mre.TypeArguments.MoveTo(newIdent.TypeArguments);
                    newIdent.CopyAnnotationsFrom(mre);
                    newIdent.RemoveAnnotations <PropertyDeclaration>();                    // remove the reference to the property of the anonymous type
                    mre.ReplaceWith(newIdent);
                    return;
                }
            }
        }
예제 #8
0
        public override object VisitBlockStatement(BlockStatement blockStatement, object data)
        {
            int numberOfVariablesOutsideBlock = currentlyUsedVariableNames.Count;

            base.VisitBlockStatement(blockStatement, data);
            foreach (ExpressionStatement stmt in blockStatement.Statements.OfType <ExpressionStatement>().ToArray())
            {
                Match displayClassAssignmentMatch = displayClassAssignmentPattern.Match(stmt);
                if (!displayClassAssignmentMatch.Success)
                {
                    continue;
                }

                ILVariable variable = displayClassAssignmentMatch.Get <AstNode>("variable").Single().Annotation <ILVariable>();
                if (variable == null)
                {
                    continue;
                }
                TypeDefinition type = variable.Type.ResolveWithinSameModule();
                if (!IsPotentialClosure(context, type))
                {
                    continue;
                }
                if (displayClassAssignmentMatch.Get <AstType>("type").Single().Annotation <TypeReference>().ResolveWithinSameModule() != type)
                {
                    continue;
                }

                // Looks like we found a display class creation. Now let's verify that the variable is used only for field accesses:
                bool ok = true;
                foreach (var identExpr in blockStatement.Descendants.OfType <IdentifierExpression>())
                {
                    if (identExpr.Identifier == variable.Name && identExpr != displayClassAssignmentMatch.Get("variable").Single())
                    {
                        //check if it a cross reference to another generated delegate class's member
                        if (identExpr.Parent is AssignmentExpression)
                        {
                            if ((identExpr.Parent as AssignmentExpression).Left is MemberReferenceExpression
                                )
                            {
                                MemberReferenceExpression tleft = (MemberReferenceExpression)(identExpr.Parent as AssignmentExpression).Left;
                                ILVariable v = tleft.Target.Annotation <ILVariable>();
                                if (v != null)
                                {
                                    TypeDefinition vtype = v.Type.ResolveWithinSameModule();


                                    if (vtype.IsNested && IsPotentialClosure(context, vtype))
                                    {
                                        Console.WriteLine(identExpr.Parent.ToString() + " cross reference by delegate  should be ok");
                                        continue;
                                    }
                                }
                            }
                        }
                        if (!(identExpr.Parent is MemberReferenceExpression && identExpr.Parent.Annotation <FieldReference>() != null))
                        {
                            ok = false;
                            break;
                        }
                    }
                }
                if (!ok)
                {
                    continue;
                }
                Dictionary <FieldReference, AstNode> dict = new Dictionary <FieldReference, AstNode>();

                // Delete the variable declaration statement:
                VariableDeclarationStatement displayClassVarDecl = PatternStatementTransform.FindVariableDeclaration(stmt, variable.Name);
                if (displayClassVarDecl != null)
                {
                    displayClassVarDecl.Remove();
                }

                // Delete the assignment statement:
                AstNode cur = stmt.NextSibling;
                stmt.Remove();

                // Delete any following statements as long as they assign parameters to the display class
                BlockStatement    rootBlock            = blockStatement.Ancestors.OfType <BlockStatement>().LastOrDefault() ?? blockStatement;
                List <ILVariable> parameterOccurrances = rootBlock.Descendants.OfType <IdentifierExpression>()
                                                         .Select(n => n.Annotation <ILVariable>()).Where(p => p != null && p.IsParameter).ToList();
                AstNode next;
                for (; cur != null; cur = next)
                {
                    next = cur.NextSibling;

                    // Test for the pattern:
                    // "variableName.MemberName = right;"
                    ExpressionStatement closureFieldAssignmentPattern = new ExpressionStatement(
                        new AssignmentExpression(
                            new NamedNode("left", new MemberReferenceExpression {
                        Target     = new IdentifierExpression(variable.Name),
                        MemberName = Pattern.AnyString
                    }),
                            new AnyNode("right")
                            )
                        );
                    Match m = closureFieldAssignmentPattern.Match(cur);
                    if (m.Success)
                    {
                        FieldDefinition fieldDef    = m.Get <MemberReferenceExpression>("left").Single().Annotation <FieldReference>().ResolveWithinSameModule();
                        AstNode         right       = m.Get <AstNode>("right").Single();
                        bool            isParameter = false;
                        bool            isDisplayClassParentPointerAssignment = false;
                        if (right is ThisReferenceExpression)
                        {
                            isParameter = true;
                        }
                        else if (right is IdentifierExpression)
                        {
                            // handle parameters only if the whole method contains no other occurrence except for 'right'
                            ILVariable v = right.Annotation <ILVariable>();
                            isParameter = v.IsParameter && parameterOccurrances.Count(c => c == v) == 1;
                            if (!isParameter && IsPotentialClosure(context, v.Type.ResolveWithinSameModule()))
                            {
                                // parent display class within the same method
                                // (closure2.localsX = closure1;)
                                isDisplayClassParentPointerAssignment = true;
                            }
                        }
                        else if (right is MemberReferenceExpression)
                        {
                            // copy of parent display class reference from an outer lambda
                            // closure2.localsX = this.localsY
                            MemberReferenceExpression mre = m.Get <MemberReferenceExpression>("right").Single();
                            do
                            {
                                // descend into the targets of the mre as long as the field types are closures
                                FieldDefinition fieldDef2 = mre.Annotation <FieldReference>().ResolveWithinSameModule();
                                if (fieldDef2 == null || !IsPotentialClosure(context, fieldDef2.FieldType.ResolveWithinSameModule()))
                                {
                                    break;
                                }
                                // if we finally get to a this reference, it's copying a display class parent pointer
                                if (mre.Target is ThisReferenceExpression)
                                {
                                    isDisplayClassParentPointerAssignment = true;
                                }
                                mre = mre.Target as MemberReferenceExpression;
                            } while (mre != null);
                        }
                        if (isParameter || isDisplayClassParentPointerAssignment)
                        {
                            dict[fieldDef] = right;
                            cur.Remove();
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        //why need to break? continue to match should be ok
                        //break;
                    }
                }

                // Now create variables for all fields of the display class (except for those that we already handled as parameters)
                List <Tuple <AstType, ILVariable> > variablesToDeclare = new List <Tuple <AstType, ILVariable> >();
                foreach (FieldDefinition field in type.Fields)
                {
                    if (field.IsStatic)
                    {
                        continue;                         // skip static fields
                    }
                    if (dict.ContainsKey(field))          // skip field if it already was handled as parameter
                    {
                        continue;
                    }
                    string capturedVariableName = field.Name;
                    if (capturedVariableName.StartsWith("$VB$Local_", StringComparison.Ordinal) && capturedVariableName.Length > 10)
                    {
                        capturedVariableName = capturedVariableName.Substring(10);
                    }
                    EnsureVariableNameIsAvailable(blockStatement, capturedVariableName);
                    currentlyUsedVariableNames.Add(capturedVariableName);
                    ILVariable ilVar = new ILVariable
                    {
                        IsGenerated = true,
                        Name        = capturedVariableName,
                        Type        = field.FieldType,
                    };
                    variablesToDeclare.Add(Tuple.Create(AstBuilder.ConvertType(field.FieldType, field), ilVar));
                    dict[field] = new IdentifierExpression(capturedVariableName).WithAnnotation(ilVar);
                }

                // Now figure out where the closure was accessed and use the simpler replacement expression there:
                foreach (var identExpr in blockStatement.Descendants.OfType <IdentifierExpression>())
                {
                    if (identExpr.Identifier == variable.Name)
                    {
                        if (!(identExpr.Parent is MemberReferenceExpression))
                        {
                            //will delete by the next round of the cross reference delegate class
                            continue;
                        }
                        MemberReferenceExpression mre = (MemberReferenceExpression)identExpr.Parent;
                        AstNode replacement;
                        if (dict.TryGetValue(mre.Annotation <FieldReference>().ResolveWithinSameModule(), out replacement))
                        {
                            mre.ReplaceWith(replacement.Clone());
                        }
                    }
                }
                // Now insert the variable declarations (we can do this after the replacements only so that the scope detection works):
                Statement insertionPoint = blockStatement.Statements.FirstOrDefault();
                foreach (var tuple in variablesToDeclare)
                {
                    var newVarDecl = new VariableDeclarationStatement(tuple.Item1, tuple.Item2.Name);
                    newVarDecl.Variables.Single().AddAnnotation(new CapturedVariableAnnotation());
                    newVarDecl.Variables.Single().AddAnnotation(tuple.Item2);
                    blockStatement.Statements.InsertBefore(insertionPoint, newVarDecl);
                }
            }
            currentlyUsedVariableNames.RemoveRange(numberOfVariablesOutsideBlock, currentlyUsedVariableNames.Count - numberOfVariablesOutsideBlock);
            return(null);
        }
예제 #9
0
        void RunAction(RefactoringContext context, AstType baseType, string enumName, Dictionary <string, string> newNames, TypeDeclaration containerTypeDeclaration, List <VariableInitializer> variables, Script script)
        {
            var names         = variables.Select(variable => variable.Name).ToList();
            var containerType = (context.Resolve(containerTypeDeclaration) as TypeResolveResult).Type;

            var fields = containerTypeDeclaration.Members.OfType <FieldDeclaration>().Where(field => field.Modifiers.HasFlag(Modifiers.Const)).ToList();
            List <VariableInitializer> variableUnitsToRemove = new List <VariableInitializer>(variables);
            List <FieldDeclaration>    fieldsToRemove        = new List <FieldDeclaration>();

            foreach (var field in fields)
            {
                if (field.Variables.All(variableUnitsToRemove.Contains))
                {
                    fieldsToRemove.Add(field);

                    variableUnitsToRemove.RemoveAll(field.Variables.Contains);
                }
            }

            var generatedEnum = CreateEnumDeclaration(baseType, enumName, variables, names, newNames);

            AstNode root    = GetRootNodeOf(containerTypeDeclaration);
            var     newRoot = root.Clone();

            FixIdentifiers(context, enumName, variables, containerType, baseType, names, newNames, root, newRoot);
            foreach (var member in root.Descendants.OfType <MemberReferenceExpression>().Where(member => names.Contains(member.MemberName)))
            {
                if (variables.Any(variable => variable.Descendants.Contains(member)))
                {
                    //Already handled
                    continue;
                }

                var resolvedIdentifier = context.Resolve(member) as MemberResolveResult;
                if (resolvedIdentifier == null)
                {
                    continue;
                }

                if (resolvedIdentifier.Type.Equals(containerType))
                {
                    continue;
                }

                var equivalentMember = GetEquivalentNodeFor(root, newRoot, member);
                MemberReferenceExpression memberToReplace = (MemberReferenceExpression)equivalentMember;

                var replacement = CreateReplacementMemberReference(enumName, baseType, newNames, memberToReplace);
                memberToReplace.ReplaceWith(replacement);
            }

            //Fix the file
            InsertAfterEquivalent(root, newRoot, containerTypeDeclaration.LBraceToken, generatedEnum, Roles.TypeMemberRole);

            foreach (var variableToRemove in variableUnitsToRemove)
            {
                GetEquivalentNodeFor(root, newRoot, variableToRemove).Remove();
            }
            foreach (var fieldToRemove in fieldsToRemove)
            {
                GetEquivalentNodeFor(root, newRoot, fieldToRemove).Remove();
            }

            script.Replace(root, newRoot);

            ReplaceVariableReferences(context, root, baseType, enumName, script, newNames, variables);
        }
예제 #10
0
            public override void VisitMemberReferenceExpression(MemberReferenceExpression p)
            {
                base.VisitMemberReferenceExpression(p);

                // Check to see whether this is on the owner of the ProcessCell method.
                if (p.Target is ThisReferenceExpression)
                {
                    // Replace the AST node with the current value.
                    var field = this.Algorithm.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                        .Where(v => v.Name == p.MemberName).DefaultIfEmpty(null).First();
                    var prop =
                        this.Algorithm.GetType()
                            .GetProperties()
                            .Where(v => v.Name == p.MemberName)
                            .DefaultIfEmpty(null)
                            .First();
                    if (prop == null && field == null)
                        throw new NotSupportedException(
                            "Unable to inline ProcessCell methods that invoke other methods on this algorithm.");
                    if (field != null)
                        return;
                    var value = prop.GetGetMethod().Invoke(this.Algorithm, null);
                    if (value is Enum)
                        p.ReplaceWith(new PrimitiveExpression(value,
                            value.GetType().FullName.Replace("+", ".") + "." + value));
                    else
                        p.ReplaceWith(new PrimitiveExpression(value));
                }
                else if (p.Target is IdentifierExpression &&
                         (p.Target as IdentifierExpression).Identifier == ParameterContextName)
                {
                    // This is a reference to the runtime context, which we replace with this.
                    p.Target.ReplaceWith(new ThisReferenceExpression());
                }
            }
예제 #11
0
            public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
            {
                if (this.m_Mappings.ContainsKey(memberReferenceExpression.MemberName))
                {
                    if (memberReferenceExpression.Target is ThisReferenceExpression)
                    {
                        memberReferenceExpression.ReplaceWith(
                            new IdentifierExpression(
                                this.m_Mappings[memberReferenceExpression.MemberName]));
                        return;
                    }
                }

                base.VisitMemberReferenceExpression(memberReferenceExpression);
            }
예제 #12
0
        public override object VisitBlockStatement(BlockStatement blockStatement, object data)
        {
            base.VisitBlockStatement(blockStatement, data);
            foreach (ExpressionStatement stmt in blockStatement.Statements.OfType <ExpressionStatement>().ToArray())
            {
                Match displayClassAssignmentMatch = displayClassAssignmentPattern.Match(stmt);
                if (displayClassAssignmentMatch == null)
                {
                    continue;
                }

                ILVariable variable = displayClassAssignmentMatch.Get("variable").Single().Annotation <ILVariable>();
                if (variable == null)
                {
                    continue;
                }
                TypeDefinition type = variable.Type.ResolveWithinSameModule();
                if (!IsPotentialClosure(context, type))
                {
                    continue;
                }
                if (displayClassAssignmentMatch.Get("type").Single().Annotation <TypeReference>().ResolveWithinSameModule() != type)
                {
                    continue;
                }

                // Looks like we found a display class creation. Now let's verify that the variable is used only for field accesses:
                bool ok = true;
                foreach (var identExpr in blockStatement.Descendants.OfType <IdentifierExpression>())
                {
                    if (identExpr.Identifier == variable.Name && identExpr != displayClassAssignmentMatch.Get("variable").Single())
                    {
                        if (!(identExpr.Parent is MemberReferenceExpression && identExpr.Parent.Annotation <FieldReference>() != null))
                        {
                            ok = false;
                        }
                    }
                }
                if (!ok)
                {
                    continue;
                }
                Dictionary <FieldReference, AstNode> dict = new Dictionary <FieldReference, AstNode>();
                // Delete the variable declaration statement:
                AstNode cur = stmt.NextSibling;
                stmt.Remove();
                if (blockStatement.Parent.NodeType == NodeType.Member || blockStatement.Parent is Accessor)
                {
                    // Delete any following statements as long as they assign parameters to the display class
                    // Do parameter handling only for closures created in the top scope (direct child of method/accessor)
                    List <ILVariable> parameterOccurrances = blockStatement.Descendants.OfType <IdentifierExpression>()
                                                             .Select(n => n.Annotation <ILVariable>()).Where(p => p != null && p.IsParameter).ToList();
                    AstNode next;
                    for (; cur != null; cur = next)
                    {
                        next = cur.NextSibling;

                        // Test for the pattern:
                        // "variableName.MemberName = right;"
                        ExpressionStatement closureFieldAssignmentPattern = new ExpressionStatement(
                            new AssignmentExpression(
                                new NamedNode("left", new MemberReferenceExpression {
                            Target = new IdentifierExpression(variable.Name)
                        }),
                                new AnyNode("right")
                                )
                            );
                        Match m = closureFieldAssignmentPattern.Match(cur);
                        if (m != null)
                        {
                            AstNode right       = m.Get("right").Single();
                            bool    isParameter = false;
                            if (right is ThisReferenceExpression)
                            {
                                isParameter = true;
                            }
                            else if (right is IdentifierExpression)
                            {
                                // handle parameters only if the whole method contains no other occurrance except for 'right'
                                ILVariable param = right.Annotation <ILVariable>();
                                isParameter = param.IsParameter && parameterOccurrances.Count(c => c == param) == 1;
                            }
                            if (isParameter)
                            {
                                dict[m.Get <MemberReferenceExpression>("left").Single().Annotation <FieldReference>().ResolveWithinSameModule()] = right;
                                cur.Remove();
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                // Now create variables for all fields of the display class (except for those that we already handled as parameters)
                List <Tuple <AstType, string> > variablesToDeclare = new List <Tuple <AstType, string> >();
                foreach (FieldDefinition field in type.Fields)
                {
                    if (dict.ContainsKey(field))
                    {
                        continue;
                    }
                    variablesToDeclare.Add(Tuple.Create(AstBuilder.ConvertType(field.FieldType, field), field.Name));
                    dict[field] = new IdentifierExpression(field.Name);
                }

                // Now figure out where the closure was accessed and use the simpler replacement expression there:
                foreach (var identExpr in blockStatement.Descendants.OfType <IdentifierExpression>())
                {
                    if (identExpr.Identifier == variable.Name)
                    {
                        MemberReferenceExpression mre = (MemberReferenceExpression)identExpr.Parent;
                        AstNode replacement;
                        if (dict.TryGetValue(mre.Annotation <FieldReference>().ResolveWithinSameModule(), out replacement))
                        {
                            mre.ReplaceWith(replacement.Clone());
                        }
                    }
                }
                // Now insert the variable declarations (we can do this after the replacements only so that the scope detection works):
                Statement insertionPoint = blockStatement.Statements.FirstOrDefault();
                foreach (var tuple in variablesToDeclare)
                {
                    var newVarDecl = new VariableDeclarationStatement(tuple.Item1, tuple.Item2);
                    newVarDecl.Variables.Single().AddAnnotation(new CapturedVariableAnnotation());
                    blockStatement.Statements.InsertBefore(insertionPoint, newVarDecl);
                }
            }
            return(null);
        }
예제 #13
0
        public override void VisitMemberReferenceExpression(MemberReferenceExpression e)
        {
            var md = e.Annotation<MethodDefinition>();
            if (md != null && md.IsPrivate && md.IsCompilerGenerated())
            {
                //public override void OnMasterMouseLeave(ModifierMouseArgs e)
                //{
                //    this.TB(ModifierGroup.YB, e);
                //}
                //
                //[CompilerGenerated]
                //private static void YB(IChartModifier x, ModifierEventArgsBase y)
                //{
                //    x.OnMasterMouseLeave((ModifierMouseArgs)y);
                //}
                //
                //====>
                //public override void OnMasterMouseLeave(ModifierMouseArgs e)
                //{
                //    this.TB((x, y) => x.OnMasterMouseLeave((ModifierMouseArgs)y), e);
                //}
                var td = e.Ancestors.OfType<TypeDeclaration>().FirstOrDefault();
                if (td != null)
                {
                    var method = td.Members.OfType<MethodDeclaration>().FirstOrDefault(x => x.Annotation<MethodDefinition>() == md);
                    if (method != null)
                    {
                        LambdaExpression le = new LambdaExpression();
                        var body = method.Body;
                        if (body.Statements.Count == 1)
                        {
                            le.Body = TryReduceLambdaBody(body.Statements.First()).Detach();
                        }
                        else
                        {
                            le.Body = body.Detach();
                        }

                        // 设置 Lambda 函数参数
                        if (method.Parameters.Count > 0)
                        {
                            var prmNames = new[] { "x", "y", "z", "u", "v", "w", "m", "n", "p", "q", "r", "s", "t" };
                            var usedNames = new HashSet<string>(body.Descendants.OfType<IdentifierExpression>().Select(x => x.Identifier).Distinct());
                            var index = 0;
                            foreach (var x in method.Parameters)
                            {
                                var pn = index < prmNames.Length ? prmNames[index] : "e" + index.ToString();
                                index++;
                                while (usedNames.Contains(pn))
                                {
                                    pn = index < prmNames.Length ? prmNames[index] : "e" + index.ToString();
                                    index++;
                                }
                                foreach (var r in le.Body.Descendants.OfType<IdentifierExpression>().Where(r => r.Identifier == x.Name))
                                {
                                    r.Identifier = pn;
                                }
                                le.Parameters.Add(new ParameterDeclaration(pn));
                            }
                        }

                        DelayRemove(method);
                        e.ReplaceWith(le);
                    }
                }
            }
            base.VisitMemberReferenceExpression(e);
        }