[svn] r6600: vs-plugin/trunk: Nemerle.Compiler.Utils Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.csproj ...

VladD2 svnadmin at nemerle.org
Sat Sep 2 20:32:17 CEST 2006


Log:
1. Optimized editing in methods body (add relocation support).
2. Added displaying of compiler messages.

Author: VladD2
Date: Sat Sep  2 20:31:51 2006
New Revision: 6600

Added:
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Relocation.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-Relocation.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.CompilerMessages.n
   vs-plugin/trunk/Nemerle.VsIntegration/NemerleAuthoringSink.cs
Modified:
   vs-plugin/trunk/Nemerle.Compiler.Utils/   (props changed)
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.csproj
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.nproj
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CompilerMessage.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-main.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.Init.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.Properties.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.crud.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/TraceWriter.n
   vs-plugin/trunk/Nemerle.VsIntegration/Engine/ProjectInfo.cs
   vs-plugin/trunk/Nemerle.VsIntegration/Nemerle.VsIntegration.csproj
   vs-plugin/trunk/Nemerle.VsIntegration/NemerleLanguage.cs
   vs-plugin/trunk/Nemerle.VsIntegration/NemerleSource.cs
   vs-plugin/trunk/Nemerle.VsIntegration/Parsing/NemerleAuthoringScope.cs

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.csproj
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.csproj	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.csproj	Sat Sep  2 20:31:51 2006
@@ -20,7 +20,7 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DefineConstants>TRACE;DEBUG</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
@@ -94,6 +94,15 @@
   <ItemGroup>
     <Compile Include="Nemerle.Completion2\CodeModel\Project.MakeCompletionList.n" />
   </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Nemerle.Completion2\CodeModel\Project.Relocation.n" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Nemerle.Completion2\Engine\Engine-Relocation.n" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Nemerle.Completion2\Engine\Engine.CompilerMessages.n" />
+  </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
@@ -103,4 +112,8 @@
   </Target>
   -->
   <Import Project="$(Nemerle)\Nemerle.MSBuild.targets" />
+  <!-- Add user defined preprocessor directives -->
+  <PropertyGroup Condition=" '$(UserDefinedConstants)' != '' ">
+    <DefineConstants>$(DefineConstants);$(UserDefinedConstants)</DefineConstants>
+  </PropertyGroup>
 </Project>
\ No newline at end of file

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.nproj
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.nproj	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.nproj	Sat Sep  2 20:31:51 2006
@@ -3,4 +3,12 @@
   <PropertyGroup>
     <ProjectGuid>{dbc77173-9367-485f-b425-74e6d6ab3f82}</ProjectGuid>
   </PropertyGroup>
+  <ItemGroup>
+    <Folder Include="Nemerle.Completion2\" />
+    <Folder Include="Nemerle.Completion2\CodeModel\" />
+    <Folder Include="Nemerle.Completion2\Engine\" />
+    <Folder Include="Nemerle.Completion2\Tests\" />
+    <Folder Include="Nemerle.Completion2\Tests\Content\" />
+    <Folder Include="Properties\" />
+  </ItemGroup>
 </Project>
\ No newline at end of file

Added: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Relocation.n
==============================================================================
--- (empty file)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Relocation.n	Sat Sep  2 20:31:51 2006
@@ -0,0 +1,73 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+using Nemerle.Assertions;
+using Nemerle.Collections;
+using Nemerle.Compiler;
+using Nemerle.Compiler.Parsetree;
+using Nemerle.Imperative;
+using Nemerle.Utility;
+
+using SR = System.Reflection;
+using SCG = System.Collections.Generic;
+using Nemerle.Compiler.Utils;
+using Typed = Nemerle.Compiler.Typedtree;
+
+
+namespace Nemerle.Completion2
+{
+	public partial class Project
+	{
+    /// This method add relocation information, if changes made in 
+    /// methode/property accessor body or in fields initialisation expression.
+    /// If relocation added this method return true. Otherwise false.
+    /// If relocation not added we must repars all project files.
+    public AddRelocation(
+      filePath : string,
+      newEndChar : int, newEndLine : int,
+      oldEndChar : int, oldEndLine : int,
+      startChar  : int, startLine  : int
+    ) : bool
+    {
+      def fileIndex = _compileUnits.GetFileIndex(filePath);
+
+      def getMember(fileIndex, line, col)
+      {
+        def decl = GetActiveDecl(fileIndex, line, col);
+        
+        match (decl)
+        {
+          | Decl.Type as ty => ty.Builder.GetActiveMember(fileIndex, line, col);
+          | GlobalAttribute | Using | Namespace | None => null
+        }
+      }
+
+      def member1 = getMember(fileIndex, startLine, startChar);
+      if (member1 == null)
+        false
+      else
+      {
+        def member2 = getMember(fileIndex, oldEndLine, oldEndChar);
+        if (member2 == null || !object.ReferenceEquals(member1, member2))
+          false
+        else match (member1)
+        {
+            | method is MethodBuilder =>
+              def loc = method.BodyLocation;
+        
+              if (loc.Contains(startLine, startChar) && loc.Contains(startLine, startChar))
+              {
+                this.Engine.AddRelocation(fileIndex, newEndChar, newEndLine, oldEndChar, oldEndLine);
+                this.Engine.Output.WriteLine(loc);
+                true
+              }
+              else
+                false
+
+            | _ => false
+        }
+      }
+    } // AddRelocation
+  } // end class Engine
+} // end namespace
+

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n	Sat Sep  2 20:31:51 2006
@@ -28,12 +28,18 @@
         | method is MethodBuilder => 
           // Adjust the body location...
           def loc = method.BodyLocation;
