/*** Standard fragments ***/

/** Files and folders **/

@location = @location_default;
 
locations_default(unique int id: @location_default,
          int file: @file ref,
          int beginLine: int ref,
          int beginColumn: int ref,
          int endLine: int ref,
          int endColumn: int ref
         );
 
@sourceline = @locatable;
 
numlines(int element_id: @sourceline ref,
         int num_lines: int ref,
         int num_code: int ref,
         int num_comment: int ref
        );
 
 
/*
  fromSource(0) = unknown,
  fromSource(1) = from source,
  fromSource(2) = from library
*/
files(unique int id: @file,
      varchar(900) name: string ref,
      varchar(900) simple: string ref,
      varchar(900) ext: string ref,
      int fromSource: int ref);
 
folders(unique int id: @folder,
        varchar(900) name: string ref,
        varchar(900) simple: string ref);
 
 
@container = @folder | @file ;
 
 
containerparent(int parent: @container ref,
                unique int child: @container ref);

/** Duplicate code **/

duplicateCode(
  unique int id : @duplication,
  varchar(900) relativePath : string ref,
  int equivClass : int ref);
 
similarCode(
  unique int id : @similarity,
  varchar(900) relativePath : string ref,
  int equivClass : int ref);
 
@duplication_or_similarity = @duplication | @similarity;
 
tokens(
  int id : @duplication_or_similarity ref,
  int offset : int ref,
  int beginLine : int ref,
  int beginColumn : int ref,
  int endLine : int ref,
  int endColumn : int ref);

/** External data **/

externalData(
  int id : @externalDataElement,
  varchar(900) path : string ref,
  int column: int ref,
  varchar(900) value : string ref
);
 
snapshotDate(unique date snapshotDate : date ref);
 
sourceLocationPrefix(varchar(900) prefix : string ref);

/** Version control data **/

svnentries(
  int id : @svnentry,
  varchar(500) revision : string ref,
  varchar(500) author : string ref,
  date revisionDate : date ref,
  int changeSize : int ref
);
 
svnaffectedfiles(
  int id : @svnentry ref,
  int file : @file ref,
  varchar(500) action : string ref
);
 
svnentrymsg(
  int id : @svnentry ref,
  varchar(500) message : string ref
);
 
svnchurn(
  int commit : @svnentry ref,
  int file : @file ref,
  int addedLines : int ref,
  int deletedLines : int ref
);


/*** JavaScript-specific part ***/

filetype(
  int file: @file ref,
  string filetype: string ref
)

// top-level code fragments
toplevels (unique int id: @toplevel,
           int kind: int ref);

isExterns (int toplevel: @toplevel ref);

case @toplevel.kind of
   0 = @script
|  1 = @inline_script
|  2 = @event_handler
|  3 = @javascript_url;

isModule (int tl: @toplevel ref);
isNodejs (int tl: @toplevel ref);

// statements
#keyset[parent, idx]
stmts (unique int id: @stmt, 
       int kind: int ref,
       int parent: @stmtparent ref, 
       int idx: int ref,
       varchar(900) tostring: string ref);

stmtContainers (unique int stmt: @stmt ref,
       int container: @stmt_container ref);
       
jumpTargets (unique int jump: @stmt ref,
       int target: @stmt ref);

@stmtparent = @stmt | @toplevel | @functionexpr | @arrowfunctionexpr;
@stmt_container = @toplevel | @function | @namespacedeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration;

case @stmt.kind of
   0 = @emptystmt
|  1 = @blockstmt
|  2 = @exprstmt
|  3 = @ifstmt
|  4 = @labeledstmt
|  5 = @breakstmt
|  6 = @continuestmt
|  7 = @withstmt
|  8 = @switchstmt
|  9 = @returnstmt
| 10 = @throwstmt
| 11 = @trystmt
| 12 = @whilestmt
| 13 = @dowhilestmt
| 14 = @forstmt
| 15 = @forinstmt
| 16 = @debuggerstmt
| 17 = @functiondeclstmt
| 18 = @vardeclstmt
| 19 = @case
| 20 = @catchclause
| 21 = @forofstmt
| 22 = @constdeclstmt
| 23 = @letstmt
| 24 = @legacy_letstmt
| 25 = @foreachstmt
| 26 = @classdeclstmt
| 27 = @importdeclaration
| 28 = @exportalldeclaration
| 29 = @exportdefaultdeclaration
| 30 = @exportnameddeclaration
| 31 = @namespacedeclaration
| 32 = @importequalsdeclaration
| 33 = @exportassigndeclaration
| 34 = @interfacedeclaration
| 35 = @typealiasdeclaration
| 36 = @enumdeclaration
| 37 = @externalmoduledeclaration
| 38 = @exportasnamespacedeclaration
| 39 = @globalaugmentationdeclaration
;

