public virtual void DoUpdateFileTags(MonoDevelop.Projects.Project project, string filename, IEnumerable <string> headers) { ProjectInformation info = ProjectInformationManager.Instance.Get(project); lock (info) { info.RemoveFileInfo(filename); IEnumerable <string> tags = GetTags(project, filename, headers); if (tags == null) { return; } foreach (string tagEntry in tags) { if (tagEntry.StartsWith("!_")) { continue; } Tag tag = ParseTag(tagEntry); if (tag != null) { AddInfo(info, tag, tagEntry); } } } }
/// <summary> /// Remove a file's parse information from the database. /// </summary> /// <param name="project"> /// A <see cref="Project"/>: The project to which the file belongs. /// </param> /// <param name="filename"> /// A <see cref="System.String"/>: The file. /// </param> public void RemoveFileInfo(Project project, string filename) { ProjectInformation info = ProjectInformationManager.Instance.Get(project); lock (info){ info.RemoveFileInfo(filename); } OnFileUpdated(new ClassPadEventArgs(project)); }
static IUnresolvedMethod FunctionToIMethod(ProjectInformation pi, IUnresolvedTypeDefinition type, Function function, string[] contentLines) { var method = new DefaultUnresolvedMethod(type, function.Name); method.Region = new DomRegion((int)function.Line, 1, FindFunctionEnd(contentLines, (int)function.Line - 1) + 2, 1); Match match; bool abort = false; var parameters = new List <IUnresolvedParameter> (); foreach (string parameter in function.Parameters) { match = paramExpression.Match(parameter); if (null == match) { abort = true; break; } var typeRef = new DefaultUnresolvedTypeDefinition(string.Format("{0}{1}{2}", match.Groups["type"].Value, match.Groups["subtype"].Value, match.Groups["array"].Value)); var p = new DefaultUnresolvedParameter(typeRef, match.Groups["name"].Value); parameters.Add(p); } if (!abort) { parameters.ForEach(p => method.Parameters.Add(p)); } return(method); }
/// <summary> /// Create an IMember from a LanguageItem, /// using the source document to locate declaration bounds. /// </summary> /// <param name="pi"> /// A <see cref="ProjectInformation"/> for the current project. /// </param> /// <param name="item"> /// A <see cref="LanguageItem"/>: The item to convert. /// </param> /// <param name="contentLines"> /// A <see cref="System.String[]"/>: The document in which item is defined. /// </param> static IMember LanguageItemToIMember(ProjectInformation pi, LanguageItem item, string[] contentLines) { if (item is Class || item is Structure) { DomType klass = new DomType(new CompilationUnit(item.File), ClassType.Class, item.Name, new DomLocation((int)item.Line, 1), string.Empty, new DomRegion((int)item.Line + 1, FindFunctionEnd(contentLines, (int)item.Line - 1) + 2), new List <IMember> ()); foreach (LanguageItem li in pi.AllItems()) { if (klass.Equals(li.Parent) && FilePath.Equals(li.File, item.File)) { klass.Add(LanguageItemToIMember(pi, li, contentLines)); } } return(klass); } if (item is Enumeration) { return(new DomType(new CompilationUnit(item.File), ClassType.Enum, item.Name, new DomLocation((int)item.Line, 1), string.Empty, new DomRegion((int)item.Line + 1, (int)item.Line + 1), new List <IMember> ())); } if (item is Function) { return(new DomMethod(item.Name, Modifiers.None, MethodModifier.None, new DomLocation((int)item.Line, 1), new DomRegion((int)item.Line + 1, FindFunctionEnd(contentLines, (int)item.Line - 1) + 2), new DomReturnType())); } if (item is Member) { return(new DomField(item.Name, Modifiers.None, new DomLocation((int)item.Line, 1), new DomReturnType())); } return(null); }
public ProjectInformation Get (Project project) { foreach (ProjectInformation p in projects) { if (project.Equals (p.Project)) { return p; } } ProjectInformation newinfo = new ProjectInformation (project); projects.Add (newinfo); return newinfo; }
/// <summary> /// Create an IMember from a LanguageItem, /// using the source document to locate declaration bounds. /// </summary> /// <param name="pi"> /// A <see cref="ProjectInformation"/> for the current project. /// </param> /// <param name="item"> /// A <see cref="LanguageItem"/>: The item to convert. /// </param> /// <param name="contentLines"> /// A <see cref="System.String[]"/>: The document in which item is defined. /// </param> static IMember LanguageItemToIMember(ProjectInformation pi, LanguageItem item, string[] contentLines) { if (item is Class || item is Structure) { DomType klass = new DomType(new CompilationUnit(item.File), ClassType.Class, item.Name, new DomLocation((int)item.Line, 1), string.Empty, new DomRegion((int)item.Line + 1, FindFunctionEnd(contentLines, (int)item.Line - 1) + 2), new List <IMember> ()); foreach (LanguageItem li in pi.AllItems()) { if (klass.Equals(li.Parent) && FilePath.Equals(li.File, item.File)) { klass.Add(LanguageItemToIMember(pi, li, contentLines)); } } return(klass); } if (item is Enumeration) { return(new DomType(new CompilationUnit(item.File), ClassType.Enum, item.Name, new DomLocation((int)item.Line, 1), string.Empty, new DomRegion((int)item.Line + 1, (int)item.Line + 1), new List <IMember> ())); } if (item is Function) { DomMethod method = new DomMethod(item.Name, Modifiers.None, MethodModifier.None, new DomLocation((int)item.Line, 1), new DomRegion((int)item.Line + 1, FindFunctionEnd(contentLines, (int)item.Line - 1) + 2), new DomReturnType()); Function function = (Function)item; Match match; bool abort = false; List <IParameter> parameters = new List <IParameter> (); foreach (string parameter in function.Parameters) { match = paramExpression.Match(parameter); if (null == match) { abort = true; break; } DomParameter p = (new DomParameter(method, match.Groups["name"].Value, new DomReturnType(string.Format("{0}{1}{2}", match.Groups["type"].Value, match.Groups["subtype"].Value, match.Groups["array"].Value)))); parameters.Add(p); } if (!abort) { method.Add(parameters); } return(method); } if (item is Member) { return(new DomField(item.Name, Modifiers.None, new DomLocation((int)item.Line, 1), new DomReturnType())); } return(null); }
} // CanParse public override ParsedDocument Parse(ProjectDom dom, string fileName, string content) { ParsedDocument doc = new ParsedDocument(fileName); doc.Flags |= ParsedDocumentFlags.NonSerializable; Project p = (null == dom || null == dom.Project)? IdeApp.Workspace.GetProjectContainingFile(fileName): dom.Project; ProjectInformation pi = ProjectInformationManager.Instance.Get(p); CompilationUnit cu; doc.CompilationUnit = cu = new CompilationUnit(fileName); IType tmp; IMember member; string[] contentLines = content.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); DomType globals = new DomType(cu, ClassType.Unknown, GettextCatalog.GetString("(Global Scope)"), new DomLocation(1, 1), string.Empty, new DomRegion(1, int.MaxValue), new List <IMember> ()); lock (pi) { // Add containers to type list foreach (LanguageItem li in pi.Containers()) { if (null == li.Parent && FilePath.Equals(li.File, fileName)) { tmp = LanguageItemToIMember(pi, li, contentLines) as IType; if (null != tmp) { cu.Add(tmp); } } } // Add global category for unscoped symbols foreach (LanguageItem li in pi.InstanceMembers()) { if (null == li.Parent && FilePath.Equals(li.File, fileName)) { member = LanguageItemToIMember(pi, li, contentLines); if (null != member) { globals.Add(member); } } } } cu.Add(globals); return(doc); }
public ProjectInformation Get(Project project) { foreach (ProjectInformation p in projects) { if (project.Equals(p.Project)) { return(p); } } ProjectInformation newinfo = new ProjectInformation(project); projects.Add(newinfo); return(newinfo); }
private void UpdateSystemTags(Project project, string filename, IEnumerable <string> includedFiles) { if (!DepsInstalled) { return; } ProjectInformation info = ProjectInformationManager.Instance.Get(project); List <FileInformation> files; lock (info) { if (!info.IncludedFiles.ContainsKey(filename)) { files = new List <FileInformation> (); info.IncludedFiles.Add(filename, files); } else { files = info.IncludedFiles[filename]; } foreach (string includedFile in includedFiles) { bool contains = false; foreach (FileInformation fi in files) { if (fi.FileName == includedFile) { contains = true; } } if (!contains) { FileInformation newFileInfo = new FileInformation(project, includedFile); files.Add(newFileInfo); ctags.FillFileInformation(newFileInfo); } contains = false; } } }
public void UpdateFileTags(Project project, string filename) { string[] headers = Headers(filename, false); string ctags_options = "--C++-kinds=+p+u --fields=+a-f+S --language-force=C++ --excmd=pattern -f - " + filename + " " + string.Join(" ", headers); string[] system_headers = diff(Headers(filename, true), headers); ProcessWrapper p; try { p = Runtime.ProcessService.StartProcess("ctags", ctags_options, null, null); p.WaitForExit(); } catch (Exception ex) { throw new IOException("Could not create tags database (You must have exuberant ctags installed).", ex); } ProjectInformation info = ProjectInformationManager.Instance.Get(project); string tagEntry; string ctags_output = p.StandardOutput.ReadToEnd(); p.Close(); using (StringReader reader = new StringReader(ctags_output)) { while ((tagEntry = reader.ReadLine()) != null) { if (tagEntry.StartsWith("!_")) { continue; } Tag tag = ParseTag(tagEntry); AddInfo(info, tag, ctags_output); } } FileUpdated(new ClassPadEventArgs(project)); UpdateSystemTags(project, filename, system_headers); }
static object AddLanguageItem(ProjectInformation pi, DefaultUnresolvedTypeDefinition klass, LanguageItem li, string[] contentLines) { if (li is Class || li is Structure || li is Enumeration) { var type = LanguageItemToIType(pi, li, contentLines); klass.NestedTypes.Add(type); return(type); } if (li is Function) { var method = FunctionToIMethod(pi, klass, (Function)li, contentLines); klass.Members.Add(method); return(method); } var field = LanguageItemToIField(klass, li, contentLines); klass.Members.Add(field); return(field); }
public override ParsedDocument Parse(bool storeAst, string fileName, TextReader reader, Project project = null) { var doc = new DefaultParsedDocument(fileName); doc.Flags |= ParsedDocumentFlags.NonSerializable; ProjectInformation pi = ProjectInformationManager.Instance.Get(project); string content = reader.ReadToEnd(); string[] contentLines = content.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); var globals = new DefaultUnresolvedTypeDefinition("", GettextCatalog.GetString("(Global Scope)")); lock (pi) { // Add containers to type list foreach (LanguageItem li in pi.Containers()) { if (null == li.Parent && FilePath.Equals(li.File, fileName)) { var tmp = AddLanguageItem(pi, globals, li, contentLines) as IUnresolvedTypeDefinition; if (null != tmp) { doc.TopLevelTypeDefinitions.Add(tmp); } } } // Add global category for unscoped symbols foreach (LanguageItem li in pi.InstanceMembers()) { if (null == li.Parent && FilePath.Equals(li.File, fileName)) { AddLanguageItem(pi, globals, li, contentLines); } } } doc.TopLevelTypeDefinitions.Add(globals); return(doc); }
public ParameterDataProvider (Document document, ProjectInformation info, string functionName) { this.editor = document.Editor; foreach (Function f in info.Functions) { if (f.Name == functionName) { functions.Add (f); } } string currentFile = document.FileName; if (info.IncludedFiles.ContainsKey (currentFile)) { foreach (CBinding.Parser.FileInformation fi in info.IncludedFiles[currentFile]) { foreach (Function f in fi.Functions) { if (f.Name == functionName) { functions.Add (f); } } } } }
public ParameterDataProvider (int startOffset, TextEditor editor, ProjectInformation info, string functionName) :base (startOffset) { this.editor = editor; foreach (Function f in info.Functions) { if (f.Name == functionName) { data.Add (new DataWrapper (f)); } } string currentFile = editor.FileName; if (info.IncludedFiles.ContainsKey (currentFile)) { foreach (CBinding.Parser.FileInformation fi in info.IncludedFiles[currentFile]) { foreach (Function f in fi.Functions) { if (f.Name == functionName) { data.Add (new DataWrapper (f)); } } } } }
public override System.Threading.Tasks.Task <ParsedDocument> Parse(ParseOptions options, System.Threading.CancellationToken cancellationToken) { var fileName = options.FileName; var project = options.Project; var doc = new DefaultParsedDocument(fileName); doc.Flags |= ParsedDocumentFlags.NonSerializable; ProjectInformation pi = ProjectInformationManager.Instance.Get(project); string content = options.Content.Text; string[] contentLines = content.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); var globals = new DefaultUnresolvedTypeDefinition("", GettextCatalog.GetString("(Global Scope)")); lock (pi) { // Add containers to type list foreach (LanguageItem li in pi.Containers()) { if (null == li.Parent && FilePath.Equals(li.File, fileName)) { var tmp = AddLanguageItem(pi, globals, li, contentLines) as IUnresolvedTypeDefinition; if (null != tmp) /*doc.TopLevelTypeDefinitions.Add (tmp);*/ } { } } // Add global category for unscoped symbols foreach (LanguageItem li in pi.InstanceMembers()) { if (null == li.Parent && FilePath.Equals(li.File, fileName)) { AddLanguageItem(pi, globals, li, contentLines); } } } //doc.TopLevelTypeDefinitions.Add (globals); return(System.Threading.Tasks.Task.FromResult((ParsedDocument)doc)); }
/// <summary> /// Create an IMember from a LanguageItem, /// using the source document to locate declaration bounds. /// </summary> /// <param name="pi"> /// A <see cref="ProjectInformation"/> for the current project. /// </param> /// <param name="item"> /// A <see cref="LanguageItem"/>: The item to convert. /// </param> /// <param name="contentLines"> /// A <see cref="System.String[]"/>: The document in which item is defined. /// </param> static DefaultUnresolvedTypeDefinition LanguageItemToIType(ProjectInformation pi, LanguageItem item, string[] contentLines) { var klass = new DefaultUnresolvedTypeDefinition("", item.File); if (item is Class || item is Structure) { klass.Region = new DomRegion((int)item.Line, 1, FindFunctionEnd(contentLines, (int)item.Line - 1) + 2, 1); klass.Kind = item is Class ? TypeKind.Class : TypeKind.Struct; foreach (LanguageItem li in pi.AllItems()) { if (klass.Equals(li.Parent) && FilePath.Equals(li.File, item.File)) { AddLanguageItem(pi, klass, li, contentLines); } } return(klass); } klass.Region = new DomRegion((int)item.Line, 1, (int)item.Line + 1, 1); klass.Kind = TypeKind.Enum; return(klass); }
/// <summary> /// Create an IMember from a LanguageItem, /// using the source document to locate declaration bounds. /// </summary> /// <param name="pi"> /// A <see cref="ProjectInformation"/> for the current project. /// </param> /// <param name="item"> /// A <see cref="LanguageItem"/>: The item to convert. /// </param> /// <param name="contentLines"> /// A <see cref="System.String[]"/>: The document in which item is defined. /// </param> static DefaultUnresolvedTypeDefinition LanguageItemToIType (ProjectInformation pi, LanguageItem item, string[] contentLines) { var klass = new DefaultUnresolvedTypeDefinition ("", item.File); if (item is Class || item is Structure) { klass.Region = new DomRegion ((int)item.Line, 1, FindFunctionEnd (contentLines, (int)item.Line-1) + 2, 1); klass.Kind = item is Class ? TypeKind.Class : TypeKind.Struct; foreach (LanguageItem li in pi.AllItems ()) { if (klass.Equals (li.Parent) && FilePath.Equals (li.File, item.File)) AddLanguageItem (pi, klass, li, contentLines); } return klass; } klass.Region = new DomRegion ((int)item.Line, 1, (int)item.Line + 1, 1); klass.Kind = TypeKind.Enum; return klass; }
/// <summary> /// Create an IMember from a LanguageItem, /// using the source document to locate declaration bounds. /// </summary> /// <param name="pi"> /// A <see cref="ProjectInformation"/> for the current project. /// </param> /// <param name="item"> /// A <see cref="LanguageItem"/>: The item to convert. /// </param> /// <param name="contentLines"> /// A <see cref="System.String[]"/>: The document in which item is defined. /// </param> static IMember LanguageItemToIMember (ProjectInformation pi, LanguageItem item, string[] contentLines) { if (item is Class || item is Structure) { DomType klass = new DomType (new CompilationUnit (item.File), ClassType.Class, item.Name, new DomLocation ((int)item.Line, 1), string.Empty, new DomRegion ((int)item.Line+1, FindFunctionEnd (contentLines, (int)item.Line-1)+2), new List<IMember> ()); foreach (LanguageItem li in pi.AllItems ()) { if (klass.Equals (li.Parent) && FilePath.Equals (li.File, item.File)) { klass.Add (LanguageItemToIMember (pi, li, contentLines)); } } return klass; } if (item is Enumeration) { return new DomType (new CompilationUnit (item.File), ClassType.Enum, item.Name, new DomLocation ((int)item.Line, 1), string.Empty, new DomRegion ((int)item.Line+1, (int)item.Line+1), new List<IMember> ()); } if (item is Function) { return new DomMethod (item.Name, Modifiers.None, MethodModifier.None, new DomLocation ((int)item.Line, 1), new DomRegion ((int)item.Line+1, FindFunctionEnd (contentLines, (int)item.Line-1)+2), new DomReturnType ()); } if (item is Member) { return new DomField (item.Name, Modifiers.None, new DomLocation ((int)item.Line, 1), new DomReturnType ()); } return null; }
private void DoUpdateFileTags(Project project, string filename) { if (!DepsInstalled) { return; } string[] headers = Headers(project, filename, false); string[] system_headers = diff(Headers(project, filename, true), headers); StringBuilder ctags_kinds = new StringBuilder("--C++-kinds=+px"); if (PropertyService.Get <bool> ("CBinding.ParseLocalVariables", true)) { ctags_kinds.Append("+l"); } // Maybe we should only ask for locals for 'local' files? (not external #includes?) ctags_kinds.AppendFormat(" --fields=+aStisk-fz --language-force=C++ --excmd=number --line-directives=yes -f - '{0}'", filename); foreach (string header in headers) { ctags_kinds.AppendFormat(" '{0}'", header); } string ctags_output = string.Empty; ProcessWrapper p = null; System.IO.StringWriter output = null, error = null; try { output = new System.IO.StringWriter(); error = new System.IO.StringWriter(); p = Runtime.ProcessService.StartProcess("ctags", ctags_kinds.ToString(), project.BaseDirectory, output, error, null); p.WaitForOutput(10000); if (p.ExitCode != 0) { LoggingService.LogError("Ctags did not successfully populate the tags database from '{0}' within ten seconds.\nError output: {1}", filename, error.ToString()); return; } ctags_output = output.ToString(); } catch (Exception ex) { throw new IOException("Could not create tags database (You must have exuberant ctags installed).", ex); } finally { if (output != null) { output.Dispose(); } if (error != null) { error.Dispose(); } if (p != null) { p.Dispose(); } } ProjectInformation info = ProjectInformationManager.Instance.Get(project); lock (info) { info.RemoveFileInfo(filename); string tagEntry; using (StringReader reader = new StringReader(ctags_output)) { while ((tagEntry = reader.ReadLine()) != null) { if (tagEntry.StartsWith("!_")) { continue; } Tag tag = ParseTag(tagEntry); if (tag != null) { AddInfo(info, tag, ctags_output); } } } } OnFileUpdated(new ClassPadEventArgs(project)); if (PropertyService.Get <bool> ("CBinding.ParseSystemTags", true)) { UpdateSystemTags(project, filename, system_headers); } if (cache.Count > cache_size) { cache.Clear(); } }
static object AddLanguageItem (ProjectInformation pi, DefaultUnresolvedTypeDefinition klass, LanguageItem li, string[] contentLines) { if (li is Class || li is Structure || li is Enumeration) { var type = LanguageItemToIType (pi, li, contentLines); klass.NestedTypes.Add (type); return type; } if (li is Function) { var method = FunctionToIMethod (pi, klass, (Function)li, contentLines); klass.Members.Add (method); return method; } var field = LanguageItemToIField (klass, li, contentLines); klass.Members.Add (field); return field; }
static IUnresolvedMethod FunctionToIMethod (ProjectInformation pi, IUnresolvedTypeDefinition type, Function function, string[] contentLines) { var method = new DefaultUnresolvedMethod (type, function.Name); method.Region = new DomRegion ((int)function.Line, 1, FindFunctionEnd (contentLines, (int)function.Line-1)+2, 1); Match match; bool abort = false; var parameters = new List<IUnresolvedParameter> (); foreach (string parameter in function.Parameters) { match = paramExpression.Match (parameter); if (null == match) { abort = true; break; } var typeRef = new DefaultUnresolvedTypeDefinition (string.Format ("{0}{1}{2}", match.Groups["type"].Value, match.Groups["subtype"].Value, match.Groups["array"].Value)); var p = new DefaultUnresolvedParameter (typeRef, match.Groups["name"].Value); parameters.Add (p); } if (!abort) parameters.ForEach (p => method.Parameters.Add (p)); return method; }
/// <summary> /// Create an IMember from a LanguageItem, /// using the source document to locate declaration bounds. /// </summary> /// <param name="pi"> /// A <see cref="ProjectInformation"/> for the current project. /// </param> /// <param name="item"> /// A <see cref="LanguageItem"/>: The item to convert. /// </param> /// <param name="contentLines"> /// A <see cref="System.String[]"/>: The document in which item is defined. /// </param> static IMember LanguageItemToIMember (ProjectInformation pi, LanguageItem item, string[] contentLines) { if (item is Class || item is Structure) { DomType klass = new DomType (new CompilationUnit (item.File), ClassType.Class, item.Name, new DomLocation ((int)item.Line, 1), string.Empty, new DomRegion ((int)item.Line+1, FindFunctionEnd (contentLines, (int)item.Line-1)+2), new List<IMember> ()); foreach (LanguageItem li in pi.AllItems ()) { if (klass.Equals (li.Parent) && FilePath.Equals (li.File, item.File)) { klass.Add (LanguageItemToIMember (pi, li, contentLines)); } } return klass; } if (item is Enumeration) { return new DomType (new CompilationUnit (item.File), ClassType.Enum, item.Name, new DomLocation ((int)item.Line, 1), string.Empty, new DomRegion ((int)item.Line+1, (int)item.Line+1), new List<IMember> ()); } if (item is Function) { DomMethod method = new DomMethod (item.Name, Modifiers.None, MethodModifier.None, new DomLocation ((int)item.Line, 1), new DomRegion ((int)item.Line+1, FindFunctionEnd (contentLines, (int)item.Line-1)+2), new DomReturnType ()); Function function = (Function)item; Match match; bool abort = false; List<IParameter> parameters = new List<IParameter> (); foreach (string parameter in function.Parameters) { match = paramExpression.Match (parameter); if (null == match) { abort = true; break; } DomParameter p = (new DomParameter (method, match.Groups["name"].Value, new DomReturnType (string.Format ("{0}{1}{2}", match.Groups["type"].Value, match.Groups["subtype"].Value, match.Groups["array"].Value)))); parameters.Add (p); } if (!abort) method.Add (parameters); return method; } if (item is Member) { return new DomField (item.Name, Modifiers.None, new DomLocation ((int)item.Line, 1), new DomReturnType ()); } return null; }