diff options
author | Levi Bard <levibard@mono-cvs.ximian.com> | 2010-02-18 20:31:18 +0300 |
---|---|---|
committer | Levi Bard <levibard@mono-cvs.ximian.com> | 2010-02-18 20:31:18 +0300 |
commit | dbddfdc99bf69c653aeacb5c0a43d8ce8054ac0a (patch) | |
tree | f2490fa3a418bb3d9b7d7e4161922f2e8b60b559 /extras/ValaBinding | |
parent | c2fefb3b55371e78774a402163c08b2de05316ed (diff) |
* Makefile.am: * Parser/Afrodite.cs: * ValaBinding.csproj: * Parser/Function.cs: * Parser/CodeNode.cs: * Gui/DataProvider.cs: * Parser/ValaDocumentParser.cs: * Parser/ProjectInformation.cs: * Gui/ValaTextEditorExtension.cs: * Navigation/LanguageItemEventArgs.cs: * Navigation/LanguageItemNodeBuilder.cs: * Navigation/LanguageItemCommandHandler.cs: * Navigation/ProjectNodeBuilderExtension.cs: Rework code completion based on libafrodite.
svn path=/trunk/monodevelop/; revision=152006
Diffstat (limited to 'extras/ValaBinding')
-rw-r--r-- | extras/ValaBinding/ChangeLog | 16 | ||||
-rw-r--r-- | extras/ValaBinding/Gui/DataProvider.cs | 175 | ||||
-rw-r--r-- | extras/ValaBinding/Gui/ValaTextEditorExtension.cs | 70 | ||||
-rw-r--r-- | extras/ValaBinding/Makefile.am | 3 | ||||
-rw-r--r-- | extras/ValaBinding/Navigation/LanguageItemCommandHandler.cs | 14 | ||||
-rw-r--r-- | extras/ValaBinding/Navigation/LanguageItemEventArgs.cs | 7 | ||||
-rw-r--r-- | extras/ValaBinding/Navigation/LanguageItemNodeBuilder.cs | 51 | ||||
-rw-r--r-- | extras/ValaBinding/Navigation/ProjectNodeBuilderExtension.cs | 36 | ||||
-rw-r--r-- | extras/ValaBinding/Parser/Afrodite.cs | 1163 | ||||
-rw-r--r-- | extras/ValaBinding/Parser/CodeNode.cs | 156 | ||||
-rw-r--r-- | extras/ValaBinding/Parser/Function.cs | 77 | ||||
-rw-r--r-- | extras/ValaBinding/Parser/ProjectInformation.cs | 614 | ||||
-rw-r--r-- | extras/ValaBinding/Parser/ValaDocumentParser.cs | 52 | ||||
-rw-r--r-- | extras/ValaBinding/ValaBinding.csproj | 5 |
14 files changed, 1578 insertions, 861 deletions
diff --git a/extras/ValaBinding/ChangeLog b/extras/ValaBinding/ChangeLog index 9503de93e0..fe26e56f8c 100644 --- a/extras/ValaBinding/ChangeLog +++ b/extras/ValaBinding/ChangeLog @@ -1,3 +1,19 @@ +2010-02-18 Levi Bard <levi.bard@emhartglass.com> + + * Makefile.am: + * Parser/Afrodite.cs: + * ValaBinding.csproj: + * Parser/Function.cs: + * Parser/CodeNode.cs: + * Gui/DataProvider.cs: + * Parser/ValaDocumentParser.cs: + * Parser/ProjectInformation.cs: + * Gui/ValaTextEditorExtension.cs: + * Navigation/LanguageItemEventArgs.cs: + * Navigation/LanguageItemNodeBuilder.cs: + * Navigation/LanguageItemCommandHandler.cs: + * Navigation/ProjectNodeBuilderExtension.cs: + 2010-02-18 Lluis Sanchez Gual <lluis@novell.com> * Gui/DataProvider.cs: Track api changes. diff --git a/extras/ValaBinding/Gui/DataProvider.cs b/extras/ValaBinding/Gui/DataProvider.cs index b5f5f8ddbf..23685eb356 100644 --- a/extras/ValaBinding/Gui/DataProvider.cs +++ b/extras/ValaBinding/Gui/DataProvider.cs @@ -42,13 +42,14 @@ using MonoDevelop.Ide.Gui; using MonoDevelop.Projects.Gui.Completion; using MonoDevelop.ValaBinding.Parser; +using MonoDevelop.ValaBinding.Parser.Afrodite; namespace MonoDevelop.ValaBinding { public class ParameterDataProvider : IParameterDataProvider { private TextEditor editor; - private IList<Function> functions; + private IList<Symbol> functions; private string functionName; private string returnType; private ProjectInformation info; @@ -60,51 +61,28 @@ namespace MonoDevelop.ValaBinding this.functionName = functionName; this.info = info; - int lastDot = functionName.LastIndexOf (".", StringComparison.OrdinalIgnoreCase); - string instancename = (0 <= lastDot)? functionName.Substring (0, lastDot): "this"; - - Match match = identifierRegex.Match (instancename); - if (match.Success && match.Groups["identifier"].Success) { - instancename = match.Groups["identifier"].Value; - } - - string typename = null; - - ThreadPool.QueueUserWorkItem (delegate(object o) { - typename = info.GetExpressionType (instancename, document.FileName, editor.CursorLine, editor.CursorColumn); // bottleneck - info.Complete(typename, document.FileName, editor.CursorLine, editor.CursorColumn, null); - }); - string functionBaseName = (0 <= lastDot)? functionName.Substring (lastDot+1): functionName; - - match = identifierRegex.Match (functionBaseName); - if (match.Success && match.Groups["identifier"].Success) { - functionBaseName = match.Groups["identifier"].Value; - } - IList<Function> myfunctions = info.GetOverloads (functionBaseName); // bottleneck - - if (null != typename) { - foreach (Function function in myfunctions) { - if (string.Format("{0}.{1}", typename, functionBaseName).Equals (function.FullName, StringComparison.Ordinal)) { - functions = new List<Function>(new Function[]{function}); - break; - } - } - } - - if (null == functions){ functions = myfunctions; } + functions = new List<Symbol> (); + Symbol function = info.GetFunction (functionName, document.FileName, editor.CursorLine, editor.CursorColumn); + if (null != function){ functions.Add (function); } }// member function constructor + /// <summary> + /// Create a ParameterDataProvider for a constructor + /// </summary> + /// <param name="constructorOverload"> + /// A <see cref="System.String"/>: The named of the pertinent constructor overload + /// </param> public ParameterDataProvider (Document document, ProjectInformation info, string typename, string constructorOverload) { this.functionName = constructorOverload; this.editor = document.TextEditor; this.info = info; - List<Function> myfunctions = info.GetConstructorsForType (typename, document.FileName, editor.CursorLine, editor.CursorColumn, null); // bottleneck - if (0 < myfunctions.Count) { - foreach (Function function in myfunctions) { + List<Symbol> myfunctions = info.GetConstructorsForType (typename, document.FileName, editor.CursorLine, editor.CursorColumn, null); // bottleneck + if (1 < myfunctions.Count) { + foreach (Symbol function in myfunctions) { if (functionName.Equals (function.Name, StringComparison.Ordinal)) { - functions = new List<Function>(new Function[]{function}); + functions = new List<Symbol> () {function}; return; } } @@ -113,23 +91,29 @@ namespace MonoDevelop.ValaBinding functions = myfunctions; }// constructor constructor - // Returns the number of methods + /// <summary> + /// The number of overloads for this method + /// </summary> public int OverloadCount { get { return functions.Count; } } - // Returns the index of the parameter where the cursor is currently positioned. - // -1 means the cursor is outside the method parameter list - // 0 means no parameter entered - // > 0 is the index of the parameter (1-based) + /// <summary> + /// Get the index of the parameter where the cursor is currently positioned. + /// </summary> + /// <param name="ctx"> + /// A <see cref="CodeCompletionContext"/> + /// </param> + /// <returns> + /// A <see cref="System.Int32"/>: The index of the parameter, + /// 0 for no parameter entered, + /// -1 for outside the list + /// </returns> public int GetCurrentParameterIndex (CodeCompletionContext ctx) { int cursor = editor.CursorPosition; int i = ctx.TriggerOffset; -// if (editor.GetCharAt (i) == ')') -// return -1; - if (i > cursor) return -1; else if (i == cursor) @@ -148,59 +132,79 @@ namespace MonoDevelop.ValaBinding return parameterIndex; } - // Returns the markup to use to represent the specified method overload - // in the parameter information window. + /// <summary> + /// Get the markup to use to represent the specified method overload + /// in the parameter information window. + /// </summary> public string GetMethodMarkup (int overload, string[] parameterMarkup, int currentParameter) { string paramTxt = string.Join (", ", parameterMarkup); - Function function = functions[overload]; + Symbol function = functions[overload]; - int len = function.FullName.LastIndexOf ("."); + int len = function.FullyQualifiedName.LastIndexOf ("."); string prename = null; if (len > 0) - prename = function.FullName.Substring (0, len + 1); + prename = function.FullyQualifiedName.Substring (0, len + 1); - string cons = string.Empty; +// string cons = string.Empty; // if (function.IsConst) // cons = " const"; return string.Format ("{2} {3}<b>{0}</b>({1})", GLib.Markup.EscapeText (function.Name), paramTxt, - GLib.Markup.EscapeText (function.ReturnType), + GLib.Markup.EscapeText (function.ReturnType.TypeName), GLib.Markup.EscapeText (prename)); // return prename + "<b>" + function.Name + "</b>" + " (" + paramTxt + ")" + cons; } - // Returns the text to use to represent the specified parameter + /// <summary> + /// Get the text to use to represent the specified parameter + /// </summary> public string GetParameterMarkup (int overload, int paramIndex) { - Function function = functions[overload]; + Symbol function = functions[overload]; + + if (null != function && null != function.Parameters[paramIndex]) { + string name = function.Parameters[paramIndex].Name; + string type = function.Parameters[paramIndex].TypeName; + return GLib.Markup.EscapeText (string.Format ("{1} {0}", name, type)); + } - return GLib.Markup.EscapeText (string.Format ("{1} {0}", function.Parameters[paramIndex].Key, function.Parameters[paramIndex].Value)); + return string.Empty; } - // Returns the number of parameters of the specified method + /// <summary> + /// Get the number of parameters of the specified method + /// </summary> public int GetParameterCount (int overload) { - return functions[overload].Parameters.Length; + if (null != functions && null != functions[overload] && null != functions[overload].Parameters) { + return functions[overload].Parameters.Count; + } + return 0; } } - public class CompletionData : ICompletionData + /// <summary> + /// Data for Vala completion + /// </summary> + internal class CompletionData : ICompletionData { private string image; private string text; private string description; private string completion_string; - public CompletionData (CodeNode item) + public CompletionData (Symbol item) { this.text = item.Name; this.completion_string = item.Name; - this.description = item.Description; + this.description = item.DisplayText; this.image = item.Icon; + DisplayFlags = DisplayFlags.None; + CompletionCategory = new ValaCompletionCategory (text, image); } public IconId Icon { @@ -220,56 +224,37 @@ namespace MonoDevelop.ValaBinding } public DisplayFlags DisplayFlags {
- get { return DisplayFlags.None; }
+ get; set;
} public CompletionCategory CompletionCategory { - get { - return null; - } + get; set; } } - /// <summary> - /// Mutable completion data list for asynchronous parsing - /// </summary> - public class ValaCompletionDataList: CompletionDataList, IMutableCompletionDataList + internal class ValaCompletionDataList: CompletionDataList { public ValaCompletionDataList (): base () { } - #region IMutableCompletionDataList implementation - - public event EventHandler Changed; - public event EventHandler Changing; - - protected virtual void OnChanged (object sender, EventArgs args) + internal virtual void AddRange (IEnumerable<CompletionData> vals) { - if (null != Changed){ Changed (sender, args); } - }// OnChanged - - protected virtual void OnChanging (object sender, EventArgs args) - { - if (null != Changing){ Changing (sender, args); } - }// OnChanging - - public virtual bool IsChanging - { - get{ return isChanging; } - internal set { - isChanging = value; - OnChanged (this, new EventArgs ()); + foreach (CompletionData item in vals) { + Add (item); } } - protected bool isChanging; - - public void Dispose () + }// ValaCompletionDataList + + internal class ValaCompletionCategory: CompletionCategory + { + public ValaCompletionCategory (string text, string image): base (text, image) { } - #endregion - - - }// ValaCompletionDataList + public override int CompareTo (CompletionCategory other) + { + return DisplayText.CompareTo (other.DisplayText); + } + } } diff --git a/extras/ValaBinding/Gui/ValaTextEditorExtension.cs b/extras/ValaBinding/Gui/ValaTextEditorExtension.cs index 3dcb837cfb..44cf46dd92 100644 --- a/extras/ValaBinding/Gui/ValaTextEditorExtension.cs +++ b/extras/ValaBinding/Gui/ValaTextEditorExtension.cs @@ -97,32 +97,27 @@ namespace MonoDevelop.ValaBinding return base.KeyPress (key, keyChar, modifier); } + /// <summary> + /// Expression to match instance construction/initialization + /// </summary> private static Regex initializationRegex = new Regex (@"(((?<typename>\w[\w\d\.<>]*)\s+)?(?<variable>\w[\w\d]*)\s*=\s*)?new\s*(?<constructor>\w[\w\d\.<>]*)?", RegexOptions.Compiled); + public override ICompletionDataList HandleCodeCompletion ( CodeCompletionContext completionContext, char completionChar) { int line, column; string lineText = null; ProjectInformation parser = Parser; - // Console.WriteLine ("({0},{1}): {2}", line, column, lineText); Editor.GetLineColumnFromPosition (completionContext.TriggerOffset, out line, out column); switch (completionChar) { - case '.': + case '.': // foo.[complete] lineText = Editor.GetLineText (line); if (column > lineText.Length){ column = lineText.Length; } lineText = lineText.Substring (0, column - 1); - // remove the trailing '.' - if (lineText.EndsWith (".", StringComparison.Ordinal)) { - lineText = lineText.Substring (0, lineText.Length-1); - } - - int nameStart = lineText.LastIndexOfAny (allowedChars); - - nameStart++; - string itemName = lineText.Substring (nameStart).Trim (); + string itemName = GetTrailingSymbol (lineText); if (string.IsNullOrEmpty (itemName)) return null; @@ -159,29 +154,38 @@ namespace MonoDevelop.ValaBinding return null; } + static string GetTrailingSymbol (string text) + { + // remove the trailing '.' + if (text.EndsWith (".", StringComparison.Ordinal)) + text = text.Substring (0, text.Length-1); + + int nameStart = text.LastIndexOfAny (allowedChars); + return text.Substring (nameStart+1).Trim (); + } + + /// <summary> + /// Perform constructor-specific completion + /// </summary> private ValaCompletionDataList CompleteConstructor (string lineText, int line, int column) { ProjectInformation parser = Parser; Match match = initializationRegex.Match (lineText); ValaCompletionDataList list = new ValaCompletionDataList (); - list.IsChanging = true; if (match.Success) { - ThreadPool.QueueUserWorkItem (delegate{ - // variable initialization - if (match.Groups["typename"].Success || "var" != match.Groups["typename"].Value) { - // simultaneous declaration and initialization - parser.GetConstructorsForType (match.Groups["typename"].Value, Document.FileName, line, column, list); - } else if (match.Groups["variable"].Success) { - // initialization of previously declared variable - parser.GetConstructorsForExpression (match.Groups["variable"].Value, Document.FileName, line, column, list); - } - if (0 == list.Count) { - // Fallback to known types - list.IsChanging = true; - parser.GetTypesVisibleFrom (Document.FileName, line, column, list); - } - }); + // variable initialization + if (match.Groups["typename"].Success || "var" != match.Groups["typename"].Value) { + // simultaneous declaration and initialization + parser.GetConstructorsForType (match.Groups["typename"].Value, Document.FileName, line, column, list); + } else if (match.Groups["variable"].Success) { + // initialization of previously declared variable + parser.GetConstructorsForExpression (match.Groups["variable"].Value, Document.FileName, line, column, list); + } + if (0 == list.Count) { + // Fallback to known types + parser.GetTypesVisibleFrom (Document.FileName, line, column, list); + } } return list; }// CompleteConstructor @@ -200,17 +204,22 @@ namespace MonoDevelop.ValaBinding return list; } + /// <summary> + /// Get the members of a symbol + /// </summary> private ValaCompletionDataList GetMembersOfItem (string itemFullName, int line, int column) { ProjectInformation info = Parser; if (null == info){ return null; } ValaCompletionDataList list = new ValaCompletionDataList (); - list.IsChanging = true; info.Complete (itemFullName, Document.FileName, line, column, list); return list; } + /// <summary> + /// Complete all symbols visible from a given location + /// </summary> private ValaCompletionDataList GlobalComplete (CodeCompletionContext context) { ProjectInformation info = Parser; @@ -226,7 +235,6 @@ namespace MonoDevelop.ValaBinding public override IParameterDataProvider HandleParameterCompletion ( CodeCompletionContext completionContext, char completionChar) { - //System.Console.WriteLine("ValaTextEditorExtension.HandleParameterCompletion({0})", completionChar); if (completionChar != '(') return null; @@ -255,8 +263,8 @@ namespace MonoDevelop.ValaBinding typename = match.Groups["constructor"].Value; } else { // Foo.Bar bar = new Foo.Bar.blah( ... - for (string[] typeTokens = typename.Split ('.'); 0 < typeTokens.Length && 0 < tokens.Length; ++index) { - if (!typeTokens[0].Equals (tokens[0], StringComparison.Ordinal)) { + for (string[] typeTokens = typename.Split ('.'); index < typeTokens.Length && index < tokens.Length; ++index) { + if (!typeTokens[index].Equals (tokens[index], StringComparison.Ordinal)) { break; } } diff --git a/extras/ValaBinding/Makefile.am b/extras/ValaBinding/Makefile.am index fef752586b..7afab3c76d 100644 --- a/extras/ValaBinding/Makefile.am +++ b/extras/ValaBinding/Makefile.am @@ -38,8 +38,7 @@ FILES = \ Navigation/LanguageItemEventArgs.cs \ Navigation/LanguageItemNodeBuilder.cs \ Navigation/ProjectNodeBuilderExtension.cs \ - Parser/CodeNode.cs \ - Parser/Function.cs \ + Parser/Afrodite.cs \ Parser/ProjectInformation.cs \ Parser/ProjectInformationManager.cs \ Parser/ValaDocumentParser.cs \ diff --git a/extras/ValaBinding/Navigation/LanguageItemCommandHandler.cs b/extras/ValaBinding/Navigation/LanguageItemCommandHandler.cs index 021c12c54c..27f60da79f 100644 --- a/extras/ValaBinding/Navigation/LanguageItemCommandHandler.cs +++ b/extras/ValaBinding/Navigation/LanguageItemCommandHandler.cs @@ -41,20 +41,22 @@ using MonoDevelop.Projects; using MonoDevelop.Ide.Gui.Components; using MonoDevelop.ValaBinding.Parser; +using MonoDevelop.ValaBinding.Parser.Afrodite; namespace MonoDevelop.ValaBinding.Navigation { public class LanguageItemCommandHandler : NodeCommandHandler { + /// <summary> + /// Jump to a node's declaration when it's activated + /// </summary> public override void ActivateItem () { - CodeNode item = (CodeNode)CurrentNode.DataItem; + Symbol item = (Symbol)CurrentNode.DataItem; - if (null != item && !string.IsNullOrEmpty (item.File) && File.Exists (item.File)) { - Document doc = IdeApp.Workbench.OpenDocument (item.File); - if(null != doc && null != doc.TextEditor) { - doc.TextEditor.JumpTo (item.FirstLine, 0); - } + if (null != item && 0 < item.SourceReferences.Count) { + SourceReference reference = item.SourceReferences[0]; + IdeApp.Workbench.OpenDocument (reference.File, reference.FirstLine, reference.FirstColumn, true); } } } diff --git a/extras/ValaBinding/Navigation/LanguageItemEventArgs.cs b/extras/ValaBinding/Navigation/LanguageItemEventArgs.cs index 47995c582f..00e804cf91 100644 --- a/extras/ValaBinding/Navigation/LanguageItemEventArgs.cs +++ b/extras/ValaBinding/Navigation/LanguageItemEventArgs.cs @@ -32,6 +32,7 @@ using System; using MonoDevelop.ValaBinding.Parser; +using MonoDevelop.ValaBinding.Parser.Afrodite; namespace MonoDevelop.ValaBinding.Navigation { @@ -39,14 +40,14 @@ namespace MonoDevelop.ValaBinding.Navigation public class LanguageItemEventArgs : EventArgs { - CodeNode item; + Symbol item; - public LanguageItemEventArgs (CodeNode item) + internal LanguageItemEventArgs (Symbol item) { this.item = item; } - public CodeNode Item { + internal Symbol Item { get { return item; } } } diff --git a/extras/ValaBinding/Navigation/LanguageItemNodeBuilder.cs b/extras/ValaBinding/Navigation/LanguageItemNodeBuilder.cs index 82bb5dd039..6f9056f62b 100644 --- a/extras/ValaBinding/Navigation/LanguageItemNodeBuilder.cs +++ b/extras/ValaBinding/Navigation/LanguageItemNodeBuilder.cs @@ -41,6 +41,7 @@ using MonoDevelop.Projects; using MonoDevelop.Ide.Gui.Components; using MonoDevelop.ValaBinding.Parser; +using MonoDevelop.ValaBinding.Parser.Afrodite; namespace MonoDevelop.ValaBinding.Navigation { @@ -50,17 +51,12 @@ namespace MonoDevelop.ValaBinding.Navigation public class LanguageItemNodeBuilder: TypeNodeBuilder { //// <value> - /// Container types - /// </value> - private static string[] containers = { "namespaces", "class", "struct", "enums" }; - - //// <value> /// Sort order for nodes /// </value> - private static string[] types = { "namespaces", "class", "struct", "property", "method", "signal", "field", "constants", "enums", "other" }; + private static string[] types = { "namespace", "class", "struct", "interface", "property", "method", "signal", "field", "constant", "enum", "other" }; public override Type NodeDataType { - get { return typeof(CodeNode); } + get { return typeof(Symbol); } } public override Type CommandHandlerType { @@ -69,7 +65,7 @@ namespace MonoDevelop.ValaBinding.Navigation public override string GetNodeName (ITreeNavigator thisNode, object dataObject) { - return ((CodeNode)dataObject).Name; + return ((Symbol)dataObject).Name; } public override void BuildNode (ITreeBuilder treeBuilder, @@ -78,49 +74,36 @@ namespace MonoDevelop.ValaBinding.Navigation ref Gdk.Pixbuf icon, ref Gdk.Pixbuf closedIcon) { - CodeNode c = (CodeNode)dataObject; - label = c.Name; + Symbol c = (Symbol)dataObject; + label = c.DisplayText; icon = Context.GetIcon (c.Icon); } public override void BuildChildNodes (ITreeBuilder treeBuilder, object dataObject) { - ValaProject p = treeBuilder.GetParentDataItem (typeof(ValaProject), false) as ValaProject; - if (p == null){ return; } - - ProjectInformation info = ProjectInformationManager.Instance.Get (p); - - bool publicOnly = treeBuilder.Options["PublicApiOnly"]; - CodeNode thisCodeNode = (CodeNode)dataObject; + // bool publicOnly = treeBuilder.Options["PublicApiOnly"]; + Symbol thisSymbol = (Symbol)dataObject; - ThreadPool.QueueUserWorkItem (delegate (object o) { - foreach (CodeNode child in info.GetChildren (thisCodeNode)) { - CodeNode clone = child.Clone (); - Gtk.Application.Invoke (delegate (object ob, EventArgs ea) { - treeBuilder.AddChild (clone); - }); - } - }); + foreach (Symbol child in thisSymbol.Children) { + treeBuilder.AddChild (child); + } } - /// <summary> - /// Show all container types as having child nodes; - /// only check on expansion - /// </summary> public override bool HasChildNodes (ITreeBuilder builder, object dataObject) { - return (0 <= Array.IndexOf<string> (containers, ((CodeNode)dataObject).NodeType)); + Symbol symbol = (Symbol)dataObject; + return (null != symbol.Children && 0 < symbol.Children.Count); } public override int CompareObjects (ITreeNavigator thisNode, ITreeNavigator otherNode) { if (null != thisNode && null != otherNode) { - CodeNode thisCN = thisNode.DataItem as CodeNode, - otherCN = otherNode.DataItem as CodeNode; + Symbol thisCN = thisNode.DataItem as Symbol, + otherCN = otherNode.DataItem as Symbol; if (null != thisCN && null != otherCN) { - return Array.IndexOf<string>(types, thisCN.NodeType) - - Array.IndexOf<string>(types, otherCN.NodeType); + return Array.IndexOf<string>(types, thisCN.SymbolType) - + Array.IndexOf<string>(types, otherCN.SymbolType); } } diff --git a/extras/ValaBinding/Navigation/ProjectNodeBuilderExtension.cs b/extras/ValaBinding/Navigation/ProjectNodeBuilderExtension.cs index cee537bde6..8ddd050b2e 100644 --- a/extras/ValaBinding/Navigation/ProjectNodeBuilderExtension.cs +++ b/extras/ValaBinding/Navigation/ProjectNodeBuilderExtension.cs @@ -46,6 +46,7 @@ using MonoDevelop.Ide.Gui.Components; using MonoDevelop.ValaBinding; using MonoDevelop.ValaBinding.Parser; +using MonoDevelop.ValaBinding.Parser.Afrodite; namespace MonoDevelop.ValaBinding.Navigation { @@ -77,19 +78,17 @@ namespace MonoDevelop.ValaBinding.Navigation if (o == null) return; ProjectInformation pi = ProjectInformationManager.Instance.Get (p); - ThreadPool.QueueUserWorkItem (delegate (object ob) { - try { - foreach (ProjectFile f in p.Files) { - if (f.BuildAction == BuildAction.Compile) - pi.AddFile (f.FilePath); - } - foreach (ProjectPackage package in p.Packages) { - if(!package.IsProject){ pi.AddPackage (p.Name); } - } - } catch (IOException) { - return; + try { + foreach (ProjectFile f in p.Files) { + if (f.BuildAction == BuildAction.Compile) + pi.AddFile (f.FilePath); } - }); + foreach (ProjectPackage package in p.Packages) { + if(!package.IsProject){ pi.AddPackage (p.Name); } + } + } catch (IOException) { + return; + } } public override void BuildNode (ITreeBuilder treeBuilder, @@ -106,19 +105,16 @@ namespace MonoDevelop.ValaBinding.Navigation ValaProject p = dataObject as ValaProject; if (p == null) return; - bool nestedNamespaces = builder.Options["NestedNamespaces"]; + // bool nestedNamespaces = builder.Options["NestedNamespaces"]; ProjectInformation info = ProjectInformationManager.Instance.Get (p); // Namespaces - ThreadPool.QueueUserWorkItem (delegate (object o) { - foreach (CodeNode child in info.GetChildren (null)) { - CodeNode clone = child.Clone (); - Gtk.Application.Invoke (delegate (object ob, EventArgs ea) { - builder.AddChild (clone); - }); + foreach (ProjectFile file in p.Files) { + foreach (Symbol child in info.GetNamespacesForFile (file.FilePath.FullPath)) { + builder.AddChild (child); } - }); + } } public override bool HasChildNodes (ITreeBuilder builder, object dataObject) diff --git a/extras/ValaBinding/Parser/Afrodite.cs b/extras/ValaBinding/Parser/Afrodite.cs new file mode 100644 index 0000000000..b9b72f0dab --- /dev/null +++ b/extras/ValaBinding/Parser/Afrodite.cs @@ -0,0 +1,1163 @@ +// +// Afrodite.cs +// +// Author: +// Levi Bard <levi.bard@emhartglass.com> +// +// Copyright (c) 2010 Levi Bard +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.IO; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +using MonoDevelop.Core.Gui; + +/// <summary> +/// Wrappers for Afrodite completion library +/// </summary> +namespace MonoDevelop.ValaBinding.Parser.Afrodite +{ + /// <summary> + /// Afrodite completion engine - interface for queueing source and getting ASTs + /// </summary> + internal class CompletionEngine + { + public CompletionEngine (string id) + { + instance = afrodite_completion_engine_new (id); + } + + /// <summary> + /// Queue a new source file for parsing + /// </summary> + public void QueueSourcefile (string path) + { + QueueSourcefile (path, !string.IsNullOrEmpty (path) && path.EndsWith (".vapi", StringComparison.OrdinalIgnoreCase), false); + } + + /// <summary> + /// Queue a new source file for parsing + /// </summary> + public void QueueSourcefile (string path, bool isVapi, bool isGlib) + { + afrodite_completion_engine_queue_sourcefile (instance, path, null, isVapi, isGlib); + } + + /// <summary> + /// Attempt to acquire the current AST + /// </summary> + /// <returns> + /// A <see cref="Ast"/>: null if unable to acquire + /// </returns> + public Ast TryAcquireAst () + { + IntPtr astInstance = IntPtr.Zero; + bool success = afrodite_completion_engine_try_acquire_ast (instance, out astInstance, 10); + return (success)? new Ast (astInstance, this): null; + } + + /// <summary> + /// Release the given AST (required for continued parsing) + /// </summary> + public void ReleaseAst (Ast ast) + { + afrodite_completion_engine_release_ast (instance, ast.Instance); + } + + #region P/Invokes + + IntPtr instance; + + [DllImport("afrodite")] + static extern IntPtr afrodite_completion_engine_new (string id); + + [DllImport("afrodite")] + static extern void afrodite_completion_engine_queue_sourcefile (IntPtr instance, string path, string content, + bool is_vapi, bool is_glib); + + [DllImport("afrodite")] + static extern bool afrodite_completion_engine_try_acquire_ast (IntPtr instance, out IntPtr ast, int retry_count); + + [DllImport("afrodite")] + static extern bool afrodite_completion_engine_release_ast (IntPtr instance, IntPtr ast); + + #endregion + } + + /// <summary> + /// Represents a Vala symbol + /// </summary> + internal class Symbol + { + public Symbol (IntPtr instance) + { + this.instance = instance; + } + + /// <summary> + /// Children of this symbol + /// </summary> + public List<Symbol> Children { + get { + List<Symbol> list = new List<Symbol> (); + IntPtr children = afrodite_symbol_get_children (instance); + + if (IntPtr.Zero != children) { + list = new ValaList (children).ToTypedList (delegate (IntPtr item){ return new Symbol (item); }); + } + + return list; + } + } + + /// <summary> + /// The type of this symbol + /// </summary> + public DataType DataType { + get { return new DataType (afrodite_symbol_get_symbol_type (instance)); } + } + + /// <summary> + /// The return type of this symbol, if applicable + /// </summary> + public DataType ReturnType { + get{ return new DataType (afrodite_symbol_get_return_type (instance)); } + } + + /// <summary> + /// The name of this symbol + /// </summary> + public string Name { + get{ return Marshal.PtrToStringAuto (afrodite_symbol_get_display_name (instance)); } + } + + /// <summary> + /// The fully qualified name of this symbol + /// </summary> + public string FullyQualifiedName { + get { return Marshal.PtrToStringAuto (afrodite_symbol_get_fully_qualified_name (instance)); } + } + + /// <summary> + /// The parent of this symbol + /// </summary> + public Symbol Parent { + get { + IntPtr parent = afrodite_symbol_get_parent (instance); + return (IntPtr.Zero == parent)? null: new Symbol (parent); + } + } + + /// <summary> + /// The places where this symbol is declared/defined + /// </summary> + public List<SourceReference> SourceReferences { + get { + List<SourceReference> list = new List<SourceReference> (); + IntPtr refs = afrodite_symbol_get_source_references (instance); + + if (IntPtr.Zero != refs) { + list = new ValaList (refs).ToTypedList (delegate (IntPtr item){ return new SourceReference (item); }); + } + + return list; + } + } + + /// <summary> + /// The symbol type (class, method, ...) of this symbol + /// </summary> + public string SymbolType { + get{ return Marshal.PtrToStringAuto (afrodite_symbol_get_type_name (instance)); } + } + + /// <summary> + /// The accessibility (public, private, ...) of this symbol + /// </summary> + public SymbolAccessibility Accessibility { + get{ return (SymbolAccessibility)afrodite_symbol_get_access (instance); } + } + + /// <summary> + /// The parameters this symbol accepts, if applicable + /// </summary> + public List<DataType> Parameters { + get { + List<DataType> list = new List<DataType> (); + IntPtr parameters = afrodite_symbol_get_parameters (instance); + + if (IntPtr.Zero != parameters) { + list = new ValaList (parameters).ToTypedList (delegate (IntPtr item){ return new DataType (item); }); + } + + return list; + } + } + + /// <summary> + /// The icon to be used for this symbol + /// </summary> + public string Icon { + get{ return GetIconForType (SymbolType, Accessibility); } + } + + /// <summary> + /// Descriptive text for this symbol + /// </summary> + public string DisplayText { + get { + StringBuilder text = new StringBuilder (Name); + List<DataType> parameters = Parameters; + if (0 < parameters.Count) { + text.AppendFormat ("({0} {1}", parameters[0].TypeName, Parameters[0].Name); + for (int i = 1; i < parameters.Count; i++) { + text.AppendFormat (", {0} {1}", parameters[i].TypeName, Parameters[i].Name); + } + text.AppendFormat (")"); + } + if (null != ReturnType && !string.IsNullOrEmpty (ReturnType.TypeName)) { + text.AppendFormat (": {0}", ReturnType.TypeName); + } + + return text.ToString (); + } + } + + #region Icons + + private static Dictionary<string,string> publicIcons = new Dictionary<string, string> () { + { "namespace", Stock.NameSpace }, + { "class", Stock.Class }, + { "struct", Stock.Struct }, + { "enum", Stock.Enum }, + { "errordomain", Stock.Enum }, + { "field", Stock.Field }, + { "method", Stock.Method }, + { "constructor", Stock.Method }, + { "creationmethod", Stock.Method }, + { "property", Stock.Property }, + { "constant", Stock.Literal }, + { "enumvalue", Stock.Literal }, + { "errorcode", Stock.Literal }, + { "signal", Stock.Event }, + { "delegate", Stock.Delegate }, + { "interface", Stock.Interface }, + { "other", Stock.Delegate } + }; + + private static Dictionary<string,string> privateIcons = new Dictionary<string, string> () { + { "namespace", Stock.NameSpace }, + { "class", Stock.PrivateClass }, + { "struct", Stock.PrivateStruct }, + { "enum", Stock.PrivateEnum }, + { "errordomain", Stock.PrivateEnum }, + { "field", Stock.PrivateField }, + { "method", Stock.PrivateMethod }, + { "constructor", Stock.PrivateMethod }, + { "creationmethod", Stock.PrivateMethod }, + { "property", Stock.PrivateProperty }, + { "constant", Stock.Literal }, + { "enumvalue", Stock.Literal }, + { "errorcode", Stock.Literal }, + { "signal", Stock.PrivateEvent }, + { "delegate", Stock.PrivateDelegate }, + { "interface", Stock.PrivateInterface }, + { "other", Stock.PrivateDelegate } + }; + + private static Dictionary<string,string> protectedIcons = new Dictionary<string, string> () { + { "namespace", Stock.NameSpace }, + { "class", Stock.ProtectedClass }, + { "struct", Stock.ProtectedStruct }, + { "enum", Stock.ProtectedEnum }, + { "errordomain", Stock.ProtectedEnum }, + { "field", Stock.ProtectedField }, + { "method", Stock.ProtectedMethod }, + { "constructor", Stock.ProtectedMethod }, + { "creationmethod", Stock.ProtectedMethod }, + { "property", Stock.ProtectedProperty }, + { "constant", Stock.Literal }, + { "enumvalue", Stock.Literal }, + { "errorcode", Stock.Literal }, + { "signal", Stock.ProtectedEvent }, + { "delegate", Stock.ProtectedDelegate }, + { "interface", Stock.ProtectedInterface }, + { "other", Stock.ProtectedDelegate } + }; + + private static Dictionary<SymbolAccessibility,Dictionary<string,string>> iconTable = new Dictionary<SymbolAccessibility, Dictionary<string, string>> () { + { SymbolAccessibility.Public, publicIcons }, + { SymbolAccessibility.Internal, publicIcons }, + { SymbolAccessibility.Private, privateIcons }, + { SymbolAccessibility.Protected, protectedIcons } + }; + + public static string GetIconForType (string nodeType, SymbolAccessibility visibility) + { + string icon = null; + iconTable[visibility].TryGetValue (nodeType.ToLower (), out icon); + return icon; + } + + #endregion + + #region P/Invokes + + IntPtr instance; + + [DllImport("afrodite")] + static extern IntPtr afrodite_symbol_get_type_name (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_symbol_get_display_name (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_symbol_get_children (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_symbol_get_parent (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_symbol_get_fully_qualified_name (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_symbol_get_source_references (IntPtr instance); + + [DllImport("afrodite")] + static extern int afrodite_symbol_get_access (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_symbol_get_parameters (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_symbol_get_symbol_type (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_symbol_get_return_type (IntPtr instance); + + #endregion + } + + /// <summary> + /// Represents a Vala AST + /// </summary> + /// <remarks> + /// MUST be disposed for parsing to continue + /// </remarks> + internal class Ast: IDisposable + { + CompletionEngine engine; + + /// <summary> + /// Create a new AST wrapper + /// </summary> + /// <param name="instance"> + /// A <see cref="IntPtr"/>: The native pointer for this AST + /// </param> + /// <param name="engine"> + /// A <see cref="CompletionEngine"/>: The completion engine to which this AST belongs + /// </param> + public Ast (IntPtr instance, CompletionEngine engine) + { + this.instance = instance; + this.engine = engine; + } + + public QueryResult GetSymbolsForPath (string path) + { + return new QueryResult (afrodite_ast_get_symbols_for_path (instance, new QueryOptions ().Instance, path)); + } + + /// <summary> + /// Lookup the symbol at a given location + /// </summary> + public Symbol LookupSymbolAt (string filename, int line, int column) + { + IntPtr symbol = afrodite_ast_lookup_symbol_at (instance, filename, line, column); + return (IntPtr.Zero == symbol)? null: new Symbol (symbol); + } + + /// <summary> + /// Lookup a symbol and its parent by fully qualified name + /// </summary> + public Symbol Lookup (string fully_qualified_name, out Symbol parent) + { + IntPtr parentInstance = IntPtr.Zero, + result = IntPtr.Zero; + + result = afrodite_ast_lookup (instance, fully_qualified_name, out parentInstance); + parent = (IntPtr.Zero == parentInstance)? null: new Symbol (parentInstance); + return (IntPtr.Zero == result)? null: new Symbol (result); + } + + /// <summary> + /// Lookup a symbol, given a name and source location + /// </summary> + public Symbol GetSymbolForNameAndPath (string name, string path, int line, int column) + { + IntPtr result = afrodite_ast_get_symbol_for_name_and_path (instance, QueryOptions.Standard ().Instance, + name, path, line, column); + if (IntPtr.Zero != result) { + QueryResult qresult = new QueryResult (result); + if (null != qresult.Children && 0 < qresult.Children.Count) + return qresult.Children[0].Symbol; + } + + return null; + } + + /// <summary> + /// Get the source files used to create this AST + /// </summary> + public List<SourceFile> SourceFiles { + get { + List<SourceFile> files = new List<SourceFile> (); + IntPtr sourceFiles = afrodite_ast_get_source_files (instance); + + if (IntPtr.Zero != sourceFiles) { + ValaList list = new ValaList (sourceFiles); + files = list.ToTypedList (delegate (IntPtr item){ return new SourceFile (item); }); + } + + return files; + } + } + + /// <summary> + /// Lookup a source file by filename + /// </summary> + public SourceFile LookupSourceFile (string filename) + { + IntPtr sourceFile = afrodite_ast_lookup_source_file (instance, filename); + return (IntPtr.Zero == sourceFile)? null: new SourceFile (sourceFile); + } + + #region P/Invokes + + IntPtr instance; + + internal IntPtr Instance { + get{ return instance; } + } + + [DllImport("afrodite")] + static extern IntPtr afrodite_ast_get_symbols_for_path (IntPtr instance, IntPtr options, string path); + + [DllImport("afrodite")] + static extern IntPtr afrodite_ast_lookup_symbol_at (IntPtr instance, string filename, int line, int column); + + [DllImport("afrodite")] + static extern IntPtr afrodite_ast_lookup (IntPtr instance, string fully_qualified_name, out IntPtr parent); + + [DllImport("afrodite")] + static extern IntPtr afrodite_ast_get_symbol_for_name_and_path (IntPtr instance, IntPtr options, + string symbol_qualified_name, string path, + int line, int column); + + [DllImport("afrodite")] + static extern IntPtr afrodite_ast_get_source_files (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_ast_lookup_source_file (IntPtr instance, string filename); + + #endregion + + #region IDisposable implementation + + /// <summary> + /// Release this AST for reuse + /// </summary> + public void Dispose () + { + engine.ReleaseAst (this); + } + + #endregion + } + + /// <summary> + /// Utility class for dumping an AST to Console.Out + /// </summary> + internal class AstDumper + { + public AstDumper () + { + instance = afrodite_ast_dumper_new (); + } + + public void Dump (Ast ast, string filterSymbol) + { + afrodite_ast_dumper_dump (instance, ast.Instance, filterSymbol); + } + + #region P/Invokes + + IntPtr instance; + + [DllImport("afrodite")] + static extern IntPtr afrodite_ast_dumper_new (); + + [DllImport("afrodite")] + static extern void afrodite_ast_dumper_dump (IntPtr instance, IntPtr ast, string filterSymbol); + + #endregion + } + + /// <summary> + /// Wrapper class for Afrodite query results + /// </summary> + internal class QueryResult + { + public QueryResult (IntPtr instance) + { + this.instance = instance; + } + + /// <summary> + /// ResultItems contained in this query result + /// </summary> + public List<ResultItem> Children { + get { + List<ResultItem> list = new List<ResultItem> (); + IntPtr children = afrodite_query_result_get_children (instance); + + if (IntPtr.Zero != children) { + list = new ValaList (children).ToTypedList (delegate (IntPtr item){ return new ResultItem (item); }); + } + + return list; + } + } + + #region P/Invokes + + IntPtr instance; + + internal IntPtr Instance { + get{ return instance; } + } + + [DllImport("afrodite")] + static extern IntPtr afrodite_query_result_get_children (IntPtr instance); + + #endregion + } + + /// <summary> + /// A single result from a query + /// </summary> + internal class ResultItem + { + public ResultItem (IntPtr instance) + { + this.instance = instance; + } + + public Symbol Symbol { + get { + IntPtr symbol = afrodite_result_item_get_symbol (instance); + return (IntPtr.Zero == symbol)? null: new Symbol (symbol); + } + } + + #region P/Invokes + + IntPtr instance; + + internal IntPtr Instance { + get{ return instance; } + } + + [DllImport("afrodite")] + static extern IntPtr afrodite_result_item_get_symbol (IntPtr instance); + + #endregion + } + + /// <summary> + /// Options for querying an AST + /// </summary> + internal class QueryOptions + { + public QueryOptions (): this (afrodite_query_options_new ()) + { + } + + public QueryOptions (IntPtr instance) + { + this.instance = instance; + } + + public static QueryOptions Standard () + { + return new QueryOptions (afrodite_query_options_standard ()); + } + + #region P/Invokes + + IntPtr instance; + + internal IntPtr Instance { + get{ return instance; } + } + + [DllImport("afrodite")] + static extern IntPtr afrodite_query_options_new (); + + [DllImport("afrodite")] + static extern IntPtr afrodite_query_options_standard (); + + #endregion + } + + /// <summary> + /// IEnumerator wrapper for (Gee|Vala).Iterator + /// </summary> + internal class ValaEnumerator: IEnumerator<IntPtr> + { + public ValaEnumerator (IntPtr instance) + { + this.instance = instance; + } + + #region IDisposable implementation + + public void Dispose () + { + } + + #endregion + + #region IEnumerator implementation + + object IEnumerator.Current { + get { return ((IEnumerator<IntPtr>)this).Current; } + } + + + public bool MoveNext () + { + return vala_iterator_next (instance); + } + + + public void Reset () + { + throw new System.NotImplementedException(); + } + + #endregion + + #region IEnumerator[System.IntPtr] implementation + + IntPtr IEnumerator<IntPtr>.Current { + get { return vala_iterator_get (instance); } + } + + #endregion + + #region P/Invoke + + IntPtr instance; + + [DllImport("vala")] + static extern bool vala_iterator_next (IntPtr instance); + + [DllImport("vala")] + static extern IntPtr vala_iterator_get (IntPtr instance); + + #endregion + } + + /// <summary> + /// IList wrapper for (Gee|Vala).List + /// </summary> + internal class ValaList: IList<IntPtr> + { + public ValaList (IntPtr instance) + { + this.instance = instance; + } + + #region ICollection[System.IntPtr] implementation + + public void Add (IntPtr item) + { + vala_collection_add (instance, item); + } + + + public void Clear () + { + vala_collection_clear (instance); + } + + + public bool Contains (IntPtr item) + { + return vala_collection_contains (instance, item); + } + + + public void CopyTo (IntPtr[] array, int arrayIndex) + { + if (Count < array.Length - arrayIndex) + throw new ArgumentException ("Destination array too small", "array"); + for (int i=0; i<Count; ++i) + array[i+arrayIndex] = this[i]; + } + + + public int Count { + get { + return vala_collection_get_size (instance); + } + } + + + public bool IsReadOnly { + get { return false; } + } + + + public bool Remove (IntPtr item) + { + return vala_collection_remove (instance, item); + } + + #endregion + + #region IEnumerable implementation + + IEnumerator IEnumerable.GetEnumerator () + { + return ((IEnumerable<IntPtr>)this).GetEnumerator (); + } + + #endregion + + #region IList[System.IntPtr] implementation + + public int IndexOf (IntPtr item) + { + return vala_list_index_of (instance, item); + } + + + public void Insert (int index, IntPtr item) + { + vala_list_insert (instance, index, item); + } + + + public IntPtr this[int index] { + get { return vala_list_get (instance, index); } + set { vala_list_set (instance, index, value); } + } + + + public void RemoveAt (int index) + { + vala_list_remove_at (instance, index); + } + + #endregion + + #region IEnumerable[System.IntPtr] implementation + IEnumerator<IntPtr> IEnumerable<IntPtr>.GetEnumerator () + { + return new ValaEnumerator (vala_iterable_iterator (instance)); + } + + #endregion + + internal List<T> ToTypedList<T> (Func<IntPtr,T> factory) + { + List<T> list = new List<T> (Count); + foreach (IntPtr item in this) { + list.Add (factory (item)); + } + return list; + } + + #region P/Invoke + + IntPtr instance; + + [DllImport("vala")] + static extern bool vala_collection_add (IntPtr instance, IntPtr item); + + [DllImport("vala")] + static extern void vala_collection_clear (IntPtr instance); + + [DllImport("vala")] + static extern bool vala_collection_contains (IntPtr instance, IntPtr item); + + [DllImport("vala")] + static extern int vala_collection_get_size (IntPtr instance); + + [DllImport("vala")] + static extern bool vala_collection_remove (IntPtr instance, IntPtr item); + + [DllImport("vala")] + static extern IntPtr vala_iterable_iterator (IntPtr instance); + + [DllImport("vala")] + static extern int vala_list_index_of (IntPtr instance, IntPtr item); + + [DllImport("vala")] + static extern void vala_list_insert (IntPtr instance, int index, IntPtr item); + + [DllImport("vala")] + static extern IntPtr vala_list_get (IntPtr instance, int index); + + [DllImport("vala")] + static extern void vala_list_set (IntPtr instance, int index, IntPtr item); + + [DllImport("vala")] + static extern void vala_list_remove_at (IntPtr instance, int index); + + #endregion + } + + /// <summary> + /// Class to represent an AST source file + /// </summary> + internal class SourceFile + { + public SourceFile (string filename) + :this (afrodite_source_file_new (filename)) + { + } + + public SourceFile (IntPtr instance) + { + this.instance = instance; + } + + /// <summary> + /// Symbols declared in this source file + /// </summary> + public List<Symbol> Symbols { + get { + List<Symbol> list = new List<Symbol> (); + IntPtr symbols = afrodite_source_file_get_symbols (instance); + + if (IntPtr.Zero != symbols) { + list = new ValaList (symbols).ToTypedList (delegate (IntPtr item){ return new Symbol (item); }); + } + + return list; + } + } + + /// <summary> + /// Using directives in this source file + /// </summary> + public List<Symbol> UsingDirectives { + get { + List<Symbol> list = new List<Symbol> (); + IntPtr symbols = afrodite_source_file_get_using_directives (instance); + + if (IntPtr.Zero != symbols) { + list = new ValaList (symbols).ToTypedList (delegate (IntPtr item){ return new Symbol (item); }); + } + + return list; + } + } + + /// <summary> + /// The name of this source file + /// </summary> + public string Name { + get{ return Marshal.PtrToStringAuto (afrodite_source_file_get_filename (instance)); } + } + + #region P/Invoke + + IntPtr instance; + + [DllImport("afrodite")] + static extern IntPtr afrodite_source_file_new (string filename); + + [DllImport("afrodite")] + static extern IntPtr afrodite_source_file_get_filename (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_source_file_get_symbols (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_source_file_get_using_directives (IntPtr instance); + + + #endregion + } + + /// <summary> + /// Represents an Afrodite symbol data type + /// </summary> + internal class DataType + { + public DataType (IntPtr instance) + { + this.instance = instance; + } + + /// <summary> + /// Get the raw name of this datatype + /// </summary> + public string Name { + get{ return Marshal.PtrToStringAuto (afrodite_data_type_get_name (instance)); } + } + + /// <summary> + /// Get the descriptive type name (ref Gee.List<string>[]?) for this datatype + /// </summary> + public string TypeName { + get { + StringBuilder text = new StringBuilder (); + + // prefix out/ref + if (IsOut) { + text.Append ("out "); + } else if (IsRef) { + text.Append ("ref "); + } + + text.Append (Marshal.PtrToStringAuto (afrodite_data_type_get_type_name (instance))); + + if (IsGeneric) { + text.Append ("<"); + List<DataType> parameters = GenericTypes; + text.Append (parameters[0].TypeName); + for (int i = 0; i < parameters.Count; i++) { + text.AppendFormat (",{0}", parameters[i].TypeName); + } + text.Append (">"); + } + + if (IsArray) { text.Append ("[]"); } + if (IsNullable){ text.Append ("?"); } + if (IsPointer){ text.Append ("*"); } + + return text.ToString (); + } + } + + /// <summary> + /// Get the symbol for this datatype + /// </summary> + public Symbol Symbol { + get { + IntPtr symbol = afrodite_data_type_get_symbol (instance); + return (IntPtr.Zero == symbol)? null: new Symbol (symbol); + } + } + + /// <summary> + /// Whether this datatype is an array + /// </summary> + public bool IsArray { + get{ return afrodite_data_type_get_is_array (instance); } + } + + /// <summary> + /// Whether this datatype is a pointer + /// </summary> + public bool IsPointer { + get{ return afrodite_data_type_get_is_pointer (instance); } + } + + /// <summary> + /// Whether this datatype is nullable + /// </summary> + public bool IsNullable { + get{ return afrodite_data_type_get_is_nullable (instance); } + } + + /// <summary> + /// Whether this is an out datatype + /// </summary> + public bool IsOut { + get{ return afrodite_data_type_get_is_out (instance); } + } + + /// <summary> + /// Whether this is a ref datatype + /// </summary> + public bool IsRef { + get{ return afrodite_data_type_get_is_ref (instance); } + } + + /// <summary> + /// Whether this datatype is generic + /// </summary> + public bool IsGeneric { + get{ return afrodite_data_type_get_is_generic (instance); } + } + + /// <summary> + /// Type list for generic datatypes (e.g. HashMap<KeyType,ValueType>) + /// </summary> + public List<DataType> GenericTypes { + get { + List<DataType> list = new List<DataType> (); + IntPtr types = afrodite_data_type_get_generic_types (instance); + + if (IntPtr.Zero != types) { + list = new ValaList (types).ToTypedList (delegate (IntPtr item){ return new DataType (item); }); + } + + return list; + } + } + + #region P/Invoke + + IntPtr instance; + + [DllImport("afrodite")] + static extern IntPtr afrodite_data_type_get_type_name (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_data_type_get_name (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_data_type_get_symbol (IntPtr instance); + + [DllImport("afrodite")] + static extern IntPtr afrodite_data_type_get_generic_types (IntPtr instance); + + [DllImport("afrodite")] + static extern bool afrodite_data_type_get_is_array (IntPtr instance); + + [DllImport("afrodite")] + static extern bool afrodite_data_type_get_is_pointer (IntPtr instance); + + [DllImport("afrodite")] + static extern bool afrodite_data_type_get_is_nullable (IntPtr instance); + + [DllImport("afrodite")] + static extern bool afrodite_data_type_get_is_out (IntPtr instance); + + [DllImport("afrodite")] + static extern bool afrodite_data_type_get_is_ref (IntPtr instance); + + [DllImport("afrodite")] + static extern bool afrodite_data_type_get_is_generic (IntPtr instance); + + + #endregion + } + + /// <summary> + /// Class to represent a reference area in a source file + /// </summary> + internal class SourceReference + { + public SourceReference (IntPtr instance) + { + this.instance = instance; + } + + public string File { + get { + IntPtr sourcefile = afrodite_source_reference_get_file (instance); + return (IntPtr.Zero == sourcefile)? string.Empty: new SourceFile (sourcefile).Name; + } + } + + public int FirstLine { + get{ return afrodite_source_reference_get_first_line (instance); } + } + + public int LastLine { + get{ return afrodite_source_reference_get_last_line (instance); } + } + + public int FirstColumn { + get{ return afrodite_source_reference_get_first_column (instance); } + } + + public int LastColumn { + get{ return afrodite_source_reference_get_last_column (instance); } + } + + #region P/Invoke + + IntPtr instance; + + [DllImport("afrodite")] + static extern IntPtr afrodite_source_reference_get_file (IntPtr instance); + + [DllImport("afrodite")] + static extern int afrodite_source_reference_get_first_line (IntPtr instance); + + [DllImport("afrodite")] + static extern int afrodite_source_reference_get_last_line (IntPtr instance); + + [DllImport("afrodite")] + static extern int afrodite_source_reference_get_first_column (IntPtr instance); + + [DllImport("afrodite")] + static extern int afrodite_source_reference_get_last_column (IntPtr instance); + + + #endregion + } + + // From afrodite.vapi + public enum SymbolAccessibility { + Private = 0x1, + Internal = 0x2, + Protected = 0x4, + Public = 0x8, + Any = 0x10 + } + + /// <summary> + /// Wrapper class for Afrodite.Utils namespace + /// </summary> + internal static class Utils + { + /// <summary> + /// Get a list of vapi files for a given package + /// </summary> + public static List<string> GetPackagePaths (string package) + { + List<string> list = new List<string> (); + IntPtr paths = afrodite_utils_get_package_paths (package, IntPtr.Zero, null); + if (IntPtr.Zero != paths) + list = new ValaList (paths).ToTypedList (delegate(IntPtr item){ return Marshal.PtrToStringAuto (item); }); + + return list; + } + + [DllImport("afrodite")] + static extern IntPtr afrodite_utils_get_package_paths (string package, IntPtr codeContext, string[] vapiDirs); + + } +} + diff --git a/extras/ValaBinding/Parser/CodeNode.cs b/extras/ValaBinding/Parser/CodeNode.cs deleted file mode 100644 index 0ba4667e7d..0000000000 --- a/extras/ValaBinding/Parser/CodeNode.cs +++ /dev/null @@ -1,156 +0,0 @@ -// -// CodeNode.cs -// -// Authors: -// Levi Bard <taktaktaktaktaktaktaktaktaktak@gmail.com> -// -// Copyright (C) 2009 Levi Bard -// -// This source code is licenced under The MIT License: -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - - -using System; -using System.Collections.Generic; - -using MonoDevelop.Core.Gui; - -namespace MonoDevelop.ValaBinding.Parser -{ - public enum AccessModifier { - Private, - Protected, - Public, - Internal - } - - /// <summary> - /// Representation of a Vala code symbol - /// </summary> - public class CodeNode - { - private static Dictionary<string,string> publicIcons = new Dictionary<string, string> () { - { "namespaces", Stock.NameSpace }, - { "class", Stock.Class }, - { "struct", Stock.Struct }, - { "enums", Stock.Enum }, - { "field", Stock.Field }, - { "method", Stock.Method }, - { "property", Stock.Property }, - { "constants", Stock.Literal }, - { "signal", Stock.Event }, - { "other", Stock.Delegate } - }; - - private static Dictionary<string,string> privateIcons = new Dictionary<string, string> () { - { "namespaces", Stock.NameSpace }, - { "class", Stock.PrivateClass }, - { "struct", Stock.PrivateStruct }, - { "enums", Stock.PrivateEnum }, - { "field", Stock.PrivateField }, - { "method", Stock.PrivateMethod }, - { "property", Stock.PrivateProperty }, - { "constants", Stock.Literal }, - { "signal", Stock.PrivateEvent }, - { "other", Stock.PrivateDelegate } - }; - - private static Dictionary<string,string> protectedIcons = new Dictionary<string, string> () { - { "namespaces", Stock.NameSpace }, - { "class", Stock.ProtectedClass }, - { "struct", Stock.ProtectedStruct }, - { "enums", Stock.ProtectedEnum }, - { "field", Stock.ProtectedField }, - { "method", Stock.ProtectedMethod }, - { "property", Stock.ProtectedProperty }, - { "constants", Stock.Literal }, - { "signal", Stock.ProtectedEvent }, - { "other", Stock.ProtectedDelegate } - }; - - private static Dictionary<AccessModifier,Dictionary<string,string>> iconTable = new Dictionary<AccessModifier, Dictionary<string, string>> () { - { AccessModifier.Public, publicIcons }, - { AccessModifier.Internal, publicIcons }, - { AccessModifier.Private, privateIcons }, - { AccessModifier.Protected, protectedIcons } - }; - - public string Name{ get; set; } - public string FullName{ get; set; } - public AccessModifier Access{ get; set; } - public string NodeType{ get; set; } - public string Icon { - get{ return GetIconForType (NodeType, Access); } - } - public virtual string Description { - get{ return string.Format("{0} {1}", NodeType, Name); } - } - public string File{ get; set; } - public int FirstLine{ get; set; } - public int LastLine{ get; set; } - - /// <value> - /// Whether this node is a class/struct/etc - /// </value> - public virtual bool IsContainerType - { - get { - return (0 <= Array.IndexOf (containerTypes, NodeType)); - } - } - private static readonly string[] containerTypes = new string[]{ "namespaces", "class", "struct", "enums" }; - - public CodeNode () {} - - public CodeNode (string type, string name, string parentname, string file, int first_line, int last_line) - { - Name = name; - NodeType = type; - FullName = (string.IsNullOrEmpty (parentname))? Name: string.Format ("{0}.{1}", parentname, name); - File = file; - FirstLine = first_line; - LastLine = (0 != last_line && last_line != first_line)? last_line-1: last_line; - } - - public CodeNode (string type, string name, string parentname, string file, int first_line, int last_line, AccessModifier access): this (type, name, parentname, file, first_line, last_line) - { - Access = access; - } - - public static string GetIconForType (string nodeType, AccessModifier visibility) - { - string icon = null; - iconTable[visibility].TryGetValue (nodeType, out icon); - return icon; - } - - /// <summary> - /// Clone the current CodeNode - /// </summary> - public virtual CodeNode Clone () - { - CodeNode clone = new CodeNode (NodeType, Name, string.Empty, File, FirstLine, LastLine, Access); - clone.FullName = FullName; - return clone; - } - } -} diff --git a/extras/ValaBinding/Parser/Function.cs b/extras/ValaBinding/Parser/Function.cs deleted file mode 100644 index 04368f81ab..0000000000 --- a/extras/ValaBinding/Parser/Function.cs +++ /dev/null @@ -1,77 +0,0 @@ -// -// Function.cs -// -// Authors: -// Levi Bard <taktaktaktaktaktaktaktaktaktak@gmail.com> -// -// Copyright (C) 2009 Levi Bard -// -// This source code is licenced under The MIT License: -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - - -using System; -using System.Collections.Generic; -using System.Text; - -namespace MonoDevelop.ValaBinding.Parser -{ - /// <summary> - /// Representation of a Vala function - /// </summary> - public class Function: CodeNode - { - public string ReturnType{ get; protected set; } - public KeyValuePair<string,string>[] Parameters{ get; set; } - - public override string Description { - get { - StringBuilder sb = new StringBuilder (); - sb.AppendFormat ("{0} {1} (", ReturnType, Name); - foreach (KeyValuePair<string,string> param in Parameters) { - sb.AppendFormat ("{0} {1},", param.Value, param.Key); - } - if (',' == sb[sb.Length-1]){ sb = sb.Remove (sb.Length-1, 1); } - sb.Append(")"); - - return sb.ToString (); - } - } - - public Function (string type, string name, string parentname, string file, int first_line, int last_line, AccessModifier access, string returnType, KeyValuePair<string,string>[] parameters): - base (type, name, parentname, file, first_line, last_line, access) - { - ReturnType = returnType; - Parameters = parameters; - } - - public override CodeNode Clone () - { - Function clone = new Function (NodeType, Name, string.Empty, File, FirstLine, LastLine, Access, ReturnType, null); - clone.FullName = FullName; - KeyValuePair<string,string>[] parameters = new KeyValuePair<string, string>[Parameters.Length]; - Parameters.CopyTo (parameters, 0); - clone.Parameters = parameters; - return clone; - } - } -} diff --git a/extras/ValaBinding/Parser/ProjectInformation.cs b/extras/ValaBinding/Parser/ProjectInformation.cs index 6e00b0b5ef..2ddc30f14b 100644 --- a/extras/ValaBinding/Parser/ProjectInformation.cs +++ b/extras/ValaBinding/Parser/ProjectInformation.cs @@ -40,6 +40,7 @@ using System.Text.RegularExpressions; using MonoDevelop.Projects; using MonoDevelop.Core; +using MonoDevelop.Core.Gui; using MonoDevelop.Core.Execution; using MonoDevelop.Projects.Gui.Completion; @@ -50,18 +51,15 @@ namespace MonoDevelop.ValaBinding.Parser /// </summary> public class ProjectInformation { - private ProcessWrapper p; private bool vtgInstalled = false; private bool checkedVtgInstalled = false; - private Dictionary<string,List<Function>> methods; - private Dictionary<string,List<CodeNode>> cache; - private HashSet<string> files; - private HashSet<string> packages; - private DateTime lastRestarted; - string lockme = "lockme"; + + private Afrodite.CompletionEngine engine; + + static readonly string[] containerTypes = new string[]{ "class", "struct", "interface" }; public Project Project{ get; set; } - + //// <value> /// Checks whether <see cref="http://code.google.com/p/vtg/">Vala Toys for GEdit</see> /// is installed. @@ -70,14 +68,16 @@ namespace MonoDevelop.ValaBinding.Parser get { if (!checkedVtgInstalled) { checkedVtgInstalled = true; + vtgInstalled = false; try { - Runtime.ProcessService.StartProcess ("vsc-shell", "--help", null, null).WaitForOutput (); - } catch { - LoggingService.LogWarning ("Cannot update Vala parser database because vsc-shell is not installed: {0}{1}", + Afrodite.Utils.GetPackagePaths ("glib-2.0"); + return (vtgInstalled = true); + } catch (DllNotFoundException) { + LoggingService.LogWarning ("Cannot update Vala parser database because libafrodite (VTG) is not installed: {0}{1}", Environment.NewLine, "http://code.google.com/p/vtg/"); - return false; + } catch (Exception ex) { + LoggingService.LogError ("ValaBinding: Error while checking for libafrodite", ex); } - vtgInstalled = true; } return vtgInstalled; } @@ -90,221 +90,35 @@ namespace MonoDevelop.ValaBinding.Parser } } - private void RestartParser () + public ProjectInformation (Project project) { - // Don't restart more often than once/five seconds - lock (lockme) { - if (0 > DateTime.Now.AddSeconds (-5).CompareTo (lastRestarted)){ return; } - lastRestarted = DateTime.Now; - } - - if (null != p) { - try { - if (!p.HasExited){ p.Kill (); } - p.Dispose (); - } catch { - // We don't care about anything that happens here. - } - } - - // Don't destroy old cached results - // cache = new Dictionary<string,List<CodeNode>> (); + this.Project = project; + string projectName = (null == project)? "NoExistingProject": project.Name; if (DepsInstalled) { - p = Runtime.ProcessService.StartProcess ("vsc-shell", string.Empty, ".", (ProcessEventHandler)null, null, null, true); - p.StandardError.Close (); - foreach (string package in packages) { - AddPackage (package); - } - foreach (string file in files) { - AddFile (file); - } - } - - lock(lockme){ lastRestarted = DateTime.Now; } - }// RestartParser - - private static Regex endOutputRegex = new Regex (@"^(\s*vsc-shell -\s*$|^\s*>)", RegexOptions.Compiled); - /// <summary> - /// Reads process output - /// </summary> - /// <returns> - /// A <see cref="System.String[]"/>: The lines output by the parser process - /// </returns> - private string[] ReadOutput () - { - List<string> result = new List<string> (); - int count = 0; - - DataReceivedEventHandler gotdata = delegate(object sender, DataReceivedEventArgs e) { - // Console.WriteLine(e.Data); - lock(result){ result.Add(e.Data); } - }; - - p.OutputDataReceived += gotdata; - - // for (int i=0; i<100; ++i) { - for (;;) { - p.BeginOutputReadLine (); - Thread.Sleep (50); - p.CancelOutputRead (); - lock (result) { - // if (count < result.Count){ i = 0; } - if (0 < result.Count && null != result[result.Count-1] && endOutputRegex.Match(result[result.Count-1]).Success) { - break; - } - count = result.Count; - } - p.StandardInput.WriteLine(string.Empty); - } - p.OutputDataReceived -= gotdata; - - return result.ToArray(); - }// ReadOutput - - /// <summary> - /// Sends a command to the parser - /// </summary> - /// <param name="command"> - /// A <see cref="System.String"/>: The command to be sent to the parser - /// </param> - /// <param name="args"> - /// A <see cref="System.Object[]"/>: string.Format-style arguments for command - /// </param> - /// <returns> - /// A <see cref="System.String[]"/>: The output from the command - /// </returns> - private string[] ParseCommand (string command, params object[] args) - { - string[] output = new string[0]; - if (null == p){ return output; } - - try { - lock (p) { - // Console.WriteLine (command, args); - p.StandardInput.WriteLine (string.Format (command, args)); - output = ReadOutput (); - // foreach (string line in output){ Console.WriteLine (line); } - } - } catch (Exception e) { - Console.WriteLine("{0}{1}{2}", e.Message, Environment.NewLine, e.StackTrace); - } - - if (0 == output.Length) { RestartParser (); } - - return output; - }// ParseCommand - - private ProjectInformation () - { - files = new HashSet<string> (); - packages = new HashSet<string> (); - methods = new Dictionary<string,List<Function>> (); - cache = new Dictionary<string, List<CodeNode>> (); - lastRestarted = DateTime.Now.AddSeconds(-6); - RestartParser (); - } - - public ProjectInformation (Project project): this () - { - this.Project = project; - } - - ~ProjectInformation () - { - lock (p) { - try { - p.StandardInput.WriteLine("quit"); - p.WaitForExit (100); - if (!p.HasExited) { - p.Kill (); - } - p.Dispose (); - } catch { - } + engine = new Afrodite.CompletionEngine (projectName); } } - - /// <summary> - /// Gets the children of a given code node - /// </summary> - public IList<CodeNode> GetChildren (CodeNode parent) - { - IList<CodeNode> children = new List<CodeNode> (); - - if (null == parent) { - string[] output = ParseCommand ("get-namespaces"); - Match match; - CodeNode child; - - foreach (string line in output) { - if (null != (child = ParseType (string.Empty, line))) { - children.Add (child); - } - } - } else if ("namespaces" != parent.NodeType) { - children = CacheCompleteType (parent.FullName, parent.File, parent.FirstLine, 0, null); - } else { - children = CacheCompleteType (parent.FullName, string.Empty, 0, 0, null); - } - - return children; - }// GetChildren - - private List<CodeNode> CacheCompleteType (string typename, string filename, int linenum, int column, ValaCompletionDataList results) - { - bool cached; - List<CodeNode> completion; - - lock (cache){ cached = cache.TryGetValue (typename, out completion); } - - if (cached) { - AddResults (completion, results); - ThreadPool.QueueUserWorkItem (delegate{ - List<CodeNode> newcompletion = CompleteType (typename, filename, linenum, column, null); - if (null != newcompletion && 0 != newcompletion.Count) { - lock (cache){ cache[typename] = newcompletion; } - } - }); - } else { - completion = CompleteType (typename, filename, linenum, column, results); - if (null != completion && 0 != completion.Count) { - lock (cache){ cache[typename] = completion; } - } - } - - return completion; - }// CacheCompleteType /// <summary> /// Gets the completion list for a given type name in a given file /// </summary> - internal List<CodeNode> CompleteType (string typename, string filename, int linenum, int column, ValaCompletionDataList results) + internal List<Afrodite.Symbol> CompleteType (string typename, string filename, int linenum, int column, ValaCompletionDataList results) { - string[] output = ParseCommand ("complete {0} {1}", typename, filename); - List<CodeNode> children = new List<CodeNode> (); - CodeNode child; - - foreach (string line in output) { - if (null != (child = ParseType (typename, line))) { - children.Add (child); - if (null != results) { - CompletionData datum = new CompletionData (child); - Gtk.Application.Invoke (delegate(object sender, EventArgs args){ - results.Add (datum); - results.IsChanging = true; - }); - } + List<Afrodite.Symbol> nodes = new List<Afrodite.Symbol> (); + if (!DepsInstalled){ return nodes; } + + using (Afrodite.Ast parseTree = engine.TryAcquireAst ()) { + if (null != parseTree) { + Afrodite.Symbol symbol = parseTree.GetSymbolForNameAndPath (typename, filename, linenum, column); + if (null == symbol){ LoggingService.LogDebug ("CompleteType: Unable to lookup {0} in {1} at {2}:{3}", typename, filename, linenum, column); } + else{ nodes = symbol.Children; } + } else { + LoggingService.LogDebug ("CompleteType: Unable to acquire ast"); } } - if (null != results) { - Gtk.Application.Invoke (delegate(object sender, EventArgs args){ - results.IsChanging = false; - }); - } - - return children; + return nodes; } /// <summary> @@ -312,13 +126,10 @@ namespace MonoDevelop.ValaBinding.Parser /// </summary> public void AddFile (string filename) { - lock (files) { - // if (files.Contains (filename)){ return; } - files.Add (filename); + if (vtgInstalled) { + LoggingService.LogDebug ("Adding file {0}", filename); + engine.QueueSourcefile (filename, filename.EndsWith (".vapi", StringComparison.OrdinalIgnoreCase), false); } - ThreadPool.QueueUserWorkItem (delegate { - ParseCommand ("add-source {0}", filename); - }); }// AddFile /// <summary> @@ -326,10 +137,7 @@ namespace MonoDevelop.ValaBinding.Parser /// </summary> public void RemoveFile (string filename) { - lock (files) { files.Remove (filename); } - ThreadPool.QueueUserWorkItem (delegate { - ParseCommand ("remove-source {0}", filename); - }); + // Not currently possible with Afrodite completion engine }// RemoveFile /// <summary> @@ -337,50 +145,82 @@ namespace MonoDevelop.ValaBinding.Parser /// </summary> public void AddPackage (string packagename) { - lock (packages) { - // if (packages.Contains (packagename)){ return; } - packages.Add (packagename); + if (!DepsInstalled){ return; } + + if ("glib-2.0".Equals (packagename, StringComparison.Ordinal)) { + LoggingService.LogDebug ("AddPackage: Skipping {0}", packagename); + return; + } else { + LoggingService.LogDebug ("AddPackage: Adding package {0}", packagename); + } + + foreach (string path in Afrodite.Utils.GetPackagePaths (packagename)) { + LoggingService.LogDebug ("AddPackage: Queueing {0} for package {1}", path, packagename); + engine.QueueSourcefile (path, true, false); } - ThreadPool.QueueUserWorkItem (delegate { - ParseCommand ("add-package {0}", packagename); - }); }// AddPackage /// <summary> - /// Tells the parser to reparse - /// </summary> - public void Reparse () - { - //ParseCommand ("reparse"); - RestartParser (); - }// Reparse - - private static Regex typeNameRegex = new Regex (@"vsc-shell - typename for [^:]+: (?<type>[^\s]+)\s*$", RegexOptions.Compiled); - /// <summary> /// Gets the completion list for a given symbol at a given location /// </summary> - public void Complete (string symbol, string filename, int line, int column, ValaCompletionDataList results) + internal List<Afrodite.Symbol> Complete (string symbol, string filename, int line, int column, ValaCompletionDataList results) { - if (cache.ContainsKey (symbol)){ CacheCompleteType (symbol, filename, line, column, results); } - else ThreadPool.QueueUserWorkItem (delegate{ - string expressionType = GetExpressionType (symbol, filename, line, column); - CacheCompleteType (expressionType, filename, line, column, results); - }); + List<Afrodite.Symbol> nodes = new List<Afrodite.Symbol> (); + if (!DepsInstalled){ return nodes; } + + + using (Afrodite.Ast parseTree = engine.TryAcquireAst ()) { + if (null != parseTree) { + LoggingService.LogDebug ("Complete: Looking up symbol at {0}:{1}:{2}", filename, line, column); + Afrodite.Symbol sym = parseTree.GetSymbolForNameAndPath (symbol, filename, line, column); + LoggingService.LogDebug ("Complete: Got {0}", (null == sym)? "null": sym.Name); + if (null != sym) { + nodes = sym.Children; + AddResults (nodes, results); + } + } else { + LoggingService.LogDebug ("Complete: Unable to acquire ast"); + } + } + + return nodes; }// Complete + + internal Afrodite.Symbol GetFunction (string name, string filename, int line, int column) + { + if (!DepsInstalled){ return null; } + + using (Afrodite.Ast parseTree = engine.TryAcquireAst ()) { + if (null != parseTree) { + LoggingService.LogDebug ("GetFunction: Looking up symbol at {0}:{1}:{2}", filename, line, column); + Afrodite.Symbol symbol = parseTree.GetSymbolForNameAndPath (name, filename, line, column); + LoggingService.LogDebug ("GetFunction: Got {0}", (null == symbol)? "null": symbol.Name); + return symbol; + } else { + LoggingService.LogDebug ("GetFunction: Unable to acquire ast"); + } + } + + return null; + } /// <summary> /// Get the type of a given expression /// </summary> public string GetExpressionType (string symbol, string filename, int line, int column) { - AddFile (filename); - string[] responses = ParseCommand ("type-name {0} {1} {2} {3}", symbol, filename, line, column); - Match match; + if (!DepsInstalled){ return symbol; } - foreach (string response in responses) { - match = typeNameRegex.Match (response); - if (match.Success) { - return match.Groups["type"].Value; + using (Afrodite.Ast parseTree = engine.TryAcquireAst ()) { + if (null != parseTree) { + LoggingService.LogDebug ("GetExpressionType: Looking up symbol at {0}:{1}:{2}", filename, line, column); + Afrodite.Symbol sym = parseTree.LookupSymbolAt (filename, line, column); + if (null != sym) { + LoggingService.LogDebug ("Got {0}", sym.DataType.TypeName); + return sym.DataType.TypeName; + } + } else { + LoggingService.LogDebug ("GetExpressionType: Unable to acquire ast"); } } @@ -390,65 +230,45 @@ namespace MonoDevelop.ValaBinding.Parser /// <summary> /// Get overloads for a method /// </summary> - public List<Function> GetOverloads (string name) + internal List<Afrodite.Symbol> GetOverloads (string name, string filename, int line, int column) { - lock (methods) { - return (methods.ContainsKey (name))? methods[name]: new List<Function> (); + List<Afrodite.Symbol> overloads = new List<Afrodite.Symbol> (); + if (!DepsInstalled){ return overloads; } + + using (Afrodite.Ast parseTree = engine.TryAcquireAst ()) { + if (null != parseTree) { + Afrodite.Symbol symbol = parseTree.GetSymbolForNameAndPath (name, filename, line, column); + overloads = new List<Afrodite.Symbol> (){ symbol }; + } else { + LoggingService.LogDebug ("GetOverloads: Unable to acquire ast"); + } } + + return overloads; }// GetOverloads /// <summary> /// Get constructors for a given type /// </summary> - public List<Function> GetConstructorsForType (string typename, string filename, int line, int column, ValaCompletionDataList results) + internal List<Afrodite.Symbol> GetConstructorsForType (string typename, string filename, int line, int column, ValaCompletionDataList results) { - string[] tokens = typename.Split ('.'); - string baseTypeName = tokens[tokens.Length-1]; - List<Function> constructors = new List<Function> (); - List<CodeNode> cachedNode = null; - - if (cache.ContainsKey (typename)) { - cachedNode = cache[typename]; - } else { - foreach (string cachedType in cache.Keys) { - if (cachedType.EndsWith (typename)) { - cachedNode = cache[cachedType]; - break; - } + List<Afrodite.Symbol> functions = new List<Afrodite.Symbol> (); + foreach (Afrodite.Symbol node in CompleteType (typename, filename, line, column, null)) { + if ("constructor".Equals (node.SymbolType, StringComparison.OrdinalIgnoreCase) || + "creationmethod".Equals (node.SymbolType, StringComparison.OrdinalIgnoreCase)) { + functions.Add (node); } } - if (null != cachedNode) { - constructors = cachedNode.FindAll (delegate (CodeNode node){ - return ("method" == node.NodeType && - (baseTypeName == node.Name || node.Name.StartsWith (baseTypeName + "."))); - }).ConvertAll<Function> (delegate (CodeNode node){ - if (null != results) { - CompletionData datum = new CompletionData (node); - Gtk.Application.Invoke (delegate (object sender, EventArgs args){ - results.Add (datum); - results.IsChanging = true; - }); - } - return node as Function; - }); - } else { - ThreadPool.QueueUserWorkItem (delegate (object o){ CacheCompleteType (typename, filename, line, column, null); }); - } - - if (null != results) { - Gtk.Application.Invoke (delegate (object sender, EventArgs args){ - results.IsChanging = false; - }); - } + AddResults ((IList<Afrodite.Symbol>)functions, results); - return constructors; + return functions; }// GetConstructorsForType /// <summary> /// Get constructors for a given expression /// </summary> - public List<Function> GetConstructorsForExpression (string expression, string filename, int line, int column, ValaCompletionDataList results) + internal List<Afrodite.Symbol> GetConstructorsForExpression (string expression, string filename, int line, int column, ValaCompletionDataList results) { string typename = GetExpressionType (expression, filename, line, column); return GetConstructorsForType (typename, filename, line, column, results); @@ -457,154 +277,116 @@ namespace MonoDevelop.ValaBinding.Parser /// <summary> /// Get types visible from a given source location /// </summary> - public void GetTypesVisibleFrom (string filename, int line, int column, ValaCompletionDataList results) + internal void GetTypesVisibleFrom (string filename, int line, int column, ValaCompletionDataList results) { - results.IsChanging = true; + if (!DepsInstalled){ return; } - ThreadPool.QueueUserWorkItem (delegate{ - string[] output = ParseCommand ("visible-types {0} {1} {2}", filename, line, column); - CodeNode child; + using (Afrodite.Ast parseTree = engine.TryAcquireAst ()) { + if (null == parseTree){ return; } - foreach (string outputline in output) { - if (null != (child = ParseType (string.Empty, outputline))) { - CompletionData datum = new CompletionData (child); - Gtk.Application.Invoke (delegate (object sender, EventArgs args){ - results.Add (datum); - results.IsChanging = true; - }); + AddResults (GetNamespacesForFile (filename), results); + AddResults (GetClassesForFile (filename), results); + Afrodite.SourceFile file = parseTree.LookupSourceFile (filename); + if (null != file) { + Afrodite.Symbol parent; + foreach (Afrodite.Symbol directive in file.UsingDirectives) { + Afrodite.Symbol ns = parseTree.Lookup (directive.FullyQualifiedName, out parent); + if (null != ns) { + List<Afrodite.Symbol> containers = new List<Afrodite.Symbol> (); + AddResults (new Afrodite.Symbol[]{ ns }, results); + foreach (Afrodite.Symbol child in ns.Children) { + foreach (string containerType in containerTypes) { + if (containerType.Equals (child.SymbolType, StringComparison.OrdinalIgnoreCase)) + containers.Add (child); + } + } + AddResults (containers, results); + } } } - Gtk.Application.Invoke (delegate (object sender, EventArgs args){ - results.IsChanging = false; - }); - }); + } }// GetTypesVisibleFrom /// <summary> /// Get symbols visible from a given source location /// </summary> - public void GetSymbolsVisibleFrom (string filename, int line, int column, ValaCompletionDataList results) + internal void GetSymbolsVisibleFrom (string filename, int line, int column, ValaCompletionDataList results) { - results.IsChanging = true; - - ThreadPool.QueueUserWorkItem (delegate{ - string[] output = ParseCommand ("visible-symbols {0} {1} {2}", filename, line, column); - CodeNode child; - - foreach (string outputline in output) { - if (null != (child = ParseType (string.Empty, outputline))) { - CompletionData datum = new CompletionData (child); - Gtk.Application.Invoke (delegate (object sender, EventArgs args){ - results.Add (datum); - results.IsChanging = true; - }); - } - } - Gtk.Application.Invoke (delegate (object sender, EventArgs args){ - results.IsChanging = false; - }); - }); + GetTypesVisibleFrom (filename, line, column, results); + Complete ("this", filename, line, column, results); }// GetSymbolsVisibleFrom - private static Regex completionRegex = new Regex (@"^\s*vsc-shell - (?<type>[^:]+):(?<name>[^\s:]+)(:(?<modifier>[^;]*);(?<static>[^:]*))?(:(?<returntype>[^;]*);(?<ownership>[^:]*))?(:(?<args>[^:]*);)?((?<file>[^:]*):(?<first_line>\d+);((?<last_line>\d+);)?)?", RegexOptions.Compiled); /// <summary> - /// Parse out a CodeNode from a vsc-shell description string + /// Add results to a ValaCompletionDataList on the GUI thread /// </summary> - private CodeNode ParseType (string typename, string typeDescription) + private static void AddResults (IEnumerable<Afrodite.Symbol> list, ValaCompletionDataList results) { - Match match = completionRegex.Match (typeDescription); - - if (match.Success) { - string childType = match.Groups["type"].Value; - string name = match.Groups["name"].Value; - AccessModifier access = AccessModifier.Public; - string[] argtokens = typename.Split ('.'); - string baseTypeName = argtokens[argtokens.Length-1]; - string file = match.Groups["file"].Success? match.Groups["file"].Value: string.Empty; - int first_line = match.Groups["first_line"].Success? int.Parse(match.Groups["first_line"].Value): 0; - int last_line = match.Groups["last_line"].Success? int.Parse(match.Groups["last_line"].Value): first_line; - - switch (match.Groups["modifier"].Value) { - case "private": - access = AccessModifier.Private; - break; - case "protected": - access = AccessModifier.Protected; - break; - case "internal": - access = AccessModifier.Internal; - break; - default: - access = AccessModifier.Public; - break; - } - - switch (childType) { - case "method": - List<KeyValuePair<string,string>> paramlist = new List<KeyValuePair<string,string>>(); - string returnType = (match.Groups["returntype"].Success)? match.Groups["returntype"].Value: string.Empty; - if (name == baseTypeName || name.StartsWith (baseTypeName + ".")) { - returnType = string.Empty; - } - - if (match.Groups["args"].Success) { - StringBuilder args = new StringBuilder (); - foreach (string arg in match.Groups["args"].Value.Split (';')) { - argtokens = arg.Split (','); - if (3 == argtokens.Length) { - paramlist.Add (new KeyValuePair<string,string> (argtokens[0], string.Format("{0} {1}", argtokens[2], argtokens[1]))); - } - } - } - Function function = new Function (childType, name, typename, file, first_line, last_line, access, returnType, paramlist.ToArray ()); - if (!methods.ContainsKey (function.Name)){ methods[function.Name] = new List<Function> (); } - methods[function.Name].Add (function); - return function; - break; - default: - return new CodeNode (childType, name, typename, file, first_line, last_line, access); - break; - } + if (null == list || null == results) + { + LoggingService.LogDebug ("AddResults: null list or results!"); + return; } - return null; - }// ParseType + foreach (Afrodite.Symbol node in list) { + results.Add (new CompletionData (node)); + } + }// AddResults /// <summary> - /// Add results to a ValaCompletionDataList on the GUI thread + /// Get a list of classes declared in a given file /// </summary> - private static void AddResults (IList<CodeNode> list, ValaCompletionDataList results) + internal List<Afrodite.Symbol> GetClassesForFile (string file) { - if (null == results){ return; } - - Gtk.Application.Invoke (delegate(object sender, EventArgs args){ - results.IsChanging = true; - foreach (CodeNode node in list) { - results.Add (new CompletionData (node)); - // results.IsChanging = true; - } - results.IsChanging = false; - }); - }// AddResults + return GetSymbolsForFile (file, containerTypes); + }// GetClassesForFile - public List<CodeNode> GetClassesForFile (string file) + /// <summary> + /// Get a list of namespaces declared in a given file + /// </summary> + internal List<Afrodite.Symbol> GetNamespacesForFile (string file) { - List<CodeNode> classes = new List<CodeNode> (); - if (null != p) { - AddFile (file); - CodeNode node = null; - - lock(p){ p.StandardInput.WriteLine ("reparse both"); } - - foreach (string result in ParseCommand ("get-classes {0}", file)) { - node = ParseType (string.Empty, result); - if(null != node && node.IsContainerType) { - classes.Add (node); + return GetSymbolsForFile (file, new string[]{ "namespace" }); + } + + /// <summary> + /// Get a list of symbols declared in a given file + /// </summary> + /// <param name="file"> + /// A <see cref="System.String"/>: The file to check + /// </param> + /// <param name="desiredTypes"> + /// A <see cref="IEnumerable<System.String>"/>: The types of symbols to allow + /// </param> + List<Afrodite.Symbol> GetSymbolsForFile (string file, IEnumerable<string> desiredTypes) + { + List<Afrodite.Symbol> symbols = null; + List<Afrodite.Symbol> classes = new List<Afrodite.Symbol> (); + + if (!DepsInstalled){ return classes; } + + using (Afrodite.Ast parseTree = engine.TryAcquireAst ()) { + if (null != parseTree){ + Afrodite.SourceFile sourceFile = parseTree.LookupSourceFile (file); + if (null != sourceFile) { + symbols = sourceFile.Symbols; + if (null != symbols) { + foreach (Afrodite.Symbol symbol in symbols) { + foreach (string containerType in desiredTypes) { + if (containerType.Equals (symbol.SymbolType, StringComparison.OrdinalIgnoreCase)) + classes.Add (symbol); + } + } + } + } else { + LoggingService.LogDebug ("GetClassesForFile: Unable to lookup source file {0}", file); } + } else { + LoggingService.LogDebug ("GetClassesForFile: Unable to acquire ast"); } + } return classes; - }// GetClassesForFile + } } } diff --git a/extras/ValaBinding/Parser/ValaDocumentParser.cs b/extras/ValaBinding/Parser/ValaDocumentParser.cs index f6501726ee..e7b4619146 100644 --- a/extras/ValaBinding/Parser/ValaDocumentParser.cs +++ b/extras/ValaBinding/Parser/ValaDocumentParser.cs @@ -32,6 +32,8 @@ using System.Threading; using MonoDevelop.Projects.Dom; using MonoDevelop.Projects.Dom.Parser; +using MonoDevelop.ValaBinding.Parser.Afrodite; + namespace MonoDevelop.ValaBinding.Parser { /// <summary> @@ -39,6 +41,8 @@ namespace MonoDevelop.ValaBinding.Parser /// </summary> public class ValaDocumentParser: AbstractParser { + private ParsedDocument lastGood; + public ValaDocumentParser(): base("Vala", "text/x-vala") { } @@ -61,51 +65,63 @@ namespace MonoDevelop.ValaBinding.Parser if(null == doc.CompilationUnit){ doc.CompilationUnit = new CompilationUnit (fileName); } CompilationUnit cu = (CompilationUnit)doc.CompilationUnit; int lastLine = 0; + List<Symbol> classes = pi.GetClassesForFile (fileName); + + if (null == classes || 0 == classes.Count) { + return lastGood; + } - foreach (CodeNode node in pi.GetClassesForFile (fileName)) { + foreach (Symbol node in classes) { if (null == node){ continue; } List<IMember> members = new List<IMember> (); - lastLine = node.LastLine; + lastLine = node.SourceReferences[0].LastLine; - foreach (CodeNode child in pi.CompleteType (node.FullName, fileName, node.FirstLine, 0, null)) { - if (child.File != node.File){ continue; } - lastLine = Math.Max (lastLine, child.LastLine+1); + foreach (Symbol child in node.Children) { + if (child.SourceReferences[0].File != node.SourceReferences[0].File){ continue; } + lastLine = Math.Max (lastLine, child.SourceReferences[0].LastLine+1); - switch (child.NodeType) { + switch (child.SymbolType.ToLower ()) { case "class": - members.Add (new DomType (new CompilationUnit (fileName), ClassType.Class, child.Name, new DomLocation (child.FirstLine, 1), string.Empty, new DomRegion (child.FirstLine+1, child.LastLine+1), new List<IMember> ())); + members.Add (new DomType (new CompilationUnit (fileName), ClassType.Class, child.Name, new DomLocation (child.SourceReferences[0].FirstLine, 1), string.Empty, new DomRegion (child.SourceReferences[0].FirstLine, int.MaxValue, child.SourceReferences[0].LastLine, int.MaxValue), new List<IMember> ())); + break; + case "interface": + members.Add (new DomType (new CompilationUnit (fileName), ClassType.Interface, child.Name, new DomLocation (child.SourceReferences[0].FirstLine, 1), string.Empty, new DomRegion (child.SourceReferences[0].FirstLine, int.MaxValue, child.SourceReferences[0].LastLine, int.MaxValue), new List<IMember> ())); break; case "delegate": - members.Add (new DomType (new CompilationUnit (fileName), ClassType.Delegate, child.Name, new DomLocation (child.FirstLine, 1), string.Empty, new DomRegion (child.FirstLine+1, child.LastLine+1), new List<IMember> ())); + members.Add (new DomType (new CompilationUnit (fileName), ClassType.Delegate, child.Name, new DomLocation (child.SourceReferences[0].FirstLine, 1), string.Empty, new DomRegion (child.SourceReferences[0].FirstLine, int.MaxValue, child.SourceReferences[0].LastLine, int.MaxValue), new List<IMember> ())); break; case "struct": - members.Add (new DomType (new CompilationUnit (fileName), ClassType.Struct, child.Name, new DomLocation (child.FirstLine, 1), string.Empty, new DomRegion (child.FirstLine+1, child.LastLine+1), new List<IMember> ())); + members.Add (new DomType (new CompilationUnit (fileName), ClassType.Struct, child.Name, new DomLocation (child.SourceReferences[0].FirstLine, 1), string.Empty, new DomRegion (child.SourceReferences[0].FirstLine, int.MaxValue, child.SourceReferences[0].LastLine, int.MaxValue), new List<IMember> ())); break; - case "enums": - members.Add (new DomType (new CompilationUnit (fileName), ClassType.Enum, child.Name, new DomLocation (child.FirstLine, 1), string.Empty, new DomRegion (child.FirstLine+1, child.LastLine+1), new List<IMember> ())); + case "enum": + members.Add (new DomType (new CompilationUnit (fileName), ClassType.Enum, child.Name, new DomLocation (child.SourceReferences[0].FirstLine, 1), string.Empty, new DomRegion (child.SourceReferences[0].FirstLine, int.MaxValue, child.SourceReferences[0].LastLine, int.MaxValue), new List<IMember> ())); break; case "method": - members.Add (new DomMethod (child.Name, Modifiers.None, MethodModifier.None, new DomLocation (child.FirstLine, 1), new DomRegion (child.FirstLine+1, child.LastLine+1), new DomReturnType (((Function)child).ReturnType))); + case "creationmethod": + case "constructor": + members.Add (new DomMethod (child.Name, Modifiers.None, MethodModifier.None, new DomLocation (child.SourceReferences[0].FirstLine, 1), new DomRegion (child.SourceReferences[0].FirstLine, int.MaxValue, child.SourceReferences[0].LastLine, int.MaxValue), new DomReturnType (child.ReturnType.TypeName))); break; case "property": - members.Add (new DomProperty (child.Name, Modifiers.None, new DomLocation (child.FirstLine, 1), new DomRegion (child.FirstLine+1, child.LastLine+1), new DomReturnType ())); + members.Add (new DomProperty (child.Name, Modifiers.None, new DomLocation (child.SourceReferences[0].FirstLine, 1), new DomRegion (child.SourceReferences[0].FirstLine, int.MaxValue, child.SourceReferences[0].LastLine, int.MaxValue), new DomReturnType ())); break; case "field": - members.Add (new DomField (child.Name, Modifiers.None, new DomLocation (child.FirstLine, 1), new DomReturnType ())); + case "constant": + case "errorcode": + members.Add (new DomField (child.Name, Modifiers.None, new DomLocation (child.SourceReferences[0].FirstLine, 1), new DomReturnType ())); break; case "signal": - members.Add (new DomEvent (child.Name, Modifiers.None, new DomLocation (child.FirstLine, 1), new DomReturnType ())); + members.Add (new DomEvent (child.Name, Modifiers.None, new DomLocation (child.SourceReferences[0].FirstLine, 1), new DomReturnType ())); break; default: - Console.WriteLine("Unsupported member type: {0}", child.NodeType); + MonoDevelop.Core.LoggingService.LogDebug ("ValaDocumentParser: Unsupported member type: {0}", child.SymbolType); break; }// Switch on node type }// Collect members - cu.Add (new DomType (new CompilationUnit (fileName), ClassType.Class, node.Name, new DomLocation (node.FirstLine, 1), string.Empty, new DomRegion (node.FirstLine+1, lastLine+1), members)); + cu.Add (new DomType (new CompilationUnit (fileName), ClassType.Class, node.Name, new DomLocation (node.SourceReferences[0].FirstLine, 1), string.Empty, new DomRegion (node.SourceReferences[0].FirstLine, int.MaxValue, lastLine, int.MaxValue), members)); }// Add each class in file - return doc; + return (lastGood = doc); }// Parse }// ValaDocumentParser } diff --git a/extras/ValaBinding/ValaBinding.csproj b/extras/ValaBinding/ValaBinding.csproj index 2d6b5c6e69..6d1f5aeafe 100644 --- a/extras/ValaBinding/ValaBinding.csproj +++ b/extras/ValaBinding/ValaBinding.csproj @@ -238,10 +238,9 @@ <Compile Include="ProjectPad\ProjectNodeExtension.cs" /> <Compile Include="AssemblyInfo.cs" /> <Compile Include="Project\MakefileHandler.cs" /> - <Compile Include="Parser\CodeNode.cs" /> + <Compile Include="Parser\Afrodite.cs" /> <Compile Include="Navigation\LanguageItemNodeBuilder.cs" /> <Compile Include="Navigation\ProjectNodeBuilderExtension.cs" /> - <Compile Include="Parser\Function.cs" /> <Compile Include="Parser\ValaDocumentParser.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> @@ -261,4 +260,4 @@ </Properties> </MonoDevelop> </ProjectExtensions> -</Project>
\ No newline at end of file +</Project> |