Skip to content

Understanding current Scala implementations

Sewen Thy edited this page Aug 22, 2022 · 3 revisions

The Scala implementation studied is implemented in the Intellij Community Scala plugin in this precise folder.

Brief Pseudocode

  1. Check if the last selected statement is a return, and get its type.

  2. Check if there is a return statement in the selected statements.

  3. Find smallest scope to scan for siblings.

   val visitor = new ScalaRecursiveElementVisitor {
      override def visitReference(ref: ScReference): Unit = {
        scopeBound(ref) match {
          case Some(bound: PsiElement) if PsiTreeUtil.isAncestor(result, bound, true) => result = bound
          case _ =>
        }
      }
    }

It appears to restrict the bound each time a new one that is smaller is found.

  1. Find the siblings which are parents of the first element that are within scope.

  2. Invoke dialog:
    a. Use CFG to find Reaching Definitions for the elements and its sibling and calculate possible input and output variables.
    b. Get user's input for selecting input and output variables then generate settings for creating method.

  3. Perform refactoring:
    a. Create method from settings (need more work to find out details that could impact lifetime).
    b. Insert method according to settings.

Possible limitation when apply to Rust

The scoping here cannot account for the lifetime requirement of Rust using only Reaching Definition criteria alone. The create method function (need further work) need to also be customizable to different ownership modes in Rust.

Quick references

https://youtu.be/IPO-cY_giNA?t=546
https://plugins.jetbrains.com/docs/intellij/navigating-psi.html#bottom-up-navigation
https://en.wikipedia.org/wiki/Visitor_pattern
https://plugins.jetbrains.com/docs/intellij/psi-references.html
https://en.wikipedia.org/wiki/Reaching_definition

Clone this wiki locally