diff --git a/tasty-query/shared/src/main/scala/tastyquery/Flags.scala b/tasty-query/shared/src/main/scala/tastyquery/Flags.scala index 709f27ca..7f619fe1 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Flags.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Flags.scala @@ -19,6 +19,7 @@ private[tastyquery] object Flags: def |(otherFlags: FlagSet): FlagSet = bits | otherFlags.bits def &(otherFlags: FlagSet): FlagSet = bits & otherFlags.bits + def &~(otherFlags: FlagSet): FlagSet = bits & ~otherFlags.bits def show: String = val result = new java.lang.StringBuilder diff --git a/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala b/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala index 6b74e714..d0bf0309 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala @@ -214,12 +214,21 @@ private[pickles] class PickleReader { if storedWhileReadingOwner != null then return storedWhileReadingOwner.asInstanceOf[MaybeExternalSymbol] val pickleFlags = readPickleFlags(name1.isTypeName) - val flags = pickleFlagsToFlags(pickleFlags) + val flags0 = pickleFlagsToFlags(pickleFlags) val name = - if pickleFlags.isType && flags.is(Module) then name1.toTermName.withObjectSuffix.toTypeName - else if flags.is(Method) && (name1 == Scala2Constructor || name1 == Scala2TraitConstructor) then nme.Constructor + if pickleFlags.isType && flags0.is(Module) then name1.toTermName.withObjectSuffix.toTypeName + else if flags0.is(Method) && (name1 == Scala2Constructor || name1 == Scala2TraitConstructor) then nme.Constructor else name1 + // Adapt the flags of getters so they become like vals/vars instead + val flags = + if flags0.isAllOf(Method | Accessor) && !name.toString().endsWith("_=") then + val flags1 = flags0 &~ (Method | Accessor) + if flags1.is(StableRealizable) then flags1 + else flags1 | Mutable + else flags0 + end flags + val (privateWithin, infoRef) = { val ref = pkl.readNat() if (!isSymbolRef(ref)) (None, ref) @@ -291,10 +300,16 @@ private[pickles] class PickleReader { cls.withGivenSelfType(givenSelfType) cls case VALsym => - // Discard `$extension` methods, as they should not be seen from a Scala 3 point of view + /* Discard symbols that should not be seen from a Scala 3 point of view: + * - private fields generated for vals/vars (with a trailing ' ' in their name) + * - `$extension` methods + */ val forceNotDeclaration = name1 match - case SimpleName(str) => flags.is(Method) && str.endsWith("$extension") - case _ => false + case SimpleName(str) => + if flags.is(Method) then str.endsWith("$extension") + else if flags.isAllOf(Private | Local, butNotAnyOf = Method) then str.endsWith(" ") + else false + case _ => false val sym = if pickleFlags.isExistential || forceNotDeclaration then TermSymbol.createNotDeclaration(name.toTermName, owner) diff --git a/tasty-query/shared/src/test/scala/tastyquery/SymbolSuite.scala b/tasty-query/shared/src/test/scala/tastyquery/SymbolSuite.scala index 34c3fe84..a0d2c75b 100644 --- a/tasty-query/shared/src/test/scala/tastyquery/SymbolSuite.scala +++ b/tasty-query/shared/src/test/scala/tastyquery/SymbolSuite.scala @@ -277,4 +277,24 @@ class SymbolSuite extends RestrictedUnpicklingSuite { testVisibility("scopedProtectedField", Visibility.ScopedProtected(simpleTreesPkg)) testVisibility("publicField", Visibility.Public) } + + testWithContext("scala-2-getters", "scala.StringContext", "scala.collection.mutable.ArrayBuffer") { + val StringContextClass = ctx.findTopLevelClass("scala.StringContext") + + val partsSym = StringContextClass.findDecl(termName("parts")) + assert(clue(partsSym.kind) == TermSymbolKind.Val) + assert(clue(partsSym.visibility) == Visibility.Public) + + assert(clue(StringContextClass.getDecl(termName("parts "))).isEmpty) + assert(!clue(StringContextClass.declarations).exists(_.name == termName("parts "))) + + val ArrayBufferClass = ctx.findTopLevelClass("scala.collection.mutable.ArrayBuffer") + + val size0Sym = ArrayBufferClass.findDecl(termName("size0")) + assert(clue(size0Sym.kind) == TermSymbolKind.Var) + assert(clue(size0Sym.visibility) == Visibility.Protected) + + assert(clue(ArrayBufferClass.getDecl(termName("size0 "))).isEmpty) + assert(!clue(ArrayBufferClass.declarations).exists(_.name == termName("size0 "))) + } }