public NRefactoryResolver(IProjectContent projectContent, LanguageProperties languageProperties) { if (projectContent == null) { throw new ArgumentNullException("projectContent"); } if (languageProperties == null) { throw new ArgumentNullException("languageProperties"); } this.languageProperties = languageProperties; this.projectContent = projectContent; if (languageProperties is LanguageProperties.CSharpProperties) { language = NR.SupportedLanguage.CSharp; } else if (languageProperties is LanguageProperties.VBNetProperties) { language = NR.SupportedLanguage.VBNet; } else { throw new NotSupportedException("The language " + languageProperties.ToString() + " is not supported in the resolver"); } }
private NRefactoryRefactoringProvider(NR.SupportedLanguage language) { this.language = language; }
/// <summary> /// Creates a new class containing only the specified member. /// This is useful because we only want to parse current method for local variables, /// as all fields etc. are already prepared in the AST. /// </summary> public static TextReader ExtractMethod(string fileContent, IMember member, NR.SupportedLanguage language, int caretLine) { // As the parse information is always some seconds old, the end line could be wrong // if the user just inserted a line in the method. // We can ignore that case because it is sufficient for the parser when the first part of the // method body is ok. // Since we are operating directly on the edited buffer, the parser might not be // able to resolve invalid declarations. // We can ignore even that because the 'invalid line' is the line the user is currently // editing, and the declarations he is using are always above that line. // The ExtractMethod-approach has the advantage that the method contents do not have // do be parsed and stored in memory before they are needed. // Previous SharpDevelop versions always stored the SharpRefactory[VB] parse tree as 'Tag' // to the AST CompilationUnit. // This approach doesn't need that, so one could even go and implement a special parser // mode that does not parse the method bodies for the normal run (in the ParserUpdateThread or // SolutionLoadThread). That could improve the parser's speed dramatically. if (member.Region.IsEmpty) { return(null); } int startLine = member.Region.BeginLine; if (startLine < 1) { return(null); } DomRegion bodyRegion; if (member is IMethodOrProperty) { bodyRegion = ((IMethodOrProperty)member).BodyRegion; } else if (member is IEvent) { bodyRegion = ((IEvent)member).BodyRegion; } else { return(null); } if (bodyRegion.IsEmpty) { return(null); } int endLine = bodyRegion.EndLine; // Fix for SD2-511 (Code completion in inserted line) if (language == NR.SupportedLanguage.CSharp) { // Do not do this for VB: the parser does not correct create the // ForEachStatement when the method in truncated in the middle // VB does not have the "inserted line looks like variable declaration"-problem // anyways. if (caretLine > startLine && caretLine < endLine) { endLine = caretLine; } } int offset = 0; for (int i = 0; i < startLine - 1; ++i) // -1 because the startLine must be included { offset = fileContent.IndexOf('\n', offset) + 1; if (offset <= 0) { return(null); } } int startOffset = offset; for (int i = startLine - 1; i < endLine; ++i) { int newOffset = fileContent.IndexOf('\n', offset) + 1; if (newOffset <= 0) { break; } offset = newOffset; } int length = offset - startOffset; string classDecl, endClassDecl; if (language == NR.SupportedLanguage.VBNet) { classDecl = "Class A"; endClassDecl = "End Class\n"; } else { classDecl = "class A {"; endClassDecl = "}\n"; } System.Text.StringBuilder b = new System.Text.StringBuilder(classDecl, length + classDecl.Length + endClassDecl.Length + startLine - 1); b.Append('\n', startLine - 1); b.Append(fileContent, startOffset, length); b.Append(endClassDecl); return(new System.IO.StringReader(b.ToString())); }