<commit_before>package coconut.ui;

import haxe.macro.Context.*;
import haxe.macro.Type;
using haxe.macro.Tools;
using tink.MacroApi;

abstract Ref<T>({}) {
  static function unwrap(t:TypedExpr)
    return switch t.expr {
      case TMeta(_, t) | TParenthesis(t) | TCast(t, _):
        unwrap(t);
      default: t;
    }

  static function getRef(t:Type)
    return switch t {
      case TAbstract(_.get() => { pack: [], name: 'Null'}, [t]): getRef(t);
      case TAbstract(_.get() => { pack: ['coconut', 'ui'], name: 'Ref'}, [t]): t;
      case TLazy(f): getRef(f());
      case TType(_): getRef(follow(t, true));
      default: throw 'assert';
    }

  static function ofExpr(e) {

    var expected = getRef(getExpectedType());

    var ct = expected.toComplexType(),
        te = unwrap(typeExpr(e));

    var setter =
      switch te.expr {
        case TField(_, FAnon(f) | FInstance(_, _, f) | FStatic(_, f)):
          var f = f.get();
          #if haxe4
          if (f.isFinal)
            fatalError('cannot store Ref in final field $f', e.pos);
          #end
          switch f.meta.extract(':refSetter') {
            case []: null;
            case [{ params: [v] }]: v;
            default: fatalError('invalid @:refSetter meta', f.pos);
          }
        default: null;
      }

    var ret =
      switch follow(te.t) {
        case TFun([{ t: t }], r):
          if (unify(expected, t))
            e;
          else
            fatalError('${te.t.toString()} should be Ref<${expected.toString()}>', e.pos);
        case t:
          e = storeTypedExpr(te);
          if (unify(expected, t))
            if (setter == null)
              macro @:pos(e.pos) function (__v:$ct) $e = __v;<commit_msg>Fix refs for parametrized views.<commit_after>package coconut.ui;

import haxe.macro.Context.*;
import haxe.macro.Type;
using haxe.macro.Tools;
using tink.MacroApi;

abstract Ref<T>({}) {
  static function unwrap(t:TypedExpr)
    return switch t.expr {
      case TMeta(_, t) | TParenthesis(t) | TCast(t, _):
        unwrap(t);
      default: t;
    }

  static function getRef(t:Type)
    return switch t {
      case TAbstract(_.get() => { pack: [], name: 'Null'}, [t]): getRef(t);
      case TAbstract(_.get() => { pack: ['coconut', 'ui'], name: 'Ref'}, [t]): t;
      case TLazy(f): getRef(f());
      case TType(_): getRef(follow(t, true));
      default: throw 'assert';
    }

  static function ofExpr(e) {

    var expected = getRef(getExpectedType());

    var ct = expected.toComplex(),
        te = unwrap(typeExpr(e));

    var setter =
      switch te.expr {
        case TField(_, FAnon(f) | FInstance(_, _, f) | FStatic(_, f)):
          var f = f.get();
          #if haxe4
          if (f.isFinal)
            fatalError('cannot store Ref in final field $f', e.pos);
          #end
          switch f.meta.extract(':refSetter') {
            case []: null;
            case [{ params: [v] }]: v;
            default: fatalError('invalid @:refSetter meta', f.pos);
          }
        default: null;
      }

    var ret =
      switch follow(te.t) {
        case TFun([{ t: t }], r):
          if (unify(expected, t))
            e;
          else
            fatalError('${te.t.toString()} should be Ref<${expected.toString()}>', e.pos);
        case t:
          e = storeTypedExpr(te);
          if (unify(expected, t))
            if (setter == null)
              macro @:pos(e.pos) function (__v:$ct) $e = __v;
{'fraction_non_alphanumeric': 0.16314111851637206, 'fraction_numerical': 0.0005795421616922632, 'mean_word_length': 2.0766488413547237, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, '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': '746335', 'n_tokens_mistral': 1180, 'n_tokens_neox': 1138, 'n_words': 295}