[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