<commit_before>package scala.meta

import org.scalameta.adt._
import org.scalameta.annotations._
import org.scalameta.invariants._
import org.scalameta.unreachable
import scala.{Seq => _}
import scala.annotation.compileTimeOnly
import scala.collection.immutable.Seq
import scala.reflect.{ClassTag, classTag}
import scala.meta.ui.{Exception => SemanticException}
import scala.meta.semantic.{Context => SemanticContext}

package object semantic {
  // ===========================
  // PART 1: ATTRIBUTES
  // ===========================

  @root trait Attr
  object Attr {
    // TODO: design the attr hierarchy of semantic facts that can be figured out about trees
    // TODO: examples: a type of a tree, a definition/definitions the tree refers to, maybe a desugaring, etc
    // TODO: see https://github.com/JetBrains/intellij-scala/blob/master/src/org/jetbrains/plugins/scala/lang/resolve/ScalaResolveResult.scala#L24
    @leaf class Type(tpe: scala.meta.Type) extends Attr
  }

  implicit class SemanticTreeOps(val tree: Tree) extends AnyVal {
    @hosted private[meta] def internalAttr[T: ClassTag]: T = {
      val relevant = tree.attrs.collect{ case x: T => x }
      require(relevant.length < 2)
      relevant match {
        case Seq(tpe) => tpe
        case Seq() => throw new SemanticException(s"failed to figure out ${classTag[T].runtimeClass.getName.toLowerCase} of ${tree.summary}")
        case _ => unreachable
      }
    }
    @hosted def attrs: Seq[Attr] = askHost
    @hosted def owner: Scope = ???
  }

  sealed trait HasTpe[+T, U]
  object HasTpe {
    implicit object Term extends HasTpe[meta.Term, meta.Type]
    implicit object Member extends HasTpe[meta.Member, meta.Type]
    implicit object Ctor extends HasTpe[meta.Ctor, meta.Type]
    implicit object TemplateParam extends HasTpe[meta.Templ.Param, meta.Type.Arg]
    implicit object Templ extends HasTpe[meta.Templ, meta.Type]
  }

  implicit class SemanticTypeableOps[T <: Tree, U <: Type : ClassTag](val tree: T)(implicit ev: HasTpe[T, U]) {
    @hosted def tpe: U = tree.internalAttr[Attr.Type].tpe.require[U]
  }

  sealed trait HasDefn[+T, U]
  object HasDefn {
    implicit object Ref extends HasDefn[meta.Ref, meta.Member]
    implicit object TermRef extends HasDefn[meta.Term.Ref, meta.Member.Term]
    implicit object TypeRef extends HasDefn[meta.Type.Ref, meta.Member] // Type.Ref can refer to both types (regular types) and terms (singleton types)
    implicit object Selector extends HasDefn[meta.Selector, meta.Member]
  }

  implicit class SemanticResolvableOps[T <: Tree, U <: Tree](val tree: T)(implicit ev: HasDefn[T, U]) {
    @hosted def defns: Seq[U] = ???
    @hosted def defn: U = ???
  }

  implicit class SemanticCtorRefOps(val tree: Ctor.Ref) extends AnyVal {
    @hosted def ctor: Ctor = ???
  }

  // ===========================
  // PART 2: TYPES
  // ===========================

  implicit class SemanticTypeOps(val tree: Type) extends AnyVal {
    @hosted def <:<(other: Type): Boolean = ???
    @hosted def weak_<:<(other: Type): Boolean = ???
    @hosted def widen: Type = ???
    @hosted def dealias: Type = ???
    @hosted def companion: Type.Ref = ???
    @hosted def parents: Seq[Type] = ???
  }

  @hosted def lub(tpes: Seq[Type]): Type = ???
  @hosted def glb(tpes: Seq[Type]): Type = ???

  // ===========================
  // PART 3: MEMBERS
  // ===========================

  implicit class SemanticMemberOps(val tree: Member) extends AnyVal {
    @hosted def ref: Ref = ???
    @hosted def parents: Seq[Member] = ???
    @hosted def children: Seq[Member] = ???
    @hosted def companion: Member = ???
    @hosted def mods: Seq[Mod] = ???
    @hosted def annots: Seq[Ctor.Ref] = ???
    @hosted def isVal: Boolean = ???
    @hosted def isVar: Boolean = ???
    @hosted def isDef: Boolean = ???
    @hosted def isMacro: Boolean = ???
    @hosted def isAbstractType: Boolean = ???
    @hosted def isAliasType: Boolean = ???
    @hosted def isClass: Boolean = ???
    @hosted def isTrait: Boolean = ???
    @hosted def isObject: Boolean = ???
    @hosted def isPackage: Boolean = ???
    @hosted def isPackageObject: Boolean = ???
    @hosted def isPrivate: Boolean = ???
    @hosted def isProtected: Boolean = ???
    @hosted def isPublic: Boolean = ???
    @hosted def accessBoundary: Member = ???
    @hosted def isImplicit: Boolean = ???
    @hosted def isFinal: Boolean = ???
    @hosted def isSealed: Boolean = ???
    @hosted def isOverride: Boolean = ???
    @hosted def isCase: Boolean = ???
    @hosted def isAbstract: Boolean = ???<commit_msg>more easy pickings based on Context methods<commit_after>package scala.meta

import org.scalameta.adt._
import org.scalameta.annotations._
import org.scalameta.invariants._
import org.scalameta.unreachable
import scala.{Seq => _}
import scala.annotation.compileTimeOnly
import scala.collection.immutable.Seq
import scala.reflect.{ClassTag, classTag}
import scala.meta.ui.{Exception => SemanticException}
import scala.meta.semantic.{Context => SemanticContext}

package object semantic {
  // ===========================
  // PART 1: ATTRIBUTES
  // ===========================

  @root trait Attr
  object Attr {
    // TODO: design the attr hierarchy of semantic facts that can be figured out about trees
    // TODO: examples: a type of a tree, a definition/definitions the tree refers to, maybe a desugaring, etc
    // TODO: see https://github.com/JetBrains/intellij-scala/blob/master/src/org/jetbrains/plugins/scala/lang/resolve/ScalaResolveResult.scala#L24
    @leaf class Type(tpe: scala.meta.Type) extends Attr
    @leaf class Defns(defns: Seq[scala.meta.Tree] @nonEmpty) extends Attr
  }

  implicit class SemanticTreeOps(val tree: Tree) extends AnyVal {
    @hosted private[meta] def internalAttr[T: ClassTag]: T = {
      val relevant = tree.attrs.collect{ case x: T => x }
      require(relevant.length < 2)
      relevant match {
        case Seq(tpe) => tpe
        case Seq() => throw new SemanticException(s"failed to figure out ${classTag[T].runtimeClass.getName.toLowerCase} of ${tree.summary}")
        case _ => unreachable
      }
    }
    @hosted def attrs: Seq[Attr] = askHost
    @hosted def owner: Scope = askHost
  }

  sealed trait HasTpe[+T, U]
  object HasTpe {
    implicit object Term extends HasTpe[meta.Term, meta.Type]
    implicit object Member extends HasTpe[meta.Member, meta.Type]
    implicit object Ctor extends HasTpe[meta.Ctor, meta.Type]
    implicit object TemplateParam extends HasTpe[meta.Templ.Param, meta.Type.Arg]
    implicit object Templ extends HasTpe[meta.Templ, meta.Type]
  }

  implicit class SemanticTypeableOps[T <: Tree, U <: Type : ClassTag](val tree: T)(implicit ev: HasTpe[T, U]) {
    @hosted def tpe: U = tree.internalAttr[Attr.Type].tpe.require[U]
  }

  sealed trait HasDefn[+T, U]
  object HasDefn {
    implicit object Ref extends HasDefn[meta.Ref, meta.Member]
    implicit object TermRef extends HasDefn[meta.Term.Ref, meta.Member.Term]
    implicit object TypeRef extends HasDefn[meta.Type.Ref, meta.Member] // Type.Ref can refer to both types (regular types) and terms (singleton types)
    implicit object Selector extends HasDefn[meta.Selector, meta.Member]
  }

  implicit class SemanticResolvableOps[T <: Tree, U <: Tree](val tree: T)(implicit ev: HasDefn[T, U]) {
    @hosted def defns: Seq[U] = tree.internalAttr[Attr.Defns].defns.require[Seq[U]]
    @hosted def defn: U = {
      defns match {
        case Seq(single) => single
        case Seq(_, _*) => throw new SemanticException(s"multiple definitions found for ${tree.summary}")
        case Seq() => unreachable
      }
    }
  }

  implicit class SemanticCtorRefOps(val tree: Ctor.Ref) extends AnyVal {
    @hosted def ctor: Ctor = {
      tree.internalAttr[Attr.Defns].defns.require[Seq[Ctor]] match {
        case Seq(single) => single
        case Seq(_, _*) => throw new SemanticException(s"multiple constructors found for ${tree.summary}")
        case Seq() => unreachable
      }
    }
  }

  // ===========================
  // PART 2: TYPES
  // ===========================

  implicit class SemanticTypeOps(val tree: Type) extends AnyVal {
    @hosted def <:<(other: Type): Boolean = implicitly[SemanticContext].isSubType(tree, other)
    @hosted def weak_<:<(other: Type): Boolean = ???
    @hosted def widen: Type = ???
    @hosted def dealias: Type = ???
    @hosted def companion: Type.Ref = ???
    @hosted def parents: Seq[Type] = ???
  }

  @hosted def lub(tpes: Seq[Type]): Type = askHost
  @hosted def glb(tpes: Seq[Type]): Type = askHost

  // ===========================
  // PART 3: MEMBERS
  // ===========================

  implicit class SemanticMemberOps(val tree: Member) extends AnyVal {
    @hosted def ref: Ref = ???
    @hosted def parents: Seq[Member] = askHost
    @hosted def children: Seq[Member] = askHost
    @hosted def companion: Member = ???
    @hosted def mods: Seq[Mod] = ???
    @hosted def annots: Seq[Ctor.Ref] = ???
    @hosted def isVal: Boolean = ???
    @hosted def isVar: Boolean = ???
    @hosted def isDef: Boolean = ???
    @hosted def isMacro: Boolean = ???
    @hosted def isAbstractType: Boolean = ???
    @hosted def isAliasType: Boolean = ???
    @hosted def isClass: Boolean = ???
    @hosted def isTrait: Boolean = ???
    @hosted def isObject: Boolean = ???
    @hosted def isPackage: Boolean = ???
    @hosted def isPackageObject: Boolean = ???
    @hosted def isPrivate: Boolean = ???
    @hosted def isProtected: Boolean = ???
    @hosted def isPublic: Boolean = ???
    @hosted def accessBoundary: Member = ???
    @hosted def isImplicit: Boolean = ???
    @hosted def isFinal: Boolean = ???
    @hosted def isSealed: Boolean = ???
    @hosted def isOverride: Boolean = ???
    @hosted def isCase: Boolean = ???
    @hosted def isAbstract: Boolean = ???
{'fraction_non_alphanumeric': 0.15498830468829453, 'fraction_numerical': 0.0012203803518763348, 'mean_word_length': 3.5401662049861495, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 23, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6437476', 'n_tokens_mistral': 3241, 'n_tokens_neox': 3210, 'n_words': 885}