[svn] r7640: vs-plugin/trunk:
Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.csproj
Nemerle.Compiler.Utils/...
kliss
svnadmin at nemerle.org
Mon Apr 30 22:54:08 CEST 2007
Log:
Work on formatter.
Author: kliss
Date: Mon Apr 30 22:53:41 2007
New Revision: 7640
Added:
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeFormattingStageBase.n
Modified:
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Compiler.Utils.csproj
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/Formatter.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/FormatterResult.n
vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/TokenStreamFinder.n
vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleSource.cs
vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.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 Mon Apr 30 22:53:41 2007
@@ -172,6 +172,9 @@
<ItemGroup>
<Compile Include="Nemerle.Completion2\TextManagement\IFileTextMerger.n" />
</ItemGroup>
+ <ItemGroup>
+ <Compile Include="Nemerle.Completion2\CodeFormatting\CodeFormattingStageBase.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/CodeFormattingStageBase.n
==============================================================================
--- (empty file)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeFormattingStageBase.n Mon Apr 30 22:53:41 2007
@@ -0,0 +1,126 @@
+using System;
+
+using Nemerle;
+using Nemerle.Compiler;
+using Nemerle.Compiler.Utils;
+
+using SCG = System.Collections.Generic;
+
+namespace Nemerle.Completion2.CodeFormatting
+{
+
+ public class CodeFormattingStageBase : IFormattingStage
+ {
+ protected 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 = GetCounterpartTokenType(t);
+ counterpartTokenType = t;
+
+ if(tokenTypeToLookFor == null)
+ throw InvalidOperationException($"$(t.Name) is not paired token type.");
+ else
+ 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 this(engine : Engine, fileIndex : int)
+ {
+ this.Engine = engine;
+ _fileIndex = fileIndex;
+ }
+
+ public Engine : Engine
+ {
+ mutable _engine : Engine;
+ get { ManagerClass.Instance = _engine; _engine; }
+ private set { _engine = value }
+ }
+
+ mutable _region : Location = Location.Default;
+ protected RegionToFormat : Location
+ {
+ get{ _region }
+ private set { _region = value; }
+ }
+
+ protected _fileIndex : int;
+
+ protected mutable rootNamespaceNode : Decl.Namespace = null;
+ protected _tokenFinder : TokenStreamFinder = TokenStreamFinder();
+
+ private results : SCG.List.[FormatterResult] = SCG.List.[FormatterResult]();
+ protected AddResult(result : FormatterResult) : void
+ {
+ results.Add(result);
+ }
+ protected GetResults() : SCG.List.[FormatterResult]
+ {
+ results;
+ }
+
+ protected Prepare() : void
+ {
+ results.Clear();
+
+ // This is PExpr form of document
+ rootNamespaceNode = this.Engine.Project.CompileUnits[_fileIndex];
+
+ def src = this.Engine.ProjectSources.GetSource(_fileIndex).GetText();
+ def lexer = NonEatingLexer(this.Engine, src, Location(_fileIndex, 1, 1));
+
+ _tokenFinder.Initialize(lexer.ReadAllTokens());
+ }
+
+ public virtual FormatDocument() : SCG.List.[FormatterResult]
+ {
+ SCG.List.[FormatterResult]();
+ }
+ public virtual FormatRegion(startLine : int, startCol : int, endLine : int, endCol : int) : SCG.List.[FormatterResult]
+ {
+ RegionToFormat = Location(_fileIndex, startLine, startCol, endLine, endCol);
+ SCG.List.[FormatterResult]();
+ }
+
+ }
+}
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeIndentationStage.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeIndentationStage.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeIndentationStage.n Mon Apr 30 22:53:41 2007
@@ -1,23 +1,713 @@
using System;
+using System.Diagnostics;
+using System.Text;
+
using Nemerle.Utility;
+using Nemerle.Compiler;
+using Nemerle.Compiler.Parsetree;
using SCG = System.Collections.Generic;
+/* TODO: Formatter
+ * format comments
+ * format multiline expressions
+ * format macro calls with respect to custom syntax
+ *
+ *
+ */
+
namespace Nemerle.Completion2.CodeFormatting
{
- public class CodeIndentationStage : IFormattingStage
+ public class CodeIndentationStage : CodeFormattingStageBase
+ {
+ public this (engine : Engine, fileIndex : int)
+ {
+ base(engine, fileIndex);
+ }
+
+ mutable currentLine = 1;
+ mutable indentStack : list[int] = [];
+
+ PushIndent() : void
+ {
+ PushIndent(PeekIndent() + defaultIndentSize);
+ }
+ PushIndent(arg : int) : void
+ {
+ indentStack ::= arg;
+ }
+ PopIndent() : int
+ {
+ match(indentStack)
+ {
+ | x :: xs => indentStack = xs; x;
+ | [] => 1 // the first column.
+ }
+ }
+ PeekIndent() : int
+ {
+ match(indentStack)
+ {
+ | x :: _ => x;
+ | [] => 1 // the first column.
+ }
+ }
+
+ class IndentPusher : IDisposable
+ {
+ parentClass : CodeIndentationStage;
+ //private this() {}
+ public this(parent : CodeIndentationStage, indentValue : int)
+ {
+ parentClass = parent;
+ parentClass.PushIndent(indentValue);
+ }
+
+ public Dispose() : void
+ {
+ _ = parentClass.PopIndent();
+ }
+ }
+ GetIndentPusher() : IndentPusher
+ {
+ IndentPusher(this, PeekIndent() + defaultIndentSize);
+ }
+ GetIndentPusher(arg : int) : IndentPusher
+ {
+ IndentPusher(this, arg);
+ }
+
+ GetFirstBeginBraceAfterLocation(loc : Location) : Token
+ {
+ GetFirstBeginBraceAfterLocation(loc.EndLine, loc.EndColumn);
+ }
+ GetFirstBeginBraceAfterLocation(line : int, col : int) : Token
+ {
+ _tokenFinder.FindNextIf(line, col, tok => tok is Token.BeginBrace);
+ }
+ GetNextPairedBrace(brace : Token) : Token
+ {
+ def matchFinder = MatchingBrackerFinder().GetSearchFunc(brace.GetType());
+ _tokenFinder.FindNextIf(brace.Location.Line, brace.Location.EndColumn + 1, matchFinder);
+ }
+
+ public static IsWhiteSpace(this token : Token) : bool
+ {
+ match(token)
+ {
+ | Token.WhiteSpace
+ | Token.Indent
+ | Token.NewLine => true;
+ | _ => false
+ }
+ }
+
+ indentValue = " "; // TODO: make it configurable by user.
+ defaultIndentSize = 2;
+ matchCasesIndentOffset = 0; // match cases will be indented by matchCasesIndentOffset * defaultIndentSize
+ matchCasesBodyIndentOffset = 2;
+ variantOptionIndentOffset = 1;
+
+
+ IndentLocation(loc : Location) : void
+ {
+ def getIndentString(size)
+ {
+ def builder = StringBuilder(size * indentValue.Length);
+ repeat(size)
+ _ = builder.Append(indentValue);
+ builder.ToString();
+ }
+
+ def canOperate = !loc.IsEmpty && _tokenFinder.GetLineTokens(loc.Line)
+ .Filter(tok => tok.Location.EndColumn <= loc.Column)
+ .ForAll(_.IsWhiteSpace());
+ def isWithinRange = if(RegionToFormat.IsEmpty) true
+ else if(RegionToFormat.Contains(loc.Line, loc.Column)) true
+ else false;
+ when(canOperate && isWithinRange)
+ {
+ def expectedPosition = PeekIndent();
+
+ if(expectedPosition != 1)
+ AddResult(FormatterResult.Replace(loc.Line, 1, loc.Column, getIndentString(expectedPosition - 1)));
+ else
+ AddResult(FormatterResult.Erase(loc.Line, 1, loc.Column));
+
+ }
+ }
+
+ FormatMatchCases(cases : list[MatchCase]) : void
+ {
+ def formatSingleCase(matchCase)
+ {
+ matchCase.patterns.Map(_.Location).Iter(loc =>
+ {
+ def pipe = _tokenFinder.FindPrevIf(loc.Line, loc.Column, _ is Token.Operator("|"));
+ IndentLocation(pipe.Location);
+ });
+
+ using(GetIndentPusher(PeekIndent() + matchCasesBodyIndentOffset * defaultIndentSize))
+ {
+ cases.Map(_.body).Iter(FormatPExpr);
+ }
+ }
+
+ using(GetIndentPusher(PeekIndent() + matchCasesIndentOffset * defaultIndentSize))
+ {
+ cases.Iter(formatSingleCase);
+ }
+ }
+
+
+ FormatPExpr(pexpr : PExpr) : void
+ {
+
+ if(pexpr.Location.Line == pexpr.Location.EndLine)
+ IndentLocation(pexpr.Location);
+ else match(pexpr)
+ {
+ | Sequence(exprs) => // Sequence { body : list [PExpr]; }
+ exprs.Iter(FormatPExpr);
+ | Try(body, cases) => // Try { body : PExpr; cases : list [TryCase]; }
+ def beginTryBrace = GetFirstBeginBraceAfterLocation(pexpr.Location.Line, pexpr.Location.Column);
+ IndentLocation(pexpr.Location);
+ IndentLocation(beginTryBrace.Location);
+
+ using(GetIndentPusher())
+ {
+ FormatPExpr(body);
+ }
+
+ def endTryBrace = GetNextPairedBrace(beginTryBrace);
+ IndentLocation(endTryBrace.Location);
+
+ def catchKeyword = _tokenFinder.FindNextIf(endTryBrace.Location.Line, endTryBrace.Location.Column, _ is Token.Keyword("catch"));
+ def beginCatchBrace = GetFirstBeginBraceAfterLocation(catchKeyword.Location);
+ def endCatchBrace = GetNextPairedBrace(beginCatchBrace);
+ IndentLocation(catchKeyword.Location);
+ IndentLocation(beginCatchBrace.Location);
+
+ //cases.Map(_.Location).Iter(WriteLocation);
+ cases.Iter(FormatTryCase);
+
+ IndentLocation(endCatchBrace.Location);
+
+ | TryFinally(body, handler) => // TryFinally { body : PExpr; handler : PExpr; }
+ def beginTryBrace = GetFirstBeginBraceAfterLocation(pexpr.Location.Line, pexpr.Location.Column);
+ IndentLocation(pexpr.Location);
+ IndentLocation(beginTryBrace.Location);
+
+ using(GetIndentPusher())
+ {
+ FormatPExpr(body);
+ }
+
+ def endTryBrace = GetNextPairedBrace(beginTryBrace);
+ IndentLocation(endTryBrace.Location);
+
+ def finallyKeyword = _tokenFinder.FindNextIf(endTryBrace.Location.Line, endTryBrace.Location.Column, _ is Token.Keyword("finally"));
+ def beginFinallyBrace = GetFirstBeginBraceAfterLocation(finallyKeyword.Location);
+ def endFinallyBrace = GetNextPairedBrace(beginFinallyBrace);
+ IndentLocation(finallyKeyword.Location);
+ IndentLocation(beginFinallyBrace.Location);
+
+ using(GetIndentPusher())
+ {
+ FormatPExpr(handler);
+ }
+
+ IndentLocation(endFinallyBrace.Location);
+
+ | MacroCall(_, ns, parms) as macroExpr => // MacroCall { name : Name; ns : NamespaceTree.Node; parms : list [SyntaxElement]; }
+ match(ns.Value)
+ {
+ | NamespaceTree.TypeInfoCache.MacroCall (m) =>
+ def (rules, _) = m.SyntaxExtension ();
+ mutable parms_left = parms;
+ //def rules = rules.Next;
+ mutable firstKeywordLoc = None();
+
+ def formatExpression(pexpr : PExpr)
+ {
+ | PExpr.Sequence(body) as seq =>
+ def beginBrace = _tokenFinder.FindAt(seq.Location.Line, seq.Location.Column);
+ assert(beginBrace is Token.BeginBrace);
+ IndentLocation(beginBrace.Location);
+
+ using(GetIndentPusher())
+ {
+ body.Iter(FormatPExpr);
+ }
+
+ IndentLocation(GetNextPairedBrace(beginBrace).Location);
+ | _ =>
+ using(GetIndentPusher())
+ {
+ FormatPExpr(pexpr);
+ }
+ }
+ def processSyntaxRules (x)
+ {
+ match (x)
+ {
+ | GrammarElement.Keyword (k) =>
+ def kw = _tokenFinder.FindNextIf(macroExpr.Location.Line,
+ macroExpr.Location.Column,
+ fun(tok : Token)
+ {
+ | Token.Keyword as a when a.name == k => true
+ | _ => false;
+ });
+ match(firstKeywordLoc)
+ {
+ | None => firstKeywordLoc = Some(kw.Location);
+ | _ => ()
+ }
+ using(GetIndentPusher(firstKeywordLoc.UnSome().Column))
+ {
+ IndentLocation(kw.Location);
+ }
+
+ //| GrammarElement.Operator (")") => acc.Write (") ")
+ //| GrammarElement.Operator ("}") => acc.Write ("} ")
+ //| GrammarElement.Operator (o) => acc.Write (o)
+ //| GrammarElement.Optional (g) => print_gel (g)
+ //| GrammarElement.RawToken =>
+ //match (parms_left) {
+ //| SyntaxElement.RawToken (t) :: xs =>
+ //acc.Write (t.ToString ());
+ //parms_left = xs;
+ //| _ =>
+ //Message.Error ("expected raw token as parameter of macro "
+ //+ namespc.GetDisplayName ())
+ //};
+ //
+ | GrammarElement.Expression =>
+ match (parms_left) {
+ | SyntaxElement.Expression (e) :: xs =>
+ //def beginBrace = GetFirstBeginBraceAfterLocation(e.Location.Line, e.Location.Column);
+ //IndentLocation(beginBrace.Location);
+ formatExpression(e);
+ //IndentLocation(GetNextPairedBrace(beginBrace).Location);
+ parms_left = xs;
+ | _ => ()
+ };
+ | GrammarElement.Parameter =>
+ match (parms_left)
+ {
+ | SyntaxElement.Parameter (p) :: xs =>
+ IndentLocation(p.Location);
+ parms_left = xs;
+ | _ => ()
+ }
+
+ //| GrammarElement.ExpressionList =>
+ //SeparatedCalls (", ", parms_left, fun (_) {
+ //| SyntaxElement.Expression (e) => SprintExpr (ctx, e, indentation, acc)
+ //| _ =>
+ //Message.Error ("expected expression in macro parameters: "
+ //+ namespc.GetDisplayName ())
+ //}, acc);
+ //
+ //| GrammarElement.Branch | GrammarElement.End => Util.ice ("invalid node");
+ | _ => ()
+ }
+ when (x.Next != null)
+ processSyntaxRules (x.Next)
+ }
+ processSyntaxRules(rules);
+ | _ => ()
+ }
+
+
+ | Match(_, cases) => // Match { expr : PExpr; cases : list [MatchCase]; }
+ def beginBrace = GetFirstBeginBraceAfterLocation(pexpr.Location.Line, pexpr.Location.Column);
+ IndentLocation(pexpr.Location);
+ IndentLocation(beginBrace.Location);
+
+ FormatMatchCases(cases);
+
+ def endBrace = GetNextPairedBrace(beginBrace);
+ IndentLocation(endBrace.Location);
+ | DefFunctions(funcs) => // DefFunctions { funs : list [Function_decl]; }
+ foreach(func in funcs)
+ {
+ def kw = _tokenFinder.FindPrevIf( func.header.Location.Line,
+ func.header.Location.Column,
+ tok => match(tok)
+ {
+ | Token.Keyword("def")
+ | Token.Keyword("and") => true;
+ | _ => false;
+ });
+ IndentLocation(kw.Location);
+ def beginBrace = GetFirstBeginBraceAfterLocation(func.header.Location);
+ IndentLocation(beginBrace.Location);
+
+ match(func.body)
+ {
+ | PExpr.Match(_, cases) => FormatMatchCases(cases);
+ | expr =>
+ using(GetIndentPusher())
{
- public this (_engine : Engine, _fileIndex : int)
+ FormatPExpr(expr);
+ }
+ }
+
+ IndentLocation(GetNextPairedBrace(beginBrace).Location);
+ }
+ | Lambda(_) => // Lambda { decl : Function_decl; }
+ ()
+ //IndentLocation(lambda.header.Location);
+ //def formatBodyAfter(loc)
+ //{
+ // def tok = _tokenFinder.FindNextIf(loc.EndLine, loc.EndColumn, FirstNonWhitespaceToken);
+ // match(tok)
+ // {
+ // | BeginBrace =>
+ // IndentLocation(tok.Location);
+ // using(GetIndentPusher())
+ // {
+ // FormatPExpr(lambda.body);
+ // }
+ // IndentLocation(GetNextPairedBrace(tok).Location);
+ // | Operator("=>") => formatBodyAfter(tok.Location);
+ // | _ =>
+ // using(GetIndentPusher())
+ // {
+ // FormatPExpr(lambda.body);
+ // }
+ // }
+ //}
+ //formatBodyAfter(lambda.header.Location);
+
+ | Define (name, val)
+ | DefMutable(name, val) =>
+ def kw = _tokenFinder.FindPrevIf( name.Location.Line,
+ name.Location.Column,
+ tok => match(tok)
+ {
+ | Token.Keyword("def")
+ | Token.Keyword("mutable") => true;
+ | _ => false;
+ });
+ IndentLocation(kw.Location);
+ FormatPExpr(name);
+
+ def equalSign = _tokenFinder.FindNextIf(name.Location.EndLine, name.Location.EndColumn, _ is Token.Operator("="));
+ using(GetIndentPusher(equalSign.Location.EndColumn + 1))
+ {
+ FormatPExpr(val);
+ }
+
+ | Assign (name, val) =>
+ FormatPExpr(name);
+
+ def equalSign = _tokenFinder.FindNextIf(name.Location.EndLine, name.Location.EndColumn, _ is Token.Operator("="));
+ using(GetIndentPusher(equalSign.Location.EndColumn + 1))
+ {
+ FormatPExpr(val);
+ }
+ //| Indexer (obj, parms)
+ | Call(obj, parms) => // here obj is the func name.
+ FormatPExpr(obj);
+ using(GetIndentPusher(parms.Head.Location.Column + defaultIndentSize))
+ {
+ parms.Iter(FormatPExpr);
+ }
+ | Member(obj, member) =>
+ FormatPExpr(obj);
+ def dot = _tokenFinder.FindNextIf(obj.Location.EndLine, obj.Location.EndColumn, _ is Token.Operator("."));
+ using(GetIndentPusher())
+ {
+ IndentLocation(dot.Location);
+ FormatSplicable(member);
+ }
+ | ListLiteral (elems) =>
+ def beginBracket = _tokenFinder.FindNextIf(pexpr.Location.Line, pexpr.Location.Column, _ is Token.BeginSquare);
+ IndentLocation(beginBracket.Location);
+ using(GetIndentPusher())
+ {
+ elems.Iter(FormatPExpr);
+ }
+ IndentLocation(GetNextPairedBrace(beginBracket).Location);
+
+ | _ => Debug.WriteLine($"Unhandled PExpr, $(pexpr.ToString())");
+ }
+ }
+
+/* Unhandled PExpr's
+ | Wildcard // _ used mainly in patterns, but also in _ = ignored
+ | Void // void used only in types
+ | As { pat : PExpr; name : Splicable; }
+ | Is { pat : PExpr; ty : PExpr; }
+ | Where { name : PExpr; fields : PExpr; }
+
+ | Ref { name : Name; }
+ | GenericSpecifier { func : PExpr; generic_parms : list [PExpr]; }
+ | Throw { exn : PExpr; }
+ | Literal { val : Nemerle.Compiler.Literal; }
+ | This
+ | Base
+ | Typeof { ty : PExpr; }
+ | TypeConversion { expr : PExpr; ty : PExpr; } // (expr :> ty)
+ | TypeEnforcement { expr : PExpr; ty : PExpr; } // (expr : ty)
+ | Tuple { args : list [PExpr]; }
+ | Array { rank : PExpr; args : PExpr; }
+ | EmptyArray { sizes : list [PExpr]; }
+ | ParmByRef { parm : PExpr; }
+ | ParmOut { parm : PExpr; }
+
+ | Error // placeholder of missing tree (where some errors occured)
+
+ // macros stuff
+ | Quoted { body : SyntaxElement; }
+ | Spliced { body : PExpr; }
+ | ToComplete { body : Name; }
+ | Ellipsis { body : PExpr; }
+ | Typed { body : Typedtree.TExpr; }
+ | TypedPattern { body : Typedtree.Pattern; }
+ | TypedType { body : TyVar; }
+
+*/
+ FormatSplicable(name : Splicable) : void
+ {
+ | Name (body)
+ | HalfId(body) => IndentLocation(body.Location);
+ | Expression(expr) => FormatPExpr(expr);
+ }
+
+ FormatTryCase(tryCase : TryCase) : void
+ {
+ def pipe = _tokenFinder.FindPrevIf(tryCase.Location.Line, tryCase.Location.Column, _ is Token.Operator("|"));
+ IndentLocation(pipe.Location);
+
+ match(tryCase)
+ {
+ | Catch(_, exn_ty, handler) =>
+ FormatPExpr(exn_ty);
+ using(GetIndentPusher(PeekIndent() + matchCasesBodyIndentOffset * defaultIndentSize))
+ {
+ FormatPExpr(handler);
+ }
+ | Filter(_, exn_ty, filter, handler) =>
+ FormatPExpr(exn_ty);
+ FormatPExpr(filter);
+ using(GetIndentPusher(PeekIndent() + matchCasesBodyIndentOffset * defaultIndentSize))
+ {
+ FormatPExpr(handler);
+ }
+ | Ellipsis(body) =>
+ using(GetIndentPusher(PeekIndent() + matchCasesBodyIndentOffset * defaultIndentSize))
+ {
+ FormatPExpr(body);
+ }
+ }
+ }
+
+ FormatMethod(mb : MethodBuilder) : void
+ {
+ // Skipping properties (other methods too?)
+ when((mb.Attributes & NemerleAttributes.SpecialName) == 0)
+ {
+ // TODO: Format header properly (handle multiline headers)
+ IndentLocation(mb.Location);
+
+ def beginBrace = GetFirstBeginBraceAfterLocation(mb.GetHeader().Location);
+ IndentLocation(beginBrace.Location);
+
+ match(mb.BodyParsed)
+ {
+ | PExpr.Match(_, cases) => FormatMatchCases(cases);
+ | expr =>
+ using(GetIndentPusher())
+ {
+ FormatPExpr(expr);
+ }
+ }
+
+ IndentLocation(GetNextPairedBrace(beginBrace).Location);
+ }
+ }
+
+ FormatProperty(pb : PropertyBuilder) : void
+ {
+ def formatInternal(method : MethodBuilder, kwPredicate)
+ {
+ when(method != null)
+ {
+ def kw = _tokenFinder.FindNextIf( method.Location.Line,
+ method.Location.Column,
+ kwPredicate);
+ IndentLocation(kw.Location);
+
+ def beginBrace = GetFirstBeginBraceAfterLocation(kw.Location);
+ IndentLocation(beginBrace.Location);
+
+ using(GetIndentPusher())
+ {
+ FormatPExpr(method.BodyParsed);
+ }
+
+ IndentLocation(GetNextPairedBrace(beginBrace).Location);
+ }
+ }
+
+ IndentLocation(pb.Location);
+ def beginBrace = GetFirstBeginBraceAfterLocation(pb.Ast.name.Location);
+ IndentLocation(beginBrace.Location);
+
+ using(GetIndentPusher())
+ {
+ formatInternal(pb.GetGetter() :> MethodBuilder, _ is Token.Identifier("get"));
+ formatInternal(pb.GetSetter() :> MethodBuilder, _ is Token.Identifier("set"));
+ }
+
+ IndentLocation(GetNextPairedBrace(beginBrace).Location);
+ }
+
+ FormatField(fb : FieldBuilder) : void
{
+ Debug.Assert(fb.Location.Line == fb.Location.EndLine, $"Declaration of field $(fb.Name) spans over several lines. Can't indent.");
+ IndentLocation(fb.Location);
+ }
+ FormatEvent(eb : EventBuilder) : void
+ {
+ Debug.Assert(eb.Location.Line == eb.Location.EndLine, $"Declaration of event $(eb.Name) spans over several lines. Can't indent.");
+ IndentLocation(eb.Location);
}
- public FormatDocument() : SCG.List.[FormatterResult]
+ FormatVariantOption(variantOption : TypeBuilder) : void
+ {
+ def pipe = _tokenFinder.FindPrevIf(variantOption.Location.Line, variantOption.Location.Column, _ is Token.Operator("|"));
+ IndentLocation(pipe.Location);
+
+ def members = variantOption.GetDirectMembers();
+ def hasFields = ! members.ForAll(member => member.Location.IsGenerated);
+ when(hasFields)
+ {
+ using(GetIndentPusher(PeekIndent() + defaultIndentSize * variantOptionIndentOffset))
+ {
+ def beginBrace = GetFirstBeginBraceAfterLocation(variantOption.Location.Line, variantOption.Location.Column);
+ IndentLocation(beginBrace.Location);
+ using(GetIndentPusher())
+ {
+ foreach(member in members)
+ FormatTypeBuilderMember(member);
+ }
+ IndentLocation(GetNextPairedBrace(beginBrace).Location);
+ }
+
+ }
+ }
+
+ FormatTypeBuilderMember(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 => if(tb.IsVariantOption)
+ FormatVariantOption(tb)
+ else
+ FormatType(tb);
+ | _ => Debug.WriteLine($"!!! Unhandled member type in FormatClassMember: $(member.GetType().Name)");
+ }
+
+ FormatType(tb : TypeBuilder) : void
+ {
+ unless(tb.Location.IsGenerated)
{
- SCG.List.[FormatterResult]();
+ 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.
+
+ IndentLocation(tb.Location);
+ def beginBrace = GetFirstBeginBraceAfterLocation(part.name.Location);
+ IndentLocation(beginBrace.Location);
+
+ PushIndent();
+
+ foreach(member in tb.GetDirectMembers())
+ FormatTypeBuilderMember(member);
+
+ _ = PopIndent();
+ def endBrace = GetNextPairedBrace(beginBrace);
+ IndentLocation(endBrace.Location);
+ }
+ }
+
+ FormatUsing(us : Decl.Using) : void
+ {
+ IndentLocation(us.Location);
+ }
+
+ FormatNamespace(ns : Decl.Namespace) : void
+ {
+ def beginBrace = GetFirstBeginBraceAfterLocation(ns.Location.Line, ns.Location.Column);
+ mutable isGlobalNS = false;
+ match(ns.Name)
+ {
+ | _ :: _ => // if namespace name isn't empty (not global namespace)
+ IndentLocation(ns.Location);
+ when(beginBrace.Location.Line > ns.Location.Line) // assume that namespace name is single-lined.
+ IndentLocation(beginBrace.Location);
+ | _ => isGlobalNS = true;
+ }
+ unless(isGlobalNS)
+ PushIndent();
+
+ 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);
+ | _ => ()
+ }
+ }
+
+ unless(isGlobalNS)
+ {
+ _ = PopIndent();
+ def endBrace = GetNextPairedBrace(beginBrace);
+ IndentLocation(endBrace.Location);
+ }
+ }
+
+ _WriteLocation(loc : Location) : void
+ {
+ Debug.WriteLine($"Location: $(loc.Line), $(loc.Column), $(loc.EndLine), $(loc.EndColumn)");
+ }
+
+ public override FormatDocument() : SCG.List.[FormatterResult]
+ {
+ Prepare();
+
+ //def preparser = PreParser(lexer);
+ //_documentTokens = preparser.PreParse();
+ //
+ FormatNamespace(rootNamespaceNode);
+ GetResults();
}
- public FormatRegion(_startLine : int, _startCol : int, _endLine : int, _endCol : int) : SCG.List.[FormatterResult]
+ public override FormatRegion(startLine : int, startCol : int, endLine : int, endCol : int) : SCG.List.[FormatterResult]
{
+ _ = base.FormatRegion(startLine, startCol, endLine, endCol);
FormatDocument();
}
}
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeLineBreakingStage.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeLineBreakingStage.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/CodeLineBreakingStage.n Mon Apr 30 22:53:41 2007
@@ -12,80 +12,16 @@
namespace Nemerle.Completion2.CodeFormatting
{
- class CodeLineBreakingStage : IFormattingStage
+ class CodeLineBreakingStage : CodeFormattingStageBase
{
- 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;
@@ -97,7 +33,7 @@
LineBreak(loc : Location) : void
{
- _results.Add(FormatterResult.Insert(loc.Line, loc.Column, Environment.NewLine));
+ AddResult(FormatterResult.Insert(loc.Line, loc.Column, Environment.NewLine));
}
NeededLineBreaks(loc : Location) : int
@@ -109,12 +45,6 @@
};
}
- IsBeginBrace(token : Token) : bool
- {
- | BeginBrace => true
- | _ => false
- }
-
#endregion
FormatBrace(token : Token) : void
@@ -131,7 +61,8 @@
FormatNamespace(ns : Decl.Namespace) : void
{
- def beginBrace = _tokenFinder.FindNextIf(ns.Location.Line, ns.Location.Column, IsBeginBrace);
+ def beginBrace = _tokenFinder.FindNextIf(ns.Location.Line, ns.Location.Column, tok => tok is Token.BeginBrace);
+
match(ns.Name)
{
| _ :: _ => // if namespace name isn't empty (not global namespace)
@@ -139,7 +70,7 @@
FormatBrace(beginBrace);
| _ => ();
}
- _expectedCol += indentSize;
+
foreach(x in ns.Decls)
{
match(x)
@@ -150,7 +81,6 @@
| _ => ()
}
}
- _expectedCol -= indentSize;
// TODO: Format end brace here.
}
@@ -172,14 +102,14 @@
unless(mb.IsGenerated)
{
SetExpectedLine(mb.Header.Location.EndLine + 1);
- def beginBrace = _tokenFinder.FindNextIf(mb.Header.Location.EndLine, mb.Header.Location.EndColumn, IsBeginBrace);
+ def beginBrace = _tokenFinder.FindNextIf(mb.Header.Location.EndLine, mb.Header.Location.EndColumn, tok => tok is Token.BeginBrace);
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*/"));
+ AddResult(FormatterResult.Insert(endBrace.Location.Line, endBrace.Location.Column, "/*endBrace*/"));
FormatBrace(endBrace);
SetExpectedLine(endBrace.Location.EndLine + 1);
@@ -227,9 +157,11 @@
| _ => Debug.WriteLine($"!!! Unhandled member type in FormatClassMember: $(member.GetType().Name)");
}
- FormatType(_tb : TypeBuilder) : void
+ FormatType(tb : TypeBuilder) : void
{
- def part = match(_tb.AstParts.Find(part => part.Location.FileIndex == _fileIndex))
+ unless(tb.Location.IsGenerated)
+ {
+ def part = match(tb.AstParts.Find(part => part.Location.FileIndex == _fileIndex))
{
| Some(val) => val
| None => throw ApplicationException($"No type part found in file $_fileIndex");
@@ -238,10 +170,10 @@
// 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);
+ def beginBrace = _tokenFinder.FindNextIf(part.name.Location.EndLine, part.name.Location.EndColumn, tok => tok is Token.BeginBrace);
FormatBrace(beginBrace);
- foreach(member in _tb.GetDirectMembers())
+ foreach(member in tb.GetDirectMembers())
FormatClassMember(member);
def matchFinder = MatchingBrackerFinder().GetSearchFunc(typeof(Token.EndBrace));
@@ -250,39 +182,30 @@
SetExpectedLine(endBrace.Location.EndLine + 1);
}
+ }
#region IFormattingStage members
public this(engine : Engine, fileIndex : int)
{
- this.Engine = engine;
- _fileIndex = fileIndex;
- _results = SCG.List.[FormatterResult]();
+ base(engine, fileIndex);
}
- public FormatRegion(_startLine : int, _startCol : int, _endLine : int, _endCol : int) : SCG.List.[FormatterResult]
+ public override FormatRegion(startLine : int, startCol : int, endLine : int, endCol : int) : SCG.List.[FormatterResult]
{
+ _ = base.FormatRegion(startLine, startCol, endLine, endCol);
FormatDocument();
}
- public FormatDocument() : SCG.List.[FormatterResult]
+ public override 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();
+ Prepare();
- FormatNamespace(declNS);
- _results;
+ //def preparser = PreParser(lexer);
+ //_documentTokens = preparser.PreParse();
+ //
+ FormatNamespace(rootNamespaceNode);
+ GetResults();
}
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 Mon Apr 30 22:53:41 2007
@@ -10,8 +10,6 @@
using SCG = System.Collections.Generic;
using Nemerle.Compiler.Parsetree;
-using MsgBox = System.Windows.Forms.MessageBox;
-
namespace Nemerle.Completion2.CodeFormatting
{
public class Formatter
@@ -99,13 +97,13 @@
public static FormatDocument(engine : Engine, filePath : string) : SCG.List[FormatterResult]
{
def fileIndex = engine.Project.CompileUnits.GetFileIndex(filePath);
- //def instance = Formatter(engine, fileIndex);
def results = SCG.List.[FormatterResult]();
+ def _ = CodeLineBreakingStage(engine, fileIndex);
def stages : list[IFormattingStage] =
[
- CodeLineBreakingStage(engine, fileIndex)
- //,CodeIndentationStage(engine, fileIndex)
+ //CodeLineBreakingStage(engine, fileIndex)
+ CodeIndentationStage(engine, fileIndex)
];
// TODO: After each stage send result to the VS,
@@ -120,10 +118,26 @@
}
// Here we have to find out what piece of AST to analyze
- public FormatSpan(_startLine : int, _startCol : int, _endLine : int,
- _endCol : int, _filePath : string) : SCG.List[FormatterResult]
+ public static FormatSpan( startLine : int, startCol : int, endLine : int,
+ endCol : int, engine : Engine, filePath : string) : SCG.List[FormatterResult]
{
- SCG.List.[FormatterResult]();
+ def fileIndex = engine.Project.CompileUnits.GetFileIndex(filePath);
+ def results = SCG.List.[FormatterResult]();
+
+ 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.FormatRegion(startLine, startCol, endLine, endCol));
+ }
+
+ results;
}
}
}
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/FormatterResult.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/FormatterResult.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/FormatterResult.n Mon Apr 30 22:53:41 2007
@@ -7,7 +7,7 @@
namespace Nemerle.Completion2.CodeFormatting
{
- [Record]
+ [Record (Exclude = [ResultType])]
public class FormatterResult
{
[Accessor] _startLine : int = -1;
@@ -15,12 +15,37 @@
[Accessor] _endLine : int = -1;
[Accessor] _endCol : int = -1;
[Accessor] _replacementString : string = "";
+ public ResultType : string
+ {
+ get
+ {
+ if(StartCol == EndCol)
+ {
+ if(ReplacementString.Length > 0)
+ "Insertion"
+ else
+ "ERROR"
+ }
+ else
+ {
+ if(ReplacementString.Length == 0)
+ "Erase"
+ else
+ "Replacement"
+ }
+ }
+ }
public static Replace(loc : Location, replacement : string) : FormatterResult
{
FormatterResult(loc.Line, loc.Column, loc.EndLine, loc.EndColumn, replacement);
}
+ public static Replace(line : int, fromCol : int, toCol : int, replacement : string) : FormatterResult
+ {
+ FormatterResult(line, fromCol, line, toCol, replacement);
+ }
+
public static Insert(line : int, column : int, value : string) : FormatterResult
{
FormatterResult(line, column, line, column, value);
@@ -28,7 +53,12 @@
public static Erase(loc : Location) : FormatterResult
{
- FormatterResult(loc.Line, loc.Column, loc.EndLine, loc.EndColumn, "");
+ Replace(loc, "");
+ }
+
+ public static Erase(line : int, fromCol : int, toCol : int) : FormatterResult
+ {
+ Replace(line, fromCol, toCol, "");
}
}
}
\ No newline at end of file
Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/TokenStreamFinder.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/TokenStreamFinder.n (original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeFormatting/TokenStreamFinder.n Mon Apr 30 22:53:41 2007
@@ -1,7 +1,9 @@
using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+
using Nemerle;
using Nemerle.Compiler;
-using System.Collections.Generic;
using Nemerle.Completion2.CodeFormatting;
namespace Nemerle.Completion2
@@ -10,10 +12,19 @@
public class TokenStreamFinder
{
_sortedTokens : Dictionary.[int, array[Token]] = Dictionary();
+ mutable isInitialized = false;
+
+ public this(){}
// We're assuming that tokens are ordered as they appear in the source, i.e. no reversing and shuffling.
public this(tokens : array[Token])
{
+ Initialize(tokens);
+ }
+
+ public Initialize(tokens : array[Token]) : void
+ {
+ isInitialized = true;
def curLineTokens = List();
// Enumerate tokens starting from currentTokenPos and see if they belong
@@ -56,6 +67,10 @@
public FindNextIf(line : int, col : int, predicate : Token -> bool) : Token
{
+ if(!isInitialized)
+ throw InvalidOperationException("TokenStreamFinder hasn't been properly initialized. Either use constructor with parameters or Initialize() method.");
+ else
+ {
mutable curLine = line;
mutable curIndex = 0;
@@ -70,7 +85,7 @@
{
if(curIndex < _sortedTokens[curLine].Length - 1)
curIndex++;
- else when(_sortedTokens.ContainsKey(curLine + 1))
+ else //when(_sortedTokens.ContainsKey(curLine + 1))
{
curLine++;
curIndex = 0;
@@ -82,6 +97,8 @@
advancePosition();
tok
}
+ when(!_sortedTokens.ContainsKey(curLine))
+ Debug.WriteLine($"No key: $curLine");
mutable startLineTokens = _sortedTokens[curLine];
def setStartPoint()
{
@@ -103,7 +120,7 @@
// Ok, start position defined. Start matching each next token against given predicate.
mutable result = getNextToken();
- while(!predicate(result))
+ while(result != null && !predicate(result))
{
result = getNextToken();
}
@@ -111,16 +128,89 @@
throw TokenNotFoundException("Token not found");
result;
}
+ }
- public FindPrevIf(_line : int, _col : int, _predicate : Token -> bool) : Token
+ public FindPrevIf(line : int, col : int, predicate : Token -> bool) : Token
+ {
+ if(!isInitialized)
+ throw InvalidOperationException("TokenStreamFinder hasn't been properly initialized. Either use constructor with parameters or Initialize() method.");
+ else
{
- throw NotImplementedException()
+ mutable curLine = line;
+ mutable curIndex = _sortedTokens[curLine].Length - 1;
+
+ def getCurrentToken()
+ {
+ if(curIndex < _sortedTokens[curLine].Length)
+ _sortedTokens[curLine][curIndex]
+ else
+ null
+ }
+ def retreatPosition()
+ {
+ if(curIndex > 0)
+ curIndex--;
+ else //when(_sortedTokens.ContainsKey(curLine - 1))
+ {
+ curLine--;
+ curIndex = _sortedTokens[curLine].Length - 1;
+ }
+ }
+ def getPrevToken()
+ {
+ def tok = getCurrentToken();
+ retreatPosition();
+ tok
+ }
+ when(!_sortedTokens.ContainsKey(curLine))
+ Debug.WriteLine($"No key: $curLine");
+ mutable startLineTokens = _sortedTokens[curLine];
+ def setStartPoint()
+ {
+ if(curLine == line && curIndex > 0 && startLineTokens[curIndex].Location.Column > col)
+ {
+ curIndex--;
+ setStartPoint();
+ }
+ else when(curIndex == 0)
+ {
+ curLine--;
+ startLineTokens = _sortedTokens[curLine];
+ curIndex = _sortedTokens[curLine].Length - 1;
+ setStartPoint();
+ }
+ }
+
+ setStartPoint();
+
+ // Ok, start position defined. Start matching each next token against given predicate.
+ mutable result = getPrevToken();
+ while(result != null && !predicate(result))
+ {
+ result = getPrevToken();
+ }
+ when(result == null)
+ throw TokenNotFoundException("Token not found");
+ result;
+ }
}
public FindAt(line : int, col : int) : Token
{
+ if(!isInitialized)
+ throw InvalidOperationException("TokenStreamFinder hasn't been properly initialized. Either use constructor with parameters or Initialize() method.");
+ else
+ {
def lineTokens = _sortedTokens[line];
- def result = Array.Find(lineTokens, tok => tok.Location.Contains(line, col));
+ def result = Array.Find(lineTokens, tok => tok.Location.Contains(line, col)
+ && col != tok.Location.EndColumn);
+ result;
+ }
+ }
+
+ public GetLineTokens(line : int) : array[Token]
+ {
+ def result = _sortedTokens[line];
result;
}
}
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 Mon Apr 30 22:53:41 2007
@@ -179,7 +179,13 @@
}
private void ReformatSpan_internal(EditArray _mgr, TextSpan span, Engine engine, string filePath)
{
- List<FormatterResult> results = Formatter.FormatDocument(engine, filePath);
+ List<FormatterResult> results =
+ Formatter.FormatSpan(span.iStartLine + 1,
+ span.iStartIndex + 1,
+ span.iEndLine + 1,
+ span.iEndIndex + 1,
+ engine,
+ filePath);
EditArray mgr = new EditArray(_mgr.Source, _mgr.TextView, true, "formatting");
foreach (FormatterResult res in results)
{
Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleViewFilter.cs
==============================================================================
More information about the svn
mailing list