[svn] r7549: vs-plugin/trunk:
Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanLexer.n
Nemerle.Com...
VladD2
svnadmin at nemerle.org
Mon Mar 26 06:29:36 CEST 2007
Log:
Work on match braces.
Author: VladD2
Date: Mon Mar 26 06:29:33 2007
New Revision: 7549
Modified:
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanLexer.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanTokenInfo.n
vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleDropDownMember.cs
vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleLanguageService.cs
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanLexer.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanLexer.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanLexer.n Mon Mar 26 06:29:33 2007
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using Nemerle.Collections;
@@ -40,6 +40,7 @@
base.eating_now = 0;
_env = if (env != null) env else Manager.CoreEnv;
+ when (typeBuilder != null)
_typeBuilder = typeBuilder;
_onPreprocessor = false;
_tokenInfo.Token = null;
@@ -759,7 +760,7 @@
_tokenInfo.Token.Location = Location(file_idx, _last_line, _last_col, line, col);
_ = checkForHighlights(_tokenInfo);
- _tokenInfo
+ _tokenInfo //VladD2: 2IT: Ðлин, пÑиколиÑÑ. Я ÑÐ°Ñ Ð¾ÑÐ¸Ð±ÐºÑ Ð¸Ñкал. ÐÑе ÑлеменÑÑ Ð² маÑÑиве одинковÑе. :(
}
checkForHighlights(tokenInfo : ScanTokenInfo) : bool
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanTokenInfo.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanTokenInfo.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanTokenInfo.n Mon Mar 26 06:29:33 2007
@@ -51,5 +51,19 @@
public IsWhiteSpaceOrCommentType : bool { get { IsWhiteSpaceType || IsCommentType } }
+ public override ToString() : string { Token.ToString() }
+
+ public Clone() : ScanTokenInfo
+ {
+ mutable clone = ScanTokenInfo();
+ clone.Token = Token;
+ clone.State = State;
+ clone.Color = Color;
+ clone.Triggers = Triggers;
+ clone.Type = Type;
+ clone.IsEndOfLine = IsEndOfLine;
+ clone.ColorizeEnd = ColorizeEnd;
+ clone
+ }
}
}
Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleDropDownMember.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleDropDownMember.cs (original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleDropDownMember.cs Mon Mar 26 06:29:33 2007
@@ -104,11 +104,6 @@
_members.Sort(delegate(DropDownMember m1, DropDownMember m2)
{
- int glyph = m1.Glyph / 6 - m2.Glyph / 6;
-
- if (glyph != 0)
- return glyph;
-
// Sort by name (like in C#).
return string.Compare(m1.Label, m2.Label);
});
Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleLanguageService.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleLanguageService.cs (original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleLanguageService.cs Mon Mar 26 06:29:33 2007
@@ -18,6 +18,7 @@
using VsShell = Microsoft.VisualStudio.Shell.VsShellUtilities;
using Nemerle.VisualStudio.GUI;
+using Nemerle.Utility;
namespace Nemerle.VisualStudio.LanguageService
{
@@ -28,8 +29,8 @@
public NemerleLanguageService()
{
- CompiledUnitAstBrowser.ShowLocation += CompiledUnitAstBrowser_ShowLocation;
- AstToolControl.ShowLocation += CompiledUnitAstBrowser_ShowLocation;
+ CompiledUnitAstBrowser.ShowLocation += GotoLocation;
+ AstToolControl.ShowLocation += GotoLocation;
}
public override void Dispose()
@@ -80,11 +81,13 @@
case ParseReason.CodeSpan:
case ParseReason.DisplayMemberList:
case ParseReason.HighlightBraces:
- case ParseReason.MatchBraces:
case ParseReason.None:
case ParseReason.MemberSelectAndHighlightBraces:
Trace.WriteLine("Request reason '" + request.Reason + "' not handled.");
break;
+ case ParseReason.MatchBraces:
+ MatchBraces(request);
+ break;
}
NemerleSource source = (NemerleSource)GetSource(request.View);
@@ -95,9 +98,246 @@
return GetDefaultScope(request);
}
+
+ private void MatchBraces(ParseRequest request)
+ {
+ // Çàäà÷à:
+ // 1. Íàéòè òîêåí íà êîòîðîì íàõîäèòñÿ êóðñîð.
+ // 2. Îïðåäåëèòü ÷òî ýòî ïàðíûé òîêåí.
+ // 3. Îïðåäåëèòü êàêîé òîêåí ÿâëÿåòñÿ îòâåòíûì.
+ // 4. Íàéòè îòâåòíûé òîêåí â ôàéëå (èñòî÷íèêå).
+ // 5. Ïåðåìåñòèòü êóðñîð íà ýòîò òîêåí.
+
+ #region Init
+
+ ProjectInfo projectInfo = GetProjectInfo(request);
+
+ if (projectInfo == null)
+ return;
+
+ NemerleSource source = projectInfo.GetSource(request.FileName);
+ IVsTextColorState colorState = source.ColorState;
+ Colorizer colorizer = source.GetColorizer();
+ NemerleScanner scanner = (NemerleScanner)colorizer.Scanner;
+ string lineText = source.GetLine(request.Line);
+ scanner.SetSource(lineText, 0);
+
+ #endregion
+
+ // 1. Íàéòè òîêåí íà êîòîðîì íàõîäèòñÿ êóðñîð.
+ BracketFinder bracketFinder = new BracketFinder(source, request.Line + 1,
+ request.Col + 1, scanner, colorState);
+
+ ScanTokenInfo matchBraceInfo = bracketFinder.FindMatchBraceInfo();
+
+ if (matchBraceInfo != null)
+ {
+ GotoLocation(matchBraceInfo.Token.Location);
+ // Ïåðåéòè ê ïîçèöèè (?, matchBraceInfo.Token.Location.Column)
+ }
+ }
+
+ #region BracketFinder class
+
+ private class BracketFinder
+ {
+ public IVsTextColorState ColorState;
+ public NemerleSource Source;
+ public int StartLine;
+ public ScanTokenInfo StartBraceInfo;
+ public ScanLexer Lex;
+ NemerleScanner Scanner;
+
+ public BracketFinder(NemerleSource source, int startLine,
+ int startCol, NemerleScanner scanner, IVsTextColorState colorState)
+ {
+ Scanner = scanner;
+ Source = source;
+ StartLine = startLine;
+ Lex = scanner.GetLexer();
+ ColorState = colorState;
+
+ StartBraceInfo = Find(GetLineTokens(startLine, true),
+ delegate(ScanTokenInfo x)
+ { return x.Token.Location.Contains(startLine, startCol); });
+ //ScanState = ScanState;
+ }
+
+ public ScanTokenInfo FindMatchBraceInfo()
+ {
+ if (StartBraceInfo == null) // 1. ÎÊ. Òîêåí íàéäåí.
+ return null;
+ // 2. Îïðåäåëèòü ÷òî ýòî ïàðíûé òîêåí.
+ // 3. Îïðåäåëèòü êàêîé òîêåí ÿâëÿåòñÿ îòâåòíûì.
+ // 4. Íàéòè îòâåòíûé òîêåí â ôàéëå (èñòî÷íèêå).
+
+ Token tok = StartBraceInfo.Token;
+ Predicate<Token> isStartBrace = GetMatchBracePredicate(tok);
+ Predicate<Token> isEndBrace = GetMatchBracePredicate(GetMatchBrace(tok));
+ int nestedLevel = 1;
+ IEnumerable<ScanTokenInfo> iter = GetTokenIter();
+ foreach (ScanTokenInfo tokInfo in iter)
+ {
+ if (isEndBrace(tokInfo.Token))
+ nestedLevel--;
+ else if (isStartBrace(tokInfo.Token))
+ nestedLevel++;
+ if (nestedLevel == 0)
+ return tokInfo;
+ }
+
+ return null;
+ }
+
+
+ private IEnumerable<ScanTokenInfo> GetTokenIter()
+ {
+ bool isScanForward = IsSearchForward(StartBraceInfo.Token);
+ int startLine = StartLine;
+ // 1. Äëÿ ïåðâîé ñòðîêè íàõîäèì òîêåí è íà÷èíàÿ îò íåãî ñêàíèðóåì âïåðåä èëè íàçàä.
+ List<ScanTokenInfo> tokInfs = new List<ScanTokenInfo>(
+ GetLineTokens(startLine, isScanForward));
+ //TODO: Èñêàòü íóæíî íå ïî àäðåñó, à ïî èíäåêñó, òàê êàê GetLineTokens() âîçâðàùàåò êàêæäûé ðàç íîâûå îáúåêòû.
+ int tokIndex = FindIndex(tokInfs, delegate(ScanTokenInfo ti)
+ { return ti.Token.Location == StartBraceInfo.Token.Location; });
+ if (tokIndex < 0)
+ throw new Exception("tokInfs.IndexOf(startBraceInfo)");
+
+ // Scan first line.
+ for (int i = tokIndex + 1; i < tokInfs.Count; i++)
+ yield return tokInfs[i];
+
+ if (isScanForward)
+ for (int i = startLine + 1, count = Source.GetLineCount(); i < count; i++)
+ foreach (ScanTokenInfo tokInf in GetLineTokens(i, true))
+ yield return tokInf;
+ else
+ for (int i = startLine - 1; i >= 0; i--)
+ foreach (ScanTokenInfo tokInf in GetLineTokens(i, false))
+ yield return tokInf;
+ }
+
+ List<ScanTokenInfo> GetLineTokens(int line, bool isForward)
+ {
+ ScanState scanState = GetLineState(line);
+ string lineText = Source.GetLine(line - 1);
+ Scanner.SetSource(lineText, 0);
+ Lex.SetLine(line, lineText, 0, null, null);
+ List<ScanTokenInfo> lst = new List<ScanTokenInfo>();
+
+ foreach (ScanTokenInfo var in GetLineTokens(Lex, scanState))
+ lst.Add(var.Clone());
+
+ if (!isForward)
+ lst.Reverse();
+
+ return lst;
+ }
+
+ IEnumerable<ScanTokenInfo> GetLineTokens(ScanLexer lex, ScanState scanState)
+ {
+ ScanTokenInfo info = lex.GetToken(scanState);
+ scanState = info.State;
+ while (!info.IsEndOfLine)
+ {
+ yield return info;
+ info = lex.GetToken(scanState);
+ scanState = info.State;
+ }
+ }
+
+ private ScanState GetLineState(int line)
+ {
+ int state;
+ ErrorHandler.ThrowOnFailure(
+ ColorState.GetColorStateAtStartOfLine(line, out state));
+ return (ScanState)state;
+ }
+
+ private static bool IsSearchForward(Token token)
+ {
+ if (token is Token.BeginBrace) return true;
+ if (token is Token.BeginQuote) return true;
+ if (token is Token.BeginRound) return true;
+ if (token is Token.BeginSquare) return true;
+
+ if (token is Token.EndBrace) return false;
+ if (token is Token.EndQuote) return false;
+ if (token is Token.EndRound) return false;
+ if (token is Token.EndSquare) return false;
+
+ throw new Exception("The token '" + token + "' not a brace!");
+ }
+
+ private static Predicate<Token> GetMatchBracePredicate(Token token)
+ {
+ if (token is Token.BeginBrace)
+ return delegate(Token t) { return t is Token.BeginBrace; };
+ if (token is Token.BeginQuote)
+ return delegate(Token t) { return t is Token.BeginQuote; };
+ if (token is Token.BeginRound)
+ return delegate(Token t) { return t is Token.BeginRound; };
+ if (token is Token.BeginSquare)
+ return delegate(Token t) { return t is Token.BeginSquare; };
+
+ if (token is Token.EndBrace)
+ return delegate(Token t) { return t is Token.EndBrace; };
+ if (token is Token.EndQuote)
+ return delegate(Token t) { return t is Token.EndQuote; };
+ if (token is Token.EndRound)
+ return delegate(Token t) { return t is Token.EndRound; };
+ if (token is Token.EndSquare)
+ return delegate(Token t) { return t is Token.EndSquare; };
+
+ return null;
+ }
+
+ private static Token GetMatchBrace(Token token)
+ {
+ if (token is Token.BeginBrace) return new Token.EndBrace(true);
+ if (token is Token.BeginQuote) return new Token.EndQuote();
+ if (token is Token.BeginRound) return new Token.EndRound();
+ if (token is Token.BeginSquare) return new Token.EndSquare();
+
+ if (token is Token.EndBrace) return new Token.BeginBrace(true);
+ if (token is Token.EndQuote) return new Token.BeginQuote();
+ if (token is Token.EndRound) return new Token.BeginRound();
+ if (token is Token.EndSquare) return new Token.BeginSquare();
+
+ return null;
+ }
+
+ private static List<T> Reverce<T>(IEnumerable<T> seq)
+ {
+ List<T> lst = new List<T>(seq);
+ lst.Reverse();
+ return lst;
+ }
+
+ static T Find<T>(IEnumerable<T> seq, Predicate<T> predicate) where T : class
+ {
+ foreach (T item in seq)
+ if (predicate(item))
+ return item;
+
+ return null;
+ }
+
+ static int FindIndex<T>(IList<T> lst, Predicate<T> predicate) where T : class
+ {
+ for (int i = 0; i < lst.Count; i++)
+ if (predicate(lst[i]))
+ return i;
+
+ return -1;
+ }
+ }
+
+ #endregion
+
private AuthoringScope Check(ParseRequest request)
{
- Trace.WriteLine(">>>> ##### Check!");
+ Trace.WriteLine((string)">>>> ##### Check!");
try
{
ProjectInfo projectInfo = ProjectInfo.FindProject(request.FileName);
@@ -648,7 +888,7 @@
#region ShowLocation event handler
- void CompiledUnitAstBrowser_ShowLocation(Location loc)
+ void GotoLocation(Location loc)
{
TextSpan span = new TextSpan();
More information about the svn
mailing list