Registering a PSI Language
Once a custom language's file type has been registered with the Project Model, the language definition needs to be registered with the PSI. If it's not registered with the PSI, ReSharper will not be able to build a PSI tree, and in fact will not consider it registered with the Project Model, either.
The PSI maintains a hierarchy of supported languages, in a similar manner to how the Project Model maintains a hierarchy of supported file types. The base class is
PsiLanguageType, and there are again, two directly derived classes -
UnknownLanguage. The first is the base class for all known languages, and can be used to mean any and all known PSI languages. The second,
UnknownLanguage, is a sealed class, and represents a language that the PSI does not support.
A custom language should create a class that derives from
KnownLanguage, or a suitable base class (for example, if your language is a subset of HTML, such as a
.aspx file, you can derive from
HtmlLanguage). The custom class should provide a programmatic name and a presentable name, and it should be marked with the
[LanguageDefinition(...)] attribute. For example, C#:
[LanguageDefinition] attribute passes in the programmatic name. It also supports an
Edition property, which is no longer used. This is a legacy feature to allow languages to be disabled based on which edition of the product has been purchased. This functionality has been replaced by Zones.
Each node in the PSI tree exposes its owning language via the
ITreeNode.Language property, which returns an instance of
Languages are instantiated by the
ILanguages shell component, which will create the class using the default constructor, and set the static
Instance field, meaning all language definitions are singletons.
ILanguages interface also provides the means to retrieve and enumerate all language definitions.