+          def sl = loc.Line;
+          def el = loc.EndLine;
+
           // IT: ÷ňî ĺńëč čńďîëüçóĺňń˙ âŕđčŕíň ńčíňŕęńčńŕ áĺç ńęîáîę?
           //
           def colStart = loc.Column + 1;  // exclude open brace
           def colEnd = loc.EndColumn - 1; // exclude close brace
           def loc = Location(loc.FileIndex, loc.Line, colStart, loc.EndLine, colEnd);
 
+          ignore(sl);
+          ignore(el);
+
           if (loc.Contains(line, col)) // completion in method body
           {
             def bodyCode = getText(loc.Line, colStart, loc.EndLine, colEnd);
@@ -83,7 +89,7 @@
       {
       | method is MethodBuilder =>
 
-        def location = method.Body.Location;
+        def location = method.BodyLocation;
 
         if (location.Contains(line, col)) // in method body
         {

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.n	Sat Sep  2 20:31:51 2006
@@ -127,8 +127,6 @@
       }
     }
 
-#define PRINT_AST
-
     private FindLocatedExpr(
       root : PExpr,
       line : int,

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CompilerMessage.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CompilerMessage.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CompilerMessage.n	Sat Sep  2 20:31:51 2006
@@ -8,5 +8,10 @@
     public mutable Message : string;
     public mutable Location : Location;
     public mutable MessageKind : MessageKind;
+
+    public override ToString() : string
+    {
+      $"$(this.MessageKind) ($(this.Location)): $Message"
+    }
   }
 }

Added: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-Relocation.n
==============================================================================
--- (empty file)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-Relocation.n	Sat Sep  2 20:31:51 2006
@@ -0,0 +1,68 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+using SCG = System.Collections.Generic;
+using Nemerle.Assertions;
+using Nemerle.Collections;
+using Nemerle.Compiler;
+using Nemerle.Compiler.Parsetree;
+using Nemerle.Imperative;
+using Nemerle.Utility;
+
+using Nemerle.Compiler.Utils;
+using Typed = Nemerle.Compiler.Typedtree;
+using SR = System.Reflection;
+
+namespace Nemerle.Completion2
+{
+  public partial class Engine
+  {
+    internal AddRelocation(
+      fileIndex : int,
+      newEndChar : int, newEndLine : int,
+      oldEndChar : int, oldEndLine : int
+    ) : void
+    {
+      def (firstLine, firstChar, lineOffset, charOffset) =
+        if (newEndLine == oldEndLine && newEndChar > oldEndChar)
+          (oldEndLine, oldEndChar, 0, newEndChar - oldEndChar)
+        else
+          (oldEndLine, oldEndChar, newEndLine - oldEndLine, 0);
+
+      def relMap = RelocationMaps[fileIndex];
+
+      if (relMap == null) // no relocations
+      {
+        def newMap = SCG.List();
+        RelocationMaps[fileIndex] = newMap;
+        newMap.Add(Relocation(firstLine, firstChar, lineOffset, charOffset));
+      }
+      else // exists some relocations
+      {
+        def res = relMap.BinarySearch (elem => elem.Line - firstLine);
+        def index = if (res < 0) ~res else res;
+
+        def prevLineOffset = if (index > 0) relMap[index - 1].LineOffset else 0;
+
+        if (res < 0)
+          relMap.Insert(index, Relocation(firstLine, firstChar, 
+            lineOffset + prevLineOffset, charOffset));
+        else
+        {
+          def rel = relMap[index];
+          relMap[index] = Relocation(firstLine, Math.Min(firstChar, rel.Column),
+            rel.LineOffset + lineOffset, rel.ColumnOffset + charOffset)
+        }
+
+        for (mutable i = index + 1; i < relMap.Count; i++)
+        {
+          def rel = relMap[i];
+          def newRel = Relocation(rel.Line, rel.Column + lineOffset,
+            rel.LineOffset + lineOffset, rel.ColumnOffset);
+          relMap[i] = newRel;
+        }
+      }
+    }
+  } // end class Engine
+} // end namespace
+

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-main.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-main.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-main.n	Sat Sep  2 20:31:51 2006
@@ -31,8 +31,7 @@
       this.Hierarchy = TypesManager (this);
 
       mutable trees = [];
