[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