[svn] r6123: vs-plugin: . CtcComponents NemerleAuthoringScope.cs NemerleColorizer.cs NemerleLanguage.cs Ne...

NoiseEHC svnadmin at nemerle.org
Tue Feb 14 20:10:10 CET 2006


Log:
Brace matching working

Author: NoiseEHC
Date: Tue Feb 14 20:10:05 2006
New Revision: 6123

Added:
   vs-plugin/NemerleAuthoringScope.cs
   vs-plugin/NemerleColorizer.cs
   vs-plugin/NemerleProject.csproj.user
Modified:
   vs-plugin/   (props changed)
   vs-plugin/CtcComponents/   (props changed)
   vs-plugin/NemerleLanguage.cs
   vs-plugin/NemerleProject.csproj
   vs-plugin/Templates/ProjectItems/   (props changed)
   vs-plugin/Templates/Projects/   (props changed)

Added: vs-plugin/NemerleAuthoringScope.cs
==============================================================================
--- (empty file)
+++ vs-plugin/NemerleAuthoringScope.cs	Tue Feb 14 20:10:05 2006
@@ -0,0 +1,31 @@
+using System;
+using Microsoft.VisualStudio.Package;
+using Microsoft.VisualStudio.TextManager.Interop;
+
+namespace NemerleProject
+{
+	public class NemerleAuthoringScope : AuthoringScope
+	{
+		public NemerleAuthoringScope()
+			: base() {
+		}
+
+		public override string Goto(Microsoft.VisualStudio.VSConstants.VSStd97CmdID cmd, IVsTextView textView, int line, int col, out TextSpan span) {
+			span = new TextSpan();
+			return null;
+		}
+
+		public override string GetDataTipText(int line, int col, out Microsoft.VisualStudio.TextManager.Interop.TextSpan span) {
+			span = new TextSpan();
+			return null;
+		}
+
+		public override Declarations GetDeclarations(Microsoft.VisualStudio.TextManager.Interop.IVsTextView view, int line, int col, TokenInfo info, ParseReason reason) {
+			return null;
+		}
+
+		public override Methods GetMethods(int line, int col, string name) {
+			return null;
+		}
+	}
+}

Added: vs-plugin/NemerleColorizer.cs
==============================================================================
--- (empty file)
+++ vs-plugin/NemerleColorizer.cs	Tue Feb 14 20:10:05 2006
@@ -0,0 +1,104 @@
+using System;
+using Microsoft.VisualStudio.Package;
+using NC = Nemerle.Compiler;
+
+namespace NemerleProject
+{
+	class NemerleColorizer : IScanner
+	{
+		static NemerleColorizer() {
+			NC.LibraryReferenceManager.LoadMacrosFrom(@"c:\program files\nemerle\Nemerle.Macros.dll");
+			NC.GlobalEnv.Init();
+		}
+
+		public NemerleColorizer() {
+			lexer = new NC.LexerColorizer("");
+		}
+
+		NC.LexerColorizer lexer;
+
+		// Its calling depends on IVsColorizer.GetStateMaintenanceFlag, which defaults to true.
+		public bool ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo, ref int state) {
+			NC.LexerColorizer.SyntaxToken tok = lexer.GetSyntaxToken(ref state);
+
+			// TokenInfo is only read in *.LanguageService.dll
+			tokenInfo.Trigger = TokenTriggers.None;
+			switch(tok.Token) {
+				case NC.SyntaxType.EndOfFile:
+					return false;
+
+				case NC.SyntaxType.Keyword:
+					tokenInfo.Color = TokenColor.Keyword;
+					tokenInfo.Type = TokenType.Keyword;
+					break;
+
+				case NC.SyntaxType.Identifier:
+					tokenInfo.Color = TokenColor.Identifier;
+					tokenInfo.Type = TokenType.Identifier;
+					break;
+
+				case NC.SyntaxType.OperatorDot:
+				case NC.SyntaxType.OperatorBrace:
+				case NC.SyntaxType.Operator:
+					tokenInfo.Color = TokenColor.Keyword;
+					tokenInfo.Type = TokenType.Operator;
+					switch(tok.Token) {
+						case NC.SyntaxType.OperatorBrace:
+							tokenInfo.Trigger = TokenTriggers.MatchBraces;
+							break;
+						case NC.SyntaxType.OperatorDot:
+							tokenInfo.Trigger = TokenTriggers.MemberSelect;
+							break;
+						default:
+							break;
+					}
+					break;
+
+				case NC.SyntaxType.Comment:
+					tokenInfo.Color = TokenColor.Comment;
+					if(state == 0)
+						tokenInfo.Type = TokenType.LineComment;
+					else
+						tokenInfo.Type = TokenType.Comment;
+					break;
+
+				case NC.SyntaxType.CharLiteral:
+					tokenInfo.Color = TokenColor.String;
+					tokenInfo.Type = TokenType.Literal;
+					break;
+
+				case NC.SyntaxType.IntLiteral:
+					tokenInfo.Color = TokenColor.Number;
+					tokenInfo.Type = TokenType.Literal;
+					break;
+
+				case NC.SyntaxType.StringLiteral:
+					tokenInfo.Color = TokenColor.String;
+					tokenInfo.Type = TokenType.String;
+					break;
+
+				default:
+					tokenInfo.Color = TokenColor.Text;
+					tokenInfo.Type = TokenType.Text;
+					break;
+			}
+
+			tokenInfo.StartIndex = tok.StartPos;
+			tokenInfo.EndIndex = tok.EndPos;
+
+			// Nemerle lexer count columns from 0, and the EndPos is inclusive. That is VS expects.
+			//System.Diagnostics.Trace.WriteLine(string.Format("{0},{1} : {2}", tok.StartPos, tok.EndPos, tok.Token.ToString()));
+
+			//TODO: it has to handle whitespace and # (pragma, region, etc)
+			// currently it handles } as a token starting from the beginning of line...
+
+			return true;
+		}
+
+		// The current implementation in *.LanguageService.dll always uses offset 0.
+		public void SetSource(string source, int offset) {
+			lexer.SetString(source, offset);
+			//System.Diagnostics.Trace.WriteLine(source);
+		}
+	}
+}