-      try
-      {
+
           foreach ((filePath, fileInfo) in Sources._sources.KeyValuePairs)
           {
               match (fileInfo)
@@ -56,8 +55,6 @@
               //  trees ::= p.decls;
               }
           }
-      }
-      catch { | _e => Trace.WriteLine(_e); }
        
       // create N.C.TypeBuilders for all parsed types and add them to namespace hierarchy
       try

Added: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.CompilerMessages.n
==============================================================================
--- (empty file)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.CompilerMessages.n	Sat Sep  2 20:31:51 2006
@@ -0,0 +1,68 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+using SCG = System.Collections.Generic;
+using Nemerle.Assertions;
+using Nemerle.Collections;
+using Nemerle.Compiler;
+using Nemerle.Compiler.Parsetree;
+using Nemerle.Imperative;
+using Nemerle.Utility;
+
+using Nemerle.Compiler.Utils;
+using Typed = Nemerle.Compiler.Typedtree;
+using SR = System.Reflection;
+
+
+namespace Nemerle.Completion2
+{
+	public partial class Engine
+	{
+    public ClearCompilerMessages() : void
+    {
+      _listMessages.Clear();
+    }
+
+    public AddCompilerMessage(location : Location, kind : MessageKind, message : string) : void
+    {
+      mutable error = CompilerMessage();
+      error.MessageKind = kind;
+      error.Location = location;
+      error.Message = message;
+      _listMessages.Add(error);
+    }
+
+    public AddErrorMessage(location : Location, message : string) : void
+    {
+      AddCompilerMessage(location, MessageKind.Error, message);
+    }
+
+    public AddWarningMessage(location : Location, message : string) : void
+    {
+      AddCompilerMessage(location, MessageKind.Warning, message);
+    }
+
+    public AddHintMessage(location : Location, message : string) : void
+    {
+      AddCompilerMessage(location, MessageKind.Hint, message);
+    }
+
+    _listMessages : SCG.List[CompilerMessage] = SCG.List();
+
+    ProcessErrorMessage(location : Location, message : string) : void
+    {
+      mutable error = CompilerMessage();
+      error.Location = location;
+      if (message.IndexOf ("error: ") != -1)
+        AddErrorMessage(location, message.Substring(
+          message.IndexOf("error: ")).Replace ("error: ", ""));
+      else if (message.IndexOf("warning: ") != -1)
+        AddWarningMessage(location, message.Substring(
+          message.IndexOf("warning: ")).Replace("warning: ", ""));
+      else when (message.IndexOf ("hint: ") != -1)
+        AddHintMessage(location, message.Substring(
+            message.IndexOf("hint: ")).Replace("hint: ", ""));
+    }
+  } // end class Engine
+} // end namespace
+

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.Init.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.Init.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.Init.n	Sat Sep  2 20:31:51 2006
@@ -34,7 +34,7 @@
       _defines = DefineCollection (this);
       _references = ReferenceCollection (this);
       _sources = SourceCollection ();
-      MessageOccured += process_error_message;
+      MessageOccured += ProcessErrorMessage;
       Options.GreedyReferences = true;
       Options.ColorMessages = false;
       Options.IgnoreConfusion = true;
@@ -63,7 +63,6 @@
       // next time Init is called, we won't rebuild external types
       _state = EngineState.LoadedLibs; 
       // Sources.set_unparsed_state ();
-      _listMessages = [];
     }
   } // end class Engine
 } // end namespace

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.Properties.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.Properties.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.Properties.n	Sat Sep  2 20:31:51 2006
@@ -25,13 +25,6 @@
     [Accessor]         _sources    : SourceCollection;
     [Accessor] mutable _state      : EngineState;
     
