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

kliss svnadmin at nemerle.org
Sat Apr 21 00:41:54 CEST 2007


Log:
- "Find inheritors" feature. See Nemerle -> Navigation -> Find inheritors
- work on formatter

Author: kliss
Date: Sat Apr 21 00:41:41 2007
New Revision: 7603

Added:
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeIndentationStage.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeLineBreakingStage.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/IFormattingStage.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/TokenStreamFinder.n
Modified:
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.csproj
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/Formatter.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/NonEatingLexer.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprWalker.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Refactoring.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ScanLexer.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/TokenFinder.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-Relocation.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/SourceCollection.n
   vs-plugin/trunk/Nemerle.VsIntegration/CtcComponents/PkgCmd.ctc
   vs-plugin/trunk/Nemerle.VsIntegration/CtcComponents/PkgCmdID.h
   vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs
   vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleLanguageService.cs
   vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleSource.cs
   vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.cs
   vs-plugin/trunk/Nemerle.VsIntegration/Project/LibraryNode.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 Apr 21 00:41:41 2007
@@ -161,6 +161,14 @@
   <ItemGroup>
     <Compile Include="Nemerle.Completion2\CodeFormatting\NonEatingLexer.n" />
   </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Nemerle.Completion2\CodeFormatting\CodeIndentationStage.n" />
+    <Compile Include="Nemerle.Completion2\CodeFormatting\CodeLineBreakingStage.n" />
+    <Compile Include="Nemerle.Completion2\CodeFormatting\IFormattingStage.n" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Nemerle.Completion2\CodeFormatting\TokenStreamFinder.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.

Added: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeIndentationStage.n
==============================================================================
--- (empty file)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeIndentationStage.n	Sat Apr 21 00:41:41 2007
@@ -0,0 +1,24 @@
+using System;
+using Nemerle.Utility;
+
+using SCG = System.Collections.Generic;
+
+namespace Nemerle.Completion2.CodeFormatting
+{
+  public class CodeIndentationStage : IFormattingStage
+  {
+    public this (engine : Engine, fileIndex : int)
+    {
+    
+    }
+    
+    public FormatDocument() : SCG.List.[FormatterResult]
+    {
+      SCG.List.[FormatterResult]();
+    }
+    public FormatRegion(startLine : int, startCol : int, endLine : int, endCol : int) : SCG.List.[FormatterResult]
+    {
+      FormatDocument();
+    }
+  }
+}

