diff --git a/compiler/src/dotty/tools/dotc/Compiler.scala b/compiler/src/dotty/tools/dotc/Compiler.scala index d34fa247b155..9cf15a83758e 100644 --- a/compiler/src/dotty/tools/dotc/Compiler.scala +++ b/compiler/src/dotty/tools/dotc/Compiler.scala @@ -39,7 +39,7 @@ class Compiler { List(new CheckShadowing) :: // Check shadowing elements List(new YCheckPositions) :: // YCheck positions List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks - List(new semanticdb.ExtractSemanticDB) :: // Extract info into .semanticdb files + List(new semanticdb.ExtractSemanticDB.ExtractSemanticInfo) :: // Extract info into .semanticdb files List(new PostTyper) :: // Additional checks and cleanups after type checking List(new sjs.PrepJSInterop) :: // Additional checks and transformations for Scala.js (Scala.js only) List(new sbt.ExtractAPI) :: // Sends a representation of the API of classes to sbt via callbacks @@ -72,6 +72,7 @@ class Compiler { new ExpandSAMs, // Expand single abstract method closures to anonymous classes new ElimRepeated, // Rewrite vararg parameters and arguments new RefChecks) :: // Various checks mostly related to abstract members and overriding + List(new semanticdb.ExtractSemanticDB.AppendDiagnostics) :: // Attach warnings to extracted SemanticDB and write to .semanticdb file List(new init.Checker) :: // Check initialization of objects List(new ProtectedAccessors, // Add accessors for protected members new ExtensionMethods, // Expand methods of value classes with extension methods diff --git a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala index f9e2cfd3ea3b..3be1a159c55c 100644 --- a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala @@ -109,9 +109,14 @@ abstract class Reporter extends interfaces.ReporterResult { private var errors: List[Error] = Nil + private var warnings: List[Warning] = Nil + /** All errors reported by this reporter (ignoring outer reporters) */ def allErrors: List[Error] = errors + /** All warnings reported by this reporter (ignoring outer reporters) */ + def allWarnings: List[Warning] = warnings + /** Were sticky errors reported? Overridden in StoreReporter. */ def hasStickyErrors: Boolean = false @@ -153,7 +158,9 @@ abstract class Reporter extends interfaces.ReporterResult { markReported(dia) withMode(Mode.Printing)(doReport(dia)) dia match { - case _: Warning => _warningCount += 1 + case w: Warning => + warnings = w :: warnings + _warningCount += 1 case e: Error => errors = e :: errors _errorCount += 1 diff --git a/compiler/src/dotty/tools/dotc/semanticdb/DiagnosticOps.scala b/compiler/src/dotty/tools/dotc/semanticdb/DiagnosticOps.scala new file mode 100644 index 000000000000..4bc6e1ecb026 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/semanticdb/DiagnosticOps.scala @@ -0,0 +1,23 @@ +package dotty.tools.dotc.semanticdb + +import dotty.tools.dotc.reporting.Diagnostic +import dotty.tools.dotc.{semanticdb => s} +import dotty.tools.dotc.interfaces.Diagnostic.{ERROR, INFO, WARNING} +import dotty.tools.dotc.core.Contexts.Context +import scala.annotation.internal.sharable + +object DiagnosticOps: + @sharable private val asciiColorCodes = "\u001B\\[[;\\d]*m".r + extension (d: Diagnostic) + def toSemanticDiagnostic: s.Diagnostic = + val severity = d.level match + case ERROR => s.Diagnostic.Severity.ERROR + case WARNING => s.Diagnostic.Severity.WARNING + case INFO => s.Diagnostic.Severity.INFORMATION + case _ => s.Diagnostic.Severity.INFORMATION + val msg = asciiColorCodes.replaceAllIn(d.msg.message, m => "") + s.Diagnostic( + range = Scala3.range(d.pos.span, d.pos.source), + severity = severity, + message = msg + ) diff --git a/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala b/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala index e364bf15ca13..f1b4e4637eb8 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala @@ -21,20 +21,34 @@ import transform.SymUtils._ import scala.collection.mutable import scala.annotation.{ threadUnsafe => tu, tailrec } +import scala.jdk.CollectionConverters._ import scala.PartialFunction.condOpt +import typer.ImportInfo.withRootImports import dotty.tools.dotc.{semanticdb => s} import dotty.tools.io.{AbstractFile, JarArchive} +import dotty.tools.dotc.semanticdb.DiagnosticOps.* +import scala.util.{Using, Failure, Success} + /** Extract symbol references and uses to semanticdb files. * See https://scalameta.org/docs/semanticdb/specification.html#symbol-1 * for a description of the format. - * TODO: Also extract type information + * + * Here, we define two phases for "ExtractSemanticDB", "PostTyper" and "PostInlining". + * + * The "PostTyper" phase extracts SemanticDB information such as symbol + * definitions, symbol occurrences, type information, and synthetics + * and write .semanticdb file. + * + * The "PostInlining" phase extracts diagnostics from "ctx.reporter" and + * attaches them to the SemanticDB information extracted in the "PostTyper" phase. + * We need to run this phase after the "CheckUnused.PostInlining" phase + * so that we can extract the warnings generated by "-Wunused". */ -class ExtractSemanticDB extends Phase: - import Scala3.{_, given} +class ExtractSemanticDB private (phaseMode: ExtractSemanticDB.PhaseMode) extends Phase: - override val phaseName: String = ExtractSemanticDB.name + override val phaseName: String = ExtractSemanticDB.phaseNamePrefix + phaseMode.toString() override val description: String = ExtractSemanticDB.description @@ -46,14 +60,145 @@ class ExtractSemanticDB extends Phase: // Check not needed since it does not transform trees override def isCheckable: Boolean = false - override def run(using Context): Unit = - val unit = ctx.compilationUnit - val extractor = Extractor() - extractor.extract(unit.tpdTree) - ExtractSemanticDB.write(unit.source, extractor.occurrences.toList, extractor.symbolInfos.toList, extractor.synthetics.toList) + override def runOn(units: List[CompilationUnit])(using ctx: Context): List[CompilationUnit] = { + val sourceRoot = ctx.settings.sourceroot.value + val appendDiagnostics = phaseMode == ExtractSemanticDB.PhaseMode.AppendDiagnostics + if (appendDiagnostics) + val warnings = ctx.reporter.allWarnings.groupBy(w => w.pos.source) + units.flatMap { unit => + warnings.get(unit.source).map { ws => + val unitCtx = ctx.fresh.setCompilationUnit(unit).withRootImports + val outputDir = + ExtractSemanticDB.semanticdbPath( + unit.source, + ExtractSemanticDB.semanticdbOutDir(using unitCtx), + sourceRoot + ) + (outputDir, ws.map(_.toSemanticDiagnostic)) + } + }.asJava.parallelStream().forEach { case (out, warnings) => + ExtractSemanticDB.appendDiagnostics(warnings, out) + } + else + val writeSemanticdbText = ctx.settings.semanticdbText.value + units.foreach { unit => + val unitCtx = ctx.fresh.setCompilationUnit(unit).withRootImports + val outputDir = + ExtractSemanticDB.semanticdbPath( + unit.source, + ExtractSemanticDB.semanticdbOutDir(using unitCtx), + sourceRoot + ) + val extractor = ExtractSemanticDB.Extractor() + extractor.extract(unit.tpdTree)(using unitCtx) + ExtractSemanticDB.write( + unit.source, + extractor.occurrences.toList, + extractor.symbolInfos.toList, + extractor.synthetics.toList, + outputDir, + sourceRoot, + writeSemanticdbText + ) + } + units + } + + def run(using Context): Unit = unsupported("run") +end ExtractSemanticDB + +object ExtractSemanticDB: + import java.nio.file.Path + import java.nio.file.Files + import java.nio.file.Paths + + val phaseNamePrefix: String = "extractSemanticDB" + val description: String = "extract info into .semanticdb files" + + enum PhaseMode: + case ExtractSemanticInfo + case AppendDiagnostics + + class ExtractSemanticInfo extends ExtractSemanticDB(PhaseMode.ExtractSemanticInfo) + + class AppendDiagnostics extends ExtractSemanticDB(PhaseMode.AppendDiagnostics) + + private def semanticdbTarget(using Context): Option[Path] = + Option(ctx.settings.semanticdbTarget.value) + .filterNot(_.isEmpty) + .map(Paths.get(_)) + + /** Destination for generated classfiles */ + private def outputDirectory(using Context): AbstractFile = + ctx.settings.outputDir.value + + /** Output directory for SemanticDB files */ + private def semanticdbOutDir(using Context): Path = + semanticdbTarget.getOrElse(outputDirectory.jpath) + + private def absolutePath(path: Path): Path = path.toAbsolutePath.normalize + + private def write( + source: SourceFile, + occurrences: List[SymbolOccurrence], + symbolInfos: List[SymbolInformation], + synthetics: List[Synthetic], + outpath: Path, + sourceRoot: String, + semanticdbText: Boolean + ): Unit = + Files.createDirectories(outpath.getParent()) + val doc: TextDocument = TextDocument( + schema = Schema.SEMANTICDB4, + language = Language.SCALA, + uri = Tools.mkURIstring(Paths.get(relPath(source, sourceRoot))), + text = if semanticdbText then String(source.content) else "", + md5 = internal.MD5.compute(String(source.content)), + symbols = symbolInfos, + occurrences = occurrences, + synthetics = synthetics, + ) + val docs = TextDocuments(List(doc)) + val out = Files.newOutputStream(outpath) + try + val stream = internal.SemanticdbOutputStream.newInstance(out) + docs.writeTo(stream) + stream.flush() + finally + out.close() + end write + + private def appendDiagnostics( + diagnostics: Seq[Diagnostic], + outpath: Path + ): Unit = + Using.Manager { use => + val in = use(Files.newInputStream(outpath)) + val sin = internal.SemanticdbInputStream.newInstance(in) + val docs = TextDocuments.parseFrom(sin) + + val out = use(Files.newOutputStream(outpath)) + val sout = internal.SemanticdbOutputStream.newInstance(out) + TextDocuments(docs.documents.map(_.withDiagnostics(diagnostics))).writeTo(sout) + sout.flush() + } match + case Failure(ex) => // failed somehow, should we say something? + case Success(_) => // success to update semanticdb, say nothing + end appendDiagnostics + + private def relPath(source: SourceFile, sourceRoot: String) = + SourceFile.relativePath(source, sourceRoot) + + private def semanticdbPath(source: SourceFile, base: Path, sourceRoot: String): Path = + absolutePath(base) + .resolve("META-INF") + .resolve("semanticdb") + .resolve(relPath(source, sourceRoot)) + .resolveSibling(source.name + ".semanticdb") /** Extractor of symbol occurrences from trees */ class Extractor extends TreeTraverser: + import Scala3.{_, given} given s.SemanticSymbolBuilder = s.SemanticSymbolBuilder() val synth = SyntheticsExtractor() given converter: s.TypeOps = s.TypeOps() @@ -465,55 +610,5 @@ class ExtractSemanticDB extends Phase: registerSymbol(vparam.symbol, symkinds) traverse(vparam.tpt) tparams.foreach(tp => traverse(tp.rhs)) - - -object ExtractSemanticDB: - import java.nio.file.Path - import java.nio.file.Files - import java.nio.file.Paths - - val name: String = "extractSemanticDB" - val description: String = "extract info into .semanticdb files" - - private def semanticdbTarget(using Context): Option[Path] = - Option(ctx.settings.semanticdbTarget.value) - .filterNot(_.isEmpty) - .map(Paths.get(_)) - - private def semanticdbText(using Context): Boolean = - ctx.settings.semanticdbText.value - - private def outputDirectory(using Context): AbstractFile = ctx.settings.outputDir.value - - def write( - source: SourceFile, - occurrences: List[SymbolOccurrence], - symbolInfos: List[SymbolInformation], - synthetics: List[Synthetic], - )(using Context): Unit = - def absolutePath(path: Path): Path = path.toAbsolutePath.normalize - val relPath = SourceFile.relativePath(source, ctx.settings.sourceroot.value) - val outpath = absolutePath(semanticdbTarget.getOrElse(outputDirectory.jpath)) - .resolve("META-INF") - .resolve("semanticdb") - .resolve(relPath) - .resolveSibling(source.name + ".semanticdb") - Files.createDirectories(outpath.getParent()) - val doc: TextDocument = TextDocument( - schema = Schema.SEMANTICDB4, - language = Language.SCALA, - uri = Tools.mkURIstring(Paths.get(relPath)), - text = if semanticdbText then String(source.content) else "", - md5 = internal.MD5.compute(String(source.content)), - symbols = symbolInfos, - occurrences = occurrences, - synthetics = synthetics, - ) - val docs = TextDocuments(List(doc)) - val out = Files.newOutputStream(outpath) - try - val stream = internal.SemanticdbOutputStream.newInstance(out) - docs.writeTo(stream) - stream.flush() - finally - out.close() + end Extractor +end ExtractSemanticDB \ No newline at end of file diff --git a/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala b/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala index 33531dec7fd8..f1302330bd8b 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala @@ -29,7 +29,7 @@ object Scala3: private val WILDCARDTypeName = nme.WILDCARD.toTypeName - def range(span: Span, treeSource: SourceFile)(using Context): Option[Range] = + def range(span: Span, treeSource: SourceFile): Option[Range] = def lineCol(offset: Int) = (treeSource.offsetToLine(offset), treeSource.column(offset)) val (startLine, startCol) = lineCol(span.start) val (endLine, endCol) = lineCol(span.end) @@ -486,6 +486,8 @@ object Scala3: given Ordering[SymbolInformation] = Ordering.by[SymbolInformation, String](_.symbol)(IdentifierOrdering()) + given Ordering[Diagnostic] = (x, y) => compareRange(x.range, y.range) + given Ordering[Synthetic] = (x, y) => compareRange(x.range, y.range) /** diff --git a/compiler/src/dotty/tools/dotc/semanticdb/Tools.scala b/compiler/src/dotty/tools/dotc/semanticdb/Tools.scala index d37973237a9f..6c6e69f12578 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/Tools.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/Tools.scala @@ -69,6 +69,8 @@ object Tools: sb.append("Language => ").append(languageString(doc.language)).nl sb.append("Symbols => ").append(doc.symbols.length).append(" entries").nl sb.append("Occurrences => ").append(doc.occurrences.length).append(" entries").nl + if doc.diagnostics.nonEmpty then + sb.append("Diagnostics => ").append(doc.diagnostics.length).append(" entries").nl if doc.synthetics.nonEmpty then sb.append("Synthetics => ").append(doc.synthetics.length).append(" entries").nl sb.nl @@ -78,6 +80,10 @@ object Tools: sb.append("Occurrences:").nl doc.occurrences.sorted.foreach(processOccurrence) sb.nl + if doc.diagnostics.nonEmpty then + sb.append("Diagnostics:").nl + doc.diagnostics.sorted.foreach(d => processDiag(d)) + sb.nl if doc.synthetics.nonEmpty then sb.append("Synthetics:").nl doc.synthetics.sorted.foreach(s => processSynth(s, synthPrinter)) @@ -108,6 +114,20 @@ object Tools: private def processSynth(synth: Synthetic, printer: SyntheticPrinter)(using sb: StringBuilder): Unit = sb.append(printer.pprint(synth)).nl + private def processDiag(d: Diagnostic)(using sb: StringBuilder): Unit = + d.range match + case Some(range) => processRange(sb, range) + case _ => sb.append("[):") + sb.append(" ") + d.severity match + case Diagnostic.Severity.ERROR => sb.append("[error]") + case Diagnostic.Severity.WARNING => sb.append("[warning]") + case Diagnostic.Severity.INFORMATION => sb.append("[info]") + case _ => sb.append("[unknown]") + sb.append(" ") + sb.append(d.message) + sb.nl + private def processOccurrence(occ: SymbolOccurrence)(using sb: StringBuilder, sourceFile: SourceFile): Unit = occ.range match case Some(range) => diff --git a/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala b/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala index a85cc9ad80f9..de8c2c11f9c2 100644 --- a/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala +++ b/compiler/test/dotty/tools/dotc/semanticdb/SemanticdbTests.scala @@ -142,7 +142,8 @@ class SemanticdbTests: "-sourceroot", expectSrc.toString, "-classpath", target.toString, "-Xignore-scala2-macros", - "-usejavacp" + "-usejavacp", + "-Wunused:all" ) ++ inputFiles().map(_.toString) val exit = Main.process(args) assertFalse(s"dotc errors: ${exit.errorCount}", exit.hasErrors) diff --git a/presentation-compiler/src/main/dotty/tools/pc/SemanticdbTextDocumentProvider.scala b/presentation-compiler/src/main/dotty/tools/pc/SemanticdbTextDocumentProvider.scala index f4e17913776d..22975c2eefcb 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/SemanticdbTextDocumentProvider.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/SemanticdbTextDocumentProvider.scala @@ -32,8 +32,7 @@ class SemanticdbTextDocumentProvider( SourceFile.virtual(filePath.toString, validCode) ) val tree = driver.currentCtx.run.units.head.tpdTree - val extract = ExtractSemanticDB() - val extractor = extract.Extractor() + val extractor = ExtractSemanticDB.Extractor() extractor.traverse(tree)(using driver.currentCtx) val path = workspace .flatMap { workspacePath => diff --git a/tests/semanticdb/expect/Deprecated.expect.scala b/tests/semanticdb/expect/Deprecated.expect.scala new file mode 100644 index 000000000000..f81dd5eacf68 --- /dev/null +++ b/tests/semanticdb/expect/Deprecated.expect.scala @@ -0,0 +1,4 @@ +object Deprecated/*<-_empty_::Deprecated.*/ { + @deprecated/*->scala::deprecated#*/ def deprecatedMethod/*<-_empty_::Deprecated.deprecatedMethod().*/ = ???/*->scala::Predef.`???`().*/ + def main/*<-_empty_::Deprecated.main().*/ = deprecatedMethod/*->_empty_::Deprecated.deprecatedMethod().*/ +} diff --git a/tests/semanticdb/expect/Deprecated.scala b/tests/semanticdb/expect/Deprecated.scala new file mode 100644 index 000000000000..cd7bb5ac61de --- /dev/null +++ b/tests/semanticdb/expect/Deprecated.scala @@ -0,0 +1,4 @@ +object Deprecated { + @deprecated def deprecatedMethod = ??? + def main = deprecatedMethod +} diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index d2220e2af17a..e05a645c0141 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -8,6 +8,7 @@ Text => empty Language => Scala Symbols => 9 entries Occurrences => 19 entries +Diagnostics => 2 entries Symbols: example/Access# => class Access extends Object { self: Access => +8 decls } @@ -41,6 +42,10 @@ Occurrences: [9:6..9:8): m7 <- example/Access#m7(). [9:11..9:14): ??? -> scala/Predef.`???`(). +Diagnostics: +[3:14..3:16): [warning] unused private member +[4:20..4:22): [warning] unused private member + expect/Advanced.scala --------------------- @@ -51,6 +56,7 @@ Text => empty Language => Scala Symbols => 61 entries Occurrences => 143 entries +Diagnostics => 1 entries Synthetics => 3 entries Symbols: @@ -261,6 +267,9 @@ Occurrences: [53:37..53:38): x -> advanced/HKClass#foo().(x) [53:39..53:47): toString -> scala/Tuple2#toString(). +Diagnostics: +[40:12..40:15): [warning] unused local definition + Synthetics: [27:12..27:16):s.s1 => reflectiveSelectable(*) [29:12..29:16):s.s2 => reflectiveSelectable(*) @@ -276,6 +285,7 @@ Text => empty Language => Scala Symbols => 23 entries Occurrences => 55 entries +Diagnostics => 2 entries Symbols: annot/Alias. => final object Alias extends Object { self: Alias.type => +2 decls } @@ -359,6 +369,10 @@ Occurrences: [39:11..39:26): ClassAnnotation -> com/javacp/annot/ClassAnnotation# [39:28..39:33): param -> scala/annotation/meta/param# +Diagnostics: +[7:67..7:68): [warning] unused explicit parameter +[21:33..21:34): [warning] unused explicit parameter + expect/Anonymous.scala ---------------------- @@ -369,6 +383,7 @@ Text => empty Language => Scala Symbols => 23 entries Occurrences => 50 entries +Diagnostics => 1 entries Synthetics => 2 entries Symbols: @@ -448,6 +463,9 @@ Occurrences: [23:33..23:39): String -> scala/Predef.String# [23:42..23:45): ??? -> scala/Predef.`???`(). +Diagnostics: +[14:8..14:9): [warning] unused local definition + Synthetics: [10:2..10:9):locally => *[Unit] [13:2..13:9):locally => *[Unit] @@ -541,6 +559,7 @@ Text => empty Language => Scala Symbols => 108 entries Occurrences => 127 entries +Diagnostics => 4 entries Synthetics => 2 entries Symbols: @@ -782,10 +801,44 @@ Occurrences: [53:4..53:9): local -> local4 [53:10..53:11): + -> scala/Int#`+`(+4). +Diagnostics: +[18:9..18:10): [warning] unused explicit parameter +[20:27..20:28): [warning] unused explicit parameter +[22:27..22:28): [warning] unused explicit parameter +[24:10..24:11): [warning] unused explicit parameter + Synthetics: [51:16..51:27):List(1).map => *[Int] [51:16..51:20):List => *.apply[Int] +expect/Deprecated.scala +----------------------- + +Summary: +Schema => SemanticDB v4 +Uri => Deprecated.scala +Text => empty +Language => Scala +Symbols => 3 entries +Occurrences => 6 entries +Diagnostics => 1 entries + +Symbols: +_empty_/Deprecated. => final object Deprecated extends Object { self: Deprecated.type => +3 decls } +_empty_/Deprecated.deprecatedMethod(). => @deprecated method deprecatedMethod => Nothing +_empty_/Deprecated.main(). => method main => Nothing + +Occurrences: +[0:7..0:17): Deprecated <- _empty_/Deprecated. +[1:3..1:13): deprecated -> scala/deprecated# +[1:18..1:34): deprecatedMethod <- _empty_/Deprecated.deprecatedMethod(). +[1:37..1:40): ??? -> scala/Predef.`???`(). +[2:6..2:10): main <- _empty_/Deprecated.main(). +[2:13..2:29): deprecatedMethod -> _empty_/Deprecated.deprecatedMethod(). + +Diagnostics: +[2:13..2:29): [warning] method deprecatedMethod in object Deprecated is deprecated + expect/Empty.scala ------------------ @@ -845,6 +898,7 @@ Text => empty Language => Scala Symbols => 30 entries Occurrences => 49 entries +Diagnostics => 3 entries Symbols: endmarkers/Container# => class Container extends Object { self: Container => +5 decls } @@ -929,6 +983,11 @@ Occurrences: [64:14..64:20): String -> scala/Predef.String# [67:4..67:14): endmarkers -> endmarkers/ +Diagnostics: +[38:8..38:16): [warning] unused local definition +[42:8..42:16): [warning] unused local definition +[46:8..46:16): [warning] unused local definition + expect/EndMarkers2.scala ------------------------ @@ -1010,6 +1069,7 @@ Text => empty Language => Scala Symbols => 181 entries Occurrences => 159 entries +Diagnostics => 1 entries Synthetics => 6 entries Symbols: @@ -1356,6 +1416,9 @@ Occurrences: [68:9..68:16): Neptune <- _empty_/Enums.Planet.Neptune. [68:25..68:31): Planet -> _empty_/Enums.Planet# +Diagnostics: +[30:12..30:17): [warning] unused explicit parameter + Synthetics: [52:9..52:13):Refl => *.unapply[Option[B]] [52:31..52:50):identity[Option[B]] => *[Function1[A, Option[B]]] @@ -1409,6 +1472,7 @@ Text => empty Language => Scala Symbols => 5 entries Occurrences => 23 entries +Diagnostics => 1 entries Symbols: example/Example. => final object Example extends Object { self: Example.type => +3 decls } @@ -1442,6 +1506,9 @@ Occurrences: [9:24..9:32): classTag -> scala/reflect/package.classTag(). [9:33..9:36): Int -> scala/Int# +Diagnostics: +[2:24..2:30): [warning] unused import + expect/Extension.scala ---------------------- @@ -1886,6 +1953,7 @@ Text => empty Language => Scala Symbols => 2 entries Occurrences => 16 entries +Diagnostics => 1 entries Symbols: _empty_/Imports$package. => final package object _empty_ extends Object { self: _empty_.type => +2 decls } @@ -1909,6 +1977,9 @@ Occurrences: [3:25..3:28): Int -> scala/Int# [3:30..3:33): Int -> scala/Int# +Diagnostics: +[0:26..0:34): [warning] unused import + expect/InstrumentTyper.scala ---------------------------- @@ -3741,6 +3812,7 @@ Text => empty Language => Scala Symbols => 22 entries Occurrences => 45 entries +Diagnostics => 3 entries Synthetics => 11 entries Symbols: @@ -3756,7 +3828,7 @@ example/ValPattern#app(). => method app (): Unit example/ValPattern#left. => val method left Int example/ValPattern#leftVar(). => var method leftVar Int example/ValPattern#number1. => val method number1 Int -example/ValPattern#number1Var(). => var method number1Var Int +example/ValPattern#number1Var(). => val method number1Var Int example/ValPattern#q1. => val method q1 Nothing example/ValPattern#right. => val method right Int example/ValPattern#rightVar(). => var method rightVar Int @@ -3765,7 +3837,7 @@ local1 => val local right: Int local2 => val local number1: Int local3 => var local leftVar: Int local4 => var local rightVar: Int -local5 => var local number1Var: Int +local5 => val local number1Var: Int Occurrences: [0:8..0:15): example <- example/ @@ -3814,6 +3886,11 @@ Occurrences: [39:10..39:17): leftVar -> local3 [40:10..40:18): rightVar -> local4 +Diagnostics: +[30:11..30:18): [warning] unset local variable, consider using an immutable val instead +[30:20..30:28): [warning] unset local variable, consider using an immutable val instead +[31:15..31:25): [warning] unset local variable, consider using an immutable val instead + Synthetics: [5:6..5:10):Some => *.unapply[Int] [6:4..6:8):Some => *.apply[Int] @@ -3837,6 +3914,7 @@ Text => empty Language => Scala Symbols => 42 entries Occurrences => 129 entries +Diagnostics => 1 entries Symbols: example/ValUsages. => final object ValUsages extends Object { self: ValUsages.type => +2 decls } @@ -4013,6 +4091,9 @@ Occurrences: [49:2..49:3): v -> example/ValUsages.v. [49:4..49:18): explicitSetter -> example/Vals#`explicitSetter_=`(). +Diagnostics: +[2:20..2:21): [warning] unused explicit parameter + expect/Vararg.scala ------------------- @@ -4055,6 +4136,7 @@ Text => empty Language => Scala Symbols => 8 entries Occurrences => 18 entries +Diagnostics => 1 entries Symbols: _empty_/Test_depmatch. => final object Test_depmatch extends Object { self: Test_depmatch.type => +4 decls } @@ -4086,6 +4168,9 @@ Occurrences: [6:19..6:20): U -> local0 [6:24..6:27): ??? -> scala/Predef.`???`(). +Diagnostics: +[6:8..6:9): [warning] unused local definition + expect/example-dir/FileInDir.scala ---------------------------------- @@ -4369,6 +4454,7 @@ Text => empty Language => Scala Symbols => 7 entries Occurrences => 9 entries +Diagnostics => 1 entries Symbols: i9727/Test# => class Test extends Object { self: Test => +2 decls } @@ -4390,6 +4476,9 @@ Occurrences: [4:4..4:5): b <- i9727/i9727$package.b. [4:12..4:16): Test -> i9727/Test# +Diagnostics: +[2:11..2:12): [warning] unused explicit parameter + expect/i9782.scala ------------------ @@ -4786,6 +4875,7 @@ Text => empty Language => Scala Symbols => 50 entries Occurrences => 78 entries +Diagnostics => 4 entries Synthetics => 2 entries Symbols: @@ -4920,6 +5010,12 @@ Occurrences: [25:27..25:28): t <- local1 [25:33..25:36): ??? -> scala/Predef.`???`(). +Diagnostics: +[9:30..9:31): [warning] unused explicit parameter +[9:36..9:37): [warning] unused explicit parameter +[9:42..9:43): [warning] unused explicit parameter +[21:11..21:12): [warning] unused explicit parameter + Synthetics: [23:6..23:10):List => *.unapplySeq[Nothing] [24:19..24:23):List => *.unapplySeq[Nothing] @@ -4934,6 +5030,7 @@ Text => empty Language => Scala Symbols => 143 entries Occurrences => 246 entries +Diagnostics => 1 entries Synthetics => 1 entries Symbols: @@ -5329,6 +5426,9 @@ Occurrences: [119:32..119:38): Option -> scala/Option# [119:39..119:42): Int -> scala/Int# +Diagnostics: +[5:13..5:14): [warning] unused explicit parameter + Synthetics: [68:20..68:24):@ann => *[Int]