@declstmt = @vardeclstmt | @constdeclstmt | @letstmt | @legacy_letstmt;

@exportdeclaration = @exportalldeclaration | @exportdefaultdeclaration | @exportnameddeclaration;

@namespacedefinition = @namespacedeclaration | @enumdeclaration;
@typedefinition = @classdefinition | @interfacedeclaration | @enumdeclaration | @typealiasdeclaration | @enum_member;

isInstantiated(unique int decl: @namespacedeclaration ref);

@declarablestmt = @declstmt | @namespacedeclaration | @classdeclstmt | @functiondeclstmt | @enumdeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration;
hasDeclareKeyword(unique int stmt: @declarablestmt ref);

isForAwaitOf(unique int forof: @forofstmt ref);

// expressions
#keyset[parent, idx]
exprs (unique int id: @expr,
       int kind: int ref,
       int parent: @exprparent ref,
       int idx: int ref,
       varchar(900) tostring: string ref);

literals (varchar(900) value: string ref,
       varchar(900) raw: string ref,
       unique int expr: @exprortype ref);
       
enclosingStmt (unique int expr: @exprortype ref,
       int stmt: @stmt ref);

exprContainers (unique int expr: @exprortype ref,
       int container: @stmt_container ref);

arraySize (unique int ae: @arraylike ref,
       int sz: int ref);

isDelegating (int yield: @yieldexpr ref);

@exprorstmt = @expr | @stmt;
@exprortype = @expr | @typeexpr;
@exprparent = @exprorstmt | @property | @functiontypeexpr;
@arraylike = @arrayexpr | @arraypattern;

case @expr.kind of
   0 = @label
|  1 = @nullliteral
|  2 = @booleanliteral
|  3 = @numberliteral
|  4 = @stringliteral
|  5 = @regexpliteral
|  6 = @thisexpr
|  7 = @arrayexpr
|  8 = @objexpr
|  9 = @functionexpr
| 10 = @seqexpr
| 11 = @conditionalexpr
| 12 = @newexpr
| 13 = @callexpr
| 14 = @dotexpr
| 15 = @indexexpr
| 16 = @negexpr
| 17 = @plusexpr
| 18 = @lognotexpr
| 19 = @bitnotexpr
| 20 = @typeofexpr
| 21 = @voidexpr
| 22 = @deleteexpr
| 23 = @eqexpr
| 24 = @neqexpr
| 25 = @eqqexpr
| 26 = @neqqexpr
| 27 = @ltexpr
| 28 = @leexpr
| 29 = @gtexpr
| 30 = @geexpr
| 31 = @lshiftexpr
| 32 = @rshiftexpr
| 33 = @urshiftexpr
| 34 = @addexpr
| 35 = @subexpr
| 36 = @mulexpr
| 37 = @divexpr
| 38 = @modexpr
| 39 = @bitorexpr
| 40 = @xorexpr
| 41 = @bitandexpr
| 42 = @inexpr
| 43 = @instanceofexpr
| 44 = @logandexpr
| 45 = @logorexpr
| 47 = @assignexpr
| 48 = @assignaddexpr
| 49 = @assignsubexpr
| 50 = @assignmulexpr
| 51 = @assigndivexpr
| 52 = @assignmodexpr
| 53 = @assignlshiftexpr
| 54 = @assignrshiftexpr
| 55 = @assignurshiftexpr
| 56 = @assignorexpr
| 57 = @assignxorexpr
| 58 = @assignandexpr
| 59 = @preincexpr
| 60 = @postincexpr
| 61 = @predecexpr
| 62 = @postdecexpr
| 63 = @parexpr
| 64 = @vardeclarator
| 65 = @arrowfunctionexpr
| 66 = @spreadelement
| 67 = @arraypattern
| 68 = @objectpattern
| 69 = @yieldexpr
| 70 = @taggedtemplateexpr
| 71 = @templateliteral
| 72 = @templateelement
| 73 = @arraycomprehensionexpr
| 74 = @generatorexpr
| 75 = @forincomprehensionblock
| 76 = @forofcomprehensionblock
| 77 = @legacy_letexpr
| 78 = @vardecl
| 79 = @proper_varaccess
| 80 = @classexpr
| 81 = @superexpr
| 82 = @newtargetexpr
| 83 = @namedimportspecifier
| 84 = @importdefaultspecifier
| 85 = @importnamespacespecifier
| 86 = @namedexportspecifier
| 87 = @expexpr
| 88 = @assignexpexpr
| 89 = @jsxelement
| 90 = @jsxqualifiedname
| 91 = @jsxemptyexpr
| 92 = @awaitexpr
| 93 = @functionsentexpr
| 94 = @decorator
| 95 = @exportdefaultspecifier
| 96 = @exportnamespacespecifier
| 97 = @bindexpr
| 98 = @externalmodulereference
| 99 = @dynamicimport
| 100 = @expressionwithtypearguments
| 101 = @prefixtypeassertion
| 102 = @astypeassertion
| 103 = @export_varaccess
| 104 = @decorator_list
| 105 = @non_null_assertion
| 106 = @bigintliteral
;