Added: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeLineBreakingStage.n
==============================================================================
--- (empty file)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeLineBreakingStage.n	Sat Apr 21 00:41:41 2007
@@ -0,0 +1,294 @@
+using System;  
+using System.Diagnostics;
+
+using Nemerle.Utility;
+using Nemerle.Compiler;
+using Nemerle.Compiler.Utils;
+using Nemerle.Completion2;
+using Nemerle.Compiler.Parsetree;
+
+using SCG = System.Collections.Generic;
+
+namespace Nemerle.Completion2.CodeFormatting
+{
+
+  class CodeLineBreakingStage : IFormattingStage
+  {
+    class MatchingBrackerFinder
+    {
+      mutable level = 0;
+      mutable tokenTypeToLookFor : Type = null;
+      mutable counterpartTokenType : Type = null;
+      
+      static GetCounterpartTokenType(t : Type) : Type
+      {
+      | bb when bb.Equals(typeof(Token.BeginBrace)) => typeof(Token.EndBrace);
+      | bq when bq.Equals(typeof(Token.BeginQuote)) => typeof(Token.EndQuote);
+      | br when br.Equals(typeof(Token.BeginRound)) => typeof(Token.EndRound);
+      | bs when bs.Equals(typeof(Token.BeginSquare)) => typeof(Token.EndSquare);
+      
+      | eb when eb.Equals(typeof(Token.EndBrace)) => typeof(Token.BeginBrace);
+      | eq when eq.Equals(typeof(Token.EndQuote)) => typeof(Token.BeginQuote);
+      | er when er.Equals(typeof(Token.EndRound)) => typeof(Token.BeginRound);
+      | es when es.Equals(typeof(Token.EndSquare)) => typeof(Token.BeginSquare);
+      | _ => null;
+      }
+      
+      public GetSearchFunc(t : Type) : Token -> bool
+      {
+        tokenTypeToLookFor = t;
+        // TODO: Check if t is paired token
+        counterpartTokenType = GetCounterpartTokenType(t);
+        IsDesirableToken
+      }        
+      
+      IsDesirableToken(t : Token) : bool
+      {
+        if(t.GetType().Equals(tokenTypeToLookFor))
+        { 
+          if(level == 0)
+            true
+          else
+          {
+            level--; 
+            false;
+          }
+        }
+        else if(t.GetType().Equals(counterpartTokenType))
+        {  
+          level++;
+          false;
+        }
+        else
+          false;
+      }
+    }
+    
+    public Engine : Engine
+    {
+      mutable _engine : Engine;
+      get         { ManagerClass.Instance = _engine; _engine; }
+      private set { _engine = value }
+    }
+
+    mutable _fileIndex : int;
+    
+    mutable _startLine = 0;
+    mutable _endLine = 0;
+    
+    mutable _results : SCG.List.[FormatterResult];
+    indentSize = 2;
+    mutable _expectedLine = 1;
+    mutable _expectedCol = -1;
+
+    mutable _insertedLines = 0;
+    
+    mutable _documentTokens : Token;
+    mutable _tokenFinder : TokenStreamFinder = null;
+
+    SetExpectedLine(val : int) : void
+    {
+      _expectedLine = val;
+      _insertedLines = 0;
+    }
+
+    
+    #region Helper methods
+    
+    LineBreak(loc : Location) : void
+    {
+      _results.Add(FormatterResult.Insert(loc.Line, loc.Column, Environment.NewLine));
+    }
+    
+    NeededLineBreaks(loc : Location) : int
+    {
+      match(_expectedLine - (loc.Line + _insertedLines))
+      {
+      | x when x > 0 => x;
+      | _ => 0;
+      };
+    }
+    
+    IsBeginBrace(token : Token) : bool
+    {
+    | BeginBrace => true
+    | _ => false
+    }
+    
+    #endregion
+    
+    FormatBrace(token : Token) : void
+    {
+      def newLineBreaks = NeededLineBreaks(token.Location);
+      when(newLineBreaks > 0)
+      {
+        LineBreak(token.Location);
+        _insertedLines += 1;
+      }
+
+      _expectedLine++;
+    }
+    
+    FormatNamespace(ns : Decl.Namespace) : void
+    {
+      def beginBrace = _tokenFinder.FindNextIf(ns.Location.Line, ns.Location.Column, IsBeginBrace);
+      match(ns.Name)
+      {
+      | _ :: _ => // if namespace name isn't empty (not global namespace)
+          SetExpectedLine(ns.Location.Line + 1);
+          FormatBrace(beginBrace);
+      | _ => ();
+      }
+      _expectedCol += indentSize;
+      foreach(x in ns.Decls)
+      {
+        match(x)
+        {
+          | Decl.Namespace as n => FormatNamespace(n);
+          | Decl.Type as t => FormatType(t.Builder);
+          | Decl.Using as u => FormatUsing(u);
+          | _ => ()
+        }
+      }
+      _expectedCol -= indentSize;
+      // TODO: Format end brace here.
+      
+    }
+    
+    FormatUsing(us : Decl.Using) : void
+    {
+      def newLineBreaks = NeededLineBreaks(us.Location);
+      when(newLineBreaks > 0)
+      {
+        LineBreak(us.Location);
+        _insertedLines++;
+      }
+
+      _expectedLine++;
+    }
+
+    FormatMethod(mb : MethodBuilder) : void
+    {
+      unless(mb.IsGenerated)
+      {
+        def x = BuiltinMethodKind.CallWithCast;
+        SetExpectedLine(mb.Header.Location.EndLine + 1);
+        def beginBrace = _tokenFinder.FindNextIf(mb.Header.Location.EndLine, mb.Header.Location.EndColumn, IsBeginBrace);
+        FormatBrace(beginBrace);
+
+        // TODO: Format every expression
+
+        def matchFinder = MatchingBrackerFinder().GetSearchFunc(typeof(Token.EndBrace));
+        def endBrace = _tokenFinder.FindNextIf(beginBrace.Location.Line, beginBrace.Location.EndColumn, matchFinder);
+        _results.Add(FormatterResult.Insert(endBrace.Location.Line, endBrace.Location.Column, "/*endBrace*/"));   
+        FormatBrace(endBrace);
+
+        SetExpectedLine(endBrace.Location.EndLine + 1);
+      }
+    }
+
+    FormatProperty(pb : PropertyBuilder) : void
+    {
+      // TODO: Format opening brace
+      // TODO: Format possible field definitions
+      // TODO: Format accessors (simple ones should be one-line'd)
+      // TODO: Format closing brace
+      
+      SetExpectedLine(pb.Location.EndLine + 1); 
+      
+    }
+    
+    FormatField(fb : FieldBuilder) : void
+    {
+      //TODO: Implement method
+      SetExpectedLine(fb.Location.EndLine + 1);
+    }
+    
+    FormatEvent(eb : EventBuilder) : void
+    {
+      //TODO: Implement method
+      SetExpectedLine(eb.Location.EndLine + 1);
+    }
+    
+    FormatClassMember(member : IMember) : void
+    {
+    | mmb is MemberBuilder => // fields, properties, methods, events
+        unless(mmb.IsGenerated)
+        {
+          match(mmb)
+          {
+          | mb is MethodBuilder => FormatMethod(mb);
+          | pb is PropertyBuilder => FormatProperty(pb);
+          | fb is FieldBuilder => FormatField(fb);
+          | eb is EventBuilder => FormatEvent(eb);
+          | _ => Debug.WriteLine($"!!! Unhandled MemberBuilder type in FormatClassMember: $(mmb.GetType().Name)");  
+          }
+        }
+    | tb is TypeBuilder => FormatType(tb);
+    | _ => Debug.WriteLine($"!!! Unhandled member type in FormatClassMember: $(member.GetType().Name)");  
+    }
+    
+    FormatType(_tb : TypeBuilder) : void
+    {
+      def part = match(_tb.AstParts.Find(part => part.Location.FileIndex == _fileIndex))
+                  {
+                  | Some(val) => val
+                  | None => throw ApplicationException($"No type part found in file $_fileIndex");
+                  };
+      
+      // TODO: Format base class and implemented interfaces list.
+      
+      SetExpectedLine(part.name.Location.EndLine + 1);
+      def beginBrace = _tokenFinder.FindNextIf(part.name.Location.EndLine, part.name.Location.EndColumn, IsBeginBrace);
+      FormatBrace(beginBrace);
+      
+      foreach(member in _tb.GetDirectMembers())
+        FormatClassMember(member);
+      
+      def matchFinder = MatchingBrackerFinder().GetSearchFunc(typeof(Token.EndBrace));
+      def endBrace = _tokenFinder.FindNextIf(beginBrace.Location.Line, beginBrace.Location.EndColumn + 1, matchFinder);
+      def str = endBrace.GetType().Name;    
+      FormatBrace(endBrace);
+
+      SetExpectedLine(endBrace.Location.EndLine + 1);
+    }
+
+    #region IFormattingStage members
+
+    public this(engine : Engine, fileIndex : int)
+    {
+      this.Engine = engine;
+      _fileIndex = fileIndex;
+      _results = SCG.List.[FormatterResult]();
+    }
+    
+    public FormatRegion(startLine : int, startCol : int, endLine : int, endCol : int) : SCG.List.[FormatterResult]
+    {
+      FormatDocument();
+    }
+
+    public FormatDocument() : SCG.List.[FormatterResult]
+    {
+      _results.Clear();
+      
+      // This is PExpr form of document
+      def declNS = this.Engine.Project.CompileUnits[_fileIndex];
+      
+      def src = this.Engine.Sources[_fileIndex];
+      def lexer = NonEatingLexer(this.Engine, src, Location(_fileIndex, 1, 1));
+      //def lexer = LexerString(this.Engine, src, Location(_fileIndex, 1, 1));
+      
+      _tokenFinder = TokenStreamFinder(lexer.ReadAllTokens());
+      
+      def preparser = PreParser(lexer);
+      _documentTokens = preparser.PreParse();
+      
+      FormatNamespace(declNS);
+      _results;
+    
+    }
+    
+    #endregion    
+
+  }
+}

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/Formatter.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/Formatter.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/Formatter.n	Sat Apr 21 00:41:41 2007
@@ -16,25 +16,9 @@
 {
   public class Formatter
   {
-    mutable _startLine = 0;
-    mutable _endLine = 0;
+    mutable _fileIndex : int = 0;
     
     mutable _results : SCG.List.[FormatterResult];
-    indentSize = 2;
-    mutable _expectedLine = 1;
-    mutable _expectedCol = -1;
-
-    mutable _insertedLines = 0;
-    
-    mutable _documentTokens : Token;
-    _tokenFinder : TokenFinder = TokenFinder();
-
-    SetExpectedLine(val : int) : void
-    {
-      _expectedLine = val;
-      _insertedLines = 0;
-    }
-
     
     public Engine : Engine
     {
@@ -43,153 +27,19 @@
       private set { _engine = value }
     }
     
-    private this(engine : Engine)
+    private this(engine : Engine, fileIndex : int)
     {
       Engine = engine;
+      _fileIndex = fileIndex;
       _results = SCG.List.[FormatterResult]();
-    }
-    
-    #region Helper methods
-    
-    static LineBreakAndIndent(loc : Location, 
-                              indentToColumn : int) : SCG.List.[FormatterResult]
-    {
-      def result = SCG.List.[FormatterResult]();
-      def insertion = Environment.NewLine + string(' ', indentToColumn - 1);
-      result.Add(FormatterResult.Insert(loc.Line, loc.Column, insertion));
-      result;
-    }
-
-    static Indent(loc : Location, 
-                  indentToColumn : int) : SCG.List.[FormatterResult]
-    {
-      def result = SCG.List.[FormatterResult]();
-      if(loc.Column < indentToColumn)
-      {
-        result.Add(FormatterResult.Insert(loc.Line, loc.Column, string(' ', indentToColumn - loc.Column)));
-      }
-      else when(loc.Column > indentToColumn)
-      {
-        result.Add(FormatterResult.Replace(Location(loc, 
-                                                    loc.Line,
-                                                    indentToColumn,
-                                                    loc.Line,
-                                                    loc.Column),
-                                           ""));  
-      }
-      result;
-    }
     
-    NeededLineBreaks(loc : Location) : int
-    {
-      match(_expectedLine - (loc.Line + _insertedLines))
-      {
-      | x when x > 0 => x;
-      | _ => 0;
-      };
     }
     
-    FindTokenAfter(line : int, col : int, predicate : Token -> bool) : Token
-    {
-      match(_tokenFinder.FindAfter(_documentTokens, line, col, predicate))
-      {
-      | x :: _ => x;
-      | [] => throw TokenNotFoundException("Required token was not found");
-      }
-    }
     
-    IsBracesGroup(token : Token) : bool
-    {
-    | BracesGroup => true;
-    | _ => false;
-    }
-    
-    
-    
-    #endregion
-    
-    FormatBrace(token : Token) : SCG.List.[FormatterResult]
-    {
-      def result = SCG.List.[FormatterResult]();
-
-      def newLineBreaks = NeededLineBreaks(token.Location);
-      if(newLineBreaks > 0)
-      {
-        result.AddRange(LineBreakAndIndent(token.Location, _expectedCol));
-        _insertedLines += 1;
-      }
-      else
-      {
-        result.AddRange(Indent(token.Location, _expectedCol));
-      }
-
-      _expectedLine++;
-      result;
-    }
-    
-    FormatNamespace(ns : Decl.Namespace) : SCG.List[FormatterResult]
-    {
-      def result = SCG.List.[FormatterResult]();
-      def body = FindTokenAfter(ns.Location.Line, ns.Location.Column, IsBracesGroup);
-      match(ns.Name)
-      {
-      | _ :: _ => // if namespace name isn't empty (not global namespace)
-          SetExpectedLine(ns.Location.Line + 1);
-          result.AddRange(FormatBrace(body));
-      | _ => ();
-      }
-      _expectedCol += indentSize;
-      foreach(x in ns.Decls)
-      {
-        match(x)
-        {
-          | Decl.Namespace as n => result.AddRange(FormatNamespace(n));
-          | Decl.Type as t => result.AddRange(FormatType(t));
-          | Decl.Using as u => result.AddRange(FormatUsing(u));
-          | _ => ()
-        }
-      }
-      _expectedCol -= indentSize;
-      // TODO: Format end brace here.
-      
-      result;  
-    }
-    
-    mutable static counter : int = 0;
-    FormatUsing(us : Decl.Using) : SCG.List[FormatterResult]
-    {
-      def result = SCG.List.[FormatterResult]();
-
-      def newLineBreaks = NeededLineBreaks(us.Location);
-      // TODO: for testing only. To be removed ASAP.
-      //result.Add(FormatterResult.Insert(us.Location.Line, us.Location.Column, $"#define test$(counter)\r\n"));
-      //counter++;
-      //_insertedLines += 1;
-      if(newLineBreaks > 0)
-      {
-        result.AddRange(LineBreakAndIndent(us.Location, _expectedCol));
-        _insertedLines += 1;
-      }
-      else
-      {
-        result.AddRange(Indent(us.Location, _expectedCol));
-        SetExpectedLine(us.Location.Line);
-      }
-
-      _expectedLine++;
-      result; 
-    }
-    
-    FormatType(_tb : Decl.Type) : SCG.List[FormatterResult]
-    {
-      def result = SCG.List.[FormatterResult](); 
-      result; 
-    }
     
     _WalkHandler (info : ExprWalkInfo) : void
     {
       def node = info.Node;
-      
       if(node != null)
       {
         def loc = if(node is Located) 
@@ -248,31 +98,23 @@
     
     public static FormatDocument(engine : Engine, filePath : string) : SCG.List[FormatterResult]
     {
-      def instance = Formatter(engine);
+      def fileIndex = engine.Project.CompileUnits.GetFileIndex(filePath);
+      //def instance = Formatter(engine, fileIndex);
       def results = SCG.List.[FormatterResult]();
       
-      // This is PExpr form of document
-      def fileIndex = instance.Engine.Project.CompileUnits.GetFileIndex(filePath);
-      def declNS = instance.Engine.Project.CompileUnits[fileIndex];
-      
-      def src = instance.Engine.Sources[filePath];
-      // And we'll also need document as token groups.
-      def _ = NonEatingLexer(instance.Engine, src, Location(fileIndex, 1, 1));
-      def lexer = LexerString(instance.Engine, src, Location(fileIndex, 1, 1));
-      //lexer.Keywords = lexer.Manager.CoreEnv.Keywords;
-      //
-      //using(def stream = StreamWriter("c:\\tokens.txt"))
-      //{
-      //  foreach(t in lexer.ReadAllTokens())
-      //  {
-      //    stream.WriteLine($"$(t.ToString())\t\t\t$(t.GetType().Name)\t\t\t$(t.Location.Line):$(t.Location.Column):$(t.Location.EndLine):$(t.Location.EndColumn)");
-      //  }
-      //}
-      
-      def preparser = PreParser(lexer);
-      instance._documentTokens = preparser.PreParse();
+      def stages : list[IFormattingStage] =  
+                    [
+                      CodeLineBreakingStage(engine, fileIndex)
+                      //,CodeIndentationStage(engine, fileIndex)
+                    ];
+                    
+      // TODO: After each stage send result to the VS,
+      // and wait for changes to be applied.
+      foreach(stage in stages)
+      {
+        results.AddRange(stage.FormatDocument()); 
+      }
       
-      results.AddRange(instance.FormatNamespace(declNS));
       results;
     
     }

Added: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/IFormattingStage.n
==============================================================================
--- (empty file)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/IFormattingStage.n	Sat Apr 21 00:41:41 2007
@@ -0,0 +1,11 @@
+using Nemerle.Completion2;
+using System.Collections.Generic;
+
+namespace Nemerle.Completion2.CodeFormatting
+{
+  interface IFormattingStage
+  {
+    FormatDocument(): List.[FormatterResult];
+    FormatRegion(startLine : int, startCol : int, endLine : int, endCol : int) : List.[FormatterResult];
+  }
+}

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/NonEatingLexer.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/NonEatingLexer.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/NonEatingLexer.n	Sat Apr 21 00:41:41 2007
@@ -1,14 +1,17 @@
 using System;
 using Nemerle;
 using Nemerle.Compiler;
+using System.Collections.Generic;
 
 namespace Nemerle.Completion2.CodeFormatting
 {
+  // The only purpose of this class is to leave whitespace and comments in the output stream
   class NonEatingLexer : LexerString
   {
     public this (manager : ManagerClass, code : string, loc : Location)
     {
       base (manager, code, loc);
+      Keywords = manager.CoreEnv.Keywords;
     }
     
     protected override do_get_token() : Token
@@ -201,4 +204,5 @@
       }
     }
   }
+  
 }

Added: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/TokenStreamFinder.n
==============================================================================
--- (empty file)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/TokenStreamFinder.n	Sat Apr 21 00:41:41 2007
@@ -0,0 +1,127 @@
+using System;
+using Nemerle;
+using Nemerle.Compiler;
+using System.Collections.Generic;
+using Nemerle.Completion2.CodeFormatting;
+
+namespace Nemerle.Completion2
+{
+  // This class is used to find tokens in token stream (no token groups)
+  public class TokenStreamFinder
+  {
+    _sortedTokens : Dictionary.[int, array[Token]] = Dictionary();
+    
+    // We're assuming that tokens are ordered as they appear in the source, i.e. no reversing and shuffling.
+    public this(tokens : array[Token])
+    {
+      def curLineTokens = List(); 
+      
+      // Enumerate tokens starting from currentTokenPos and see if they belong 
+      // to line number linePos. As long as they do, add them to temp list.
+      // When we see a token located at line with greater number, then stop.
+      def GetLineTokens(linePos, currentTokenPos)
+      {
+        if(currentTokenPos == tokens.Length)
+          currentTokenPos
+        else
+        {
+          def tok = tokens[currentTokenPos];
+          if(tok.Location.Line == linePos)
+          {
+            curLineTokens.Add(tok);
+            GetLineTokens(linePos, currentTokenPos + 1);
+          }
+          else if(tok.Location.Line > linePos)
+          {
+            currentTokenPos;    
+          }
+          else
+          {
+            throw ApplicationException("Order of tokens is invalid");
+          }
+        }
+      }
+      
+      mutable curLinePos = tokens[0].Location.Line;
+      mutable curTokenIndex = 0;
+      while(curTokenIndex < tokens.Length)
+      {
+        // Get index of last token in this line.
+        curTokenIndex = GetLineTokens(curLinePos, curTokenIndex);
+        _sortedTokens[curLinePos] = curLineTokens.ToArray();
+        curLineTokens.Clear();
+        curLinePos++;
+      }
+    }  
+    
+    public FindNextIf(line : int, col : int, predicate : Token -> bool) : Token
+    {
+      mutable curLine = line;
+      mutable curIndex = 0;
+
+      def getCurrentToken()
+      {
+        if(curIndex < _sortedTokens[curLine].Length)
+          _sortedTokens[curLine][curIndex]
+        else
+          null
+      }
+      def advancePosition()
+      {
+        if(curIndex < _sortedTokens[curLine].Length - 1)
+          curIndex++;
+        else when(_sortedTokens.ContainsKey(curLine + 1))
+        {
+          curLine++;
+          curIndex = 0;
+        }  
+      }
+      def getNextToken()
+      {
+        def tok = getCurrentToken();
+        advancePosition();
+        tok
+      }
+      mutable startLineTokens = _sortedTokens[curLine];
+      def setStartPoint()
+      {
+        if(curLine == line && curIndex < startLineTokens.Length && startLineTokens[curIndex].Location.Column < col)
+        {
+          curIndex++;
+          setStartPoint();
+        }
+        else when(curIndex == startLineTokens.Length)
+        {
+          curLine++;
+          startLineTokens = _sortedTokens[curLine];
+          curIndex = 0;
+          setStartPoint();
+        }
+      }
+      
+      setStartPoint();
+
+      // Ok, start position defined. Start matching each next token against given predicate.
+      mutable result = getNextToken();
+      while(!predicate(result))
+      {
+        result = getNextToken();
+      }
+      when(result == null)
+        throw TokenNotFoundException("Token not found");
+      result;
+    }
+    
+    public FindPrevIf(_line : int, _col : int, _predicate : Token -> bool) : Token
+    {
+      throw NotImplementedException()
+    }
+    
+    public FindAt(line : int, col : int) : Token
+    {
+      def lineTokens = _sortedTokens[line];
+      def result = Array.Find(lineTokens, tok => tok.Location.Contains(line, col));
+      result;
+    }
+  }
+}

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprFinder.n	Sat Apr 21 00:41:41 2007
@@ -118,7 +118,7 @@
       }
     }
     
