Skip to content

Commit

Permalink
Merge pull request #10700 from scalacenter/fix-classpath-issue
Browse files Browse the repository at this point in the history
".tasty" files are no longer considered source files of a symbol.
  • Loading branch information
lrytz committed Feb 26, 2024
2 parents 5359ece + 08e81d1 commit 577ab8e
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 4 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Expand Up @@ -712,7 +712,7 @@ lazy val partest = configureAsSubproject(project)
)

lazy val tastytest = configureAsSubproject(project)
.dependsOn(library, reflect, compiler)
.dependsOn(library, reflect, compiler, scaladoc)
.settings(disableDocs)
.settings(fatalWarningsSettings)
.settings(publish / skip := true)
Expand Down
Expand Up @@ -173,7 +173,7 @@ abstract class ClassfileParser(reader: ReusableInstance[ReusableDataReader]) {
AnyRefClass

val bytes = in.buf.take(file.sizeOption.get)
TastyUnpickler.unpickle(TastyUniverse)(bytes, clazz, staticModule, file.path.stripSuffix(".class") + ".tasty")
TastyUnpickler.unpickle(TastyUniverse)(bytes, clazz, staticModule, file.path)
} else {
parseHeader()
this.pool = new ConstantPool
Expand Down
2 changes: 1 addition & 1 deletion src/reflect/scala/reflect/internal/Symbols.scala
Expand Up @@ -2635,7 +2635,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (
(file eq NoAbstractFile) || {
val path = file.path
path.endsWith(".class") || path.endsWith(".sig")
path.endsWith(".class") || path.endsWith(".sig") || path.endsWith(".tasty")
}) null else file
}

Expand Down
76 changes: 76 additions & 0 deletions src/tastytest/scala/tools/tastytest/Scaladoc.scala
@@ -0,0 +1,76 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.tools.tastytest

import scala.collection.immutable.ArraySeq
import scala.util.{ Try, Success, chaining }, chaining._
import scala.tools.nsc.{ reporters}, reporters.{Reporter, ConsoleReporter}
import java.io.OutputStream
import java.io.PrintWriter

import scala.tools.nsc.{ScalaDoc => RealScaladoc, doc}
import scala.reflect.internal.util.NoPosition

object Scaladoc extends Script.Command {

def scaladoc(out: String, additionalSettings: Seq[String], sources: String*): Try[Boolean] =
scaladoc(Console.out, out, additionalSettings, sources:_*)

def scaladoc(writer: OutputStream, out: String, additionalSettings: Seq[String], sources: String*) = {

def setup(args: Seq[String]): (Reporter, doc.Settings, RealScaladoc.Command) = {
lazy val (reporter: Reporter, docSettings) = {
val docSettings = new doc.Settings(msg => reporter.error(NoPosition, msg), msg => reporter.echo(msg))
val pwriter = new PrintWriter(writer, true)
(new ConsoleReporter(docSettings, Console.in, pwriter).tap(_.shortname = true), docSettings)
}
(reporter, docSettings, new RealScaladoc.Command(args.toList, docSettings))
}

def compile(args: String*): Try[Boolean] = {
val (reporter, docSettings, command) = setup(args)
Try {
assert(command.files.nonEmpty, "no files to compile")
try { new doc.DocFactory(reporter, docSettings).document(command.files) }
finally reporter.finish()
}.map(_ => !reporter.hasErrors)
}

if (sources.isEmpty) {
Success(true)
}
else {
val settings = Array(
"-d", out,
"-classpath", out,
"-deprecation",
"-Xfatal-warnings",
"-usejavacp"
) ++ additionalSettings ++ sources
compile(ArraySeq.unsafeWrapArray(settings):_*)
}
}

val commandName: String = "scaladoc"
val describe: String = s"$commandName <out: Directory> <src: File> <args: String*>"

def process(args: String*): Int = {
if (args.length < 2) {
println(red(s"please provide at least 2 arguments in sub-command: $describe"))
return 1
}
val Seq(out, src, additionalArgs @ _*) = args: @unchecked
val success = scaladoc(out, additionalArgs, src).get
if (success) 0 else 1
}
}
22 changes: 21 additions & 1 deletion src/tastytest/scala/tools/tastytest/TastyTest.scala
Expand Up @@ -99,7 +99,21 @@ object TastyTest {
_ <- scalacPos(out, individualCapable=true, sourceRoot=srcRoot/src/"src-2", additionalSettings, src2:_*)
} yield ()