@varaccess = @proper_varaccess | @export_varaccess;
@varref = @vardecl | @varaccess;

@identifier = @label | @varref | @typeidentifier;

@literal = @nullliteral | @booleanliteral | @numberliteral | @stringliteral | @regexpliteral | @bigintliteral;

@propaccess = @dotexpr | @indexexpr;

@invokeexpr = @newexpr | @callexpr;

@unaryexpr = @negexpr | @plusexpr | @lognotexpr | @bitnotexpr | @typeofexpr | @voidexpr | @deleteexpr | @spreadelement;

@equalitytest = @eqexpr | @neqexpr | @eqqexpr | @neqqexpr;

@comparison = @equalitytest | @ltexpr | @leexpr | @gtexpr | @geexpr;

@binaryexpr = @comparison | @lshiftexpr | @rshiftexpr | @urshiftexpr | @addexpr | @subexpr | @mulexpr | @divexpr | @modexpr | @expexpr | @bitorexpr | @xorexpr | @bitandexpr | @inexpr | @instanceofexpr | @logandexpr | @logorexpr;

@assignment = @assignexpr | @assignaddexpr | @assignsubexpr | @assignmulexpr | @assigndivexpr | @assignmodexpr | @assignexpexpr | @assignlshiftexpr | @assignrshiftexpr | @assignurshiftexpr | @assignorexpr | @assignxorexpr | @assignandexpr;

@updateexpr = @preincexpr | @postincexpr | @predecexpr | @postdecexpr;

@pattern = @varref | @arraypattern | @objectpattern;

@comprehensionexpr = @arraycomprehensionexpr | @generatorexpr;

@comprehensionblock = @forincomprehensionblock | @forofcomprehensionblock;

@importspecifier = @namedimportspecifier | @importdefaultspecifier | @importnamespacespecifier;

@exportspecifier = @namedexportspecifier | @exportdefaultspecifier | @exportnamespacespecifier;

@typeassertion = @astypeassertion | @prefixtypeassertion;

@classdefinition = @classdeclstmt | @classexpr;
@interfacedefinition = @interfacedeclaration | @interfacetypeexpr;
@classorinterface = @classdefinition | @interfacedefinition;

@lexical_decl = @vardecl | @typedecl;
@lexical_access = @varaccess | @localtypeaccess | @localvartypeaccess | @localnamespaceaccess;
@lexical_ref = @lexical_decl | @lexical_access;

// scopes
scopes (unique int id: @scope,
        int kind: int ref);

case @scope.kind of
   0 = @globalscope
