/// <summary> /// If given symbol is Unknown ResolveResult, returns action that can generate code for this missing symbol. /// </summary> public static GenerateCodeContextAction GetContextAction(EditorContext context) { if (context.CurrentSymbol is UnknownMethodResolveResult) { UnknownMethodResolveResult unknownMethodCall = (UnknownMethodResolveResult)context.CurrentSymbol; Ast.Expression expression = context.GetContainingElement <Ast.InvocationExpression>(); if (expression == null) { return(null); } string title = "${res:AddIns.SharpRefactoring.IntroduceMethod}"; try { title = string.Format(StringParser.Parse("${res:AddIns.SharpRefactoring.IntroduceMethod}"), unknownMethodCall.CallName, unknownMethodCall.Target.FullyQualifiedName); } catch (FormatException) { } if (unknownMethodCall.Target != null && unknownMethodCall.Target.IsUserCode()) { // Don't introduce method on non-modyfiable types return(new IntroduceMethodContextAction(unknownMethodCall, expression, context.Editor) { Title = title }); } } return(null); }
public string Search(UnknownMethodResolveResult rr, IProjectContent pc, List <IClass> results) { SearchAttributesWithName(results, pc, rr.CallName); foreach (IProjectContent content in pc.ThreadSafeGetReferencedContents()) { SearchAttributesWithName(results, content, rr.CallName); } return(rr.CallName); }
public IntroduceMethodContextAction(UnknownMethodResolveResult symbol, Ast.Expression invocationExpr, ITextEditor editor) { if (symbol == null) throw new ArgumentNullException("rr"); if (invocationExpr == null) throw new ArgumentNullException("ex"); if (editor == null) throw new ArgumentNullException("editor"); this.UnknownMethodCall = symbol; this.InvocationExpr = invocationExpr; this.Editor = editor; }
public MenuItem Create(RefactoringMenuContext context) { if (context.ExpressionResult.Context == ExpressionContext.Attribute) { return(null); } if (!(context.ResolveResult is UnknownMethodResolveResult)) { return(null); } if (context.ProjectContent == null) { return(null); } UnknownMethodResolveResult rr = context.ResolveResult as UnknownMethodResolveResult; MenuItem item = new MenuItem() { Header = string.Format(StringParser.Parse("${res:AddIns.SharpRefactoring.ResolveExtensionMethod}"), rr.CallName), Icon = ClassBrowserIconService.GotoArrow.CreateImage() }; List <IClass> results = new List <IClass>(); SearchAllExtensionMethodsWithName(results, context.ProjectContent, rr.CallName); foreach (IProjectContent content in context.ProjectContent.ThreadSafeGetReferencedContents()) { SearchAllExtensionMethodsWithName(results, content, rr.CallName); } if (!results.Any()) { return(null); } foreach (IClass c in results) { string newNamespace = c.Namespace; MenuItem subItem = new MenuItem(); subItem.Header = "using " + newNamespace; subItem.Icon = ClassBrowserIconService.Namespace.CreateImage(); item.Items.Add(subItem); subItem.Click += delegate { NamespaceRefactoringService.AddUsingDeclaration(context.CompilationUnit, context.Editor.Document, newNamespace, true); ParserService.BeginParse(context.Editor.FileName, context.Editor.Document); }; } return(item); }
public IntroduceMethodContextAction(UnknownMethodResolveResult symbol, Ast.Expression invocationExpr, ITextEditor editor) { if (symbol == null) { throw new ArgumentNullException("rr"); } if (invocationExpr == null) { throw new ArgumentNullException("ex"); } if (editor == null) { throw new ArgumentNullException("editor"); } this.UnknownMethodCall = symbol; this.InvocationExpr = invocationExpr; this.Editor = editor; }
IEnumerable <IContextAction> GetAddUsingExtensionMethodActions(EditorContext context) { UnknownMethodResolveResult rr = context.CurrentSymbol as UnknownMethodResolveResult; if (rr == null) { yield break; } List <IClass> results = new List <IClass>(); IProjectContent pc = context.ProjectContent; SearchAllExtensionMethodsWithName(results, pc, rr.CallName); foreach (IProjectContent content in pc.ThreadSafeGetReferencedContents()) { SearchAllExtensionMethodsWithName(results, content, rr.CallName); } foreach (IClass c in results) { yield return(new RefactoringService.AddUsingAction(context.CurrentParseInformation.CompilationUnit, context.Editor, c.Namespace)); } }
IEnumerable<Ast.ParameterDeclarationExpression> CreateParameters(UnknownMethodResolveResult rr, ClassFinder context, Ast.InvocationExpression invocation) { List<string> usedNames = new List<string>(); for (int i = 0; i < rr.Arguments.Count; i++) { IReturnType type = rr.Arguments[i]; if (type is LambdaReturnType) type = (type as LambdaReturnType).ToDefaultDelegate(); Ast.TypeReference typeRef = CodeGenerator.ConvertType(type, context); typeRef = typeRef.IsNull ? new Ast.TypeReference("object", true) : typeRef; Ast.Expression ex = invocation.Arguments[i]; string paramName = IsNumericType(type) ? "num" + i : type.Name + i.ToString(); if (ex is Ast.IdentifierExpression) { paramName = (ex as Ast.IdentifierExpression).Identifier; } if (ex is Ast.MemberReferenceExpression) { paramName = (ex as Ast.MemberReferenceExpression).MemberName; } Ast.ParameterModifiers mod = Ast.ParameterModifiers.None; if (ex is Ast.DirectionExpression) { var dex = ex as Ast.DirectionExpression; if (dex.Expression is Ast.IdentifierExpression) { paramName = (dex.Expression as Ast.IdentifierExpression).Identifier; } if (dex.Expression is Ast.MemberReferenceExpression) { paramName = (dex.Expression as Ast.MemberReferenceExpression).MemberName; } mod = dex.FieldDirection == Ast.FieldDirection.Out ? Ast.ParameterModifiers.Out : (dex.FieldDirection == Ast.FieldDirection.Ref ? Ast.ParameterModifiers.Ref : Ast.ParameterModifiers.None); } paramName = rr.CallingClass.ProjectContent.Language.CodeGenerator.GetParameterName(paramName); if (usedNames.Contains(paramName)) paramName += i.ToString(); usedNames.Add(paramName); yield return new Ast.ParameterDeclarationExpression(typeRef, paramName) { ParamModifier = mod }; } }
internal void ExecuteIntroduceMethod(UnknownMethodResolveResult rr, Ast.Expression invocationExpr, ITextEditor editor, bool isNew, object result) { IClass targetClass = IsEqualClass(rr.CallingClass, rr.Target.GetUnderlyingClass()) ? rr.CallingClass : rr.Target.GetUnderlyingClass(); CodeGenerator gen = targetClass.ProjectContent.Language.CodeGenerator; IAmbience ambience = targetClass.ProjectContent.Language.GetAmbience(); ClassFinder finder = new ClassFinder(rr.CallingMember); ModifierEnum modifiers = ModifierEnum.None; bool isExtension = !targetClass.IsUserCode(); if (IsEqualClass(rr.CallingClass, targetClass)) { if (rr.CallingMember != null) modifiers |= (rr.CallingMember.Modifiers & ModifierEnum.Static); } else { if (isExtension) { if (isNew) targetClass = rr.CallingClass; else targetClass = result as IClass; } // exclude in Unit Test mode if (WorkbenchSingleton.Workbench != null) editor = (FileService.OpenFile(targetClass.CompilationUnit.FileName) as ITextEditorProvider).TextEditor; if (targetClass.ClassType != ClassType.Interface) modifiers |= ModifierEnum.Public; if (rr.IsStaticContext) modifiers |= ModifierEnum.Static; } NRefactoryResolver resolver = Extensions.CreateResolverForContext(targetClass.ProjectContent.Language, editor); IReturnType type = resolver.GetExpectedTypeFromContext(invocationExpr); Ast.TypeReference typeRef = CodeGenerator.ConvertType(type, finder); if (typeRef.IsNull) { if (invocationExpr.Parent is Ast.ExpressionStatement) typeRef = new Ast.TypeReference("void", true); else typeRef = new Ast.TypeReference("object", true); } Ast.MethodDeclaration method = new Ast.MethodDeclaration { Name = rr.CallName, Modifier = CodeGenerator.ConvertModifier(modifiers, finder), TypeReference = typeRef, Parameters = CreateParameters(rr, finder, invocationExpr as Ast.InvocationExpression).ToList(), }; if (targetClass.ClassType != ClassType.Interface) method.Body = CodeGenerator.CreateNotImplementedBlock(); RefactoringDocumentAdapter documentWrapper = new RefactoringDocumentAdapter(editor.Document); if (isExtension) { method.Parameters.Insert(0, new Ast.ParameterDeclarationExpression(CodeGenerator.ConvertType(rr.Target, finder), "thisInstance")); method.IsExtensionMethod = true; method.Modifier |= Ast.Modifiers.Static; } if (isNew) { Ast.TypeDeclaration newType = new Ast.TypeDeclaration(isExtension ? Ast.Modifiers.Static : Ast.Modifiers.None, null); newType.Name = result as string; newType.AddChild(method); gen.InsertCodeAfter(targetClass, documentWrapper, newType); } else { if (IsEqualClass(rr.CallingClass, targetClass)) gen.InsertCodeAfter(rr.CallingMember, documentWrapper, method); else gen.InsertCodeAtEnd(targetClass.BodyRegion, documentWrapper, method); } if (targetClass.ClassType == ClassType.Interface) return; ParseInformation info = ParserService.ParseFile(targetClass.CompilationUnit.FileName); if (info != null) { IMember newMember; if (isNew) targetClass = info.CompilationUnit.Classes.FirstOrDefault(c => c.DotNetName == c.Namespace + "." + (result as string)); else targetClass = info.CompilationUnit.Classes.Flatten(c => c.InnerClasses).FirstOrDefault(c => c.DotNetName == targetClass.DotNetName); if (targetClass == null) return; if (IsEqualClass(rr.CallingClass, targetClass)) { newMember = targetClass.GetInnermostMember(editor.Caret.Line, editor.Caret.Column); newMember = targetClass.AllMembers .OrderBy(m => m.BodyRegion.BeginLine) .ThenBy(m2 => m2.BodyRegion.BeginColumn) .First(m3 => m3.BodyRegion.BeginLine > newMember.BodyRegion.BeginLine); } else { newMember = targetClass.Methods.Last(); } IDocumentLine line = editor.Document.GetLine(newMember.BodyRegion.BeginLine + 2); int indentLength = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset).Length; editor.Select(line.Offset + indentLength, "throw new NotImplementedException();".Length); } }
public JsNode VisitUnknownMethodResolveResult(UnknownMethodResolveResult res) { throw new NotImplementedException(); }
public JsNode VisitUnknownMethodResolveResult(UnknownMethodResolveResult res) { return(Js.Member("UNKNOWN_METHOD")); }
IEnumerable <Ast.ParameterDeclarationExpression> CreateParameters(UnknownMethodResolveResult rr, ClassFinder context, Ast.InvocationExpression invocation) { List <string> usedNames = new List <string>(); for (int i = 0; i < rr.Arguments.Count; i++) { IReturnType type = rr.Arguments[i]; if (type is LambdaReturnType) { type = (type as LambdaReturnType).ToDefaultDelegate(); } Ast.TypeReference typeRef = CodeGenerator.ConvertType(type, context); typeRef = typeRef.IsNull ? new Ast.TypeReference("object", true) : typeRef; Ast.Expression ex = invocation.Arguments[i]; string paramName = IsNumericType(type) ? "num" + i : type.Name + i.ToString(); if (ex is Ast.IdentifierExpression) { paramName = (ex as Ast.IdentifierExpression).Identifier; } if (ex is Ast.MemberReferenceExpression) { paramName = (ex as Ast.MemberReferenceExpression).MemberName; } Ast.ParameterModifiers mod = Ast.ParameterModifiers.None; if (ex is Ast.DirectionExpression) { var dex = ex as Ast.DirectionExpression; if (dex.Expression is Ast.IdentifierExpression) { paramName = (dex.Expression as Ast.IdentifierExpression).Identifier; } if (dex.Expression is Ast.MemberReferenceExpression) { paramName = (dex.Expression as Ast.MemberReferenceExpression).MemberName; } mod = dex.FieldDirection == Ast.FieldDirection.Out ? Ast.ParameterModifiers.Out : (dex.FieldDirection == Ast.FieldDirection.Ref ? Ast.ParameterModifiers.Ref : Ast.ParameterModifiers.None); } paramName = rr.CallingClass.ProjectContent.Language.CodeGenerator.GetParameterName(paramName); if (usedNames.Contains(paramName)) { paramName += i.ToString(); } usedNames.Add(paramName); yield return(new Ast.ParameterDeclarationExpression(typeRef, paramName) { ParamModifier = mod }); } }
internal void ExecuteIntroduceMethod(UnknownMethodResolveResult rr, Ast.Expression invocationExpr, ITextEditor editor, bool isNew, object result) { IClass targetClass = IsEqualClass(rr.CallingClass, rr.Target.GetUnderlyingClass()) ? rr.CallingClass : rr.Target.GetUnderlyingClass(); CodeGenerator gen = targetClass.ProjectContent.Language.CodeGenerator; IAmbience ambience = targetClass.ProjectContent.Language.GetAmbience(); ClassFinder finder = new ClassFinder(rr.CallingMember); ModifierEnum modifiers = ModifierEnum.None; bool isExtension = !targetClass.IsUserCode(); if (IsEqualClass(rr.CallingClass, targetClass)) { if (rr.CallingMember != null) { modifiers |= (rr.CallingMember.Modifiers & ModifierEnum.Static); } } else { if (isExtension) { if (isNew) { targetClass = rr.CallingClass; } else { targetClass = result as IClass; } } // exclude in Unit Test mode if (WorkbenchSingleton.Workbench != null) { editor = (FileService.OpenFile(targetClass.CompilationUnit.FileName) as ITextEditorProvider).TextEditor; } if (targetClass.ClassType != ClassType.Interface) { modifiers |= ModifierEnum.Public; } if (rr.IsStaticContext) { modifiers |= ModifierEnum.Static; } } NRefactoryResolver resolver = Extensions.CreateResolverForContext(targetClass.ProjectContent.Language, editor); IReturnType type = resolver.GetExpectedTypeFromContext(invocationExpr); Ast.TypeReference typeRef = CodeGenerator.ConvertType(type, finder); if (typeRef.IsNull) { if (invocationExpr.Parent is Ast.ExpressionStatement) { typeRef = new Ast.TypeReference("void", true); } else { typeRef = new Ast.TypeReference("object", true); } } Ast.MethodDeclaration method = new Ast.MethodDeclaration { Name = rr.CallName, Modifier = CodeGenerator.ConvertModifier(modifiers, finder), TypeReference = typeRef, Parameters = CreateParameters(rr, finder, invocationExpr as Ast.InvocationExpression).ToList(), }; if (targetClass.ClassType != ClassType.Interface) { method.Body = CodeGenerator.CreateNotImplementedBlock(); } RefactoringDocumentAdapter documentWrapper = new RefactoringDocumentAdapter(editor.Document); if (isExtension) { method.Parameters.Insert(0, new Ast.ParameterDeclarationExpression(CodeGenerator.ConvertType(rr.Target, finder), "thisInstance")); method.IsExtensionMethod = true; method.Modifier |= Ast.Modifiers.Static; } if (isNew) { Ast.TypeDeclaration newType = new Ast.TypeDeclaration(isExtension ? Ast.Modifiers.Static : Ast.Modifiers.None, null); newType.Name = result as string; newType.AddChild(method); gen.InsertCodeAfter(targetClass, documentWrapper, newType); } else { if (IsEqualClass(rr.CallingClass, targetClass)) { gen.InsertCodeAfter(rr.CallingMember, documentWrapper, method); } else { gen.InsertCodeAtEnd(targetClass.BodyRegion, documentWrapper, method); } } if (targetClass.ClassType == ClassType.Interface) { return; } ParseInformation info = ParserService.ParseFile(targetClass.CompilationUnit.FileName); if (info != null) { IMember newMember; if (isNew) { targetClass = info.CompilationUnit.Classes.FirstOrDefault(c => c.DotNetName == c.Namespace + "." + (result as string)); } else { targetClass = info.CompilationUnit.Classes.Flatten(c => c.InnerClasses).FirstOrDefault(c => c.DotNetName == targetClass.DotNetName); } if (targetClass == null) { return; } if (IsEqualClass(rr.CallingClass, targetClass)) { newMember = targetClass.GetInnermostMember(editor.Caret.Line, editor.Caret.Column); newMember = targetClass.AllMembers .OrderBy(m => m.BodyRegion.BeginLine) .ThenBy(m2 => m2.BodyRegion.BeginColumn) .First(m3 => m3.BodyRegion.BeginLine > newMember.BodyRegion.BeginLine); } else { newMember = targetClass.Methods.Last(); } IDocumentLine line = editor.Document.GetLine(newMember.BodyRegion.BeginLine + 2); int indentLength = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset).Length; editor.Select(line.Offset + indentLength, "throw new NotImplementedException();".Length); } }
public string Search(UnknownMethodResolveResult rr, IProjectContent pc, List<IClass> results) { SearchAttributesWithName(results, pc, rr.CallName); foreach (IProjectContent content in pc.ReferencedContents) SearchAttributesWithName(results, content, rr.CallName); return rr.CallName; }