Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Semester Project] Add new front-end phase for unused entities and add support for unused imports #16157

Merged
merged 54 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
27bfda8
Report simple unused import
PaulCoral Sep 30, 2022
93ba6c9
Merge branch 'lampepfl:main' into feature/linter/unused
PaulCoral Sep 30, 2022
f2c1551
Add warnings for unused wildcard imports
PaulCoral Oct 4, 2022
d6fa4cb
Add tests and fixes for unused warning
PaulCoral Oct 8, 2022
9f75334
Add warning unused given imports
PaulCoral Oct 9, 2022
b131601
Merge branch 'lampepfl:main' into feature/linter/unused
PaulCoral Oct 9, 2022
e37c2f9
Add tests for inline method
PaulCoral Oct 10, 2022
2d6da62
Add an `isRunnable` for `CheckUnused`
PaulCoral Oct 11, 2022
617155d
Merge branch 'lampepfl:main' into feature/linter/unused
PaulCoral Oct 14, 2022
0801dd6
Ignore exclusion when unused import
PaulCoral Oct 14, 2022
a6e7d05
Merge branch 'lampepfl:main' into feature/linter/unused
PaulCoral Oct 23, 2022
e1188b6
Add "-Wunused:locals" warning support
PaulCoral Oct 23, 2022
5447cdb
Add "-Wunused:privates" warning option
PaulCoral Oct 24, 2022
950e7de
Fix CheckUnused phasename
PaulCoral Oct 25, 2022
9ad1daa
Merge branch 'lampepfl:main' into feature/linter/unused
PaulCoral Oct 28, 2022
5ecb0eb
fix overlapping warning
PaulCoral Oct 28, 2022
a1c2bae
Merge branch 'lampepfl:main' into feature/linter/unused
PaulCoral Oct 31, 2022
f993782
Fix warning location
PaulCoral Oct 31, 2022
b2fd8cb
Add -Wunused:params,explicits,implicits,patvars
PaulCoral Nov 6, 2022
368748a
Merge branch 'lampepfl:main' into feature/linter/unused
PaulCoral Nov 6, 2022
e69c4a3
Merge branch 'feature/linter/unused' of github.com:PaulCoral/dotty in…
PaulCoral Nov 6, 2022
8ac97b3
Fix requested changes, add new tests
PaulCoral Nov 16, 2022
892621b
Annotation usage, allow unsed Self, add tests
PaulCoral Nov 17, 2022
6d8d20d
Refactor CheckUnused, fix pkg false negative
PaulCoral Nov 17, 2022
412412c
No -Wunused:imports for language imports
PaulCoral Nov 17, 2022
f354b96
Clean CheckUnused phase code, add doc+comments
PaulCoral Nov 18, 2022
d41c6dd
Remove report unused implicit imports
PaulCoral Nov 23, 2022
95c8a40
Revert to unused implicit check, also synthetics
PaulCoral Nov 24, 2022
b2f0fa1
Add warn Annotated Types and "new" kw
PaulCoral Dec 5, 2022
82290c8
Fix unused imports in import stmt
PaulCoral Dec 5, 2022
5a755dd
Reports more import alternatives
PaulCoral Dec 5, 2022
2ed1f1f
Warn unused Imports methods overload
PaulCoral Dec 5, 2022
8a91af1
Add an helpful message for `-W` option
PaulCoral Dec 12, 2022
ca8dbaf
Merge branch 'feature/linter/unused' of github.com:PaulCoral/dotty in…
PaulCoral Dec 12, 2022
426d34a
Fix typo in help -W
PaulCoral Dec 12, 2022
5ab55f8
Fix isBlank not member of String on CI
PaulCoral Dec 12, 2022
0cb2af0
Add `-Wunused:strict-no-implicit-warn` warning option
PaulCoral Dec 13, 2022
d1f9441
Fix test i15503j
PaulCoral Dec 13, 2022
e158a9f
Add better support for unused renamed import
PaulCoral Dec 13, 2022
e2b6b61
Clean, refine scope, add comments
PaulCoral Dec 14, 2022
b0790d1
Refactor CheckUnused into a MiniPhase
PaulCoral Dec 16, 2022
7f04ce3
Add support for @annotation.unused
PaulCoral Dec 26, 2022
779ec7d
Add support for trivial body
PaulCoral Dec 26, 2022
d37d99e
Fix the import precedence in -Wunused:imports
PaulCoral Dec 27, 2022
ae24d64
Improve -Wunused:locals
PaulCoral Dec 27, 2022
527aa31
Fix -Wunused:privates trait accessor
PaulCoral Dec 27, 2022
bfa20a1
Fix -Wunused:locals,privates with recursive
PaulCoral Dec 27, 2022
c70fa68
Fixes for -Wunused:params
PaulCoral Dec 29, 2022
7de90b3
Add better support for trivial methods -Wunused
PaulCoral Jan 3, 2023
c89e27c
Merge branch 'lampepfl:main' into feature/linter/unused
PaulCoral Jan 3, 2023
422ecb8
Merge branch 'lampepfl:main' into feature/linter/unused
PaulCoral Jan 4, 2023
4a06bc6
Remove unused method in CheckUnused
PaulCoral Jan 5, 2023
1db9040
Merge branch 'feature/linter/unused' of github.com:PaulCoral/dotty in…
PaulCoral Jan 5, 2023
08f807c
Make -Wunused:patvars to unsafe
PaulCoral Jan 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Compiler {
protected def frontendPhases: List[List[Phase]] =
List(new Parser) :: // Compiler frontend: scanner, parser
List(new TyperPhase) :: // Compiler frontend: namer, typer
List(new CheckUnused) :: // Check for unused 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
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/config/CliCommand.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ trait CliCommand:
def defaultValue = s.default match
case _: Int | _: String => s.default.toString
case _ => ""
val info = List(shortHelp(s), if defaultValue.nonEmpty then s"Default $defaultValue" else "", if s.legalChoices.nonEmpty then s"Choices ${s.legalChoices}" else "")
val info = List(shortHelp(s), if defaultValue.nonEmpty then s"Default $defaultValue" else "", if s.legalChoices.nonEmpty then s"Choices : ${s.legalChoices}" else "")
(s.name, info.filter(_.nonEmpty).mkString("\n"))
end help

Expand Down
47 changes: 45 additions & 2 deletions compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -155,20 +155,63 @@ private sealed trait VerboseSettings:
*/
private sealed trait WarningSettings:
self: SettingGroup =>
import Setting.ChoiceWithHelp

val Whelp: Setting[Boolean] = BooleanSetting("-W", "Print a synopsis of warning options.")
val XfatalWarnings: Setting[Boolean] = BooleanSetting("-Werror", "Fail the compilation if there are any warnings.", aliases = List("-Xfatal-warnings"))

val Wunused: Setting[List[String]] = MultiChoiceSetting(
val Wunused: Setting[List[ChoiceWithHelp[String]]] = MultiChoiceHelpSetting(
name = "-Wunused",
helpArg = "warning",
descr = "Enable or disable specific `unused` warnings",
choices = List("nowarn", "all"),
choices = List(
ChoiceWithHelp("nowarn", ""),
ChoiceWithHelp("all",""),
ChoiceWithHelp(
name = "imports",
description = "Warn if an import selector is not referenced.\n" +
"NOTE : overrided by -Wunused:strict-no-implicit-warn"),
ChoiceWithHelp("patvars","Warn if a variable bound in a pattern is unused"),
ChoiceWithHelp("privates","Warn if a private member is unused"),
ChoiceWithHelp("locals","Warn if a local definition is unused"),
ChoiceWithHelp("explicits","Warn if an explicit parameter is unused"),
ChoiceWithHelp("implicits","Warn if an implicit parameter is unused"),
ChoiceWithHelp("params","Enable -Wunused:explicits,implicits"),
ChoiceWithHelp("linted","Enable -Wunused:imports,privates,locals,implicits"),
ChoiceWithHelp(
name = "strict-no-implicit-warn",
Copy link
Member

Choose a reason for hiding this comment

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

Could we live without this option? It really seems to address an edge case that is very, very unlikely to affect anyone and Martin says it would only stem from a "blatant abuse of inlining and the type system".

There's always @nowarn if someone needs to work around a false positive.

@szymon-rd wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

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

In general I agree, but it's not possible to annotate imports. So I wanted to leave some workaround.

Copy link
Member

Choose a reason for hiding this comment

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

True...

description = "Same as -Wunused:import, only for imports of explicit named members.\n" +
"NOTE : This overrides -Wunused:imports and NOT set by -Wunused:all"
)
),
default = Nil
)
object WunusedHas:
def isChoiceSet(s: String)(using Context) = Wunused.value.pipe(us => us.contains(s))
def allOr(s: String)(using Context) = Wunused.value.pipe(us => us.contains("all") || us.contains(s))
def nowarn(using Context) = allOr("nowarn")

// overrided by strict-no-implicit-warn
def imports(using Context) =
(allOr("imports") || allOr("linted")) && !(strictNoImplicitWarn)
def locals(using Context) =
allOr("locals") || allOr("linted")
/** -Wunused:explicits OR -Wunused:params */
def explicits(using Context) =
allOr("explicits") || allOr("params")
/** -Wunused:implicits OR -Wunused:params */
def implicits(using Context) =
allOr("implicits") || allOr("params") || allOr("linted")
def params(using Context) = allOr("params")
def privates(using Context) =
allOr("privates") || allOr("linted")
def patvars(using Context) =
allOr("patvars")
def linted(using Context) =
allOr("linted")
def strictNoImplicitWarn(using Context) =
isChoiceSet("strict-no-implicit-warn")

val Wconf: Setting[List[String]] = MultiStringSetting(
"-Wconf",
"patterns",
Expand Down
17 changes: 17 additions & 0 deletions compiler/src/dotty/tools/dotc/config/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import annotation.tailrec
import collection.mutable.ArrayBuffer
import reflect.ClassTag
import scala.util.{Success, Failure}
import dotty.tools.dotc.config.Settings.Setting.ChoiceWithHelp

object Settings:

Expand Down Expand Up @@ -189,6 +190,19 @@ object Settings:
def update(x: T)(using Context): SettingsState = setting.updateIn(ctx.settingsState, x)
def isDefault(using Context): Boolean = setting.isDefaultIn(ctx.settingsState)

/**
* A choice with help description.
*
* NOTE : `equals` and `toString` have special behaviors
*/
case class ChoiceWithHelp[T](name: T, description: String):
override def equals(x: Any): Boolean = x match
Copy link
Member

Choose a reason for hiding this comment

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

This looks like a bit of a hack... But I think we can address this in the future, there are probably other things that could be cleaned up in the Settings implementation at some point.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this was a dirty fix, just to give basic documentation for this new feature. I can maybe find a better solution if I have some time once I fixed the main parts of the PR.

case s:String => s == name.toString()
case _ => false
override def toString(): String =
s"\n- $name${if description.isEmpty() then "" else s" :\n\t${description.replace("\n","\n\t")}"}"
end Setting

class SettingGroup {

private val _allSettings = new ArrayBuffer[Setting[?]]
Expand Down Expand Up @@ -270,6 +284,9 @@ object Settings:
def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: List[String], aliases: List[String] = Nil): Setting[List[String]] =
publish(Setting(name, descr, default, helpArg, Some(choices), aliases = aliases))

def MultiChoiceHelpSetting(name: String, helpArg: String, descr: String, choices: List[ChoiceWithHelp[String]], default: List[ChoiceWithHelp[String]], aliases: List[String] = Nil): Setting[List[ChoiceWithHelp[String]]] =
publish(Setting(name, descr, default, helpArg, Some(choices), aliases = aliases))

def IntSetting(name: String, descr: String, default: Int, aliases: List[String] = Nil): Setting[Int] =
publish(Setting(name, descr, default, aliases = aliases))

Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,7 @@ class Definitions {
@tu lazy val MappedAlternativeAnnot: ClassSymbol = requiredClass("scala.annotation.internal.MappedAlternative")
@tu lazy val MigrationAnnot: ClassSymbol = requiredClass("scala.annotation.migration")
@tu lazy val NowarnAnnot: ClassSymbol = requiredClass("scala.annotation.nowarn")
@tu lazy val UnusedAnnot: ClassSymbol = requiredClass("scala.annotation.unused")
@tu lazy val TransparentTraitAnnot: ClassSymbol = requiredClass("scala.annotation.transparentTrait")
@tu lazy val NativeAnnot: ClassSymbol = requiredClass("scala.native")
@tu lazy val RepeatedAnnot: ClassSymbol = requiredClass("scala.annotation.internal.Repeated")
Expand Down
Loading