From e149e4c62206088d18e82b8b41932abc2a28f19d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Rochala?= <48657087+rochala@users.noreply.github.com> Date: Wed, 8 Nov 2023 19:14:22 +0100 Subject: [PATCH] Add missing -Yexplicit-nulls for presentation compiler (#18776) With a new definition of untyped trees, it is now required to have `-Yexplicit-nulls` flag in modules that use them in order to have proper type checking. This PR adds the missing flag. Without the flag, it was possible to first assign untyped trees to typed trees, and secondly use extension methods for typed trees which can be seen at `KeywordsCompletions.scala` with usage of `untpdTree.filterSubtrees`. It is also blocked by: https://github.com/lampepfl/dotty/issues/18775 I can also make a workaround in the unmanaged module, but it will require a dependency on nightly version / a new release from metals. --- .../src/main/dotty/tools/pc/AutoImports.scala | 4 +- .../dotty/tools/pc/AutoImportsProvider.scala | 13 ++- .../tools/pc/CompilerSearchVisitor.scala | 6 +- .../tools/pc/CompletionItemResolver.scala | 10 +- .../pc/ConvertToNamedArgumentsProvider.scala | 11 +-- .../tools/pc/ExtractMethodProvider.scala | 8 +- .../main/dotty/tools/pc/HoverProvider.scala | 17 ++-- .../main/dotty/tools/pc/IndexedContext.scala | 6 +- .../dotty/tools/pc/InferredTypeProvider.scala | 31 +++---- .../main/dotty/tools/pc/MetalsDriver.scala | 2 +- .../src/main/dotty/tools/pc/PcCollector.scala | 13 ++- .../dotty/tools/pc/PcDefinitionProvider.scala | 7 +- .../tools/pc/PcInlineValueProviderImpl.scala | 4 +- .../tools/pc/PcSemanticTokensProvider.scala | 2 +- .../tools/pc/ScalaPresentationCompiler.scala | 38 ++++---- .../tools/pc/SelectionRangeProvider.scala | 5 +- .../pc/SemanticdbTextDocumentProvider.scala | 12 +-- .../tools/pc/SignatureHelpProvider.scala | 24 ++--- .../src/main/dotty/tools/pc/TastyUtils.scala | 6 +- .../completions/AmmoniteFileCompletions.scala | 38 ++++---- .../completions/AmmoniteIvyCompletions.scala | 4 +- .../tools/pc/completions/CompletionPos.scala | 17 +--- .../pc/completions/CompletionProvider.scala | 41 ++++----- .../pc/completions/CompletionValue.scala | 2 +- .../tools/pc/completions/Completions.scala | 22 ++--- .../completions/InterpolatorCompletions.scala | 2 +- .../pc/completions/KeywordsCompletions.scala | 80 ++++++++-------- .../pc/completions/MatchCaseCompletions.scala | 25 ++--- .../MultilineCommentCompletion.scala | 2 +- .../pc/completions/NamedArgCompletions.scala | 11 ++- .../pc/completions/OverrideCompletions.scala | 92 ++++++++++--------- .../pc/completions/ScaladocCompletions.scala | 2 +- .../pc/printer/ShortenedTypePrinter.scala | 4 +- .../tools/pc/utils/MtagsEnrichments.scala | 24 ++--- .../tools/pc/base/BaseAutoImportsSuite.scala | 1 + .../tools/pc/base/BaseCodeActionSuite.scala | 1 + .../tools/pc/base/BaseCompletionSuite.scala | 1 + .../pc/base/BaseDocumentHihglightSuite.scala | 1 + .../pc/base/BaseExtractMethodSuite.scala | 1 + .../dotty/tools/pc/base/BaseHoverSuite.scala | 1 + .../dotty/tools/pc/base/BasePCSuite.scala | 1 + .../tools/pc/base/BasePcDefinitionSuite.scala | 1 + .../tools/pc/base/BasePcRenameSuite.scala | 1 + .../pc/base/BaseSelectionRangeSuite.scala | 1 + .../pc/base/BaseSemanticTokensSuite.scala | 1 + .../pc/base/BaseSignatureHelpSuite.scala | 1 + .../tools/pc/base/ReusableClassRunner.scala | 1 + .../pc/tests/CompilerJobQueueSuite.scala | 1 + .../tools/pc/tests/PcSemanticdbSuite.scala | 1 + .../completion/CompletionCancelSuite.scala | 1 + .../completion/CompletionKeywordSuite.scala | 13 +++ .../pc/tests/completion/CompletionSuite.scala | 1 + .../tests/definition/PcDefinitionSuite.scala | 1 + .../definition/TypeDefinitionSuite.scala | 1 + .../AutoImplementAbstractMembersSuite.scala | 1 + .../edit/ConvertToNamedArgumentsSuite.scala | 4 +- .../pc/tests/edit/InlineValueSuite.scala | 1 + .../tests/edit/InsertInferredTypeSuite.scala | 1 + .../tools/pc/utils/MockSymbolSearch.scala | 1 + .../dotty/tools/pc/utils/PcAssertions.scala | 2 + .../dotty/tools/pc/utils/RangeReplace.scala | 1 + .../tools/pc/utils/TestCompletions.scala | 1 + .../dotty/tools/pc/utils/TestHovers.scala | 1 + .../tools/pc/utils/TestSemanticTokens.scala | 1 + .../pc/utils/TestingWorkspaceSearch.scala | 1 + .../test/dotty/tools/pc/utils/TextEdits.scala | 1 + project/Build.scala | 8 +- .../AbstractMemberSignaturesTest.scala | 5 +- 68 files changed, 332 insertions(+), 314 deletions(-) diff --git a/presentation-compiler/src/main/dotty/tools/pc/AutoImports.scala b/presentation-compiler/src/main/dotty/tools/pc/AutoImports.scala index 4a204105d7b2..0ccaec14927c 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/AutoImports.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/AutoImports.scala @@ -23,7 +23,7 @@ object AutoImports: def renameConfigMap(config: PresentationCompilerConfig)(using Context ): Map[Symbol, String] = - config.symbolPrefixes.asScala.flatMap { (from, to) => + config.symbolPrefixes().nn.asScala.flatMap { (from, to) => val pkg = SemanticdbSymbols.inverseSemanticdbSymbol(from) val rename = to.stripSuffix(".").stripSuffix("#") List(pkg, pkg.map(_.moduleClass)).flatten @@ -246,7 +246,7 @@ object AutoImports: // see WorksheetProvider.worksheetScala3AdjustmentsForPC val indent = if pos.source.path.isWorksheet && - editPos.getStart().getCharacter() == 0 + editPos.getStart().nn.getCharacter() == 0 then indent0.drop(2) else indent0 val topPadding = diff --git a/presentation-compiler/src/main/dotty/tools/pc/AutoImportsProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/AutoImportsProvider.scala index 6a1b91cba31f..b95c5fb949e0 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/AutoImportsProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/AutoImportsProvider.scala @@ -29,13 +29,12 @@ final class AutoImportsProvider( )(using ReportContext): def autoImports(isExtension: Boolean): List[AutoImportsResult] = - val uri = params.uri + val uri = params.uri().nn + val text = params.text().nn val filePath = Paths.get(uri) - driver.run( - uri, - SourceFile.virtual(filePath.toString, params.text) - ) - val unit = driver.currentCtx.run.units.head + driver.run(uri, SourceFile.virtual(filePath.toString, text)) + + val unit = driver.currentCtx.run.nn.units.head val tree = unit.tpdTree val pos = driver.sourcePosition(params) @@ -81,7 +80,7 @@ final class AutoImportsProvider( val generator = AutoImports.generator( correctedPos, - params.text, + text, tree, unit.comments, indexedContext.importContext, diff --git a/presentation-compiler/src/main/dotty/tools/pc/CompilerSearchVisitor.scala b/presentation-compiler/src/main/dotty/tools/pc/CompilerSearchVisitor.scala index 2f7ee282450c..d217a0acd9b1 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/CompilerSearchVisitor.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/CompilerSearchVisitor.scala @@ -17,7 +17,7 @@ class CompilerSearchVisitor( )(using ctx: Context, reports: ReportContext) extends SymbolSearchVisitor: - val logger: Logger = Logger.getLogger(classOf[CompilerSearchVisitor].getName) + val logger: Logger = Logger.getLogger(classOf[CompilerSearchVisitor].getName().nn).nn private def isAccessible(sym: Symbol): Boolean = try sym != NoSymbol && sym.isPublic && sym.isStatic @@ -68,7 +68,7 @@ class CompilerSearchVisitor( .split("\\$") val added = - try toSymbols(pkg, innerPath.toList).filter(visitSymbol) + try toSymbols(pkg, innerPath.nn.toList.map(_.nn)).filter(visitSymbol) catch case NonFatal(e) => logger.log(Level.WARNING, e.getMessage(), e) @@ -95,6 +95,6 @@ class CompilerSearchVisitor( override def isCancelled: Boolean = false private def normalizePackage(pkg: String): String = - pkg.replace("/", ".").stripSuffix(".") + pkg.replace("/", ".").nn.stripSuffix(".") end CompilerSearchVisitor diff --git a/presentation-compiler/src/main/dotty/tools/pc/CompletionItemResolver.scala b/presentation-compiler/src/main/dotty/tools/pc/CompletionItemResolver.scala index d393e9204c27..4a20ab0f8e5f 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/CompletionItemResolver.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/CompletionItemResolver.scala @@ -30,7 +30,7 @@ object CompletionItemResolver extends ItemResolver: .orElse( search.symbolDocumentation(gsym.companion) ) match - case Some(info) if item.getDetail != null => + case Some(info) if item.getDetail() != null => enrichDocs( item, info, @@ -50,7 +50,7 @@ object CompletionItemResolver extends ItemResolver: Context ): String = def docs(gsym: Symbol): String = - search.symbolDocumentation(gsym).fold("")(_.docstring()) + search.symbolDocumentation(gsym).fold("")(_.docstring().nn) val gsymDoc = docs(gsym) def keyword(gsym: Symbol): String = if gsym.isClass then "class" @@ -60,7 +60,7 @@ object CompletionItemResolver extends ItemResolver: else "" val companion = gsym.companion if companion == NoSymbol || gsym.is(JavaDefined) then - if gsymDoc.isEmpty then + if gsymDoc.isEmpty() then if gsym.isAliasType then fullDocstring(gsym.info.metalsDealias.typeSymbol, search) else if gsym.is(Method) then @@ -73,8 +73,8 @@ object CompletionItemResolver extends ItemResolver: else gsymDoc else val companionDoc = docs(companion) - if companionDoc.isEmpty then gsymDoc - else if gsymDoc.isEmpty then companionDoc + if companionDoc.isEmpty() then gsymDoc + else if gsymDoc.isEmpty() then companionDoc else List( s"""|### ${keyword(companion)} ${companion.name} diff --git a/presentation-compiler/src/main/dotty/tools/pc/ConvertToNamedArgumentsProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/ConvertToNamedArgumentsProvider.scala index 99cc82cdf6a1..817ab5402c00 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/ConvertToNamedArgumentsProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/ConvertToNamedArgumentsProvider.scala @@ -23,13 +23,12 @@ final class ConvertToNamedArgumentsProvider( ): def convertToNamedArguments: Either[String, List[l.TextEdit]] = - val uri = params.uri + val uri = params.uri().nn + val text = params.text().nn val filePath = Paths.get(uri) - driver.run( - uri, - SourceFile.virtual(filePath.toString, params.text) - ) - val unit = driver.currentCtx.run.units.head + driver.run(uri, SourceFile.virtual(filePath.toString, text)) + + val unit = driver.currentCtx.run.nn.units.head val newctx = driver.currentCtx.fresh.setCompilationUnit(unit) val pos = driver.sourcePosition(params) val trees = driver.openedTrees(uri) diff --git a/presentation-compiler/src/main/dotty/tools/pc/ExtractMethodProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/ExtractMethodProvider.scala index cbdc39a90118..0b5fd1b06a8f 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/ExtractMethodProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/ExtractMethodProvider.scala @@ -38,12 +38,12 @@ final class ExtractMethodProvider( extends ExtractMethodUtils: def extractMethod(): List[TextEdit] = - val text = range.text() - val uri = range.uri + val text = range.text().nn + val uri = range.uri().nn val filePath = Paths.get(uri) val source = SourceFile.virtual(filePath.toString, text) driver.run(uri, source) - val unit = driver.currentCtx.run.units.head + val unit = driver.currentCtx.run.nn.units.head val pos = driver.sourcePosition(range).startPos val path = Interactive.pathTo(driver.openedTrees(uri), pos)(using driver.currentCtx) @@ -145,7 +145,7 @@ final class ExtractMethodProvider( val oldIndentLen = head.startPos.startColumnPadding.length() val toExtract = textToExtract( - range.text(), + text, head.startPos.start, expr.endPos.end, newIndent, diff --git a/presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala index 1ddb79fabc98..545607c0b8ff 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala @@ -32,8 +32,9 @@ object HoverProvider: driver: InteractiveDriver, search: SymbolSearch )(implicit reportContext: ReportContext): ju.Optional[HoverSignature] = - val uri = params.uri - val sourceFile = SourceFile.virtual(params.uri, params.text) + val uri = params.uri().nn + val text = params.text().nn + val sourceFile = SourceFile.virtual(uri, text) driver.run(uri, sourceFile) given ctx: Context = driver.currentCtx @@ -54,7 +55,7 @@ object HoverProvider: then def report = val posId = - if path.isEmpty || path.head.sourcePos == null || !path.head.sourcePos.exists + if path.isEmpty || !path.head.sourcePos.exists then pos.start else path.head.sourcePos.start Report( @@ -77,7 +78,7 @@ object HoverProvider: ) end report reportContext.unsanitized.create(report, ifVerbose = true) - ju.Optional.empty() + ju.Optional.empty().nn else val skipCheckOnName = !pos.isPoint // don't check isHoveringOnName for RangeHover @@ -125,7 +126,7 @@ object HoverProvider: val docString = symbolTpes .flatMap(symTpe => search.symbolDocumentation(symTpe._1)) - .map(_.docstring) + .map(_.docstring()) .mkString("\n") printer.expressionType(exprTpw) match case Some(expressionType) => @@ -143,9 +144,9 @@ object HoverProvider: docstring = Some(docString), forceExpressionType = forceExpressionType ) - ) + ).nn case _ => - ju.Optional.empty + ju.Optional.empty().nn end match end match end if @@ -188,7 +189,7 @@ object HoverProvider: refTpe.flatMap(findRefinement).asJava case _ => - ju.Optional.empty() + ju.Optional.empty().nn end HoverProvider diff --git a/presentation-compiler/src/main/dotty/tools/pc/IndexedContext.scala b/presentation-compiler/src/main/dotty/tools/pc/IndexedContext.scala index 03bc711e8f18..e31f4756b220 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/IndexedContext.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/IndexedContext.scala @@ -7,6 +7,7 @@ import dotty.tools.dotc.core.Contexts.* import dotty.tools.dotc.core.Flags.* import dotty.tools.dotc.core.NameOps.moduleClassName import dotty.tools.dotc.core.Names.* +import dotty.tools.dotc.core.Scopes.EmptyScope import dotty.tools.dotc.core.Symbols.* import dotty.tools.dotc.core.Types.* import dotty.tools.dotc.typer.ImportInfo @@ -82,7 +83,6 @@ object IndexedContext: def apply(ctx: Context): IndexedContext = ctx match - case null => Empty case NoContext => Empty case _ => LazyWrapper(using ctx) @@ -205,14 +205,14 @@ object IndexedContext: val (symbols, renames) = if ctx.isImportContext then val (syms, renames) = - fromImportInfo(ctx.importInfo) + fromImportInfo(ctx.importInfo.nn) .map((sym, rename) => (sym, rename.map(r => sym -> r.decoded))) .unzip (syms, renames.flatten.toMap) else if ctx.owner.isClass then val site = ctx.owner.thisType (accesibleMembers(site), Map.empty) - else if ctx.scope != null then (ctx.scope.toList, Map.empty) + else if ctx.scope != EmptyScope then (ctx.scope.toList, Map.empty) else (List.empty, Map.empty) val initial = Map.empty[String, List[Symbol]] diff --git a/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala index 578353ef4c90..69d89d5b0d13 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/InferredTypeProvider.scala @@ -62,14 +62,14 @@ final class InferredTypeProvider( adjustOpt: Option[AdjustTypeOpts] = None ): List[TextEdit] = val retryType = adjustOpt.isEmpty - val uri = params.uri - val filePath = Paths.get(uri) + val uri = params.uri().nn + val filePath = Paths.get(uri).nn - val sourceText = adjustOpt.map(_.text).getOrElse(params.text) + val sourceText = adjustOpt.map(_.text).getOrElse(params.text().nn) val source = - SourceFile.virtual(filePath.toString, sourceText) + SourceFile.virtual(filePath.toString(), sourceText) driver.run(uri, source) - val unit = driver.currentCtx.run.units.head + val unit = driver.currentCtx.run.nn.units.head val pos = driver.sourcePosition(params) val path = Interactive.pathTo(driver.openedTrees(uri), pos)(using driver.currentCtx) @@ -78,7 +78,7 @@ final class InferredTypeProvider( val indexedCtx = IndexedContext(locatedCtx) val autoImportsGen = AutoImports.generator( pos, - params.text, + sourceText, unit.tpdTree, unit.comments, indexedCtx, @@ -86,7 +86,7 @@ final class InferredTypeProvider( ) def removeType(nameEnd: Int, tptEnd: Int) = - sourceText.substring(0, nameEnd) + + sourceText.substring(0, nameEnd).nn + sourceText.substring(tptEnd + 1, sourceText.length()) def optDealias(tpe: Type): Type = @@ -134,7 +134,7 @@ final class InferredTypeProvider( def baseEdit(withParens: Boolean): TextEdit = val keywordOffset = if isParam then 0 else 4 val endPos = - findNamePos(params.text, vl, keywordOffset).endPos.toLsp + findNamePos(sourceText, vl, keywordOffset).endPos.toLsp adjustOpt.foreach(adjust => endPos.setEnd(adjust.adjustedEndPos)) new TextEdit( endPos, @@ -148,11 +148,10 @@ final class InferredTypeProvider( toCheckFor: Char, blockStartPos: SourcePosition ) = - val text = params.text - val isParensFunction: Boolean = text(applyEndingPos) == toCheckFor + val isParensFunction: Boolean = sourceText(applyEndingPos) == toCheckFor val alreadyHasParens = - text(blockStartPos.start) == '(' + sourceText(blockStartPos.start) == '(' if isParensFunction && !alreadyHasParens then new TextEdit(blockStartPos.toLsp, "(") :: baseEdit(withParens = @@ -188,7 +187,7 @@ final class InferredTypeProvider( Some( AdjustTypeOpts( removeType(vl.namePos.end, tpt.sourcePos.end - 1), - tpt.sourcePos.toLsp.getEnd() + tpt.sourcePos.toLsp.getEnd().nn ) ) ) @@ -227,7 +226,7 @@ final class InferredTypeProvider( Some( AdjustTypeOpts( removeType(lastColon, tpt.sourcePos.end - 1), - tpt.sourcePos.toLsp.getEnd() + tpt.sourcePos.toLsp.getEnd().nn ) ) ) @@ -256,8 +255,8 @@ final class InferredTypeProvider( val firstEnd = patterns(0).endPos.end val secondStart = patterns(1).startPos.start val hasDot = params - .text() - .substring(firstEnd, secondStart) + .text().nn + .substring(firstEnd, secondStart).nn .exists(_ == ',') if !hasDot then val leftParen = new TextEdit(body.startPos.toLsp, "(") @@ -309,7 +308,7 @@ final class InferredTypeProvider( val end = if withBacktick then idx + 1 else idx val pos = tree.source.atSpan(Span(start, end, start)) Some(pos) - case None if idx < text.length => + case None if idx < text.length() => val ch = text.charAt(idx) if ch == realName.head then lookup(idx + 1, Some((idx, realName.tail)), withBacktick) diff --git a/presentation-compiler/src/main/dotty/tools/pc/MetalsDriver.scala b/presentation-compiler/src/main/dotty/tools/pc/MetalsDriver.scala index 4f7ed751f958..55504db7a11a 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/MetalsDriver.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/MetalsDriver.scala @@ -48,7 +48,7 @@ class MetalsDriver( override def run(uri: URI, sourceCode: String): List[Diagnostic] = val diags = - if alreadyCompiled(uri, sourceCode.toCharArray()) then Nil + if alreadyCompiled(uri, sourceCode.toCharArray().nn) then Nil else super.run(uri, sourceCode) lastCompiledURI = uri diags diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala b/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala index 8ffd8ed28044..cf9e31cd4524 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala @@ -33,15 +33,15 @@ abstract class PcCollector[T]( params: VirtualFileParams ): private val caseClassSynthetics: Set[Name] = Set(nme.apply, nme.copy) - val uri = params.uri() - val filePath = Paths.get(uri) - val sourceText = params.text + val uri = params.uri().nn + val filePath = Paths.get(uri).nn + val sourceText = params.text().nn val source = - SourceFile.virtual(filePath.toString, sourceText) + SourceFile.virtual(filePath.toString(), sourceText) driver.run(uri, source) given ctx: Context = driver.currentCtx - val unit = driver.currentCtx.run.units.head + val unit = driver.currentCtx.run.nn.units.head val compilatonUnitContext = ctx.fresh.setCompilationUnit(unit) val offset = params match case op: OffsetParams => op.offset() @@ -49,8 +49,7 @@ abstract class PcCollector[T]( val offsetParams = params match case op: OffsetParams => op - case _ => - CompilerOffsetParams(params.uri(), params.text(), 0, params.token()) + case _ => CompilerOffsetParams(uri, sourceText, 0, params.token().nn) val pos = driver.sourcePosition(offsetParams) val rawPath = Interactive diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcDefinitionProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/PcDefinitionProvider.scala index 5d80b7d9be48..f010c8b2d95a 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcDefinitionProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcDefinitionProvider.scala @@ -36,11 +36,12 @@ class PcDefinitionProvider( definitions(findTypeDef = true) private def definitions(findTypeDef: Boolean): DefinitionResult = - val uri = params.uri + val uri = params.uri().nn + val text = params.text().nn val filePath = Paths.get(uri) driver.run( uri, - SourceFile.virtual(filePath.toString, params.text) + SourceFile.virtual(filePath.toString, text) ) val pos = driver.sourcePosition(params) @@ -53,7 +54,7 @@ class PcDefinitionProvider( if findTypeDef then findTypeDefinitions(path, pos, indexedContext) else findDefinitions(path, pos, indexedContext) - if result.locations().isEmpty() then fallbackToUntyped(pos)(using ctx) + if result.locations().nn.isEmpty() then fallbackToUntyped(pos)(using ctx) else result end definitions diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcInlineValueProviderImpl.scala b/presentation-compiler/src/main/dotty/tools/pc/PcInlineValueProviderImpl.scala index 2d4a9d8643c9..e591f89f0152 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcInlineValueProviderImpl.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcInlineValueProviderImpl.scala @@ -27,9 +27,9 @@ final class PcInlineValueProviderImpl( ) extends PcCollector[Option[Occurence]](driver, params) with InlineValueProvider: - val text = params.text.toCharArray() + val text = params.text().nn.toCharArray().nn - val position: l.Position = pos.toLsp.getStart() + val position: l.Position = pos.toLsp.getStart().nn override def collect(parent: Option[Tree])( tree: Tree | EndMarker, diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcSemanticTokensProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/PcSemanticTokensProvider.scala index d70fa32c2b10..92efcb034564 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcSemanticTokensProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcSemanticTokensProvider.scala @@ -69,7 +69,7 @@ final class PcSemanticTokensProvider( case tree: Tree => symbol.fold(tree.symbol)(identity) case EndMarker(sym) => sym - if !pos.exists || sym == null || sym == NoSymbol then None + if !pos.exists || sym == NoSymbol then None else Some( makeNode( diff --git a/presentation-compiler/src/main/dotty/tools/pc/ScalaPresentationCompiler.scala b/presentation-compiler/src/main/dotty/tools/pc/ScalaPresentationCompiler.scala index 3c201cb4634a..4dc9cd6d743f 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/ScalaPresentationCompiler.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/ScalaPresentationCompiler.scala @@ -12,6 +12,7 @@ import java.util as ju import scala.concurrent.ExecutionContext import scala.concurrent.ExecutionContextExecutor import scala.jdk.CollectionConverters._ +import scala.language.unsafeNulls import scala.meta.internal.metals.CompilerVirtualFileParams import scala.meta.internal.metals.EmptyCancelToken import scala.meta.internal.metals.EmptyReportContext @@ -36,6 +37,7 @@ import org.eclipse.lsp4j as l case class ScalaPresentationCompiler( buildTargetIdentifier: String = "", + buildTargetName: Option[String] = None, classpath: Seq[Path] = Nil, options: List[String] = Nil, search: SymbolSearch = EmptySymbolSearch, @@ -46,17 +48,21 @@ case class ScalaPresentationCompiler( reportsLevel: ReportLevel = ReportLevel.Info ) extends PresentationCompiler: - def this() = this("", Nil, Nil) + def this() = this("", None, Nil, Nil) val scalaVersion = BuildInfo.scalaVersion private val forbiddenOptions = Set("-print-lines", "-print-tasty") private val forbiddenDoubleOptions = Set("-release") + given ReportContext = folderPath - .map(StdReportContext(_, reportsLevel)) + .map(StdReportContext(_, _ => buildTargetName, reportsLevel)) .getOrElse(EmptyReportContext) + override def withBuildTargetName(buildTargetName: String) = + copy(buildTargetName = Some(buildTargetName)) + override def withReportsLoggerLevel(level: String): PresentationCompiler = copy(reportsLevel = ReportLevel.fromString(level)) @@ -111,7 +117,7 @@ case class ScalaPresentationCompiler( def complete(params: OffsetParams): CompletableFuture[l.CompletionList] = compilerAccess.withInterruptableCompiler(Some(params))( EmptyCompletionList(), - params.token + params.token() ) { access => val driver = access.compiler() new CompletionProvider( @@ -128,7 +134,7 @@ case class ScalaPresentationCompiler( def definition(params: OffsetParams): CompletableFuture[DefinitionResult] = compilerAccess.withInterruptableCompiler(Some(params))( DefinitionResultImpl.empty, - params.token + params.token() ) { access => val driver = access.compiler() PcDefinitionProvider(driver, params, search).definitions() @@ -139,7 +145,7 @@ case class ScalaPresentationCompiler( ): CompletableFuture[DefinitionResult] = compilerAccess.withInterruptableCompiler(Some(params))( DefinitionResultImpl.empty, - params.token + params.token() ) { access => val driver = access.compiler() PcDefinitionProvider(driver, params, search).typeDefinitions() @@ -150,7 +156,7 @@ case class ScalaPresentationCompiler( ): CompletableFuture[ju.List[DocumentHighlight]] = compilerAccess.withInterruptableCompiler(Some(params))( List.empty[DocumentHighlight].asJava, - params.token + params.token() ) { access => val driver = access.compiler() PcDocumentHighlightProvider(driver, params).highlights.asJava @@ -202,7 +208,7 @@ case class ScalaPresentationCompiler( ] = compilerAccess.withNonInterruptableCompiler(Some(params))( List.empty[scala.meta.pc.AutoImportsResult].asJava, - params.token + params.token() ) { access => val driver = access.compiler() new AutoImportsProvider( @@ -223,7 +229,7 @@ case class ScalaPresentationCompiler( val empty: ju.List[l.TextEdit] = new ju.ArrayList[l.TextEdit]() compilerAccess.withNonInterruptableCompiler(Some(params))( empty, - params.token + params.token() ) { pc => val driver = pc.compiler() OverrideCompletions.implementAllAt( @@ -241,7 +247,7 @@ case class ScalaPresentationCompiler( val empty: ju.List[l.TextEdit] = new ju.ArrayList[l.TextEdit]() compilerAccess.withNonInterruptableCompiler(Some(params))( empty, - params.token + params.token() ) { pc => new InferredTypeProvider(params, pc.compiler(), config, search) .inferredTypeEdits() @@ -253,7 +259,7 @@ case class ScalaPresentationCompiler( ): CompletableFuture[ju.List[l.TextEdit]] = val empty: Either[String, List[l.TextEdit]] = Right(List()) (compilerAccess - .withInterruptableCompiler(Some(params))(empty, params.token) { pc => + .withInterruptableCompiler(Some(params))(empty, params.token()) { pc => new PcInlineValueProviderImpl(pc.compiler(), params) .getInlineTextEdits() }) @@ -268,7 +274,7 @@ case class ScalaPresentationCompiler( extractionPos: OffsetParams ): CompletableFuture[ju.List[l.TextEdit]] = val empty: ju.List[l.TextEdit] = new ju.ArrayList[l.TextEdit]() - compilerAccess.withInterruptableCompiler(Some(range))(empty, range.token) { + compilerAccess.withInterruptableCompiler(Some(range))(empty, range.token()) { pc => new ExtractMethodProvider( range, @@ -288,7 +294,7 @@ case class ScalaPresentationCompiler( ): CompletableFuture[ju.List[l.TextEdit]] = val empty: Either[String, List[l.TextEdit]] = Right(List()) (compilerAccess - .withNonInterruptableCompiler(Some(params))(empty, params.token) { pc => + .withNonInterruptableCompiler(Some(params))(empty, params.token()) { pc => new ConvertToNamedArgumentsProvider( pc.compiler(), params, @@ -320,7 +326,7 @@ case class ScalaPresentationCompiler( ): CompletableFuture[ju.Optional[HoverSignature]] = compilerAccess.withNonInterruptableCompiler(Some(params))( ju.Optional.empty[HoverSignature](), - params.token + params.token() ) { access => val driver = access.compiler() HoverProvider.hover(params, driver, search) @@ -332,7 +338,7 @@ case class ScalaPresentationCompiler( ): CompletableFuture[ju.Optional[l.Range]] = compilerAccess.withNonInterruptableCompiler(Some(params))( Optional.empty[l.Range](), - params.token + params.token() ) { access => val driver = access.compiler() Optional.ofNullable( @@ -346,7 +352,7 @@ case class ScalaPresentationCompiler( ): CompletableFuture[ju.List[l.TextEdit]] = compilerAccess.withNonInterruptableCompiler(Some(params))( List[l.TextEdit]().asJava, - params.token + params.token() ) { access => val driver = access.compiler() PcRenameProvider(driver, params, Some(name)).rename().asJava @@ -366,7 +372,7 @@ case class ScalaPresentationCompiler( def signatureHelp(params: OffsetParams): CompletableFuture[l.SignatureHelp] = compilerAccess.withNonInterruptableCompiler(Some(params))( new l.SignatureHelp(), - params.token + params.token() ) { access => val driver = access.compiler() SignatureHelpProvider.signatureHelp(driver, params, search) diff --git a/presentation-compiler/src/main/dotty/tools/pc/SelectionRangeProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/SelectionRangeProvider.scala index f0268baaaf23..a7d07b12f40c 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/SelectionRangeProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/SelectionRangeProvider.scala @@ -36,9 +36,10 @@ class SelectionRangeProvider( params.asScala.toList.map { param => - val uri = param.uri + val uri = param.uri().nn + val text = param.text().nn val filePath = Paths.get(uri) - val source = SourceFile.virtual(filePath.toString, param.text) + val source = SourceFile.virtual(filePath.toString, text) driver.run(uri, source) val pos = driver.sourcePosition(param) val path = diff --git a/presentation-compiler/src/main/dotty/tools/pc/SemanticdbTextDocumentProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/SemanticdbTextDocumentProvider.scala index 22975c2eefcb..43e75a4d6130 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/SemanticdbTextDocumentProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/SemanticdbTextDocumentProvider.scala @@ -25,13 +25,13 @@ class SemanticdbTextDocumentProvider( uri: URI, sourceCode: String ): Array[Byte] = - val filePath = Paths.get(uri) + val filePath = Paths.get(uri).nn val validCode = removeMagicImports(sourceCode, filePath) driver.run( uri, - SourceFile.virtual(filePath.toString, validCode) + SourceFile.virtual(filePath.toString(), validCode) ) - val tree = driver.currentCtx.run.units.head.tpdTree + val tree = driver.currentCtx.run.nn.units.head.tpdTree val extractor = ExtractSemanticDB.Extractor() extractor.traverse(tree)(using driver.currentCtx) val path = workspace @@ -42,12 +42,12 @@ class SemanticdbTextDocumentProvider( if Properties.isWin then relativeUri.toString().replace("\\", "/") else relativeUri.toString() } - .getOrElse(filePath.toString) + .getOrElse(filePath.toString()) val document = TextDocument( schema = Schema.SEMANTICDB4, language = Language.SCALA, - uri = path, + uri = path.nn, text = sourceCode, md5 = MD5.compute(sourceCode), symbols = extractor.symbolInfos.toList, @@ -57,7 +57,7 @@ class SemanticdbTextDocumentProvider( val out = SemanticdbOutputStream.newInstance(byteStream) document.writeTo(out) out.flush() - byteStream.toByteArray + byteStream.toByteArray().nn end textDocument end SemanticdbTextDocumentProvider diff --git a/presentation-compiler/src/main/dotty/tools/pc/SignatureHelpProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/SignatureHelpProvider.scala index f020a4d999d0..46ca85af7319 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/SignatureHelpProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/SignatureHelpProvider.scala @@ -28,14 +28,14 @@ object SignatureHelpProvider: params: OffsetParams, search: SymbolSearch ) = - val uri = params.uri - val sourceFile = SourceFile.virtual(params.uri, params.text) - driver.run(uri, sourceFile) + val uri = params.uri() + val sourceFile = SourceFile.virtual(params.uri().nn, params.text().nn) + driver.run(uri.nn, sourceFile) given ctx: Context = driver.currentCtx val pos = driver.sourcePosition(params) - val trees = driver.openedTrees(uri) + val trees = driver.openedTrees(uri.nn) val path = Interactive.pathTo(trees, pos).dropWhile(t => notCurrentApply(t, pos)) @@ -101,7 +101,7 @@ object SignatureHelpProvider: signature: Signatures.Signature, isJavaSymbol: Boolean ): Option[Signature] = - val allParams = info.parameters.asScala + val allParams = info.parameters().nn.asScala def updateParams( params: List[Signatures.Param], index: Int @@ -114,11 +114,11 @@ object SignatureHelpProvider: case Some(paramDoc) => val newName = if isJavaSymbol && head.name.startsWith("x$") then - paramDoc.displayName + paramDoc.nn.displayName() else head.name head.copy( - doc = Some(paramDoc.docstring), - name = newName + doc = Some(paramDoc.docstring.nn), + name = newName.nn ) :: rest case _ => head :: rest @@ -132,7 +132,7 @@ object SignatureHelpProvider: val updated = updateParams(head, index) updated :: updateParamss(tail, index + head.size) val updatedParams = updateParamss(signature.paramss, 0) - Some(signature.copy(doc = Some(info.docstring), paramss = updatedParams)) + Some(signature.copy(doc = Some(info.docstring().nn), paramss = updatedParams)) end withDocumentation private def signatureToSignatureInformation( @@ -174,12 +174,12 @@ object SignatureHelpProvider: documentation.foreach(info.setDocumentation(_)) info - private def markupContent(content: String): l.MarkupContent = - if content.isEmpty then null + private def markupContent(content: String): l.MarkupContent | Null = + if content.isEmpty() then null else val markup = new l.MarkupContent markup.setKind("markdown") - markup.setValue(content.trim) + markup.setValue(content.trim()) markup end SignatureHelpProvider diff --git a/presentation-compiler/src/main/dotty/tools/pc/TastyUtils.scala b/presentation-compiler/src/main/dotty/tools/pc/TastyUtils.scala index f4970424a490..747f104cfede 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/TastyUtils.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/TastyUtils.scala @@ -21,7 +21,7 @@ object TastyUtils: private def normalTasty(tastyURI: URI): String = val tastyBytes = Files.readAllBytes(Paths.get(tastyURI)) - new TastyPrinter(tastyBytes).showContents() + new TastyPrinter(tastyBytes.nn).showContents() private def htmlTasty( tastyURI: URI, @@ -30,7 +30,7 @@ object TastyUtils: ): String = val title = tastyHtmlPageTitle(tastyURI) val tastyBytes = Files.readAllBytes(Paths.get(tastyURI)) - val tastyHtml = new TastyHTMLPrinter(tastyBytes).showContents() + val tastyHtml = new TastyHTMLPrinter(tastyBytes.nn).showContents() HtmlBuilder() .page(title, htmlStyles :: headElems, bodyAttributes) { builder => builder @@ -40,7 +40,7 @@ object TastyUtils: end htmlTasty private def tastyHtmlPageTitle(file: URI) = - val filename = Paths.get(file).getFileName.toString + val filename = Paths.get(file).nn.getFileName().toString s"TASTy for $filename" private val standaloneHtmlStyles = diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/AmmoniteFileCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/AmmoniteFileCompletions.scala index a2c74ef903ae..31bf7c348119 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/AmmoniteFileCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/AmmoniteFileCompletions.scala @@ -38,15 +38,11 @@ object AmmoniteFileCompletions: workspace: Option[Path], rawFileName: String )(using Context): List[CompletionValue] = + val fileName: Option[String] = Option(rawFileName) + .flatMap(_.split("/").nn.lastOption.map(_.nn.stripSuffix(".amm.sc.scala"))) - val fileName = rawFileName - .split("/") - .last - .stripSuffix(".amm.sc.scala") - - val split = rawPath - .split("\\$file") - .toList + val split: List[String] = Option(rawPath) + .fold(Nil)(_.split("\\$file").nn.toList.map(_.nn)) val editRange = selector.headOption.map { sel => if sel.sourcePos.span.isZeroExtent then posRange @@ -66,35 +62,33 @@ object AmmoniteFileCompletions: isDirectory = true ) + def matches(file: Path): Boolean = + (Files.isDirectory(file) || file.toAbsolutePath().toString.isAmmoniteScript) && + query.exists(q => CompletionFuzzy.matches(q.nn, file.getFileName().toString)) + (split, workspace) match case (_ :: script :: Nil, Some(workspace)) => // drop / or \ val current = workspace.resolve(script.drop(1)) val importPath = translateImportToPath(select).drop(1) - val currentPath = current.getParent.resolve(importPath).toAbsolutePath + val currentPath = current.nn.getParent().nn.resolve(importPath).nn.toAbsolutePath() val parentTextEdit = - if query.exists(_.isEmpty()) && - Files.exists(currentPath.getParent) && Files.isDirectory( + if query.exists(_.nn.isEmpty()) && + Files.exists(currentPath.nn.getParent()) && Files.isDirectory( currentPath ) then List(parent) else Nil Files - .list(currentPath) - .iterator + .list(currentPath).nn + .iterator().nn .asScala .toList - .filter(_.getFileName.toString.stripSuffix(".sc") != fileName) + .filter(path => !fileName.contains(path.nn.getFileName().toString.stripSuffix(".sc"))) .collect { - case file - if (Files.isDirectory( - file - ) || file.toAbsolutePath.toString.isAmmoniteScript) && - query.exists( - CompletionFuzzy.matches(_, file.getFileName.toString) - ) => + case file if matches(file) => CompletionValue.FileSystemMember( - file.getFileName.toString, + file.getFileName().toString, editRange, isDirectory = Files.isDirectory(file) ) diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/AmmoniteIvyCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/AmmoniteIvyCompletions.scala index 4404dbdfb7cc..39f7144835c9 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/AmmoniteIvyCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/AmmoniteIvyCompletions.scala @@ -23,7 +23,7 @@ object AmmoniteIvyCompletions: case None => Nil case Some(dependency) => val isInitialCompletion = - pos.lineContent.trim == "import $ivy." + pos.lineContent.trim() == "import $ivy." val ivyEditRange = if isInitialCompletion then completionPos.toEditRange else @@ -31,7 +31,7 @@ object AmmoniteIvyCompletions: val (rangeStart, rangeEnd) = CoursierComplete.inferEditRange(pos.point, text) pos.withStart(rangeStart).withEnd(rangeEnd).toLsp - val completions = coursierComplete.complete(dependency) + val completions = coursierComplete.complete(dependency.nn) completions .map(insertText => CompletionValue.IvyImport( diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionPos.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionPos.scala index 29699bd05203..a0cf6bafcf46 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionPos.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionPos.scala @@ -41,7 +41,7 @@ object CompletionPos: offsetParams: OffsetParams, treePath: List[Tree] )(using Context): CompletionPos = - infer(cursorPos, offsetParams.uri, offsetParams.text, treePath) + infer(cursorPos, offsetParams.uri().nn, offsetParams.text().nn, treePath) def infer( cursorPos: SourcePosition, @@ -55,18 +55,11 @@ object CompletionPos: val prevIsDot = if start - 1 >= 0 then text.charAt(start - 1) == '.' else false val kind = - if query.isEmpty && !prevIsDot then CompletionKind.Empty + if query.nn.isEmpty() && !prevIsDot then CompletionKind.Empty else if prevIsDot then CompletionKind.Members else CompletionKind.Scope - CompletionPos( - kind, - start, - end, - query, - cursorPos, - uri - ) + CompletionPos(kind, start, end, query.nn, cursorPos, uri) end infer /** @@ -80,7 +73,7 @@ object CompletionPos: ): (Int, Boolean) = var i = 0 var tabIndented = false - while lineOffset + i < text.length && { + while lineOffset + i < text.length() && { val char = text.charAt(lineOffset + i) if char == '\t' then tabIndented = true @@ -132,7 +125,7 @@ object CompletionPos: */ private def inferIdentEnd(pos: SourcePosition, text: String): Int = var i = pos.point - while i < text.length && Chars.isIdentifierPart(text.charAt(i)) do i += 1 + while i < text.length() && Chars.isIdentifierPart(text.charAt(i)) do i += 1 i end CompletionPos diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala index 323f63050377..13a6e7cdb7cb 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionProvider.scala @@ -41,10 +41,11 @@ class CompletionProvider( folderPath: Option[Path] )(using reports: ReportContext): def completions(): CompletionList = - val uri = params.uri + val uri = params.uri().nn + val text = params.text().nn val code = applyCompletionCursor(params) - val sourceFile = SourceFile.virtual(params.uri, code) + val sourceFile = SourceFile.virtual(uri, code) driver.run(uri, sourceFile) val ctx = driver.currentCtx @@ -66,7 +67,7 @@ class CompletionProvider( CompletionPos.infer(pos, params, path)(using newctx) val autoImportsGen = AutoImports.generator( completionPos.sourcePos, - params.text, + text, unit.tpdTree, unit.comments, indexedCtx, @@ -75,7 +76,7 @@ class CompletionProvider( val (completions, searchResult) = new Completions( pos, - params.text, + text, ctx.fresh.setCompilationUnit(unit), search, buildTargetIdentifier, @@ -124,22 +125,22 @@ class CompletionProvider( * because scala parser trim end position to the last statement pos. */ private def applyCompletionCursor(params: OffsetParams): String = - import params.* + val text = params.text().nn + val offset = params.offset().nn + val isStartMultilineComment = val i = params.offset() - i >= 3 && (params.text().charAt(i - 1) match + i >= 3 && (text.charAt(i - 1) match case '*' => - params.text().charAt(i - 2) == '*' && - params.text().charAt(i - 3) == '/' + text.charAt(i - 2) == '*' && + text.charAt(i - 3) == '/' case _ => false ) if isStartMultilineComment then // Insert potentially missing `*/` to avoid comment out all codes after the "/**". - text.substring(0, offset) + Cursor.value + "*/" + text.substring(offset) + text.substring(0, offset).nn + Cursor.value + "*/" + text.substring(offset) else - text.substring(0, offset) + Cursor.value + text.substring( - offset - ) + text.substring(0, offset).nn + Cursor.value + text.substring(offset) end applyCompletionCursor private def completionItems( @@ -166,7 +167,7 @@ class CompletionProvider( additionalEdits: List[TextEdit] = Nil, range: Option[LspRange] = None ): CompletionItem = - val oldText = params.text.substring(completionPos.start, completionPos.end) + val oldText = params.text().nn.substring(completionPos.start, completionPos.end) val editRange = if newText.startsWith(oldText) then completionPos.stripSuffixEditRange else completionPos.toEditRange @@ -186,7 +187,7 @@ class CompletionProvider( item.setTags(completion.lspTags.asJava) - if config.isCompletionSnippetsEnabled then + if config.isCompletionSnippetsEnabled() then item.setInsertTextFormat(InsertTextFormat.Snippet) completion.command.foreach { command => @@ -230,18 +231,10 @@ class CompletionProvider( case Some(edits) => edits match case AutoImportEdits(Some(nameEdit), other) => - mkItem( - nameEdit.getNewText(), - other.toList, - range = Some(nameEdit.getRange()) - ) + mkItem(nameEdit.getNewText().nn, other.toList, range = Some(nameEdit.getRange().nn)) case _ => mkItem( - v.insertText.getOrElse( - ident.backticked( - backtickSoftKeyword - ) + completionTextSuffix - ), + v.insertText.getOrElse( ident.backticked(backtickSoftKeyword) + completionTextSuffix), edits.edits, range = v.range ) diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionValue.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionValue.scala index c5232418a813..6011a1a3d660 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionValue.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/CompletionValue.scala @@ -162,7 +162,7 @@ object CompletionValue: tpe: Type, symbol: Symbol ) extends Symbolic: - override def insertText: Option[String] = Some(label.replace("$", "$$")) + override def insertText: Option[String] = Some(label.replace("$", "$$").nn) override def completionItemKind(using Context): CompletionItemKind = CompletionItemKind.Field override def description(printer: ShortenedTypePrinter)(using Context): String = diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala index aa3fa59e518e..557d1762720b 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/Completions.scala @@ -87,7 +87,7 @@ class Completions( def hasSyntheticCursorSuffix: Boolean = if !sym.name.endsWith(Cursor.value) then false else - val realNameLength = sym.decodedName.length - Cursor.value.length + val realNameLength = sym.decodedName.length() - Cursor.value.length() sym.source == pos.source && sym.span.start + realNameLength == pos.span.end @@ -201,7 +201,7 @@ class Completions( paramss match case Nil => suffix case List(Nil) => suffix.withNewSuffix(SuffixKind.Brace) - case _ if config.isCompletionSnippetsEnabled => + case _ if config.isCompletionSnippetsEnabled() => val onlyParameterless = paramss.forall(_.isEmpty) lazy val onlyImplicitOrTypeParams = paramss.forall( _.exists { sym => @@ -273,7 +273,7 @@ class Completions( completionPos: CompletionPos ): (List[CompletionValue], Boolean) = lazy val rawPath = Paths - .get(pos.source.path) + .get(pos.source.path).nn lazy val rawFileName = rawPath .getFileName() .toString() @@ -391,7 +391,7 @@ class Completions( // class Fo@@ case (td: TypeDef) :: _ if Fuzzy.matches( - td.symbol.name.decoded.replace(Cursor.value, ""), + td.symbol.name.decoded.replace(Cursor.value, "").nn, filename ) => val values = FilenameCompletions.contribute(filename, td) @@ -452,7 +452,7 @@ class Completions( pos, path, indexedContext, - config.isCompletionSnippetsEnabled + config.isCompletionSnippetsEnabled() ) (args, false) end match @@ -517,7 +517,7 @@ class Completions( CompletionValue.Workspace(_, _, _, sym) ).map(visit).forall(_ == true), ) - Some(search.search(query, buildTargetIdentifier, visitor)) + Some(search.search(query, buildTargetIdentifier, visitor).nn) case CompletionKind.Members => val visitor = new CompilerSearchVisitor(sym => if sym.is(ExtensionMethod) && @@ -530,7 +530,7 @@ class Completions( ).map(visit).forall(_ == true) else false, ) - Some(search.searchMethods(query, buildTargetIdentifier, visitor)) + Some(search.searchMethods(query, buildTargetIdentifier, visitor).nn) end match end enrichWithSymbolSearch @@ -571,7 +571,7 @@ class Completions( val nameId = if sym.isClass || sym.is(Module) then // drop #|. at the end to avoid duplication - name.substring(0, name.length - 1) + name.substring(0, name.length() - 1).nn else name val suffix = if symOnly.snippetSuffix.addLabelSnippet then "[]" else "" @@ -693,7 +693,7 @@ class Completions( if !ov.symbol.is(Deferred) then penalty |= MemberOrdering.IsNotAbstract penalty case CompletionValue.Workspace(_, sym, _, _) => - symbolRelevance(sym) | (IsWorkspaceSymbol + sym.name.show.length) + symbolRelevance(sym) | (IsWorkspaceSymbol + sym.name.show.length()) case sym: CompletionValue.Symbolic => symbolRelevance(sym.symbol) case _ => @@ -782,9 +782,9 @@ class Completions( def fuzzyScore(o: CompletionValue.Symbolic): Int = fuzzyCache.getOrElseUpdate( o, { - val name = o.label.toLowerCase() + val name = o.label.toLowerCase().nn if name.startsWith(queryLower) then 0 - else if name.toLowerCase().contains(queryLower) then 1 + else if name.contains(queryLower) then 1 else 2 } ) diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/InterpolatorCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/InterpolatorCompletions.scala index 0a929c79dcc5..1d063bc6d873 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/InterpolatorCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/InterpolatorCompletions.scala @@ -35,7 +35,7 @@ object InterpolatorCompletions: config: PresentationCompilerConfig, buildTargetIdentifier: String )(using Context, ReportContext) = - InterpolationSplice(pos.span.point, text.toCharArray(), text) match + InterpolationSplice(pos.span.point, text.toCharArray().nn, text) match case Some(interpolator) => InterpolatorCompletions.contributeScope( text, diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/KeywordsCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/KeywordsCompletions.scala index a5eb23b26ed3..9f1a5a0e9bff 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/KeywordsCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/KeywordsCompletions.scala @@ -1,10 +1,13 @@ package dotty.tools.pc.completions +import scala.collection.mutable.ListBuffer import scala.meta.internal.pc.Keyword import dotty.tools.dotc.ast.NavigateAST +import dotty.tools.dotc.ast.Positioned import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.ast.untpd +import dotty.tools.dotc.ast.untpd.UntypedTreeTraverser import dotty.tools.dotc.core.Comments import dotty.tools.dotc.core.Comments.Comment import dotty.tools.dotc.core.Contexts.Context @@ -23,7 +26,7 @@ object KeywordsCompletions: checkIfNotInComment(completionPos.cursorPos, comments) path match - case Nil if completionPos.query.isEmpty => + case Nil if completionPos.query.isEmpty() => Keyword.all.collect { // topelevel definitions are allowed in Scala 3 case kw if (kw.isPackage || kw.isTemplate) && notInComment => @@ -163,6 +166,19 @@ object KeywordsCompletions: def checkTemplateForNewParents(enclosing: List[Tree], pos: CompletionPos)( using ctx: Context ): TemplateKeywordAvailability = + + def collectTypeAndModuleDefs( + tree: untpd.Tree, + f: PartialFunction[untpd.Tree, Boolean] + )(using Context): List[untpd.Tree] = { + val buf = ListBuffer.empty[untpd.Tree] + val traverser = new UntypedTreeTraverser: + def traverse(tree: untpd.Tree)(using Context) = + foldOver(if f(tree) then buf += tree, tree) + traverser.traverse(tree) + buf.toList + } + /* * Finds tree which ends just before cursor positions, that may be extended or derive. * In Scala 3, such tree must be a `TypeDef` which has field of type `Template` describing @@ -172,44 +188,19 @@ object KeywordsCompletions: * * @returns TypeDef tree defined before the cursor position or `enclosingTree` otherwise */ - def findLastSatisfyingTree(span: Span): Option[Tree] = - NavigateAST.untypedPath(span).headOption.flatMap { - case other: untpd.Tree => - val typeDefs = other.filterSubTrees { - // package test - // class Test ext@@ - Interactive.pathTo returns `PackageDef` instead of `TypeDef` - // - because it tried to repair the broken tree by finishing `TypeDef` before ext - // - // The cursor position is 27 and tree positions after parsing are: - // - // package Test@../Test.sc<8..12> { - // class Test {}@../Test.sc[13..19..23] - // }@../Test.sc<0..27> + def findLastSatisfyingTree(untpdPath: List[Positioned]): Option[untpd.Tree] = + untpdPath.headOption.flatMap { + case untpdTree: untpd.Tree => + collectTypeAndModuleDefs(untpdTree, { case typeDef: (untpd.TypeDef | untpd.ModuleDef) => typeDef.span.exists && typeDef.span.end < pos.sourcePos.span.start - case other => - false - } - - typeDefs match - // If we didn't find any trees, it means the enclosingTree is not a TypeDef, - // thus can't be followed with `extends`, `with` and `derives` - case Nil => - // we have to fallback to typed tree and check if it is an enum - enclosing match - case (tree: TypeDef) :: _ if tree.symbol.isEnumClass => - Some(other) - case _ => None - case other => - other - .filter(tree => tree.span.exists && tree.span.end < pos.start) - .maxByOption(_.span.end) - + case _ => false + }) + .filter(tree => tree.span.exists && tree.span.end < pos.start) + .maxByOption(_.span.end) case _ => None } - end findLastSatisfyingTree - def checkForPossibleKeywords( template: Template ): TemplateKeywordAvailability = @@ -219,16 +210,17 @@ object KeywordsCompletions: template.derived.isEmpty ) - findLastSatisfyingTree(pos.cursorPos.span) - .flatMap { - case untpd.TypeDef(_, template: Template) => - Some(checkForPossibleKeywords(template)) - case untpd.ModuleDef(_, template: Template) => - Some(checkForPossibleKeywords(template)) - case template: Template => Some(checkForPossibleKeywords(template)) - case other => None - } - .getOrElse(TemplateKeywordAvailability.default) + val untpdPath = NavigateAST.untypedPath(pos.cursorPos.span) + + findLastSatisfyingTree(untpdPath).orElse { enclosing match + case (typeDef: TypeDef) :: _ if typeDef.symbol.isEnumClass => untpdPath.headOption + case _ => None + }.map { + case untpd.TypeDef(_, template: Template) => checkForPossibleKeywords(template) + case untpd.ModuleDef(_, template: Template) => checkForPossibleKeywords(template) + case template: Template => checkForPossibleKeywords(template) + }.getOrElse(TemplateKeywordAvailability.default) + end checkTemplateForNewParents diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/MatchCaseCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/MatchCaseCompletions.scala index d55df93f1e70..fe9a73655835 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/MatchCaseCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/MatchCaseCompletions.scala @@ -74,20 +74,16 @@ object CaseKeywordCompletion: val parents: Parents = selector match case EmptyTree => val seenFromType = parent match - case TreeApply(fun, _) if fun.tpe != null && !fun.tpe.isErroneous => - fun.tpe - case _ => - parent.tpe + case TreeApply(fun, _) if !fun.tpe.isErroneous => fun.tpe + case _ => parent.tpe seenFromType.paramInfoss match case (head :: Nil) :: _ if definitions.isFunctionType(head) || head.isRef( definitions.PartialFunctionClass ) => - val argTypes = - head.argTypes.init + val argTypes = head.argTypes.init new Parents(argTypes, definitions) - case _ => - new Parents(NoType, definitions) + case _ => new Parents(NoType, definitions) case sel => new Parents(sel.tpe, definitions) val selectorSym = parents.selector.widen.metalsDealias.typeSymbol @@ -113,7 +109,7 @@ object CaseKeywordCompletion: ), Nil, range = Some(completionPos.toEditRange), - command = config.parameterHintsCommand().asScala, + command = config.parameterHintsCommand().nn.asScala, ) ) else Nil @@ -305,10 +301,7 @@ object CaseKeywordCompletion: syms.sortBy(_._1.sym.sourcePos.point) else val defnSymbols = search - .definitionSourceToplevels( - SemanticdbSymbols.symbolName(tpe.typeSymbol), - uri - ) + .definitionSourceToplevels(SemanticdbSymbols.symbolName(tpe.typeSymbol), uri).nn .asScala .zipWithIndex .toMap @@ -410,11 +403,7 @@ class CompletionValueGenerator( case None => true case Some("") => true case Some(Cursor.value) => true - case Some(query) => - CompletionFuzzy.matches( - query.replace(Cursor.value, ""), - name - ) + case Some(query) => CompletionFuzzy.matches(query.replace(Cursor.value, "").nn, name) def labelForCaseMember(sym: Symbol, name: String)(using Context diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/MultilineCommentCompletion.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/MultilineCommentCompletion.scala index 46a23446a7f1..ca207c9f7b80 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/MultilineCommentCompletion.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/MultilineCommentCompletion.scala @@ -7,7 +7,7 @@ import dotty.tools.dotc.util.SourcePosition object MultilineCommentCompletion: def contribute(config: PresentationCompilerConfig): List[CompletionValue] = - val newText = if config.isCompletionSnippetsEnabled then " $0 */" else " */" + val newText = if config.isCompletionSnippetsEnabled() then " $0 */" else " */" List(CompletionValue.document("/* */", newText, "Multiline Comment")) def isMultilineCommentCompletion(pos: SourcePosition, text: String): Boolean = diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/NamedArgCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/NamedArgCompletions.scala index d5ecf60dc341..54325c89945b 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/NamedArgCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/NamedArgCompletions.scala @@ -270,11 +270,12 @@ object NamedArgCompletions: ) } - val prefix = - ident - .map(_.name.toString) - .getOrElse("") - .replace(Cursor.value, "") + val prefix = ident + .map(_.name.toString) + .getOrElse("") + .replace(Cursor.value, "") + .nn + val params: List[ParamSymbol] = allParams .filter(param => param.name.startsWith(prefix)) diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/OverrideCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/OverrideCompletions.scala index c4c9b47ff4a4..e7b1acb9aa87 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/OverrideCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/OverrideCompletions.scala @@ -89,7 +89,7 @@ object OverrideCompletions: val name = completing .fold(fallbackName)(sym => Some(sym.name.show)) - .map(_.replace(Cursor.value, "")) + .map(_.replace(Cursor.value, "").nn) .filter(!_.isEmpty()) // not using `td.tpe.abstractTermMembers` because those members includes @@ -173,50 +173,52 @@ object OverrideCompletions: case _ => None end FindTypeDef - val uri = params.uri - driver.run( - uri, - SourceFile.virtual(uri.toASCIIString, params.text) - ) - val unit = driver.currentCtx.run.units.head - val pos = driver.sourcePosition(params) - - val newctx = driver.currentCtx.fresh.setCompilationUnit(unit) - val tpdTree = newctx.compilationUnit.tpdTree - val path = - Interactive.pathTo(tpdTree, pos.span)(using newctx) match - case path @ TypeDef(_, template) :: _ => - template :: path - case path => path - - val indexedContext = IndexedContext( - Interactive.contextOfPath(path)(using newctx) - ) - import indexedContext.ctx + val uri = params.uri().nn + val text = params.text().nn + driver.run(uri, SourceFile.virtual(uri.toASCIIString().nn, text)) + + val unit = driver.currentCtx.run.nn.units.headOption + unit match + case None => new ju.ArrayList[l.TextEdit]() + case Some(unit) => + val pos = driver.sourcePosition(params) + + val newctx = driver.currentCtx.fresh.setCompilationUnit(unit) + val tpdTree = newctx.compilationUnit.tpdTree + val path = + Interactive.pathTo(tpdTree, pos.span)(using newctx) match + case path @ TypeDef(_, template) :: _ => + template :: path + case path => path + + val indexedContext = IndexedContext( + Interactive.contextOfPath(path)(using newctx) + ) + import indexedContext.ctx - lazy val autoImportsGen = AutoImports.generator( - pos, - params.text, - unit.tpdTree, - unit.comments, - indexedContext, - config - ) - lazy val implementAll = implementAllFor( - indexedContext, - params.text, - search, - autoImportsGen, - config - ) - path match - // given <> - case (_: Ident) :: (dd: DefDef) :: _ => - implementAll(dd).asJava - case FindTypeDef(td) => - implementAll(td).asJava - case _ => - new ju.ArrayList[l.TextEdit]() + lazy val autoImportsGen = AutoImports.generator( + pos, + text, + unit.tpdTree, + unit.comments, + indexedContext, + config + ) + lazy val implementAll = implementAllFor( + indexedContext, + text, + search, + autoImportsGen, + config + ) + path match + // given <> + case (_: Ident) :: (dd: DefDef) :: _ => + implementAll(dd).asJava + case FindTypeDef(td) => + implementAll(td).asJava + case _ => + new ju.ArrayList[l.TextEdit]() end implementAllAt private def implementAllFor( @@ -440,7 +442,7 @@ object OverrideCompletions: val label = s"$overrideDefLabel$signature" val stub = - if config.isCompletionSnippetsEnabled && shouldMoveCursor then "${0:???}" + if config.isCompletionSnippetsEnabled() && shouldMoveCursor then "${0:???}" else "???" val value = s"$signature = $stub" diff --git a/presentation-compiler/src/main/dotty/tools/pc/completions/ScaladocCompletions.scala b/presentation-compiler/src/main/dotty/tools/pc/completions/ScaladocCompletions.scala index 81260c4df923..136c4a268df7 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/completions/ScaladocCompletions.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/completions/ScaladocCompletions.scala @@ -31,7 +31,7 @@ object ScaladocCompletions: val builder = new StringBuilder() builder.append("\n") builder.append(s"${indent}*") - if config.isCompletionSnippetsEnabled then builder.append(" $0\n") + if config.isCompletionSnippetsEnabled() then builder.append(" $0\n") else builder.append("\n") if params.nonEmpty || hasReturnValue then builder.append(s"$indent*\n") diff --git a/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala b/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala index 5652fd0d9bcc..9c255d20d212 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/printer/ShortenedTypePrinter.scala @@ -295,7 +295,7 @@ class ShortenedTypePrinter( lazy val paramsDocs = symbolSearch.symbolDocumentation(gsym) match case Some(info) => - (info.typeParameters.asScala ++ info.parameters.asScala).toSeq + (info.typeParameters().nn.asScala ++ info.parameters().nn.asScala).toSeq case _ => Seq.empty @@ -503,7 +503,7 @@ class ShortenedTypePrinter( if includeDefaultParam == ShortenedTypePrinter.IncludeDefaultParam.Include && isDefaultParam then val defaultValue = docInfo match - case Some(value) if !value.defaultValue().isEmpty => + case Some(value) if !value.defaultValue().nn.isEmpty() => value.defaultValue() case _ => "..." s" = $defaultValue" diff --git a/presentation-compiler/src/main/dotty/tools/pc/utils/MtagsEnrichments.scala b/presentation-compiler/src/main/dotty/tools/pc/utils/MtagsEnrichments.scala index ff081c779342..337e0790b738 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/utils/MtagsEnrichments.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/utils/MtagsEnrichments.scala @@ -9,6 +9,7 @@ import scala.meta.pc.RangeParams import scala.meta.pc.SymbolDocumentation import scala.meta.pc.SymbolSearch import scala.util.control.NonFatal +import scala.jdk.OptionConverters.* import dotty.tools.dotc.ast.tpd.* import dotty.tools.dotc.core.Contexts.* @@ -37,29 +38,29 @@ object MtagsEnrichments extends CommonMtagsEnrichments: def sourcePosition( params: OffsetParams ): SourcePosition = - val uri = params.uri - val source = driver.openedFiles(uri) + val uri = params.uri() + val source = driver.openedFiles(uri.nn) val span = params match - case p: RangeParams if p.offset != p.endOffset => + case p: RangeParams if p.offset() != p.endOffset() => p.trimWhitespaceInRange.fold { - Spans.Span(p.offset, p.endOffset) + Spans.Span(p.offset(), p.endOffset()) } { case trimmed: RangeParams => - Spans.Span(trimmed.offset, trimmed.endOffset) + Spans.Span(trimmed.offset(), trimmed.endOffset()) case offset => - Spans.Span(p.offset, p.offset) + Spans.Span(p.offset(), p.offset()) } - case _ => Spans.Span(params.offset) + case _ => Spans.Span(params.offset()) new SourcePosition(source, span) end sourcePosition def localContext(params: OffsetParams): Context = - if driver.currentCtx.run.units.isEmpty then + if driver.currentCtx.run.nn.units.isEmpty then throw new RuntimeException( "No source files were passed to the Scala 3 presentation compiler" ) - val unit = driver.currentCtx.run.units.head + val unit = driver.currentCtx.run.nn.units.head val pos = driver.sourcePosition(params) val newctx = driver.currentCtx.fresh.setCompilationUnit(unit) val tpdPath = @@ -100,7 +101,7 @@ object MtagsEnrichments extends CommonMtagsEnrichments: for uri <- InteractiveDriver.toUriOption(pos.source) range <- if pos.exists then Some(pos.toLsp) else None - yield new l.Location(uri.toString, range) + yield new l.Location(uri.toString(), range) def encloses(other: SourcePosition): Boolean = pos.start <= other.start && pos.end >= other.end @@ -208,8 +209,7 @@ object MtagsEnrichments extends CommonMtagsEnrichments: sym, () => parentSymbols.iterator.map(toSemanticdbSymbol).toList.asJava, ) - if documentation.isPresent then Some(documentation.get()) - else None + documentation.nn.toScala end symbolDocumentation end extension diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseAutoImportsSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseAutoImportsSuite.scala index 57efb7dce4dc..f2732c28e93a 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseAutoImportsSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseAutoImportsSuite.scala @@ -5,6 +5,7 @@ import java.nio.file.Paths import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.CompilerOffsetParams import scala.meta.pc.AutoImportsResult +import scala.language.unsafeNulls import dotty.tools.pc.utils.TextEdits diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseCodeActionSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseCodeActionSuite.scala index bab6bb529c1e..a6a864c901d5 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseCodeActionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseCodeActionSuite.scala @@ -6,6 +6,7 @@ import java.nio.file.Files import scala.collection.immutable import scala.meta.internal.metals.EmptyCancelToken import scala.meta.pc.CancelToken +import scala.language.unsafeNulls abstract class BaseCodeActionSuite extends BasePCSuite: diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseCompletionSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseCompletionSuite.scala index 76bf795ccfc5..8314c9370fca 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseCompletionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseCompletionSuite.scala @@ -6,6 +6,7 @@ import java.util.Collections import scala.jdk.CollectionConverters.* import scala.meta.internal.metals.{CompilerOffsetParams, EmptyCancelToken} import scala.meta.pc.CancelToken +import scala.language.unsafeNulls import dotty.tools.pc.utils.MtagsEnrichments.* import dotty.tools.pc.utils.{TestCompletions, TextEdits} diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseDocumentHihglightSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseDocumentHihglightSuite.scala index bc470bf3cab2..730f32e3d41b 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseDocumentHihglightSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseDocumentHihglightSuite.scala @@ -4,6 +4,7 @@ import java.net.URI import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.{CompilerOffsetParams, EmptyCancelToken} +import scala.language.unsafeNulls import dotty.tools.pc.utils.RangeReplace diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseExtractMethodSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseExtractMethodSuite.scala index 364012eb4405..af4f21fbe991 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseExtractMethodSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseExtractMethodSuite.scala @@ -4,6 +4,7 @@ import java.net.URI import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.{CompilerOffsetParams, CompilerRangeParams} +import scala.language.unsafeNulls import dotty.tools.pc.utils.TextEdits diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseHoverSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseHoverSuite.scala index a541c39b4761..0b8d663f8b33 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseHoverSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseHoverSuite.scala @@ -3,6 +3,7 @@ package dotty.tools.pc.base import java.nio.file.Paths import scala.meta.internal.metals.{CompilerOffsetParams, CompilerRangeParams} +import scala.language.unsafeNulls import dotty.tools.pc.utils.MtagsEnrichments.* import dotty.tools.pc.utils.{RangeReplace, TestHovers} diff --git a/presentation-compiler/test/dotty/tools/pc/base/BasePCSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BasePCSuite.scala index eb7a0783d941..7e2f6669c6a7 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BasePCSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BasePCSuite.scala @@ -11,6 +11,7 @@ import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.{ClasspathSearch, ExcludedPackagesHandler} import scala.meta.internal.pc.PresentationCompilerConfigImpl import scala.meta.pc.{PresentationCompiler, PresentationCompilerConfig} +import scala.language.unsafeNulls import dotty.tools.pc.* import dotty.tools.pc.ScalaPresentationCompiler diff --git a/presentation-compiler/test/dotty/tools/pc/base/BasePcDefinitionSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BasePcDefinitionSuite.scala index a4e67bbdac17..8269d4ce1c44 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BasePcDefinitionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BasePcDefinitionSuite.scala @@ -4,6 +4,7 @@ import java.nio.file.Paths import scala.meta.internal.metals.CompilerOffsetParams import scala.meta.pc.OffsetParams +import scala.language.unsafeNulls import dotty.tools.dotc.util.Spans.Span import dotty.tools.dotc.util.{SourceFile, SourcePosition} diff --git a/presentation-compiler/test/dotty/tools/pc/base/BasePcRenameSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BasePcRenameSuite.scala index 52ffb91c522a..dd30eda1a1c5 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BasePcRenameSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BasePcRenameSuite.scala @@ -4,6 +4,7 @@ import java.net.URI import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.{CompilerOffsetParams, EmptyCancelToken} +import scala.language.unsafeNulls import dotty.tools.pc.utils.{RangeReplace, TextEdits} diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseSelectionRangeSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseSelectionRangeSuite.scala index 3dc854e86477..1f4b15f3500a 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseSelectionRangeSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseSelectionRangeSuite.scala @@ -7,6 +7,7 @@ import scala.collection.immutable import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.{CompilerOffsetParams, EmptyCancelToken} import scala.meta.pc.OffsetParams +import scala.language.unsafeNulls import dotty.tools.pc.utils.TestExtensions._ diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseSemanticTokensSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseSemanticTokensSuite.scala index 660549a32943..7b7ec5b551d2 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseSemanticTokensSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseSemanticTokensSuite.scala @@ -4,6 +4,7 @@ import java.net.URI import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.CompilerVirtualFileParams +import scala.language.unsafeNulls import dotty.tools.pc.utils.TestSemanticTokens diff --git a/presentation-compiler/test/dotty/tools/pc/base/BaseSignatureHelpSuite.scala b/presentation-compiler/test/dotty/tools/pc/base/BaseSignatureHelpSuite.scala index 2306c51bffdb..f993bb49921e 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/BaseSignatureHelpSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/BaseSignatureHelpSuite.scala @@ -4,6 +4,7 @@ import java.nio.file.Paths import scala.jdk.CollectionConverters.* import scala.meta.internal.metals.CompilerOffsetParams +import scala.language.unsafeNulls abstract class BaseSignatureHelpSuite extends BasePCSuite: def checkDoc( diff --git a/presentation-compiler/test/dotty/tools/pc/base/ReusableClassRunner.scala b/presentation-compiler/test/dotty/tools/pc/base/ReusableClassRunner.scala index 43ebffa25e1f..82e697e6e9a1 100644 --- a/presentation-compiler/test/dotty/tools/pc/base/ReusableClassRunner.scala +++ b/presentation-compiler/test/dotty/tools/pc/base/ReusableClassRunner.scala @@ -1,6 +1,7 @@ package dotty.tools.pc.base import scala.jdk.CollectionConverters._ +import scala.language.unsafeNulls import org.junit.runners.BlockJUnit4ClassRunner import org.junit.runners.model.FrameworkMethod diff --git a/presentation-compiler/test/dotty/tools/pc/tests/CompilerJobQueueSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/CompilerJobQueueSuite.scala index 97a8759f3d53..123eed81a51c 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/CompilerJobQueueSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/CompilerJobQueueSuite.scala @@ -7,6 +7,7 @@ import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration.Duration import scala.concurrent.{Await, Future, Promise} import scala.meta.internal.pc.CompilerJobQueue +import scala.language.unsafeNulls import scala.util.Try import org.junit.{After, Assert, Before, Test} diff --git a/presentation-compiler/test/dotty/tools/pc/tests/PcSemanticdbSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/PcSemanticdbSuite.scala index 192abb418373..8d412bcc844a 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/PcSemanticdbSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/PcSemanticdbSuite.scala @@ -4,6 +4,7 @@ import java.net.URI import dotty.tools.dotc.semanticdb.{SymbolOccurrence, TextDocument} import dotty.tools.pc.base.BasePCSuite +import scala.language.unsafeNulls import org.junit.Test diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionCancelSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionCancelSuite.scala index db32ec8e894f..4746eb93f25d 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionCancelSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionCancelSuite.scala @@ -16,6 +16,7 @@ import scala.meta.internal.pc.{ PresentationCompilerConfigImpl } import scala.meta.pc.{CancelToken, PresentationCompilerConfig} +import scala.language.unsafeNulls import dotty.tools.pc.base.BaseCompletionSuite diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala index ded1700fd603..583b138a255b 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionKeywordSuite.scala @@ -505,6 +505,19 @@ class CompletionKeywordSuite extends BaseCompletionSuite: |""".stripMargin ) + @Test def `extends-class-nested-in-object` = + check( + """ + |package foo + | + |object Foo { + | class Boo ext@@ + |} + """.stripMargin, + """|extends + |""".stripMargin + ) + @Test def `extends-class-nested-with-body` = check( """ diff --git a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala index a64a6dfac6a2..055363830a1b 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala @@ -1,6 +1,7 @@ package dotty.tools.pc.tests.completion import scala.meta.pc.SymbolDocumentation +import scala.language.unsafeNulls import dotty.tools.pc.base.BaseCompletionSuite import dotty.tools.pc.utils.MockEntries diff --git a/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala index 2b49d2db3f08..358e159eb539 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala @@ -2,6 +2,7 @@ package dotty.tools.pc.tests.definition import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.pc.OffsetParams +import scala.language.unsafeNulls import dotty.tools.pc.base.BasePcDefinitionSuite import dotty.tools.pc.utils.MockEntries diff --git a/presentation-compiler/test/dotty/tools/pc/tests/definition/TypeDefinitionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/definition/TypeDefinitionSuite.scala index b8d737b0991d..1fe4abfa9628 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/definition/TypeDefinitionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/definition/TypeDefinitionSuite.scala @@ -2,6 +2,7 @@ package dotty.tools.pc.tests.definition import scala.jdk.CollectionConverters.* import scala.meta.pc.OffsetParams +import scala.language.unsafeNulls import dotty.tools.pc.base.BasePcDefinitionSuite import dotty.tools.pc.utils.MockEntries diff --git a/presentation-compiler/test/dotty/tools/pc/tests/edit/AutoImplementAbstractMembersSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/edit/AutoImplementAbstractMembersSuite.scala index 72a7c01597a7..04c3f8a018e9 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/edit/AutoImplementAbstractMembersSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/edit/AutoImplementAbstractMembersSuite.scala @@ -4,6 +4,7 @@ import java.net.URI import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.CompilerOffsetParams +import scala.language.unsafeNulls import dotty.tools.pc.base.BaseCodeActionSuite import dotty.tools.pc.utils.TextEdits diff --git a/presentation-compiler/test/dotty/tools/pc/tests/edit/ConvertToNamedArgumentsSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/edit/ConvertToNamedArgumentsSuite.scala index 9d3cf6c5c92e..5285be83b537 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/edit/ConvertToNamedArgumentsSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/edit/ConvertToNamedArgumentsSuite.scala @@ -7,6 +7,7 @@ import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.CompilerOffsetParams import scala.meta.internal.pc.CodeActionErrorMessages import scala.meta.pc.DisplayableException +import scala.language.unsafeNulls import dotty.tools.pc.base.BaseCodeActionSuite import dotty.tools.pc.utils.TextEdits @@ -102,8 +103,7 @@ class ConvertToNamedArgumentsSuite extends BaseCodeActionSuite: catch case e: ExecutionException => e.getCause() match - case cause: DisplayableException => - assertNoDiff(expectedErrorMsg, cause.getMessage) + case cause => assertNoDiff(expectedErrorMsg, cause.getMessage) def checkEdit( original: String, diff --git a/presentation-compiler/test/dotty/tools/pc/tests/edit/InlineValueSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/edit/InlineValueSuite.scala index 60f5f01d1424..0cec3952a7ef 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/edit/InlineValueSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/edit/InlineValueSuite.scala @@ -7,6 +7,7 @@ import scala.meta.internal.metals.CompilerOffsetParams import scala.meta.internal.mtags.CommonMtagsEnrichments import scala.meta.internal.pc.InlineValueProvider.Errors as InlineErrors import scala.meta.pc.DisplayableException +import scala.language.unsafeNulls import dotty.tools.pc.base.BaseCodeActionSuite import dotty.tools.pc.utils.TextEdits diff --git a/presentation-compiler/test/dotty/tools/pc/tests/edit/InsertInferredTypeSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/edit/InsertInferredTypeSuite.scala index 982264fa4b2a..d6707c54894e 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/edit/InsertInferredTypeSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/edit/InsertInferredTypeSuite.scala @@ -4,6 +4,7 @@ import java.net.URI import scala.meta.internal.jdk.CollectionConverters.* import scala.meta.internal.metals.CompilerOffsetParams +import scala.language.unsafeNulls import dotty.tools.pc.base.BaseCodeActionSuite import dotty.tools.pc.utils.TextEdits diff --git a/presentation-compiler/test/dotty/tools/pc/utils/MockSymbolSearch.scala b/presentation-compiler/test/dotty/tools/pc/utils/MockSymbolSearch.scala index 3dc23fd8ab37..b0be98850630 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/MockSymbolSearch.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/MockSymbolSearch.scala @@ -14,6 +14,7 @@ import scala.meta.pc.{ SymbolSearch, SymbolSearchVisitor } +import scala.language.unsafeNulls import org.eclipse.lsp4j.Location diff --git a/presentation-compiler/test/dotty/tools/pc/utils/PcAssertions.scala b/presentation-compiler/test/dotty/tools/pc/utils/PcAssertions.scala index 8d9f2446cd90..b77ad7f64bde 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/PcAssertions.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/PcAssertions.scala @@ -1,5 +1,7 @@ package dotty.tools.pc.utils +import scala.language.unsafeNulls + import dotty.tools.dotc.util.DiffUtil import dotty.tools.pc.utils.MtagsEnrichments.* diff --git a/presentation-compiler/test/dotty/tools/pc/utils/RangeReplace.scala b/presentation-compiler/test/dotty/tools/pc/utils/RangeReplace.scala index 7dc0f0a2a5c7..0b41b106eb02 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/RangeReplace.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/RangeReplace.scala @@ -1,6 +1,7 @@ package dotty.tools.pc.utils import scala.collection.immutable +import scala.language.unsafeNulls import dotty.tools.pc.utils.TestExtensions.* diff --git a/presentation-compiler/test/dotty/tools/pc/utils/TestCompletions.scala b/presentation-compiler/test/dotty/tools/pc/utils/TestCompletions.scala index 2450ce870ac4..769ad7675866 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/TestCompletions.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/TestCompletions.scala @@ -1,6 +1,7 @@ package dotty.tools.pc.utils import org.eclipse.lsp4j.CompletionItem +import scala.language.unsafeNulls object TestCompletions: diff --git a/presentation-compiler/test/dotty/tools/pc/utils/TestHovers.scala b/presentation-compiler/test/dotty/tools/pc/utils/TestHovers.scala index b0cf49048137..1241f5aeaa65 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/TestHovers.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/TestHovers.scala @@ -1,6 +1,7 @@ package dotty.tools.pc.utils import scala.meta.internal.pc.HoverMarkup +import scala.language.unsafeNulls import dotty.tools.pc.utils.TestExtensions.* diff --git a/presentation-compiler/test/dotty/tools/pc/utils/TestSemanticTokens.scala b/presentation-compiler/test/dotty/tools/pc/utils/TestSemanticTokens.scala index 5c298668a704..25da747f5812 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/TestSemanticTokens.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/TestSemanticTokens.scala @@ -6,6 +6,7 @@ import scala.collection.mutable.ListBuffer import scala.meta.internal.pc.SemanticTokens import scala.meta.internal.pc.SemanticTokens.* import scala.meta.pc.Node +import scala.language.unsafeNulls import org.eclipse.lsp4j as l diff --git a/presentation-compiler/test/dotty/tools/pc/utils/TestingWorkspaceSearch.scala b/presentation-compiler/test/dotty/tools/pc/utils/TestingWorkspaceSearch.scala index ebbb29769ebb..3e8f6d261155 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/TestingWorkspaceSearch.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/TestingWorkspaceSearch.scala @@ -10,6 +10,7 @@ import scala.meta.internal.metals.{ WorkspaceSymbolQuery } import scala.meta.pc.SymbolSearchVisitor +import scala.language.unsafeNulls import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Symbols.* diff --git a/presentation-compiler/test/dotty/tools/pc/utils/TextEdits.scala b/presentation-compiler/test/dotty/tools/pc/utils/TextEdits.scala index 890a9366e9b5..f6d12bd88e9a 100644 --- a/presentation-compiler/test/dotty/tools/pc/utils/TextEdits.scala +++ b/presentation-compiler/test/dotty/tools/pc/utils/TextEdits.scala @@ -2,6 +2,7 @@ package dotty.tools.pc.utils import scala.jdk.CollectionConverters.* import scala.meta.internal.mtags.CommonMtagsEnrichments.* +import scala.language.unsafeNulls import dotty.tools.pc.utils.TestExtensions.* diff --git a/project/Build.scala b/project/Build.scala index d44effa5431f..3ac19a0f7b35 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1254,18 +1254,20 @@ object Build { BuildInfoPlugin.buildInfoDefaultSettings lazy val presentationCompilerSettings = { - val mtagsVersion = "1.0.0" + val mtagsVersion = "1.1.0+53-af181de4-SNAPSHOT" Seq( + resolvers ++= Resolver.sonatypeOssRepos("snapshots"), libraryDependencies ++= Seq( "org.lz4" % "lz4-java" % "1.8.0", "io.get-coursier" % "interface" % "1.0.18", "org.scalameta" % "mtags-interfaces" % mtagsVersion, ), - libraryDependencies += ("org.scalameta" % "mtags-shared_2.13.11" % mtagsVersion % SourceDeps), + libraryDependencies += ("org.scalameta" % "mtags-shared_2.13.12" % mtagsVersion % SourceDeps), ivyConfigurations += SourceDeps.hide, transitiveClassifiers := Seq("sources"), - (Compile / sourceGenerators) += Def.task { + Compile / scalacOptions ++= Seq("-Yexplicit-nulls", "-Ysafe-init"), + Compile / sourceGenerators += Def.task { val s = streams.value val cacheDir = s.cacheDirectory val targetDir = (Compile/sourceManaged).value / "mtags-shared" diff --git a/scaladoc/test/dotty/tools/scaladoc/signatures/AbstractMemberSignaturesTest.scala b/scaladoc/test/dotty/tools/scaladoc/signatures/AbstractMemberSignaturesTest.scala index eb27987f3f6c..824aec6daa16 100644 --- a/scaladoc/test/dotty/tools/scaladoc/signatures/AbstractMemberSignaturesTest.scala +++ b/scaladoc/test/dotty/tools/scaladoc/signatures/AbstractMemberSignaturesTest.scala @@ -1,11 +1,14 @@ package dotty.tools.scaladoc package signatures +import java.nio.file.Path; + import scala.io.Source import scala.jdk.CollectionConverters._ import scala.util.matching.Regex +import scala.language.unsafeNulls + import dotty.tools.scaladoc.test.BuildInfo -import java.nio.file.Path; import org.jsoup.Jsoup import util.IO import org.junit.Assert.assertTrue