From 64929b47cc3efa9b6c01d9307247eed347a769cd Mon Sep 17 00:00:00 2001 From: Ingar Abrahamsen Date: Wed, 2 May 2018 15:06:07 +0200 Subject: [PATCH 1/3] improve error message for rename the same import twice --- .../reporting/diagnostic/ErrorMessageID.java | 1 + .../dotc/reporting/diagnostic/messages.scala | 7 +++++++ .../dotty/tools/dotc/transform/PostTyper.scala | 17 ++++++----------- .../dotc/reporting/ErrorMessagesTests.scala | 13 +++++++++++++ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java index 1abe9f119e07..b9941ee11151 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java @@ -129,6 +129,7 @@ public enum ErrorMessageID { JavaSymbolIsNotAValueID, DoubleDeclarationID, MatchCaseOnlyNullWarningID, + ImportRenamedTwiceID, ; public int errorNumber() { diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 54f042d5a62d..e291fc508664 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -2105,4 +2105,11 @@ object messages { } val explanation = "" } + + case class ImportRenamedTwice(ident: untpd.Ident)(implicit ctx: Context) extends Message(ImportRenamedTwiceID) { + val kind = "Syntax" + val msg: String = s"${ident.show} is renamed twice on the same import line." + val explanation: String = "" + } + } diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index 103afdad960a..3416da942a88 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -2,19 +2,14 @@ package dotty.tools.dotc package transform import dotty.tools.dotc.ast.{Trees, tpd, untpd} -import scala.collection.{ mutable, immutable } -import ValueClasses._ -import scala.annotation.tailrec +import scala.collection.mutable import core._ -import typer.ErrorReporting._ import typer.Checking -import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTransformers._ -import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._ -import util.Positions._ +import Types._, Contexts._, Names._, Flags._, DenotTransformers._ +import SymDenotations._, StdNames._, Annotations._, Trees._ import Decorators._ -import config.Printers.typr -import Symbols._, TypeUtils._, SymUtils._ -import reporting.diagnostic.messages.{NotAMember, SuperCallsNotAllowedInline} +import Symbols._, SymUtils._ +import reporting.diagnostic.messages.{ImportRenamedTwice, NotAMember, SuperCallsNotAllowedInline} object PostTyper { val name = "posttyper" @@ -293,7 +288,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase if (name != nme.WILDCARD && !exprTpe.member(name).exists && !exprTpe.member(name.toTypeName).exists) ctx.error(NotAMember(exprTpe, name, "value"), ident.pos) if (seen(ident.name)) - ctx.error(s"${ident.show} is renamed twice", ident.pos) + ctx.error(ImportRenamedTwice(ident), ident.pos) seen += ident.name } selectors.foreach { diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index 1d730311b4dd..a23a4a3f3c29 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -6,6 +6,7 @@ import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Types.WildcardType import dotty.tools.dotc.parsing.Tokens import dotty.tools.dotc.reporting.diagnostic.messages._ +import dotty.tools.dotc.transform.PostTyper import org.junit.Assert._ import org.junit.Test @@ -1348,4 +1349,16 @@ class ErrorMessagesTests extends ErrorMessagesTest { val (msg @ FunctionTypeNeedsNonEmptyParameterList(_, _)) :: Nil = messages assertEquals(msg.mods, "erased implicit") } + + @Test def renameImportTwice = + checkMessagesAfter(PostTyper.name) { + """ + |import java.lang.{Integer => Foo, Integer => Baz} + """.stripMargin + }.expect { (ictx, messages) => + implicit val ctx: Context = ictx + assertMessageCount(1, messages) + val (msg @ ImportRenamedTwice(ident)) :: Nil = messages + assertEquals(ident.show, "Integer") + } } From 12635515acf52c79b6d00baa402894667c0c5b3b Mon Sep 17 00:00:00 2001 From: Ingar Abrahamsen Date: Wed, 2 May 2018 16:27:10 +0200 Subject: [PATCH 2/3] improve error message for @tailrec Now the compiler will give compile errors if the annotation is used on other kinds then methods. --- .../dotc/reporting/diagnostic/messages.scala | 9 ++++++-- .../dotty/tools/dotc/transform/TailRec.scala | 5 ---- .../src/dotty/tools/dotc/typer/Checking.scala | 13 ++++------- .../src/dotty/tools/dotc/typer/FrontEnd.scala | 6 ++++- .../dotc/reporting/ErrorMessagesTests.scala | 23 +++++++++++++++++++ 5 files changed, 39 insertions(+), 17 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index e291fc508664..1dd469df6b85 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1825,10 +1825,15 @@ object messages { } } - case class TailrecNotApplicable(method: Symbol)(implicit ctx: Context) + case class TailrecNotApplicable(symbol: Symbol)(implicit ctx: Context) extends Message(TailrecNotApplicableID) { val kind = "Syntax" - val msg = hl"TailRec optimisation not applicable, $method is neither ${"private"} nor ${"final"}." + val symbolKind = symbol.showKind + val msg = + if (symbol.is(Method)) + hl"TailRec optimisation not applicable, $symbol is neither ${"private"} nor ${"final"}." + else + hl"TailRec optimisation not applicable, ${symbolKind} isn't a method." val explanation = hl"A method annotated ${"@tailrec"} must be declared ${"private"} or ${"final"} so it can't be overridden." } diff --git a/compiler/src/dotty/tools/dotc/transform/TailRec.scala b/compiler/src/dotty/tools/dotc/transform/TailRec.scala index 6ef41144204b..1a38f2935bf3 100644 --- a/compiler/src/dotty/tools/dotc/transform/TailRec.scala +++ b/compiler/src/dotty/tools/dotc/transform/TailRec.scala @@ -6,8 +6,6 @@ import ast.{TreeTypeMap, tpd} import core._ import Contexts.Context import Decorators._ -import DenotTransformers.IdentityDenotTransformer -import Denotations.SingleDenotation import Symbols._ import Types._ import NameKinds.TailLabelName @@ -161,9 +159,6 @@ class TailRec extends MiniPhase with FullParameterization { case d: DefDef if d.symbol.hasAnnotation(defn.TailrecAnnot) || methodsWithInnerAnnots.contains(d.symbol) => ctx.error(TailrecNotApplicable(sym), sym.pos) d - case d if d.symbol.hasAnnotation(defn.TailrecAnnot) || methodsWithInnerAnnots.contains(d.symbol) => - ctx.error("TailRec optimisation not applicable, not a method", sym.pos) - d case _ => tree } diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 1fedfa37f219..26ecee23b338 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -7,33 +7,25 @@ import ast._ import Contexts._ import Types._ import Flags._ -import Denotations._ import Names._ import StdNames._ -import NameOps._ import Symbols._ import Trees._ import TreeInfo._ import ProtoTypes._ -import Constants._ -import Scopes._ import CheckRealizable._ import ErrorReporting.errorTree -import annotation.unchecked import util.Positions._ -import util.Stats -import util.common._ import transform.SymUtils._ import Decorators._ -import Uniques._ import ErrorReporting.{err, errorType} import config.Printers.typr import NameKinds.DefaultGetterName import collection.mutable import SymDenotations.{NoCompleter, NoDenotation} -import dotty.tools.dotc.reporting.diagnostic.{ErrorMessageID, Message} +import dotty.tools.dotc.reporting.diagnostic.Message import dotty.tools.dotc.reporting.diagnostic.messages._ import dotty.tools.dotc.transform.ValueClasses._ @@ -358,6 +350,9 @@ object Checking { fail(AbstractOverrideOnlyInTraits(sym)) if (sym.is(Trait) && sym.is(Final)) fail(TraitsMayNotBeFinal(sym)) + // Skip ModuleVal since the annotation will also be on the ModuleClass + if (sym.hasAnnotation(defn.TailrecAnnot) && !sym.is(Method | ModuleVal)) + fail(TailrecNotApplicable(sym)) if (sym.hasAnnotation(defn.NativeAnnot)) { if (!sym.is(Deferred)) fail(NativeMembersMayNotHaveImplementation(sym)) diff --git a/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala b/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala index 19eb297ff652..0bb16e42a634 100644 --- a/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala +++ b/compiler/src/dotty/tools/dotc/typer/FrontEnd.scala @@ -15,7 +15,7 @@ import ast.Trees._ class FrontEnd extends Phase { - override def phaseName = "frontend" + override def phaseName = FrontEnd.name override def isTyper = true import ast.tpd @@ -103,3 +103,7 @@ class FrontEnd extends Phase { typeCheck } } + +object FrontEnd { + val name = "frontend" +} diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index a23a4a3f3c29..868d9810846f 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -7,6 +7,7 @@ import dotty.tools.dotc.core.Types.WildcardType import dotty.tools.dotc.parsing.Tokens import dotty.tools.dotc.reporting.diagnostic.messages._ import dotty.tools.dotc.transform.PostTyper +import dotty.tools.dotc.typer.FrontEnd import org.junit.Assert._ import org.junit.Test @@ -1361,4 +1362,26 @@ class ErrorMessagesTests extends ErrorMessagesTest { val (msg @ ImportRenamedTwice(ident)) :: Nil = messages assertEquals(ident.show, "Integer") } + + @Test def tailRecOptimisation = + checkMessagesAfter(FrontEnd.name) { + """ + |import scala.annotation.tailrec + |@tailrec + |object Test { + | @tailrec val a = "" + | @tailrec var b = "" + |} + |@tailrec + |class Test {} + | + """.stripMargin + }.expect{ (ictx, messages) => + implicit val ctx: Context = ictx + assertMessageCount(4, messages) + + val tailRegMessages = messages.map{ case m :TailrecNotApplicable => m.symbolKind}.toSet + assertEquals(tailRegMessages, Set("variable", "value", "object", "class")) + } + } From e0632574e93d0ea9ba0ca3a2a0aa748826d78067 Mon Sep 17 00:00:00 2001 From: Ingar Abrahamsen Date: Wed, 2 May 2018 16:41:22 +0200 Subject: [PATCH 3/3] use reference to the phase name in ErrorMessagesTests --- .../dotty/tools/backend/jvm/GenBCode.scala | 25 +-- .../tools/dotc/transform/CheckStatic.scala | 20 +- .../dotty/tools/dotc/typer/RefChecks.scala | 15 +- .../dotc/reporting/ErrorMessagesTests.scala | 173 +++++++++--------- 4 files changed, 107 insertions(+), 126 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala index ed194b8d189f..ad736918e2b9 100644 --- a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala +++ b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala @@ -4,45 +4,32 @@ import dotty.tools.dotc.CompilationUnit import dotty.tools.dotc.ast.Trees.{PackageDef, ValDef} import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Phases.Phase -import dotty.tools.dotc.core.Names.TypeName import scala.collection.mutable -import scala.collection.JavaConverters._ -import scala.tools.asm.{ClassVisitor, CustomAttr, FieldVisitor, MethodVisitor} +import scala.tools.asm.CustomAttr import scala.tools.nsc.backend.jvm._ -import dotty.tools.dotc -import dotty.tools.dotc.transform.Erasure import dotty.tools.dotc.transform.SymUtils._ import dotty.tools.dotc.interfaces import java.util.Optional -import scala.reflect.ClassTag import dotty.tools.dotc.core._ import dotty.tools.dotc.sbt.ExtractDependencies -import Periods._ -import SymDenotations._ import Contexts._ -import Types._ import Symbols._ -import Denotations._ import Decorators._ -import Phases._ -import java.lang.AssertionError -import java.io.{DataOutputStream, File => JFile} -import java.nio.file.{Files, FileSystem, FileSystems, Path => JPath} +import java.io.DataOutputStream -import dotty.tools.io.{Directory, File, Jar} +import dotty.tools.io.Directory import scala.tools.asm import scala.tools.asm.tree._ -import dotty.tools.dotc.util.{DotClass, Positions} import tpd._ import StdNames._ import dotty.tools.io._ class GenBCode extends Phase { - def phaseName: String = "genBCode" + def phaseName: String = GenBCode.name private val entryPoints = new mutable.HashSet[Symbol]() def registerEntryPoint(sym: Symbol) = entryPoints += sym @@ -80,6 +67,10 @@ class GenBCode extends Phase { } } +object GenBCode { + val name: String = "genBCode" +} + class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInterface)(implicit val ctx: Context) extends BCodeSyncAndTry { var tree: Tree = _ diff --git a/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala b/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala index 775965f59c1e..27759cbc90b6 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala @@ -2,26 +2,12 @@ package dotty.tools.dotc package transform import core._ -import Names._ -import StdNames.nme -import Types._ import dotty.tools.dotc.transform.MegaPhase._ -import ast.Trees._ import Flags._ import Contexts.Context import Symbols._ -import Constants._ -import Denotations._ -import SymDenotations._ -import Decorators.StringInterpolators import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Annotations.ConcreteAnnotation -import scala.collection.mutable -import DenotTransformers._ -import Names.Name -import NameOps._ import Decorators._ -import TypeUtils._ import reporting.diagnostic.messages.{MissingCompanionForStatic, StaticFieldsOnlyAllowedInObjects} /** A transformer that check that requirements of Static fields\methods are implemented: @@ -39,7 +25,7 @@ import reporting.diagnostic.messages.{MissingCompanionForStatic, StaticFieldsOnl class CheckStatic extends MiniPhase { import ast.tpd._ - override def phaseName = "checkStatic" + override def phaseName = CheckStatic.name override def transformTemplate(tree: tpd.Template)(implicit ctx: Context): tpd.Tree = { val defns = tree.body.collect{case t: ValOrDefDef => t} @@ -91,3 +77,7 @@ class CheckStatic extends MiniPhase { } else tree } } + +object CheckStatic { + val name = "checkStatic" +} diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index bec2403aff7d..628c069d99d5 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -3,9 +3,8 @@ package typer import transform._ import core._ -import config._ -import Symbols._, SymDenotations._, Types._, Contexts._, Decorators._, Flags._, Names._, NameOps._ -import StdNames._, Denotations._, Scopes._, Constants.Constant, SymUtils._ +import Symbols._, Types._, Contexts._, Flags._, Names._, NameOps._ +import StdNames._, Denotations._, SymUtils._ import NameKinds.DefaultGetterName import Annotations._ import util.Positions._ @@ -16,17 +15,17 @@ import Trees._ import MegaPhase._ import config.Printers.{checks, noPrinter} import util.DotClass -import scala.util.{Try, Success, Failure} -import config.{ScalaVersion, NoScalaVersion} +import scala.util.Failure +import config.NoScalaVersion import Decorators._ import typer.ErrorReporting._ -import DenotTransformers._ object RefChecks { import tpd._ - import reporting.diagnostic.Message import reporting.diagnostic.messages._ + val name = "refchecks" + private val defaultMethodFilter = new NameFilter { def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean = name.is(DefaultGetterName) } @@ -910,7 +909,7 @@ class RefChecks extends MiniPhase { thisPhase => import reporting.diagnostic.messages.ForwardReferenceExtendsOverDefinition import dotty.tools.dotc.reporting.diagnostic.messages.UnboundPlaceholderParameter - override def phaseName: String = "refchecks" + override def phaseName: String = RefChecks.name // Needs to run after ElimRepeated for override checks involving varargs methods override def runsAfter = Set(ElimRepeated.name) diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index 868d9810846f..101d5664973c 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -2,12 +2,13 @@ package dotty.tools package dotc package reporting +import dotty.tools.backend.jvm.GenBCode import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Types.WildcardType import dotty.tools.dotc.parsing.Tokens import dotty.tools.dotc.reporting.diagnostic.messages._ -import dotty.tools.dotc.transform.PostTyper -import dotty.tools.dotc.typer.FrontEnd +import dotty.tools.dotc.transform.{CheckStatic, PostTyper, TailRec} +import dotty.tools.dotc.typer.{FrontEnd, RefChecks} import org.junit.Assert._ import org.junit.Test @@ -15,11 +16,11 @@ class ErrorMessagesTests extends ErrorMessagesTest { // In the case where there are no errors, we can do "expectNoErrors" in the // `Report` @Test def noErrors = - checkMessagesAfter("frontend")("""class Foo""") + checkMessagesAfter(FrontEnd.name)("""class Foo""") .expectNoErrors @Test def typeMismatch = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Foo { | def bar: String = 1 @@ -47,7 +48,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def overridesNothing = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """ |object Foo { | override def bar: Unit = {} @@ -63,7 +64,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def overridesNothingDifferentSignature = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """ |class Bar { | def bar(s: String): Unit = {} @@ -88,7 +89,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def forwardReference = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """ |object Forward { | def block = { @@ -109,7 +110,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def unexpectedToken = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Forward { | def val = "ds" @@ -126,7 +127,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def expectedToken = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Forward { | def `val` = "ds" @@ -136,7 +137,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { .expectNoErrors @Test def leftAndRightAssociative = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Ops { | case class I(j: Int) { @@ -158,7 +159,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def cantInstantiateAbstract = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """ |object Scope { | abstract class Concept @@ -176,7 +177,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def cantInstantiateTrait = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """ |object Scope { | trait Concept @@ -194,7 +195,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def overloadedMethodNeedsReturnType = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class Scope() { | def foo(i: Int) = foo(i.toString) @@ -211,7 +212,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def recursiveMethodNeedsReturnType = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class Scope() { | def i = i + 5 @@ -227,7 +228,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def recursiveValueNeedsReturnType = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class Scope() { | lazy val i = i + 5 @@ -243,7 +244,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def cyclicReferenceInvolving = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class A { | val x: T = ??? @@ -260,7 +261,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def cyclicReferenceInvolvingImplicit = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object implicitDefs { | def foo(implicit x: String) = 1 @@ -280,7 +281,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def superQualMustBeParent = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class A { | def foo(): Unit = () @@ -305,7 +306,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def ambiguousImport = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object A { | class ToBeImported @@ -334,7 +335,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def methodDoesNotTakePrameters = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Scope { | def foo = () @@ -353,7 +354,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def methodDoesNotTakeMorePrameters = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Scope{ | def foo(a: Int) = () @@ -372,7 +373,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def ambiugousOverloadWithWildcard = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """object Context { | trait A { | def foo(s: String): String @@ -396,7 +397,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def reassignmentToVal = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class Context { | val value = 3 @@ -412,7 +413,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def typeDoesNotTakeParameters = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |trait WithOutParams |class Extending extends WithOutParams[String] @@ -427,7 +428,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def parameterizedTypeLacksParameters = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |trait WithParams(s: String) |class Extending extends WithParams @@ -442,7 +443,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def varValParametersMayNotBeCallByName = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { "trait Trait(val noNoNo: => String)" } .expect { (ictx, messages) => @@ -453,7 +454,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def missingTypeParameter = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """object Scope { | val value: List = null |}""".stripMargin @@ -466,7 +467,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def doesNotConformToBound = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class WithParam[A <: List[Int]] |object Scope { | val value: WithParam[Int] = null @@ -482,7 +483,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def doesNotConformToSelfType = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class Base |trait BlendItIn { | this: Base => @@ -503,7 +504,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def doesNotConformToSelfTypeCantBeInstantiated = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class Base |class RequiresBase { self: Base => } |object Scope { @@ -520,7 +521,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def abstractValueMayNotHaveFinalModifier = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """abstract class Foo { | final val s: String |} @@ -535,7 +536,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def topLevelCantBeImplicit = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """package Foo { | implicit object S |} @@ -549,7 +550,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def typesAndTraitsCantBeImplicit = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """class Foo { | implicit trait S |} @@ -563,7 +564,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def onlyClassesCanBeAbstract = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """class Foo { | abstract val s: String |} @@ -577,7 +578,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def abstractOverrideOnlyInTraits = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """class Foo { | abstract override val s: String = "" |} @@ -591,7 +592,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def traitMayNotBeFinal = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """final trait Foo""" } .expect { (ictx, messages) => @@ -602,7 +603,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def nativeMemberMayNotHaveImplementation = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """trait Foo { | @native def foo() = 5 |} @@ -616,7 +617,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def onlyClassesCanHaveDeclaredButUndefinedMembers = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """object Foo { | def foo(): Int |} @@ -630,7 +631,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def cannotExtendAnyval = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """trait Foo extends AnyVal""" } .expect { (ictx, messages) => @@ -641,7 +642,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def cannotHaveSameNameAs = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """trait Foo { | class A |} @@ -658,7 +659,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def valueClassesMayNotDefineInner = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class MyValue(i: Int) extends AnyVal { | class Inner |} @@ -673,7 +674,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def valueClassesMayNotDefineNonParameterField = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class MyValue(i: Int) extends AnyVal { | val illegal: Int |} @@ -688,7 +689,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def valueClassesMayNotDefineASecondaryConstructor = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class MyValue(i: Int) extends AnyVal { | def this() = this(2) |} @@ -703,7 +704,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def valueClassesMayNotContainInitalization = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class MyValue(i: Int) extends AnyVal { | println("Hallo?") |} @@ -717,7 +718,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def valueClassesMayNotBeContained = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class Outer { | class MyValue(i: Int) extends AnyVal |} @@ -731,7 +732,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def valueClassesMayNotWrapItself = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class MyValue(i: MyValue) extends AnyVal""" } .expect { (ictx, messages) => @@ -742,7 +743,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def valueClassParameterMayNotBeVar = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class MyValue(var i: Int) extends AnyVal""" } .expect { (ictx, messages) => @@ -754,7 +755,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def valueClassNeedsOneVal = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """class MyValue() extends AnyVal""" } .expect { (ictx, messages) => @@ -765,7 +766,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def onlyCaseClassOrCaseObjectAllowed = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """case Foobar""" } .expect { (ictx, messages) => @@ -776,7 +777,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def expectedClassOrObjectDef = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """Foo""" } .expect { (ictx, messages) => @@ -787,7 +788,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def implicitClassPrimaryConstructorArity = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Test { | implicit class Foo(i: Int, s: String) @@ -802,7 +803,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def anonymousFunctionMissingParamType = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """ |object AnonymousF { | val f = { case x: Int => x + 1 } @@ -818,7 +819,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def superCallsNotAllowedInline = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """ |class A { | def foo(): Unit = () @@ -845,7 +846,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { private def verifyModifiersNotAllowed(code: String, modifierAssertion: String, typeAssertion: Option[String] = None) = { - checkMessagesAfter("refchecks")(code) + checkMessagesAfter(RefChecks.name)(code) .expect { (ictx, messages) => implicit val ctx: Context = ictx assertMessageCount(1, messages) @@ -856,7 +857,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def wildcardOnTypeArgumentNotAllowedOnNew = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """ |object TyperDemo { | class Team[A] @@ -873,7 +874,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def implicitFunctionTypeNeedsNonEmptyParameterList = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """abstract class Foo { | type Contextual[T] = implicit () => T | val x: implicit () => Int @@ -887,7 +888,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def wrongNumberOfParameters = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """object NumberOfParams { | def unary[T](x: T => Unit) = () | unary((x, y) => ()) @@ -903,7 +904,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def duplicatePrivateProtectedQualifier = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """class Test { | private[Test] protected[this] def foo(): Unit = () |} """.stripMargin @@ -918,7 +919,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def expectedStartOfTopLevelDefinition = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """private Test {}""" } .expect { (ictx, messages) => @@ -931,7 +932,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def missingReturnTypeWithReturnStatement = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """class BadFunction { | def bad() = { return "fail" } |} @@ -946,7 +947,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def noReturnInInline = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """class BadFunction { | @inline def usesReturn: Int = { return 42 } |} @@ -961,7 +962,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def returnOutsideMethodDefinition = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """object A { | return 5 |} @@ -973,7 +974,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { assertEquals("object A", owner.show) } - @Test def extendFinalClass = checkMessagesAfter("refchecks") { + @Test def extendFinalClass = checkMessagesAfter(RefChecks.name) { """final class A | |class B extends A @@ -987,7 +988,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def tailrecNotApplicableNeitherPrivateNorFinal = - checkMessagesAfter("tailrec") { + checkMessagesAfter(TailRec.name) { """ |class Foo { | @scala.annotation.tailrec @@ -1002,7 +1003,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def expectedTypeBoundOrEquals = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """object typedef { | type asd > Seq |} @@ -1016,7 +1017,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def classAndCompanionNameClash = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """ |class T { | class G @@ -1039,7 +1040,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def onlyFunctionsCanBeFollowedByUnderscore = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class T { | def main(args: Array[String]): Unit = { @@ -1057,7 +1058,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def missingEmptyArgumentList = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class Test { | def greet(): String = "Hello" @@ -1076,7 +1077,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def duplicateNamedTypeParameter = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Test { | def f[A, B]() = ??? @@ -1096,7 +1097,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def undefinedNamedTypeParameter = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Test { | def f[A, B]() = ??? @@ -1120,7 +1121,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def illegalStartOfStatement = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Test { | { ) } @@ -1139,7 +1140,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def traitIsExpected = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class A |class B @@ -1160,7 +1161,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def traitRedefinedFinalMethodFromAnyRef = - checkMessagesAfter("refchecks") { + checkMessagesAfter(RefChecks.name) { """ |trait C { | def wait (): Unit @@ -1176,7 +1177,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def packageNameAlreadyDefined = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |package bar { } |object bar { } @@ -1190,7 +1191,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def unapplyInvalidNumberOfArguments = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |case class Boo(a: Int, b: String) | @@ -1212,7 +1213,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def staticOnlyAllowedInsideObjects = - checkMessagesAfter("checkStatic") { + checkMessagesAfter(CheckStatic.name) { """ |class Foo { | @annotation.static def bar(): Unit = bar() @@ -1225,7 +1226,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def cyclicInheritance = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { "class A extends A" } .expect { (ictx, messages) => @@ -1237,7 +1238,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def missingCompanionForStatic = - checkMessagesAfter("checkStatic") { + checkMessagesAfter(CheckStatic.name) { """ |object Foo { | @annotation.static def bar(): Unit = () @@ -1250,7 +1251,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def polymorphicMethodMissingTypeInParent = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |object Test { | import scala.reflect.Selectable.reflectiveSelectable @@ -1267,7 +1268,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def javaSymbolIsNotAValue = - checkMessagesAfter("checkStatic") { + checkMessagesAfter(CheckStatic.name) { """ |package p |object O { @@ -1283,7 +1284,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def i3187 = - checkMessagesAfter("genBCode") { + checkMessagesAfter(GenBCode.name) { """ |package scala |object collection @@ -1295,7 +1296,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def typeDoubleDeclaration = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class Foo { | val a = 1 @@ -1310,7 +1311,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def i4127a = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class Foo { | val x: implicit () => Int = () => 1 @@ -1324,7 +1325,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def i4127b = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class Foo { | val x: erased () => Int = () => 1 @@ -1338,7 +1339,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { } @Test def i4127c = - checkMessagesAfter("frontend") { + checkMessagesAfter(FrontEnd.name) { """ |class Foo { | val x: erased implicit () => Int = () => 1 @@ -1380,7 +1381,7 @@ class ErrorMessagesTests extends ErrorMessagesTest { implicit val ctx: Context = ictx assertMessageCount(4, messages) - val tailRegMessages = messages.map{ case m :TailrecNotApplicable => m.symbolKind}.toSet + val tailRegMessages = messages.map({ case m: TailrecNotApplicable => m.symbolKind }).toSet assertEquals(tailRegMessages, Set("variable", "value", "object", "class")) }