Modified: vs-plugin/NemerleLanguage.cs
==============================================================================
--- vs-plugin/NemerleLanguage.cs	(original)
+++ vs-plugin/NemerleLanguage.cs	Tue Feb 14 20:10:05 2006
@@ -1,88 +1,63 @@
-
 using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Runtime.InteropServices;
-
 using Microsoft.VisualStudio.Package;
 using Microsoft.VisualStudio.TextManager.Interop;
-
 using NC = Nemerle.Compiler;
 
 //TODO: if you open a single .n file (not a project) then there is no syntax highlight
-//TODO: match_brace finds the pair of braces inside comments (needs real lexer support)
 
 namespace NemerleProject
 {
-	[Guid("0F15B13F-4C95-405f-97A5-7E0E341C4FD3")]
+	[System.Runtime.InteropServices.Guid("0F15B13F-4C95-405f-97A5-7E0E341C4FD3")]
 	class NemerleLanguage : LanguageService
 	{
 		private NemerleColorizer _scanner = null;
 		private LanguagePreferences _preferences = null;
-		private IVsTextLines _buffer = null;
 
-		private TextSpan[] match_braces(ParseRequest req) {
-			int pos;
-			_buffer.GetPositionOfLineIndex(req.Line, req.Col, out pos);
-			--pos;
-			char brace = req.Text[pos];
-			char complement;
-			switch(brace) {
-				case ')':
-					complement = '(';
-					break;
-				case ']':
-					complement = '[';
-					break;
-				case '}':
-					complement = '{';
-					break;
-				default:
-					return null;
-			}
-
-			int nesting = 0;
-
-			do {
-				char curr = req.Text[pos];
-				if(curr == brace)
-					nesting++;
-				else if(curr == complement)
-					nesting--;
-				--pos;
-			}
-			while(pos >= 0 && nesting > 0);
-
-			if(nesting > 0)
-				return null;
-			else {
-				TextSpan[] result = new TextSpan[2];
-				_buffer.GetLineIndexOfPosition(pos + 1, out result[0].iStartLine,
-					out result[0].iStartIndex);
-				result[0].iEndLine = result[0].iStartLine;
-				result[0].iEndIndex = result[0].iStartIndex + 1;
-				result[1].iStartLine = req.Line;
-				result[1].iStartIndex = req.Col - 1;
-				result[1].iEndLine = req.Line;
-				result[1].iEndIndex = req.Col;
-
-				return result;
+		/// <summary>
+		/// Recursively add brace pairs to Sink.
+		/// </summary>
+		/// <param name="Group">Parent token which has Child or Body so we can enumerate</param>
+		/// <param name="Sink">The object holding the braces</param>
+		/// <param name="Level">Recursing depth so the Sink can decide the correct brace to choose when they are nested</param>
+		private void AddBraces(NC.Token Group, AuthoringSink Sink, int Level) {
+			foreach(NC.Token token in Group) {
+				// We cannot optimize by ignoring groups with wrong location early since 
+				// for example loosegroup contains only the first token's location.
+				if(token is NC.Token.RoundGroup || token is NC.Token.BracesGroup || token is NC.Token.SquareGroup || token is NC.Token.QuoteGroup) {
+					// Since PreParse seems to destroy BeginBrace/EndBrace and alike 
+					// we have to calculate the assumed TextSpans.
+					int bracelen = (token is NC.Token.QuoteGroup) ? 2 : 1;
+					//FUCK: seems VS counts lines and columns from 0,0 while Nemerle from 1,1
+					TextSpan start = new TextSpan();
+					start.iStartLine = start.iEndLine = token.Location.Line-1;
+					start.iStartIndex = token.Location.Column-1;
+					start.iEndIndex = start.iStartIndex + bracelen;
+					TextSpan end = new TextSpan();
+					end.iStartLine = end.iEndLine = token.Location.EndLine - 1;
+					end.iStartIndex = token.Location.EndColumn - bracelen - 1;
+					end.iEndIndex = end.iStartIndex + bracelen;
+					Sink.MatchPair(start, end, Level);
+					// Nemerle parser counts lines/columns from 1/1, and the EndPos is exclusive.
+					//System.Diagnostics.Trace.WriteLine(string.Format("{0},{1}-{2},{3} : {4}", token.Location.Line, token.Location.Column, token.Location.EndLine, token.Location.EndColumn, token.ToString()));
+					AddBraces(token, Sink, Level+1);
+				} else if(token is NC.Token.LooseGroup || token is NC.Token.Namespace) {
+					AddBraces(token, Sink, Level+1);
+				}
 			}
 		}
 
 		public override AuthoringScope ParseSource(ParseRequest req) {
 			//System.Diagnostics.Trace.WriteLine(string.Format("ParseSource{0}", req.Reason));
-			if(req.Reason != ParseReason.MatchBraces)
+			// HighlightBraces -> Show brace pairs when moving cursor
+			// MatchBraces -> Jump to maching brace pair when pressed Ctrl+]
+			if(req.Reason != ParseReason.HighlightBraces && req.Reason != ParseReason.MatchBraces)
 				return new NemerleAuthoringScope();
 
-			NC.LexerColorizer lexer = new NC.LexerColorizer(req.Text);
-			int state = 0;
-			while(true) {
-				NC.LexerColorizer.SyntaxToken tok = lexer.GetSyntaxToken(ref state);
-				if(tok.Token == NC.SyntaxType.EndOfFile)
-					break;
-				//if(tok.Token == Nemerle.Compiler.SyntaxType.OperatorBrace && tok.
-			}
+			NC.LexerString lexer = new Nemerle.Compiler.LexerString(req.Text, new NC.Location(0, 1, 1));
+			NC.PreParser preparser = new Nemerle.Compiler.PreParser(lexer);
+			NC.Token.BracesGroup braces = preparser.PreParse();
+
+			AddBraces(braces, req.Sink, 0);
 
 			return new NemerleAuthoringScope();
 		}
@@ -95,8 +70,6 @@
 		public override IScanner GetScanner(IVsTextLines buffer) {
 			if(_scanner == null)
 				_scanner = new NemerleColorizer();
-			this._buffer = buffer;
-
 			return _scanner;
 		}
 
@@ -109,129 +82,7 @@
 				_preferences.EnableMatchBracesAtCaret = true; // hilites braces when cursor moved over them
 				//_preferences.IndentStyle = IndentingStyle.Smart;
 			}
-
 			return _preferences;
 		}
 	}
-
-	class NemerleColorizer : IScanner
-	{
-		static NemerleColorizer() {
-			NC.LibraryReferenceManager.LoadMacrosFrom(@"c:\program files\nemerle\Nemerle.Macros.dll");
-			NC.GlobalEnv.Init();
-		}
-
-		public NemerleColorizer() {
-			lexer = new NC.LexerColorizer("");
-		}
-
-		#region IScanner Members
-
-		NC.LexerColorizer lexer;
-
-		// Its calling depends on IVsColorizer.GetStateMaintenanceFlag, which defaults to true.
-		public bool ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo, ref int state) {
-			NC.LexerColorizer.SyntaxToken tok = lexer.GetSyntaxToken(ref state);
-
-			// TokenInfo is only read in *.LanguageService.dll
-			tokenInfo.Trigger = TokenTriggers.None;
-			switch(tok.Token) {
-				case NC.SyntaxType.EndOfFile:
-					return false;
-
-				case NC.SyntaxType.Keyword:
-					tokenInfo.Color = TokenColor.Keyword;
-					tokenInfo.Type = TokenType.Keyword;
-					break;
-
-				case NC.SyntaxType.Identifier:
-					tokenInfo.Color = TokenColor.Identifier;
-					tokenInfo.Type = TokenType.Identifier;
-					break;
-
-				case NC.SyntaxType.OperatorDot:
-				case NC.SyntaxType.OperatorBrace:
-				case NC.SyntaxType.Operator:
-					tokenInfo.Color = TokenColor.Keyword;
-					tokenInfo.Type = TokenType.Operator;
-					switch(tok.Token) {
-						case NC.SyntaxType.OperatorBrace:
-							tokenInfo.Trigger = TokenTriggers.MatchBraces;
-							break;
-						case NC.SyntaxType.OperatorDot:
-							tokenInfo.Trigger = TokenTriggers.MemberSelect;
-							break;
-						default:
-							break;
-					}
-					break;
-
-				case NC.SyntaxType.Comment:
-					tokenInfo.Color = TokenColor.Comment;
-					if(state == 0)
-						tokenInfo.Type = TokenType.LineComment;
-					else
-						tokenInfo.Type = TokenType.Comment;
-					break;
-
-				case NC.SyntaxType.CharLiteral:
-					tokenInfo.Color = TokenColor.String;
-					tokenInfo.Type = TokenType.Literal;
-					break;
-
-				case NC.SyntaxType.IntLiteral:
-					tokenInfo.Color = TokenColor.Number;
-					tokenInfo.Type = TokenType.Literal;
-					break;
-
-				case NC.SyntaxType.StringLiteral:
-					tokenInfo.Color = TokenColor.String;
-					tokenInfo.Type = TokenType.String;
-					break;
-
-				default:
-					tokenInfo.Color = TokenColor.Text;
-					tokenInfo.Type = TokenType.Text;
-					break;
-			}
-
-			tokenInfo.StartIndex = tok.StartPos;
-			tokenInfo.EndIndex = tok.EndPos;
-
-			return true;
-		}
-
-		// The current implementation in *.LanguageService.dll always uses offset 0.
-		public void SetSource(string source, int offset) {
-			lexer.SetString(source, offset);
-			System.Diagnostics.Trace.WriteLine(source);
-		}
-
-		#endregion
-	}
-
-	public class NemerleAuthoringScope : AuthoringScope
-	{
-		public NemerleAuthoringScope()
-			: base() {
-		}
-
-		public override string Goto(Microsoft.VisualStudio.VSConstants.VSStd97CmdID cmd, IVsTextView textView, int line, int col, out TextSpan span) {
-			span = new TextSpan();
-			return null;
-		}
-
-		public override string GetDataTipText(int line, int col, out Microsoft.VisualStudio.TextManager.Interop.TextSpan span) {
-			span = new TextSpan();
-			return null;
-		}
-
-		public override Declarations GetDeclarations(Microsoft.VisualStudio.TextManager.Interop.IVsTextView view, int line, int col, TokenInfo info, ParseReason reason) {
-			return null;
-		}
-
-		public override Methods GetMethods(int line, int col, string name) {
-			return null;
-		}
-	}
 }

