@@ -5,11 +5,12 @@ 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
11
12
import interfaces .Diagnostic .{ERROR , WARNING , INFO }
12
- import printing .SyntaxHighlighting ._
13
+ import printing .Highlighting ._
13
14
import printing .Formatting
14
15
15
16
object messages {
@@ -318,4 +319,85 @@ object messages {
318
319
| $code2
319
320
| """ .stripMargin
320
321
}
322
+
323
+ def implicitClassRestrictionsText (implicit ctx : Context ) =
324
+ hl """ ${NoColor (" For a full list of restrictions on implicit classes visit" )}
325
+ | ${Blue (" 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
+ def defHasBody [T ] = impl.body.exists(! _.isEmpty)
337
+ val exampleBody = if (defHasBody) " {\n ...\n }" else " "
338
+ hl """ |There may not be any method, member or object in scope with the same name as the
339
+ |implicit class and a case class automatically gets a companion object with the same name
340
+ |created by the compiler which would cause a naming conflict if it were allowed.
341
+ |
342
+ | """ .stripMargin + implicitClassRestrictionsText + hl """ |
343
+ |
344
+ |To resolve the conflict declare ${cdef.name} inside of an ${" object" } then import the class
345
+ |from the object at the use site if needed, for example:
346
+ |
347
+ |object Implicits {
348
+ | implicit class ${cdef.name}( $exampleArgs) $exampleBody
349
+ |}
350
+ |
351
+ |// At the use site:
352
+ |import Implicits. ${cdef.name}""" .stripMargin
353
+ }
354
+ }
355
+
356
+ case class ImplicitCaseClass (cdef : untpd.TypeDef )(implicit ctx : Context )
357
+ extends Message (11 ) {
358
+ val kind = " Syntax"
359
+
360
+ val msg = hl """ |A ${" case class" } may not be defined as ${" implicit" }"""
361
+
362
+ val explanation =
363
+ hl """ |implicit classes may not be case classes. Instead use a plain class:
364
+ | example: implicit class ${cdef.name}...
365
+ |
366
+ | """ .stripMargin + implicitClassRestrictionsText
367
+ }
368
+
369
+ case class ObjectMayNotHaveSelfType (mdef : untpd.ModuleDef )(implicit ctx : Context )
370
+ extends Message (12 ) {
371
+ val kind = " Syntax"
372
+
373
+ val msg = hl """ | ${" objects" } must not have a ${" self type" }"""
374
+
375
+ val explanation = {
376
+ val ModuleDef (name, tmpl) = mdef
377
+ val ValDef (_, selfTpt, _) = tmpl.self
378
+ hl """ |objects must not have a ${" self type" }:
379
+ |
380
+ |Consider these alternative solutions:
381
+ | - Create a trait or a class instead of an object
382
+ | - Let the object extend a trait containing the self type:
383
+ | example: object $name extends ${selfTpt.show}""" .stripMargin
384
+ }
385
+ }
386
+
387
+ case class TupleTooLong (ts : List [untpd.Tree ])(implicit ctx : Context )
388
+ extends Message (13 ) {
389
+ import Definitions .MaxTupleArity
390
+ val kind = " Syntax"
391
+
392
+ val msg = hl """ |A ${" tuple" } cannot have more than ${MaxTupleArity } members """
393
+
394
+ val explanation = {
395
+ val members = ts.map(_.showSummary).grouped(MaxTupleArity )
396
+ val nestedRepresentation = members.map(_.mkString(" , " )).mkString(" )(" )
397
+ hl """ |This restriction will be removed in the future.
398
+ |Currently it is possible to use nested tuples when more than ${MaxTupleArity } are needed, for example:
399
+ |
400
+ | (( ${nestedRepresentation})) """ .stripMargin
401
+ }
402
+ }
321
403
}
0 commit comments