7mind / izumi

Productivity-oriented collection of lightweight fancy stuff for Scala toolchain
https://izumi.7mind.io
BSD 2-Clause "Simplified" License
615 stars 66 forks source link

Support fields in dynamic trait instances #26

Closed pshirshov closed 6 years ago

pshirshov commented 6 years ago

Technically, we have enough data for that.

A trait:

// class version 52.0 (52)
// access flags 0x601
public abstract interface org/bitbucket/pshirshov/izumi/distage/Case2$ATrait {

  // compiled from: Fixtures.scala

  ATTRIBUTE Scala : unknown

  ATTRIBUTE ScalaInlineInfo : unknown
  // access flags 0x609
  public static abstract INNERCLASS org/bitbucket/pshirshov/izumi/distage/Case2$ATrait org/bitbucket/pshirshov/izumi/distage/Case2 ATrait

  // access flags 0x401
  public abstract org$bitbucket$pshirshov$izumi$distage$Case2$ATrait$_setter_$x_$eq(I)V
    // parameter final  x$1

  // access flags 0x401
  public abstract x()I

  // access flags 0x9
  public static $init$(Lorg/bitbucket/pshirshov/izumi/distage/Case2$ATrait;)V
    // parameter final synthetic  $this
   L0
    LINENUMBER 85 L0
    ALOAD 0
    ICONST_1
    INVOKEINTERFACE org/bitbucket/pshirshov/izumi/distage/Case2$ATrait.org$bitbucket$pshirshov$izumi$distage$Case2$ATrait$_setter_$x_$eq (I)V
   L1
    LINENUMBER 84 L1
    RETURN
   L2
    LOCALVARIABLE $this Lorg/bitbucket/pshirshov/izumi/distage/Case2$ATrait; L0 L2 0
    MAXSTACK = 2
    MAXLOCALS = 1
}

And corresponding class:

  // class version 52.0 (52)
// access flags 0x21
public class org/bitbucket/pshirshov/izumi/distage/Case2$AClass implements org/bitbucket/pshirshov/izumi/distage/Case2$ATrait  {

  // compiled from: Fixtures.scala

  ATTRIBUTE Scala : unknown

  ATTRIBUTE ScalaInlineInfo : unknown
  // access flags 0x9
  public static INNERCLASS org/bitbucket/pshirshov/izumi/distage/Case2$AClass org/bitbucket/pshirshov/izumi/distage/Case2 AClass
  // access flags 0x609
  public static abstract INNERCLASS org/bitbucket/pshirshov/izumi/distage/Case2$ATrait org/bitbucket/pshirshov/izumi/distage/Case2 ATrait

  // access flags 0x12
  private final I x

  // access flags 0x1
  public x()I
   L0
    LINENUMBER 88 L0
    ALOAD 0
    GETFIELD org/bitbucket/pshirshov/izumi/distage/Case2$AClass.x : I
    IRETURN
   L1
    LOCALVARIABLE this Lorg/bitbucket/pshirshov/izumi/distage/Case2$AClass; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public org$bitbucket$pshirshov$izumi$distage$Case2$ATrait$_setter_$x_$eq(I)V
    // parameter final  x$1
   L0
    LINENUMBER 88 L0
    ALOAD 0
    ILOAD 1
    PUTFIELD org/bitbucket/pshirshov/izumi/distage/Case2$AClass.x : I
    RETURN
   L1
    LOCALVARIABLE this Lorg/bitbucket/pshirshov/izumi/distage/Case2$AClass; L0 L1 0
    LOCALVARIABLE x$1 I L0 L1 1
    MAXSTACK = 2
    MAXLOCALS = 2

  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 88 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    ALOAD 0
    INVOKESTATIC org/bitbucket/pshirshov/izumi/distage/Case2$ATrait.$init$ (Lorg/bitbucket/pshirshov/izumi/distage/Case2$ATrait;)V
    RETURN
   L1
    LOCALVARIABLE this Lorg/bitbucket/pshirshov/izumi/distage/Case2$AClass; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1
}

So, what we need to do:

  1. Enumerate vals. This is the most problematic part, seems like we can't distinguish between method and val
  2. Add field
  3. Generate implementations for both setter and getter
pshirshov commented 6 years ago

Done on interceptors, even without cogen