|  1 = @functionscope
|  2 = @catchscope
|  3 = @modulescope
|  4 = @blockscope
|  5 = @forscope
|  6 = @forinscope // for-of scopes work the same as for-in scopes
|  7 = @comprehensionblockscope
|  8 = @classexprscope
|  9 = @namespacescope
| 10 = @classdeclscope
| 11 = @interfacescope
| 12 = @typealiasscope
| 13 = @mappedtypescope
| 14 = @enumscope
| 15 = @externalmodulescope
| 16 = @conditionaltypescope;

scopenodes (unique int node: @ast_node ref,
            int scope: @scope ref);
            
scopenesting (unique int inner: @scope ref,
              int outer: @scope ref);

// functions
@function = @functiondeclstmt | @functionexpr | @arrowfunctionexpr;

@parameterized = @function | @catchclause;
@type_parameterized = @function | @classorinterface | @typealiasdeclaration | @mappedtypeexpr | @infertypeexpr;

isGenerator (int fun: @function ref);
hasRestParameter (int fun: @function ref);
isAsync (int fun: @function ref);

// variables and lexically scoped type names
#keyset[scope, name]
variables (unique int id: @variable,
           varchar(900) name: string ref,
           int scope: @scope ref);

#keyset[scope, name]
local_type_names (unique int id: @local_type_name,
                  varchar(900) name: string ref,
                  int scope: @scope ref);

#keyset[scope, name]
local_namespace_names (unique int id: @local_namespace_name,
                       varchar(900) name: string ref,
                       int scope: @scope ref);

isArgumentsObject (int id: @variable ref);

@lexical_name = @variable | @local_type_name | @local_namespace_name;

@bind_id = @varaccess | @localvartypeaccess;
bind (unique int id: @bind_id ref,
      int decl: @variable ref);

decl (unique int id: @vardecl ref,
      int decl: @variable ref);

@typebind_id = @localtypeaccess | @export_varaccess;
typebind (unique int id: @typebind_id ref,
          int decl: @local_type_name ref);

@typedecl_id = @typedecl | @vardecl;
typedecl (unique int id: @typedecl_id ref,
          int decl: @local_type_name ref);

namespacedecl (unique int id: @vardecl ref,
               int decl: @local_namespace_name ref);

@namespacebind_id = @localnamespaceaccess | @export_varaccess;
namespacebind (unique int id: @namespacebind_id ref,
               int decl: @local_namespace_name ref);


// properties in object literals, property patterns in object patterns, and method declarations in classes
#keyset[parent, index]
properties (unique int id: @property,
            int parent: @property_parent ref,
            int index: int ref,
            int kind: int ref,
            varchar(900) tostring: string ref);

case @property.kind of
  0 = @value_property
| 1 = @property_getter
| 2 = @property_setter
| 3 = @jsx_attribute
| 4 = @function_call_signature
| 5 = @constructor_call_signature
| 6 = @index_signature
| 7 = @enum_member
| 8 = @proper_field
| 9 = @parameter_field
;

@property_parent = @objexpr | @objectpattern | @classdefinition | @jsxelement | @interfacedefinition | @enumdeclaration;
@property_accessor = @property_getter | @property_setter;
@call_signature = @function_call_signature | @constructor_call_signature;
@field = @proper_field | @parameter_field;
@field_or_vardeclarator = @field | @vardeclarator;

isComputed (int id: @property ref);
isMethod   (int id: @property ref);
isStatic   (int id: @property ref);
isAbstractMember (int id: @property ref);
isConstEnum (int id: @enumdeclaration ref);
isAbstractClass (int id: @classdeclstmt ref);

hasPublicKeyword (int id: @property ref);
hasPrivateKeyword (int id: @property ref);
hasProtectedKeyword (int id: @property ref);
hasReadonlyKeyword (int id: @property ref);
isOptionalMember (int id: @property ref);
hasDefiniteAssignmentAssertion (int id: @field_or_vardeclarator ref);

#keyset[constructor, param_index]
parameter_fields(
  unique int field: @parameter_field ref,
  int constructor: @functionexpr ref,
  int param_index: int ref
);

// types
#keyset[parent, idx]
typeexprs (
  unique int id: @typeexpr,
  int kind: int ref,
  int parent: @typeexpr_parent ref,
  int idx: int ref,
  varchar(900) tostring: string ref
);

