anchor.diff:  -type form()         :: atom().
   -type position()     :: {non_neg_integer(), non_neg_integer()}.
   
  --type otp_version() :: 14|15|16|17.
  +-type otp_version() :: 14|15|16|17|18|19.
   -spec(make_forms_by_version([syntaxTree()], otp_version()) ->syntaxTree()).
   -spec compile(binary() | [atom() | [any()] | char()]) -> {'error',atom() | {_,[any(),...]}}.
   -spec compile(binary() | [atom() | [any()] | char()],[any()]) -> {'error',atom() | {_,[any(),...]}}.
  
positive.code:     TransformFun(Tokens).
  
  
  parse_tokens(Tokens, FileName) ->
      parse_tokens(Tokens, [], [], [], FileName).
  
  parse_tokens([], _, FormAcc, ErrorAcc, _) ->
      {lists:reverse(FormAcc), lists:reverse(ErrorAcc)};
  parse_tokens([{dot, _}=Token|Rest], TokenAcc, FormAcc, ErrorAcc, FileName) ->
      case erl_parse:parse_form(lists:reverse([Token|TokenAcc])) of
          {ok, {attribute, _, file, {NewFileName, _Line}} = AbsForm} ->
              parse_tokens(Rest, [], [AbsForm|FormAcc], ErrorAcc, NewFileName);
          {ok, {attribute, La, record, {Record, Fields}} = AbsForm} ->
              case epp:normalize_typed_record_fields(Fields) of
                  {typed, NewFields} ->
                      parse_tokens(Rest, [], lists:reverse([
                                  {attribute, La, record, {Record, NewFields}},
                                  {attribute, La, type, {{record, Record}, Fields, []}}],
                              FormAcc), ErrorAcc, FileName);
                  not_typed ->
                      parse_tokens(Rest, [], [AbsForm|FormAcc], ErrorAcc, FileName)
              end;
          {ok, AbsForm} ->
              parse_tokens(Rest, [], [AbsForm|FormAcc], ErrorAcc, FileName);
          {error, ErrorInfo} ->
              parse_tokens(Rest, [], FormAcc, [{FileName, ErrorInfo}|ErrorAcc], FileName)
      end;
  parse_tokens([{eof, Location}], TokenAcc, FormAcc, ErrorAcc, FileName) ->
      parse_tokens([], TokenAcc, [{eof, Location}|FormAcc], ErrorAcc, FileName);
  parse_tokens([Token|Rest], TokenAcc, FormAcc, ErrorAcc, FileName) ->
      parse_tokens(Rest, [Token|TokenAcc], FormAcc, ErrorAcc, FileName).
  
  scan_transform(FileContents) ->
      scan_transform(FileContents, {1, 1}).
  
negative.code:     % has a bug that chokes on {Line, Col} locations in typed record
      % definitions
      TokensWithOnlyLineNumbers = flatten_token_locations(ProcessedTokens),
  
      Version = otp_version(),
      {Forms, Errors}           = parse_tokens(TokensWithOnlyLineNumbers, FileName, Version),
      parse_has_errors(TokenInfo, Forms, Errors).
  
  
  