/*** 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 ***/

// 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
stmts (unique int id: @stmt, 
       int kind: int ref,
       int parent: @stmtparent ref, 
       int idx: int ref,
       varchar(900) tostring: string ref);

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

@stmtparent = @stmt | @toplevel | @functionexpr | @arrowfunctionexpr;
@stmt_container = @toplevel | @function;

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
;

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

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

// expressions
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: @expr ref);
       
enclosingStmt (int expr: @expr ref,
       int stmt: @stmt ref);

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

arraySize (int ae: @expr ref, // @arrayexpr or @arraypattern
       int sz: int ref);

isDelegating (int yield: @yieldexpr ref);

@exprorstmt = @expr | @stmt;
@exprparent = @exprorstmt | @property;

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 = @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
;

@varref = @vardecl | @varaccess;

@identifier = @label | @varref;

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

@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;

// 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;

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

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

@parameterized = @function | @catchclause;

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

// variables
variables (unique int id: @variable,
        varchar(900) name: string ref,
        int scope: @scope ref);

isArgumentsObject (int id: @variable ref);

bind (int id: @varaccess ref,
      int decl: @variable ref);

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

// properties in object literals, property patterns in object patterns, and method declarations in classes
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;

@property_parent = @objexpr | @objectpattern | @class | @jsxelement;
@property_accessor = @property_getter | @property_setter;

isComputed (int id: @property ref);
isMethod   (int id: @property ref);
isStatic   (int id: @property 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);
  
// regular expressions
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;

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_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;

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

// tokens
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
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,
      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 | @class;

@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
    | @class
    | @xmllocatable;

hasLocation (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 | @class;

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);
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 (int tag: @jsdoc_tag ref, varchar(900) text: string ref);
jsdoc_tag_names (int tag: @jsdoc_tag ref, varchar(900) text: string ref);

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
;

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
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 (int node: @yaml_node ref,
              varchar(900) anchor: string ref);

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

yaml_scalars (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);

// classes
classes (unique int id: @class, int decl: @classdecl ref, varchar(900) tostring: string ref);

@classdecl = @classdeclstmt | @classexpr;

/* 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;

/* Last updated 2017/02/22. */