[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