public InsertBefore ( AstNode node, AstNode newNode ) : void | ||
node | AstNode | |
newNode | AstNode | |
return | void |
void ResolveIssue(Script s, AstNode node, Func <TypeSystemAstBuilder, AstType> type, string methodCall) { var rr = ctx.Resolve(node) as LocalResolveResult; if (rr == null || rr.IsError) { return; } var refs = ctx.FindReferences(ctx.RootNode, rr.Variable); var nodes = refs.Select(r => r.Node).Where(IsEnumeration).OfType <Expression>().ToList(); if (nodes.Count == 0) { return; } var first = nodes.First().GetParent <Statement>(); var varName = ctx.GetNameProposal("enumerable", first.StartLocation); var astBuilder = ctx.CreateTypeSystemAstBuilder(first); var links = new List <AstNode>(); var varDec = new VariableDeclarationStatement(new PrimitiveType("var"), varName, new BinaryOperatorExpression(new AsExpression((Expression)node.Clone(), type(astBuilder)), BinaryOperatorType.NullCoalescing, new InvocationExpression(new MemberReferenceExpression((Expression)node.Clone(), methodCall)))); links.Add(varDec.Variables.First().NameToken); s.InsertBefore(first, varDec); foreach (var n in nodes) { var id = new IdentifierExpression(varName); links.Add(id); s.Replace(n, id); } s.Link(links); }
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()); } }
/// <summary> /// Inserts 'newUsing' in the current scope. /// This method will try to insert new usings in the correct position (depending on /// where the existing usings are; and maintaining the sort order). /// </summary> public static void InsertUsing(RefactoringContext context, Script script, AstNode newUsing) { UsingInfo newUsingInfo = new UsingInfo(newUsing, context); AstNode enclosingNamespace = context.GetNode <NamespaceDeclaration>() ?? context.RootNode; // Find nearest enclosing parent that has usings: AstNode usingParent = enclosingNamespace; while (usingParent != null && !usingParent.Children.OfType <UsingDeclaration>().Any()) { usingParent = usingParent.Parent; } if (usingParent == null) { // No existing usings at all -> use the default location if (script.FormattingOptions.UsingPlacement == UsingPlacement.TopOfFile) { usingParent = context.RootNode; } else { usingParent = enclosingNamespace; } } // Find the main block of using declarations in the chosen scope: AstNode blockStart = usingParent.Children.FirstOrDefault(IsUsingDeclaration); AstNode insertionPoint; bool insertAfter = false; if (blockStart == null) { // no using declarations in the file Debug.Assert(SyntaxTree.MemberRole == NamespaceDeclaration.MemberRole); insertionPoint = usingParent.GetChildrenByRole(SyntaxTree.MemberRole).SkipWhile(CanAppearBeforeUsings).FirstOrDefault(); } else { insertionPoint = blockStart; while (IsUsingFollowing(ref insertionPoint) && newUsingInfo.CompareTo(new UsingInfo(insertionPoint, context)) > 0) { insertionPoint = insertionPoint.NextSibling; } if (!IsUsingDeclaration(insertionPoint)) { // Insert after last using instead of before next node // This affects where empty lines get placed. insertionPoint = insertionPoint.PrevSibling; insertAfter = true; } } if (insertionPoint != null) { if (insertAfter) { script.InsertAfter(insertionPoint, newUsing); } else { script.InsertBefore(insertionPoint, newUsing); } } }