-    // This method accepts Decl as a starting point.
+    //// This method accepts Decl as a starting point.
     //public Find(pRoot : Decl, line : int, col : int) : Location * object
     //{
     //  if(pRoot == null)
@@ -272,16 +272,6 @@
       !location.IsGenerated && location.Contains(_line, _col);
     }
     
-    //IsInList(locations : list[Location]) : bool
-    //{
-    //  match(locations.Find(IsIn))
-    //  {
-    //  | Some => true;
-    //  | _ => false;
-    //  }
-    //}
-    
-
     IsInEx(location : Location) : bool
     {
       location.Contains(_line, _col);

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprWalker.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprWalker.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/ExprWalker.n	Sat Apr 21 00:41:41 2007
@@ -61,10 +61,19 @@
       {
         match(member)
         {
-        | mb is MethodBuilder => Go(mb.BodyParsed);
-        | fb is FieldBuilder => Go(fb.InitializerParsed);
-        | tb is TypeBuilder => Go(tb.GetDirectMembers().Reverse());
-        | pb is PropertyBuilder => Go(pb.GetGetter()); Go(pb.GetSetter());
+        | mb is MethodBuilder => Go(mb.Ast.name);
+                                 unless(mb.IsAbstract)
+                                  Go(mb.BodyParsed);
+        | fb is FieldBuilder => Go(fb.Ast.name);
+                                when(fb.IsInitializerPresent)
+                                 Go(fb.InitializerParsed);
+        | tb is TypeBuilder => Go(tb.Ast.name);
+                               Go(tb.GetDirectMembers().Reverse());
+        | pb is PropertyBuilder =>  unless(pb.IsAbstract)
+                                    {
+                                      Go(pb.GetGetter()); 
+                                      Go(pb.GetSetter());
+                                    }
         | _ => ();
         }
         _info.Pop();

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Refactoring.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Refactoring.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Refactoring.n	Sat Apr 21 00:41:41 2007
@@ -13,6 +13,7 @@
 using Nemerle.Compiler.Typedtree;
 using Nemerle.Utility;
 using Nemerle.Logging;
+using Nemerle.Imperative;
 
 using SCG = System.Collections.Generic;
 
@@ -45,6 +46,39 @@
       }
     }
 
