[svn] r6902: vs-plugin/trunk/Nemerle.Compiler.Utils: Nemerle.Completion2/CodeModel/ExprFinder.n Nemerle.Co...

phantom svnadmin at nemerle.org
Wed Nov 15 15:47:48 CET 2006


Log:


Author: phantom
Date: Wed Nov 15 15:47:46 2006
New Revision: 6902

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

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	Wed Nov 15 15:47:46 2006
@@ -69,6 +69,59 @@
       }
     }
 
+    mutable localValue : LocalValue;
+    mutable localValueEntries : list[Location];
+    mutable definitionFound : bool;
+    
+    // TODO: think about (dis)advantages of switching to a parsed tree walking
+    ProcessNodeInFindLocalValueEntries(exprWalkInfo: ExprWalkInfo) : void
+    {
+      def node = exprWalkInfo.Node;
+      Debug.WriteLine($"processing node: $(node.ToString().Brief())");
+      when (node is TExpr)
+      {
+        def node = node :> TExpr;
+        Debug.WriteLine($"(location: $(node.Location)");
+        when (localValue.Location.NotStrictlyBefore(node.Location))
+        {
+          //Debug.WriteLine("located after definition or is definition");
+          Debug.WriteLine($" type of node: $(node.GetType())");          
+          def processLocalValueEntry(entry, definition = false)
+          {
+            Debug.WriteLine($"  contains $entry");
+            when (entry.Name == localValue.Name)
+            {
+              Debug.WriteLine($"   has the same name: $(entry.Name)");
+              // TODO: check the if it is really in the same scope
+              // TODO: walk around LocalValue.Location incorrect value
+              if (definition)
+              {
+                if (definitionFound)
+                  exprWalkInfo.Stop();
+                else
+                {
+                  definitionFound = true;
+                  Debug.WriteLine($"    it's a definition! (location: $(entry.Location))");
+                  localValueEntries ::= node.Location;
+                }
+              }
+              else
+              {
+                Debug.WriteLine($"    it's a reference! (location: $(entry.Location))");
+                localValueEntries ::= node.Location;
+              }
+            }
+          }
+          match (node)
+          {
+            | DefValIn(entry, _, _) => processLocalValueEntry(entry, true);
+            | LocalRef(entry) => processLocalValueEntry(entry);
+            | _ => ();
+          }
+        }
+      }
+    }
+
     GetPattern(pattern : Pattern) : object
     {
     | Application(name, _) =>      // { name : TypeInfo; arg : Pattern; }
@@ -273,6 +326,19 @@
         (Location.Default, null, null)
     }
 
+    public FindLocalValueEntries(typedExpressionRoot : TExpr, localValue: LocalValue) : list[Location]
+    {
+      this.localValue = localValue;
+      localValueEntries = [];
+      definitionFound = false;
+      ExprWalker().Walk(typedExpressionRoot, ProcessNodeInFindLocalValueEntries);
+      def entries = localValueEntries.Reverse();
+      Debug.WriteLine($"Found $(entries.Length) entries:");
+      // why it doesn't guess about type?
+      entries.Iter(location : Location => Debug.WriteLine(location));
+      entries
+    }
+
     Init(line : int, col : int) : void
     {
 #if PRINT_AST

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	Wed Nov 15 15:47:46 2006
@@ -252,64 +252,6 @@
     }
 
     // TODO: implement get usages behaviour, this is a stub yet