-    mutable _isInCompletionMode : bool;
-
-    public override IsInCompletionMode : bool
-    {
-      get { _isInCompletionMode }
-    }
-    
     // If you want to recover the messages done by the parser/typer
     public Output : System.IO.TextWriter
     {
@@ -41,13 +34,7 @@
     
     public CompilerMessages : array[CompilerMessage]
     {
-      get
-      {
-        if (_listMessages == null)
-          array(0)
-        else
-          _listMessages.ToArray ()
-      }
+      get { _listMessages.ToArray() }
     }
   } // end class Engine
 } // end namespace

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.crud.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.crud.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine.crud.n	Sat Sep  2 20:31:51 2006
@@ -27,36 +27,6 @@
     {
       LibrariesManager.AddAssembly(assembly);
     }
-
-    mutable _listMessages : list[CompilerMessage];
-
-    process_error_message (location : Location, message : string) : void
-    {
-      mutable error = CompilerMessage();
-      error.Location = location;
-      if (message.IndexOf ("error: ") != -1)
-      {
-          error.Message = message.Substring(
-            message.IndexOf("error: ")).Replace ("error: ", "");
-          error.MessageKind = MessageKind.Error;
-          _listMessages ::= error;
-      }
-      else if (message.IndexOf("warning: ") != -1)
-      {
-          error.Message = message.Substring(
-            message.IndexOf("warning: ")).Replace("warning: ", "");
-          error.MessageKind = MessageKind.Warning;
-          _listMessages ::= error;
-      }
-      else when (message.IndexOf ("hint: ") != -1)
-      {
-          error.Message = message.Substring(
-            message.IndexOf("hint: ")).Replace("hint: ", "");
-
-          error.MessageKind = MessageKind.Hint;
-          _listMessages ::= error;
-      }
-    }
   } // end class Engine
 } // end namespace
 

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/TraceWriter.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/TraceWriter.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/TraceWriter.n	Sat Sep  2 20:31:51 2006
@@ -26,22 +26,6 @@
       Trace.Write(result);
     }
 
-    //public override Write(value : string) : void
-    //{
-    //	def value = value.Replace('`', '\'');
-    //	def rx = Regex(@"(.+?):(\d+):(\d+):(\d+):(\d+):(.*)");
-    //	def mtch = rx.Match(value);
-    //	if (mtch.Groups.Count == 7)
-    //	{
-    //    def m(index : int) : string { mtch.Groups[index].Value; }
-    //    def (m1, m2, m3, m4, m5, m6) = (m(1), m(2), m(3), m(4), m(5), m(6));
-    //    def msg = $"$m1($m2,$m3,$m4,$m5):$m6";
-    //		Trace.Write(msg);
-    //	}
-    //	else
-    //		Trace.Write(value);
-    //}
-
     public override WriteLine(value : string) : void
     {
       Write(value);

Modified: vs-plugin/trunk/Nemerle.VsIntegration/Engine/ProjectInfo.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/Engine/ProjectInfo.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/Engine/ProjectInfo.cs	Sat Sep  2 20:31:51 2006
@@ -220,16 +220,55 @@
 			return null;
 		}
 
