コード例 #1
0
ファイル: LockThisIssue.cs プロジェクト: HusterYP/VimConf
            void FixLockThisIssue(Script script, EntityDeclaration containerEntity, TypeDeclaration containerType)
            {
                bool isStatic = IsEntityStatic(containerEntity);

                List <BlockStatement> synchronizedStatements = FixMethodsWithMethodImplAttribute(script, containerType, isStatic).ToList();

                List <AstNode> linkNodes = new List <AstNode>();

                var            locksToModify = LocksToModify(containerType, synchronizedStatements);
                List <AstNode> nodeContexts  = new List <AstNode>(locksToModify);

                foreach (var synchronizedStatement in synchronizedStatements)
                {
                    if (synchronizedStatement.Statements.Count > 0)
                    {
                        nodeContexts.Add(synchronizedStatement.Statements.First());

                        if (!isStatic)
                        {
                            foreach (var childLock in synchronizedStatement.Descendants.OfType <LockStatement>())
                            {
                                if (IsThisReference(childLock.Expression))
                                {
                                    nodeContexts.Add(childLock);
                                }
                            }
                        }
                    }
                }

                string proposedName = GetNameProposal(nodeContexts, "locker");

                if (!isStatic)
                {
                    foreach (var lockToModify in locksToModify)
                    {
                        var identifier = new IdentifierExpression(proposedName);
                        script.Replace(lockToModify.Expression, identifier);

                        linkNodes.Add(identifier);
                    }
                }

                foreach (var synchronizedStatement in synchronizedStatements)
                {
                    if (synchronizedStatement.Statements.Count > 0)
                    {
                        var newBody = synchronizedStatement.Clone();

                        var outerLock           = new LockStatement();
                        var outerLockIdentifier = new IdentifierExpression(proposedName);
                        outerLock.Expression        = outerLockIdentifier;
                        outerLock.EmbeddedStatement = newBody;

                        linkNodes.Add(outerLockIdentifier);

                        if (!isStatic)
                        {
                            foreach (var childLock in newBody.Descendants.OfType <LockStatement>())
                            {
                                if (IsThisReference(childLock.Expression))
                                {
                                    var identifier = new IdentifierExpression(proposedName);
                                    childLock.Expression.ReplaceWith(identifier);

                                    linkNodes.Add(identifier);
                                }
                            }
                        }

                        script.InsertBefore(synchronizedStatement.Statements.First(), outerLock);

                        foreach (var stmt in synchronizedStatement.Statements)
                        {
                            script.Remove(stmt);
                        }
                    }
                }

                if (linkNodes.Any())
                {
                    var objectType = new PrimitiveType("object");

                    var lockerFieldDeclaration = new FieldDeclaration()
                    {
                        Modifiers  = isStatic ? Modifiers.Static : Modifiers.None,
                        ReturnType = objectType.Clone()
                    };

                    var lockerVariable = new VariableInitializer(proposedName, new ObjectCreateExpression(objectType.Clone()));
                    lockerFieldDeclaration.Variables.Add(lockerVariable);
                    script.InsertBefore(containerEntity, lockerFieldDeclaration);

                    linkNodes.Add(lockerVariable.NameToken);

                    script.Link(linkNodes.ToArray());
                }
            }