diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs
index 71743c984e..abcbfb0077 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs
@@ -19,7 +19,7 @@ namespace CSharpBinding.Parser
{
public class TParser : IParser
{
- ///IParser Interface
+ ///IParser Interface
string[] lexerTags;
public string[] LexerTags {
@@ -53,7 +53,7 @@ namespace CSharpBinding.Parser
ICSharpCode.NRefactory.Parser.PreProcessingDirective directive = tracker.CurrentSpecials[i] as ICSharpCode.NRefactory.Parser.PreProcessingDirective;
if (directive != null) {
if (directive.Cmd == "#region") {
- int deep = 1;
+ int deep = 1;
for (int j = i + 1; j < tracker.CurrentSpecials.Count; ++j) {
ICSharpCode.NRefactory.Parser.PreProcessingDirective nextDirective = tracker.CurrentSpecials[j] as ICSharpCode.NRefactory.Parser.PreProcessingDirective;
if (nextDirective != null) {
@@ -81,37 +81,31 @@ namespace CSharpBinding.Parser
{
Properties textEditorProperties = ((Properties)PropertyService.Get("ICSharpCode.TextEditor.Document.Document.DefaultDocumentAggregatorProperties", new Properties()));
using (ICSharpCode.NRefactory.Parser.IParser p = ICSharpCode.NRefactory.Parser.ParserFactory.CreateParser(fileName, Encoding.GetEncoding(textEditorProperties.Get("Encoding", 1252)))) {
- p.Lexer.SpecialCommentTags = lexerTags;
- p.Parse();
-
- NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(projectContent);
- visitor.Visit(p.CompilationUnit, null);
- visitor.Cu.FileName = fileName;
- visitor.Cu.ErrorsDuringCompile = p.Errors.count > 0;
- RetrieveRegions(visitor.Cu, p.Lexer.SpecialTracker);
- AddCommentTags(visitor.Cu, p.Lexer.TagComments);
- return visitor.Cu;
+ return Parse(p, fileName, projectContent);
}
}
public ICompilationUnit Parse(IProjectContent projectContent, string fileName, string fileContent)
- {
+ {
using (ICSharpCode.NRefactory.Parser.IParser p = ICSharpCode.NRefactory.Parser.ParserFactory.CreateParser(ICSharpCode.NRefactory.Parser.SupportedLanguages.CSharp, new StringReader(fileContent))) {
- p.Lexer.SpecialCommentTags = lexerTags;
- p.Parse();
-
- NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(projectContent);
- visitor.Visit(p.CompilationUnit, null);
- visitor.Cu.FileName = fileName;
- visitor.Cu.ErrorsDuringCompile = p.Errors.count > 0;
- visitor.Cu.Tag = p.CompilationUnit;
-
- RetrieveRegions(visitor.Cu, p.Lexer.SpecialTracker);
- AddCommentTags(visitor.Cu, p.Lexer.TagComments);
- return visitor.Cu;
+ return Parse(p, fileName, projectContent);
}
}
+ ICompilationUnit Parse(ICSharpCode.NRefactory.Parser.IParser p, string fileName, IProjectContent projectContent)
+ {
+ p.Lexer.SpecialCommentTags = lexerTags;
+ p.Parse();
+
+ NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(projectContent);
+ visitor.Visit(p.CompilationUnit, null);
+ visitor.Cu.FileName = fileName;
+ visitor.Cu.ErrorsDuringCompile = p.Errors.count > 0;
+ RetrieveRegions(visitor.Cu, p.Lexer.SpecialTracker);
+ AddCommentTags(visitor.Cu, p.Lexer.TagComments);
+ return visitor.Cu;
+ }
+
void AddCommentTags(ICompilationUnit cu, ArrayList tagComments)
{
foreach (ICSharpCode.NRefactory.Parser.TagComment tagComment in tagComments) {
@@ -124,7 +118,7 @@ namespace CSharpBinding.Parser
public IResolver CreateResolver()
{
- return new ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryResolver(ICSharpCode.NRefactory.Parser.SupportedLanguages.CSharp);
+ return new ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryResolver(ICSharpCode.NRefactory.Parser.SupportedLanguages.CSharp);
}
///////// IParser Interface END
}
diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/Parser.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/Parser.cs
index 9449c761ee..e2c49d5f5c 100644
--- a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/Parser.cs
+++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/Parser.cs
@@ -94,36 +94,30 @@ namespace VBNetBinding.Parser
{
Properties textEditorProperties = ((Properties)PropertyService.Get("ICSharpCode.TextEditor.Document.Document.DefaultDocumentAggregatorProperties", new Properties()));
using (ICSharpCode.NRefactory.Parser.IParser p = ICSharpCode.NRefactory.Parser.ParserFactory.CreateParser(fileName, Encoding.GetEncoding(textEditorProperties.Get("Encoding", 1252)))) {
- p.Lexer.SpecialCommentTags = lexerTags;
- p.Parse();
-
- NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(projectContent);
- visitor.Visit(p.CompilationUnit, null);
- visitor.Cu.FileName = fileName;
- visitor.Cu.ErrorsDuringCompile = p.Errors.count > 0;
- RetrieveRegions(visitor.Cu, p.Lexer.SpecialTracker);
- AddCommentTags(visitor.Cu, p.Lexer.TagComments);
- return visitor.Cu;
+ return Parse(p, fileName, projectContent);
}
}
public ICompilationUnit Parse(IProjectContent projectContent, string fileName, string fileContent)
{
using (ICSharpCode.NRefactory.Parser.IParser p = ICSharpCode.NRefactory.Parser.ParserFactory.CreateParser(ICSharpCode.NRefactory.Parser.SupportedLanguages.VBNet, new StringReader(fileContent))) {
- p.Lexer.SpecialCommentTags = lexerTags;
- p.Parse();
-
- NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(projectContent);
- visitor.Visit(p.CompilationUnit, null);
- visitor.Cu.FileName = fileName;
- visitor.Cu.ErrorsDuringCompile = p.Errors.count > 0;
- visitor.Cu.Tag = p.CompilationUnit;
-
- RetrieveRegions(visitor.Cu, p.Lexer.SpecialTracker);
- AddCommentTags(visitor.Cu, p.Lexer.TagComments);
- return visitor.Cu;
+ return Parse(p, fileName, projectContent);
}
}
+
+ ICompilationUnit Parse(ICSharpCode.NRefactory.Parser.IParser p, string fileName, IProjectContent projectContent)
+ {
+ p.Lexer.SpecialCommentTags = lexerTags;
+ p.Parse();
+
+ NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(projectContent);
+ visitor.Visit(p.CompilationUnit, null);
+ visitor.Cu.FileName = fileName;
+ visitor.Cu.ErrorsDuringCompile = p.Errors.count > 0;
+ RetrieveRegions(visitor.Cu, p.Lexer.SpecialTracker);
+ AddCommentTags(visitor.Cu, p.Lexer.TagComments);
+ return visitor.Cu;
+ }
void AddCommentTags(ICompilationUnit cu, ArrayList tagComments)
{
diff --git a/src/Main/Base/Project/Src/Dom/IResolver.cs b/src/Main/Base/Project/Src/Dom/IResolver.cs
index 36026e2fc4..188126b56b 100644
--- a/src/Main/Base/Project/Src/Dom/IResolver.cs
+++ b/src/Main/Base/Project/Src/Dom/IResolver.cs
@@ -3,7 +3,7 @@
* User: Omnibrain
* Date: 30.11.2004
* Time: 23:23
- *
+ *
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
@@ -24,10 +24,11 @@ namespace ICSharpCode.SharpDevelop.Dom
/// Resolves an expression.
/// The caretLineNumber and caretColumn is 1 based.
///
- ResolveResult Resolve(string expression,
- int caretLineNumber,
- int caretColumn,
- string fileName);
+ ResolveResult Resolve(string expression,
+ int caretLineNumber,
+ int caretColumn,
+ string fileName,
+ string fileContent);
ArrayList CtrlSpace(int caretLine, int caretColumn, string fileName);
}
diff --git a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
index 9d3b9d37bd..f26ea3ce63 100644
--- a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
+++ b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
@@ -96,7 +96,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
public ResolveResult Resolve(string expression,
int caretLineNumber,
int caretColumn,
- string fileName)
+ string fileName,
+ string fileContent)
{
if (expression == null) {
expression = "";
@@ -110,12 +111,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (parseInfo == null) {
return null;
}
- ICSharpCode.NRefactory.Parser.AST.CompilationUnit fileCompilationUnit = parseInfo.MostRecentCompilationUnit.Tag as ICSharpCode.NRefactory.Parser.AST.CompilationUnit;
- if (fileCompilationUnit == null) {
-// ICSharpCode.NRefactory.Parser.Parser fileParser = new ICSharpCode.NRefactory.Parser.Parser();
-// fileParser.Parse(new Lexer(new StringReader(fileContent)));
- return null;
- }
Expression expr = null;
if (expression == "") {
if ((expr = WithResolve()) == null) {
@@ -125,7 +120,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (expr == null) {
expr = SpecialConstructs(expression);
if (expr == null) {
- ICSharpCode.NRefactory.Parser.IParser p = ICSharpCode.NRefactory.Parser.ParserFactory.CreateParser(language, new System.IO.StringReader(expression));
+ ICSharpCode.NRefactory.Parser.IParser p = ParserFactory.CreateParser(language, new System.IO.StringReader(expression));
expr = p.ParseExpression();
if (expr == null) {
return null;
@@ -133,17 +128,23 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
}
lookupTableVisitor = new LookupTableVisitor(languageProperties.NameComparer);
- lookupTableVisitor.Visit(fileCompilationUnit, null);
- NRefactoryASTConvertVisitor cSharpVisitor = new NRefactoryASTConvertVisitor(parseInfo.MostRecentCompilationUnit != null ? parseInfo.MostRecentCompilationUnit.ProjectContent : null);
-
- cu = (ICompilationUnit)cSharpVisitor.Visit(fileCompilationUnit, null);
+ //NRefactoryASTConvertVisitor cSharpVisitor = new NRefactoryASTConvertVisitor(parseInfo.MostRecentCompilationUnit != null ? parseInfo.MostRecentCompilationUnit.ProjectContent : null);
+ cu = parseInfo.MostRecentCompilationUnit; //(ICompilationUnit)cSharpVisitor.Visit(fileCompilationUnit, null);
if (cu != null) {
callingClass = cu.GetInnermostClass(caretLine, caretColumn);
cu.FileName = fileName;
}
callingMember = GetCurrentMember();
+ if (callingMember != null) {
+ System.IO.TextReader content = ExtractMethod(fileContent, callingMember);
+ if (content != null) {
+ ICSharpCode.NRefactory.Parser.IParser p = ParserFactory.CreateParser(language, content);
+ p.Parse();
+ lookupTableVisitor.Visit(p.CompilationUnit, null);
+ }
+ }
TypeVisitor typeVisitor = new TypeVisitor(this);
@@ -206,12 +207,71 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
return null;
}
- return new ResolveResult(callingClass, callingMember, FixType(type));
+ return new ResolveResult(callingClass, callingMember, type);
}
- IReturnType FixType(IReturnType type)
+ ///
+ /// 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.
+ ///
+ System.IO.TextReader ExtractMethod(string fileContent, IMember member)
{
- return type;
+ // 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 == null) return null;
+ int startLine = member.Region.BeginLine;
+ if (startLine < 1) return null;
+ IRegion bodyRegion;
+ if (member is IMethod) {
+ bodyRegion = ((IMethod)member).BodyRegion;
+ } else if (member is IProperty) {
+ bodyRegion = ((IProperty)member).BodyRegion;
+ } else if (member is IIndexer) {
+ bodyRegion = ((IIndexer)member).BodyRegion;
+ } else if (member is IEvent) {
+ bodyRegion = ((IEvent)member).BodyRegion;
+ } else {
+ return null;
+ }
+ if (bodyRegion == null) return null;
+ int endLine = bodyRegion.EndLine;
+ 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;
+ }
+// Console.WriteLine("", startLine, endLine);
+// Console.Write(fileContent.Substring(startOffset, offset - startOffset));
+// Console.WriteLine("");
+ int length = offset - startOffset;
+ System.Text.StringBuilder b = new System.Text.StringBuilder("class A {", length + 10 + startLine);
+ b.Append('\n', startLine - 1);
+ b.Append(fileContent, startOffset, length);
+ b.Append("}\n");
+ return new System.IO.StringReader(b.ToString());
}
#region Resolve Identifier
@@ -225,12 +285,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
LocalLookupVariable var = SearchVariable(identifier);
if (var != null) {
IReturnType type = GetVariableType(var);
- IField field = new DefaultField(FixType(type), identifier, ModifierEnum.None, new DefaultRegion(var.StartPos, var.EndPos), callingClass);
+ IField field = new DefaultField(type, identifier, ModifierEnum.None, new DefaultRegion(var.StartPos, var.EndPos), callingClass);
return new LocalResolveResult(callingMember, field, false);
}
IParameter para = SearchMethodParameter(identifier);
if (para != null) {
- IField field = new DefaultField(FixType(para.ReturnType), para.Name, ModifierEnum.None, para.Region, callingClass);
+ IField field = new DefaultField(para.ReturnType, para.Name, ModifierEnum.None, para.Region, callingClass);
return new LocalResolveResult(callingMember, field, true);
}
}
@@ -263,7 +323,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
private ResolveResult CreateMemberResolveResult(IMember member)
{
- member.ReturnType = FixType(member.ReturnType);
return new MemberResolveResult(callingClass, callingMember, member);
}
@@ -339,14 +398,19 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
if (callingClass == null)
return null;
+ foreach (IMethod method in callingClass.Methods) {
+ if (method.BodyRegion != null && method.BodyRegion.IsInside(caretLine, caretColumn)) {
+ return method;
+ }
+ }
foreach (IProperty property in callingClass.Properties) {
if (property.BodyRegion != null && property.BodyRegion.IsInside(caretLine, caretColumn)) {
return property;
}
}
- foreach (IMethod method in callingClass.Methods) {
- if (method.BodyRegion != null && method.BodyRegion.IsInside(caretLine, caretColumn)) {
- return method;
+ foreach (IIndexer indexer in callingClass.Indexer) {
+ if (indexer.BodyRegion != null && indexer.BodyRegion.IsInside(caretLine, caretColumn)) {
+ return indexer;
}
}
return null;
diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
index 7fc617aa66..69396d6040 100644
--- a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
+++ b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
@@ -401,7 +401,7 @@ namespace ICSharpCode.Core
//try {
IParser parser = GetParser(fileName);
if (parser != null) {
- return parser.CreateResolver().Resolve(expression, caretLineNumber, caretColumn, fileName);
+ return parser.CreateResolver().Resolve(expression, caretLineNumber, caretColumn, fileName, fileContent);
}
return null;
//} catch {