+    public GetInheritors([NotNull]filePath : string, line : int, col : int) : array [GotoInfo]
+    {
+      def fileIndex = _compileUnits.GetFileIndex(filePath);
+      GetInheritors(fileIndex, line, col);
+    }
+    
+    public GetInheritors(fileIndex : int, line : int, col : int) : array [GotoInfo]
+    {
+      def getTokenAtCursor()
+      {
+        def src = this.Engine.Sources[fileIndex];
+        def lexer = LexerString(this.Engine, src, Location(fileIndex, 1, 1));
+        lexer.Keywords = this.Engine.CoreEnv.Keywords;
+
+        def tokenFinder = TokenStreamFinder(lexer.ReadAllTokens());
+        tokenFinder.FindAt(line, col);
+      }
+
+      def (activeEnv, activeBuilder, _, _) = this.Engine.Project.GetActiveEnv(fileIndex, line);
+      def tok = getTokenAtCursor();
+      match(tok)
+      {
+      | Identifier(name) => 
+              match (activeEnv.LookupType([name], activeBuilder, -1))
+              {
+              | Some(ti) => FindInheritors(ti).ToArray();
+              | None => array[];
+              }
+      | _ => array[]
+      }
+    }
+    
+
   public HighlightUsages([NotNull] lexer : ScanLexer, 
                            [NotNull] filePath : string, 
                            line : int, 
@@ -388,5 +422,47 @@
       chain
     }
   