-    private FindUsages(
-      typeDecl  : Decl.Type,
-      fileIndex : int,
-      line      : int,
-      col       : int
-    )
-      : list [GotoInfo]
-    {
-      def (_, _, declarationObject) = FindObject(typeDecl, fileIndex, line, col);
-
-      // TODO: use lexer output for quick search, cache it if it is not cached yet
-      //VladD2:  ëåñ lexer. Ïîèñê ïî èñõîäíèêàì áîëåå ÷åì äîñòàòî÷åí äëÿ
-      // òîãî ÷òîáû íàéòè íóæíûå ìåòîäû.
-      def findPossibleUsages(name)
-      {
-        def entries = SCG.List();
-        def projSources = _engine.ProjectSources;
-
-        foreach (fileIndex in _engine.Sources.GetFileIndices())
-        {
-          def source = projSources.GetSource(fileIndex); // get ISource
-          def code = source.GetText(); // get code as text
-          def findEntry(startPos)
-          {
-            def pos = code.OrdinalIndexOf(name, startPos);
-            when (pos >= 0) // we found entry...
-            {
-              def (line, ch) = source.GetLineIndexOfPosition(pos);
-              def loc = Location(fileIndex, line, ch, line, ch + name.Length);
-              entries.Add(loc);
-              Debug.WriteLine($"\t$(loc.File)($(loc.Line),$(loc.Column)): ...");
-              findEntry(pos + name.Length); // try again...
-            }
-          }
-
-          Debug.WriteLine($"Try finde name '$name'");
-
-          findEntry(0); // find from start of file
-
-          Debug.WriteLine($"End: Try finde name '$name'");
-        }
-
-        entries
-      }
-
-      // TODO: check the symbol found
-      def isRealUsages(_)
-      {
-        true
-      }
-
-      // TODO: implement other type usages finding, not only variables
-      match (declarationObject)
-      {
-        | localValue is LocalValue => // try find only on method body!
-          [GotoInfo(localValue)] //TODO: find entry of local value
-
-        | member is IMember => 
           // Ïðèìåðíîå îïèñàíèå àëãîðèòìà ïîèñêà ÷ëåíà êëàññà:
           // 1. Íàõîäèì âñå ññûëêè íà äàííûé ÷ëåí â äåðåâå òèïîâ.
           //    Ýòî ìîæíî ñäåëàòü ïðîñêàíèðîâàâ TypeBuilder-û.
@@ -340,12 +282,68 @@
           //    (It may be done by GetAllMetodsDefinedInFile(fileIndex : int) : SCG.List[MethodBuilder])
           //    If lacations from step 2 intersect with method try find entries
           //    in it method.
+    private FindUsages(type' : Decl.Type, fileIndex : int, line : int, column : int) : list [GotoInfo]
+    {
+      def (_, _, declarationObject) = FindObject(type', fileIndex, line, column);
 
-          // Èç âûøå ñêàçàííîãî ÿñíî, ÷òî äàííûé êîä íå âåðíûé, òàê íî ïîêà õîòü òàê...
-          $[GotoInfo(x) | x in findPossibleUsages(member.Name), isRealUsages(x)]
+      // TODO: for rename refactoring, we should know all usages, including generated
+      // However, this implementation neglects generated usages
+      def findPossibleUsages(name)
+      {
+        mutable entries = [];
+        def sources = _engine.ProjectSources;
 
+        foreach (fileIndex in _engine.Sources.GetFileIndices())
+        {
+          def source = sources.GetSource(fileIndex);
+          def code = source.GetText();
+          def findEntry(startPos)
+          {
+            def position = code.OrdinalIndexOf(name, startPos);
+            unless (position < 0)
+            {
+              def (line, column) = source.GetLineIndexOfPosition(position);
+              def location = Location(fileIndex, line, column, line, column + name.Length);
+              entries ::= location;
+              findEntry(position + name.Length);
+            }
+          }
+          findEntry(0);
+        }
+
+        entries
+      }
+
+      def findInMethod(localValueDeclaration)
+      {
+        def member = type'.Builder.GetActiveMember(fileIndex, line, column);
+        Debug.WriteLine($"searching for $localValueDeclaration");
+        Debug.WriteLine($"enclosing member:\n $member");
+        match (member)
+        {
+          | method is MethodBuilder =>
+            Debug.WriteLine("parsed tree:");
+            Debug.WriteLine(PrettyPrint.SprintExpr(None(), method.BodyParsed));
+            Debug.WriteLine("typed tree:");
+            Debug.WriteLine(PrettyPrint.SprintTyExpr(method.BodyTyped));
+            ExprFinder().FindLocalValueEntries(method.BodyTyped, localValueDeclaration);
+          | _ => []
+        }
+      }
+
+      def isRealUsage(_)
+      {
+        true
+      }
+
+      def locations = match (declarationObject)
+      {
+        | localValue is LocalValue => findInMethod(localValue)
+        | member is IMember => 
+          $[x | x in findPossibleUsages(member.Name), isRealUsage(x)]
         | _ => [] //TODO: May be it wrong!
       }
+      locations.Map(GotoInfo(_))
     }
 
     GetMethodTip(

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Utils.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Utils.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Utils.n	Wed Nov 15 15:47:46 2006
@@ -18,6 +18,32 @@
     InvariantCultureCompareInfo : CompareInfo 
       = CultureInfo.InvariantCulture.CompareInfo;
 
+    // Returns (non-strictly) whether the first location is before the second
+    public NotStrictlyBefore(this firstLocation : Location, secondLocation: Location) : bool
+    {
+      if (firstLocation.Line < secondLocation.Line)
+        true
+      else if (firstLocation.Line > secondLocation.Line)
+        false
+      else if (firstLocation.Column < secondLocation.Column)
+        true
+      else if (firstLocation.Column > secondLocation.Column)
+        false
+      else
+        true
+    }
+
+    // For debug purposes, brief output
+    public Brief(this output : string, maximalLength : int = 100) : string
+    {
+      def ellipsis = "...";
+      def s = output.Replace('\n', ' ');
+      if (s.Length > maximalLength)
+        s.Substring(0, maximalLength - ellipsis.Length) + ellipsis;
+      else
+        s
+    }
+    
     /// Fast find index of substing.
     public OrdinalIndexOf(this source : string, value : string, startIndex : int) : int
     {



More information about the svn mailing list