[svn] r7260: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n

VladD2 svnadmin at nemerle.org
Fri Jan 12 12:54:52 CET 2007


Log:
Add completion Add support of completion outside method body (but in method).

Author: VladD2
Date: Fri Jan 12 12:54:50 2007
New Revision: 7260

Modified:
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n	Fri Jan 12 12:54:50 2007
@@ -10,6 +10,7 @@
 using Nemerle.Compiler.Parsetree;
 using Nemerle.Compiler.Typedtree;
 using Nemerle.Utility;
+using Nemerle.Imperative;
 
 using SCG = System.Collections.Generic;
 
@@ -47,38 +48,85 @@
           }
           else
           {
-            Trace.WriteLine($"# RunCompletionEngine() return $(result.ObjectType)");
+            Debug.WriteLine($"# RunCompletionEngine() return $(result.ObjectType)");
             MakeCompletionList(result);
           }
         }
-        else
+        else // Completion outside method body.
+        {
+          def tryGetTypeEnforcementExpressionTokens() : bool * list[Token]
         {
           def header = method.Ast.header;
-          def headerLoc = header.Location + method.BodyLocation.FromStart();
-          if (headerLoc.Contains(line, col))
+            Debug.WriteLine($"# Completion outside body");
+            // Get all tokens of method...
+            // Note: If method not wellformed it can take next methods 
+            // tokens or no take body tokens.
+            def lex = this.Engine.GetLexer(source, header.Location);
+            def toks = lex.ReadAllTokens(); // toks is array!
+            // Fing near (to completion point) token index...
+            mutable index = toks.FindIndex(fun(x : Token)
+            {
+              def loc = x.Location;
+              loc.Contains(line, col) || loc.Line > line || loc.Line == line && loc.Column >= col
+            });
+            //DEBUG def (line, col) = (line, col);
+
+            // If last token location not on the completion point 
+            // or completion point at the start of last token location 
+            // we must ignore this token. Skip it...
+            def lastLoc = toks[index].Location;
+            when (index >= 0 && (!lastLoc.Contains(line, col)
+              || lastLoc.Line == line && lastLoc.Column == col)
+            )
+              index--; // Shift to the previos token location index...
+
+            if (index >= 0)
           {
-            Trace.WriteLine($"# Completion outside body");
-            def retLoc = header.ret_type.Location + method.BodyLocation.FromStart();
-            if (retLoc.Contains(line, col))
+              def findColonToken(i, lst) : bool * list[Token]
+              { // scat tokens backward.
+                def tok = toks[i];
+                match (tok)
+                {
+                  | Operator(":")          => (true, lst)
+                  | Operator(".")          => findColonToken(i - 1, tok :: lst)
+                  | BeginBrace  | BeginQuote | BeginRound | CharLiteral | EndBrace
+                  | EndQuote | EndRound | FloatLiteral | Operator | Semicolon | null | EndOfFile
+                                           => (false, []) // this tokens can't contains in type
+                  | _                      => findColonToken(i - 1, tok :: lst)
+                }
+              }
+              
+              // Get list of completion tokens. It can be situated on the interval
+              // from colone token to toks[index]. If before toks[index] no 
+              // colon token it is not type enforcement expression.
+              findColonToken(index, []);
+            }
+            else (false, [])
+          }
+          
+          def completeTypeEnforcement(lst)
             {
+            // Make fake expression and type it...
               def prefix = "_ : ";
-              def loc = Location(retLoc.FileIndex, retLoc.Line, retLoc.Column, line, col);
-              def typeName = source.GetRegion(loc);
+            def loc = if (lst is []) Location(fileIndex, line, col, line, col)
+                      else lst.Head.Location + lst.Last.Location;
+            def typeName = if (lst is []) "" else source.GetRegion(loc);
               def code = prefix + typeName;
               def result = _engine.RunCompletionEngine(method, code, loc, line, col + prefix.Length);
-              if ("void".StartsWithIgnoreCace(typeName) || typeName.TrimEnd() == "")
-                MakeCompletionList(result).Append(CompletionElem(0, "void", "type System.Void", null));
-              else
-                MakeCompletionList(result)
-            }
-            else
-              _topKeywords; // completion outside body (try conplete types)
-          }
-          else
+            if (result == null)
           {
-            Trace.WriteLine($"# Completion outside body");
-            _topKeywords
+              Trace.WriteLine("### RunCompletionEngine() (type enforcement completion) return null!");
+              array(0)
+            }
+            else if ("void".StartsWithIgnoreCace(typeName) || typeName.TrimEnd() == "")
+              MakeCompletionList(result).Append(CompletionElem(0, "void", "type System.Void", null));
+            else MakeCompletionList(result)
           }
+          
+          def (ok, tokens) = tryGetTypeEnforcementExpressionTokens();
+          
+          if (ok) completeTypeEnforcement(tokens)
+          else    _topKeywords;
         }
       }
 
@@ -400,7 +448,7 @@
             def bodyCode = source.GetRegion(loc.Line, loc.Column, loc.EndLine, loc.EndColumn);
             def tokens   = TokenFinder().Find(method.BodyTokens, line, col);
 
-            Trace.WriteLine($"Comlete took $(timer.Elapsed)");
+            Debug.WriteLine($"Comlete took $(timer.Elapsed)");
 
             match (tokens.Find(t => t is Token.RoundGroup))
             {



More information about the svn mailing list