1

(매크로) 컨텍스트의 resetLocalAttrs 메서드를 사용하는 매크로를 코딩했습니다. 매크로가 확장 된 후에 이상한 오류가 발생하고 어떤 일이 발생하는지 알 수 없습니다. 첫째, 나는 그 문제를 소개 할 것이다. 우리는 상태 인 (간단한 int로 표시)과 액션의 두 가지 프리미티브가 있습니다. 상태는 시스템의 현재 상태를 나타내고 동작은 상태 수정을 담당합니다. 액션은 원자 적이거나 원자 적 동작으로 구성 될 수 있습니다. 하나의 코드에서 보듯이 그 순간의 현재 상태에 따라 하나 개 또는 다른 동작을 실행할 수 있기 때문에resetLocalAttrs를 사용하는 중에 이상한 오류가 발생했습니다.

trait Action { 
    def andNext(action: PartialFunction[Int, Int => Action]): AndNext = AndNext(this, action) 
} 
case class ActionId extends Action 
case class AndNext(action: Action, and: PartialFunction[Int, Int => Action]) extends Action 

AndNext는 일부 기능을 수신한다. 합성 된 동작 내부의 원자 동작은 시퀀스의 이전 원자 동작에 의해 왼쪽으로 이전 상태를 요구할 수 있으므로 Int => 동작으로 보호해야합니다.

지능 => 액션 매개 변수를 요구하는 테스트를 강제로 더미 함수를 사용하여,의 코드를 테스트 해보자

def f(lifted: Int => Action) = ??? 
f(implicit state => ActionId() andNext { case _ => implicit state => ActionId() }) 

괜찮아,하지만 나는 DSL 일하고, 그것은 너무 이 코드를 DSL 사용에 좋게 만들려면 모두 암시 적 상태 인을 모두 작성하는 것이 좋습니다. 내가 보호 조치로 작업을 켤 수있는 매크로를 구현 한

f(ActionId() andNext { case _ => ActionId() }) 

... 다음 귀여운 호출에 도달하려고 노력하는 (INT => 작업 기억) :

implicit def lift[T](expr: T): Int => T = macro liftImpl[T] 

def liftImpl[T: c.WeakTypeTag](c: Context)(expr: c.Expr[T]): c.Expr[Int => T] = { 
    import c.mirror._ 
    import c.universe._ 

    //reify(implicit state => expr.splice) 
    reify(implicit state => c.Expr[T](c.resetLocalAttrs(expr.tree)).splice) 
} 

(*)가 을 주목하라 뷰에서 메서드를 변환하는 매크로 선언에 암시 적이 있습니다.

reef는 잘 작동하지만 몇 가지 제한 사항으로 인해 resetLocalAttrs() (이 질문은 너무 길어지고 있습니다.)을 호출해야합니다. 이 구체화는 이상한 오류와 함께 실패합니다.

class Any is abstract; cannot be instantiated 

어디에서 AnyNothing을 인스턴스화하려고합니까? 재설정이 AST에 영향을 미치는 이유는 무엇입니까? 나는 그것을 여러 번 사용했고 유형과 기호를 멋지게 재설정하고있었습니다.

문제를 찾는 더 좋은 방법은 무엇입니까? 나는 showRaw와 협력하여 유형ids ids 플래그를 사용하여 매우 어려워졌습니다.

답변

1

일부 기능은 합성 익명 클래스를 야기하고, 익명 클래스의 유형 체킹 - 리셋 retypechecking 문제 알고 : https://issues.scala-lang.org/browse/SI-6187

17:04 ~/Projects/Kepler_macrosnippet00/sandbox (topic/macrosnippet00)$ scalac -Ymacro-debug-lite Test.scala 
performing macro expansion Macros.lift[ActionId](ActionId.apply()) at source-/Users/xeno_by/Projects/Kepler_macrosnippet00/sandbox/Test.scala,line-11,offset=449 
((implicit state) => ActionId.apply()) 
Function(List(ValDef(Modifiers(IMPLICIT | PARAM), newTermName("state"), TypeTree(), EmptyTree)), Apply(Select(Ident(ActionId), newTermName("apply")), List())) 
performing macro expansion Macros.lift[AndNext](ActionId.apply().andNext(({ 
    @SerialVersionUID(0) final <synthetic> class $anonfun extends scala.runtime.AbstractPartialFunction[Int,Int => Action] with Serializable { 
    def <init>(): anonymous class $anonfun = { 
     $anonfun.super.<init>(); 
    () 
    }; 
    final override def applyOrElse[A1 >: Nothing <: Int, B1 >: Int => Action <: Any](x$1: A1, default: A1 => B1): B1 = (x$1: A1 @unchecked) match { 
     case _ => ((implicit state: Int) => ActionId.apply()) 
    }; 
    final def isDefinedAt(x$1: Int): Boolean = (x$1: Int @unchecked) match { 
     case _ => true 
    } 
    }; 
    new anonymous class $anonfun() // an anonymous class created for a partial function 
}: PartialFunction[Int,Int => Action]))) at source-/Users/xeno_by/Projects/Kepler_macrosnippet00/sandbox/Test.scala,line-11,offset=421 
((implicit state) => ActionId.apply().andNext(({ 
    final <synthetic> class $anonfun extends scala.runtime.AbstractPartialFunction[Int,Int => Action] with Serializable { 
    def <init>() = { 
     super.<init>(); 
    () 
    }; 
    final override def applyOrElse[A1 <: Int, B1 >: Int => Action](x$1, default) = (x$1: <type ?>) match { 
     case _ => ((implicit state: Int) => ActionId.apply()) 
    }; 
    final def isDefinedAt(x$1: Int): Boolean = (x$1: Int @unchecked) match { 
     case _ => true 
    } 
    }; 
    new <type ?>() // <= the problem is here: the type has been irreversibly erased by resetLocalAttrs 
}: PartialFunction[Int,Int => Action])))