@@ -5,6 +5,7 @@ package diagnostic
5
5
6
6
import dotc .core ._
7
7
import Contexts .Context , Decorators ._ , Symbols ._ , Names ._ , Types ._
8
+ import ast .untpd .{Modifiers , ModuleDef }
8
9
import util .{SourceFile , NoSource }
9
10
import util .{SourcePosition , NoSourcePosition }
10
11
import config .Settings .Setting
@@ -318,4 +319,91 @@ object messages {
318
319
| $code2
319
320
| """ .stripMargin
320
321
}
322
+
323
+ val implicitClassRestrictionsText =
324
+ """ For a full list of restrictions on implicit classes visit
325
+ |http://docs.scala-lang.org/overviews/core/implicit-classes.html""" .stripMargin
326
+
327
+ case class TopLevelImplicitClass (cdef : untpd.TypeDef )(implicit ctx : Context )
328
+ extends Message (10 ) {
329
+ val kind = " Syntax"
330
+
331
+ val msg = hl """ |An ${" implicit class" } may not be top-level """
332
+
333
+ val explanation = {
334
+ val TypeDef (name, impl @ Template (constr0, parents, self, _)) = cdef
335
+ val exampleArgs = constr0.vparamss(0 ).map(_.withMods(Modifiers ()).show).mkString(" , " )
336
+ val exampleBodyDefs = impl.body.collect {
337
+ case t if ! t.isEmpty => t.show
338
+ }
339
+ val exampleBody = if (exampleBodyDefs.isEmpty) " "
340
+ else exampleBodyDefs.mkString(
341
+ start = " {\n " ,
342
+ sep = " \n\n " ,
343
+ end = " \n }"
344
+ )
345
+ hl """ |There may not be any method, member or object in scope with the same name as the
346
+ |implicit class and a case class automatically gets a companion object with the same name
347
+ |created by the compiler which would cause a naming conflict if it were allowed.
348
+ |
349
+ | $implicitClassRestrictionsText
350
+ |
351
+ |To resolve the conflict declare ${cdef.name} inside of an ${" object" } then import the class
352
+ |from the object at the use site if needed, for example:
353
+ |
354
+ |object Implicits {
355
+ | implicit class ${cdef.name}( $exampleArgs) $exampleBody
356
+ |}
357
+ |
358
+ |import Implicits. ${cdef.name}""" .stripMargin
359
+ }
360
+ }
361
+
362
+ case class ImplicitCaseClass (cdef : untpd.TypeDef )(implicit ctx : Context )
363
+ extends Message (11 ) {
364
+ val kind = " Syntax"
365
+
366
+ val msg = hl """ |A ${" case class" } may not be defined as ${" implicit" }"""
367
+
368
+ val explanation =
369
+ hl """ |implicit classes may not be case classes. Instead use a plain class:
370
+ | example: implicit class ${cdef.name}...
371
+ |
372
+ | $implicitClassRestrictionsText""" .stripMargin
373
+ }
374
+
375
+ case class ObjectMayNotHaveSelfType (mdef : untpd.ModuleDef )(implicit ctx : Context )
376
+ extends Message (12 ) {
377
+ val kind = " Syntax"
378
+
379
+ val msg = hl """ | ${" objects" } must not have a ${" self type" }"""
380
+
381
+ val explanation = {
382
+ val ModuleDef (name, tmpl) = mdef
383
+ val ValDef (_, selfTpt, _) = tmpl.self
384
+ hl """ |objects must not have a ${" self type" }:
385
+ |
386
+ |Consider these alternative solutions:
387
+ | - Create a trait or a class instead of an object
388
+ | - Let the object extend a trait containing the self type:
389
+ | example: object $name extends ${selfTpt.show}""" .stripMargin
390
+ }
391
+ }
392
+
393
+ case class TupleTooLong (ts : List [untpd.Tree ])(implicit ctx : Context )
394
+ extends Message (13 ) {
395
+ import Definitions .MaxTupleArity
396
+ val kind = " Syntax"
397
+
398
+ val msg = hl """ |A ${" tuple" } cannot have more than ${MaxTupleArity } members """
399
+
400
+ val explanation = {
401
+ val members = ts.map(_.showSummary).grouped(MaxTupleArity )
402
+ val nestedRepresentation = members.map(_.mkString(" , " )).mkString(" )(" )
403
+ hl """ |This restriction will be removed in the future.
404
+ |Currently it is possible to use nested tuples when more than ${MaxTupleArity } are needed, for example:
405
+ |
406
+ | (( ${nestedRepresentation})) """ .stripMargin
407
+ }
408
+ }
321
409
}
0 commit comments