+		Project _project;
+
+		public bool IsTypeTreeParsed
+		{
+			get { return _project != null; }
+		}
+
+		public void ResetTypeTree() { _project = null; }
+
+		public void AddRelocation(
+			string filePath,
+			int newEndIndex, int newEndLine,
+			int oldEndIndex, int oldEndLine,
+			int startIndex, int startLine
+		)
+		{
+			if (!IsTypeTreeParsed)
+				return;
+
+			Trace.Assert(_project != null);
+
+			// If can't add relocation we must reparse types tree.
+			if (!Project.AddRelocation(filePath, newEndIndex, newEndLine, 
+				oldEndIndex, oldEndLine, startIndex, startLine)
+			)
+				ResetTypeTree();
+		}
+
+
+		public Project Project
+		{
+			get
+			{
+				if (_project == null)
+					_project = Engine.GetProject();
+
+				return _project;
+			}
+		}
+
 		internal CompletionElem[] CompleteWord(
 			string filePath, int line, int col, GetText getText)
 		{
-			Project project = Engine.GetProject();
-			return project.CompleteWord(filePath, line + 1, col + 1, getText);
+			return Project.CompleteWord(filePath, line + 1, col + 1, getText);
 		}
 
 		public QuickTipInfo GetQuickTip(string filePath, int line, int col, GetText getText)
 		{
-			QuickTipInfo info = Engine.GetProject().GetQuickTipInfo(filePath, line + 1, col + 1, getText);
+			QuickTipInfo info = Project.GetQuickTipInfo(filePath, line + 1, col + 1, getText);
 
 			if (info != null)
 				info.Text = info.Text.Replace(_projectLocation, "");

Modified: vs-plugin/trunk/Nemerle.VsIntegration/Nemerle.VsIntegration.csproj
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/Nemerle.VsIntegration.csproj	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/Nemerle.VsIntegration.csproj	Sat Sep  2 20:31:51 2006
@@ -136,6 +136,7 @@
       <Link>RegistrationAttributes\WebSiteProjectRelatedFilesAttribute.cs</Link>
     </Compile>
     <Compile Include="Automation.cs" />
+    <Compile Include="NemerleAuthoringSink.cs" />
     <Compile Include="Utils.cs" />
     <Compile Include="ConfigurationPropertyPages.cs" />
     <Compile Include="EditorFactory.cs" />

Added: vs-plugin/trunk/Nemerle.VsIntegration/NemerleAuthoringSink.cs
==============================================================================
--- (empty file)
+++ vs-plugin/trunk/Nemerle.VsIntegration/NemerleAuthoringSink.cs	Sat Sep  2 20:31:51 2006
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.VisualStudio.Package;
+using Microsoft.Samples.VisualStudio.NemerleLanguageService;
+
+namespace Nemerle.VsIntegration
+{
+	public class NemerleAuthoringSink : AuthoringSink
+	{
+		public NemerleAuthoringSink(
+			NemerleSource source, 
+			ParseReason reason, 
+			int line, 
+			int col, 
+			int maxErrors) : base(reason, line, col, maxErrors)
+		{
+			_source = source;
+		}
+
+		NemerleSource _source;
+
+		public NemerleSource Source
+		{
+			get { return _source; }
+		}
+	}
+}

Modified: vs-plugin/trunk/Nemerle.VsIntegration/NemerleLanguage.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/NemerleLanguage.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/NemerleLanguage.cs	Sat Sep  2 20:31:51 2006
@@ -164,7 +164,7 @@
 						Trace.Assert(false, ex.ToString());
 						Trace.WriteLine(ex);
 					}
-					return new NemerleAuthoringScope();
+					return new NemerleAuthoringScope((NemerleAuthoringSink)request.Sink);
 				case ParseReason.DisplayMemberList:
 					break;
 				case ParseReason.Goto:
@@ -197,7 +197,7 @@
 
 			//NemerleSink sink = new NemerleSink(req.Sink);
 			//return new NemerleScope(modules.AnalyzeModule(sink, req.FileName, req.Text), this);
-			return new NemerleAuthoringScope();
+			return new NemerleAuthoringScope((NemerleAuthoringSink)request.Sink);
 		}
 
 		AuthoringScope GetRequestedScope(ParseRequest request)
@@ -215,15 +215,16 @@
 			if (text.Length == 0 || text[0] == ' ' || text[0] == '\t')
 				return null;
 
-			ProjectInfo project = ProjectInfo.FindProject(request.FileName);
+			ProjectInfo projectInfo = ProjectInfo.FindProject(request.FileName);
 
-			if (project == null)
+			if (projectInfo == null)
 				return null;
 