case @typeexpr.kind of
  0 = @localtypeaccess
| 1 = @typedecl
| 2 = @keywordtypeexpr
| 3 = @stringliteraltypeexpr
| 4 = @numberliteraltypeexpr
| 5 = @booleanliteraltypeexpr
| 6 = @arraytypeexpr
| 7 = @uniontypeexpr
| 8 = @indexedaccesstypeexpr
| 9 = @intersectiontypeexpr
| 10 = @parenthesizedtypeexpr
| 11 = @tupletypeexpr
| 12 = @keyoftypeexpr
| 13 = @qualifiedtypeaccess
| 14 = @generictypeexpr
| 15 = @typelabel
| 16 = @typeoftypeexpr
| 17 = @localvartypeaccess
| 18 = @qualifiedvartypeaccess
| 19 = @thisvartypeaccess
| 20 = @istypeexpr
| 21 = @interfacetypeexpr
| 22 = @typeparameter
| 23 = @plainfunctiontypeexpr
| 24 = @constructortypeexpr
| 25 = @localnamespaceaccess
| 26 = @qualifiednamespaceaccess
| 27 = @mappedtypeexpr
| 28 = @conditionaltypeexpr
| 29 = @infertypeexpr
| 30 = @importtypeaccess
| 31 = @importnamespaceaccess
| 32 = @importvartypeaccess
| 33 = @optionaltypeexpr
| 34 = @resttypeexpr
;

@typeref = @typeaccess | @typedecl;
@typeidentifier = @typedecl | @localtypeaccess | @typelabel | @localvartypeaccess | @localnamespaceaccess;
@typeexpr_parent = @expr | @stmt | @property | @typeexpr;
@literaltypeexpr = @stringliteraltypeexpr | @numberliteraltypeexpr | @booleanliteraltypeexpr;
@typeaccess = @localtypeaccess | @qualifiedtypeaccess | @importtypeaccess;
@vartypeaccess = @localvartypeaccess | @qualifiedvartypeaccess | @thisvartypeaccess | @importvartypeaccess;
@namespaceaccess = @localnamespaceaccess | @qualifiednamespaceaccess | @importnamespaceaccess;
@importtypeexpr = @importtypeaccess | @importnamespaceaccess | @importvartypeaccess;

@functiontypeexpr = @plainfunctiontypeexpr | @constructortypeexpr;

// types
types (
  unique int id: @type,
  int kind: int ref,
  varchar(900) tostring: string ref
);

#keyset[parent, idx]
type_child (
  int child: @type ref,
  int parent: @type ref,
  int idx: int ref
);

case @type.kind of
  0 = @anytype
| 1 = @stringtype
| 2 = @numbertype
| 3 = @uniontype
| 4 = @truetype
| 5 = @falsetype
| 6 = @typereference
| 7 = @objecttype
| 8 = @canonicaltypevariabletype
| 9 = @typeoftype
| 10 = @voidtype
| 11 = @undefinedtype
| 12 = @nulltype
| 13 = @nevertype
| 14 = @plainsymboltype
| 15 = @uniquesymboltype
| 16 = @objectkeywordtype
| 17 = @intersectiontype
| 18 = @tupletype
| 19 = @lexicaltypevariabletype
| 20 = @thistype
| 21 = @numberliteraltype
| 22 = @stringliteraltype
| 23 = @unknowntype
;

@booleanliteraltype = @truetype | @falsetype;
@symboltype = @plainsymboltype | @uniquesymboltype;
@unionorintersectiontype = @uniontype | @intersectiontype;
@typevariabletype = @canonicaltypevariabletype | @lexicaltypevariabletype;

@typed_ast_node = @expr | @typeexpr | @function;
ast_node_type(
  unique int node: @typed_ast_node ref, 
  int typ: @type ref);

invoke_expr_signature(
  unique int node: @invokeexpr ref,
  int sig: @signature_type ref
);

invoke_expr_overload_index(
  unique int node: @invokeexpr ref,
  int index: int ref
);

symbols (
  unique int id: @symbol,
  int kind: int ref,
  varchar(900) name: string ref
);

symbol_parent (
  unique int symbol: @symbol ref,
  int parent: @symbol ref
);

