[Monodevelop-devel] Working on the monodevelop dom after 2.2

Lluis Sanchez Gual lluis at novell.com
Wed Sep 30 18:08:39 EDT 2009

El dt 29 de 09 de 2009 a les 13:19 +0200, en/na Mike Krüger va
> Hi
> > I feel there is some misunderstanding here. If we introduce a new set of
> > INew* interfaces we'll certainly have to track the changes in
> > MethodNodeBuilder and all the builders. And those changes will include
> > rendering child nodes, since any node can have child nodes.
> > 
> Don't solve the case, where the DOM goes deeper than methods. 

I don't know why you say that. If an IMethod is an INode, and an INode
can have child INodes. MethodNodeBuilder can be a subclass of
INodeBuilder, which by default renders child INodes.

> I'm sure
> you're coming up with an interface: IClassBrowserProvider { bool
> IncludeInClassBrowser { get; }} that 'just' needs to be provided for
> every dom. 
> The class browser works better when non .NET languages don't re-use our
> DOM, if they use their own one they can add their node builders to the
> class browser and the thing works.

Agreed, in this case using node builders bound to the particular
language dom is an easy solution.

> > > 
> > > Quick Member navigation - it's not so easy to set the rules:
> > > 
> > > 'showing first level items of the file' means:
> > > + Showing only the namespaces -> no containing types (they're first
> > > level, and will be part of the DOM as nodes)
> > > + Don't show inner types (they're second level at best)
> > > 
> > > 'children of the active first level item' means:
> > > + Show the current inner type (should be in the type selector).
> > > + Show the current statement, if the DOM is extended and more specific
> > > than the monodevelop DOM.
> > 
> > This has a very simple solution:
> > 
> > interface IQuickMemberNavigationProvider
> > {
> > 	IEnumerable<INode> GetTypes ();
> > 	IEnumerable<INode> GetMembers (INode type);
> > }
> > 
> > to be implemented by language bindings.
> > 
> Doesn't solve the issue with more than one panel or three panels. 

It does solve the problems you asked for.

> You
> need something like:
> interface IQuickMemberNavigationProvider
> {
> 	IEnumerable<IQuickNavigationPanel> GetPanels ();
> }
> -> then the quick navigation code has nothing to do with any dom. 

Agreed, that's the most generic solution (well, the most generic would
be just returning a gtk.widget).

In any case we can have both interfaces. The first interface could be
used by language bindings which don't want to implement its own custom
panel. MD would use the default panel in this case, filling the data
retrieved from the interface. Language bindings with more advanced needs
could implement the second interface and provide a full custom set of

The Properties Pad already works in this way. You can implement
IPropertyPadProvider, which has a GetActiveComponent() method. When
using this interface, MD will create a standard PropertyGrid and fill it
up with the data of the active component (retrieved using the
System.ComponentModel classes). On the other hand, you can implement
ICustomPropertyPadProvider, which has a GetCustomPropertyWidget(). When
finding this interface, MD will just create the custom widget and embed
it in the properties pad, replacing the default property grid.

> > > 
> > > btw. another thing: All pads/output function currently build on ambience
> > > flags - but for other languages there may be different sets of flags
> > > required for displaying the information at that point. 
> > > 
> > > > Yes, that's currently possible (with some tweaks). But it means that the
> > > > language has to implement all the DOM interfaces: IField, IMethod,
> > > > IType, etc, which are full of .NET specific stuff. Yes, you can just
> > > > throw NotSupportedException of all .NET specific methods and properties,
> > > > but that's just unnecessary bloat. If anything, it would be better to
> > > > have:
> > > 
> > > We've classes that implement the interfaces, no .NET specific
> > > implementation is required. But the other thing is that a new languages
> > > now would ALWAYS require to implement all DOM interfaces that are full
> > > of .NET specific stuff. (ok could use the same base class)
> > > You've still not told how to display a VB output, Boo output and c#
> > > output of a reflection source when putting the output code inside the
> > > DOM objects. I think that's not easily possible.
> > 
> > I showed it some posts ago:
> > 
> > class DomField: IMember, INewField
> > {
> >         public string GetDescription (SomeContext ctx)
> >         {
> >                 return ctx.Ambience.GetString (this, ctx.AmbienceOptions);
> >         }
> >         ...
> > }
> Doesn't solve what I'm describing, because it doesn't solve the problem
> for the reflection source. Or you're saying that we use a same set of
> classes for every .NET language - that is what we currently have. 

