[svn] r6139: nemerle/trunk/ncc: completion/CodeCompletionEngine.n completion/CompletionEngineTree.n testsu...

trupill svnadmin at nemerle.org
Sun Feb 26 21:09:46 CET 2006


Log:
Changing the Code Completion Engine again. Added some tests under 
ncc/testsuite/completion-playground. Now, instead of a line number, we 
use the returned tree from GetTypeTree() to get the method. Also, Engine 
is made a module.


Author: trupill
Date: Sun Feb 26 21:09:41 2006
New Revision: 6139

Added:
   nemerle/trunk/ncc/testsuite/completion-playground/compl-s2.n
   nemerle/trunk/ncc/testsuite/completion-playground/compl2.n
Modified:
   nemerle/trunk/ncc/completion/CodeCompletionEngine.n
   nemerle/trunk/ncc/completion/CompletionEngineTree.n
   nemerle/trunk/ncc/typing/Typer.n

Modified: nemerle/trunk/ncc/completion/CodeCompletionEngine.n
==============================================================================
--- nemerle/trunk/ncc/completion/CodeCompletionEngine.n	(original)
+++ nemerle/trunk/ncc/completion/CodeCompletionEngine.n	Sun Feb 26 21:09:41 2006
@@ -64,25 +64,23 @@
     
     public class DefineCollection : System.Collections.Generic.IEnumerable [string]
     {
-        internal this (parent : Engine)
+        internal this ()
         {
-            parentEngine = parent;
             defines = [];
         }
         
-        internal parentEngine : Engine;
         internal mutable defines : list[string];
         
         public Add (Define : string) : void
         {
             defines ::= Define;
-            parentEngine.set_unparsed_state ();
+            Engine.set_unparsed_state ();
         }
         
         public Remove (Define : string) : void
         {
             _ = defines.Remove (Define);
-            parentEngine.set_unparsed_state ();
+            Engine.set_unparsed_state ();
         }
         
         public Contains (Define : string) : bool
@@ -90,6 +88,12 @@
             defines.Contains (Define)
         }
         