symbol_module (
  int symbol: @symbol ref,
  varchar(900) moduleName: string ref
);

symbol_global (
  int symbol: @symbol ref,
  varchar(900) globalName: string ref
);

case @symbol.kind of
  0 = @root_symbol
| 1 = @member_symbol
| 2 = @other_symbol
;

@type_with_symbol = @typereference | @typevariabletype | @typeoftype | @uniquesymboltype;
@ast_node_with_symbol = @typedefinition | @namespacedefinition | @toplevel | @typeaccess | @namespaceaccess | @vardecl | @function | @invokeexpr;

ast_node_symbol(
  unique int node: @ast_node_with_symbol ref,
  int symbol: @symbol ref);

type_symbol(
  unique int typ: @type_with_symbol ref,
  int symbol: @symbol ref);

#keyset[typ, name]
type_property(
  int typ: @type ref,
  varchar(900) name: string ref,
  int propertyType: @type ref);

@literaltype = @stringliteraltype | @numberliteraltype | @booleanliteraltype;
@type_with_literal_value = @stringliteraltype | @numberliteraltype;
type_literal_value(
  unique int typ: @type_with_literal_value ref,
  varchar(900) value: string ref);

signature_types (
  unique int id: @signature_type,
  int kind: int ref,
  varchar(900) tostring: string ref,
  int type_parameters: int ref,
  int required_params: int ref
);

case @signature_type.kind of
  0 = @function_signature_type
| 1 = @constructor_signature_type
;

#keyset[typ, kind, index]
type_contains_signature (
  int typ: @type ref,
  int kind: int ref,  // constructor/call/index
  int index: int ref, // ordering of overloaded signatures
  int sig: @signature_type ref
);

#keyset[parent, index]
signature_contains_type (
  int child: @type ref,
  int parent: @signature_type ref,
  int index: int ref
);

#keyset[sig, index]
signature_parameter_name (
  int sig: @signature_type ref,
  int index: int ref,
  varchar(900) name: string ref
);

number_index_type (
  unique int baseType: @type ref,
  int propertyType: @type ref
);

string_index_type (
  unique int baseType: @type ref,
  int propertyType: @type ref
);

base_type_names(
  int typeName: @symbol ref,
  int baseTypeName: @symbol ref
);

self_types(
  int typeName: @symbol ref,
  int selfType: @typereference ref
);

tuple_type_min_length(
  unique int typ: @type ref,
  int minLength: int ref
);

tuple_type_rest(
  unique int typ: @type ref
);

// comments
comments (unique int id: @comment,
          int kind: int ref,
          int toplevel: @toplevel ref,
          varchar(900) text: string ref,
          varchar(900) tostring: string ref);

case @comment.kind of
  0 = @slashslashcomment
| 1 = @slashstarcomment
| 2 = @doccomment
| 3 = @htmlcommentstart
| 4 = @htmlcommentend;

@htmlcomment = @htmlcommentstart | @htmlcommentend;
@linecomment = @slashslashcomment | @htmlcomment;
@blockcomment = @slashstarcomment | @doccomment;

// source lines
lines (unique int id: @line,
       int toplevel: @toplevel ref,
       varchar(900) text: string ref,
       varchar(2) terminator: string ref);
indentation (int file: @file ref,
            int lineno: int ref,
            varchar(1) indentChar: string ref,
            int indentDepth: int ref);

// JavaScript parse errors
jsParseErrors (unique int id: @js_parse_error,
        int toplevel: @toplevel ref,
        varchar(900) message: string ref,
        varchar(900) line: string ref);
  
// regular expressions
#keyset[parent, idx]
regexpterm (unique int id: @regexpterm,
        int kind: int ref,
        int parent: @regexpparent ref,
        int idx: int ref,
        varchar(900) tostring: string ref);
        
@regexpparent = @regexpterm | @regexpliteral;

case @regexpterm.kind of
   0 = @regexp_alt
