Skip to content

Fix #196: Do not instrument default parameter for Scala.js #281

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

Merged
merged 2 commits into from
Oct 28, 2020

Conversation

exoego
Copy link
Contributor

@exoego exoego commented Oct 8, 2019

Closes #196 and scala-js/scala-js#3803

Quick and dirty.
I am not familiar with Scala macro, so advices are appreciated.

@exoego exoego marked this pull request as ready for review October 8, 2019 01:36
@exoego
Copy link
Contributor Author

exoego commented Dec 3, 2019

Hello, could someone review this PR?
I hope this PR fixes an issue that prevents scoverage being used in Scala.js ecosystem.

@exoego
Copy link
Contributor Author

exoego commented Mar 4, 2020

@sjrd @gzm0 Could you review this from Scala.js creator pov ?

@@ -107,6 +107,15 @@ class ScoverageInstrumentationComponent(val global: Global, extraAfterPhase: Opt
private var options: ScoverageOptions = new ScoverageOptions()
private var coverageFilter: CoverageFilter = AllCoverageFilter

private val isScalaJsEnabled: Boolean = {
try {
getClass.getClassLoader.loadClass("scala.scalajs.js.Any")
Copy link

Choose a reason for hiding this comment

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

This is testing whether scala.scalajs.js.Any is on the classpath of the compiler. This is not what you want. You want to test whether it is on the classpath of the project being compiled. You can test that with

rootMirror.getClassIfDefined("foo") != NoSymbol

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in be4e95d and 3c76241

@@ -17,7 +19,7 @@ object ScoverageCompiler {
case _ => ScalaVersion
}

def classPath = getScalaJars.map(_.getAbsolutePath) :+ sbtCompileDir.getAbsolutePath :+ runtimeClasses.getAbsolutePath
def classPath = (getScalaJars ++ getScalaJsJars ++ List(sbtCompileDir, runtimeClasses)).map(_.getAbsolutePath)
Copy link

Choose a reason for hiding this comment

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

You should not put scalajs-library.jar on the classpath of the compiler, ever. It should be passed to the -classpath setting of the compiler so that it ends up on the classpath of the project being compiled instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 4dffb6c
I am uncertain about this, but addToClassPath seems to append the file at the tend of classpath.

Comment on lines 242 to 244
isScalaJsEnabled && symbol != null && symbol.isSynthetic && symbol.isMethod &&
symbol.nameString.contains("$default$") &&
symbol.tpe.resultType.annotations.exists(_.symbol.nameString == "uncheckedVariance")
Copy link

Choose a reason for hiding this comment

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

This is too broad, and maybe also too restrictive (e.g., I don't know what the uncheckedVariance is doing here).

Here is how we identify an undefined parameter in the real Scala.js compiler:
https://github.com/scala-js/scala-js/blob/4619d906baef7feb5d0b6d555d5b33044669434e/compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala#L2696-L2721
You should basically copy-paste that logic, along with the helper methods that it calls.

Copy link

Choose a reason for hiding this comment

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

Alternatively, you could disable all default parameters under Scala.js. It is less precise, but it will be much easier. In that case you should write

isScalaJsEnabled && symbol.hasFlag(scala.reflect.internal.Flags.DEFAULTPARAM)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy-pasted from scala-js in f83f2ec

@exoego
Copy link
Contributor Author

exoego commented Mar 17, 2020

After 345721b, the below two tests, which import scoverage.macrosupport.Tester, failed due to missing import 🤔

  test("macro range positions should not break plugin") {
    val compiler = ScoverageCompiler.default
    macroSupportDeps.foreach(compiler.addToClassPath(_))
    compiler.compileCodeSnippet( s"""import scoverage.macrosupport.Tester
                          |
                          |object MacroTest {
                          | Tester.test
                          |} """.stripMargin)
    assert(!compiler.reporter.hasErrors)
    assert(!compiler.reporter.hasWarnings)
  }

 test("plugin should not instrument expanded macro code http://github.com/skinny-framework/skinny-framework/issues/97") {
    val compiler = ScoverageCompiler.default
    macroSupportDeps.foreach(compiler.addToClassPath(_))
    compiler.compileCodeSnippet( s"""import scoverage.macrosupport.Tester
                                   |
                                   |class MacroTest {
                                   |  Tester.test
                                   |} """.stripMargin)
    assert(!compiler.reporter.hasErrors)
    assert(!compiler.reporter.hasWarnings)
    compiler.assertNoCoverage()
  }

@julienrf
Copy link

Hello, what’s the status of this PR?

@exoego
Copy link
Contributor Author

exoego commented Oct 23, 2020

Changed from last night,

  • Merged latest master
  • Update sbt-pgp because it seems break build on my end

I have no idea why CI do not run...

@exoego
Copy link
Contributor Author

exoego commented Oct 28, 2020

@sksamuel @D-Roch @gslowikowski @sjrd @julienrf
Could you review on this so scoverage can be used with more Scala.js projects

Copy link

@julienrf julienrf left a comment

Choose a reason for hiding this comment

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

I am not familiar with the Scala.js compiler and scoverage, but the changes look reasonable to me. It would be good to have the approval of someone with more expertise than myself.

Copy link

@sjrd sjrd left a comment

Choose a reason for hiding this comment

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

This LGTM from the point of view of Scala.js.

@sksamuel
Copy link
Member

Seems reasonable from what little I know of scala.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Scala.js breaks scoverage
4 participants