
We’ve been hard at work over the past several weeks on the SyntaxEditor .NET Languages Add-on, for both the WPF and Silverlight platforms. In the SyntaxEditor 2011.1 release (previously described in this post), we added the first phase of the add-on, which includes multi-threaded parsing, AST construction, syntax error reporting, and automatic outlining for C# and VB code.
The next phase of the add-on is to work on the core pieces needed to support automated IntelliPrompt, as our end goal is to have it working very similarly to Visual Studio 2010’s code editor for C# and VB.
In today’s post, we’ll walk through an overview of what we need working to support automated IntelliPrompt features.
Reflection Database
The first piece is a complete reflection database that can examine binary assemblies as well as source files, and can create a repository of reflection data that supports fast lookup for namespaces, types, members, etc.
There are two types of assemblies: project assemblies and binary assemblies.
Project assemblies are analogous to Visual Studio projects. They have a collection of source files with related compilation unit reflection data, and can reference zero to many other assemblies. Referenced assemblies can be other project assemblies or binary assemblies.
Binary assemblies are loaded from real binary assembly instances, and reflection data for their contained type definitions is read from them.
Exactly one project assembly must be associated with each CSharpSyntaxLanguage or VBSyntaxLanguage instance as a service. Thus as a document is changed that uses the language, its compilation unit parse results can be merged into the project assembly’s reflection data so that it is available for querying later on by the resolver.
Context Factory
The next piece that is needed is a context factory, one specific to each language. This object takes an offset and uses language-specific rules to examine the tokens around the offset, along with the document’s AST, to figure out what is going on at the offset.
It is tasked with creating a context object that provides these details back to the factory’s caller.
Project Assembly Resolver
Each project assembly has a resolver object associated with it that can examine context information into a namespace, type definition, member definition, etc.
The resolver has to use extremely complex logic per the C# and VB specs to appropriately resolve identifiers and sequences of identifiers.
Automated IntelliPrompt Processing
At a very high level, automated IntelliPrompt features will work like this:
- A request is made for automated IntelliPrompt. This could be quick info, completion, etc.
- The IntelliPrompt provider on the language requests a “context” object for a certain text offset that is related to where the automated IntelliPrompt will show.
- A context factory object answers the request and returns some general contextual information about the offset.
- The IntelliPrompt provider takes this context and uses the current project assembly’s resolver to figure out exactly what the context refers to. The resolver result could be something defined in the project assembly, or could be something defined in a referenced assembly.
- If the resolution succeeds, the IntelliPrompt provider can populate its UI appropriately and show it. For quick info, it would show a tooltip detailing the resolved result. For completion lists, it would take the resolved result, and add items into its list that are accessible from the resolved result, such as members.
Next Steps
We already have a lot of code written for some of these features, but there’s still quite a way to go. We’re continuing to plug away at it every day and should be able to show some preliminary screens soon. We also will try and give some more details about the various new feature areas in upcoming posts. Stay tuned!