Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How We Support New Technologies, Languages, and Frameworks in IntelliJ IDEA

How We Support New Technologies, Languages, and Frameworks in IntelliJ IDEA

Many developers, sooner or later, come to a point where they realize none of the existing tools can do exactly what they want. For example, the vendor of your favorite IDE has not implemented a feature you are using, or you are working with a rather new custom framework that isn't yet supported by your IDE. What to do? The good news is that IntelliJ IDEA and its plugins are not set in stone, so anyone yes, that includes you can implement support for a new language, library, or framework.

Yuriy Artamonov

February 25, 2021
Tweet

More Decks by Yuriy Artamonov

Other Decks in Programming

Transcript

  1. How We Support
    New Technologies,
    Languages, and Frameworks
    in IntelliJ IDEA
    Yuriy Artamonov

    View Slide

  2. Author
    ■ Developing libraries, frameworks,
    and tools for developers for the
    past 10 years
    ■ Sad about their imperfect IDE
    support
    ■ Working in IntelliJ IDEA team on
    features for new technologies
    2

    View Slide

  3. Plan
    1. IntelliJ IDEA Plugin System
    2. Code Insight and Frameworks (Spring Framework)
    3. Custom Languages (JSONPath)
    4. Integration with External Tools (Swagger, JSONPath)
    5. Useful Resources
    3

    View Slide

  4. Motivation
    ■ Almost every company has:
    in-house frameworks, libraries,
    code style, processes and
    conventions.
    ■ At the same time —
    we all have routine tasks and
    it is inevitable.
    4

    View Slide

  5. How to deal with the routine
    ■ Build more languages and
    frameworks!
    ■ Generate more code!
    ■ Improve tooling - IDE
    5

    View Slide

  6. Sharing our experience!
    6

    View Slide

  7. IntelliJ IDEA Plugin Capabilities
    ★ Languages and file formats
    ★ Static analysis on the fly
    ★ Navigation
    ★ Editor improvements
    ★ Refactoring and code generation
    ★ Integration with tools and services
    ★ Code migrations
    7

    View Slide

  8. IDE Internals
    ■ Services
    ■ Virtual File System (VFS)
    ■ Languages - Parsing, Highlighting (PSI)
    ■ Editor
    ■ Inspection engine
    ■ Indexes
    ■ Background Processes
    ■ UI Library
    ■ Extension Points
    IntelliJ Platform
    IDEA CE (Java,
    Groovy, Kotlin)
    PHP Support Ruby Support
    IDEA Ultimate PHP Storm RubyMine
    8

    View Slide

  9. Plugin System
    All JetBrains IDEs consist of plugins:
    1. Every plugin implements extension points of IDE
    and may declare their own
    2. Plugins may depend on platform modules and plugins
    9
    Groovy
    Plugin
    Java
    Plugin
    Properties
    Plugin
    Ultimate
    Modules
    optional

    View Slide

  10. Getting Started
    10
    1. Check/Enable
    Plugin DevKit
    2. Create a Gradle project
    with IntelliJ Platform
    Plugin preset
    3. Declare and implement
    extension points
    Kotlin recommended!
    (but not required)

    View Slide

  11. IntelliJ Plugin Template
    https://github.com/JetBrains/intellij-platform-plugin-template
    Recommended way to start your plugin development!
    11

    View Slide

  12. Plugin Structure
    .../resources/META-INF/plugin.xml

    spring-intellij-plugin
    Spring Framework Support
    Provides support for Spring Framework for JVM languages
    ]]>
    com.intellij.modules.java

    View Slide

  13. Extension Points
    ■ Lots of them:
    action, inspection, intention action, reference contributor, ui settings group,
    language parser, language formatter, etc.
    ■ Register them in XML config – plugin.xml
    ■ Check also: LangExtensionPoints.xml, PlatformExtensionPoints.xml,
    VcsExtensionPoints.xml, etc.
    Example: Groovy support - plugin of IntelliJ IDEA > 1300 lines in plugin.xml.
    github.com/JetBrains/intellij-community
    13

    View Slide

  14. Extension Points Explorer
    https://plugins.jetbrains.com/intellij-platform-explorer
    A search tool for browsing extension points inside existing implementations of
    OSS IntelliJ Platform plugins.
    14

    View Slide

  15. What you can do with all
    those extension points?
    15

    View Slide

  16. Let’s Improve Something
    Imagine: we have developed a framework that is very similar to Spring Framework.
    What can go wrong?
    16

    View Slide

  17. Implicit Usages
    Problem: frameworks are powerful and they love implicit conventions.
    @Controller
    class WelcomeController {
    @GetMapping("/welcome")
    public String welcome() {
    return "Nice to meet you!";
    }
    }
    💡 Class ‘WelcomeController’ is never used.
    17
    Let’s teach IDE to understand those implicit usages!

    View Slide

  18. Implicit Usage Provider
    There is an extension point for that:

    class SpringImplicitUsageProvider : ImplicitUsageProvider {
    override fun isImplicitWrite(element: PsiElement): Boolean {
    TODO()
    }
    override fun isImplicitRead(element: PsiElement): Boolean {
    TODO()
    }
    override fun isImplicitUsage(element: PsiElement): Boolean {
    TODO()
    }
    }
    18

    View Slide

  19. Syntax Trees
    PSI - Program Structure Interface, a special representation of the program:
    ■ Syntax structure of files
    ■ Includes semantics and provides resolve procedure
    ■ Everything (almost) is represented by PsiElement
    ■ Languages provide their own PSI elements
    19
    PsiFile
    PsiElement
    PsiElement
    PsiElement
    PsiElement
    PSI Tree

    View Slide

  20. Java PSI Model
    Key Elements:
    ■ PsiJavaFile
    ■ PsiImportList
    ■ PsiClass
    ■ PsiAnnotation
    ■ PsiField
    ■ PsiMethod
    ■ ...
    Check Tools - View PSI Structure of
    Current File
    20

    View Slide

  21. Inspections
    ■ Perform static analysis
    on the fly
    ■ Traverse PSI tree
    ■ Can provide automatic fixes
    See
    LocalInspectionTool
    LocalQuickFix
    21

    View Slide

  22. Enforce coding conventions
    Register extension point:
    displayName="@Autowired on a field in Spring beans"
    groupName="Spring"
    enabledByDefault="true"
    implementationClass="demo.SpringAutowiredInspection"/>
    Inspection class:
    class SpringAutowiredInspection : AbstractBaseJavaLocalInspectionTool() {
    override fun checkMethod(method: PsiMethod, manager: InspectionManager, isOnTheFly: Boolean)
    : Array? {
    // check here
    return ProblemDescriptor.EMPTY_ARRAY
    }
    }
    22

    View Slide

  23. References in PSI
    ■ Establish connection between
    PsiElement usages and its
    declaration:
    usage ➜ declaration
    ■ Can provide auto completion
    variants
    ■ Plugins can contribute new
    references to existing languages!
    See
    PsiReferenceContributor
    PsiLanguageInjectionHost
    23

    View Slide

  24. Property References
    In Spring @Value annotation supports property interpolation from
    application.properties via expressions ${some.property-name}:
    @Value("${datasources.default.url}")
    private String datasourceUrl;
    Idea: let’s connect these usages with property!
    24

    View Slide

  25. Find Usages and Rename Refactoring
    1. Find elements with the same text
    2. Try to find references
    3. Match references with PsiElement
    Works automatically if text of element and references is the same!
    Customize search of elements with Searcher, ReferenceSearcher.
    25

    View Slide

  26. What’s next?
    26

    View Slide

  27. Custom Languages
    IntelliJ Platform is a powerful platform for building development tools targeting
    any language.
    Language Support Plan:
    1. File and Language Definition
    2. Grammar
    3. Lexer and Parser
    4. Highlighting
    5. Completion
    6. Inspections
    7. Refactorings
    27

    View Slide

  28. Grammar-Kit
    Additional plugin for IntelliJ IDEA:
    ■ Provides support for BNF Grammars and JFlex lexers editor.
    ■ Generates Lexer by BNF.
    ■ Generates readable parser/PSI code generator.
    Must read:
    https://plugins.jetbrains.com/docs/intellij/custom-language-support.html
    28

    View Slide

  29. Language Injection
    Language injections let you work with pieces of code in other languages
    embedded in your code.
    Any language can be injected to any other language!
    29

    View Slide

  30. Language Injections in Real Life
    ■ Regexp
    ■ SQL
    ■ JSON
    ■ XML & HTML
    ■ XPath / JSONPath
    ■ JavaScript
    ■ ...
    30

    View Slide

  31. How to Integrate External Tools
    1. Just works: Settings - External Tools
    2. Easy: find JVM library that implements integration:
    (Gradle API, Docker Java, Swagger Codegen)
    3. Harder: connect to external API via network or
    UNIX-socket (Spring Initializr, Java Debugger)
    4. Pain and Suffering: run command line tools
    (Git, Docker, NPM)
    5. Web Content
    31

    View Slide

  32. Running External Processes
    Main API: java.lang.ProcessBuilder
    See also: com.intellij.execution.process.OSProcessHandler
    Run Configurations: com.intellij.execution.configurations.GeneralCommandLine
    32

    View Slide

  33. UI Development
    ■ Java Swing + Kotlin UI DSL
    plugins.jetbrains.com/
    docs/intellij/kotlin-ui-dsl.html
    ■ Integrated Web Content
    with JCEF
    33

    View Slide

  34. Web Content
    JCEF - Java Chromium Embedded Framework
    https://plugins.jetbrains.com/docs/intellij/jcef.html
    Embedding of the browser component inside the IDE allows amongst others:
    ■ Rendering HTML content
    ■ Previewing generated HTML (e.g., from Markdown or Swagger UI)
    34

    View Slide

  35. Sometimes It Takes a Lot of Effort
    Spring Framework Support in numbers:
    ■ 260k LOC Java
    ■ 20k LOC Kotlin
    ■ 350k LOC Total
    ■ 3500 Tests
    35

    View Slide

  36. It Pays Off!
    36

    View Slide

  37. Useful Resources
    ■ Examples from the Talk:
    github.com/jreznot/intellij-plugin-showcase
    ■ Source Code of IntelliJ IDEA CE:
    github.com/JetBrains/intellij-community
    ■ Plugin DevKit Documentation:
    jetbrains.org/intellij/sdk/docs/basics.html
    ■ JetBrains Platform Slack:
    plugins.jetbrains.com/slack
    37

    View Slide

  38. Thanks!
    @Yuriy_Artamonov

    View Slide