+    private FindInheritors(ofInfo : TypeInfo) : list[GotoInfo]
+    {
+      mutable result = [];
+      def otherBuilders = NamespaceTree.GetTypeBuilders();
+      
+      def isInheritorOf(possibleInheritor, ourBase)
+      {
+        def checkParents(ty)
+        {
+        | tb is TypeBuilder =>  
+            if(tb.BaseType : object == ourBase || tb.InterfacesToImplement().Contains(ourBase))
+              true
+            else
+            {
+              def parents = tb.BaseType :: tb.InterfacesToImplement();
+              foreach(parent in parents)
+              {
+                when(isInheritorOf(parent, ourBase))
+                  return true;
+              }
+              false
+            }
+        | ti is TypeInfo =>
+            if(ti.BaseType : object == ourBase)
+              true
+            else
+            {
+              when(isInheritorOf(ti.BaseType, ourBase))
+                return true;
+              false
+            }
+        | _ => false
+        }
+        checkParents(possibleInheritor);
+      }
+      
+      foreach(builder : TypeBuilder in otherBuilders)
+        when(!object.ReferenceEquals(builder, ofInfo) && isInheritorOf(builder, ofInfo))
+          result ::= GotoInfo(builder.Ast.name.Location);
+      
+      result
+    }
   }
 }
