Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Rider - Taking ReSharper out of Process

232 views

Published on

A look at how Rider, a new .NET IDE from JetBrains, uses IntelliJ to provide a cross platform, fully featured UI for ReSharper.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Rider - Taking ReSharper out of Process

  1. 1. Taking ReSharper out of process Matt Ellis @citizenmatt
  2. 2. Why build a .NET IDE now?
  3. 3. How do you build a .NET IDE?
  4. 4. How do you build a 
 cross platform .NET IDE?
  5. 5. How do you build a 
 cross platform IDE?
  6. 6. Hello IntelliJ
  7. 7. Hello IntelliJ IDEA
  8. 8. Hello IntelliJ Platform
  9. 9. https://github.com/JetBrains/intellij-community
  10. 10. Uh-oh. JVM
  11. 11. How do you build a .NET IDE in the JVM?
  12. 12. Options?
  13. 13. ReSharper out of process • Language server • Headless. Command line process. IntelliJ provides the UI
 Client/server communication • Cross platform
 .NET Framework on Windows. Mono on MacOS and Linux • Removes Visual Studio in-process constraints
 Memory usage. 64 bit • Continued investment in ReSharper
  14. 14. Thick Client? Thin Client? • IntelliJ provides high level UI elements, functionality and infrastructure
 Editors, Alt+Enter, completion, Find Usages, test runner, debugging…
 Searchable tree views, popup dialogs, settings pages… • No knowledge of syntax trees or semantic model
 Parsing, resolving, syntax highlighting, folding, inspections, refactoring, code completion, etc. all owned by ReSharper • (Some standalone functionality)
 Find in path, REST client, Databases, VCS • Optimisations
 Lexing for initial syntax highlighting
  15. 15. Alt+Enter • IntelliJ provides editor, text caret, and tracks Alt+Enter keypress • Asks current language for items • Current language is an IntelliJ facade for ReSharper out-of-proc
 Asks ReSharper for items at current location • ReSharper returns list of display names, icons and submenus • IntelliJ displays items in Alt+Enter menu
  16. 16. Inspection highlights • IntelliJ provides infrastructure to display “squigglies” • Opposite direction, pushed from ReSharper • Source file is opened, or modified
 IntelliJ notifies ReSharper • ReSharper analyses the file, runs inspections, gathers highlights • ReSharper publishes list of range, severity and tooltip • IntelliJ displays squiggles
  17. 17. Modifying source • Bi-directional • User typing
 IntelliJ publishes changes as delta of typed characters at offset • ReSharper rewriting code
 Publishes delta as chunk of code
 Renamed variable, new method, additional `using` statement, etc.
  18. 18. Observations • Enabling functionality, rather than implementing it
 Can show all Alt+Enter menus, run all inspections, rewrite code in context actions and quick fixes • As long as there is no UI… • The data is very lightweight
  19. 19. IPC - RPC? • Boilerplate - define calls and messages for each required action • Imperative • Conflict resolution?
 Who wins? How to reset/resync state? • JSON? Protobuf? Client
 (IntelliJ) Server
 (ReSharper)
  20. 20. MVVM • Only send data required for UI components • Lightweight View Model data View
 (IntelliJ) Model
 (ReSharper) View
 Model
  21. 21. Hierarchical View Model
  22. 22. Shared View Model • Single view of state of entire IDE
 Shared between front end and back end
 Keep in sync. Only need to update changed fields • Becomes declarative
 No more boilerplate messages, just update View Model • Reactive/observable. Composable
 Subscribe for changes • Two way
 Client and server can both contribute to View Model
 E.g. button click/refactoring results • Tightly coupled? 🤔
  23. 23. Conflict resolution • The client is always right • Each value has a version • Version increments only when client changes value • If server changes value, no version update • Only accept change with same or newer version
  24. 24. “foo”/1 “foo”/1 “bar”/2 “bar”/2 “quux”/2 “quux”/2 “wibble”/3 “blah”/2 “wibble”/3 Client (IntelliJ) Server (ReSharper)
  25. 25. Wire protocol • Becomes trivial - no messages, just deltas
 Don’t change the protocol, just extend model • Supports batching • Serialisation by code generation via DSL • Binary wire protocol, with logging • Sockets
  26. 26. Rider Framework • Two libraries, C# and Kotlin
 Provides primitives and handles communication • Kotlin based DSL to describe View Model • Generates real code - C# and Kotlin
 Interfaces, implementation and serialisation • Business logic subscribes to and manipulates “real model”
 Magic happens
  27. 27. View Model building blocks • Lifetime • Signals (events) • Properties (observable value) • Maps (observable collections) • Fields (immutable) • Call (async RPC) • string • int • enum • classdef (node) • structdef (data)
  28. 28. Lifetime class Lifetime { static Lifetime Eternal; void Add(Action action); } class LifetimeDef { ctor(Lifetime parent); Lifetime Lifetime; void Terminate(); } Dual of IDisposable
  29. 29. Signal // Produce event interface ISource<T> { void Fire(T value); } // Subscribe to event interface ISink<T> { void Advise(Lifetime l, Action<T> handler); } // Composable event interface ISignal<T> : ISource<T>, ISink<T> { }
  30. 30. Properties // Subscribe to event interface ISink<T> { void Advise(Lifetime l, Action<T> handler); } // Observable property interface IProperty<T> : ISink<T> { T Value { get; set; } void View(Lifetime l, Action<Lifetime, T> action); } Stateful signal
  31. 31. Maps class MapEvent<K,V> { enum Kind { Add, Remove } Kind kind; K key; V value; } // Observable collection interface IViewableMap<K,V> : IDictionary<K,V>, ISink<MapEvent<K,V >> { void View(Lifetime l, Action<Lifetime, K, V> action); }
  32. 32. Kotlin DSL fun classdef ( name : String, init : ClassdefNode.() -> Unit ) classdef ( “Foo”, { myClassdef.map(…) } ) classdef ( “Foo”, { map(…) } )
  33. 33. Kotlin DSL fun classdef ( name : String, init : ClassdefNode.() -> Unit ) classdef ( “Foo”, { lambda_expression } ) classdef (“Foo”) { lambda_expression }
  34. 34. object Solution { init { map(“editors”, string, classdef(“Editor”) { list(“document”, char) property(“caret”, int) map(“highlighters”, Range, Highlighter) property(“completion”, Completion.nullable) }) voidSource(“build”) } val Range = classdef(“Range”) { field(“start”, int) field(“length”, int) } val Highlighter = classdef(“Highlighter”) { … } }
  35. 35. Challenges • Rider’s Project Model very different to IntelliJ
 Replace Project view with Solution Explorer
 IntelliJ uses “project” where we expect “solution” • What about duplicate language implementations?
 E.g. JavaScript - WebStorm or ReSharper?
 C++ CLion or ReSharper? • Plugins are more complex
 Front end and back end • ReSharper out of process with Visual Studio? 🙊
  36. 36. Thanks! Matt Ellis @citizenmatt www.jetbrains.com/rider

×