Skip to content

Commit

Permalink
support varargs and fields
Browse files Browse the repository at this point in the history
  • Loading branch information
bishabosha committed Jan 24, 2024
1 parent 44713c2 commit 3934cdf
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1189,7 +1189,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
// wrong number of arguments in some scenarios reading F-bounded
// types. This came up in #137 of collection strawman.
tpd.AppliedTypeTree(readTpt(), until(end)(readTpt()), isJava)
case ANNOTATEDtpt => tpd.Annotated(readTpt(), readTerm()(ctx.addMode(ReadAnnotTopLevel)))
case ANNOTATEDtpt => tpd.Annotated(readTpt(), readTerm()(ctx.addMode(ReadAnnotTopLevel)), isJava)
case LAMBDAtpt => tpd.LambdaTypeTree(readParams[NoCycle](TYPEPARAM).map(symFromNoCycle), readTpt())
case MATCHtpt => matchTypeIsUnsupported
case TYPEBOUNDStpt =>
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ trait ContextOps { self: TastyUniverse =>
else if (name === TastyName.MixinConstructor) {
owner.newMethodSymbol(u.nme.MIXIN_CONSTRUCTOR, u.NoPosition, newSymbolFlagSet(flags &~ Stable, isJava))
}
else if (isJava && flags.is(FlagSets.JavaEnumCase)) {
else if (isJava && flags.not(Method)) {
owner.newValue(encodeTermName(name), u.NoPosition, newSymbolFlagSet(flags, isJava))
}
else {
Expand Down
11 changes: 8 additions & 3 deletions src/compiler/scala/tools/nsc/tasty/bridge/TreeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -161,16 +161,21 @@ trait TreeOps { self: TastyUniverse =>
def AppliedTypeTree(tpt: Tree, args: List[Tree], isJava: Boolean)(implicit ctx: Context): Tree = {
if (tpt.tpe === AndTpe) {
u.CompoundTypeTree(u.Template(args, u.noSelfType, Nil)).setType(u.intersectionType(args.map(_.tpe)))
} else {
}
else if (isJava && u.definitions.isScalaRepeatedParamType(tpt.tpe)) {
u.AppliedTypeTree(tpt, args).setType(u.definitions.javaRepeatedType(args.head.tpe))
}
else {
u.AppliedTypeTree(tpt, args).setType(defn.AppliedType(tpt.tpe, args.map(_.tpe), isJava))
}
}

def Annotated(tpt: Tree, annot: Tree)(implicit ctx: Context): Tree = {
def Annotated(tpt: Tree, annot: Tree, isJava: Boolean)(implicit ctx: Context): Tree = {
if (annot.tpe.typeSymbol === defn.RepeatedAnnot
&& tpt.tpe.typeSymbol.isSubClass(u.definitions.SeqClass)
&& tpt.tpe.typeArgs.length == 1) {
tpd.TypeTree(u.definitions.scalaRepeatedType(tpt.tpe.typeArgs.head))
if (isJava) tpd.TypeTree(u.definitions.javaRepeatedType(tpt.tpe.typeArgs.head))
else tpd.TypeTree(u.definitions.scalaRepeatedType(tpt.tpe.typeArgs.head))
}
else {
u.Annotated(annot, tpt).setType(defn.AnnotatedType(tpt.tpe, annot))
Expand Down
37 changes: 37 additions & 0 deletions test/tasty/run-pipelined/src-2/tastytest/TestObjectTpeJava.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package tastytest

import lib.ObjectTpeJava
import scala.annotation.nowarn

// keep in sync with ObjectTpeJava.java
object TestObjectTpeJava extends scala.App {

val newOTJ = new ObjectTpeJava

val newOTJInner = new ObjectTpeJava.Inner[Int](23, true)

newOTJ.meth1(1) // OK
newOTJ.meth2(1) // OK
newOTJ.meth3(List[Int](1)) // OK
newOTJ.meth4(List[Int](1)) // OK
newOTJ.meth5(Array[Object]("abc")) // OK
newOTJ.meth6(Array[String]("abc")) // Ok
// newOTJ.meth5(Array[Int](1)) // error: Array[Int] is not a subtype of Array[Object]
// newOTJ.meth6(Array[Int](1)) // error: Array[Int] is not a subtype of Array[T & Object]
newOTJ.meth7(1) // OK (creates a reference array)
newOTJ.meth8(1) // OK (creates a primitive array and copies it into a reference array at Erasure)
val li = Array[Int](1)
newOTJ.meth7(li: _*) // OK (will copy the array at Erasure)
newOTJ.meth8(li: _*) // OK (will copy the array at Erasure)

newOTJInner.meth1(1) // OK
newOTJInner.meth2(1) // OK

assert((newOTJInner.field1: Int) == 23) // OK
newOTJInner.field1 = 31 // OK
assert((newOTJInner.getter1: Int) == 31) // OK
assert(newOTJInner.field2 == true) // OK
newOTJInner.field2 = false // OK
assert(newOTJInner.getter2 == false) // OK
}

38 changes: 38 additions & 0 deletions test/tasty/run-pipelined/src-3/lib/ObjectTpeJava.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// this test ensures that Object can accept Any from Scala
// see Definitions.ObjectTpeJava
package lib;

@SuppressWarnings("unchecked")
public class ObjectTpeJava {

public static class Inner<T> extends Object {
public T field1;
public T getter1() { return field1; }
public Object field2;
public Object getter2() { return field2; }

public Inner(T param1, Object param2) {
this.field1 = param1;
this.field2 = param2;
}

public void meth1(T arg) {}
public <U extends T> void meth2(U arg) {}
}

// 1. At the top level:
public void meth1(Object arg) {}
public <T> void meth2(T arg) {} // T implicitly extends Object

// 2. In a class type argument:
public void meth3(scala.collection.immutable.List<Object> arg) {}
public <T> void meth4(scala.collection.immutable.List<T> arg) {}

// 3. As the type argument of an array:
public void meth5(Object[] arg) {}
public <T> void meth6(T[] arg) {}

// 4. As the repeated argument of a varargs method:
public void meth7(Object... args) {}
public <T> void meth8(T... args) {}
}

0 comments on commit 3934cdf

Please sign in to comment.