summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/annotation/showAsInfix.scala42
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala5
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala8
-rw-r--r--test/files/run/t4700.check27
-rw-r--r--test/files/run/t4700.scala11
5 files changed, 50 insertions, 43 deletions
diff --git a/src/library/scala/annotation/showAsInfix.scala b/src/library/scala/annotation/showAsInfix.scala
index 41c93b697f..6c25e08efa 100644
--- a/src/library/scala/annotation/showAsInfix.scala
+++ b/src/library/scala/annotation/showAsInfix.scala
@@ -1,21 +1,27 @@
package scala.annotation
/**
- * This annotation, used for two-parameter generic types makes Scala print
- * the type using infix notation:
- *
- * ```
- * scala> class &&[T, U]
- * defined class $amp$amp
- *
- * scala> def foo: Int && Int = ???
- * foo: &&[Int,Int]
- *
- * scala> @showAsInfix class &&[T, U]
- * defined class $amp$amp
- *
- * scala> def foo: Int && Int = ???
- * foo: Int && Int
- * ```
- */
-class showAsInfix extends annotation.StaticAnnotation \ No newline at end of file
+ * This annotation configures how Scala prints two-parameter generic types.
+ *
+ * By default, types with symbolic names are printed infix; while types without
+ * them are printed using the regular generic type syntax.
+ *
+ * Example of usage:
+ {{{
+ scala> class Map[T, U]
+ defined class Map
+
+ scala> def foo: Int Map Int = ???
+ foo: Map[Int,Int]
+
+ scala> @showAsInfix class Map[T, U]
+ defined class Map
+
+ scala> def foo: Int Map Int = ???
+ foo: Int Map Int
+ }}}
+ *
+ * @param enabled whether to show this type as an infix type operator.
+ * @since 2.12.2
+ */
+class showAsInfix(enabled: Boolean = true) extends annotation.StaticAnnotation \ No newline at end of file
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index cfde164754..14a8e053e9 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -316,8 +316,9 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
/** Check whether any of the arguments mention a symbol */
def refsSymbol(sym: Symbol) = hasArgWhich(_.symbol == sym)
- def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue)
- def intArg(index: Int) = constantAtIndex(index) map (_.intValue)
+ def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue)
+ def intArg(index: Int) = constantAtIndex(index) map (_.intValue)
+ def booleanArg(index: Int) = constantAtIndex(index) map (_.booleanValue)
def symbolArg(index: Int) = argAtIndex(index) collect {
case Apply(fun, Literal(str) :: Nil) if fun.symbol == definitions.Symbol_apply =>
newTermName(str.stringValue)
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 44e96163ea..73103668e3 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -2101,9 +2101,13 @@ trait Types
toBoolean(trivial)
}
- /* It only makes sense to show 2-ary type constructors infix. */
+ /* It only makes sense to show 2-ary type constructors infix.
+ * By default we do only if it's a symbolic name. */
override def isShowAsInfixType: Boolean =
- sym.hasAnnotation(ShowAsInfixAnnotationClass) && hasLength(args, 2)
+ hasLength(args, 2) &&
+ sym.getAnnotation(ShowAsInfixAnnotationClass)
+ .map(_ booleanArg 0 getOrElse true)
+ .getOrElse(!Character.isUnicodeIdentifierStart(sym.decodedName.head))
private[Types] def invalidateTypeRefCaches(): Unit = {
parentsCache = null
diff --git a/test/files/run/t4700.check b/test/files/run/t4700.check
index 40caf0fd36..ae854b959d 100644
--- a/test/files/run/t4700.check
+++ b/test/files/run/t4700.check
@@ -6,16 +6,7 @@ scala> class &&[T,U]
defined class $amp$amp
scala> def foo: Int && Boolean = ???
-foo: &&[Int,Boolean]
-
-scala> @showAsInfix class ||[T,U]
-defined class $bar$bar
-
-scala> def foo: Int || Boolean = ???
-foo: Int || Boolean
-
-scala> @showAsInfix class &&[T, U]
-defined class $amp$amp
+foo: Int && Boolean
scala> def foo: Int && Boolean && String = ???
foo: Int && Boolean && String
@@ -29,7 +20,13 @@ defined type alias Mappy
scala> def foo: Int Mappy (Boolean && String) = ???
foo: Int Mappy (Boolean && String)
-scala> @showAsInfix class &:[L, R]
+scala> @showAsInfix(false) class ||[T,U]
+defined class $bar$bar
+
+scala> def foo: Int || Boolean = ???
+foo: ||[Int,Boolean]
+
+scala> class &:[L, R]
defined class $amp$colon
scala> def foo: Int &: String = ???
@@ -38,10 +35,10 @@ foo: Int &: String
scala> def foo: Int &: Boolean &: String = ???
foo: Int &: Boolean &: String
-scala> def foo: (Int || String) &: Boolean = ???
-foo: (Int || String) &: Boolean
+scala> def foo: (Int && String) &: Boolean = ???
+foo: (Int && String) &: Boolean
-scala> def foo: Int || (Boolean &: String) = ???
-foo: Int || (Boolean &: String)
+scala> def foo: Int && (Boolean &: String) = ???
+foo: Int && (Boolean &: String)
scala> :quit
diff --git a/test/files/run/t4700.scala b/test/files/run/t4700.scala
index 77f0de3d38..7c02676e89 100644
--- a/test/files/run/t4700.scala
+++ b/test/files/run/t4700.scala
@@ -6,18 +6,17 @@ object Test extends ReplTest {
|import scala.annotation.showAsInfix
|class &&[T,U]
|def foo: Int && Boolean = ???
- |@showAsInfix class ||[T,U]
- |def foo: Int || Boolean = ???
- |@showAsInfix class &&[T, U]
|def foo: Int && Boolean && String = ???
|def foo: Int && (Boolean && String) = ???
|@showAsInfix type Mappy[T, U] = Map[T, U]
|def foo: Int Mappy (Boolean && String) = ???
- |@showAsInfix class &:[L, R]
+ |@showAsInfix(false) class ||[T,U]
+ |def foo: Int || Boolean = ???
+ |class &:[L, R]
|def foo: Int &: String = ???
|def foo: Int &: Boolean &: String = ???
- |def foo: (Int || String) &: Boolean = ???
- |def foo: Int || (Boolean &: String) = ???
+ |def foo: (Int && String) &: Boolean = ???
+ |def foo: Int && (Boolean &: String) = ???
|""".stripMargin
}