PageRenderTime 24ms CodeModel.GetById 13ms app.highlight 7ms RepoModel.GetById 2ms app.codeStats 1ms

/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ContextAction/CreateLocalVariable.cs

http://github.com/icsharpcode/ILSpy
C# | 129 lines | 93 code | 11 blank | 25 comment | 31 complexity | 44bf76349e4449dea30fd84bcc722967 MD5 | raw file
  1// 
  2// CreateLocalVariable.cs
  3//  
  4// Author:
  5//       Mike Kr├╝ger <mkrueger@novell.com>
  6// 
  7// Copyright (c) 2011 Novell, Inc (http://www.novell.com)
  8// 
  9// Permission is hereby granted, free of charge, to any person obtaining a copy
 10// of this software and associated documentation files (the "Software"), to deal
 11// in the Software without restriction, including without limitation the rights
 12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 13// copies of the Software, and to permit persons to whom the Software is
 14// furnished to do so, subject to the following conditions:
 15// 
 16// The above copyright notice and this permission notice shall be included in
 17// all copies or substantial portions of the Software.
 18// 
 19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 25// THE SOFTWARE.
 26using System;
 27using ICSharpCode.NRefactory.PatternMatching;
 28using System.Linq;
 29using System.Collections.Generic;
 30using ICSharpCode.NRefactory.TypeSystem;
 31
 32namespace ICSharpCode.NRefactory.CSharp.Refactoring
 33{
 34	public class CreateLocalVariable : IContextAction
 35	{
 36		public List<IdentifierExpression> GetUnresolvedArguments (RefactoringContext context)
 37		{
 38			var expressions = new List<IdentifierExpression> ();
 39			
 40			var invocation = GetInvocation (context);
 41			if (invocation != null) {
 42				foreach (var arg in invocation.Arguments) {
 43					IdentifierExpression identifier;
 44					if (arg is DirectionExpression) {
 45						identifier = ((DirectionExpression)arg).Expression as IdentifierExpression;
 46					} else if (arg is NamedArgumentExpression) {
 47						identifier = ((NamedArgumentExpression)arg).Expression as IdentifierExpression;
 48					} else {
 49						identifier = arg as IdentifierExpression;
 50					}
 51					if (identifier == null)
 52						continue;
 53						
 54					if (context.Resolve (identifier) == null && GuessType (context, identifier) != null)
 55						expressions.Insert (0, identifier);
 56				}
 57			}
 58			return expressions;
 59		}
 60		
 61		public bool IsValid (RefactoringContext context)
 62		{
 63			if (GetUnresolvedArguments (context).Count > 0)
 64				return true;
 65			var identifier = CreateField.GetIdentifier (context);
 66			if (identifier == null)
 67				return false;
 68			if (context.GetNode<Statement> () == null)
 69				return false;
 70			return context.Resolve (identifier) == null && GuessType (context, identifier) != null;
 71		}
 72		
 73		public void Run (RefactoringContext context)
 74		{
 75			var stmt = context.GetNode<Statement> ();
 76			var unresolvedArguments = GetUnresolvedArguments (context);
 77			if (unresolvedArguments.Count > 0) {
 78				using (var script = context.StartScript ()) {
 79					foreach (var id in unresolvedArguments) {
 80						script.InsertBefore (stmt, GenerateLocalVariableDeclaration (context, id));
 81					}
 82				}
 83				return;
 84			}
 85			
 86			using (var script = context.StartScript ()) {
 87				script.InsertBefore (stmt, GenerateLocalVariableDeclaration (context, CreateField.GetIdentifier (context)));
 88			}
 89		}
 90		
 91		AstNode GenerateLocalVariableDeclaration (RefactoringContext context, IdentifierExpression identifier)
 92		{
 93			return new VariableDeclarationStatement () {
 94				Type = GuessType (context, identifier),
 95				Variables = { new VariableInitializer (identifier.Identifier) }
 96			};
 97		}
 98		
 99		InvocationExpression GetInvocation (RefactoringContext context)
100		{
101			return context.GetNode<InvocationExpression> ();
102		}
103		
104		AstType GuessType (RefactoringContext context, IdentifierExpression identifier)
105		{
106			var type = CreateField.GuessType (context, identifier);
107			if (type != null)
108				return type;
109			
110			if (identifier != null && (identifier.Parent is InvocationExpression || identifier.Parent.Parent is InvocationExpression)) {
111				var invocation = (identifier.Parent as InvocationExpression) ?? (identifier.Parent.Parent as InvocationExpression);
112				var result = context.Resolve (invocation).Type.GetDelegateInvokeMethod ();
113				if (result == null)
114					return null;
115				int i = 0;
116				foreach (var arg in invocation.Arguments) {
117					if (arg.Contains (identifier.StartLocation))
118						break;
119					i++;
120				}
121				if (result.Parameters.Count < i)
122					return null;
123				return context.CreateShortType (result.Parameters[i].Type);
124			}
125			return null;
126		}
127	}
128}
129