[Monodevelop-devel] Rethinking the IDocumentMetaInformation

Michael Hutchinson m.j.hutchinson at gmail.com
Wed Sep 10 00:24:27 EDT 2008

Hi all,

I'm confused about the purpose of the IDocumentMetaInformation. I
think it exists because I once complained that I had to implement a
LanguageBinding simply to add code folding and error underlining. My
exact complaint was that I had to use an ICompilationUnit to mark
folding region and errors, and that it contained a lot of
.NET-specific information which my parser didn't need to populate.
However, I did implement the language binding for ASP.NET and it works
fine, and adding a parser is easier in the C# 3 branch...

The IDocumentMetaInformation is confusing; it does not fix the
original problem at all. It's worse -- it requires a second parse and
isn't stored is a publicly shared location, so has to be reparsed by
e.g. the document outline provider, which requires the #region
locations. Also, the source editor only parses an
IDocumentMetaInformation when a CompilationUnit appears, so a
CompilationUnit still has to be generated by the parser in order for
the IDocumentMetaInformation to be used!

I have some suggestions for a solution, which will also solve a few of
the issue the C/C++ addin had when implementing a parser
scheduler/notofication system. It will hopefully make it easier to add
other parses in the future.

I suggest we have the IParser instead return an IParsedDocument, which
would be very generic, with the basic info used by the text editor:

  string FileName;
  DateTime ParseTime { get; }
  IEnumerable<Fold> GetFoldLocations ();   // expected to iterate over
types, comments etc and generate folds
  ICollection<Error> Errors { get; } // also warnings
  bool HasErrors { get; }

There would then be an ICompilationUnit derived interface, with
generic info for things like the quick finder and document outline.

ICompilationUnit : IParsedDocument
  ICollection<IDisplayType> Types { get; }
  ICollection<IDisplayMember> GlobalMembers { get; }
  IEnumerable<Comment> Comments { get; }

The .NET info would be in the derived ICompilationUnit, and would be
returned by .NET parsers:

IDotNetCompilationUnit : ICompilationUnit
  ICollection<IUsing> Usings { get; }
  ICollection<IAttribute> Attributes { get; }
  ICollection<IType> Classes { get; }   // foreach (IBaseType t in
Types) yield return (IType) t;
  ICollection<Coderegion> CodeRegions { get; }   //#regions

I could implement an AspNetDocument : IParsedDocument. The C/C++
parser could return a CCompilationUnit : ICompilationUnit.

Even better, this moves some generic logic out of the SourceEditor2,
so that the compilationunit / parseddocument could control the fold
locations, i.e. GetFoldLocations () would generate regions by
iterating over the members, classes, comments, C #regions, etc. Other
such things should be implemented in a similar manner rather than
being in SourceEditor2, so that it's easier to implement other
editors. This is also, perhaps, a step being able to store and query
C/C++ (ad other non-.NET languages) type information effectively in
the pidb system.

Does this sound like a good plan? Should I implement it? Any suggested
changes to the above interfaces, in order to work better with other

Michael Hutchinson

More information about the Monodevelop-devel-list mailing list