<commit_before>/*
 * Copyright © 2014 <NAME> (<EMAIL>)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.emmalanguage
package ast

import scala.annotation.tailrec
import scala.reflect.api.Universe
import scala.reflect.macros.Attachments

/**
 * Implements various utility functions that mitigate and/or workaround deficiencies in Scala's
 * macros and runtime reflection APIs, e.g. non-idempotent type checking, lack of hygiene,
 * capture-avoiding substitution, fully-qualified names, fresh name generation, identifying
 * closures, etc.
 *
 * This trait has to be instantiated with a [[scala.reflect.api.Universe]] type and works for both
 * runtime and compile time reflection.
 */
trait CommonAST {

  val universe: Universe
  lazy val u: universe.type = universe

  type =?>[-A, +B] = PartialFunction[A, B]

  import universe._
  import internal._
  import decorators._
  import reificationSupport._
  import u.Flag._

  /** Raises an error and terminates compilation. */
  def abort(msg: String, pos: Position = NoPosition): Nothing

  /** Raises a compiler warning. */
  def warning(msg: String, pos: Position = NoPosition): Unit

  /** Constant limits. */
  object Max {

    /** Maximum number of lambda arguments. */
    val FunParams = definitions.FunctionClass.seq.size

    /** Maximum number of tuple elements. */
    val TupleElems = definitions.TupleClass.seq.size
  }

  // ---------------------------
  // Parsing and type-checking
  // ---------------------------

  /** Parses a snippet of source code and returns the AST. */
  private[emmalanguage] def parse(code: String): Tree

  /** Type-checks a `tree` (use `typeMode=true` for type-trees). */
  private[emmalanguage] def typeCheck(tree: Tree, typeMode: Boolean = false): Tree

  /** Removes all type and symbol attributes from a `tree`. */
  // FIXME: Replace with `c.untypecheck` or `tb.untypecheck` once SI-5464 is resolved.
  private[emmalanguage] def unTypeCheck(tree: Tree): Tree =
    parse(showCode(tree, printRootPkg = true))

  /** Infers an implicit value from the enclosing context (if possible). */
  private[emmalanguage] def inferImplicit(tpe: Type): Tree

  // ------------------------------
  // Abstract getters and setters
  // ------------------------------

  /** Getter for the attributes of various compilation entities. */
  val get: Getter

  /**
   * Setter for the attributes of various compilation entities.
   * WARN: Mutates in place.
   */
  private[ast] val set: Setter

  /** Getter for the attributes of various compilation entities. */
  trait Getter {

    // Symbols
    def enclosingOwner: Symbol
    def ans(sym: Symbol): Seq[Annotation] = sym.annotations
    def flags(sym: Symbol): FlagSet = sym.flags
    def meta(sym: Symbol): Attachments
    def name(sym: Symbol): Name = sym.name
    def owner(sym: Symbol): Symbol = sym.owner
    def pos(sym: Symbol): Position = sym.pos<commit_msg>[IR] Added `Getter.ann` to the compiler API.<commit_after>/*
 * Copyright © 2014 <NAME> (<EMAIL>)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.emmalanguage
package ast

import scala.annotation.tailrec
import scala.reflect.api.Universe
import scala.reflect.macros.Attachments

/**
 * Implements various utility functions that mitigate and/or workaround deficiencies in Scala's
 * macros and runtime reflection APIs, e.g. non-idempotent type checking, lack of hygiene,
 * capture-avoiding substitution, fully-qualified names, fresh name generation, identifying
 * closures, etc.
 *
 * This trait has to be instantiated with a [[scala.reflect.api.Universe]] type and works for both
 * runtime and compile time reflection.
 */
trait CommonAST {

  val universe: Universe
  lazy val u: universe.type = universe

  type =?>[-A, +B] = PartialFunction[A, B]

  import universe._
  import internal._
  import decorators._
  import reificationSupport._
  import u.Flag._

  /** Raises an error and terminates compilation. */
  def abort(msg: String, pos: Position = NoPosition): Nothing

  /** Raises a compiler warning. */
  def warning(msg: String, pos: Position = NoPosition): Unit

  /** Constant limits. */
  object Max {

    /** Maximum number of lambda arguments. */
    val FunParams = definitions.FunctionClass.seq.size

    /** Maximum number of tuple elements. */
    val TupleElems = definitions.TupleClass.seq.size
  }

  // ---------------------------
  // Parsing and type-checking
  // ---------------------------

  /** Parses a snippet of source code and returns the AST. */
  private[emmalanguage] def parse(code: String): Tree

  /** Type-checks a `tree` (use `typeMode=true` for type-trees). */
  private[emmalanguage] def typeCheck(tree: Tree, typeMode: Boolean = false): Tree

  /** Removes all type and symbol attributes from a `tree`. */
  // FIXME: Replace with `c.untypecheck` or `tb.untypecheck` once SI-5464 is resolved.
  private[emmalanguage] def unTypeCheck(tree: Tree): Tree =
    parse(showCode(tree, printRootPkg = true))

  /** Infers an implicit value from the enclosing context (if possible). */
  private[emmalanguage] def inferImplicit(tpe: Type): Tree

  // ------------------------------
  // Abstract getters and setters
  // ------------------------------

  /** Getter for the attributes of various compilation entities. */
  val get: Getter

  /**
   * Setter for the attributes of various compilation entities.
   * WARN: Mutates in place.
   */
  private[ast] val set: Setter

  /** Getter for the attributes of various compilation entities. */
  trait Getter {

    // Symbols
    def enclosingOwner: Symbol
    def ans(sym: Symbol): Seq[Annotation] = sym.annotations
    def ann[A: TypeTag](sym: Symbol): Option[Annotation] = ans(sym).find(_.tree.tpe =:= typeOf[A])
    def flags(sym: Symbol): FlagSet = sym.flags
    def meta(sym: Symbol): Attachments
    def name(sym: Symbol): Name = sym.name
    def owner(sym: Symbol): Symbol = sym.owner
    def pos(sym: Symbol): Position = sym.pos
{'fraction_non_alphanumeric': 0.13201603665521192, 'fraction_numerical': 0.003436426116838488, 'mean_word_length': 3.0492753623188404, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '4153640', 'n_tokens_mistral': 1982, 'n_tokens_neox': 1877, 'n_words': 740}