-			project.UpdateFile(request);
+			projectInfo.UpdateFile(request);
 
 			return new NemerleAuthoringScope(
-				project, request.FileName,
+				(NemerleAuthoringSink)request.Sink,
+				projectInfo, request.FileName,
 				delegate(int lineStart, int colStart, int lineEnd, int colEnd)
 				{
 					return GetCodeRegion(request, lineStart - 1, colStart - 1, lineEnd - 1, colEnd - 1);
@@ -259,11 +260,11 @@
 				foreach (object overload in overloads)
 					Trace.WriteLine("#    " + overload);
 
-				return new NemerleAuthoringScope(overloads);
+				return new NemerleAuthoringScope((NemerleAuthoringSink)request.Sink, overloads);
 			}
 
 			Trace.WriteLine("### RunCompletionEngine() return empty list!");
-			return new NemerleAuthoringScope();
+			return new NemerleAuthoringScope((NemerleAuthoringSink)request.Sink);
 		}
 
 		string GetCodeRegion(ParseRequest request, int startLine, int startCol,

Modified: vs-plugin/trunk/Nemerle.VsIntegration/NemerleSource.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/NemerleSource.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/NemerleSource.cs	Sat Sep  2 20:31:51 2006
@@ -11,6 +11,14 @@
 
 using Microsoft.VisualStudio.Package;
 using Microsoft.VisualStudio.TextManager.Interop;
+using Nemerle.Completion2;
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+using Microsoft.VisualStudio;
+using Nemerle.VsIntegration;
 
 namespace Microsoft.Samples.VisualStudio.NemerleLanguageService
 {
@@ -43,5 +51,287 @@
 		{
 			base.Completion(textView, info, reason);
 		}
+
+		public override void OnChangeLineText(TextLineChange[] lineChange, int last)
+		{
+			//TODO: Ńţäŕ íóćíî âńňŕâčňü ęîä îáíîâë˙ţůčé ëîęĺéřîíű â äĺđĺâĺ ňčďîâ ĺńëč đĺäŕęňčđîâŕíčĺ
+			// ďđîčńőîäčň âíóňđč âűđŕćĺíčé č îáíóë˙ňü äĺđĺâî ňčďîâ â îáđŕňîíîě ńëó÷ŕĺ.
+			// Ĺńëč äĺđĺâî ňčďîâ íĺň, ňî íč÷ĺăî íĺ äĺëŕĺě.
+
+			string fileName = GetFilePath();
+			ProjectInfo projectInfo = ProjectInfo.FindProject(fileName);
+
+			for (int i = 0; i < lineChange.Length; i++)
+			{
+				TextLineChange changes = ConvertToLocation(lineChange[i]);
+				projectInfo.AddRelocation(
+					fileName,
+					changes.iNewEndIndex, changes.iNewEndLine,
+					changes.iOldEndIndex, changes.iOldEndLine,
+					changes.iStartIndex, changes.iStartLine);
+			}
+
+			//{
+			//  Project project = projectInfo.Project;
+			//  int fileIndex = project.CompileUnits.GetFileIndex(fileName);
+
+			//  for (int i = 0; i < lineChange.Length; i++)
+			//  {
+			//    TextLineChange changes = ConvertToLocation(lineChange[i]);
+			//    PExpr expr = project.GetActiveExpressinOrNull(fileIndex, line, col);
+			//    if (expr != null)
+			//    {
+			//      project.
+			//    }
+
+			//    int line = Math.Min(changes.iStartLine, changes.iOldEndLine);
+			//    //áđĺä int col = Math.Min(changes.iStartIndex, changes.iOldEndIndex);
+			//    Decl decl = project.GetActiveDecl(fileIndex, line, col);
+			//    Decl.Type ty = decl as Decl.Type;
+			//    if (ty == null)
+			//    {
+			//      projectInfo.ResetTypeTree();
+			//      break;
+			//    }
+			//    else
+			//    {
+			//      ty.Builder
+			//      Trace.WriteLine(decl);
+			//    }
+			//  }
+			//}
+
+			base.OnChangeLineText(lineChange, last);
+		}
+
+		private static TextLineChange ConvertToLocation(TextLineChange changes)
+		{
+			changes.iNewEndIndex++;
+			changes.iNewEndLine++;
+			changes.iOldEndIndex++;
+			changes.iOldEndLine++;
+			changes.iStartIndex++;
+			changes.iStartLine++;
+			return changes;
+		}
+
+		internal class ErrorNode
+		{
+			public string Uri;
+			public string Message;
+			public TextSpan Context;
+			public Severity Severity;
+
+			public ErrorNode(string uri, string message, TextSpan context, Severity severity)
+			{
+				Uri = uri;
+				Message = message;
+				Context = context;
+				Severity = severity;
+			}
+		}
+
+		internal void ReportMessage(IList<ErrorNode> errors)
+		{
+			TaskProvider taskProvider = GetTaskProvider();
+
+			if (errors == null || errors.Count == 0)
+			{
+				if (taskProvider.Tasks.Count > 0)
+					taskProvider.Tasks.Clear();
+
+				return;
+			}
+
+			int removed = 0;
+			int added = 0;
+			int merged = 0;
+			int errorMax = LanguageService.Preferences.MaxErrorMessages;
+			string fname = GetFilePath();
+			RunningDocumentTable rdt = new RunningDocumentTable(LanguageService.Site);
+			IVsHierarchy thisHeirarchy = rdt.GetHierarchyItem(fname);
+
+			// Here we merge errors lists to reduce flicker.  It is not a very intelligent merge
+			// but that is ok, the worst case is the task list flickers a bit.  But 99% of the time
+			// one error is added or removed as the user is typing, and this merge will reduce flicker
+			// in this case.
+			taskProvider.SuspendRefresh(); // batch updates.
+
+			try
+	    {	        
+		    int pos = 0;
+				TaskErrorCategory mostSevere = TaskErrorCategory.Message;
+
+				for (int i = 0, n = errors.Count; i < n; i++)
+				{
+					ErrorNode enode = (ErrorNode)errors[i];
+					string filename = enode.Uri;
+					bool thisFile = (!string.IsNullOrEmpty(filename) && NativeMethods.IsSamePath(fname, filename));
+					TextSpan span = enode.Context;
+					Severity severity = enode.Severity;
+					string message = enode.Message;
+
+					if (message == null)
+						continue;
+
+					// Don't do multi-line squiggles, instead just squiggle to the
+					// end of the first line.
+					if (span.iEndLine > span.iStartLine)
+					{
+						span.iEndLine = span.iStartLine;
+						NativeMethods.ThrowOnFailure(GetTextLines().GetLengthOfLine(
+							span.iStartLine, out span.iEndIndex));
+					}
+
+					//normalize text span
+					if (thisFile)
+						FixupMarkerSpan(ref span);
+					else
+						TextSpanHelper.MakePositive(ref span);
+
+					//set options
+					TaskPriority priority = TaskPriority.Normal;
+					TaskCategory category = TaskCategory.BuildCompile;
+					MARKERTYPE markerType = MARKERTYPE.MARKER_CODESENSE_ERROR;
+					TaskErrorCategory errorCategory = TaskErrorCategory.Warning;
+
+					if (severity == Severity.Fatal || severity == Severity.Error)
+					{
+						priority = TaskPriority.High;
+						errorCategory = TaskErrorCategory.Error;
+					}
+					else if (severity == Severity.Hint)
+					{
+						category = TaskCategory.Comments;
+						markerType = MARKERTYPE.MARKER_INVISIBLE;
+						errorCategory = TaskErrorCategory.Message;
+					}
+					else if (severity == Severity.Warning)
+					{
+						markerType = MARKERTYPE.MARKER_COMPILE_ERROR;
+						errorCategory = TaskErrorCategory.Warning;
+					}
+
+					if (errorCategory < mostSevere)
+						mostSevere = errorCategory;
+
+					IVsHierarchy hierarchy = thisHeirarchy;
+					if (!thisFile)
+					{
+						// must be an error reference to another file.
+						hierarchy = rdt.GetHierarchyItem(filename);
+						markerType = MARKERTYPE.MARKER_OTHER_ERROR; // indicate to CreateErrorTaskItem
+					}
+
+					bool found = false;
+					while (pos < taskProvider.Tasks.Count)
+					{
+						Task current = taskProvider.Tasks[pos];
+						if (current is DocumentTask)
+						{
+							DocumentTask dt = (DocumentTask)current;
+							if (dt.IsMarkerValid && // marker is still valid?
+									NativeMethods.IsSamePath(current.Document, filename) &&
+									current.Text == message && TextSpanHelper.IsSameSpan(span, dt.Span) &&
+									current.Category == category &&
+									current.Priority == priority &&
+									dt.ErrorCategory == errorCategory
+							)
+							{
+								pos++;
+								merged++;
+								found = true;
+								// Since we're reusing the existing entry, let's make sure the line
+								// line number we are displaying the right line number information.
+								// (The DocumentTask gets out of sync with the IVsTextLineMarker because
+								// the IVsTextLineMarker is a bookmark that tracks user edits). 
+								if (dt.Column != span.iStartIndex || dt.Line != span.iStartLine)
+								{
+									dt.Column = span.iStartIndex;
+									dt.Line = span.iStartLine;
+									taskProvider.Refresh(); // mark it as dirty.
+								}
+								break;
+							}
+						}
+						removed++;
+						taskProvider.Tasks.RemoveAt(pos);
+					}
+
+					if (!found)
+					{
+						added++;
+						DocumentTask docTask = CreateErrorTaskItem(span, filename, message, priority, category, markerType, errorCategory);
+						docTask.HierarchyItem = hierarchy;
+						taskProvider.Tasks.Insert(pos, docTask);
+						pos++;
+					}
+					//check error count
+					if (pos == errorMax)
+					{
+						string maxMsg = "MaxErrorsReached";
+						string localFile = GetFilePath();
+						span = GetDocumentSpan();
+						span.iStartIndex = span.iEndIndex;
+						span.iStartLine = span.iEndLine;
+						DocumentTask error = CreateErrorTaskItem(span, localFile, maxMsg, TaskPriority.High, TaskCategory.CodeSense, MARKERTYPE.MARKER_INVISIBLE, mostSevere);
+						error.HierarchyItem = hierarchy;
+						taskProvider.Tasks.Insert(pos, error);
+						pos++;
+						break;
+					}
+				}
+				// remove trailing errors that should no longer exist.
+				while (pos < taskProvider.Tasks.Count)
+				{
+					removed++;
+					taskProvider.Tasks.RemoveAt(pos);
+				}
+	    }
+	    finally
+	    {
+				taskProvider.ResumeRefresh(); // batch updates.
+	    }
+		}
+
+		internal void FixupMarkerSpan(ref TextSpan span)
+		{
+			// This is similar to TextSpanHelper.Normalize except that 
+			// we try not to create empty spans at end of line, since VS doesn't like
+			// empty spans for text markers.  See comment in CreateMaker in DocumentTask.cs 
+
+			//adjust max. lines
+			int lineCount;
+			if (NativeMethods.Failed(GetTextLines().GetLineCount(out lineCount)))
+				return;
+			span.iEndLine = Math.Min(span.iEndLine, lineCount - 1);
+			//make sure the start is still before the end
+			if (!TextSpanHelper.IsPositive(span))
+			{
+				span.iStartLine = span.iEndLine;
+				span.iStartIndex = span.iEndIndex;
+			}
+			//adjust for line length
+			int lineLength;
+			if (NativeMethods.Failed(GetTextLines().GetLengthOfLine(span.iStartLine, out lineLength)))
+				return;
+			span.iStartIndex = Math.Min(span.iStartIndex, lineLength);
+			if (NativeMethods.Failed(GetTextLines().GetLengthOfLine(span.iEndLine, out lineLength)))
+				return;
+			span.iEndIndex = Math.Min(span.iEndIndex, lineLength);
+
+			if (TextSpanHelper.IsEmpty(span) && span.iStartIndex == lineLength && span.iEndLine + 1 < lineCount)
+			{
+				// Make the span include the newline if it was empty and at the end of the line.
+				span.iEndLine++;
+				span.iEndIndex = 0;
+			}
+		}
+
+		public override AuthoringSink CreateAuthoringSink(ParseReason reason, int line, int col)
+		{
+			int maxErrors = LanguageService.Preferences.MaxErrorMessages;
+			return new NemerleAuthoringSink(this, reason, line, col, maxErrors);
 	}
+	} // end of NemerleSource class
 }
