Browse Source

Improved performance of parser run after opening a solution (really big improvement!!).

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@140 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
8ec53afcbd
  1. 1
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs
  2. 12
      src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexer.cs
  3. 21
      src/Libraries/NRefactory/Project/Src/Lexer/CSharp/Lexer.cs
  4. 5
      src/Libraries/NRefactory/Project/Src/Lexer/ILexer.cs
  5. 11
      src/Libraries/NRefactory/Project/Src/Parser/AbstractParser.cs
  6. 955
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  7. 4
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  8. 26
      src/Libraries/NRefactory/Test/Lexer/CSharp/LexerTest.cs
  9. 13
      src/Main/Base/Project/Src/Project/AbstractProject.cs
  10. 22
      src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs

1
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs

@ -95,6 +95,7 @@ namespace CSharpBinding.Parser @@ -95,6 +95,7 @@ namespace CSharpBinding.Parser
ICompilationUnit Parse(ICSharpCode.NRefactory.Parser.IParser p, string fileName, IProjectContent projectContent)
{
p.Lexer.SpecialCommentTags = lexerTags;
((ICSharpCode.NRefactory.Parser.AbstractParser)p).ParseMethodContents = false;
p.Parse();
NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(projectContent);

12
src/Libraries/NRefactory/Project/Src/Lexer/AbstractLexer.cs

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
* User: Omnibrain
* Date: 08.09.2004
* Time: 23:13
*
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
@ -169,6 +169,14 @@ namespace ICSharpCode.NRefactory.Parser @@ -169,6 +169,14 @@ namespace ICSharpCode.NRefactory.Parser
protected abstract Token Next();
/// <summary>
/// Skips to the end of the current code block.
/// </summary>
public virtual void SkipCurrentBlock()
{
throw new NotSupportedException();
}
protected bool IsIdentifierPart(char ch)
{
return Char.IsLetterOrDigit(ch) || ch == '_';
@ -224,7 +232,7 @@ namespace ICSharpCode.NRefactory.Parser @@ -224,7 +232,7 @@ namespace ICSharpCode.NRefactory.Parser
int nextChar;
while ((nextChar = reader.Read()) != -1) {
char ch = (char)nextChar;
// Return read string, if EOL is reached
if (HandleLineEnd(ch)) {
return sb.ToString();;

21
src/Libraries/NRefactory/Project/Src/Lexer/CSharp/Lexer.cs

@ -16,7 +16,7 @@ using ICSharpCode.NRefactory.Parser; @@ -16,7 +16,7 @@ using ICSharpCode.NRefactory.Parser;
namespace ICSharpCode.NRefactory.Parser.CSharp
{
internal class Lexer : AbstractLexer
internal sealed class Lexer : AbstractLexer
{
public Lexer(TextReader reader) : base(reader)
{
@ -802,5 +802,24 @@ namespace ICSharpCode.NRefactory.Parser.CSharp @@ -802,5 +802,24 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
// Reached EOF before end of multiline comment.
errors.Error(line, col, String.Format("Reached EOF before the end of a multiline comment"));
}
/// <summary>
/// Skips to the end of the current code block.
/// </summary>
public override void SkipCurrentBlock()
{
int braceCount = 0;
Token t;
StartPeek();
while ((t = Peek()).kind != Tokens.EOF) {
if (t.kind == Tokens.OpenCurlyBrace) {
++braceCount;
} else if (t.kind == Tokens.CloseCurlyBrace) {
if (--braceCount < 0)
return;
}
NextToken();
}
}
}
}

5
src/Libraries/NRefactory/Project/Src/Lexer/ILexer.cs

@ -67,5 +67,10 @@ namespace ICSharpCode.NRefactory.Parser @@ -67,5 +67,10 @@ namespace ICSharpCode.NRefactory.Parser
/// </summary>
/// <returns>An <see cref="Token"/> object.</returns>
Token NextToken();
/// <summary>
/// Skips to the end of the current code block.
/// </summary>
void SkipCurrentBlock();
}
}

11
src/Libraries/NRefactory/Project/Src/Parser/AbstractParser.cs

@ -27,6 +27,17 @@ namespace ICSharpCode.NRefactory.Parser @@ -27,6 +27,17 @@ namespace ICSharpCode.NRefactory.Parser
protected CompilationUnit compilationUnit;
protected bool parseMethodContents = true;
public bool ParseMethodContents {
get {
return parseMethodContents;
}
set {
parseMethodContents = value;
}
}
public ILexer Lexer {
get {
return lexer;

955
src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs

File diff suppressed because it is too large Load Diff

4
src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG

@ -1415,9 +1415,11 @@ Block<out Statement stmt> /* not BlockStatement because of EmbeddedStatement */ @@ -1415,9 +1415,11 @@ Block<out Statement stmt> /* not BlockStatement because of EmbeddedStatement */
"{" (. BlockStatement blockStmt = new BlockStatement();
blockStmt.StartLocation = t.EndLocation;
compilationUnit.BlockStart(blockStmt);
if (!parseMethodContents) lexer.SkipCurrentBlock();
.)
{ Statement }
"}" (. stmt = blockStmt;
"}" (.
stmt = blockStmt;
blockStmt.EndLocation = t.EndLocation;
compilationUnit.BlockEnd();
.)

26
src/Libraries/NRefactory/Test/Lexer/CSharp/LexerTest.cs

@ -112,6 +112,32 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.CSharp @@ -112,6 +112,32 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.CSharp
ILexer lexer = GenerateLexer(new StringReader("}"));
Assert.AreEqual(Tokens.CloseCurlyBrace, lexer.NextToken().kind);
}
[Test]
public void TestEmptyBlock()
{
ILexer lexer = GenerateLexer(new StringReader("{}"));
Assert.AreEqual(Tokens.OpenCurlyBrace, lexer.NextToken().kind);
Assert.AreEqual(Tokens.CloseCurlyBrace, lexer.NextToken().kind);
}
[Test]
public void TestSkippedEmptyBlock()
{
ILexer lexer = GenerateLexer(new StringReader("{}"));
Assert.AreEqual(Tokens.OpenCurlyBrace, lexer.NextToken().kind);
lexer.SkipCurrentBlock();
Assert.AreEqual(Tokens.CloseCurlyBrace, lexer.NextToken().kind);
}
[Test]
public void TestSkippedNonEmptyBlock()
{
ILexer lexer = GenerateLexer(new StringReader("{ TestMethod('}'); /* }}} */ break; }"));
Assert.AreEqual(Tokens.OpenCurlyBrace, lexer.NextToken().kind);
lexer.SkipCurrentBlock();
Assert.AreEqual(Tokens.CloseCurlyBrace, lexer.NextToken().kind);
}
[Test]
public void TestOpenSquareBracket()

13
src/Main/Base/Project/Src/Project/AbstractProject.cs

@ -101,13 +101,18 @@ namespace ICSharpCode.SharpDevelop.Project @@ -101,13 +101,18 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
string directoryName;
[Browsable(false)]
public string Directory {
get {
if (fileName == null) {
return String.Empty;
if (directoryName == null) {
if (fileName == null) {
return String.Empty;
}
directoryName = Path.GetFullPath(Path.GetDirectoryName(fileName));
}
return Path.GetFullPath(Path.GetDirectoryName(fileName));
return directoryName;
}
}
@ -337,7 +342,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -337,7 +342,7 @@ namespace ICSharpCode.SharpDevelop.Project
}
#endregion
public virtual CompilerResults Build()
{
return null;

22
src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs

@ -41,6 +41,9 @@ namespace ICSharpCode.Core @@ -41,6 +41,9 @@ namespace ICSharpCode.Core
/// </summary>
public sealed class FileUtility
{
// TODO: GetFullPath is a **very** expensive method (performance-wise)!
// Call it only when necessary. (see IsEqualFile)
readonly static char[] separators = { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, Path.VolumeSeparatorChar };
static string sharpDevelopRootPath;
const string fileNameRegEx = @"^(([a-zA-Z]:)|.)[^:]*$";
@ -155,11 +158,28 @@ namespace ICSharpCode.Core @@ -155,11 +158,28 @@ namespace ICSharpCode.Core
public static bool IsEqualFile(string fileName1, string fileName2)
{
// Optimized for performance:
//return Path.GetFullPath(fileName1.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)).ToLower() == Path.GetFullPath(fileName2.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)).ToLower();
if (fileName1.Length == 0 || fileName2.Length == 0) return false;
char lastChar;
lastChar = fileName1[fileName1.Length - 1];
if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar)
fileName1 = fileName1.Substring(0, fileName1.Length - 1);
lastChar = fileName2[fileName2.Length - 1];
if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar)
fileName2 = fileName2.Substring(0, fileName2.Length - 1);
try {
return Path.GetFullPath(fileName1.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)).ToLower() == Path.GetFullPath(fileName2.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)).ToLower();
if (fileName1.Length < 2 || fileName1[1] != ':')
fileName1 = Path.GetFullPath(fileName1);
if (fileName2.Length < 2 || fileName2[1] != ':')
fileName2 = Path.GetFullPath(fileName2);
} catch (Exception) {
return false;
}
return string.Equals(fileName1, fileName2, StringComparison.OrdinalIgnoreCase);
}
public static bool IsBaseDirectory(string baseDirectory, string testDirectory)

Loading…
Cancel
Save