From e60768b62151a160026985269a87fd5b63ee0ae8 Mon Sep 17 00:00:00 2001 From: Vlad Ureche Date: Wed, 14 Sep 2016 14:06:01 +0100 Subject: SI-4700 Add `@infix` annotation for type printing ``` scala> import scala.annotation.infix import scala.annotation.infix scala> @infix class &&[T, U] defined class $amp$amp scala> def foo: Int && Boolean = ??? foo: Int && Boolean ``` --- src/library/scala/annotation/showAsInfix.scala | 21 +++++++++++++++++++++ .../scala/reflect/internal/Definitions.scala | 2 ++ src/reflect/scala/reflect/internal/Types.scala | 14 ++++++++++++++ .../scala/reflect/runtime/JavaUniverseForce.scala | 1 + 4 files changed, 38 insertions(+) create mode 100644 src/library/scala/annotation/showAsInfix.scala (limited to 'src') diff --git a/src/library/scala/annotation/showAsInfix.scala b/src/library/scala/annotation/showAsInfix.scala new file mode 100644 index 0000000000..41c93b697f --- /dev/null +++ b/src/library/scala/annotation/showAsInfix.scala @@ -0,0 +1,21 @@ +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 diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index eca1bbea5a..8dda5737d4 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -1405,6 +1405,8 @@ trait Definitions extends api.StandardDefinitions { case _ => false } + lazy val ShowAsInfixAnnotationClass = rootMirror.getClassIfDefined("scala.annotation.showAsInfix") + // todo: reconcile with javaSignature!!! def signature(tp: Type): String = { def erasure(tp: Type): Type = tp match { diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 7dda805378..54200dea8e 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -307,6 +307,9 @@ trait Types /** Is this type completed (i.e. not a lazy type)? */ def isComplete: Boolean = true + /** Should this be printed as an infix type (@showAsInfix class &&[T, U])? */ + def isShowAsInfixType: Boolean = false + /** If this is a lazy type, assign a new type to `sym`. */ def complete(sym: Symbol) {} @@ -2097,6 +2100,9 @@ trait Types trivial = fromBoolean(!sym.isTypeParameter && pre.isTrivial && areTrivialTypes(args)) toBoolean(trivial) } + + override def isShowAsInfixType: Boolean = sym.hasAnnotation(ShowAsInfixAnnotationClass) + private[Types] def invalidateTypeRefCaches(): Unit = { parentsCache = null parentsPeriod = NoPeriod @@ -2345,6 +2351,14 @@ trait Types xs.init.mkString("(", ", ", ")") + " => " + xs.last } } + else if (isShowAsInfixType && args.length == 2) + args(0) + " " + sym.decodedName + " " + + ( + if (args(1).isShowAsInfixType) + "(" + args(1) + ")" + else + args(1) + ) else if (isTupleTypeDirect(this)) tupleTypeString else if (sym.isAliasType && prefixChain.exists(_.termSymbol.isSynthetic) && (this ne dealias)) diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index caef5535b4..53ac439daa 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -425,6 +425,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.hijackedCoreClasses definitions.symbolsNotPresentInBytecode definitions.isPossibleSyntheticParent + definitions.ShowAsInfixAnnotationClass definitions.abbrvTag definitions.numericWeight definitions.boxedModule -- cgit v1.2.3