+        public Clear () : void
+        {
+            defines = [];
+            Engine.set_unparsed_state();
+        }
+        
         public GetEnumerator () : Nemerle.Collections.IEnumerator[string]
         {
             Nemerle.Collections.ListEnumerator (defines)
@@ -98,31 +102,35 @@
     
     public class ReferenceCollection
     {
-        internal this (parent : Engine)
+        internal this ()
         {
-            parentEngine = parent;
             references = Hashtable ();
         }
         
-        internal parentEngine : Engine;
         internal mutable references : Hashtable[string, InternalReference];
         
         public Add (Key : string, Path : string) : void
         {
             references.Add (Key, InternalReference.Library (Path));
-            parentEngine.set_unparsed_state ();
+            Engine.set_unparsed_state ();
         }
         
         public Add (Key : string, LoadedAssembly : System.Reflection.Assembly) : void
         {
             references.Add (Key, InternalReference.Assembly (LoadedAssembly));
-            parentEngine.set_unparsed_state ();
+            Engine.set_unparsed_state ();
         }
         
         public Remove (Key : string) : void
         {
             references.Remove (Key);
         }
+        
+        public Clear () : void
+        {
+            references = Hashtable ();
+            Engine.set_unparsed_state();
+        }
     }
     
     internal variant ParsedFile
@@ -133,13 +141,11 @@
     
     public class SourceCollection
     {
-        internal this (parent : Engine)
+        internal this ()
         {
-            parentEngine = parent;
             sources = Hashtable ();
         }
         
-        internal parentEngine : Engine;
         internal mutable sources : Hashtable[string, ParsedFile];
 
         public Add (File : string, Contents : string) : void
@@ -147,42 +153,43 @@
             sources.Add (File, ParsedFile.NotParsed (Contents));
         }
         
-        public AddToComplete (File : string, Contents : string, Offset : int) : void
-        {
-            def contents = Contents.Insert(Offset, Engine.MagicWord);
-            Add (File, contents);
-        }
-        
         public Remove (File : string) : void
         {
             sources.Remove (File);
             set_unparsed_state ();
         }
         
-        internal set_unparsed_state () : void
+        public Clear () : void
         {
-            foreach (file in sources)
-            {
-                match (file.Value)
+            sources = Hashtable ();
+            set_unparsed_state();
+        }       
+        
+        internal set_unparsed_state () : void
                 {
-                | Parsed as p => sources[file.Key] = ParsedFile.NotParsed (p.code);
+            mutable fileList : list[string * string] = [];
+            foreach (file in sources) {
+                match (file.Value) {
+                | Parsed as p => fileList ::= (file.Key, p.code);
                 | _ => ();
                 }
             }
+            foreach (item in fileList) {
+                sources [item [0]] = ParsedFile.NotParsed (item [1]);
+            }
         }
     }
     
-    public class Engine
+    public module Engine
     {
-        public mutable static IsInCompletionMode : bool;
-        public static MagicWord = "CodeCompletionEnginePlaceholder";
+        public mutable IsInCompletionMode : bool;
         internal mutable textWriter : System.IO.TextWriter;
         
         public mutable Defines : DefineCollection;
         public mutable References : ReferenceCollection;
         public Sources : SourceCollection;
         
-        static syncObject : object;
+        syncObject : object;
 
         internal set_unparsed_state () : void
         {
@@ -193,13 +200,9 @@
         {
             IsInCompletionMode = false;
             syncObject = object();
-        }
-        
-        public this()
-        {
-            Defines = DefineCollection (this);
-            References = ReferenceCollection (this);
-            Sources = SourceCollection (this);
+            Defines = DefineCollection ();
+            References = ReferenceCollection ();
+            Sources = SourceCollection ();
             Passes.ParsingPipeline = MainParser.Parse;
             Passes.ScanningPipeline = ScanTypeHierarchy.ProcessDeclaration;
             textWriter = null;
@@ -218,6 +221,7 @@
             MacroRegistry.Init ();
             LibraryReferenceManager.Init ();     
             NamespaceTree.Init ();
+            NamespaceTree.namespace_tree.Clear ();
             Util.Init ();
             AttributeCompiler.Init ();
             PreParser.Init ();
@@ -234,13 +238,14 @@
             InternalType.InitSystemTypes ();
             InternalType.InitNemerleTypes ();
             LibraryReferenceManager.LoadMacrosFrom ("Nemerle.Macros");
+            Sources.set_unparsed_state ();
             
             GlobalEnv.Init();
             
             listMessages = [];
         }
         
-        public static LesserInit() : void
+        public LesserInit() : void
         {
             LibraryReferenceManager.Init ();     
             NamespaceTree.Init ();
@@ -249,14 +254,6 @@
             PreParser.Init ();
             Passes.Solver = Solver ();
       
-            /*LibraryReferenceManager.AddLibrary("mscorlib");
-            LibraryReferenceManager.AddLibrary ("System");
-            LibraryReferenceManager.AddLibrary ("Nemerle");
-            SystemType.Init ();                 
-            InternalType.InitSystemTypes ();
-            InternalType.InitNemerleTypes ();
-            LibraryReferenceManager.LoadMacrosFrom ("Nemerle.Macros");*/
-            
             GlobalEnv.Init();
         }
         
@@ -278,182 +275,51 @@
             }
         }
         
-        public RunCompletionEngine () : CompletionInfo
+        public RunCompletionEngine (memberInfo : NemerleMemberInfo, contents : string) : CompletionInfo
         {
             lock (syncObject)
             {
                 // Tell the methods we are in completion mode
                 IsInCompletionMode = true;
+                def theMember = memberInfo._member;
+                def observed_method = theMember :> MethodBuilder;
                 
-                Init ();
-                
-                foreach (define in Defines.defines)
-                    Options.DefineConstant (define);
-                
-                foreach (references in References.references.Values)
-                {
-                | Library as l => LibraryReferenceManager.AddLibrary (l.path);
-                | Assembly as a => LibraryReferenceManager.AddAssembly (a.assembly);
-                }
-    
-                mutable trees = [];
-                
-                mutable fileToComplete = "";
-                mutable (offsetToComplete, lineToComplete, columnToComplete) = (0, 0, 0);
-                
-                def get_line_and_col_from_offset (contents : string, offset : int)
-                {
-                    def new_contents = contents.Substring (0, offset);
-                    mutable (column, line) = (1, 1);
-                    foreach (character in new_contents)
-                    {
-                        if (character == '\n')
-                        {
-                            line++;
-                            column = 1;
-                        }
-                        else
-                        {
-                            column++;
-                        }
-                    }
-                    lineToComplete = line;
-                    columnToComplete = column;
-                }
-                
-                try
-                {
-                    def filenames = Sources.sources.Fold ([], fun (k, _, acc) { k :: acc });
-                    
-                    foreach (filename in filenames)
-                    {
-                        match (Sources.sources [filename])
-                        {
-                        | NotParsed as np =>
-                            mutable contents = np.code;
-                            def completionIndex = contents.IndexOf (MagicWord);
-                            when (completionIndex > -1)
-                            {
-                                fileToComplete = filename;
-                                offsetToComplete = completionIndex;
-                                contents = contents.Replace (MagicWord, "");
-                                get_line_and_col_from_offset (contents, completionIndex);
-                            }
-                            def lexer = LexerString (contents, Location (Location.GetFileIndex (filename), 1, 1));
-                            def decls = Passes.ParsingPipeline (lexer);
-                            Sources.sources[filename] = ParsedFile.Parsed (decls, contents);
-                            trees ::= decls;
-                        | Parsed as p => trees ::= p.decls;
-                        }
-                    }
-                }
-                catch
-                {
-                    | _ => ();
-                }
-    
-                Passes.Hierarchy = TypesManager ();
-                
-                // create N.C.TypeBuilders for all parsed types and add them to namespace hierarchy
-                try
-                {
-                    foreach (group in trees) {
-                        List.Iter (group, Passes.ScanningPipeline);
-                    }
-                }
-                catch
-                {
-                    | _ => ();
-                }
-                
-                try
-                {
-                    Passes.Hierarchy.Run ();
-                }
-                catch
-                {
-                    | _ => ();
-                }
-                
-                def find_line_col (file_contents : string, line, col) {
-                    def loop (cur_line = 1, i = 0) {
-                        if (i >= file_contents.Length)
-                        -1
-                        else if (cur_line == line)
-                        i + col - 1
-                        else if (file_contents [i] == '\n')
-                        loop (cur_line + 1, i + 1)
-                        else 
-                        loop (cur_line, i + 1)
-                    }
-                loop ()
-                }
-        
-                def check_if_method_is (method)
-                {
-                    if (method.Location.File != fileToComplete)
-                        false
-                    else
-                    {
-                        if ( (method.BodyLocation.Line < lineToComplete ||
-                                 (method.BodyLocation.Line == lineToComplete && 
-                                  method.BodyLocation.Column < columnToComplete)) &&
-                             (method.BodyLocation.EndLine > lineToComplete ||
-                                 (method.BodyLocation.EndLine == lineToComplete &&
-                                  method.BodyLocation.Column > columnToComplete)))
-                            true
-                        else
-                            false
-                    }
-                }
-    
-                mutable observed_method = null;
-                // get the method
-                Passes.Hierarchy.infos.Iter (fun (ti) {
-                    foreach (member in ti.GetDirectMembers ())
-                    {
+                // As a NemerleMemberInfo is provided, we don't need to
+                // search every type for the member
+                /*Passes.Hierarchy.infos.Iter (fun (ti) {
+                    when (ti.Name == typeName && ti.NamespaceNode.Parent.Name.ToString(".") == namespaceName) {
+                        foreach (member in ti.GetDirectMembers ()) {
                     | meth is MethodBuilder => 
-                        when (check_if_method_is (meth))
+                            when (meth.Name == methodName)
                             observed_method = meth;
                     | prop is PropertyBuilder =>
                         def getter = prop.GetGetter() :> MethodBuilder;
                         def setter = prop.GetSetter() :> MethodBuilder;
-                        when (getter != null && check_if_method_is (getter))
+                            when (getter != null && methodName == ("get_" + prop.Name))
                             observed_method = getter;
-                        when (setter != null && check_if_method_is (setter))
+                            when (setter != null && methodName == ("set_" + prop.Name))
                             observed_method = setter;
                     | ev is EventBuilder =>
                         def adder = ev.GetAdder();
                         def remover = ev.GetRemover();
-                        when (adder != null && check_if_method_is (adder))
+                            when (adder != null && methodName == ("add_" + ev.Name))
                             observed_method = adder;
-                        when (remover != null && check_if_method_is (remover))
+                            when (remover != null && methodName == ("remove_" + ev.Name))
                             observed_method = remover;
                     | _ => ();
                     }
-                } );
-                
-                def env = observed_method.DeclaringType.GlobalEnv;
-                mutable real_contents = "";
-                match (Sources.sources [fileToComplete])
-                {
-                | NotParsed as np => real_contents = np.code;
-                | Parsed as p => real_contents = p.code;
                 }
-                def body_start = find_line_col (real_contents, 
-                    observed_method.BodyLocation.Line, observed_method.BodyLocation.Column);
-                def bracket_location = real_contents.IndexOf ("{", body_start);
-                mutable my_body = real_contents.Substring (
-                    bracket_location + 1, offsetToComplete - body_start - 1);
+                } );*/
                 
-                my_body = my_body.Trim();
+                mutable completionList  = null;
+                when (observed_method != null) {
+                    def env = observed_method.DeclaringType.GlobalEnv;
+                    def my_body = contents.Trim();
     
                 def lexer = LexerCompletion (my_body + " ", my_body.Length);
-                // def lexer = LexerCompletion (element + " ", element.Length);
                 observed_method.GetHeader ().body =
                     FunBody.Parsed (MainParser.ParseExpr (env, lexer));
                 
-                mutable completionList  = null;
                 try
                 {
                     observed_method.RunBodyTyper ();
@@ -463,7 +329,7 @@
                 | e is CompletionResult => completionList = translate_ovpossibility_to_info (e.Overloads);
                 | _ => ();
                 }
-                
+                }
                 IsInCompletionMode = false;
                 completionList
             }
@@ -497,7 +363,7 @@
         
         # region Code completion
         
-        public static translate_ovpossibility_to_info (ovpos : list[OverloadPossibility]) : CompletionInfo
+        public translate_ovpossibility_to_info (ovpos : list[OverloadPossibility]) : CompletionInfo
         {
             mutable info : CompletionInfo = null;
             if (ovpos.Length == 0)
@@ -506,13 +372,9 @@
             {
                 mutable complete_types = false;
                 def first = ovpos.Head;
-                when (first is IMethod)
-                {
-                    when ((first :> IMethod).GetFunKind() is FunKind.Constructor)
-                    {
+                when (first.Member.Name == ".ctor" || first.Member.Name == ".cctor")
                         complete_types = true;
-                    }
-                }
+
                 if (complete_types)
                 {
                 }
@@ -537,7 +399,7 @@
             info
         }
         
-        static complete_common_member_props (member : IMember, info : NemerleMemberInfo) : void
+        complete_common_member_props (member : IMember, info : NemerleMemberInfo) : void
         {
             info.Name = member.Name;
             
@@ -549,7 +411,7 @@
         }
 
         
-        static complete_field (field : IField) : FieldInfo
+        complete_field (field : IField) : FieldInfo
         {
             mutable returnField = FieldInfo();
             complete_common_member_props(field, returnField);
@@ -587,7 +449,7 @@
             returnField
         }
 
-        static complete_method (method : IMethod) : MethodInfo
+        complete_method (method : IMethod) : MethodInfo
         {
             mutable returnMethod = MethodInfo();
             complete_common_member_props(method, returnMethod);
@@ -623,7 +485,7 @@
             returnMethod
         }
         
-        static complete_property (property : IProperty) : PropertyInfo
+        complete_property (property : IProperty) : PropertyInfo
         {
             mutable returnProperty = PropertyInfo();
             complete_common_member_props (property, returnProperty);
@@ -656,7 +518,7 @@
             returnProperty
         }
 
-        static complete_event (ev : IEvent) : EventInfo
+        complete_event (ev : IEvent) : EventInfo
         {
             mutable returnEvent = EventInfo();
             complete_common_member_props (ev, returnEvent);
@@ -679,7 +541,7 @@
             returnEvent
         }
         
-        static complete_type (t : TypeInfo) : NemerleTypeInfo
+        complete_type (t : TypeInfo) : NemerleTypeInfo
         {
         | x is TypeBuilder => get_type (x)
         | _ => ReferencedTypeInfo (t.SystemType)
@@ -693,14 +555,14 @@
             have the most information we could take, but if there's
             some error in the code, the engine must continue */
         mutable listTypes : list[DeclaredTypeInfo];
-        static mutable uniqueTypesTable : Hashtable[string, DeclaredTypeInfo];
+        mutable uniqueTypesTable : Hashtable[string, DeclaredTypeInfo];
+        mutable tree : TypeTree;
         
         public GetTypeTree () : TypeTree
         {
             lock (syncObject)
             {
-                mutable tree = TypeTree ();
-            
+                tree = TypeTree ();
                 Init ();
             
                 foreach (define in Defines.defines)
@@ -712,6 +574,7 @@
                 | Assembly as a => LibraryReferenceManager.AddAssembly (a.assembly);
                 }
     
+                System.Console.WriteLine ("just before lexing");
                 mutable trees = [];
                 try
                 {
@@ -740,9 +603,11 @@
                       {}
                 }
                 
+                System.Console.WriteLine ("just before TypesManager");
                 Passes.Hierarchy = TypesManager ();
     
                 // create N.C.TypeBuilders for all parsed types and add them to namespace hierarchy
+                System.Console.WriteLine ("just before parsing");
                 try
                 {
                     foreach (group in trees) {
@@ -758,6 +623,7 @@
                       {}
                 }
                 
+                System.Console.WriteLine ("just before building the hierarchy");
                 try
                 {
                     Passes.Hierarchy.Run();
@@ -799,7 +665,7 @@
              }
          }
          
-         static get_type (t : TypeBuilder) : DeclaredTypeInfo
+         get_type (t : TypeBuilder) : DeclaredTypeInfo
          {
              mutable uniqueName = t.FrameworkTypeName;
              
@@ -895,7 +761,7 @@
              }
          }
          
-         static get_type_info (x : TypeInfo) : NemerleTypeInfo
+         get_type_info (x : TypeInfo) : NemerleTypeInfo
          {
              if (x == null)
                  null
@@ -907,7 +773,7 @@
              }
          }
          
-         static fill_common_member_props (member : MemberBuilder, info : NemerleMemberInfo) : void
+         fill_common_member_props (member : MemberBuilder, info : NemerleMemberInfo) : void
          {
              info.Name = member.Name;
              info.Location = CodeLocation(member.Location.File, member.Location.Line, 
@@ -921,7 +787,7 @@
              info._member = member;
          }
          
-         static construct_type (t : MType) : ConstructedTypeInfo
+         construct_type (t : MType) : ConstructedTypeInfo
          {
             | Class as c =>
                  def returnClass = ConstructedTypeInfo.Class();
@@ -968,7 +834,7 @@
                          // so they should never appear here
          }
          
-         static get_field (field : FieldBuilder) : FieldInfo
+         get_field (field : FieldBuilder) : FieldInfo
          {
              mutable returnField = FieldInfo();
              fill_common_member_props(field, returnField);
@@ -1001,7 +867,7 @@
              returnField
          }
          
-         static get_method (method : MethodBuilder) : MethodInfo
+         get_method (method : MethodBuilder) : MethodInfo
          {
              mutable returnMethod = MethodInfo();
              fill_common_member_props(method, returnMethod);
@@ -1038,7 +904,7 @@
              returnMethod
          }
          
-         static get_parm (parm : Typed.Fun_parm) : ParameterInfo
+         get_parm (parm : Typed.Fun_parm) : ParameterInfo
          {
              mutable returnParam = ParameterInfo();
              returnParam.Name = parm.name;
@@ -1076,7 +942,7 @@
              returnParam
          }
          
-         static get_typarm (typarm : StaticTyVar) : TypeParameterInfo
+         get_typarm (typarm : StaticTyVar) : TypeParameterInfo
          {
              mutable returnTyparm = TypeParameterInfo();
              returnTyparm.Name = typarm.Name;
@@ -1087,7 +953,7 @@
              returnTyparm
          }
          
-         static get_property (property : PropertyBuilder) : PropertyInfo
+         get_property (property : PropertyBuilder) : PropertyInfo
          {
              mutable returnProperty = PropertyInfo();
              fill_common_member_props (property, returnProperty);
@@ -1119,7 +985,7 @@
              returnProperty
          }
          
-         static get_event (ev : EventBuilder) : EventInfo
+         get_event (ev : EventBuilder) : EventInfo
          {
              mutable returnEvent = EventInfo();
              fill_common_member_props (ev, returnEvent);

Modified: nemerle/trunk/ncc/completion/CompletionEngineTree.n
==============================================================================
--- nemerle/trunk/ncc/completion/CompletionEngineTree.n	(original)
+++ nemerle/trunk/ncc/completion/CompletionEngineTree.n	Sun Feb 26 21:09:41 2006
@@ -262,6 +262,7 @@
         public mutable Location : CodeLocation;
 
         // tmp hack
+        // please do not remove
         public mutable _member : IMember;
         
         public mutable IsStatic : bool;

Added: nemerle/trunk/ncc/testsuite/completion-playground/compl-s2.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/completion-playground/compl-s2.n	Sun Feb 26 21:09:41 2006
@@ -0,0 +1,22 @@
+using System.Collections.Generic;
+
+// foo
+#define foobar
+
+namespace Example {
+  public class SomeClass {
+    public Foo () : void
+    {
+    }
+    public Foo2 () : void
+    {
+    }
+    public Bar () : void
+    {
+      this.Foo ();
+    }
+  }
+} 
+
+public class SomeOtherClass {
+}

Added: nemerle/trunk/ncc/testsuite/completion-playground/compl2.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/completion-playground/compl2.n	Sun Feb 26 21:09:41 2006
@@ -0,0 +1,60 @@
+using Nemerle.Compiler;
+using Nemerle.Completion;
+using Nemerle.Collections;
+using System.IO;
+using System.Console;
+
+def files = Hashtable ();
+def rawArgs = List.FromArray (System.Environment.GetCommandLineArgs ());
+def (progName, args) = rawArgs.Head::rawArgs.Tail;
+when (args.Length == 0) {
+	WriteLine($"usage: $progName <filename>\n"+
+		       "       <filename> is the Nemerle source code you want "+
+	           "to pass to the \n"+
+	           "       code completion engine");
+	System.Environment.Exit(1);
+}
+foreach (arg in args) {
+  using (sr = StreamReader (arg)) {
+    def str = sr.ReadToEnd ();
+    Engine.Sources.Add (arg, str);
+    files [arg] = str;
+  }
+}
+
+def type_tree = Engine.GetTypeTree ();
+def _second_tree = Engine.GetTypeTree ();
+mutable the_method = null;
+
+System.Console.WriteLine ("FOUND TYPES\n===========");
+foreach (t in type_tree.Types) {
+  System.Console.WriteLine (t.Name);
+  foreach (method in t.Methods) {
+    System.Console.WriteLine ("* " + method.Name);
+    when (method.Name == "Bar")
+      the_method = method;
+  }
+}
+
+def try_completion (body) {
+  System.Console.WriteLine ("\nTrying to complete:");
+  System.Console.WriteLine (body);
+  def info = Engine.RunCompletionEngine (the_method, body);
+  if (info == null) {
+    System.Console.WriteLine ("NO MEMBER FOUND");
+  }
+  else {
+    when (info.CompletionKind == CompletionKind.Members) {
+      System.Console.WriteLine ("FOUND MEMBERS\n=============");
+      def members = info :> CompletionMembers;
+      foreach (member in members.Members)
+        System.Console.WriteLine (member.Name);
+    }
+  }
+  System.Console.WriteLine ("Finished");
+}
+
+try_completion ("def a = \"a\"; a.");
+try_completion ("string.For");
+try_completion ("this.Fo");
+try_completion ("Q");

Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n	(original)
+++ nemerle/trunk/ncc/typing/Typer.n	Sun Feb 26 21:09:41 2006
@@ -2205,8 +2205,7 @@
     {
       match (TypeMember (obj, mem_name, expected)) {
         | Some ([]) =>
-            if (Completion.Engine.IsInCompletionMode && 
-                mem_name.IndexOf(Completion.Engine.MagicWord) != -1) {
+            if (Completion.Engine.IsInCompletionMode) {
               TExpr.Error()
             }
             else



More information about the svn mailing list