2013-04-15 6 views
7

Supposed Ho la seguente classe Java:Strano comportamento della compilazione toolbox quando si fa riferimento una classe Java statico interno

package com.test; 
public class Outer { 
    public static class Inner { public static final String VAL = "Inner"; } 
} 

mi può fare riferimento la costante VAL dal codice Scala proprio come ci si aspetterebbe, ma quando provo codice di compilazione che fa riferimento a questo campo usando il compilatore scala toolbox, fallisce. (Stacktrace segue l'esempio di seguito).

Questo codice ha dimostrato quello che voglio dire:

import scala.reflect.runtime.universe 
import scala.tools.reflect.ToolBox 
object Issue extends App { 
    val mirror = universe.runtimeMirror(getClass.getClassLoader) 
    val toolbox = ToolBox(mirror).mkToolBox() 
    println     (com.test.Outer.Inner.VAL) // prints 'Inner' 
    val tree = toolbox.parse("com.test.Outer.Inner.VAL") 
    val compiled = toolbox.compile(tree)() // fails to compile 
} 

Questa è la traccia eccezione ottengo:

Exception in thread "main" scala.tools.reflect.ToolBoxError: reflective compilation has failed: 

value Inner is not a member of object com.test.Outer 
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.throwIfErrors(ToolBoxFactory.scala:319) 
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:252) 
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:416) 
    at Issue$delayedInit$body.apply(Issue.scala:8) 
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40) 
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) 
    at scala.App$$anonfun$main$1.apply(App.scala:71) 
    at scala.App$$anonfun$main$1.apply(App.scala:71) 
    at scala.collection.immutable.List.foreach(List.scala:318) 
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32) 
    at scala.App$class.main(App.scala:71) 
    at Issue$.main(Issue.scala:3) 
    at Issue.main(Issue.scala) 

Chiunque ha incontrato questo prima? C'è qualcosa che posso cambiare (le opzioni del compilatore) per fare in modo che funzioni?

Grazie.

EDIT

Questo è ciò che ottengo quando compilo con "verbose -Yissue-debug":

