Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/MainGenericCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ case class CompileSettings(

object MainGenericCompiler {

val classpathSeparator = File.pathSeparator
val classpathSeparator: String = File.pathSeparator

@sharable val javaOption = raw"""-J(.*)""".r
@sharable val javaPropOption = raw"""-D(.+?)=(.?)""".r
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/MainGenericRunner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ case class Settings(

object MainGenericRunner {

val classpathSeparator = File.pathSeparator
val classpathSeparator: String = File.pathSeparator

def processClasspath(cp: String, tail: List[String]): (List[String], List[String]) =
val cpEntries = cp.split(classpathSeparator).toList
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/backend/jvm/CodeGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class CodeGen(val int: DottyBackendInterface, val primitives: DottyPrimitives)(
new interfaces.AbstractFile {
override def name = absfile.name
override def path = absfile.path
override def jfile = Optional.ofNullable(absfile.file)
override def jfile: Optional[java.io.File] = Optional.ofNullable(absfile.file)
}

private def genClass(cd: TypeDef, unit: CompilationUnit): ClassNode = {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2959,7 +2959,7 @@ object SymDenotations {
dependent = null
}

protected def addDependent(dep: InheritedCache) = {
protected def addDependent(dep: InheritedCache): Unit = {
if (dependent == null) dependent = new WeakHashMap
dependent.nn.put(dep, ())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
private def classesFromDir(dir: Path, buffer: mutable.ListBuffer[TypeName]): Unit =
try
Files.walkFileTree(dir, new SimpleFileVisitor[Path] {
override def visitFile(path: Path, attrs: BasicFileAttributes) = {
override def visitFile(path: Path, attrs: BasicFileAttributes): FileVisitResult = {
if (!attrs.isDirectory) {
val name = path.getFileName.toString
if name.endsWith(tastySuffix) then
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/sbt/APIUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import xsbti.api.SafeLazy.strict
*/
object APIUtils {
private object Constants {
val PublicAccess = api.Public.create()
val EmptyModifiers = new api.Modifiers(false, false, false, false, false, false, false, false)
val EmptyStructure = api.Structure.of(strict(Array.empty), strict(Array.empty), strict(Array.empty))
val EmptyType = api.EmptyType.of()
val PublicAccess: api.Public = api.Public.create()
val EmptyModifiers: api.Modifiers = new api.Modifiers(false, false, false, false, false, false, false, false)
val EmptyStructure: api.Structure = api.Structure.of(strict(Array.empty), strict(Array.empty), strict(Array.empty))
val EmptyType: api.EmptyType = api.EmptyType.of()
}

import Constants.*
Expand Down
14 changes: 7 additions & 7 deletions compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,13 @@ private class ExtractAPICollector(nonLocalClassSymbols: mutable.HashSet[Symbol])

private object Constants {
val emptyStringArray = Array[String]()
val local = api.ThisQualifier.create()
val public = api.Public.create()
val privateLocal = api.Private.create(local)
val protectedLocal = api.Protected.create(local)
val unqualified = api.Unqualified.create()
val thisPath = api.This.create()
val emptyType = api.EmptyType.create()
val local: api.ThisQualifier = api.ThisQualifier.create()
val public: api.Public = api.Public.create()
val privateLocal: api.Private = api.Private.create(local)
val protectedLocal: api.Protected = api.Protected.create(local)
val unqualified: api.Unqualified = api.Unqualified.create()
val thisPath: api.This = api.This.create()
val emptyType: api.EmptyType = api.EmptyType.create()
val emptyModifiers =
new api.Modifiers(false, false, false, false, false,false, false, false)
}
Expand Down
14 changes: 14 additions & 0 deletions compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,18 @@ object RefChecks {
report.warning(ExtensionNullifiedByMember(sym, target), sym.srcPos)
end checkExtensionMethods

/** Check that public (and protected) methods/fields do not expose flexible types. */
def checkPublicFlexibleTypes(sym: Symbol)(using Context): Unit =
if ctx.explicitNulls && !ctx.isJava
&& sym.exists && !sym.is(Private) && sym.owner.isClass
&& !sym.isOneOf(Synthetic | InlineProxy | Param | Exported) then
val resTp = sym.info.finalResultType
if resTp.existsPart(_.isInstanceOf[FlexibleType], StopAt.Static) then
report.warning(
em"${sym.show} exposes a flexible type in its inferred result type ${resTp}. Consider annotating the type explicitly",
sym.srcPos
)

/** Verify that references in the user-defined `@implicitNotFound` message are valid.
* (i.e. they refer to a type variable that really occurs in the signature of the annotated symbol.)
*/
Expand Down Expand Up @@ -1330,6 +1342,7 @@ class RefChecks extends MiniPhase { thisPhase =>
val sym = tree.symbol
checkNoPrivateOverrides(sym)
checkVolatile(sym)
checkPublicFlexibleTypes(sym)
if (sym.exists && sym.owner.isTerm) {
tree.rhs match {
case Ident(nme.WILDCARD) => report.error(UnboundPlaceholderParameter(), sym.srcPos)
Expand All @@ -1345,6 +1358,7 @@ class RefChecks extends MiniPhase { thisPhase =>
checkImplicitNotFoundAnnotation.defDef(sym.denot)
checkUnaryMethods(sym)
checkExtensionMethods(sym)
checkPublicFlexibleTypes(sym)
tree
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/io/Path.scala
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,12 @@ class Path private[io] (val jpath: JPath) {
if (!exists) false
else {
Files.walkFileTree(jpath, new SimpleFileVisitor[JPath]() {
override def visitFile(file: JPath, attrs: BasicFileAttributes) = {
override def visitFile(file: JPath, attrs: BasicFileAttributes): FileVisitResult = {
Files.delete(file)
FileVisitResult.CONTINUE
}

override def postVisitDirectory(dir: JPath, exc: IOException) = {
override def postVisitDirectory(dir: JPath, exc: IOException): FileVisitResult = {
Files.delete(dir)
FileVisitResult.CONTINUE
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/repl/AbstractFileClassLoader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader) exten
// on JDK 20 the URL constructor we're using is deprecated,
// but the recommended replacement, URL.of, doesn't exist on JDK 8
@annotation.nowarn("cat=deprecation")
override protected def findResource(name: String) =
override protected def findResource(name: String): URL | Null =
findAbstractFile(name) match
case null => null
case file => new URL(null, s"memory:${file.path}", new URLStreamHandler {
Expand All @@ -35,13 +35,13 @@ class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader) exten
override def getInputStream = file.input
}
})
override protected def findResources(name: String) =
override protected def findResources(name: String): java.util.Enumeration[URL] =
findResource(name) match
case null => Collections.enumeration(Collections.emptyList[URL]) //Collections.emptyEnumeration[URL]
case url => Collections.enumeration(Collections.singleton(url))

override def findClass(name: String): Class[?] = {
var file: AbstractFile = root
var file: AbstractFile | Null = root
val pathParts = name.split("[./]").toList
for (dirPart <- pathParts.init) {
file = file.lookupName(dirPart, true)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/repl/JLineTerminal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class JLineTerminal extends java.io.Closeable {
) extends reader.ParsedLine {
// Using dummy values, not sure what they are used for
def wordIndex = -1
def words = java.util.Collections.emptyList[String]
def words: java.util.List[String] = java.util.Collections.emptyList[String]
}

def parse(input: String, cursor: Int, context: ParseContext): reader.ParsedLine = {
Expand Down
13 changes: 7 additions & 6 deletions compiler/src/dotty/tools/repl/ScriptEngine.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,21 @@ class ScriptEngine extends AbstractScriptEngine {

object ScriptEngine {
import java.util.Arrays
import java.util.List
Copy link
Preview

Copilot AI Sep 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import for java.util.List is added but the existing java.util.Arrays import already covers the usage. This creates redundant imports that could be consolidated.

Suggested change
import java.util.List

Copilot uses AI. Check for mistakes.

import scala.util.Properties

class Factory extends ScriptEngineFactory {
def getEngineName = "Scala REPL"
def getEngineVersion = "3.0"
def getExtensions = Arrays.asList("scala")
def getExtensions: List[String] = Arrays.asList("scala")
def getLanguageName = "Scala"
def getLanguageVersion = Properties.versionString
def getMimeTypes = Arrays.asList("application/x-scala")
def getNames = Arrays.asList("scala")
def getMimeTypes: List[String] = Arrays.asList("application/x-scala")
def getNames: List[String] = Arrays.asList("scala")

def getMethodCallSyntax(obj: String, m: String, args: String*) = s"$obj.$m(${args.mkString(", ")})"
def getMethodCallSyntax(obj: String, m: String, args: String*): String = s"$obj.$m(${args.mkString(", ")})"

def getOutputStatement(toDisplay: String) = s"""print("$toDisplay")"""
def getOutputStatement(toDisplay: String): String = s"""print("$toDisplay")"""

def getParameter(key: String): Object = key match {
case JScriptEngine.ENGINE => getEngineName
Expand All @@ -88,7 +89,7 @@ object ScriptEngine {
case _ => null
}

def getProgram(statements: String*) = statements.mkString("; ")
def getProgram(statements: String*): String = statements.mkString("; ")

def getScriptEngine: JScriptEngine = new ScriptEngine
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ object BestEffortTastyFormat {
// added AST tag - Best Effort TASTy only
final val ERRORtype = 50

def astTagToString(tag: Int) = tag match {
def astTagToString(tag: Int): String = tag match {
case ERRORtype => "ERRORtype"
case _ => TastyFormat.astTagToString(tag)
}
Expand Down
22 changes: 13 additions & 9 deletions compiler/test/dotty/tools/dotc/TupleShowTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,24 +54,28 @@ class TupleShowTests extends DottyTest:

@Test def tup3_show10 = chkEq("(Int,\n Long,\n Short)".normEOL, tup3.toText(ctx.printer).mkString(10, false))

val res21 = """|(Int, Int, Int, Int, Int, Long, Long, Long, Long, Long, Int, Int, Int, Int,
| Int, Long, Long, Long, Long, Long, Int)""".stripMargin.normEOL
val res21: String =
"""|(Int, Int, Int, Int, Int, Long, Long, Long, Long, Long, Int, Int, Int, Int,
| Int, Long, Long, Long, Long, Long, Int)""".stripMargin.normEOL

val res22 = """|(Int, Int, Int, Int, Int, Long, Long, Long, Long, Long, Int, Int, Int, Int,
| Int, Long, Long, Long, Long, Long, Int, Long)""".stripMargin.normEOL
val res22: String =
"""|(Int, Int, Int, Int, Int, Long, Long, Long, Long, Long, Int, Int, Int, Int,
| Int, Long, Long, Long, Long, Long, Int, Long)""".stripMargin.normEOL

val res23 = """|(Int, Int, Int, Int, Int, Long, Long, Long, Long, Long, Int, Int, Int, Int,
| Int, Long, Long, Long, Long, Long, Int, Long, Short)""".stripMargin.normEOL
val res23: String =
"""|(Int, Int, Int, Int, Int, Long, Long, Long, Long, Long, Int, Int, Int, Int,
| Int, Long, Long, Long, Long, Long, Int, Long, Short)""".stripMargin.normEOL

val res24 = """|(Int, Int, Int, Int, Int, Long, Long, Long, Long, Long, Int, Int, Int, Int,
| Int, Long, Long, Long, Long, Long, Int, Long, Short, Short)""".stripMargin.normEOL
val res24: String =
"""|(Int, Int, Int, Int, Int, Long, Long, Long, Long, Long, Int, Int, Int, Int,
| Int, Long, Long, Long, Long, Long, Int, Long, Short, Short)""".stripMargin.normEOL

def chkEq[A](expected: A, obtained: A) = assert(expected == obtained, diff(s"$expected", s"$obtained"))

/** On Windows the string literal in this test source file will be read with `\n` (b/c of "-encoding UTF8")
* but the compiler will correctly emit \r\n as the line separator.
* So we align the expected result to faithfully compare test results. */
extension (str: String) def normEOL = if EOL == "\n" then str else str.replace("\n", EOL)
extension (str: String) def normEOL: String = if EOL == "\n" then str else str.replace("\n", EOL)

def diff(exp: String, obt: String) =
val min = math.min(exp.length, obt.length)
Expand Down
16 changes: 8 additions & 8 deletions compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import dotty.tools.dotc.util.SourceFile
* only 1 semanticdb file should be present
* @param source the single source file producing the semanticdb
*/
@main def metac(root: String, source: String) =
@main def metac(root: String, source: String): Unit =
val rootSrc = Paths.get(root)
val sourceSrc = Paths.get(source)
val semanticFile = FileSystems.getDefault.getPathMatcher("glob:**.semanticdb")
Expand All @@ -53,13 +53,13 @@ import dotty.tools.dotc.util.SourceFile

@Category(Array(classOf[BootstrappedOnlyTests]))
class SemanticdbTests:
val javaFile = FileSystems.getDefault.getPathMatcher("glob:**.java")
val scalaFile = FileSystems.getDefault.getPathMatcher("glob:**.scala")
val expectFile = FileSystems.getDefault.getPathMatcher("glob:**.expect.scala")
val rootSrc = Paths.get(System.getProperty("dotty.tools.dotc.semanticdb.test"))
val expectSrc = rootSrc.resolve("expect")
val javaRoot = rootSrc.resolve("javacp")
val metacExpectFile = rootSrc.resolve("metac.expect")
val javaFile: PathMatcher = FileSystems.getDefault.getPathMatcher("glob:**.java")
val scalaFile: PathMatcher = FileSystems.getDefault.getPathMatcher("glob:**.scala")
val expectFile: PathMatcher = FileSystems.getDefault.getPathMatcher("glob:**.expect.scala")
val rootSrc: Path = Paths.get(System.getProperty("dotty.tools.dotc.semanticdb.test"))
val expectSrc: Path = rootSrc.resolve("expect")
val javaRoot: Path = rootSrc.resolve("javacp")
val metacExpectFile: Path = rootSrc.resolve("metac.expect")

@Category(Array(classOf[dotty.SlowTests]))
@Test def expectTests: Unit = if (!scala.util.Properties.isWin) runExpectTest(updateExpectFiles = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class AbstractFileClassLoaderTest:
// cf ScalaClassLoader#classBytes
extension (loader: ClassLoader)
// An InputStream representing the given class name, or null if not found.
def classAsStream(className: String) = loader.getResourceAsStream {
def classAsStream(className: String): InputStream = loader.getResourceAsStream {
if className.endsWith(".class") then className
else s"${className.replace('.', '/')}.class" // classNameToPath
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/test/dotty/tools/scripting/ScriptTestEnv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ object ScriptTestEnv {
}

extension(f: File) {
def name = f.getName
def name: String = f.getName
def norm: String = f.toPath.normalize.norm
def absPath: String = f.getAbsolutePath.norm
def relpath: Path = f.toPath.relpath
Expand All @@ -305,7 +305,7 @@ object ScriptTestEnv {
// dist[*]/target/universal/stage, if present
// else, SCALA_HOME if defined
// else, not defined
lazy val envScalaHome =
lazy val envScalaHome: String =
printf("scalacPath: %s\n", scalacPath.norm)
if scalacPath.isFile then scalacPath.replaceAll("/bin/scalac", "")
else envOrElse("SCALA_HOME", "not-found").norm
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/dotty/tools/utils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def scriptsDir(path: String): File = {
dir
}

extension (f: File) def absPath =
extension (f: File) def absPath: String =
f.getAbsolutePath.replace('\\', '/')

extension (str: String) def dropExtension =
Expand Down
4 changes: 2 additions & 2 deletions compiler/test/dotty/tools/vulpix/ParallelTesting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,8 @@ trait ParallelTesting extends RunnerOrchestration:

import summaryReport._

protected final val realStdout = System.out
protected final val realStderr = System.err
protected final val realStdout: PrintStream = System.out
protected final val realStderr: PrintStream = System.err

/** A runnable that logs its contents in a buffer */
trait LoggedRunnable extends Runnable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class InferExpectedType(
driver: InteractiveDriver,
params: OffsetParams
)(implicit rc: ReportContext):
val uri = params.uri().nn
val code = params.text().nn
val uri: java.net.URI = params.uri()
val code: String = params.text()

val sourceFile = SourceFile.virtual(uri, code)
driver.run(uri, sourceFile)
Expand Down
Loading
Loading