diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala index 7d5886193c6b..1e855e6e541a 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala @@ -96,7 +96,9 @@ trait ClassLikeSupport: getSupertypesGraph(LinkToType(selfSignature, classDef.symbol.dri, bareClasslikeKind(classDef.symbol)), unpackTreeToClassDef(classDef).parents) ) - val baseMember = mkMember(classDef.symbol, kindForClasslike(classDef), selfSignature)( + val kind = if intrinsicClassDefs.contains(classDef.symbol) then Kind.Class(Nil, Nil) else kindForClasslike(classDef) + + val baseMember = mkMember(classDef.symbol, kind, selfSignature)( modifiers = modifiers, graph = graph, deprecated = classDef.symbol.isDeprecated(), @@ -253,8 +255,9 @@ trait ClassLikeSupport: } def getParentsAsTreeSymbolTuples: List[(Tree, Symbol)] = - for - parentTree <- c.parents if isValidPos(parentTree.pos) // We assume here that order is correct + if noPosClassDefs.contains(c.symbol) then Nil + else for + parentTree <- c.parents if parentTree.pos.start != parentTree.pos.end // We assume here that order is correct parentSymbol = parentTree match case t: TypeTree => t.tpe.typeSymbol case tree if tree.symbol.isClassConstructor => tree.symbol.owner @@ -482,7 +485,7 @@ trait ClassLikeSupport: def unwrapMemberInfo(c: ClassDef, symbol: Symbol): MemberInfo = - val baseTypeRepr = memberInfo(c, symbol) + val baseTypeRepr = typeForClass(c).memberType(symbol) def isSyntheticEvidence(name: String) = if !name.startsWith(NameKinds.EvidenceParamName.separator) then false else @@ -551,4 +554,4 @@ trait ClassLikeSupport: if parameters(0).symbol.flags.is(Flags.Given) then "using " else if parameters(0).symbol.flags.is(Flags.Implicit) then "implicit " else "" - else "" \ No newline at end of file + else "" diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/SyntheticSupport.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/SyntheticSupport.scala index 735d9c74d733..8b98e40fd6b0 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/SyntheticSupport.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/SyntheticSupport.scala @@ -5,17 +5,6 @@ import scala.quoted._ object SyntheticsSupport: - extension (using Quotes)(t: reflect.TypeRepr) - - def isCompiletimeAppliedType: Boolean = t.hackIsCompiletimeAppliedType(t) - - private def hackIsCompiletimeAppliedType(rtpe: reflect.TypeRepr): Boolean = - import dotty.tools.dotc - given ctx: dotc.core.Contexts.Context = quotes.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx - val tpe = rtpe.asInstanceOf[dotc.core.Types.Type] - ctx.definitions.isCompiletimeAppliedType(tpe.typeSymbol) - end extension - extension (using Quotes)(s: reflect.Symbol) def isSyntheticFunc: Boolean = import reflect._ @@ -29,39 +18,32 @@ object SyntheticsSupport: import reflect._ s.flags.is(Flags.Opaque) - def isInfix: Boolean = hackIsInfix(s) - def getmembers: List[reflect.Symbol] = hackGetmembers(s) end extension - def isValidPos(using Quotes)(pos: reflect.Position) = - if hackExists(pos) then pos.start != pos.end else false - def isSyntheticField(using Quotes)(c: reflect.Symbol) = import reflect._ c.flags.is(Flags.CaseAccessor) || (c.flags.is(Flags.Module) && !c.flags.is(Flags.Given)) def constructorWithoutParamLists(using Quotes)(c: reflect.ClassDef): Boolean = - !isValidPos(c.constructor.pos) || { + c.constructor.pos.start == c.constructor.pos.end || { val end = c.constructor.pos.end val typesEnd = c.constructor.leadingTypeParams.lastOption.fold(end - 1)(_.pos.end) val classDefTree = c.constructor.show c.constructor.leadingTypeParams.nonEmpty && end <= typesEnd + 1 } - // TODO: #49 Remove it after TASTY-Reflect release with published flag Extension - private def hackIsInfix(using Quotes)(rsym: reflect.Symbol): Boolean = { - import reflect._ - import dotty.tools.dotc - given ctx: dotc.core.Contexts.Context = quotes.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx - val sym = rsym.asInstanceOf[dotc.core.Symbols.Symbol] - ctx.definitions.isInfix(sym) - } + def getSupertypes(using Quotes)(c: reflect.ClassDef) = + c.symbol.typeRef.baseClasses.map(b => b -> c.symbol.typeRef.baseType(b)).tail + + def typeForClass(using Quotes)(c: reflect.ClassDef): reflect.TypeRepr = + c.symbol.typeRef.appliedTo(c.symbol.typeMembers.filter(_.isTypeParam).map(_.typeRef)) + /* We need there to filter out symbols with certain flagsets, because these symbols come from compiler and TASTY can't handle them well. - They are valdefs that describe case companion objects and cases from enum. - TASTY crashed when calling _.tree on them. - */ + They are valdefs that describe case companion objects and cases from enum. + TASTY crashed when calling _.tree on them. + */ private def hackGetmembers(using Quotes)(rsym: reflect.Symbol): List[reflect.Symbol] = { import reflect._ import dotty.tools.dotc @@ -75,40 +57,3 @@ object SyntheticsSupport: sym.asInstanceOf[Symbol] }.toList } - - private def hackGetSupertypes(using Quotes)(rdef: reflect.ClassDef) = { - import reflect._ - import dotty.tools.dotc - given dotc.core.Contexts.Context = quotes.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx - val classdef = rdef.asInstanceOf[dotc.ast.tpd.TypeDef] - val ref = classdef.symbol.info.asInstanceOf[dotc.core.Types.ClassInfo].appliedRef - val baseTypes: List[(dotc.core.Symbols.Symbol, dotc.core.Types.Type)] = - ref.baseClasses.map(b => b -> ref.baseType(b)) - baseTypes.asInstanceOf[List[(Symbol, TypeRepr)]] - } - - private def hackExists(using Quotes)(rpos: reflect.Position) = { - import reflect._ - import dotty.tools.dotc - import dotty.tools.dotc.util.Spans._ - given dotc.core.Contexts.Context = quotes.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx - val pos = rpos.asInstanceOf[dotc.util.SourcePosition] - pos.exists - } - - def getSupertypes(using Quotes)(c: reflect.ClassDef) = hackGetSupertypes(c).tail - - def typeForClass(using Quotes)(c: reflect.ClassDef): reflect.TypeRepr = - import reflect._ - import dotty.tools.dotc - given dotc.core.Contexts.Context = quotes.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx - val cSym = c.symbol.asInstanceOf[dotc.core.Symbols.Symbol] - cSym.typeRef.appliedTo(cSym.typeParams.map(_.typeRef)).asInstanceOf[TypeRepr] - - def memberInfo(using Quotes)(c: reflect.ClassDef, symbol: reflect.Symbol): reflect.TypeRepr = - import reflect._ - import dotty.tools.dotc - given dotc.core.Contexts.Context = quotes.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx - typeForClass(c).asInstanceOf[dotc.core.Types.Type] - .memberInfo(symbol.asInstanceOf[dotc.core.Symbols.Symbol]) - .asInstanceOf[TypeRepr] diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/TastyParser.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/TastyParser.scala index 76416c793b1d..b78dab1e28df 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/TastyParser.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/TastyParser.scala @@ -123,27 +123,17 @@ case class ScaladocTastyInspector()(using ctx: DocContext) extends DocTastyInspe topLevels ++= parser.parseRootTree(treeRoot) } - val defn = ctx.compilerContext.definitions - if ctx.args.documentSyntheticTypes then - val intrinsicClassDefs = Seq( - defn.AnyClass, - defn.MatchableClass, - defn.AnyKindClass, - defn.AnyValClass, - defn.NullClass, - defn.NothingClass, - defn.SingletonClass, - defn.andType, - defn.orType, - ).map { s => - "scala" -> s.asInstanceOf[parser.qctx.reflect.Symbol].tree.match { - case cd: parser.qctx.reflect.ClassDef => parser.parseClasslike(cd) - case td: parser.qctx.reflect.TypeDef => parser.parseTypeDef(td) - } + import parser.qctx.reflect._ + val intrinsicTypeDefs = parser.intrinsicTypeDefs.toSeq.map { s => + "scala" -> parser.parseTypeDef(s.tree.asInstanceOf[TypeDef]) + } + val intrinsicClassDefs = parser.intrinsicClassDefs.toSeq.map { s => + "scala" -> parser.parseClasslike(s.tree.asInstanceOf[ClassDef]) } topLevels ++= intrinsicClassDefs - val scalaPckg = defn.ScalaPackageVal.asInstanceOf[parser.qctx.reflect.Symbol] + topLevels ++= intrinsicTypeDefs + val scalaPckg = defn.ScalaPackage given parser.qctx.type = parser.qctx topLevels += "scala" -> Member(scalaPckg.fullName, scalaPckg.dri, Kind.Package) topLevels += mergeAnyRefAliasAndObject(parser) @@ -167,12 +157,13 @@ case class ScaladocTastyInspector()(using ctx: DocContext) extends DocTastyInspe }.toList -> rootDoc def mergeAnyRefAliasAndObject(parser: TastyParser) = - val defn = ctx.compilerContext.definitions - val oM = parser.parseClasslike(defn.ObjectClass.asInstanceOf[parser.qctx.reflect.Symbol].tree.asInstanceOf[parser.qctx.reflect.ClassDef]) - val aM = parser.parseTypeDef(defn.AnyRefAlias.asInstanceOf[parser.qctx.reflect.Symbol].tree.asInstanceOf[parser.qctx.reflect.TypeDef]) + import parser.qctx.reflect._ + val javaLangObjectDef = defn.ObjectClass.tree.asInstanceOf[ClassDef] + val objectMembers = parser.extractPatchedMembers(javaLangObjectDef) + val aM = parser.parseTypeDef(defn.AnyRefClass.tree.asInstanceOf[TypeDef]) "scala" -> aM.copy( - kind = oM.kind, - members = oM.members + kind = Kind.Class(Nil, Nil), + members = objectMembers ) /** Parses a single Tasty compilation unit. */ case class TastyParser( @@ -187,6 +178,25 @@ case class TastyParser( private given qctx.type = qctx + val intrinsicClassDefs = Set( + defn.AnyClass, + defn.MatchableClass, + defn.ScalaPackage.typeMember("AnyKind"), + defn.AnyValClass, + defn.NullClass, + defn.NothingClass, + defn.ScalaPackage.typeMember("Singleton"), + ) + + val noPosClassDefs = intrinsicClassDefs ++ Set( + defn.ObjectClass, + defn.AnyRefClass + ) + + val intrinsicTypeDefs = Set( + defn.ScalaPackage.typeMember("&"), + defn.ScalaPackage.typeMember("|"), + ) def processTree[T](tree: Tree)(op: => T): Option[T] = try Option(op) catch case e: Exception => report.warning(throwableToString(e), tree.pos)