[reflect-compiler] made Scala package scala 
[reflect-compiler] unpickling Scala package package and package scala, owner = package scala 
[reflect-compiler] made Scala package java 
[reflect-compiler] made Scala package lang 
[reflect-compiler] made Scala package runtime 
[reflect-compiler] made Scala package annotation 
[reflect-compiler] unpickling Scala package package and package runtime, owner = package runtime 
[reflect-compiler] made Scala package collection 
[reflect-compiler] unpickling Scala package package and package collection, owner = package collection 
[reflect-compiler] translating reflection info for Java class java.lang.Object 
[reflect-compiler] unpickling Scala class Unit and object Unit, owner = package scala 
[reflect-compiler] translating reflection info for Java class java.lang.Throwable 
[reflect-compiler] unpickling Scala class Long and object Long, owner = package scala 
[reflect-compiler] translating reflection info for Java class java.lang.InterruptedException 
[reflect-compiler] unpickling Scala class Int and object Int, owner = package scala 
[reflect-compiler] unpickling Scala class Boolean and object Boolean, owner = package scala 
[reflect-compiler] translating reflection info for Java class java.lang.String 
[reflect-compiler] translating reflection info for Java class java.lang.CloneNotSupportedException 
[reflect-compiler] made Scala package io 
[reflect-compiler] translating reflection info for Java interface java.io.Serializable 
[reflect-compiler] translating reflection info for Java interface java.lang.CharSequence 
[reflect-compiler] unpickling Scala class Char and object Char, owner = package scala 
[reflect-compiler] translating reflection info for Java class java.io.ObjectStreamField 
[reflect-compiler] made Scala package util 
[reflect-compiler] unpickling Scala class Float and object Float, owner = package scala 
[reflect-compiler] unpickling Scala class Double and object Double, owner = package scala 
[reflect-compiler] unpickling Scala class Byte and object Byte, owner = package scala 
[reflect-compiler] translating reflection info for Java class java.lang.StringBuffer 
[reflect-compiler] translating reflection info for Java class java.util.Locale 
[reflect-compiler] translating reflection info for Java class java.io.UnsupportedEncodingException 
[reflect-compiler] made Scala package nio 
[reflect-compiler] made Scala package charset 
[reflect-compiler] translating reflection info for Java class java.nio.charset.Charset 
[reflect-compiler] translating reflection info for Java class java.lang.StringBuilder 
[reflect-compiler] translating reflection info for Java interface java.lang.Comparable 
[reflect-compiler] made Scala package beans 
parsing com.test.Outer.Inner.VAL 
importing com.test.Outer.Inner.VAL 
compiling com.test.Outer.Inner.VAL 
[reflect-compiler] unpickling Scala class Predef and object Predef, owner = package scala 
[reflect-compiler] unpickling Scala class ClassfileAnnotation and object ClassfileAnnotation, owner = package annotation 
[reflect-compiler] unpickling Scala class Annotation and object Annotation, owner = package annotation 
[reflect-compiler] unpickling Scala class StaticAnnotation and object StaticAnnotation, owner = package annotation 
[reflect-compiler] made Scala package reflect 
[reflect-compiler] unpickling Scala package package and package reflect, owner = package reflect 
[reflect-compiler] made Scala package api 
[reflect-compiler] unpickling Scala package package and package api, owner = package api 
[reflect-compiler] unpickling Scala class Universe and object Universe, owner = package api 
[reflect-compiler] unpickling Scala class Symbols and object Symbols, owner = package api 
[reflect-compiler] unpickling Scala class Types and object Types, owner = package api 
[reflect-compiler] unpickling Scala class FlagSets and object FlagSets, owner = package api 
[reflect-compiler] unpickling Scala class Scopes and object Scopes, owner = package api 
[reflect-compiler] unpickling Scala class Names and object Names, owner = package api 
[reflect-compiler] unpickling Scala class Trees and object Trees, owner = package api 
[reflect-compiler] unpickling Scala class Constants and object Constants, owner = package api 
[reflect-compiler] unpickling Scala class Annotations and object Annotations, owner = package api 
[reflect-compiler] unpickling Scala class Positions and object Positions, owner = package api 
[reflect-compiler] unpickling Scala class Exprs and object Exprs, owner = package api 
[reflect-compiler] unpickling Scala class TypeTags and object TypeTags, owner = package api 
[reflect-compiler] unpickling Scala class TagInterop and object TagInterop, owner = package api 
[reflect-compiler] unpickling Scala class StandardDefinitions and object StandardDefinitions, owner = package api 
[reflect-compiler] unpickling Scala class StandardNames and object StandardNames, owner = package api 
[reflect-compiler] unpickling Scala class BuildUtils and object BuildUtils, owner = package api 
[reflect-compiler] unpickling Scala class Mirrors and object Mirrors, owner = package api 
[reflect-compiler] unpickling Scala class Printers and object Printers, owner = package api 
[reflect-compiler] unpickling Scala class Importers and object Importers, owner = package api 
[reflect-compiler] made Scala package runtime 
[reflect-compiler] unpickling Scala package package and package runtime, owner = package runtime 
[reflect-compiler] unpickling Scala class StringContext and object StringContext, owner = package scala 
[reflect-compiler] unpickling Scala class Product and object Product, owner = package scala 
[reflect-compiler] unpickling Scala class Equals and object Equals, owner = package scala 
[reflect-compiler] unpickling Scala class Serializable and object Serializable, owner = package scala 
[reflect-compiler] made Scala package immutable 
[reflect-compiler] unpickling Scala package package and package immutable, owner = package immutable 
[reflect-compiler] unpickling Scala class Array and object Array, owner = package scala 
[reflect-compiler] translating reflection info for Java interface java.lang.Cloneable 
[reflect-compiler] unpickling Scala class AnyVal and object AnyVal, owner = package scala 
[reflect-compiler] unpickling Scala class NotNull and object NotNull, owner = package scala 
[reflect-compiler] unpickling Scala class LowPriorityImplicits and object LowPriorityImplicits, owner = package scala 
[reflect-compiler] made Scala package com 
[reflect-compiler] unpickling Scala class Dynamic and object Dynamic, owner = package scala 
[reflect-compiler] made Scala package test 
[reflect-compiler] translating reflection info for Java class com.test.Outer 
[reflect-compiler] *** missing: Inner/true/object Outer/false/class scala.reflect.runtime.SynchronizedOps$$anon$1 
java.lang.Exception 
    at scala.tools.nsc.typechecker.Contexts$Context.issue(Contexts.scala:399) 
    at scala.tools.nsc.typechecker.ContextErrors$ErrorUtils$.issueTypeError(ContextErrors.scala:84) 
    at scala.tools.nsc.typechecker.ContextErrors$ErrorUtils$.issueNormalTypeError(ContextErrors.scala:69) 
    at scala.tools.nsc.typechecker.ContextErrors$TyperContextErrors$TyperErrorGen$.NotAMemberError(ContextErrors.scala:331) 
    at scala.tools.nsc.typechecker.Typers$Typer.handleMissing$1(Typers.scala:4846) 
    at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedSelect$1(Typers.scala:4851) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedSelectOrSuperCall$1(Typers.scala:4938) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5551) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5630) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedQualifier(Typers.scala:5710) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedQualifier(Typers.scala:5716) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedSelectOrSuperCall$1(Typers.scala:4918) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5551) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5630) 
    at scala.tools.nsc.typechecker.Typers$Typer.transformedOrTyped(Typers.scala:5825) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedDefDef(Typers.scala:2250) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5557) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5630) 
    at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedStat$1(Typers.scala:2921) 
    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$62.apply(Typers.scala:3025) 
    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$62.apply(Typers.scala:3025) 
    at scala.collection.immutable.List.loop$1(List.scala:170) 
    at scala.collection.immutable.List.mapConserve(List.scala:186) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:3025) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedTemplate(Typers.scala:1914) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedModuleDef(Typers.scala:1794) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5572) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5630) 
    at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedStat$1(Typers.scala:2921) 
    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$62.apply(Typers.scala:3025) 
    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$62.apply(Typers.scala:3025) 
    at scala.collection.immutable.List.loop$1(List.scala:170) 
    at scala.collection.immutable.List.mapConserve(List.scala:186) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:3025) 
    at scala.tools.nsc.typechecker.Typers$Typer.typedPackageDef$1(Typers.scala:5288) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5575) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5630) 
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5687) 
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.apply(Analyzer.scala:99) 
    at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:463) 
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3$$anonfun$run$1.apply(Analyzer.scala:91) 
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3$$anonfun$run$1.apply(Analyzer.scala:91) 
    at scala.collection.Iterator$class.foreach(Iterator.scala:727) 
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1157) 
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.run(Analyzer.scala:91) 
    at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1582) 
    at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1556) 
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:251) 
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:416) 
    at Issue$delayedInit$body.apply(Issue.scala:8) 
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40) 
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) 
    at scala.App$$anonfun$main$1.apply(App.scala:71) 
    at scala.App$$anonfun$main$1.apply(App.scala:71) 
    at scala.collection.immutable.List.foreach(List.scala:318) 
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32) 
    at scala.App$class.main(App.scala:71) 
    at Issue$.main(Issue.scala:3) 
    at Issue.main(Issue.scala) 
