Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
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) 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
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
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ class PcInlayHintsProvider(
symbolSearch: SymbolSearch,
)(using ReportContext):

val uri = params.uri().nn
val filePath = Paths.get(uri).nn
val sourceText = params.text().nn
val text = sourceText.toCharArray().nn
val source =
val uri: java.net.URI = params.uri()
val filePath: java.nio.file.Path = Paths.get(uri)
val sourceText: String = params.text()
val text: Array[Char] = sourceText.toCharArray()
val source: SourceFile =
SourceFile.virtual(filePath.toString, sourceText)
driver.run(uri, source)
given InlayHintsParams = params
Expand Down Expand Up @@ -119,7 +119,7 @@ class PcInlayHintsProvider(
InlayHintKind.Type,
)
.addDefinition(adjustedPos.start)
case Parameters(isInfixFun, args) =>
case Parameters(isInfixFun, args) =>
def isNamedParam(pos: SourcePosition): Boolean =
val start = text.indexWhere(!_.isWhitespace, pos.start)
val end = text.lastIndexWhere(!_.isWhitespace, pos.end - 1)
Expand All @@ -142,9 +142,9 @@ class PcInlayHintsProvider(
case (ih, (name, pos0, isByName)) =>
val pos = adjustPos(pos0)
val isBlock = isBlockParam(pos)
val namedLabel =
val namedLabel =
if params.namedParameters() && !isInfixFun && !isBlock && !isNamedParam(pos) then s"${name} = " else ""
val byNameLabel =
val byNameLabel =
if params.byNameParameters() && isByName && (!isInfixFun || isBlock) then "=> " else ""

val labelStr = s"${namedLabel}${byNameLabel}"
Expand Down Expand Up @@ -432,19 +432,19 @@ object InferredType:
end InferredType

object Parameters:
def unapply(tree: Tree)(using params: InlayHintsParams, ctx: Context): Option[(Boolean, List[(Name, SourcePosition, Boolean)])] =
def shouldSkipFun(fun: Tree)(using Context): Boolean =
def unapply(tree: Tree)(using params: InlayHintsParams, ctx: Context): Option[(Boolean, List[(Name, SourcePosition, Boolean)])] =
def shouldSkipFun(fun: Tree)(using Context): Boolean =
fun match
case sel: Select => isForComprehensionMethod(sel) || sel.symbol.name == nme.unapply || sel.symbol.is(Flags.JavaDefined)
case _ => false

def isInfixFun(fun: Tree, args: List[Tree])(using Context): Boolean =
def isInfixFun(fun: Tree, args: List[Tree])(using Context): Boolean =
val isInfixSelect = fun match
case Select(sel, _) => sel.isInfix
case _ => false
val source = fun.source
if args.isEmpty then isInfixSelect
else
else
(!(fun.span.end until args.head.span.start)
.map(source.apply)
.contains('.') && fun.symbol.is(Flags.ExtensionMethod)) || isInfixSelect
Expand All @@ -467,23 +467,23 @@ object Parameters:

if (params.namedParameters() || params.byNameParameters()) then
tree match
case Apply(fun, args) if isRealApply(fun) =>
case Apply(fun, args) if isRealApply(fun) =>
val underlyingFun = getUnderlyingFun(fun)
if shouldSkipFun(underlyingFun) then
None
else
val funTp = fun.typeOpt.widenTermRefExpr
val paramNames = funTp.paramNamess.flatten
val paramInfos = funTp.paramInfoss.flatten

Some(
isInfixFun(fun, args) || underlyingFun.isInfix,
(
args
.zip(paramNames)
.zip(paramInfos)
.collect {
case ((arg, paramName), paramInfo) if !arg.span.isZeroExtent && !isDefaultArg(arg) =>
case ((arg, paramName), paramInfo) if !arg.span.isZeroExtent && !isDefaultArg(arg) =>
(paramName.fieldName, arg.sourcePos, paramInfo.isByName)
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ case class ScalaPresentationCompiler(
): PresentationCompiler =
copy(completionItemPriority = priority)

override def withBuildTargetName(buildTargetName: String) =
override def withBuildTargetName(buildTargetName: String): PresentationCompiler =
copy(buildTargetName = Some(buildTargetName))

override def withReportsLoggerLevel(level: String): PresentationCompiler =
Expand Down
Loading
Loading