\ No newline at end of file

Modified: vs-plugin/trunk/Nemerle.VsIntegration/Parsing/NemerleAuthoringScope.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/Parsing/NemerleAuthoringScope.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/Parsing/NemerleAuthoringScope.cs	Sat Sep  2 20:31:51 2006
@@ -6,29 +6,38 @@
 
 using Nemerle.Compiler;
 using Nemerle.Completion2;
+using Nemerle.VsIntegration;
+using Microsoft.VisualStudio.Shell;
 
 namespace Microsoft.Samples.VisualStudio.NemerleLanguageService
 {
 	class NemerleAuthoringScope : AuthoringScope
 	{
-		public NemerleAuthoringScope(CompletionElem[] overloadPossibility)
+		public NemerleAuthoringScope(NemerleAuthoringSink sink, CompletionElem[] overloadPossibility)
 		{
+			_sink = sink;
 			_overloadPossibility = overloadPossibility;
 		}
 
-		public NemerleAuthoringScope(ProjectInfo project, string filePath, GetText getText)
-			: this()
+		public NemerleAuthoringScope(
+			NemerleAuthoringSink sink,
+			ProjectInfo project,
+			string filePath,
+			GetText getText
+		) : this(sink)
 		{
 			_project  = project;
 			_filePath = filePath;
 			_getText  = getText;
 		}
 
-		public NemerleAuthoringScope()
+		public NemerleAuthoringScope(NemerleAuthoringSink sink)
 		{
+			_sink = sink;
 			_overloadPossibility = new CompletionElem[0];
 		}
 
+		private NemerleAuthoringSink _sink;
 		private CompletionElem[] _overloadPossibility;
 		private ProjectInfo _project;
 		private string      _filePath;
@@ -40,6 +49,20 @@
 
 			QuickTipInfo info = _project.GetQuickTip(_filePath, line, col, _getText);
 
+			CompilerMessage[] errors = _project.Project.Engine.CompilerMessages;
+
+			TaskProvider prov = _sink.Source.GetTaskProvider();
+			foreach (CompilerMessage error in errors)
+			{
+				Task task = new Task();
+				task.Line = error.Location.Line;
+				task.Column = error.Location.Column;
+				task.Document = _filePath;
+				task.CanDelete = true;
+				task.Text = error.Message;
+				prov.Tasks.Add(task);
+			}
+
 			if (info == null)
 				return null;
 



More information about the svn mailing list