Yes, that's what I've been saying since the beginning. The current DOM
is OK for .NET languages and I'm not proposing the change it. I just
proposed creating a higher level set of interfaces (which would not
replace the ones we have now, only complement them). Those interfaces
would allow using the current set of navigation/information widgets
without having to use the .NET specific DOM.

> You're coming up with a design that isn't better than the thing we
> already have, it's just the same. The discussion is about visitors vs.
> member methods - this is pointless.

No, this is not the discussion. I hope my previous paragraph clarifies

> > I think we have to look at this case by case. For the tooltip case,
> > maybe this is enough:
> > 
> > interface ITooltipProvider
> > {
> > 	string GetMarkup (INode node);
> > }
> > 
> > to be implemented in every non-.net language binding.
> > 
> Just another DOM extender interface - you see the design gets more and
> more complicated this way ? It's generally not possible to handle every
> possible language output/model in a single GetString() - you'll get
> scaling problems. If you try this you basically come up with:
> INode { 
> 	GetDescription (CaseEnum, SomeContext ctx); 
> }
> CaseEnum { CompletionList, CompletionListTooltip, ParameterTooltip,
> ParameterDescription, ClassBrowser, QuickNavigationList, ... }
> SomeContext { ... } 
> ClassBrowserContext : SomeContext { ... }
> CompletionContext : SomeContext { ... }
> ParameterListContext : SomeContext { ... } 
> ...
> Is that really an option ? What are the others saying ? (The problem
> will be adding new controls that display DOM stuff - currently we've a
> set of display options where the controls choose from).

The problem is that those display options are .NET specific:
UseFullName, IncludeBaseTypes, IncludeGenerics, HideArrayBrackets,
HideExtensionsParameter, UseNETTypeNames, UseFullInnerTypeName.

So, a non-.net language won't make any use of those properties, and it
will have a hard time figuring out which information to show. On the
other hand, there is no doubt about how to implement ITooltipProvider:
it is very clear that the markup is going to be used to show a tooltip
to the user, so the language can decide what needs to be shown.

I'm not saying however that ITooltipProvider is the best solution, it
was just an example of high level interface which could be used to avoid
a DOM dependency.

> > > 
> > > I tend to make the monodevelop DOM stuff .NET dependent in the type
> > > model, generalize the object model so that other .NET languages can be
> > > supported that are more far from C#/VB.NET and have a way to do
> > > something like the IOutlinedDocument for each component. I don't want to
> > > make the life harder for .NET language implementors when the non .NET
> > > language implementors get little to no gain (See above - they need to
> > > implement their own widgets/infrastructure - regardless of what we try,
> > > more worse they can run into dead ends when trying to re-use the
> > > monodevelop DOM - see the class output pad method example).
> > 
> > No, what I'm proposing does not involve implementing additional
> > widgets/infrastructure. See above.
> > 
> But to change every widget/infrastructure with an interface that may not
> work for the case the language implementor needs, doesn't add
> functionality and makes the life more difficult implementing standard
> language bindings isn't a solution.
> Again what I wanted:
> Extend the MD DOM to make it EASIER to implement .NET based languages -
> and MAYBE being able to map non .NET languages to it. I don't intend to 
> make anything HARDER to implement for .NET languages.

And I'm OK with that. Now, what I want is to make it EASIER to implement
non .NET languages, without making it HARDER to implement the .NET
languages (no changes should be required in the existing .NET language
bindings). That's the whole point of my proposal.

> What I learned from our discussion:
> a) Don't provide too much infrastructure for trees you don't yet know
> how they look like.
> b) Make every component of monodevelop extendable without sticking to a
> specific DOM - provide defaults for the .NET based DOM.

Agreed. The document outline component is a good example of this. I
think however that there must be a middle-ground solution between
getting the document outline automatically filled from the .NET DOM
(using the default component), and having to write your custom widget
from scratch. I'd like to make it easier to support non .net languages
by providing this kind of middle-ground solution (whatever it is).


More information about the Monodevelop-devel-list mailing list