- Build Developer Tools Webinar
- Writing language plugins
- JetBrains Rider
Build Developer Tools Webinar
- Started as monolithic IDE
- Refactored over the years to modularize and introduce extension points
- Meta Programming System - IDE for domain specific language
- Uses IntelliJ IDEA’s overall UI framework
- Replaces text editing and PSI-based features with its own DSL framework
- Virtual file system, lexer, parser, PSI, references
- Action system
- UI framework: toolwindow, dialog…
- Text editor
- Language-independent implementations of core insight features
- Highlighting, navigation, completion, refactorings, code formatter
- Other Platform modules
- Local history
- Debugger framework
- Test runner framework
- VCS framework
- UI-less part of intellij IDEA’s java support
- Parser, reference resolution, inspections etc.
- Parsing, DTD/XML Schema, etc.
- DOM framework for XML-based DSLs
- Other Platform Extensions
- Images support
- Regular extensions support
- Community Edition Plugins
- Version control: Git, Mercurial, Subversion, CVS
- Build system: Ant, Maven, Gradle
- Tasks / issue tracker integration
- UI Designer
- Language IDEs: Haskell, Go, Lua, D, Perl, assembly, Verilog/VHDL
- Framework-specific IDEs
- Code analysis / exploration tools
- Game Development ?
Plugin vs. Product:
- Start with plugin in any case
- Product lets you remove what you don’t need, change what you don’t like
- Product gives you control over branding
- Both plugins and products can use commercial license
- Exception reporting
- Automatic updates and patches
- Plugin repository
- Usage statistics
- Tooling / Language / Framework / Extending UI…
- the IDE itself is a collection of plugins
- everything is a component
Writing language plugins
- lexing: usually a JFlex based parser
- hand-written recursive descent top-down parser
- needs to be fuzzy (allow for syntax erros with decent recovery)
- needs to output a “good” PSI tree
- or use GrammerKit
- additional tooling
- run configurations / debugging / etc
- a richer abstraction over the AST (abstract syntax tree) derived from a normal parser
- a good PSI tree will greatly help the inspections / refactorings implementation
- the interaction with the PSI nodes has specific semantics which should be explained more clearly
- Where is this name defined?
- is the name defined in more than one place? (MultiResolve)
- should this name always be defined?
- same mechanism as resolving except it will not return the definition but all the possible definitions
- based on the PSI structure
- does this node has all the required children defined?
- is it located under the proper node?
- using the resolving infrastructure
- is this name defined somewhere (if it is required by the language to be)?
- is this name defined multiple times when it shouldn’t be?
- basic naming issues
- rearrangements of the PSI nodes in the tree
- can be defined by inspections or they can be run standalone
- a way to change the PSI tree when you know the current structure
- Run configurations
- mostly independent of the PSI tree but can be helped by it.
- run binary / script / etc
- run tests (integrated with test UI)
- run upload scripts / etc
- Language-agnostic intellij plugins
- Build tools
- IDEA-based annotation processing
- Headless IDEA environment
- The ReSharper Platform is a common, shared, binary platform: https://twitter.com/intelliyole/status/1057693524026707968
- One of the design choices for the ReSharper 2.0 IDE was to keep functionality separate from the actual IDE… all that was needed was to plug another integration layer on top of ReSharper’s core.
- Much like with the ReSharper 2.0 IDE, JetBrains wanted to reuse as much of the existing technology and tools as possible. A logical step was to re-use the IDE platform that JetBrains had been building for years: IntelliJ IDEA.
- JetBrains set out on an adventure of marrying IntelliJ and ReSharper. One could provide a rich front-end and its existing tools, like version control and many more. The other could provide .NET tooling.
- Each is built on a different technology stack: IntelliJ is built on the Java Virtual Machine (JVM), and ReSharper is all .NET-based. We needed a way for both processes to be able to work together. JetBrains/rd is a reactive protocol to connect these two worlds
A Thin but Smart UI Layer
- Rider runs IntelliJ as a thin layer on top of ReSharper. IntelliJ provides the user interface, displaying an editor and a text caret in a source file.
- When editing a source file, IntelliJ tracks what you’re doing. For example, when you want to complete a statement, IntelliJ asks the current language service for completion items.
- C#, VB.NET, F#, and several other languages have no real implementation in Rider’s front-end, and instead call into a facade language service that requests the information from the ReSharper back-end. This information then flows back into the front-end where a list of potential completions can be displayed. Information flows in the opposite direction as well.
- Rider’s IntelliJ front-end has the infrastructure to show code inspections (“squiggles”), but again has no notion of inspections for C#.
- When a file is opened, it notifies the ReSharper process and waits for it to analyze the file, run inspections, and gather highlights that should be displayed. ReSharper publishes a list of document ranges, inspection severity, and a tooltip text, and the front-end simply displays these. In the end, Rider’s IntelliJ front-end knows about some languages, providing several tool windows and things like version-control integration.
- For the .NET languages, it’s really a thin UI layer that provides editing and other infrastructure, and it gets information from the back-end process when it’s needed.