Browse Source

Fixed BOO-300: #region folding

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@609 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
a67e3f5220
  1. 80
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooParser.cs
  2. 14
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ExpressionFinder.cs

80
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooParser.cs

@ -6,7 +6,9 @@ @@ -6,7 +6,9 @@
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Dom;
@ -20,7 +22,6 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -20,7 +22,6 @@ namespace Grunwald.BooBinding.CodeCompletion
{
public class BooParser : IParser
{
///<summary>IParser Interface</summary>
string[] lexerTags;
public string[] LexerTags {
@ -80,7 +81,82 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -80,7 +81,82 @@ namespace Grunwald.BooBinding.CodeCompletion
lineLength[i] = length;
BooCompiler compiler = new BooCompiler();
compiler.Parameters.Input.Add(new StringInput(fileName, fileContent));
return Parse(projectContent, fileName, lineLength, compiler);
ICompilationUnit cu = Parse(projectContent, fileName, lineLength, compiler);
AddCommentsAndRegions(cu, fileContent, fileName);
return cu;
}
void AddCommentsAndRegions(ICompilationUnit cu, string fileContent, string fileName)
{
ExpressionFinder ef = new ExpressionFinder(fileName);
ef.ResetStateMachine();
int state = 0;
StringBuilder commentBuilder = null;
char commentStartChar = '\0';
int commentStartColumn = 0;
Stack<string> regionTitleStack = new Stack<string>();
Stack<int> regionLineStack = new Stack<int>();
Stack<int> regionColumnStack = new Stack<int>();
int line = 1;
int column = 0;
for (int i = 0; i < fileContent.Length; i++) {
column += 1;
char c = fileContent[i];
if (c == '\n') {
column = 0;
line += 1;
}
state = ef.FeedStateMachine(state, c);
if (state == ExpressionFinder.PossibleRegexStart) {
// after / could be a regular expression, do a special check for that
int regexEnd = ef.SkipRegularExpression(fileContent, i, fileContent.Length - 1);
if (regexEnd > 0) {
i = regexEnd;
} else if (regexEnd == -1) {
// end of file is in regex
return;
} // else: regexEnd is 0 if its not a regex
}
if (state == ExpressionFinder.LineCommentState) {
if (commentBuilder == null) {
commentStartChar = c;
commentStartColumn = column;
commentBuilder = new StringBuilder();
} else {
if (commentBuilder.Length > 0) {
commentBuilder.Append(c);
} else if (!char.IsWhiteSpace(c)) {
commentStartColumn = column;
commentBuilder.Append(c);
}
}
} else if (commentBuilder != null) {
string text = commentBuilder.ToString();
commentBuilder = null;
if (commentStartChar == '#' && text.StartsWith("region ")) {
regionTitleStack.Push(text.Substring(7));
regionLineStack.Push(line);
regionColumnStack.Push(commentStartColumn - 1);
} else if (commentStartChar == '#' && text.StartsWith("endregion") && regionTitleStack.Count > 0) {
// Add folding region
cu.FoldingRegions.Add(new FoldingRegion(regionTitleStack.Pop(),
new DomRegion(regionLineStack.Pop(),
regionColumnStack.Pop(),
line, column)));
} else {
foreach (string tag in lexerTags) {
if (text.StartsWith(tag)) {
Tag tagComment = new Tag(tag, new DomRegion(line, commentStartColumn));
tagComment.CommentString = text.Substring(tag.Length);
cu.TagComments.Add(tagComment);
break;
}
}
}
}
}
}
private ICompilationUnit Parse(IProjectContent projectContent, string fileName, int[] lineLength, BooCompiler compiler)

14
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ExpressionFinder.cs

@ -299,6 +299,8 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -299,6 +299,8 @@ namespace Grunwald.BooBinding.CodeCompletion
}
const int _elseIndex = 10;
public const int PossibleRegexStart = 12;
public const int LineCommentState = 13;
static readonly
int[][] _stateTable = { // " ' \ \n $ { } # / * else
@ -327,12 +329,12 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -327,12 +329,12 @@ namespace Grunwald.BooBinding.CodeCompletion
int commentblocks;
void ResetStateMachine()
public void ResetStateMachine()
{
commentblocks = 0;
}
int FeedStateMachine(int oldState, char c)
public int FeedStateMachine(int oldState, char c)
{
int charNum = (int)c;
int input;
@ -371,7 +373,7 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -371,7 +373,7 @@ namespace Grunwald.BooBinding.CodeCompletion
break;
char c = text[pos];
state = FeedStateMachine(state, c);
if (state == 12) {
if (state == PossibleRegexStart) {
// after / could be a regular expression, do a special check for that
int regexEnd = SkipRegularExpression(text, pos, text.Length - 1);
if (regexEnd > 0) {
@ -406,9 +408,9 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -406,9 +408,9 @@ namespace Grunwald.BooBinding.CodeCompletion
else
inStringResult.Length = 1;
state = action;
} else if (action == 0 || action == 12) {
} else if (action == 0 || action == PossibleRegexStart) {
// go to normal code
if (action == 12) {
if (action == PossibleRegexStart) {
// after / could be a regular expression, do a special check for that
int regexEnd = SkipRegularExpression(inText, i, offset);
if (regexEnd > 0) {
@ -443,7 +445,7 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -443,7 +445,7 @@ namespace Grunwald.BooBinding.CodeCompletion
/// <summary>Skips the regular expression in inText at position pos. Returns end position of the ending / if
/// successful or 0 is no regular expression was found at the location.
/// Return -1 if maxOffset is inside the regular expression.</summary>
int SkipRegularExpression(string inText, int pos, int maxOffset)
public int SkipRegularExpression(string inText, int pos, int maxOffset)
{
bool containsWhitespace;
if (pos > 0) {

Loading…
Cancel
Save