\ No newline at end of file

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	Sat Apr 21 00:41:41 2007
@@ -74,12 +74,7 @@
     mutable _identifiers    : list[string] = [];
 
     _tokenInfo : ScanTokenInfo = ScanTokenInfo();
-    // This is for supporting partly colorized comments.
-    // Example: this is some text. TODO: And this is special comment. Only part after todo must be colorized.
-    // When comment matches special comment regex, it is then split into two parts.
-    // Part before match location is regular comment and is immediately returned from GetToken().
-    // The rest is turned into special comment and stored in this field.
-    mutable _specialCommentToken : ScanTokenInfo = null;
+    mutable _pendingToken : ScanTokenInfo = null;
 
     static _keywords       : Dictionary[string,string] = Dictionary();
     static _quotationTypes : Dictionary[string,string] = Dictionary();
@@ -587,13 +582,12 @@
       }
     }
 
-
     public GetToken(prevState : ScanState) : ScanTokenInfo
     {
-      if(_specialCommentToken != null)
+      if(_pendingToken != null)
       {
-        def tmp = _specialCommentToken;
-        _specialCommentToken = null;
+        def tmp = _pendingToken;
+        _pendingToken = null;
         tmp;
       }
       else
@@ -802,6 +796,8 @@
         (ScanTokenColor.CommentHACK, Regex(@"(\b(HACK)\b\s*:.*)", RegexOptions.Compiled))
       ];
     
+;
+    
     CheckForSpecialComments(tokenInfo : ScanTokenInfo) : void
     { 
       def chooseColor(str, regexList)
@@ -821,19 +817,19 @@
       match(tokenInfo.Token)
       {
       | Comment(value) =>
-            //Debug.WriteLine($"Comment value: $value");
+            //TODO: Implement special comment in the middle of regular one, ie // regular >special one< regular again
             def commentWOBeginning = value.Substring(2);
             def (idx, len, color) = chooseColor(commentWOBeginning, specialCommentRegexes);
             when(idx != -1)
             {
-              _specialCommentToken = tokenInfo.Clone();
-              _specialCommentToken.Token = Token.Comment(commentWOBeginning.Substring(idx, len));
+              _pendingToken = tokenInfo.Clone();
+              _pendingToken.Token = Token.Comment(commentWOBeginning.Substring(idx, len));
 
               def l = tokenInfo.Token.Location;
               // shrinking regular comment location
               tokenInfo.Token.Location = Location(l, l.Line, l.Column, l.EndLine, l.Column + 1 + idx);
-              _specialCommentToken.Color = color;
-              _specialCommentToken.Token.Location = Location(l, l.Line, l.Column + 2 + idx, l.EndLine, l.EndColumn);
+              _pendingToken.Color = color;
+              _pendingToken.Token.Location = Location(l, l.Line, l.Column + 2 + idx, l.EndLine, l.EndColumn);
             }
       | _ => () 
       }

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/TokenFinder.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/TokenFinder.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/TokenFinder.n	Sat Apr 21 00:41:41 2007
@@ -118,20 +118,6 @@
       Go(root, [])
     }
     
-    public FindAfter(
-      root : Token,
-      line : int,
-      col  : int,
-      predicate : Token -> bool
-    )
-      : list[Token]
-    {
-      Init(root.Location, line, col);
-
-      Go(root, predicate, [])
-    }
-    
-
     #endregion
 
     #region Helpers

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-Relocation.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-Relocation.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/Engine/Engine-Relocation.n	Sat Apr 21 00:41:41 2007
@@ -24,6 +24,7 @@
       oldEndChar : int, oldEndLine : int
     ) : void
     {
+      // K-Liss: Ehm, what is it for? Preventing "unused parameter" warning?
       _ = newEndChar + newEndLine + oldEndChar + oldEndLine;
       
       def prj = this.Project;

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/SourceCollection.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/SourceCollection.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/SourceCollection.n	Sat Apr 21 00:41:41 2007
@@ -73,6 +73,12 @@
         get { _sources[filePath] }
       }
 
+      public Item[fileIndex : int] : string
+      {
+        get { _sources[Location.GetFileName(fileIndex)] }
+      }
+   
+
       public Count : int { get { _sources.Count } }
     }
   }

Modified: vs-plugin/trunk/Nemerle.VsIntegration/CtcComponents/PkgCmd.ctc
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/CtcComponents/PkgCmd.ctc	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/CtcComponents/PkgCmd.ctc	Sat Apr 21 00:41:41 2007
@@ -66,6 +66,7 @@
 //phantom: if you want the menu back, uncomment
     guidNemerleProjectCmdSet:NemerleTopLevelMenu, guidNemerleProjectCmdSet:VsTopLevelMenuGroup,  0x000,   ,  "NemerleMenu",      "&Nemerle" ;
     guidNemerleProjectCmdSet:Selection,           guidNemerleProjectCmdSet:NemerleGroup,         0x000,   ,  "NemerleSelection", "&Selection" ;
+    guidNemerleProjectCmdSet:Navigation,          guidNemerleProjectCmdSet:NemerleGroup,         0x000,   ,  "NemerleNavigation", "Na&vigation" ;
     guidNemerleProjectCmdSet:Refactor,            guidNemerleProjectCmdSet:NemerleGroup,         0x000,   ,  "NemerleRefactor",  "&Refactor" ;
     guidNemerleProjectCmdSet:Highlighting,        guidNemerleProjectCmdSet:NemerleGroup,         0x000,   ,  "NemerleHighlighting",  "&Highlighting" ;
 
