// Generated by ReScript, PLEASE EDIT WITH CARE

import * as List from "rescript/lib/es6/list.js";
import * as Curry from "rescript/lib/es6/curry.js";
import * as Hashtbl from "rescript/lib/es6/hashtbl.js";
import * as Res_doc from "./res_doc.js";
import * as Caml_obj from "rescript/lib/es6/caml_obj.js";
import * as $$Location from "./location.js";
import * as Ast_helper from "./ast_helper.js";
import * as Res_comment from "./res_comment.js";
import * as Res_parsetree_viewer from "./res_parsetree_viewer.js";

function make(param) {
  return {
          leading: Hashtbl.create(undefined, 100),
          inside: Hashtbl.create(undefined, 100),
          trailing: Hashtbl.create(undefined, 100)
        };
}

function copy(tbl) {
  return {
          leading: Hashtbl.copy(tbl.leading),
          inside: Hashtbl.copy(tbl.inside),
          trailing: Hashtbl.copy(tbl.trailing)
        };
}

var empty = make(undefined);

function log(t) {
  var leadingStuff = Hashtbl.fold((function (k, v, acc) {
          var loc = Res_doc.concat({
                hd: Res_doc.lbracket,
                tl: {
                  hd: Res_doc.text(String(k.loc_start.pos_lnum)),
                  tl: {
                    hd: Res_doc.text(":"),
                    tl: {
                      hd: Res_doc.text(String(k.loc_start.pos_cnum - k.loc_start.pos_bol | 0)),
                      tl: {
                        hd: Res_doc.text("-"),
                        tl: {
                          hd: Res_doc.text(String(k.loc_end.pos_lnum)),
                          tl: {
                            hd: Res_doc.text(":"),
                            tl: {
                              hd: Res_doc.text(String(k.loc_end.pos_cnum - k.loc_end.pos_bol | 0)),
                              tl: {
                                hd: Res_doc.rbracket,
                                tl: /* [] */0
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              });
          var doc = Res_doc.breakableGroup(true, Res_doc.concat({
                    hd: loc,
                    tl: {
                      hd: Res_doc.indent(Res_doc.concat({
                                hd: Res_doc.line,
                                tl: {
                                  hd: Res_doc.join(Res_doc.comma, List.map((function (c) {
                                              return Res_doc.text(Res_comment.txt(c));
                                            }), v)),
                                  tl: /* [] */0
                                }
                              })),
                      tl: {
                        hd: Res_doc.line,
                        tl: /* [] */0
                      }
                    }
                  }));
          return {
                  hd: doc,
                  tl: acc
                };
        }), t.leading, /* [] */0);
  var trailingStuff = Hashtbl.fold((function (k, v, acc) {
          var loc = Res_doc.concat({
                hd: Res_doc.lbracket,
                tl: {
                  hd: Res_doc.text(String(k.loc_start.pos_lnum)),
                  tl: {
                    hd: Res_doc.text(":"),
                    tl: {
                      hd: Res_doc.text(String(k.loc_start.pos_cnum - k.loc_start.pos_bol | 0)),
                      tl: {
                        hd: Res_doc.text("-"),
                        tl: {
                          hd: Res_doc.text(String(k.loc_end.pos_lnum)),
                          tl: {
                            hd: Res_doc.text(":"),
                            tl: {
                              hd: Res_doc.text(String(k.loc_end.pos_cnum - k.loc_end.pos_bol | 0)),
                              tl: {
                                hd: Res_doc.rbracket,
                                tl: /* [] */0
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              });
          var doc = Res_doc.breakableGroup(true, Res_doc.concat({
                    hd: loc,
                    tl: {
                      hd: Res_doc.indent(Res_doc.concat({
                                hd: Res_doc.line,
                                tl: {
                                  hd: Res_doc.join(Res_doc.concat({
                                            hd: Res_doc.comma,
                                            tl: {
                                              hd: Res_doc.line,
                                              tl: /* [] */0
                                            }
                                          }), List.map((function (c) {
                                              return Res_doc.text(Res_comment.txt(c));
                                            }), v)),
                                  tl: /* [] */0
                                }
                              })),
                      tl: {
                        hd: Res_doc.line,
                        tl: /* [] */0
                      }
                    }
                  }));
          return {
                  hd: doc,
                  tl: acc
                };
        }), t.trailing, /* [] */0);
  console.log(Res_doc.toString(80, Res_doc.breakableGroup(true, Res_doc.concat({
                    hd: Res_doc.text("leading comments:"),
                    tl: {
                      hd: Res_doc.line,
                      tl: {
                        hd: Res_doc.indent(Res_doc.concat(leadingStuff)),
                        tl: {
                          hd: Res_doc.line,
                          tl: {
                            hd: Res_doc.line,
                            tl: {
                              hd: Res_doc.text("trailing comments:"),
                              tl: {
                                hd: Res_doc.indent(Res_doc.concat(trailingStuff)),
                                tl: {
                                  hd: Res_doc.line,
                                  tl: {
                                    hd: Res_doc.line,
                                    tl: /* [] */0
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }))));
  
}

function attach(tbl, loc, comments) {
  if (comments) {
    return Hashtbl.replace(tbl, loc, comments);
  }
  
}

function partitionByLoc(comments, loc) {
  var _param = [
    /* [] */0,
    /* [] */0,
    /* [] */0
  ];
  var _comments = comments;
  while(true) {
    var param = _param;
    var comments$1 = _comments;
    var trailing = param[2];
    var inside = param[1];
    var leading = param[0];
    if (!comments$1) {
      return [
              List.rev(leading),
              List.rev(inside),
              List.rev(trailing)
            ];
    }
    var rest = comments$1.tl;
    var comment = comments$1.hd;
    var cmtLoc = Res_comment.loc(comment);
    if (cmtLoc.loc_end.pos_cnum <= loc.loc_start.pos_cnum) {
      _comments = rest;
      _param = [
        {
          hd: comment,
          tl: leading
        },
        inside,
        trailing
      ];
      continue ;
    }
    if (cmtLoc.loc_start.pos_cnum >= loc.loc_end.pos_cnum) {
      _comments = rest;
      _param = [
        leading,
        inside,
        {
          hd: comment,
          tl: trailing
        }
      ];
      continue ;
    }
    _comments = rest;
    _param = [
      leading,
      {
        hd: comment,
        tl: inside
      },
      trailing
    ];
    continue ;
  };
}

function partitionLeadingTrailing(comments, loc) {
  var _param = [
    /* [] */0,
    /* [] */0
  ];
  var _comments = comments;
  while(true) {
    var param = _param;
    var comments$1 = _comments;
    var trailing = param[1];
    var leading = param[0];
    if (!comments$1) {
      return [
              List.rev(leading),
              List.rev(trailing)
            ];
    }
    var rest = comments$1.tl;
    var comment = comments$1.hd;
    var cmtLoc = Res_comment.loc(comment);
    if (cmtLoc.loc_end.pos_cnum <= loc.loc_start.pos_cnum) {
      _comments = rest;
      _param = [
        {
          hd: comment,
          tl: leading
        },
        trailing
      ];
      continue ;
    }
    _comments = rest;
    _param = [
      leading,
      {
        hd: comment,
        tl: trailing
      }
    ];
    continue ;
  };
}

function partitionByOnSameLine(loc, comments) {
  var _param = [
    /* [] */0,
    /* [] */0
  ];
  var _comments = comments;
  while(true) {
    var param = _param;
    var comments$1 = _comments;
    var onOtherLine = param[1];
    var onSameLine = param[0];
    if (!comments$1) {
      return [
              List.rev(onSameLine),
              List.rev(onOtherLine)
            ];
    }
    var rest = comments$1.tl;
    var comment = comments$1.hd;
    var cmtLoc = Res_comment.loc(comment);
    if (cmtLoc.loc_start.pos_lnum === loc.loc_end.pos_lnum) {
      _comments = rest;
      _param = [
        {
          hd: comment,
          tl: onSameLine
        },
        onOtherLine
      ];
      continue ;
    }
    _comments = rest;
    _param = [
      onSameLine,
      {
        hd: comment,
        tl: onOtherLine
      }
    ];
    continue ;
  };
}

function partitionAdjacentTrailing(loc1, comments) {
  var _prevEndPos = loc1.loc_end;
  var _afterLoc1 = /* [] */0;
  var _comments = comments;
  while(true) {
    var comments$1 = _comments;
    var afterLoc1 = _afterLoc1;
    var prevEndPos = _prevEndPos;
    if (!comments$1) {
      return [
              List.rev(afterLoc1),
              /* [] */0
            ];
    }
    var comment = comments$1.hd;
    var cmtPrevEndPos = Res_comment.prevTokEndPos(comment);
    if (prevEndPos.pos_cnum !== cmtPrevEndPos.pos_cnum) {
      return [
              List.rev(afterLoc1),
              comments$1
            ];
    }
    var commentEnd = Res_comment.loc(comment).loc_end;
    _comments = comments$1.tl;
    _afterLoc1 = {
      hd: comment,
      tl: afterLoc1
    };
    _prevEndPos = commentEnd;
    continue ;
  };
}

function collectListPatterns(_acc, _pattern) {
  while(true) {
    var pattern = _pattern;
    var acc = _acc;
    var match = pattern.ppat_desc;
    if (typeof match === "number") {
      return List.rev({
                  hd: pattern,
                  tl: acc
                });
    }
    if (match.TAG !== /* Ppat_construct */5) {
      return List.rev({
                  hd: pattern,
                  tl: acc
                });
    }
    var match$1 = match._0.txt;
    switch (match$1.TAG | 0) {
      case /* Lident */0 :
          switch (match$1._0) {
            case "::" :
                var match$2 = match._1;
                if (match$2 === undefined) {
                  return List.rev({
                              hd: pattern,
                              tl: acc
                            });
                }
                var match$3 = match$2.ppat_desc;
                if (typeof match$3 === "number") {
                  return List.rev({
                              hd: pattern,
                              tl: acc
                            });
                }
                if (match$3.TAG !== /* Ppat_tuple */4) {
                  return List.rev({
                              hd: pattern,
                              tl: acc
                            });
                }
                var match$4 = match$3._0;
                if (!match$4) {
                  return List.rev({
                              hd: pattern,
                              tl: acc
                            });
                }
                var match$5 = match$4.tl;
                if (!match$5) {
                  return List.rev({
                              hd: pattern,
                              tl: acc
                            });
                }
                if (match$5.tl) {
                  return List.rev({
                              hd: pattern,
                              tl: acc
                            });
                }
                _pattern = match$5.hd;
                _acc = {
                  hd: match$4.hd,
                  tl: acc
                };
                continue ;
            case "[]" :
                if (match._1 !== undefined) {
                  return List.rev({
                              hd: pattern,
                              tl: acc
                            });
                } else {
                  return List.rev(acc);
                }
            default:
              return List.rev({
                          hd: pattern,
                          tl: acc
                        });
          }
      case /* Ldot */1 :
      case /* Lapply */2 :
          return List.rev({
                      hd: pattern,
                      tl: acc
                    });
      
    }
  };
}

function collectListExprs(_acc, _expr) {
  while(true) {
    var expr = _expr;
    var acc = _acc;
    var match = expr.pexp_desc;
    if (typeof match === "number") {
      return List.rev({
                  hd: expr,
                  tl: acc
                });
    }
    if (match.TAG !== /* Pexp_construct */9) {
      return List.rev({
                  hd: expr,
                  tl: acc
                });
    }
    var match$1 = match._0.txt;
    switch (match$1.TAG | 0) {
      case /* Lident */0 :
          switch (match$1._0) {
            case "::" :
                var match$2 = match._1;
                if (match$2 === undefined) {
                  return List.rev({
                              hd: expr,
                              tl: acc
                            });
                }
                var match$3 = match$2.pexp_desc;
                if (typeof match$3 === "number") {
                  return List.rev({
                              hd: expr,
                              tl: acc
                            });
                }
                if (match$3.TAG !== /* Pexp_tuple */8) {
                  return List.rev({
                              hd: expr,
                              tl: acc
                            });
                }
                var match$4 = match$3._0;
                if (!match$4) {
                  return List.rev({
                              hd: expr,
                              tl: acc
                            });
                }
                var match$5 = match$4.tl;
                if (!match$5) {
                  return List.rev({
                              hd: expr,
                              tl: acc
                            });
                }
                if (match$5.tl) {
                  return List.rev({
                              hd: expr,
                              tl: acc
                            });
                }
                _expr = match$5.hd;
                _acc = {
                  hd: match$4.hd,
                  tl: acc
                };
                continue ;
            case "[]" :
                return List.rev(acc);
            default:
              return List.rev({
                          hd: expr,
                          tl: acc
                        });
          }
      case /* Ldot */1 :
      case /* Lapply */2 :
          return List.rev({
                      hd: expr,
                      tl: acc
                    });
      
    }
  };
}

function arrowType(ct) {
  var $$process = function (attrsBefore, _acc, _typ) {
    while(true) {
      var typ = _typ;
      var acc = _acc;
      var match = typ.ptyp_desc;
      if (typeof match === "number") {
        return [
                attrsBefore,
                List.rev(acc),
                typ
              ];
      }
      if (match.TAG !== /* Ptyp_arrow */1) {
        return [
                attrsBefore,
                List.rev(acc),
                typ
              ];
      }
      var lbl = match._0;
      if (typeof lbl === "number") {
        var attrs = typ.ptyp_attributes;
        var typ2 = match._2;
        var typ1 = match._1;
        if (attrs) {
          if (attrs.hd[0].txt === "bs" && !attrs.tl) {
            var arg = [
              attrs,
              lbl,
              typ1
            ];
            _typ = typ2;
            _acc = {
              hd: arg,
              tl: acc
            };
            continue ;
          }
          
        } else {
          var arg$1 = [
            /* [] */0,
            lbl,
            typ1
          ];
          _typ = typ2;
          _acc = {
            hd: arg$1,
            tl: acc
          };
          continue ;
        }
        var args = List.rev(acc);
        return [
                attrsBefore,
                args,
                typ
              ];
      }
      var arg_0 = typ.ptyp_attributes;
      var arg_2 = match._1;
      var arg$2 = [
        arg_0,
        lbl,
        arg_2
      ];
      _typ = match._2;
      _acc = {
        hd: arg$2,
        tl: acc
      };
      continue ;
    };
  };
  var match = ct.ptyp_desc;
  if (typeof match === "number" || !(match.TAG === /* Ptyp_arrow */1 && typeof match._0 === "number")) {
    return $$process(/* [] */0, /* [] */0, ct);
  } else {
    return $$process(ct.ptyp_attributes, /* [] */0, {
                ptyp_desc: ct.ptyp_desc,
                ptyp_loc: ct.ptyp_loc,
                ptyp_attributes: /* [] */0
              });
  }
}

function modExprApply(modExpr) {
  var _acc = /* [] */0;
  var _modExpr = modExpr;
  while(true) {
    var modExpr$1 = _modExpr;
    var acc = _acc;
    var match = modExpr$1.pmod_desc;
    if (match.TAG !== /* Pmod_apply */3) {
      return {
              hd: modExpr$1,
              tl: acc
            };
    }
    _modExpr = match._0;
    _acc = {
      hd: match._1,
      tl: acc
    };
    continue ;
  };
}

function modExprFunctor(modExpr) {
  var _acc = /* [] */0;
  var _modExpr = modExpr;
  while(true) {
    var modExpr$1 = _modExpr;
    var acc = _acc;
    var match = modExpr$1.pmod_desc;
    if (match.TAG !== /* Pmod_functor */2) {
      return [
              List.rev(acc),
              modExpr$1
            ];
    }
    var param_0 = modExpr$1.pmod_attributes;
    var param_1 = match._0;
    var param_2 = match._1;
    var param = [
      param_0,
      param_1,
      param_2
    ];
    _modExpr = match._2;
    _acc = {
      hd: param,
      tl: acc
    };
    continue ;
  };
}

function functorType(modtype) {
  var _acc = /* [] */0;
  var _modtype = modtype;
  while(true) {
    var modtype$1 = _modtype;
    var acc = _acc;
    var match = modtype$1.pmty_desc;
    if (match.TAG !== /* Pmty_functor */2) {
      return [
              List.rev(acc),
              modtype$1
            ];
    }
    var arg_0 = modtype$1.pmty_attributes;
    var arg_1 = match._0;
    var arg_2 = match._1;
    var arg = [
      arg_0,
      arg_1,
      arg_2
    ];
    _modtype = match._2;
    _acc = {
      hd: arg,
      tl: acc
    };
    continue ;
  };
}

function funExpr(expr) {
  var collectNewTypes = function (_acc, _returnExpr) {
    while(true) {
      var returnExpr = _returnExpr;
      var acc = _acc;
      var match = returnExpr.pexp_desc;
      if (typeof match !== "number" && match.TAG === /* Pexp_newtype */31 && !returnExpr.pexp_attributes) {
        _returnExpr = match._1;
        _acc = {
          hd: match._0,
          tl: acc
        };
        continue ;
      }
      var match$1 = List.rev(acc);
      var loc;
      if (acc && match$1) {
        var endLoc = match$1.hd;
        var init = endLoc.loc;
        loc = {
          loc_start: init.loc_start,
          loc_end: endLoc.loc.loc_end,
          loc_ghost: init.loc_ghost
        };
      } else {
        loc = $$Location.none;
      }
      var txt = List.fold_right((function (curr, acc) {
              return acc + (" " + curr.txt);
            }), acc, "type");
      return [
              $$Location.mkloc(txt, loc),
              returnExpr
            ];
    };
  };
  var collect = function (attrsBefore, _acc, _expr) {
    while(true) {
      var expr = _expr;
      var acc = _acc;
      var match = expr.pexp_desc;
      if (typeof match !== "number") {
        switch (match.TAG | 0) {
          case /* Pexp_fun */4 :
              var lbl = match._0;
              var exit = 0;
              var attrs = expr.pexp_attributes;
              var returnExpr = match._3;
              var pattern = match._2;
              var defaultExpr = match._1;
              if (attrs) {
                if (attrs.hd[0].txt === "bs" && !attrs.tl) {
                  var parameter = [
                    attrs,
                    lbl,
                    defaultExpr,
                    pattern
                  ];
                  _expr = returnExpr;
                  _acc = {
                    hd: parameter,
                    tl: acc
                  };
                  continue ;
                }
                exit = 2;
              } else {
                var parameter$1 = [
                  /* [] */0,
                  lbl,
                  defaultExpr,
                  pattern
                ];
                _expr = returnExpr;
                _acc = {
                  hd: parameter$1,
                  tl: acc
                };
                continue ;
              }
              if (exit === 2 && typeof lbl !== "number") {
                var parameter_0 = expr.pexp_attributes;
                var parameter_2 = match._1;
                var parameter_3 = match._2;
                var parameter$2 = [
                  parameter_0,
                  lbl,
                  parameter_2,
                  parameter_3
                ];
                _expr = match._3;
                _acc = {
                  hd: parameter$2,
                  tl: acc
                };
                continue ;
              }
              break;
          case /* Pexp_newtype */31 :
              var stringLoc = match._0;
              var match$1 = collectNewTypes({
                    hd: stringLoc,
                    tl: /* [] */0
                  }, match._1);
              var parameter_0$1 = expr.pexp_attributes;
              var parameter_3$1 = Ast_helper.Pat.$$var(stringLoc.loc, undefined, match$1[0]);
              var parameter$3 = [
                parameter_0$1,
                /* Nolabel */0,
                undefined,
                parameter_3$1
              ];
              _expr = match$1[1];
              _acc = {
                hd: parameter$3,
                tl: acc
              };
              continue ;
          default:
            
        }
      }
      return [
              attrsBefore,
              List.rev(acc),
              expr
            ];
    };
  };
  var match = expr.pexp_desc;
  if (typeof match === "number" || !(match.TAG === /* Pexp_fun */4 && typeof match._0 === "number")) {
    return collect(/* [] */0, /* [] */0, expr);
  } else {
    return collect(expr.pexp_attributes, /* [] */0, {
                pexp_desc: expr.pexp_desc,
                pexp_loc: expr.pexp_loc,
                pexp_attributes: /* [] */0
              });
  }
}

function isBlockExpr(expr) {
  var match = expr.pexp_desc;
  if (typeof match === "number") {
    return false;
  }
  switch (match.TAG | 0) {
    case /* Pexp_apply */5 :
    case /* Pexp_field */12 :
    case /* Pexp_setfield */13 :
    case /* Pexp_constraint */19 :
        break;
    case /* Pexp_let */2 :
    case /* Pexp_sequence */16 :
    case /* Pexp_letmodule */25 :
    case /* Pexp_letexception */26 :
    case /* Pexp_open */33 :
        return true;
    default:
      return false;
  }
  if (isBlockExpr(match._0)) {
    return true;
  } else {
    return false;
  }
}

function isIfThenElseExpr(expr) {
  var match = expr.pexp_desc;
  if (typeof match === "number" || match.TAG !== /* Pexp_ifthenelse */15) {
    return false;
  } else {
    return true;
  }
}

function walkStructure(s, t, comments) {
  if (comments === /* [] */0) {
    return ;
  } else if (s) {
    return walkList(undefined, (function (n) {
                  return n.pstr_loc;
                }), walkStructureItem, s, t, comments);
  } else {
    return attach(t.inside, $$Location.none, comments);
  }
}

function walkStructureItem(si, t, comments) {
  var valueDescription = si.pstr_desc;
  if (comments === /* [] */0) {
    return ;
  }
  switch (valueDescription.TAG | 0) {
    case /* Pstr_eval */0 :
        return walkExpr(valueDescription._0, t, comments);
    case /* Pstr_value */1 :
        return walkValueBindings(valueDescription._1, t, comments);
    case /* Pstr_primitive */2 :
        return walkValueDescription(valueDescription._0, t, comments);
    case /* Pstr_type */3 :
        return walkTypeDeclarations(valueDescription._1, t, comments);
    case /* Pstr_typext */4 :
        return walkTypeExtension(valueDescription._0, t, comments);
    case /* Pstr_exception */5 :
        return walkExtConstr(valueDescription._0, t, comments);
    case /* Pstr_module */6 :
        return walkModuleBinding(valueDescription._0, t, comments);
    case /* Pstr_recmodule */7 :
        return walkList(undefined, (function (mb) {
                      return mb.pmb_loc;
                    }), walkModuleBinding, valueDescription._0, t, comments);
    case /* Pstr_modtype */8 :
        return walkModuleTypeDeclaration(valueDescription._0, t, comments);
    case /* Pstr_open */9 :
        return walkOpenDescription(valueDescription._0, t, comments);
    case /* Pstr_class */10 :
    case /* Pstr_class_type */11 :
        return ;
    case /* Pstr_include */12 :
        return walkIncludeDeclaration(valueDescription._0, t, comments);
    case /* Pstr_attribute */13 :
        return walkAttribute(valueDescription._0, t, comments);
    case /* Pstr_extension */14 :
        return walkExtension(valueDescription._0, t, comments);
    
  }
}

function walkValueDescription(vd, t, comments) {
  var match = partitionLeadingTrailing(comments, vd.pval_name.loc);
  attach(t.leading, vd.pval_name.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(vd.pval_name.loc, match[1]);
  attach(t.trailing, vd.pval_name.loc, match$1[0]);
  var match$2 = partitionByLoc(match$1[1], vd.pval_type.ptyp_loc);
  attach(t.leading, vd.pval_type.ptyp_loc, match$2[0]);
  walkTypExpr(vd.pval_type, t, match$2[1]);
  return attach(t.trailing, vd.pval_type.ptyp_loc, match$2[2]);
}

function walkTypeExtension(te, t, comments) {
  var match = partitionLeadingTrailing(comments, te.ptyext_path.loc);
  attach(t.leading, te.ptyext_path.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(te.ptyext_path.loc, match[1]);
  var rest = match$1[1];
  attach(t.trailing, te.ptyext_path.loc, match$1[0]);
  var typeParams = te.ptyext_params;
  var rest$1 = typeParams ? visitListButContinueWithRemainingComments(undefined, false, (function (param) {
            return param[0].ptyp_loc;
          }), walkTypeParam, typeParams, t, rest) : rest;
  return walkList(undefined, (function (n) {
                return n.pext_loc;
              }), walkExtConstr, te.ptyext_constructors, t, rest$1);
}

function walkIncludeDeclaration(inclDecl, t, comments) {
  var match = partitionByLoc(comments, inclDecl.pincl_mod.pmod_loc);
  attach(t.leading, inclDecl.pincl_mod.pmod_loc, match[0]);
  walkModExpr(inclDecl.pincl_mod, t, match[1]);
  return attach(t.trailing, inclDecl.pincl_mod.pmod_loc, match[2]);
}

function walkModuleTypeDeclaration(mtd, t, comments) {
  var match = partitionLeadingTrailing(comments, mtd.pmtd_name.loc);
  var trailing = match[1];
  attach(t.leading, mtd.pmtd_name.loc, match[0]);
  var modType = mtd.pmtd_type;
  if (modType === undefined) {
    return attach(t.trailing, mtd.pmtd_name.loc, trailing);
  }
  var match$1 = partitionAdjacentTrailing(mtd.pmtd_name.loc, trailing);
  attach(t.trailing, mtd.pmtd_name.loc, match$1[0]);
  var match$2 = partitionByLoc(match$1[1], modType.pmty_loc);
  attach(t.leading, modType.pmty_loc, match$2[0]);
  walkModType(modType, t, match$2[1]);
  return attach(t.trailing, modType.pmty_loc, match$2[2]);
}

function walkModuleBinding(mb, t, comments) {
  var match = partitionLeadingTrailing(comments, mb.pmb_name.loc);
  attach(t.leading, mb.pmb_name.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(mb.pmb_name.loc, match[1]);
  attach(t.trailing, mb.pmb_name.loc, match$1[0]);
  var match$2 = partitionByLoc(match$1[1], mb.pmb_expr.pmod_loc);
  var inside = match$2[1];
  var leading = match$2[0];
  var match$3 = mb.pmb_expr.pmod_desc;
  if (match$3.TAG === /* Pmod_constraint */4) {
    walkModExpr(mb.pmb_expr, t, List.concat({
              hd: leading,
              tl: {
                hd: inside,
                tl: /* [] */0
              }
            }));
  } else {
    attach(t.leading, mb.pmb_expr.pmod_loc, leading);
    walkModExpr(mb.pmb_expr, t, inside);
  }
  return attach(t.trailing, mb.pmb_expr.pmod_loc, match$2[2]);
}

function walkSignature(signature, t, comments) {
  if (comments === /* [] */0) {
    return ;
  } else if (signature) {
    return walkList(undefined, (function (n) {
                  return n.psig_loc;
                }), walkSignatureItem, signature, t, comments);
  } else {
    return attach(t.inside, $$Location.none, comments);
  }
}

function walkSignatureItem(si, t, comments) {
  var valueDescription = si.psig_desc;
  if (comments === /* [] */0) {
    return ;
  }
  switch (valueDescription.TAG | 0) {
    case /* Psig_value */0 :
        return walkValueDescription(valueDescription._0, t, comments);
    case /* Psig_type */1 :
        return walkTypeDeclarations(valueDescription._1, t, comments);
    case /* Psig_typext */2 :
        return walkTypeExtension(valueDescription._0, t, comments);
    case /* Psig_exception */3 :
        return walkExtConstr(valueDescription._0, t, comments);
    case /* Psig_module */4 :
        return walkModuleDeclaration(valueDescription._0, t, comments);
    case /* Psig_recmodule */5 :
        return walkList(undefined, (function (n) {
                      return n.pmd_loc;
                    }), walkModuleDeclaration, valueDescription._0, t, comments);
    case /* Psig_modtype */6 :
        return walkModuleTypeDeclaration(valueDescription._0, t, comments);
    case /* Psig_open */7 :
        return walkOpenDescription(valueDescription._0, t, comments);
    case /* Psig_include */8 :
        return walkIncludeDescription(valueDescription._0, t, comments);
    case /* Psig_class */9 :
    case /* Psig_class_type */10 :
        return ;
    case /* Psig_attribute */11 :
        return walkAttribute(valueDescription._0, t, comments);
    case /* Psig_extension */12 :
        return walkExtension(valueDescription._0, t, comments);
    
  }
}

function walkIncludeDescription(id, t, comments) {
  var match = partitionByLoc(comments, id.pincl_mod.pmty_loc);
  attach(t.leading, id.pincl_mod.pmty_loc, match[0]);
  walkModType(id.pincl_mod, t, match[1]);
  return attach(t.trailing, id.pincl_mod.pmty_loc, match[2]);
}

function walkModuleDeclaration(md, t, comments) {
  var match = partitionLeadingTrailing(comments, md.pmd_name.loc);
  attach(t.leading, md.pmd_name.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(md.pmd_name.loc, match[1]);
  attach(t.trailing, md.pmd_name.loc, match$1[0]);
  var match$2 = partitionByLoc(match$1[1], md.pmd_type.pmty_loc);
  attach(t.leading, md.pmd_type.pmty_loc, match$2[0]);
  walkModType(md.pmd_type, t, match$2[1]);
  return attach(t.trailing, md.pmd_type.pmty_loc, match$2[2]);
}

function walkList(_prevLoc, getLoc, walkNode, _l, t, _comments) {
  while(true) {
    var comments = _comments;
    var l = _l;
    var prevLoc = _prevLoc;
    if (comments === /* [] */0) {
      return ;
    }
    if (!l) {
      if (prevLoc !== undefined) {
        return attach(t.trailing, prevLoc, comments);
      } else {
        return ;
      }
    }
    var node = l.hd;
    var currLoc = Curry._1(getLoc, node);
    var match = partitionByLoc(comments, currLoc);
    var leading = match[0];
    if (prevLoc !== undefined) {
      if (prevLoc.loc_end.pos_lnum === currLoc.loc_start.pos_lnum) {
        var match$1 = partitionAdjacentTrailing(prevLoc, leading);
        attach(t.trailing, prevLoc, match$1[0]);
        attach(t.leading, currLoc, match$1[1]);
      } else {
        var match$2 = partitionByOnSameLine(prevLoc, leading);
        attach(t.trailing, prevLoc, match$2[0]);
        var match$3 = partitionByLoc(match$2[1], currLoc);
        attach(t.leading, currLoc, match$3[0]);
      }
    } else {
      attach(t.leading, currLoc, leading);
    }
    Curry._3(walkNode, node, t, match[1]);
    _comments = match[2];
    _l = l.tl;
    _prevLoc = currLoc;
    continue ;
  };
}

function visitListButContinueWithRemainingComments(_prevLoc, newlineDelimited, getLoc, walkNode, _l, t, _comments) {
  while(true) {
    var comments = _comments;
    var l = _l;
    var prevLoc = _prevLoc;
    if (comments === /* [] */0) {
      return /* [] */0;
    }
    if (l) {
      var node = l.hd;
      var currLoc = Curry._1(getLoc, node);
      var match = partitionByLoc(comments, currLoc);
      var leading = match[0];
      if (prevLoc !== undefined) {
        if (prevLoc.loc_end.pos_lnum === currLoc.loc_start.pos_lnum) {
          var match$1 = partitionAdjacentTrailing(prevLoc, leading);
          attach(t.trailing, prevLoc, match$1[0]);
          attach(t.leading, currLoc, match$1[1]);
        } else {
          var match$2 = partitionByOnSameLine(prevLoc, leading);
          attach(t.trailing, prevLoc, match$2[0]);
          var match$3 = partitionByLoc(match$2[1], currLoc);
          attach(t.leading, currLoc, match$3[0]);
        }
      } else {
        attach(t.leading, currLoc, leading);
      }
      Curry._3(walkNode, node, t, match[1]);
      _comments = match[2];
      _l = l.tl;
      _prevLoc = currLoc;
      continue ;
    }
    if (prevLoc === undefined) {
      return comments;
    }
    var match$4 = newlineDelimited ? partitionByOnSameLine(prevLoc, comments) : partitionAdjacentTrailing(prevLoc, comments);
    attach(t.trailing, prevLoc, match$4[0]);
    return match$4[1];
  };
}

function walkValueBindings(vbs, t, comments) {
  return walkList(undefined, (function (n) {
                return n.pvb_loc;
              }), walkValueBinding, vbs, t, comments);
}

function walkOpenDescription(openDescription, t, comments) {
  var loc = openDescription.popen_lid.loc;
  var match = partitionLeadingTrailing(comments, loc);
  attach(t.leading, loc, match[0]);
  return attach(t.trailing, loc, match[1]);
}

function walkTypeDeclarations(typeDeclarations, t, comments) {
  return walkList(undefined, (function (n) {
                return n.ptype_loc;
              }), walkTypeDeclaration, typeDeclarations, t, comments);
}

function walkTypeParam(param, t, comments) {
  return walkTypExpr(param[0], t, comments);
}

function walkTypeDeclaration(td, t, comments) {
  var match = partitionLeadingTrailing(comments, td.ptype_name.loc);
  attach(t.leading, td.ptype_name.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(td.ptype_name.loc, match[1]);
  var rest = match$1[1];
  attach(t.trailing, td.ptype_name.loc, match$1[0]);
  var typeParams = td.ptype_params;
  var rest$1 = typeParams ? visitListButContinueWithRemainingComments(undefined, false, (function (param) {
            return param[0].ptyp_loc;
          }), walkTypeParam, typeParams, t, rest) : rest;
  var typexpr = td.ptype_manifest;
  var rest$2;
  if (typexpr !== undefined) {
    var match$2 = partitionByLoc(rest$1, typexpr.ptyp_loc);
    attach(t.leading, typexpr.ptyp_loc, match$2[0]);
    walkTypExpr(typexpr, t, match$2[1]);
    var match$3 = partitionAdjacentTrailing(typexpr.ptyp_loc, match$2[2]);
    attach(t.trailing, typexpr.ptyp_loc, match$3[0]);
    rest$2 = match$3[1];
  } else {
    rest$2 = rest$1;
  }
  var labelDeclarations = td.ptype_kind;
  var rest$3;
  if (typeof labelDeclarations === "number") {
    rest$3 = rest$2;
  } else if (labelDeclarations.TAG === /* Ptype_variant */0) {
    rest$3 = walkConstructorDeclarations(labelDeclarations._0, t, rest$2);
  } else {
    walkList(undefined, (function (ld) {
            return ld.pld_loc;
          }), walkLabelDeclaration, labelDeclarations._0, t, rest$2);
    rest$3 = /* [] */0;
  }
  return attach(t.trailing, td.ptype_loc, rest$3);
}

function walkLabelDeclarations(lds, t, comments) {
  return visitListButContinueWithRemainingComments(undefined, false, (function (ld) {
                return ld.pld_loc;
              }), walkLabelDeclaration, lds, t, comments);
}

function walkLabelDeclaration(ld, t, comments) {
  var match = partitionLeadingTrailing(comments, ld.pld_name.loc);
  attach(t.leading, ld.pld_name.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(ld.pld_name.loc, match[1]);
  attach(t.trailing, ld.pld_name.loc, match$1[0]);
  var match$2 = partitionByLoc(match$1[1], ld.pld_type.ptyp_loc);
  attach(t.leading, ld.pld_type.ptyp_loc, match$2[0]);
  walkTypExpr(ld.pld_type, t, match$2[1]);
  return attach(t.trailing, ld.pld_type.ptyp_loc, match$2[2]);
}

function walkConstructorDeclarations(cds, t, comments) {
  return visitListButContinueWithRemainingComments(undefined, false, (function (cd) {
                return cd.pcd_loc;
              }), walkConstructorDeclaration, cds, t, comments);
}

function walkConstructorDeclaration(cd, t, comments) {
  var match = partitionLeadingTrailing(comments, cd.pcd_name.loc);
  attach(t.leading, cd.pcd_name.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(cd.pcd_name.loc, match[1]);
  attach(t.trailing, cd.pcd_name.loc, match$1[0]);
  var rest = walkConstructorArguments(cd.pcd_args, t, match$1[1]);
  var typexpr = cd.pcd_res;
  var rest$1;
  if (typexpr !== undefined) {
    var match$2 = partitionByLoc(rest, typexpr.ptyp_loc);
    attach(t.leading, typexpr.ptyp_loc, match$2[0]);
    walkTypExpr(typexpr, t, match$2[1]);
    var match$3 = partitionAdjacentTrailing(typexpr.ptyp_loc, match$2[2]);
    attach(t.trailing, typexpr.ptyp_loc, match$3[0]);
    rest$1 = match$3[1];
  } else {
    rest$1 = rest;
  }
  return attach(t.trailing, cd.pcd_loc, rest$1);
}

function walkConstructorArguments(args, t, comments) {
  if (args.TAG === /* Pcstr_tuple */0) {
    return visitListButContinueWithRemainingComments(undefined, false, (function (n) {
                  return n.ptyp_loc;
                }), walkTypExpr, args._0, t, comments);
  } else {
    return walkLabelDeclarations(args._0, t, comments);
  }
}

function walkValueBinding(vb, t, comments) {
  var match = vb.pvb_pat;
  var match$1 = vb.pvb_expr;
  var match$2 = match.ppat_desc;
  var vb$1;
  if (typeof match$2 === "number" || match$2.TAG !== /* Ppat_constraint */10) {
    vb$1 = vb;
  } else {
    var typ = match$2._1;
    var match$3 = typ.ptyp_desc;
    if (typeof match$3 === "number" || match$3.TAG !== /* Ptyp_poly */8) {
      vb$1 = vb;
    } else {
      var pat = match$2._0;
      if (match$3._0) {
        var match$4 = match$1.pexp_desc;
        var t$1 = match$3._1;
        if (typeof match$4 === "number") {
          vb$1 = vb;
        } else {
          switch (match$4.TAG | 0) {
            case /* Pexp_fun */4 :
                var init = vb.pvb_pat;
                var init$1 = pat.ppat_loc;
                vb$1 = {
                  pvb_pat: {
                    ppat_desc: init.ppat_desc,
                    ppat_loc: {
                      loc_start: init$1.loc_start,
                      loc_end: t$1.ptyp_loc.loc_end,
                      loc_ghost: init$1.loc_ghost
                    },
                    ppat_attributes: init.ppat_attributes
                  },
                  pvb_expr: vb.pvb_expr,
                  pvb_attributes: vb.pvb_attributes,
                  pvb_loc: vb.pvb_loc
                };
                break;
            case /* Pexp_newtype */31 :
                var match$5 = match$4._1.pexp_desc;
                if (typeof match$5 === "number" || match$5.TAG !== /* Pexp_constraint */19) {
                  vb$1 = vb;
                } else {
                  var init$2 = match.ppat_loc;
                  vb$1 = {
                    pvb_pat: {
                      ppat_desc: {
                        TAG: /* Ppat_constraint */10,
                        _0: pat,
                        _1: typ
                      },
                      ppat_loc: {
                        loc_start: init$2.loc_start,
                        loc_end: t$1.ptyp_loc.loc_end,
                        loc_ghost: init$2.loc_ghost
                      },
                      ppat_attributes: match.ppat_attributes
                    },
                    pvb_expr: match$5._0,
                    pvb_attributes: vb.pvb_attributes,
                    pvb_loc: vb.pvb_loc
                  };
                }
                break;
            default:
              vb$1 = vb;
          }
        }
      } else {
        var match$6 = match$1.pexp_desc;
        if (typeof match$6 === "number" || match$6.TAG !== /* Pexp_constraint */19) {
          vb$1 = vb;
        } else {
          var t$2 = match$3._1;
          var init$3 = pat.ppat_loc;
          vb$1 = {
            pvb_pat: Ast_helper.Pat.constraint_({
                  loc_start: init$3.loc_start,
                  loc_end: t$2.ptyp_loc.loc_end,
                  loc_ghost: init$3.loc_ghost
                }, undefined, pat, t$2),
            pvb_expr: match$6._0,
            pvb_attributes: vb.pvb_attributes,
            pvb_loc: vb.pvb_loc
          };
        }
      }
    }
  }
  var patternLoc = vb$1.pvb_pat.ppat_loc;
  var exprLoc = vb$1.pvb_expr.pexp_loc;
  var expr = vb$1.pvb_expr;
  var match$7 = partitionByLoc(comments, patternLoc);
  attach(t.leading, patternLoc, match$7[0]);
  walkPattern(vb$1.pvb_pat, t, match$7[1]);
  var match$8 = partitionAdjacentTrailing(patternLoc, match$7[2]);
  attach(t.trailing, patternLoc, match$8[0]);
  var match$9 = partitionByLoc(match$8[1], exprLoc);
  var afterExpr = match$9[2];
  var insideExpr = match$9[1];
  var beforeExpr = match$9[0];
  if (isBlockExpr(expr)) {
    return walkExpr(expr, t, List.concat({
                    hd: beforeExpr,
                    tl: {
                      hd: insideExpr,
                      tl: {
                        hd: afterExpr,
                        tl: /* [] */0
                      }
                    }
                  }));
  } else {
    attach(t.leading, exprLoc, beforeExpr);
    walkExpr(expr, t, insideExpr);
    return attach(t.trailing, exprLoc, afterExpr);
  }
}

function walkExpr(_expr, t, _comments) {
  while(true) {
    var comments = _comments;
    var expr = _expr;
    var longident = expr.pexp_desc;
    var exit = 0;
    var exprs;
    var expr$1;
    var cases;
    if (comments === /* [] */0) {
      return ;
    }
    var exit$1 = 0;
    if (typeof longident === "number") {
      return ;
    }
    switch (longident.TAG | 0) {
      case /* Pexp_ident */0 :
          var longident$1 = longident._0;
          var match = partitionLeadingTrailing(comments, longident$1.loc);
          attach(t.leading, longident$1.loc, match[0]);
          return attach(t.trailing, longident$1.loc, match[1]);
      case /* Pexp_constant */1 :
          var match$1 = partitionLeadingTrailing(comments, expr.pexp_loc);
          attach(t.leading, expr.pexp_loc, match$1[0]);
          return attach(t.trailing, expr.pexp_loc, match$1[1]);
      case /* Pexp_let */2 :
          var expr2 = longident._2;
          var match$2 = expr2.pexp_desc;
          var valueBindings = longident._1;
          var exit$2 = 0;
          if (typeof match$2 === "number" || match$2.TAG !== /* Pexp_construct */9) {
            exit$2 = 6;
          } else {
            var match$3 = match$2._0.txt;
            switch (match$3.TAG | 0) {
              case /* Lident */0 :
                  if (match$3._0 === "()") {
                    if (match$2._1 === undefined) {
                      return walkValueBindings(valueBindings, t, comments);
                    }
                    exit$2 = 6;
                  } else {
                    exit$2 = 6;
                  }
                  break;
              case /* Ldot */1 :
              case /* Lapply */2 :
                  exit$2 = 6;
                  break;
              
            }
          }
          if (exit$2 === 6) {
            var comments$1 = visitListButContinueWithRemainingComments(undefined, true, (function (n) {
                    if (n.pvb_pat.ppat_loc.loc_ghost) {
                      return n.pvb_expr.pexp_loc;
                    } else {
                      return n.pvb_loc;
                    }
                  }), walkValueBinding, valueBindings, t, comments);
            if (isBlockExpr(expr2)) {
              _comments = comments$1;
              _expr = expr2;
              continue ;
            }
            var match$4 = partitionByLoc(comments$1, expr2.pexp_loc);
            attach(t.leading, expr2.pexp_loc, match$4[0]);
            walkExpr(expr2, t, match$4[1]);
            return attach(t.trailing, expr2.pexp_loc, match$4[2]);
          }
          break;
      case /* Pexp_apply */5 :
          var callExpr = longident._0;
          var match$5 = callExpr.pexp_desc;
          var exit$3 = 0;
          if (typeof match$5 === "number" || match$5.TAG !== /* Pexp_ident */0) {
            exit$3 = 6;
          } else {
            var match$6 = match$5._0.txt;
            switch (match$6.TAG | 0) {
              case /* Lident */0 :
                  var exit$4 = 0;
                  switch (match$6._0) {
                    case "!=" :
                    case "!==" :
                    case "&&" :
                    case "*" :
                    case "**" :
                    case "*." :
                    case "+" :
                    case "++" :
                    case "+." :
                    case "-" :
                    case "-." :
                    case "/" :
                    case "/." :
                    case ":=" :
                    case "<" :
                    case "<=" :
                    case "<>" :
                    case "=" :
                    case "==" :
                    case ">" :
                    case ">=" :
                    case "^" :
                    case "|." :
                    case "|>" :
                    case "||" :
                        exit$4 = 8;
                        break;
                    case "!" :
                    case "not" :
                    case "~+" :
                    case "~+." :
                    case "~-" :
                    case "~-." :
                        exit$4 = 7;
                        break;
                    default:
                      exit$3 = 6;
                  }
                  switch (exit$4) {
                    case 7 :
                        var match$7 = longident._1;
                        if (match$7) {
                          var match$8 = match$7.hd;
                          if (typeof match$8[0] === "number" && !match$7.tl) {
                            var argExpr = match$8[1];
                            var match$9 = partitionByLoc(comments, argExpr.pexp_loc);
                            attach(t.leading, argExpr.pexp_loc, match$9[0]);
                            walkExpr(argExpr, t, match$9[1]);
                            return attach(t.trailing, argExpr.pexp_loc, match$9[2]);
                          }
                          exit$3 = 6;
                        } else {
                          exit$3 = 6;
                        }
                        break;
                    case 8 :
                        var match$10 = longident._1;
                        if (match$10) {
                          var match$11 = match$10.hd;
                          if (typeof match$11[0] === "number") {
                            var match$12 = match$10.tl;
                            if (match$12) {
                              var match$13 = match$12.hd;
                              if (typeof match$13[0] === "number" && !match$12.tl) {
                                var operand2 = match$13[1];
                                var operand1 = match$11[1];
                                var match$14 = partitionByLoc(comments, operand1.pexp_loc);
                                attach(t.leading, operand1.pexp_loc, match$14[0]);
                                walkExpr(operand1, t, match$14[1]);
                                var match$15 = partitionAdjacentTrailing(operand1.pexp_loc, match$14[2]);
                                attach(t.trailing, operand1.pexp_loc, match$15[0]);
                                var match$16 = partitionByLoc(match$15[1], operand2.pexp_loc);
                                attach(t.leading, operand2.pexp_loc, match$16[0]);
                                walkExpr(operand2, t, match$16[1]);
                                return attach(t.trailing, operand2.pexp_loc, match$16[2]);
                              }
                              exit$3 = 6;
                            } else {
                              exit$3 = 6;
                            }
                          } else {
                            exit$3 = 6;
                          }
                        } else {
                          exit$3 = 6;
                        }
                        break;
                    
                  }
                  break;
              case /* Ldot */1 :
              case /* Lapply */2 :
                  exit$3 = 6;
                  break;
              
            }
          }
          if (exit$3 === 6) {
            var match$17 = partitionByLoc(comments, callExpr.pexp_loc);
            var after = match$17[2];
            var inside = match$17[1];
            var before = match$17[0];
            var after$1;
            if (isBlockExpr(callExpr)) {
              var match$18 = partitionAdjacentTrailing(callExpr.pexp_loc, after);
              walkExpr(callExpr, t, List.concat({
                        hd: before,
                        tl: {
                          hd: inside,
                          tl: {
                            hd: match$18[0],
                            tl: /* [] */0
                          }
                        }
                      }));
              after$1 = match$18[1];
            } else {
              attach(t.leading, callExpr.pexp_loc, before);
              walkExpr(callExpr, t, inside);
              after$1 = after;
            }
            var match$19 = partitionAdjacentTrailing(callExpr.pexp_loc, after$1);
            attach(t.trailing, callExpr.pexp_loc, match$19[0]);
            return walkList(undefined, (function (param) {
                          var expr = param[1];
                          var match = expr.pexp_attributes;
                          if (!match) {
                            return expr.pexp_loc;
                          }
                          var match$1 = match.hd[0];
                          if (match$1.txt !== "ns.namedArgLoc") {
                            return expr.pexp_loc;
                          }
                          var loc = match$1.loc;
                          return {
                                  loc_start: loc.loc_start,
                                  loc_end: expr.pexp_loc.loc_end,
                                  loc_ghost: loc.loc_ghost
                                };
                        }), walkExprArgument, longident._1, t, match$19[1]);
          }
          break;
      case /* Pexp_match */6 :
          var cases$1 = longident._1;
          var expr1 = longident._0;
          if (cases$1) {
            var match$20 = cases$1.tl;
            if (match$20 && !match$20.tl) {
              var elseBranch = match$20.hd;
              var $$case = cases$1.hd;
              if (Res_parsetree_viewer.hasIfLetAttribute(expr.pexp_attributes)) {
                var match$21 = partitionByLoc(comments, $$case.pc_lhs.ppat_loc);
                attach(t.leading, $$case.pc_lhs.ppat_loc, match$21[0]);
                walkPattern($$case.pc_lhs, t, match$21[1]);
                var match$22 = partitionAdjacentTrailing($$case.pc_lhs.ppat_loc, match$21[2]);
                attach(t.trailing, $$case.pc_lhs.ppat_loc, match$22[0]);
                var match$23 = partitionByLoc(match$22[1], expr1.pexp_loc);
                attach(t.leading, expr1.pexp_loc, match$23[0]);
                walkExpr(expr1, t, match$23[1]);
                var match$24 = partitionAdjacentTrailing(expr1.pexp_loc, match$23[2]);
                attach(t.trailing, expr1.pexp_loc, match$24[0]);
                var match$25 = partitionByLoc(match$24[1], $$case.pc_rhs.pexp_loc);
                var after$2 = match$25[2];
                var inside$1 = match$25[1];
                var before$1 = match$25[0];
                var after$3;
                if (isBlockExpr($$case.pc_rhs)) {
                  var match$26 = partitionAdjacentTrailing($$case.pc_rhs.pexp_loc, after$2);
                  walkExpr($$case.pc_rhs, t, List.concat({
                            hd: before$1,
                            tl: {
                              hd: inside$1,
                              tl: {
                                hd: match$26[0],
                                tl: /* [] */0
                              }
                            }
                          }));
                  after$3 = match$26[1];
                } else {
                  attach(t.leading, $$case.pc_rhs.pexp_loc, before$1);
                  walkExpr($$case.pc_rhs, t, inside$1);
                  after$3 = after$2;
                }
                var match$27 = partitionAdjacentTrailing($$case.pc_rhs.pexp_loc, after$3);
                attach(t.trailing, $$case.pc_rhs.pexp_loc, match$27[0]);
                var match$28 = partitionByLoc(match$27[1], elseBranch.pc_rhs.pexp_loc);
                var after$4 = match$28[2];
                var inside$2 = match$28[1];
                var before$2 = match$28[0];
                var after$5;
                if (isBlockExpr(elseBranch.pc_rhs)) {
                  var match$29 = partitionAdjacentTrailing(elseBranch.pc_rhs.pexp_loc, after$4);
                  walkExpr(elseBranch.pc_rhs, t, List.concat({
                            hd: before$2,
                            tl: {
                              hd: inside$2,
                              tl: {
                                hd: match$29[0],
                                tl: /* [] */0
                              }
                            }
                          }));
                  after$5 = match$29[1];
                } else {
                  attach(t.leading, elseBranch.pc_rhs.pexp_loc, before$2);
                  walkExpr(elseBranch.pc_rhs, t, inside$2);
                  after$5 = after$4;
                }
                return attach(t.trailing, elseBranch.pc_rhs.pexp_loc, after$5);
              }
              expr$1 = expr1;
              cases = cases$1;
              exit = 3;
            } else {
              expr$1 = expr1;
              cases = cases$1;
              exit = 3;
            }
          } else {
            expr$1 = expr1;
            cases = cases$1;
            exit = 3;
          }
          break;
      case /* Pexp_try */7 :
          expr$1 = longident._0;
          cases = longident._1;
          exit = 3;
          break;
      case /* Pexp_tuple */8 :
          var exprs$1 = longident._0;
          if (exprs$1) {
            exprs = exprs$1;
            exit = 2;
          } else {
            exit = 1;
          }
          break;
      case /* Pexp_construct */9 :
          var longident$2 = longident._0;
          var match$30 = longident$2.txt;
          var exit$5 = 0;
          switch (match$30.TAG | 0) {
            case /* Lident */0 :
                switch (match$30._0) {
                  case "::" :
                      return walkList(undefined, (function (n) {
                                    return n.pexp_loc;
                                  }), walkExpr, collectListExprs(/* [] */0, expr), t, comments);
                  case "[]" :
                      exit = 1;
                      break;
                  default:
                    exit$5 = 6;
                }
                break;
            case /* Ldot */1 :
            case /* Lapply */2 :
                exit$5 = 6;
                break;
            
          }
          if (exit$5 === 6) {
            var args = longident._1;
            var match$31 = partitionLeadingTrailing(comments, longident$2.loc);
            var trailing = match$31[1];
            attach(t.leading, longident$2.loc, match$31[0]);
            if (args === undefined) {
              return attach(t.trailing, longident$2.loc, trailing);
            }
            var match$32 = partitionAdjacentTrailing(longident$2.loc, trailing);
            attach(t.trailing, longident$2.loc, match$32[0]);
            _comments = match$32[1];
            _expr = args;
            continue ;
          }
          break;
      case /* Pexp_variant */10 :
          var expr$2 = longident._1;
          if (expr$2 === undefined) {
            return ;
          }
          _expr = expr$2;
          continue ;
      case /* Pexp_record */11 :
          var spreadExpr = longident._1;
          var comments$2;
          if (spreadExpr !== undefined) {
            var match$33 = partitionByLoc(comments, spreadExpr.pexp_loc);
            attach(t.leading, spreadExpr.pexp_loc, match$33[0]);
            walkExpr(spreadExpr, t, match$33[1]);
            var match$34 = partitionAdjacentTrailing(spreadExpr.pexp_loc, match$33[2]);
            attach(t.trailing, spreadExpr.pexp_loc, match$34[0]);
            comments$2 = match$34[1];
          } else {
            comments$2 = comments;
          }
          return walkList(undefined, (function (param) {
                        var init = param[0].loc;
                        return {
                                loc_start: init.loc_start,
                                loc_end: param[1].pexp_loc.loc_end,
                                loc_ghost: init.loc_ghost
                              };
                      }), walkExprRecordRow, longident._0, t, comments$2);
      case /* Pexp_field */12 :
          var longident$3 = longident._1;
          var expr$3 = longident._0;
          var match$35 = partitionByLoc(comments, expr$3.pexp_loc);
          var trailing$1 = match$35[2];
          var inside$3 = match$35[1];
          var leading = match$35[0];
          var trailing$2;
          if (isBlockExpr(expr$3)) {
            var match$36 = partitionAdjacentTrailing(expr$3.pexp_loc, trailing$1);
            walkExpr(expr$3, t, List.concat({
                      hd: leading,
                      tl: {
                        hd: inside$3,
                        tl: {
                          hd: match$36[0],
                          tl: /* [] */0
                        }
                      }
                    }));
            trailing$2 = match$36[1];
          } else {
            attach(t.leading, expr$3.pexp_loc, leading);
            walkExpr(expr$3, t, inside$3);
            trailing$2 = trailing$1;
          }
          var match$37 = partitionAdjacentTrailing(expr$3.pexp_loc, trailing$2);
          attach(t.trailing, expr$3.pexp_loc, match$37[0]);
          var match$38 = partitionLeadingTrailing(match$37[1], longident$3.loc);
          attach(t.leading, longident$3.loc, match$38[0]);
          return attach(t.trailing, longident$3.loc, match$38[1]);
      case /* Pexp_setfield */13 :
          var expr2$1 = longident._2;
          var longident$4 = longident._1;
          var expr1$1 = longident._0;
          var match$39 = partitionByLoc(comments, expr1$1.pexp_loc);
          var trailing$3 = match$39[2];
          var inside$4 = match$39[1];
          var leading$1 = match$39[0];
          var rest;
          if (isBlockExpr(expr1$1)) {
            var match$40 = partitionAdjacentTrailing(expr1$1.pexp_loc, trailing$3);
            walkExpr(expr1$1, t, List.concat({
                      hd: leading$1,
                      tl: {
                        hd: inside$4,
                        tl: {
                          hd: match$40[0],
                          tl: /* [] */0
                        }
                      }
                    }));
            rest = match$40[1];
          } else {
            var match$41 = partitionAdjacentTrailing(expr1$1.pexp_loc, trailing$3);
            attach(t.leading, expr1$1.pexp_loc, leading$1);
            walkExpr(expr1$1, t, inside$4);
            attach(t.trailing, expr1$1.pexp_loc, match$41[0]);
            rest = match$41[1];
          }
          var match$42 = partitionLeadingTrailing(rest, longident$4.loc);
          attach(t.leading, longident$4.loc, match$42[0]);
          var match$43 = partitionAdjacentTrailing(longident$4.loc, match$42[1]);
          var rest$1 = match$43[1];
          attach(t.trailing, longident$4.loc, match$43[0]);
          if (isBlockExpr(expr2$1)) {
            _comments = rest$1;
            _expr = expr2$1;
            continue ;
          }
          var match$44 = partitionByLoc(rest$1, expr2$1.pexp_loc);
          attach(t.leading, expr2$1.pexp_loc, match$44[0]);
          walkExpr(expr2$1, t, match$44[1]);
          return attach(t.trailing, expr2$1.pexp_loc, match$44[2]);
      case /* Pexp_array */14 :
          var exprs$2 = longident._0;
          if (exprs$2) {
            exprs = exprs$2;
            exit = 2;
          } else {
            exit = 1;
          }
          break;
      case /* Pexp_ifthenelse */15 :
          var elseExpr = longident._2;
          var thenExpr = longident._1;
          var ifExpr = longident._0;
          var match$45 = partitionByLoc(comments, ifExpr.pexp_loc);
          var trailing$4 = match$45[2];
          var inside$5 = match$45[1];
          var leading$2 = match$45[0];
          var comments$3;
          if (isBlockExpr(ifExpr)) {
            var match$46 = partitionAdjacentTrailing(ifExpr.pexp_loc, trailing$4);
            walkExpr(ifExpr, t, List.concat({
                      hd: leading$2,
                      tl: {
                        hd: inside$5,
                        tl: {
                          hd: match$46[0],
                          tl: /* [] */0
                        }
                      }
                    }));
            comments$3 = match$46[1];
          } else {
            attach(t.leading, ifExpr.pexp_loc, leading$2);
            walkExpr(ifExpr, t, inside$5);
            var match$47 = partitionAdjacentTrailing(ifExpr.pexp_loc, trailing$4);
            attach(t.trailing, ifExpr.pexp_loc, match$47[0]);
            comments$3 = match$47[1];
          }
          var match$48 = partitionByLoc(comments$3, thenExpr.pexp_loc);
          var trailing$5 = match$48[2];
          var inside$6 = match$48[1];
          var leading$3 = match$48[0];
          var comments$4;
          if (isBlockExpr(thenExpr)) {
            var match$49 = partitionAdjacentTrailing(thenExpr.pexp_loc, trailing$5);
            walkExpr(thenExpr, t, List.concat({
                      hd: leading$3,
                      tl: {
                        hd: inside$6,
                        tl: {
                          hd: match$49[0],
                          tl: /* [] */0
                        }
                      }
                    }));
            comments$4 = match$49[1];
          } else {
            attach(t.leading, thenExpr.pexp_loc, leading$3);
            walkExpr(thenExpr, t, inside$6);
            var match$50 = partitionAdjacentTrailing(thenExpr.pexp_loc, trailing$5);
            attach(t.trailing, thenExpr.pexp_loc, match$50[0]);
            comments$4 = match$50[1];
          }
          if (elseExpr === undefined) {
            return ;
          }
          if (isBlockExpr(elseExpr) || isIfThenElseExpr(elseExpr)) {
            _comments = comments$4;
            _expr = elseExpr;
            continue ;
          }
          var match$51 = partitionByLoc(comments$4, elseExpr.pexp_loc);
          attach(t.leading, elseExpr.pexp_loc, match$51[0]);
          walkExpr(elseExpr, t, match$51[1]);
          return attach(t.trailing, elseExpr.pexp_loc, match$51[2]);
      case /* Pexp_sequence */16 :
          var expr2$2 = longident._1;
          var expr1$2 = longident._0;
          var match$52 = partitionByLoc(comments, expr1$2.pexp_loc);
          var trailing$6 = match$52[2];
          var inside$7 = match$52[1];
          var leading$4 = match$52[0];
          var comments$5;
          if (isBlockExpr(expr1$2)) {
            var match$53 = partitionByOnSameLine(expr1$2.pexp_loc, trailing$6);
            walkExpr(expr1$2, t, List.concat({
                      hd: leading$4,
                      tl: {
                        hd: inside$7,
                        tl: {
                          hd: match$53[0],
                          tl: /* [] */0
                        }
                      }
                    }));
            comments$5 = match$53[1];
          } else {
            attach(t.leading, expr1$2.pexp_loc, leading$4);
            walkExpr(expr1$2, t, inside$7);
            var match$54 = partitionByOnSameLine(expr1$2.pexp_loc, trailing$6);
            attach(t.trailing, expr1$2.pexp_loc, match$54[0]);
            comments$5 = match$54[1];
          }
          if (isBlockExpr(expr2$2)) {
            _comments = comments$5;
            _expr = expr2$2;
            continue ;
          }
          var match$55 = partitionByLoc(comments$5, expr2$2.pexp_loc);
          attach(t.leading, expr2$2.pexp_loc, match$55[0]);
          walkExpr(expr2$2, t, match$55[1]);
          return attach(t.trailing, expr2$2.pexp_loc, match$55[2]);
      case /* Pexp_while */17 :
          var expr2$3 = longident._1;
          var expr1$3 = longident._0;
          var match$56 = partitionByLoc(comments, expr1$3.pexp_loc);
          var trailing$7 = match$56[2];
          var inside$8 = match$56[1];
          var leading$5 = match$56[0];
          var rest$2;
          if (isBlockExpr(expr1$3)) {
            var match$57 = partitionAdjacentTrailing(expr1$3.pexp_loc, trailing$7);
            walkExpr(expr1$3, t, List.concat({
                      hd: leading$5,
                      tl: {
                        hd: inside$8,
                        tl: {
                          hd: match$57[0],
                          tl: /* [] */0
                        }
                      }
                    }));
            rest$2 = match$57[1];
          } else {
            attach(t.leading, expr1$3.pexp_loc, leading$5);
            walkExpr(expr1$3, t, inside$8);
            var match$58 = partitionAdjacentTrailing(expr1$3.pexp_loc, trailing$7);
            attach(t.trailing, expr1$3.pexp_loc, match$58[0]);
            rest$2 = match$58[1];
          }
          if (isBlockExpr(expr2$3)) {
            _comments = rest$2;
            _expr = expr2$3;
            continue ;
          }
          var match$59 = partitionByLoc(rest$2, expr2$3.pexp_loc);
          attach(t.leading, expr2$3.pexp_loc, match$59[0]);
          walkExpr(expr2$3, t, match$59[1]);
          return attach(t.trailing, expr2$3.pexp_loc, match$59[2]);
      case /* Pexp_for */18 :
          var expr3 = longident._4;
          var expr2$4 = longident._2;
          var expr1$4 = longident._1;
          var pat = longident._0;
          var match$60 = partitionByLoc(comments, pat.ppat_loc);
          attach(t.leading, pat.ppat_loc, match$60[0]);
          walkPattern(pat, t, match$60[1]);
          var match$61 = partitionAdjacentTrailing(pat.ppat_loc, match$60[2]);
          attach(t.trailing, pat.ppat_loc, match$61[0]);
          var match$62 = partitionByLoc(match$61[1], expr1$4.pexp_loc);
          attach(t.leading, expr1$4.pexp_loc, match$62[0]);
          walkExpr(expr1$4, t, match$62[1]);
          var match$63 = partitionAdjacentTrailing(expr1$4.pexp_loc, match$62[2]);
          attach(t.trailing, expr1$4.pexp_loc, match$63[0]);
          var match$64 = partitionByLoc(match$63[1], expr2$4.pexp_loc);
          attach(t.leading, expr2$4.pexp_loc, match$64[0]);
          walkExpr(expr2$4, t, match$64[1]);
          var match$65 = partitionAdjacentTrailing(expr2$4.pexp_loc, match$64[2]);
          var rest$3 = match$65[1];
          attach(t.trailing, expr2$4.pexp_loc, match$65[0]);
          if (isBlockExpr(expr3)) {
            _comments = rest$3;
            _expr = expr3;
            continue ;
          }
          var match$66 = partitionByLoc(rest$3, expr3.pexp_loc);
          attach(t.leading, expr3.pexp_loc, match$66[0]);
          walkExpr(expr3, t, match$66[1]);
          return attach(t.trailing, expr3.pexp_loc, match$66[2]);
      case /* Pexp_constraint */19 :
          var typexpr = longident._1;
          var expr$4 = longident._0;
          var match$67 = partitionByLoc(comments, expr$4.pexp_loc);
          attach(t.leading, expr$4.pexp_loc, match$67[0]);
          walkExpr(expr$4, t, match$67[1]);
          var match$68 = partitionAdjacentTrailing(expr$4.pexp_loc, match$67[2]);
          attach(t.trailing, expr$4.pexp_loc, match$68[0]);
          var match$69 = partitionByLoc(match$68[1], typexpr.ptyp_loc);
          attach(t.leading, typexpr.ptyp_loc, match$69[0]);
          walkTypExpr(typexpr, t, match$69[1]);
          return attach(t.trailing, typexpr.ptyp_loc, match$69[2]);
      case /* Pexp_coerce */20 :
          var typexpr$1 = longident._2;
          var optTypexpr = longident._1;
          var expr$5 = longident._0;
          var match$70 = partitionByLoc(comments, expr$5.pexp_loc);
          attach(t.leading, expr$5.pexp_loc, match$70[0]);
          walkExpr(expr$5, t, match$70[1]);
          var match$71 = partitionAdjacentTrailing(expr$5.pexp_loc, match$70[2]);
          attach(t.trailing, expr$5.pexp_loc, match$71[0]);
          var rest$4;
          if (optTypexpr !== undefined) {
            var match$72 = partitionByLoc(comments, optTypexpr.ptyp_loc);
            attach(t.leading, optTypexpr.ptyp_loc, match$72[0]);
            walkTypExpr(optTypexpr, t, match$72[1]);
            var match$73 = partitionAdjacentTrailing(optTypexpr.ptyp_loc, match$72[2]);
            attach(t.trailing, optTypexpr.ptyp_loc, match$73[0]);
            rest$4 = match$73[1];
          } else {
            rest$4 = match$71[1];
          }
          var match$74 = partitionByLoc(rest$4, typexpr$1.ptyp_loc);
          attach(t.leading, typexpr$1.ptyp_loc, match$74[0]);
          walkTypExpr(typexpr$1, t, match$74[1]);
          return attach(t.trailing, typexpr$1.ptyp_loc, match$74[2]);
      case /* Pexp_letmodule */25 :
          var expr2$5 = longident._2;
          var modExpr = longident._1;
          var stringLoc = longident._0;
          var match$75 = partitionLeadingTrailing(comments, expr.pexp_loc);
          var init = expr.pexp_loc;
          attach(t.leading, {
                loc_start: init.loc_start,
                loc_end: modExpr.pmod_loc.loc_end,
                loc_ghost: init.loc_ghost
              }, match$75[0]);
          var match$76 = partitionLeadingTrailing(match$75[1], stringLoc.loc);
          attach(t.leading, stringLoc.loc, match$76[0]);
          var match$77 = partitionAdjacentTrailing(stringLoc.loc, match$76[1]);
          attach(t.trailing, stringLoc.loc, match$77[0]);
          var match$78 = partitionByLoc(match$77[1], modExpr.pmod_loc);
          attach(t.leading, modExpr.pmod_loc, match$78[0]);
          walkModExpr(modExpr, t, match$78[1]);
          var match$79 = partitionByOnSameLine(modExpr.pmod_loc, match$78[2]);
          var rest$5 = match$79[1];
          attach(t.trailing, modExpr.pmod_loc, match$79[0]);
          if (isBlockExpr(expr2$5)) {
            _comments = rest$5;
            _expr = expr2$5;
            continue ;
          }
          var match$80 = partitionByLoc(rest$5, expr2$5.pexp_loc);
          attach(t.leading, expr2$5.pexp_loc, match$80[0]);
          walkExpr(expr2$5, t, match$80[1]);
          return attach(t.trailing, expr2$5.pexp_loc, match$80[2]);
      case /* Pexp_letexception */26 :
          var expr2$6 = longident._1;
          var extensionConstructor = longident._0;
          var match$81 = partitionLeadingTrailing(comments, expr.pexp_loc);
          var init$1 = expr.pexp_loc;
          attach(t.leading, {
                loc_start: init$1.loc_start,
                loc_end: extensionConstructor.pext_loc.loc_end,
                loc_ghost: init$1.loc_ghost
              }, match$81[0]);
          var match$82 = partitionByLoc(match$81[1], extensionConstructor.pext_loc);
          attach(t.leading, extensionConstructor.pext_loc, match$82[0]);
          walkExtConstr(extensionConstructor, t, match$82[1]);
          var match$83 = partitionByOnSameLine(extensionConstructor.pext_loc, match$82[2]);
          var rest$6 = match$83[1];
          attach(t.trailing, extensionConstructor.pext_loc, match$83[0]);
          if (isBlockExpr(expr2$6)) {
            _comments = rest$6;
            _expr = expr2$6;
            continue ;
          }
          var match$84 = partitionByLoc(rest$6, expr2$6.pexp_loc);
          attach(t.leading, expr2$6.pexp_loc, match$84[0]);
          walkExpr(expr2$6, t, match$84[1]);
          return attach(t.trailing, expr2$6.pexp_loc, match$84[2]);
      case /* Pexp_assert */27 :
      case /* Pexp_lazy */28 :
          exit$1 = 5;
          break;
      case /* Pexp_fun */4 :
      case /* Pexp_newtype */31 :
          exit = 4;
          break;
      case /* Pexp_pack */32 :
          var modExpr$1 = longident._0;
          var match$85 = partitionByLoc(comments, modExpr$1.pmod_loc);
          attach(t.leading, modExpr$1.pmod_loc, match$85[0]);
          walkModExpr(modExpr$1, t, match$85[1]);
          return attach(t.trailing, modExpr$1.pmod_loc, match$85[2]);
      case /* Pexp_open */33 :
          var expr2$7 = longident._2;
          var longident$5 = longident._1;
          var match$86 = partitionLeadingTrailing(comments, expr.pexp_loc);
          var init$2 = expr.pexp_loc;
          attach(t.leading, {
                loc_start: init$2.loc_start,
                loc_end: longident$5.loc.loc_end,
                loc_ghost: init$2.loc_ghost
              }, match$86[0]);
          var match$87 = partitionLeadingTrailing(match$86[1], longident$5.loc);
          attach(t.leading, longident$5.loc, match$87[0]);
          var match$88 = partitionByOnSameLine(longident$5.loc, match$87[1]);
          var rest$7 = match$88[1];
          attach(t.trailing, longident$5.loc, match$88[0]);
          if (isBlockExpr(expr2$7)) {
            _comments = rest$7;
            _expr = expr2$7;
            continue ;
          }
          var match$89 = partitionByLoc(rest$7, expr2$7.pexp_loc);
          attach(t.leading, expr2$7.pexp_loc, match$89[0]);
          walkExpr(expr2$7, t, match$89[1]);
          return attach(t.trailing, expr2$7.pexp_loc, match$89[2]);
      case /* Pexp_extension */34 :
          var extension = longident._0;
          var exit$6 = 0;
          switch (extension[0].txt) {
            case "bs.obj" :
            case "obj" :
                exit$6 = 6;
                break;
            default:
              return walkExtension(extension, t, comments);
          }
          if (exit$6 === 6) {
            var match$90 = extension[1];
            if (match$90.TAG !== /* PStr */0) {
              return walkExtension(extension, t, comments);
            }
            var match$91 = match$90._0;
            if (!match$91) {
              return walkExtension(extension, t, comments);
            }
            var match$92 = match$91.hd.pstr_desc;
            if (match$92.TAG !== /* Pstr_eval */0) {
              return walkExtension(extension, t, comments);
            }
            var match$93 = match$92._0.pexp_desc;
            if (typeof match$93 === "number" || !(match$93.TAG === /* Pexp_record */11 && !(match$92._1 || match$91.tl))) {
              return walkExtension(extension, t, comments);
            } else {
              return walkList(undefined, (function (param) {
                            var init = param[0].loc;
                            return {
                                    loc_start: init.loc_start,
                                    loc_end: param[1].pexp_loc.loc_end,
                                    loc_ghost: init.loc_ghost
                                  };
                          }), walkExprRecordRow, match$93._0, t, comments);
            }
          }
          break;
      default:
        return ;
    }
    if (exit$1 === 5) {
      var expr$6 = longident._0;
      if (isBlockExpr(expr$6)) {
        _expr = expr$6;
        continue ;
      }
      var match$94 = partitionByLoc(comments, expr$6.pexp_loc);
      attach(t.leading, expr$6.pexp_loc, match$94[0]);
      walkExpr(expr$6, t, match$94[1]);
      return attach(t.trailing, expr$6.pexp_loc, match$94[2]);
    }
    switch (exit) {
      case 1 :
          return attach(t.inside, expr.pexp_loc, comments);
      case 2 :
          return walkList(undefined, (function (n) {
                        return n.pexp_loc;
                      }), walkExpr, exprs, t, comments);
      case 3 :
          var match$95 = partitionByLoc(comments, expr$1.pexp_loc);
          var after$6 = match$95[2];
          var inside$9 = match$95[1];
          var before$3 = match$95[0];
          var after$7;
          if (isBlockExpr(expr$1)) {
            var match$96 = partitionAdjacentTrailing(expr$1.pexp_loc, after$6);
            walkExpr(expr$1, t, List.concat({
                      hd: before$3,
                      tl: {
                        hd: inside$9,
                        tl: {
                          hd: match$96[0],
                          tl: /* [] */0
                        }
                      }
                    }));
            after$7 = match$96[1];
          } else {
            attach(t.leading, expr$1.pexp_loc, before$3);
            walkExpr(expr$1, t, inside$9);
            after$7 = after$6;
          }
          var match$97 = partitionAdjacentTrailing(expr$1.pexp_loc, after$7);
          attach(t.trailing, expr$1.pexp_loc, match$97[0]);
          return walkList(undefined, (function (n) {
                        var init = n.pc_lhs.ppat_loc;
                        return {
                                loc_start: init.loc_start,
                                loc_end: n.pc_rhs.pexp_loc.loc_end,
                                loc_ghost: init.loc_ghost
                              };
                      }), walkCase, cases, t, match$97[1]);
      case 4 :
          var match$98 = funExpr(expr);
          var returnExpr = match$98[2];
          var comments$6 = visitListButContinueWithRemainingComments(undefined, false, (function (param) {
                  var pattern = param[3];
                  var exprOpt = param[2];
                  var match = pattern.ppat_attributes;
                  var startPos;
                  if (match) {
                    var match$1 = match.hd[0];
                    startPos = match$1.txt === "ns.namedArgLoc" ? match$1.loc.loc_start : pattern.ppat_loc.loc_start;
                  } else {
                    startPos = pattern.ppat_loc.loc_start;
                  }
                  if (exprOpt !== undefined) {
                    var init = pattern.ppat_loc;
                    return {
                            loc_start: startPos,
                            loc_end: exprOpt.pexp_loc.loc_end,
                            loc_ghost: init.loc_ghost
                          };
                  }
                  var init$1 = pattern.ppat_loc;
                  return {
                          loc_start: startPos,
                          loc_end: init$1.loc_end,
                          loc_ghost: init$1.loc_ghost
                        };
                }), walkExprPararameter, match$98[1], t, comments);
          var match$99 = returnExpr.pexp_desc;
          var exit$7 = 0;
          if (typeof match$99 === "number" || match$99.TAG !== /* Pexp_constraint */19) {
            exit$7 = 5;
          } else {
            var typ = match$99._1;
            var expr$7 = match$99._0;
            if (expr$7.pexp_loc.loc_start.pos_cnum >= typ.ptyp_loc.loc_end.pos_cnum) {
              var match$100 = partitionByLoc(comments$6, typ.ptyp_loc);
              attach(t.leading, typ.ptyp_loc, match$100[0]);
              walkTypExpr(typ, t, match$100[1]);
              var match$101 = partitionAdjacentTrailing(typ.ptyp_loc, match$100[2]);
              var comments$7 = match$101[1];
              attach(t.trailing, typ.ptyp_loc, match$101[0]);
              if (isBlockExpr(expr$7)) {
                _comments = comments$7;
                _expr = expr$7;
                continue ;
              }
              var match$102 = partitionByLoc(comments$7, expr$7.pexp_loc);
              attach(t.leading, expr$7.pexp_loc, match$102[0]);
              walkExpr(expr$7, t, match$102[1]);
              return attach(t.trailing, expr$7.pexp_loc, match$102[2]);
            }
            exit$7 = 5;
          }
          if (exit$7 === 5) {
            if (isBlockExpr(returnExpr)) {
              _comments = comments$6;
              _expr = returnExpr;
              continue ;
            }
            var match$103 = partitionByLoc(comments$6, returnExpr.pexp_loc);
            attach(t.leading, returnExpr.pexp_loc, match$103[0]);
            walkExpr(returnExpr, t, match$103[1]);
            return attach(t.trailing, returnExpr.pexp_loc, match$103[2]);
          }
          break;
      
    }
  };
}

function walkExprPararameter(param, t, comments) {
  var pattern = param[3];
  var exprOpt = param[2];
  var match = partitionByLoc(comments, pattern.ppat_loc);
  var trailing = match[2];
  attach(t.leading, pattern.ppat_loc, match[0]);
  walkPattern(pattern, t, match[1]);
  if (exprOpt === undefined) {
    return attach(t.trailing, pattern.ppat_loc, trailing);
  }
  var match$1 = partitionAdjacentTrailing(pattern.ppat_loc, trailing);
  var rest = match$1[1];
  attach(t.trailing, pattern.ppat_loc, trailing);
  if (isBlockExpr(exprOpt)) {
    return walkExpr(exprOpt, t, rest);
  }
  var match$2 = partitionByLoc(rest, exprOpt.pexp_loc);
  attach(t.leading, exprOpt.pexp_loc, match$2[0]);
  walkExpr(exprOpt, t, match$2[1]);
  return attach(t.trailing, exprOpt.pexp_loc, match$2[2]);
}

function walkExprArgument(param, t, comments) {
  var expr = param[1];
  var match = expr.pexp_attributes;
  if (match) {
    var match$1 = match.hd[0];
    if (match$1.txt === "ns.namedArgLoc") {
      var loc = match$1.loc;
      var match$2 = partitionLeadingTrailing(comments, loc);
      attach(t.leading, loc, match$2[0]);
      var match$3 = partitionAdjacentTrailing(loc, match$2[1]);
      attach(t.trailing, loc, match$3[0]);
      var match$4 = partitionByLoc(match$3[1], expr.pexp_loc);
      attach(t.leading, expr.pexp_loc, match$4[0]);
      walkExpr(expr, t, match$4[1]);
      return attach(t.trailing, expr.pexp_loc, match$4[2]);
    }
    
  }
  var match$5 = partitionByLoc(comments, expr.pexp_loc);
  attach(t.leading, expr.pexp_loc, match$5[0]);
  walkExpr(expr, t, match$5[1]);
  return attach(t.trailing, expr.pexp_loc, match$5[2]);
}

function walkCase($$case, t, comments) {
  var match = partitionByLoc(comments, $$case.pc_lhs.ppat_loc);
  walkPattern($$case.pc_lhs, t, List.concat({
            hd: match[0],
            tl: {
              hd: match[1],
              tl: /* [] */0
            }
          }));
  var match$1 = partitionAdjacentTrailing($$case.pc_lhs.ppat_loc, match[2]);
  var rest = match$1[1];
  attach(t.trailing, $$case.pc_lhs.ppat_loc, match$1[0]);
  var expr = $$case.pc_guard;
  var comments$1;
  if (expr !== undefined) {
    var match$2 = partitionByLoc(rest, expr.pexp_loc);
    var inside = match$2[1];
    var before = match$2[0];
    var match$3 = partitionAdjacentTrailing(expr.pexp_loc, match$2[2]);
    var afterExpr = match$3[0];
    if (isBlockExpr(expr)) {
      walkExpr(expr, t, List.concat({
                hd: before,
                tl: {
                  hd: inside,
                  tl: {
                    hd: afterExpr,
                    tl: /* [] */0
                  }
                }
              }));
    } else {
      attach(t.leading, expr.pexp_loc, before);
      walkExpr(expr, t, inside);
      attach(t.trailing, expr.pexp_loc, afterExpr);
    }
    comments$1 = match$3[1];
  } else {
    comments$1 = rest;
  }
  if (isBlockExpr($$case.pc_rhs)) {
    return walkExpr($$case.pc_rhs, t, comments$1);
  }
  var match$4 = partitionByLoc(comments$1, $$case.pc_rhs.pexp_loc);
  attach(t.leading, $$case.pc_rhs.pexp_loc, match$4[0]);
  walkExpr($$case.pc_rhs, t, match$4[1]);
  return attach(t.trailing, $$case.pc_rhs.pexp_loc, match$4[2]);
}

function walkExprRecordRow(param, t, comments) {
  var expr = param[1];
  var longident = param[0];
  var match = partitionLeadingTrailing(comments, longident.loc);
  attach(t.leading, longident.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(longident.loc, match[1]);
  attach(t.trailing, longident.loc, match$1[0]);
  var match$2 = partitionByLoc(match$1[1], expr.pexp_loc);
  attach(t.leading, expr.pexp_loc, match$2[0]);
  walkExpr(expr, t, match$2[1]);
  return attach(t.trailing, expr.pexp_loc, match$2[2]);
}

function walkExtConstr(extConstr, t, comments) {
  var match = partitionLeadingTrailing(comments, extConstr.pext_name.loc);
  attach(t.leading, extConstr.pext_name.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(extConstr.pext_name.loc, match[1]);
  attach(t.trailing, extConstr.pext_name.loc, match$1[0]);
  return walkExtensionConstructorKind(extConstr.pext_kind, t, match$1[1]);
}

function walkExtensionConstructorKind(kind, t, comments) {
  if (kind.TAG === /* Pext_decl */0) {
    var maybeTypExpr = kind._1;
    var rest = walkConstructorArguments(kind._0, t, comments);
    if (maybeTypExpr === undefined) {
      return ;
    }
    var match = partitionByLoc(rest, maybeTypExpr.ptyp_loc);
    attach(t.leading, maybeTypExpr.ptyp_loc, match[0]);
    walkTypExpr(maybeTypExpr, t, match[1]);
    return attach(t.trailing, maybeTypExpr.ptyp_loc, match[2]);
  }
  var longident = kind._0;
  var match$1 = partitionLeadingTrailing(comments, longident.loc);
  attach(t.leading, longident.loc, match$1[0]);
  return attach(t.trailing, longident.loc, match$1[1]);
}

function walkModExpr(modExpr, t, comments) {
  var longident = modExpr.pmod_desc;
  switch (longident.TAG | 0) {
    case /* Pmod_ident */0 :
        var longident$1 = longident._0;
        var match = partitionLeadingTrailing(comments, longident$1.loc);
        attach(t.leading, longident$1.loc, match[0]);
        return attach(t.trailing, longident$1.loc, match[1]);
    case /* Pmod_structure */1 :
        var structure = longident._0;
        if (structure) {
          return walkStructure(structure, t, comments);
        } else {
          return attach(t.inside, modExpr.pmod_loc, comments);
        }
    case /* Pmod_functor */2 :
        var match$1 = modExprFunctor(modExpr);
        var returnModExpr = match$1[1];
        var comments$1 = visitListButContinueWithRemainingComments(undefined, false, (function (param) {
                var modTypeOption = param[2];
                var lbl = param[1];
                if (modTypeOption === undefined) {
                  return lbl.loc;
                }
                var init = lbl.loc;
                return {
                        loc_start: init.loc_start,
                        loc_end: modTypeOption.pmty_loc.loc_end,
                        loc_ghost: init.loc_ghost
                      };
              }), walkModExprParameter, match$1[0], t, comments);
        var match$2 = returnModExpr.pmod_desc;
        if (match$2.TAG === /* Pmod_constraint */4) {
          var modType = match$2._1;
          var modExpr$1 = match$2._0;
          if (modType.pmty_loc.loc_end.pos_cnum <= modExpr$1.pmod_loc.loc_start.pos_cnum) {
            var match$3 = partitionByLoc(comments$1, modType.pmty_loc);
            attach(t.leading, modType.pmty_loc, match$3[0]);
            walkModType(modType, t, match$3[1]);
            var match$4 = partitionAdjacentTrailing(modType.pmty_loc, match$3[2]);
            attach(t.trailing, modType.pmty_loc, match$4[0]);
            var match$5 = partitionByLoc(match$4[1], modExpr$1.pmod_loc);
            attach(t.leading, modExpr$1.pmod_loc, match$5[0]);
            walkModExpr(modExpr$1, t, match$5[1]);
            return attach(t.trailing, modExpr$1.pmod_loc, match$5[2]);
          }
          
        }
        var match$6 = partitionByLoc(comments$1, returnModExpr.pmod_loc);
        attach(t.leading, returnModExpr.pmod_loc, match$6[0]);
        walkModExpr(returnModExpr, t, match$6[1]);
        return attach(t.trailing, returnModExpr.pmod_loc, match$6[2]);
    case /* Pmod_apply */3 :
        var modExprs = modExprApply(modExpr);
        return walkList(undefined, (function (n) {
                      return n.pmod_loc;
                    }), walkModExpr, modExprs, t, comments);
    case /* Pmod_constraint */4 :
        var modtype = longident._1;
        var modexpr = longident._0;
        if (Caml_obj.caml_greaterequal(modtype.pmty_loc.loc_start, modexpr.pmod_loc.loc_end)) {
          var match$7 = partitionByLoc(comments, modexpr.pmod_loc);
          attach(t.leading, modexpr.pmod_loc, match$7[0]);
          walkModExpr(modexpr, t, match$7[1]);
          var match$8 = partitionAdjacentTrailing(modexpr.pmod_loc, match$7[2]);
          attach(t.trailing, modexpr.pmod_loc, match$8[0]);
          var match$9 = partitionByLoc(match$8[1], modtype.pmty_loc);
          attach(t.leading, modtype.pmty_loc, match$9[0]);
          walkModType(modtype, t, match$9[1]);
          return attach(t.trailing, modtype.pmty_loc, match$9[2]);
        }
        var match$10 = partitionByLoc(comments, modtype.pmty_loc);
        attach(t.leading, modtype.pmty_loc, match$10[0]);
        walkModType(modtype, t, match$10[1]);
        var match$11 = partitionAdjacentTrailing(modtype.pmty_loc, match$10[2]);
        attach(t.trailing, modtype.pmty_loc, match$11[0]);
        var match$12 = partitionByLoc(match$11[1], modexpr.pmod_loc);
        attach(t.leading, modexpr.pmod_loc, match$12[0]);
        walkModExpr(modexpr, t, match$12[1]);
        return attach(t.trailing, modexpr.pmod_loc, match$12[2]);
    case /* Pmod_unpack */5 :
        var expr = longident._0;
        var match$13 = partitionByLoc(comments, expr.pexp_loc);
        attach(t.leading, expr.pexp_loc, match$13[0]);
        walkExpr(expr, t, match$13[1]);
        return attach(t.trailing, expr.pexp_loc, match$13[2]);
    case /* Pmod_extension */6 :
        return walkExtension(longident._0, t, comments);
    
  }
}

function walkModExprParameter(parameter, t, comments) {
  var modTypeOption = parameter[2];
  var lbl = parameter[1];
  var match = partitionLeadingTrailing(comments, lbl.loc);
  var trailing = match[1];
  attach(t.leading, lbl.loc, match[0]);
  if (modTypeOption === undefined) {
    return attach(t.trailing, lbl.loc, trailing);
  }
  var match$1 = partitionAdjacentTrailing(lbl.loc, trailing);
  attach(t.trailing, lbl.loc, match$1[0]);
  var match$2 = partitionByLoc(match$1[1], modTypeOption.pmty_loc);
  attach(t.leading, modTypeOption.pmty_loc, match$2[0]);
  walkModType(modTypeOption, t, match$2[1]);
  return attach(t.trailing, modTypeOption.pmty_loc, match$2[2]);
}

function walkModType(modType, t, comments) {
  var signature = modType.pmty_desc;
  switch (signature.TAG | 0) {
    case /* Pmty_signature */1 :
        var signature$1 = signature._0;
        if (signature$1) {
          return walkSignature(signature$1, t, comments);
        } else {
          return attach(t.inside, modType.pmty_loc, comments);
        }
    case /* Pmty_functor */2 :
        var match = functorType(modType);
        var returnModType = match[1];
        var comments$1 = visitListButContinueWithRemainingComments(undefined, false, (function (param) {
                var modTypeOption = param[2];
                var lbl = param[1];
                if (modTypeOption === undefined) {
                  return lbl.loc;
                }
                if (lbl.txt === "_") {
                  return modTypeOption.pmty_loc;
                }
                var init = lbl.loc;
                return {
                        loc_start: init.loc_start,
                        loc_end: modTypeOption.pmty_loc.loc_end,
                        loc_ghost: init.loc_ghost
                      };
              }), walkModTypeParameter, match[0], t, comments);
        var match$1 = partitionByLoc(comments$1, returnModType.pmty_loc);
        attach(t.leading, returnModType.pmty_loc, match$1[0]);
        walkModType(returnModType, t, match$1[1]);
        return attach(t.trailing, returnModType.pmty_loc, match$1[2]);
    case /* Pmty_with */3 :
        var modType$1 = signature._0;
        var match$2 = partitionByLoc(comments, modType$1.pmty_loc);
        attach(t.leading, modType$1.pmty_loc, match$2[0]);
        walkModType(modType$1, t, match$2[1]);
        return attach(t.trailing, modType$1.pmty_loc, match$2[2]);
    case /* Pmty_typeof */4 :
        var modExpr = signature._0;
        var match$3 = partitionByLoc(comments, modExpr.pmod_loc);
        attach(t.leading, modExpr.pmod_loc, match$3[0]);
        walkModExpr(modExpr, t, match$3[1]);
        return attach(t.trailing, modExpr.pmod_loc, match$3[2]);
    case /* Pmty_extension */5 :
        return walkExtension(signature._0, t, comments);
    case /* Pmty_ident */0 :
    case /* Pmty_alias */6 :
        break;
    
  }
  var longident = signature._0;
  var match$4 = partitionLeadingTrailing(comments, longident.loc);
  attach(t.leading, longident.loc, match$4[0]);
  return attach(t.trailing, longident.loc, match$4[1]);
}

function walkModTypeParameter(param, t, comments) {
  var modTypeOption = param[2];
  var lbl = param[1];
  var match = partitionLeadingTrailing(comments, lbl.loc);
  var trailing = match[1];
  attach(t.leading, lbl.loc, match[0]);
  if (modTypeOption === undefined) {
    return attach(t.trailing, lbl.loc, trailing);
  }
  var match$1 = partitionAdjacentTrailing(lbl.loc, trailing);
  attach(t.trailing, lbl.loc, match$1[0]);
  var match$2 = partitionByLoc(match$1[1], modTypeOption.pmty_loc);
  attach(t.leading, modTypeOption.pmty_loc, match$2[0]);
  walkModType(modTypeOption, t, match$2[1]);
  return attach(t.trailing, modTypeOption.pmty_loc, match$2[2]);
}

function walkPattern(_pat, t, comments) {
  while(true) {
    var pat = _pat;
    var patterns = pat.ppat_desc;
    if (comments === /* [] */0) {
      return ;
    }
    var exit = 0;
    if (typeof patterns === "number") {
      return ;
    }
    switch (patterns.TAG | 0) {
      case /* Ppat_alias */1 :
          var alias = patterns._1;
          var pat$1 = patterns._0;
          var match = partitionByLoc(comments, pat$1.ppat_loc);
          var leading = match[0];
          attach(t.leading, pat$1.ppat_loc, leading);
          walkPattern(pat$1, t, match[1]);
          var match$1 = partitionAdjacentTrailing(pat$1.ppat_loc, match[2]);
          attach(t.leading, pat$1.ppat_loc, leading);
          attach(t.trailing, pat$1.ppat_loc, match$1[0]);
          var match$2 = partitionLeadingTrailing(match$1[1], alias.loc);
          attach(t.leading, alias.loc, match$2[0]);
          return attach(t.trailing, alias.loc, match$2[1]);
      case /* Ppat_tuple */4 :
          var patterns$1 = patterns._0;
          if (patterns$1) {
            return walkList(undefined, (function (n) {
                          return n.ppat_loc;
                        }), walkPattern, patterns$1, t, comments);
          }
          break;
      case /* Ppat_construct */5 :
          var constr = patterns._0;
          var match$3 = constr.txt;
          var exit$1 = 0;
          switch (match$3.TAG | 0) {
            case /* Lident */0 :
                switch (match$3._0) {
                  case "::" :
                      return walkList(undefined, (function (n) {
                                    return n.ppat_loc;
                                  }), walkPattern, collectListPatterns(/* [] */0, pat), t, comments);
                  case "()" :
                  case "[]" :
                      break;
                  default:
                    exit$1 = 3;
                }
                break;
            case /* Ldot */1 :
            case /* Lapply */2 :
                exit$1 = 3;
                break;
            
          }
          if (exit$1 === 3) {
            var pat$2 = patterns._1;
            if (pat$2 !== undefined) {
              var match$4 = partitionLeadingTrailing(comments, constr.loc);
              attach(t.leading, constr.loc, match$4[0]);
              var match$5 = partitionAdjacentTrailing(constr.loc, match$4[1]);
              attach(t.trailing, constr.loc, match$5[0]);
              var match$6 = partitionByLoc(match$5[1], pat$2.ppat_loc);
              attach(t.leading, pat$2.ppat_loc, match$6[0]);
              walkPattern(pat$2, t, match$6[1]);
              return attach(t.trailing, pat$2.ppat_loc, match$6[2]);
            }
            var match$7 = partitionLeadingTrailing(comments, constr.loc);
            attach(t.leading, constr.loc, match$7[0]);
            return attach(t.trailing, constr.loc, match$7[1]);
          }
          break;
      case /* Ppat_variant */6 :
          var pat$3 = patterns._1;
          if (pat$3 === undefined) {
            return ;
          }
          _pat = pat$3;
          continue ;
      case /* Ppat_record */7 :
          return walkList(undefined, (function (param) {
                        var init = param[0].loc;
                        return {
                                loc_start: init.loc_start,
                                loc_end: param[1].ppat_loc.loc_end,
                                loc_ghost: init.loc_ghost
                              };
                      }), walkPatternRecordRow, patterns._0, t, comments);
      case /* Ppat_array */8 :
          var patterns$2 = patterns._0;
          if (patterns$2) {
            return walkList(undefined, (function (n) {
                          return n.ppat_loc;
                        }), walkPattern, patterns$2, t, comments);
          }
          break;
      case /* Ppat_or */9 :
          return walkList(undefined, (function (pattern) {
                        return pattern.ppat_loc;
                      }), (function (pattern) {
                        return function (param, param$1) {
                          return walkPattern(pattern, param, param$1);
                        };
                      }), Res_parsetree_viewer.collectOrPatternChain(pat), t, comments);
      case /* Ppat_constraint */10 :
          var typ = patterns._1;
          var pattern = patterns._0;
          var match$8 = partitionByLoc(comments, pattern.ppat_loc);
          attach(t.leading, pattern.ppat_loc, match$8[0]);
          walkPattern(pattern, t, match$8[1]);
          var match$9 = partitionAdjacentTrailing(pattern.ppat_loc, match$8[2]);
          attach(t.trailing, pattern.ppat_loc, match$9[0]);
          var match$10 = partitionByLoc(match$9[1], typ.ptyp_loc);
          attach(t.leading, typ.ptyp_loc, match$10[0]);
          walkTypExpr(typ, t, match$10[1]);
          return attach(t.trailing, typ.ptyp_loc, match$10[2]);
      case /* Ppat_type */11 :
          return ;
      case /* Ppat_unpack */13 :
          var stringLoc = patterns._0;
          var match$11 = partitionLeadingTrailing(comments, stringLoc.loc);
          attach(t.leading, stringLoc.loc, match$11[0]);
          return attach(t.trailing, stringLoc.loc, match$11[1]);
      case /* Ppat_lazy */12 :
      case /* Ppat_exception */14 :
          exit = 2;
          break;
      case /* Ppat_extension */15 :
          return walkExtension(patterns._0, t, comments);
      default:
        return ;
    }
    if (exit === 2) {
      var pattern$1 = patterns._0;
      var match$12 = partitionByLoc(comments, pattern$1.ppat_loc);
      attach(t.leading, pattern$1.ppat_loc, match$12[0]);
      walkPattern(pattern$1, t, match$12[1]);
      return attach(t.trailing, pattern$1.ppat_loc, match$12[2]);
    }
    return attach(t.inside, pat.ppat_loc, comments);
  };
}

function walkPatternRecordRow(row, t, comments) {
  var longident = row[0];
  var ident = longident.txt;
  switch (ident.TAG | 0) {
    case /* Lident */0 :
        var match = row[1].ppat_desc;
        if (typeof match !== "number" && match.TAG === /* Ppat_var */0 && ident._0 === match._0.txt) {
          var longidentLoc = longident.loc;
          var match$1 = partitionLeadingTrailing(comments, longidentLoc);
          attach(t.leading, longidentLoc, match$1[0]);
          return attach(t.trailing, longidentLoc, match$1[1]);
        }
        break;
    case /* Ldot */1 :
    case /* Lapply */2 :
        break;
    
  }
  var pattern = row[1];
  var match$2 = partitionLeadingTrailing(comments, longident.loc);
  attach(t.leading, longident.loc, match$2[0]);
  var match$3 = partitionAdjacentTrailing(longident.loc, match$2[1]);
  attach(t.trailing, longident.loc, match$3[0]);
  var match$4 = partitionByLoc(match$3[1], pattern.ppat_loc);
  attach(t.leading, pattern.ppat_loc, match$4[0]);
  walkPattern(pattern, t, match$4[1]);
  return attach(t.trailing, pattern.ppat_loc, match$4[2]);
}

function walkTypExpr(typ, t, comments) {
  var typexprs = typ.ptyp_desc;
  if (comments === /* [] */0) {
    return ;
  }
  if (typeof typexprs === "number") {
    return ;
  }
  switch (typexprs.TAG | 0) {
    case /* Ptyp_arrow */1 :
        var match = arrowType(typ);
        var typexpr = match[2];
        var comments$1 = walkTypeParameters(match[1], t, comments);
        var match$1 = partitionByLoc(comments$1, typexpr.ptyp_loc);
        attach(t.leading, typexpr.ptyp_loc, match$1[0]);
        walkTypExpr(typexpr, t, match$1[1]);
        return attach(t.trailing, typexpr.ptyp_loc, match$1[2]);
    case /* Ptyp_tuple */2 :
        return walkList(undefined, (function (n) {
                      return n.ptyp_loc;
                    }), walkTypExpr, typexprs._0, t, comments);
    case /* Ptyp_constr */3 :
        var longident = typexprs._0;
        var match$2 = partitionLeadingTrailing(comments, longident.loc);
        var match$3 = partitionAdjacentTrailing(longident.loc, comments);
        attach(t.leading, longident.loc, match$2[0]);
        attach(t.trailing, longident.loc, match$3[0]);
        return walkList(undefined, (function (n) {
                      return n.ptyp_loc;
                    }), walkTypExpr, typexprs._1, t, match$3[1]);
    case /* Ptyp_object */4 :
        return walkTypObjectFields(typexprs._0, t, comments);
    case /* Ptyp_alias */6 :
        var typexpr$1 = typexprs._0;
        var match$4 = partitionByLoc(comments, typexpr$1.ptyp_loc);
        attach(t.leading, typexpr$1.ptyp_loc, match$4[0]);
        walkTypExpr(typexpr$1, t, match$4[1]);
        return attach(t.trailing, typexpr$1.ptyp_loc, match$4[2]);
    case /* Ptyp_poly */8 :
        var typexpr$2 = typexprs._1;
        var comments$2 = visitListButContinueWithRemainingComments(undefined, false, (function (n) {
                return n.loc;
              }), (function (longident, t, comments) {
                var match = partitionLeadingTrailing(comments, longident.loc);
                attach(t.leading, longident.loc, match[0]);
                return attach(t.trailing, longident.loc, match[1]);
              }), typexprs._0, t, comments);
        var match$5 = partitionByLoc(comments$2, typexpr$2.ptyp_loc);
        attach(t.leading, typexpr$2.ptyp_loc, match$5[0]);
        walkTypExpr(typexpr$2, t, match$5[1]);
        return attach(t.trailing, typexpr$2.ptyp_loc, match$5[2]);
    case /* Ptyp_package */9 :
        return walkPackageType(typexprs._0, t, comments);
    case /* Ptyp_extension */10 :
        return walkExtension(typexprs._0, t, comments);
    default:
      return ;
  }
}

function walkTypObjectFields(fields, t, comments) {
  return walkList(undefined, (function (field) {
                if (field.TAG !== /* Otag */0) {
                  return $$Location.none;
                }
                var init = field._0.loc;
                return {
                        loc_start: init.loc_start,
                        loc_end: field._2.ptyp_loc.loc_end,
                        loc_ghost: init.loc_ghost
                      };
              }), walkTypObjectField, fields, t, comments);
}

function walkTypObjectField(field, t, comments) {
  if (field.TAG !== /* Otag */0) {
    return ;
  }
  var typexpr = field._2;
  var lbl = field._0;
  var match = partitionLeadingTrailing(comments, lbl.loc);
  attach(t.leading, lbl.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(lbl.loc, match[1]);
  attach(t.trailing, lbl.loc, match$1[0]);
  var match$2 = partitionByLoc(match$1[1], typexpr.ptyp_loc);
  attach(t.leading, typexpr.ptyp_loc, match$2[0]);
  walkTypExpr(typexpr, t, match$2[1]);
  return attach(t.trailing, typexpr.ptyp_loc, match$2[2]);
}

function walkTypeParameters(typeParameters, t, comments) {
  return visitListButContinueWithRemainingComments(undefined, false, (function (param) {
                var typexpr = param[2];
                var match = typexpr.ptyp_attributes;
                if (!match) {
                  return typexpr.ptyp_loc;
                }
                var match$1 = match.hd[0];
                if (match$1.txt !== "ns.namedArgLoc") {
                  return typexpr.ptyp_loc;
                }
                var loc = match$1.loc;
                return {
                        loc_start: loc.loc_start,
                        loc_end: typexpr.ptyp_loc.loc_end,
                        loc_ghost: loc.loc_ghost
                      };
              }), walkTypeParameter, typeParameters, t, comments);
}

function walkTypeParameter(param, t, comments) {
  var typexpr = param[2];
  var match = partitionByLoc(comments, typexpr.ptyp_loc);
  attach(t.leading, typexpr.ptyp_loc, match[0]);
  walkTypExpr(typexpr, t, match[1]);
  return attach(t.trailing, typexpr.ptyp_loc, match[2]);
}

function walkPackageType(packageType, t, comments) {
  var longident = packageType[0];
  var match = partitionLeadingTrailing(comments, longident.loc);
  attach(t.leading, longident.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(longident.loc, match[1]);
  attach(t.trailing, longident.loc, match$1[0]);
  return walkPackageConstraints(packageType[1], t, match$1[1]);
}

function walkPackageConstraints(packageConstraints, t, comments) {
  return walkList(undefined, (function (param) {
                var init = param[0].loc;
                return {
                        loc_start: init.loc_start,
                        loc_end: param[1].ptyp_loc.loc_end,
                        loc_ghost: init.loc_ghost
                      };
              }), walkPackageConstraint, packageConstraints, t, comments);
}

function walkPackageConstraint(packageConstraint, t, comments) {
  var typexpr = packageConstraint[1];
  var longident = packageConstraint[0];
  var match = partitionLeadingTrailing(comments, longident.loc);
  attach(t.leading, longident.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(longident.loc, match[1]);
  attach(t.trailing, longident.loc, match$1[0]);
  var match$2 = partitionByLoc(match$1[1], typexpr.ptyp_loc);
  attach(t.leading, typexpr.ptyp_loc, match$2[0]);
  walkTypExpr(typexpr, t, match$2[1]);
  return attach(t.trailing, typexpr.ptyp_loc, match$2[2]);
}

function walkExtension(extension, t, comments) {
  var id = extension[0];
  var match = partitionLeadingTrailing(comments, id.loc);
  attach(t.leading, id.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(id.loc, match[1]);
  attach(t.trailing, id.loc, match$1[0]);
  return walkPayload(extension[1], t, match$1[1]);
}

function walkAttribute(param, t, comments) {
  var id = param[0];
  var match = partitionLeadingTrailing(comments, id.loc);
  attach(t.leading, id.loc, match[0]);
  var match$1 = partitionAdjacentTrailing(id.loc, match[1]);
  attach(t.trailing, id.loc, match$1[0]);
  return walkPayload(param[1], t, match$1[1]);
}

function walkPayload(payload, t, comments) {
  if (payload.TAG === /* PStr */0) {
    return walkStructure(payload._0, t, comments);
  }
  
}

var $$Comment;

var Doc;

export {
  $$Comment ,
  Doc ,
  make ,
  copy ,
  empty ,
  log ,
  attach ,
  partitionByLoc ,
  partitionLeadingTrailing ,
  partitionByOnSameLine ,
  partitionAdjacentTrailing ,
  collectListPatterns ,
  collectListExprs ,
  arrowType ,
  modExprApply ,
  modExprFunctor ,
  functorType ,
  funExpr ,
  isBlockExpr ,
  isIfThenElseExpr ,
  walkStructure ,
  walkStructureItem ,
  walkValueDescription ,
  walkTypeExtension ,
  walkIncludeDeclaration ,
  walkModuleTypeDeclaration ,
  walkModuleBinding ,
  walkSignature ,
  walkSignatureItem ,
  walkIncludeDescription ,
  walkModuleDeclaration ,
  walkList ,
  visitListButContinueWithRemainingComments ,
  walkValueBindings ,
  walkOpenDescription ,
  walkTypeDeclarations ,
  walkTypeParam ,
  walkTypeDeclaration ,
  walkLabelDeclarations ,
  walkLabelDeclaration ,
  walkConstructorDeclarations ,
  walkConstructorDeclaration ,
  walkConstructorArguments ,
  walkValueBinding ,
  walkExpr ,
  walkExprPararameter ,
  walkExprArgument ,
  walkCase ,
  walkExprRecordRow ,
  walkExtConstr ,
  walkExtensionConstructorKind ,
  walkModExpr ,
  walkModExprParameter ,
  walkModType ,
  walkModTypeParameter ,
  walkPattern ,
  walkPatternRecordRow ,
  walkTypExpr ,
  walkTypObjectFields ,
  walkTypObjectField ,
  walkTypeParameters ,
  walkTypeParameter ,
  walkPackageType ,
  walkPackageConstraints ,
  walkPackageConstraint ,
  walkExtension ,
  walkAttribute ,
  walkPayload ,
  
}
/* empty Not a pure module */