Exception in thread "main" scala.tools.reflect.ToolBoxError: reflective compilation has failed: 

[namer in 31ms] 
[packageobjects in 0ms] 
value Inner is not a member of object com.test.Outer 
[typer in 211ms] 
[total in 247ms] 
[reset] recursing in package <root> 
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.throwIfErrors(ToolBoxFactory.scala:319) 
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:252) 
    at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:416) 
    at Issue$delayedInit$body.apply(Issue.scala:8) 
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40) 
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) 
    at scala.App$$anonfun$main$1.apply(App.scala:71) 
    at scala.App$$anonfun$main$1.apply(App.scala:71) 
    at scala.collection.immutable.List.foreach(List.scala:318) 
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32) 
    at scala.App$class.main(App.scala:71) 
    at Issue$.main(Issue.scala:3) 
    at Issue.main(Issue.scala) 

EDIT 2

Penso che questo sia un bug nella riflessione API ma non sono sicuro. Ho il debug la fase di digitazione e sono venuto con il seguente:

Dopo com.test.Outer è stato assegnato con un apposito simbolo, si raggiunge la fase della tipizzazione di com.test.Outer.Inner.

Qui viene visualizzato un simbolo per Inner utilizzando scala.reflect.internal.Scopes.Scope#lookupEntry(Name).

Controllo della guardata portata rivela che esso contiene una ScopeEntry per un ClassSymbol di Inner ma il test di uguaglianza tra il nome del simbolo finalità e le modalità name parametro viene fatto utilizzando Object#equals (cioè equals non è stato sovrascritto), e la due istanze di nomi non sono le stesse.

Un'ultima nota riguardante il nome del simbolo e il parametro del nome passato è che vedo che hanno lo stesso campo index. Non sono sicuro di cosa significhi, ma ho l'impressione che questo significhi che si riferiscono allo stesso nome nella tabella dei nomi, quindi sono uguali (?) (C'è una differenza tra i due, uno è TermName e il il nome del simbolo è TypeName).

In ogni caso, probabilmente aprirò un insetto bug bug di Scala, volevo solo concludere qui.

+0

Provare 'toolbox.parse (" com.test.Outer # Inner.VAL ")'? – Impredicative

+0

Sì, per favore, invia un bug, e darò un'occhiata. Grazie per l'analisi dettagliata! –

+0

@EugeneBurmako Grazie, appena aperto SI-7378 – dankilman

risposta

0

Corretto: sembra che l'API Scala/JVM reflection non sia in grado di determinare che VAR è un membro statico della classe Inner nidificata.