|  1 = @regexp_seq
|  2 = @regexp_caret
|  3 = @regexp_dollar
|  4 = @regexp_wordboundary
|  5 = @regexp_nonwordboundary
|  6 = @regexp_positive_lookahead
|  7 = @regexp_negative_lookahead
|  8 = @regexp_star
|  9 = @regexp_plus
| 10 = @regexp_opt
| 11 = @regexp_range
| 12 = @regexp_dot
| 13 = @regexp_group
| 14 = @regexp_normal_char
| 15 = @regexp_hex_escape
| 16 = @regexp_unicode_escape
| 17 = @regexp_dec_escape
| 18 = @regexp_oct_escape
| 19 = @regexp_ctrl_escape
| 20 = @regexp_char_class_escape
| 21 = @regexp_id_escape
| 22 = @regexp_backref
| 23 = @regexp_char_class
| 24 = @regexp_char_range
| 25 = @regexp_positive_lookbehind
| 26 = @regexp_negative_lookbehind
| 27 = @regexp_unicode_property_escape;

regexpParseErrors (unique int id: @regexp_parse_error,
    int regexp: @regexpterm ref,
    varchar(900) message: string ref);

@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range;
@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape;
@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape;
@regexp_constant = @regexp_normal_char | @regexp_char_escape;
@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead;
@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind;
@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind;

isGreedy (int id: @regexp_quantifier ref);
rangeQuantifierLowerBound (unique int id: @regexp_range ref, int lo: int ref);
rangeQuantifierUpperBound (unique int id: @regexp_range ref, int hi: int ref);
isCapture (unique int id: @regexp_group ref, int number: int ref);
isNamedCapture (unique int id: @regexp_group ref, string name: string ref);
isInverted (int id: @regexp_char_class ref);
regexpConstValue (unique int id: @regexp_constant ref, varchar(1) value: string ref);
charClassEscape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref);
backref (unique int id: @regexp_backref ref, int value: int ref);
namedBackref (unique int id: @regexp_backref ref, string name: string ref);
unicodePropertyEscapeName (unique int id: @regexp_unicode_property_escape ref, string name: string ref);
unicodePropertyEscapeValue (unique int id: @regexp_unicode_property_escape ref, string value: string ref);

// tokens
#keyset[toplevel, idx]
tokeninfo (unique int id: @token,
    int kind: int ref,
    int toplevel: @toplevel ref,
    int idx: int ref,
    varchar(900) value: string ref);

case @token.kind of
  0 = @token_eof
| 1 = @token_null_literal
| 2 = @token_boolean_literal
| 3 = @token_numeric_literal
| 4 = @token_string_literal
| 5 = @token_regular_expression
| 6 = @token_identifier
| 7 = @token_keyword
| 8 = @token_punctuator;

// associate comments with the token immediately following them (which may be EOF)
next_token (int comment: @comment ref, int token: @token ref);

// JSON
#keyset[parent, idx]
json (unique int id: @json_value,
      int kind: int ref,
      int parent: @json_parent ref,
      int idx: int ref,
      varchar(900) tostring: string ref);

json_literals (varchar(900) value: string ref,
      varchar(900) raw: string ref,
      unique int expr: @json_value ref);

json_properties (int obj: @json_object ref,
      varchar(900) property: string ref,
      int value: @json_value ref);

json_errors (unique int id: @json_parse_error,
      varchar(900) message: string ref);

case @json_value.kind of
  0 = @json_null
| 1 = @json_boolean
| 2 = @json_number
| 3 = @json_string
| 4 = @json_array
| 5 = @json_object;

@json_parent = @json_object | @json_array | @file;

// locations
@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr;

@locatable = @file 
    | @ast_node
    | @comment
    | @line
    | @js_parse_error | @regexp_parse_error | @json_parse_error
    | @regexpterm
    | @json_value
    | @token
    | @cfg_node
    | @jsdoc | @jsdoc_type_expr | @jsdoc_tag
    | @yaml_node | @yaml_error
    | @xmllocatable;

hasLocation (unique int locatable: @locatable ref,
    int location: @location ref);

// CFG
entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref);
exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref);
guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref);
case @guard_node.kind of
  0 = @falsy_guard
| 1 = @truthy_guard;
@condition_guard = @falsy_guard | @truthy_guard;

@synthetic_cfg_node = @entry_node | @exit_node | @guard_node;
@cfg_node = @synthetic_cfg_node | @exprparent;