/**Simulates a Scala 2 application that depends on a Scala 3 library, and is expected to fail compilation.

/**Simulates running scaladoc on a Scala 2 library that depends on a Scala 3 library.
* Steps:
* 1) compile all Scala files in `src-3` with scala 3 to `out`, with `out` as the classpath
* 2) compile all Scala files in `src-2` with scaladoc (scala 2) to `out`, with `out` as the classpath
*/
def posDocSuite(src: String, srcRoot: String, pkgName: String, outDir: Option[String], additionalSettings: Seq[String], additionalDottySettings: Seq[String])(implicit cl: Dotc.ClassLoader): Try[Unit] = for {
(src2, src3) <- get2And3Sources(srcRoot/src, src2Filters = Set(Scala), src3Filters = Set(Scala))
_ = log(s"Sources to compile under test: ${src2.map(cyan).mkString(", ")}")
out <- outDir.fold(tempDir(pkgName))(dir)
_ <- dotcPos(out, sourceRoot=srcRoot/src/"src-3", additionalDottySettings, src3:_*)
_ <- scaladoc(out, sourceRoot=srcRoot/src/"src-2", additionalSettings, src2:_*)
} yield ()

/**Simulates a Scala 2 application that depends on a Scala 3 library, and is expected to fail compilation.
* Steps:
* 1) compile all Scala files in `src-3` with scala 3 to `out`
* 2) attempt to compile all Scala files in `src-2` with scala 2 to `out`, with `out` as the classpath.
Expand Down Expand Up @@ -225,6 +239,12 @@ object TastyTest {
successWhen(res)("scalac failed to compile sources.")
}

private def scaladoc(out: String, sourceRoot: String, additionalSettings: Seq[String], sources: String*): Try[Unit] = {
log(s"compiling sources in ${yellow(sourceRoot)} with scalac.")
val res = Scaladoc.scaladoc(out, "-Ytasty-reader" +: additionalSettings, sources:_*)
successWhen(res)("scaladoc failed to compile resources")
}

private def scalacNeg(out: String, additionalSettings: Seq[String], files: String*): Try[Unit] =
scalacNeg(out, extraCp = None, additionalSettings, files:_*)

Expand Down
8 changes: 8 additions & 0 deletions test/tasty/pos-doctool/src-2/app/Main.scala
@@ -0,0 +1,8 @@
package app

object Main {
def main(args: Array[String]): Unit = {
println(testlib.ADT.SingletonCase)
println(testlib.ADT.ClassCase("foo"))
}
}
5 changes: 5 additions & 0 deletions test/tasty/pos-doctool/src-3/testlib/ADT.scala
@@ -0,0 +1,5 @@
package testlib

enum ADT:
case SingletonCase
case ClassCase(x: String)
9 changes: 9 additions & 0 deletions test/tasty/test/scala/tools/tastytest/TastyTestJUnit.scala
Expand Up @@ -51,6 +51,15 @@ class TastyTestJUnit {
additionalDottySettings = Nil
).eval

@test def posDoctool(): Unit = TastyTest.posDocSuite(
src = "pos-doctool",
srcRoot = assertPropIsSet(propSrc),
pkgName = assertPropIsSet(propPkgName),
outDir = None,
additionalSettings = Nil,
additionalDottySettings = Nil
).eval

@test def neg(): Unit = TastyTest.negSuite(
src = "neg",
srcRoot = assertPropIsSet(propSrc),
Expand Down

0 comments on commit 577ab8e

Please sign in to comment.