Modified: vs-plugin/NemerleProject.csproj
==============================================================================
--- vs-plugin/NemerleProject.csproj	(original)
+++ vs-plugin/NemerleProject.csproj	Tue Feb 14 20:10:05 2006
@@ -58,6 +58,10 @@
       <Name>Microsoft.VisualStudio.TextManager.Interop</Name>
     </Reference>
     <Reference Include="Microsoft.VisualStudio.TextManager.Interop.8.0, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+    <Reference Include="Nemerle, Version=0.9.1.0, Culture=neutral, PublicKeyToken=e080a9c724e2bfcd, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\..\..\Nemerle\Nemerle.dll</HintPath>
+    </Reference>
     <Reference Include="Nemerle.Compiler, Version=0.9.1.0, Culture=neutral, PublicKeyToken=5291d186334f6101, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\..\..\Nemerle\Nemerle.Compiler.dll</HintPath>
@@ -82,6 +86,8 @@
     <Compile Include="AssemblyInfo.cs">
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="NemerleAuthoringScope.cs" />
+    <Compile Include="NemerleColorizer.cs" />
     <Compile Include="NemerleLanguage.cs" />
     <Compile Include="NemerleFileNode.cs" />
     <Compile Include="NemerleMenus.cs" />

Added: vs-plugin/NemerleProject.csproj.user
==============================================================================
--- (empty file)
+++ vs-plugin/NemerleProject.csproj.user	Tue Feb 14 20:10:05 2006
@@ -0,0 +1,7 @@
+ďťż<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <StartAction>Program</StartAction>
+    <StartProgram>C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.exe</StartProgram>
+    <StartArguments>/rootsuffix Exp</StartArguments>
+  </PropertyGroup>
+</Project>
\ No newline at end of file



More information about the svn mailing list