@@ -87,6 +88,7 @@
     guidNemerleProjectCmdSet:NemerleGroup,        guidNemerleProjectCmdSet:NemerleTopLevelMenu,  0x600;
 
     guidNemerleProjectCmdSet:SelectionGroup,      guidNemerleProjectCmdSet:Selection,            0x600;
+    guidNemerleProjectCmdSet:NavigationGroup,     guidNemerleProjectCmdSet:Navigation,           0x600;
     guidNemerleProjectCmdSet:RefactorGroup,       guidNemerleProjectCmdSet:Refactor,             0x600;
     guidNemerleProjectCmdSet:HighlightingGroup,   guidNemerleProjectCmdSet:Highlighting,         0x600;
 
@@ -114,6 +116,10 @@
     guidNemerleProjectCmdSet:cmdIdExtendSelection, guidNemerleProjectCmdSet:SelectionGroup,  0x100,   guidOfficeIcon:msotcidNoIcon, BUTTON,                ,                      "&Extend";
     guidNemerleProjectCmdSet:cmdIdShrinkSelection, guidNemerleProjectCmdSet:SelectionGroup,  0x100,   guidOfficeIcon:msotcidNoIcon, BUTTON,                ,                      "&Shrink";
 
+    guidNemerleProjectCmdSet:cmdIdFindInheritors,  guidNemerleProjectCmdSet:NavigationGroup,  0x100,   guidOfficeIcon:msotcidNoIcon, BUTTON,                ,                      "Find &inheritors";
+
+
+
     guidNemerleProjectCmdSet:cmdIdRename,          guidNemerleProjectCmdSet:RefactorGroup,   0x100,   guidOfficeIcon:msotcidNoIcon, BUTTON,                ,                      "&Rename...";
     guidNemerleProjectCmdSet:cmdIdInline,          guidNemerleProjectCmdSet:RefactorGroup,   0x100,   guidOfficeIcon:msotcidNoIcon, BUTTON,                ,                      "&Inline";
 

Modified: vs-plugin/trunk/Nemerle.VsIntegration/CtcComponents/PkgCmdID.h
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/CtcComponents/PkgCmdID.h	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/CtcComponents/PkgCmdID.h	Sat Apr 21 00:41:41 2007
@@ -19,8 +19,9 @@
 //
 #define NemerleTopLevelMenu  0x1001
 #define Selection            0x1002
-#define Refactor             0x1003
-#define Highlighting         0x1004
+#define Navigation           0x1003 
+#define Refactor             0x1004
+#define Highlighting         0x1005
 
 /////////////////////////////////////////////////////////////////////
 // Menu Groups
@@ -30,9 +31,10 @@
 #define VsTopLevelMenuGroup  0x2100
 #define NemerleGroup         0x2101
 
-#define SelectionGroup       0x2102
-#define RefactorGroup        0x2103
-#define HighlightingGroup    0x2104
+#define NavigationGroup      0x2102
+#define SelectionGroup       0x2103
+#define RefactorGroup        0x2104
+#define HighlightingGroup    0x2105
 
 /////////////////////////////////////////////////////////////////////
 // Commands
@@ -42,15 +44,17 @@
 #define cmdIdExtendSelection 0x3101
 #define cmdIdShrinkSelection 0x3102
 
-#define cmdIdRename          0x3103
-#define cmdIdInline          0x3104
+#define cmdIdFindInheritors  0x3103
 
-#define cmdIdOptions         0x3105
+#define cmdIdRename          0x3104
+#define cmdIdInline          0x3105
 
-#define cmdIdAstToolWindow   0x3106
+#define cmdIdOptions         0x3106
 
-#define cmdIdAddHighlighting          0x3107
-#define cmdIdRemoveLastHighlighting   0x3108
+#define cmdIdAstToolWindow   0x3107
+
+#define cmdIdAddHighlighting          0x3108
+#define cmdIdRemoveLastHighlighting   0x3109
 
 /////////////////////////////////////////////////////////////////////
 // Bitmaps

Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs	Sat Apr 21 00:41:41 2007
@@ -155,52 +155,52 @@
 
 			span = new TextSpan();
 
-			GotoInfo[] info;
+			GotoInfo[] infos;
 
 			switch (cmd)
 			{
 				case VSConstants.VSStd97CmdID.GotoDecl:
 				case VSConstants.VSStd97CmdID.GotoDefn:
-					info = _project.GetGoto(_filePath, line, col, _sourceText);
+					infos = _project.GetGoto(_filePath, line, col, _sourceText);
 					break;
 
 				case VSConstants.VSStd97CmdID.GotoRef:
-					info = _project.GetUsages(_filePath, line, col, _sourceText);
+					infos = _project.GetUsages(_filePath, line, col, _sourceText);
 					break;
 
 				default:
 					Trace.Fail(string.Format("{0}: Unknown cmd ({1})", TS.DisplayName, cmd));
-					info = null;
+					infos = null;
 					break;
 			}
 
-			if (info == null || info.Length == 0)
+			if (infos == null || infos.Length == 0)
 			{
 				// Not implemented nor expected
 				//
 				return null;
 			}
 
-			if (!info[0].HasLocation && info[0].Member != null)
+			if (!infos[0].HasLocation && infos[0].Member != null)
 			{
-				Debug.Assert(info.Length == 1, "Multiple unknown locations are unexpected");
-				GotoInfo[] infoFromPdb = LookupLocationsFromPdb(info[0]);
+				Debug.Assert(infos.Length == 1, "Multiple unknown locations are unexpected");
+				GotoInfo[] infoFromPdb = LookupLocationsFromPdb(infos[0]);
 
 				if (infoFromPdb == null)
-					return GenerateSource(ref span, info[0]);
+					return GenerateSource(ref span, infos[0]);
 
-				info = infoFromPdb;
+				infos = infoFromPdb;
 			}
 
