CoolFace
Apppublic

sourav-das/stem-separator

sourceHugging Facemitupdated 6mo agoView on Hugging Face
3likes
scopes.ts346 linesDownload Raw Back to src
1import { StringReader, StringWriter } from './strings';2import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq';3 4const EMPTY: any[] = [];5 6type Line = number;7type Column = number;8type Kind = number;9type Name = number;10type Var = number;11type SourcesIndex = number;12type ScopesIndex = number;13 14type Mix<A, B, O> = (A & O) | (B & O);15 16export type OriginalScope = Mix<17  [Line, Column, Line, Column, Kind],18  [Line, Column, Line, Column, Kind, Name],19  { vars: Var[] }20>;21 22export type GeneratedRange = Mix<23  [Line, Column, Line, Column],24  [Line, Column, Line, Column, SourcesIndex, ScopesIndex],25  {26    callsite: CallSite | null;27    bindings: Binding[];28    isScope: boolean;29  }30>;31export type CallSite = [SourcesIndex, Line, Column];32type Binding = BindingExpressionRange[];33export type BindingExpressionRange = [Name] | [Name, Line, Column];34 35export function decodeOriginalScopes(input: string): OriginalScope[] {36  const { length } = input;37  const reader = new StringReader(input);38  const scopes: OriginalScope[] = [];39  const stack: OriginalScope[] = [];40  let line = 0;41 42  for (; reader.pos < length; reader.pos++) {43    line = decodeInteger(reader, line);44    const column = decodeInteger(reader, 0);45 46    if (!hasMoreVlq(reader, length)) {47      const last = stack.pop()!;48      last[2] = line;49      last[3] = column;50      continue;51    }52 53    const kind = decodeInteger(reader, 0);54    const fields = decodeInteger(reader, 0);55    const hasName = fields & 0b0001;56 57    const scope: OriginalScope = (58      hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]59    ) as OriginalScope;60 61    let vars: Var[] = EMPTY;62    if (hasMoreVlq(reader, length)) {63      vars = [];64      do {65        const varsIndex = decodeInteger(reader, 0);66        vars.push(varsIndex);67      } while (hasMoreVlq(reader, length));68    }69    scope.vars = vars;70 71    scopes.push(scope);72    stack.push(scope);73  }74 75  return scopes;76}77 78export function encodeOriginalScopes(scopes: OriginalScope[]): string {79  const writer = new StringWriter();80 81  for (let i = 0; i < scopes.length; ) {82    i = _encodeOriginalScopes(scopes, i, writer, [0]);83  }84 85  return writer.flush();86}87 88function _encodeOriginalScopes(89  scopes: OriginalScope[],90  index: number,91  writer: StringWriter,92  state: [93    number, // GenColumn94  ],95): number {96  const scope = scopes[index];97  const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope;98 99  if (index > 0) writer.write(comma);100 101  state[0] = encodeInteger(writer, startLine, state[0]);102  encodeInteger(writer, startColumn, 0);103  encodeInteger(writer, kind, 0);104 105  const fields = scope.length === 6 ? 0b0001 : 0;106  encodeInteger(writer, fields, 0);107  if (scope.length === 6) encodeInteger(writer, scope[5], 0);108 109  for (const v of vars) {110    encodeInteger(writer, v, 0);111  }112 113  for (index++; index < scopes.length; ) {114    const next = scopes[index];115    const { 0: l, 1: c } = next;116    if (l > endLine || (l === endLine && c >= endColumn)) {117      break;118    }119    index = _encodeOriginalScopes(scopes, index, writer, state);120  }121 122  writer.write(comma);123  state[0] = encodeInteger(writer, endLine, state[0]);124  encodeInteger(writer, endColumn, 0);125 126  return index;127}128 129export function decodeGeneratedRanges(input: string): GeneratedRange[] {130  const { length } = input;131  const reader = new StringReader(input);132  const ranges: GeneratedRange[] = [];133  const stack: GeneratedRange[] = [];134 135  let genLine = 0;136  let definitionSourcesIndex = 0;137  let definitionScopeIndex = 0;138  let callsiteSourcesIndex = 0;139  let callsiteLine = 0;140  let callsiteColumn = 0;141  let bindingLine = 0;142  let bindingColumn = 0;143 144  do {145    const semi = reader.indexOf(';');146    let genColumn = 0;147 148    for (; reader.pos < semi; reader.pos++) {149      genColumn = decodeInteger(reader, genColumn);150 151      if (!hasMoreVlq(reader, semi)) {152        const last = stack.pop()!;153        last[2] = genLine;154        last[3] = genColumn;155        continue;156      }157 158      const fields = decodeInteger(reader, 0);159      const hasDefinition = fields & 0b0001;160      const hasCallsite = fields & 0b0010;161      const hasScope = fields & 0b0100;162 163      let callsite: CallSite | null = null;164      let bindings: Binding[] = EMPTY;165      let range: GeneratedRange;166      if (hasDefinition) {167        const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex);168        definitionScopeIndex = decodeInteger(169          reader,170          definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0,171        );172 173        definitionSourcesIndex = defSourcesIndex;174        range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex] as GeneratedRange;175      } else {176        range = [genLine, genColumn, 0, 0] as GeneratedRange;177      }178 179      range.isScope = !!hasScope;180 181      if (hasCallsite) {182        const prevCsi = callsiteSourcesIndex;183        const prevLine = callsiteLine;184        callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex);185        const sameSource = prevCsi === callsiteSourcesIndex;186        callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0);187        callsiteColumn = decodeInteger(188          reader,189          sameSource && prevLine === callsiteLine ? callsiteColumn : 0,190        );191 192        callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn];193      }194      range.callsite = callsite;195 196      if (hasMoreVlq(reader, semi)) {197        bindings = [];198        do {199          bindingLine = genLine;200          bindingColumn = genColumn;201          const expressionsCount = decodeInteger(reader, 0);202          let expressionRanges: BindingExpressionRange[];203          if (expressionsCount < -1) {204            expressionRanges = [[decodeInteger(reader, 0)]];205            for (let i = -1; i > expressionsCount; i--) {206              const prevBl = bindingLine;207              bindingLine = decodeInteger(reader, bindingLine);208              bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0);209              const expression = decodeInteger(reader, 0);210              expressionRanges.push([expression, bindingLine, bindingColumn]);211            }212          } else {213            expressionRanges = [[expressionsCount]];214          }215          bindings.push(expressionRanges);216        } while (hasMoreVlq(reader, semi));217      }218      range.bindings = bindings;219 220      ranges.push(range);221      stack.push(range);222    }223 224    genLine++;225    reader.pos = semi + 1;226  } while (reader.pos < length);227 228  return ranges;229}230 231export function encodeGeneratedRanges(ranges: GeneratedRange[]): string {232  if (ranges.length === 0) return '';233 234  const writer = new StringWriter();235 236  for (let i = 0; i < ranges.length; ) {237    i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]);238  }239 240  return writer.flush();241}242 243function _encodeGeneratedRanges(244  ranges: GeneratedRange[],245  index: number,246  writer: StringWriter,247  state: [248    number, // GenLine249    number, // GenColumn250    number, // DefSourcesIndex251    number, // DefScopesIndex252    number, // CallSourcesIndex253    number, // CallLine254    number, // CallColumn255  ],256): number {257  const range = ranges[index];258  const {259    0: startLine,260    1: startColumn,261    2: endLine,262    3: endColumn,263    isScope,264    callsite,265    bindings,266  } = range;267 268  if (state[0] < startLine) {269    catchupLine(writer, state[0], startLine);270    state[0] = startLine;271    state[1] = 0;272  } else if (index > 0) {273    writer.write(comma);274  }275 276  state[1] = encodeInteger(writer, range[1], state[1]);277 278  const fields =279    (range.length === 6 ? 0b0001 : 0) | (callsite ? 0b0010 : 0) | (isScope ? 0b0100 : 0);280  encodeInteger(writer, fields, 0);281 282  if (range.length === 6) {283    const { 4: sourcesIndex, 5: scopesIndex } = range;284    if (sourcesIndex !== state[2]) {285      state[3] = 0;286    }287    state[2] = encodeInteger(writer, sourcesIndex, state[2]);288    state[3] = encodeInteger(writer, scopesIndex, state[3]);289  }290 291  if (callsite) {292    const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite!;293    if (sourcesIndex !== state[4]) {294      state[5] = 0;295      state[6] = 0;296    } else if (callLine !== state[5]) {297      state[6] = 0;298    }299    state[4] = encodeInteger(writer, sourcesIndex, state[4]);300    state[5] = encodeInteger(writer, callLine, state[5]);301    state[6] = encodeInteger(writer, callColumn, state[6]);302  }303 304  if (bindings) {305    for (const binding of bindings) {306      if (binding.length > 1) encodeInteger(writer, -binding.length, 0);307      const expression = binding[0][0];308      encodeInteger(writer, expression, 0);309      let bindingStartLine = startLine;310      let bindingStartColumn = startColumn;311      for (let i = 1; i < binding.length; i++) {312        const expRange = binding[i];313        bindingStartLine = encodeInteger(writer, expRange[1]!, bindingStartLine);314        bindingStartColumn = encodeInteger(writer, expRange[2]!, bindingStartColumn);315        encodeInteger(writer, expRange[0]!, 0);316      }317    }318  }319 320  for (index++; index < ranges.length; ) {321    const next = ranges[index];322    const { 0: l, 1: c } = next;323    if (l > endLine || (l === endLine && c >= endColumn)) {324      break;325    }326    index = _encodeGeneratedRanges(ranges, index, writer, state);327  }328 329  if (state[0] < endLine) {330    catchupLine(writer, state[0], endLine);331    state[0] = endLine;332    state[1] = 0;333  } else {334    writer.write(comma);335  }336  state[1] = encodeInteger(writer, endColumn, state[1]);337 338  return index;339}340 341function catchupLine(writer: StringWriter, lastLine: number, line: number) {342  do {343    writer.write(semicolon);344  } while (++lastLine < line);345}346