successor (int pred: @cfg_node ref, int succ: @cfg_node ref);

// JSDoc comments
jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref);
#keyset[parent, idx]
jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref,
            int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref);
jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref);
jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref);

#keyset[parent, idx]
jsdoc_type_exprs (unique int id: @jsdoc_type_expr,
                  int kind: int ref,
                  int parent: @jsdoc_type_expr_parent ref,
                  int idx: int ref,
                  varchar(900) tostring: string ref);
case @jsdoc_type_expr.kind of
    0 = @jsdoc_any_type_expr
|   1 = @jsdoc_null_type_expr
|   2 = @jsdoc_undefined_type_expr
|   3 = @jsdoc_unknown_type_expr
|   4 = @jsdoc_void_type_expr
|   5 = @jsdoc_named_type_expr
|   6 = @jsdoc_applied_type_expr
|   7 = @jsdoc_nullable_type_expr
|   8 = @jsdoc_non_nullable_type_expr
|   9 = @jsdoc_record_type_expr
|  10 = @jsdoc_array_type_expr
|  11 = @jsdoc_union_type_expr
|  12 = @jsdoc_function_type_expr
|  13 = @jsdoc_optional_type_expr
|  14 = @jsdoc_rest_type_expr
;

#keyset[id, idx]
jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref);
jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref);
jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref);

@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag;

jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref);

// YAML
#keyset[parent, idx]
yaml (unique int id: @yaml_node,
      int kind: int ref,
      int parent: @yaml_node_parent ref,
      int idx: int ref,
      varchar(900) tag: string ref,
      varchar(900) tostring: string ref);

case @yaml_node.kind of
  0 = @yaml_scalar_node
| 1 = @yaml_mapping_node
| 2 = @yaml_sequence_node
| 3 = @yaml_alias_node
;

@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node;

@yaml_node_parent = @yaml_collection_node | @file;

yaml_anchors (unique int node: @yaml_node ref,
              varchar(900) anchor: string ref);

yaml_aliases (unique int alias: @yaml_alias_node ref,
              varchar(900) target: string ref);

yaml_scalars (unique int scalar: @yaml_scalar_node ref,
              int style: int ref,
              varchar(900) value: string ref);

yaml_errors (unique int id: @yaml_error,
             varchar(900) message: string ref);

/* XML Files */

xmlEncoding(
  unique int id: @file ref,
  varchar(900) encoding: string ref
);

xmlDTDs(
  unique int id: @xmldtd,
  varchar(900) root: string ref,
  varchar(900) publicId: string ref,
  varchar(900) systemId: string ref,
  int fileid: @file ref
);

xmlElements(
  unique int id: @xmlelement,
  varchar(900) name: string ref,
  int parentid: @xmlparent ref,
  int idx: int ref,
  int fileid: @file ref
);

xmlAttrs(
  unique int id: @xmlattribute,
  int elementid: @xmlelement ref,
  varchar(900) name: string ref,
  varchar(3600) value: string ref,
  int idx: int ref,
  int fileid: @file ref
);

xmlNs(
  int id: @xmlnamespace,
  varchar(900) prefixName: string ref,
  varchar(900) URI: string ref,
  int fileid: @file ref
);

xmlHasNs(
  int elementId: @xmlnamespaceable ref,
  int nsId: @xmlnamespace ref,
  int fileid: @file ref
);

xmlComments(
  unique int id: @xmlcomment,
  varchar(3600) text: string ref,
  int parentid: @xmlparent ref,
  int fileid: @file ref
);

xmlChars(
  unique int id: @xmlcharacters,
  varchar(3600) text: string ref,
  int parentid: @xmlparent ref,
  int idx: int ref,
  int isCDATA: int ref,
  int fileid: @file ref
);

@xmlparent = @file | @xmlelement;
@xmlnamespaceable = @xmlelement | @xmlattribute;

xmllocations(
  int xmlElement: @xmllocatable ref,
  int location: @location_default ref
);

@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;

@dataflownode = @expr | @functiondeclstmt | @classdeclstmt | @namespacedeclaration | @enumdeclaration | @property;

/* Last updated 2017/07/11. */