-			if (info.Length == 1)
-				return SetTextSpan(ref span, info[0]);
-			else if (info.Length > 0)
+			if (infos.Length == 1)
+				return SetTextSpan(ref span, infos[0]);
+			else if (infos.Length > 0)
 			{
 
 				NativeWindow textEditorWnd = 
 					NativeWindow.FromHandle(textView.GetWindowHandle());
 
-				using (GotoUsageForm popup = new GotoUsageForm(info))
+				using (GotoUsageForm popup = new GotoUsageForm(infos))
 					if (popup.ShowDialog(textEditorWnd) == DialogResult.OK)
 						return SetTextSpan(ref span, popup.Result);
 			}

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	Sat Apr 21 00:41:41 2007
@@ -999,12 +999,12 @@
 
 				// Setup default values.
 				//
+                _preferences.EnableFormatSelection = true;
 				_preferences.ShowNavigationBar     = true;
 
 				// Load from the registry.
 				//
 				_preferences.Init();
-                _preferences.EnableFormatSelection = false;
 
 #if DEBUG
 				//VladD2: Switch on synchronous mode for debugging purpose!
@@ -1087,7 +1087,7 @@
 
 		#region ShowLocation event handler
 
-		void GotoLocation(Location loc)
+		public void GotoLocation(Location loc)
 		{
 			TextSpan span = new TextSpan();
 

Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleSource.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleSource.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleSource.cs	Sat Apr 21 00:41:41 2007
@@ -173,8 +173,8 @@
 			Engine engine = projectInfo.Engine;
 
             ReformatSpan_internal(mgr, span, engine, filePath);
-            ReformatSpan_internal(mgr, span, engine, filePath);
-            ReformatSpan_internal(mgr, span, engine, filePath);
+            //ReformatSpan_internal(mgr, span, engine, filePath);
+            //ReformatSpan_internal(mgr, span, engine, filePath);
             //base.ReformatSpan(mgr, span);
 		}
         private void ReformatSpan_internal(EditArray _mgr, TextSpan span, Engine engine, string filePath)

Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.cs	Sat Apr 21 00:41:41 2007
@@ -1,10 +1,13 @@
 using System;
 using System.Diagnostics;
 using System.Collections.Generic;
-
+using System.IO;
+using System.Threading;
+using System.Windows.Forms;
 using Microsoft.VisualStudio;
 using Microsoft.VisualStudio.OLE.Interop;
 using Microsoft.VisualStudio.Package;
+using Microsoft.VisualStudio.Shell.Interop;
 using Microsoft.VisualStudio.TextManager.Interop;
 
 using Nemerle.Completion2;
@@ -69,23 +72,27 @@
 					// cmdIdShrinkSelection
 					ShrinkSelection();
 					break;
-				case 0x3103: txt = "cmdIdRename"; break;
-				case 0x3104: txt = "cmdIdInline"; break;
-				case 0x3105:
+                case 0x3103: //cmdIdFindInheritors  
+                    FindInheritors();
+			        break;
+
+				case 0x3104: txt = "cmdIdRename"; break;
+				case 0x3105: txt = "cmdIdInline"; break;
+				case 0x3106:
 					// cmdIdOptions
 					ShowOptions();
 					break;
-				case 0x3106: // AstToolWindow
+				case 0x3107: // AstToolWindow
 					//this.CodeWindowManager.LanguageService.
 					NemerleSource source = Source as NemerleSource;
 					if (source != null)
 						source.ProjectInfo.ProjectNode.Package.OnAstToolWindowShow(null, null);
 					break;
-				case 0x3107: // cmdIdAddHighlighting
+				case 0x3108: // cmdIdAddHighlighting
 					HighlightSymbol();
 					break;
 				case 103: // ESC
-				case 0x3108: // cmdIdRemoveLastHighlighting
+				case 0x3109: // cmdIdRemoveLastHighlighting
 					RemoveLastHighlighting();
 					break;
 			}
@@ -160,6 +167,32 @@
 			}
 		}
 
+	    private void FindInheritors()
+	    {
+	        NemerleSource source = Source as NemerleSource;
+            NemerleLanguageService ourLanguageService = Source.LanguageService as NemerleLanguageService;
+	        if (source != null && ourLanguageService != null)
+	        {
+	            int lineIndex;
+	            int colIndex;
+	            TextView.GetCaretPos(out lineIndex, out colIndex);
+	            GotoInfo[] infos =
+	                Source.ProjectInfo.Project.GetInheritors(source.FileIndex, lineIndex + 1, colIndex + 1);
+
+	            // If we have only one found usage, then jump directly to it.
+	            if (infos.Length == 1)
+                    ourLanguageService.GotoLocation(infos[0].Location);
+	            else if (infos.Length > 0) // otherwise show a form to let user select entry manually
+	            {
+	                NativeWindow textEditorWnd =
+	                    NativeWindow.FromHandle(TextView.GetWindowHandle());
+	                using (GotoUsageForm popup = new GotoUsageForm(infos))
+	                    if (popup.ShowDialog(textEditorWnd) == DialogResult.OK)
+	                        ourLanguageService.GotoLocation(popup.Result.Location);
+	            }
+	        }
+	    }
+
 		private bool SelectionIsInStack(TextSpan selection)
 		{
 			// perhaps, using OnSelectChange routine would be better

Modified: vs-plugin/trunk/Nemerle.VsIntegration/Project/LibraryNode.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/Project/LibraryNode.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/Project/LibraryNode.cs	Sat Apr 21 00:41:41 2007
@@ -43,7 +43,7 @@
 		/// This is actually a copy of the _LIB_LISTTYPE enumeration with the difference that the
 		/// Flags attribute is set so that it is possible to specify more than one value.
 		/// </summary>
-		[Flags()]
+		[Flags]
 		public enum LibraryNodeType
 		{
 			None                   = 0,



More information about the svn mailing list