polystat / odin

Object Dependency Inspector
10 stars 2 forks source link

Inlining all method calls in an object #30

Closed nikololiahim closed 2 years ago

nikololiahim commented 2 years ago

This pull request introduces a module Inliner with one function among other things:

def inlineAllCalls(prog: EOProg[EOExprOnly]): Either[NonEmptyList[String], EOProg[EOExprOnly]]

which takes a program AST as input, detects all objects, detects all methods inside objects, inside methods finds all the method calls and inlines those calls with their definitions. This method can also fail if some errors occur in the process. These errors include:

Directory test/scala/org/polystat/odin/analysis/inlining contains the test case definitions (XTestCases.scala) and the runner code for tests (InliningTests.scala). Link to test inlining test cases. Example test case:

val average3WithComponentsTest: InliningTestCase = InliningTestCase(
    label = "average3 that also returns the sum and count",
    codeBefore = // before inlining
      """[] > obj
        |  [self arg1 arg2 arg3] > average3
        |    arg1.add (arg2.add arg3) > sum
        |    3 > count
        |    sum.div count > average
        |    [] > @
        |      ^.sum > sum
        |      ^.count > count
        |      ^.average > average
        |  [self] > call-site
        |    self.average3 self 1 2 3 > @
        |""".stripMargin,
    codeAfter = // code after inlining
      """[] > obj
        |  [self arg1 arg2 arg3] > average3
        |    $.arg1.add > sum
        |      $.arg2.add
        |        $.arg3
        |    3 > count
        |    $.sum.div > average
        |      $.count
        |    [] > @
        |      ^.sum > sum
        |      ^.count > count
        |      ^.average > average
        |  [self] > call-site
        |    [] > local_average3
        |      1.add > sum
        |        2.add
        |          3
        |      3 > count
        |      $.sum.div > average
        |        $.count
        |    [] > @
        |      ^.local_average3.sum > sum
        |      ^.local_average3.count > count
        |      ^.local_average3.average > average
        |""".stripMargin.asRight
  )