# TODO: Project Specific Lints # # 1. Anything that implements ASTNode must be suffixed by AST # 2. Make sure {VariableDeclaration}AST because it's suffixed by AST implements VariableDeclaration schema { query: RootSchemaQuery } directive @filter( """ Name of the filter operation to perform. """ op: String! """ List of string operands for the operator. """ value: [String!] ) on FIELD | INLINE_FRAGMENT directive @tag( """ Name to apply to the given property field. """ name: String ) on FIELD directive @output( """ What to designate the output field generated from this property field. """ name: String ) on FIELD directive @optional on FIELD directive @recurse( """ Recurse up to this many times on this edge. A depth of 1 produces the current vertex and its immediate neighbors along the given edge. """ depth: Int! ) on FIELD directive @fold on FIELD directive @transform( """ Name of the transformation operation to perform. """ op: String! ) on FIELD """ All the possible data types where querying can begin in this API. """ type RootSchemaQuery { File: [File!]! } type File { last_path_part: PathPart! path_part: [PathPart!]! class: [ClassAST!] type_annotation: [TypeAnnotationAST!] interface: [InterfaceAST!] jsx_element: [JSXElementAST!] import: [ImportAST!] variable_declaration: [VariableDeclarationAST!] function: [Function!] expression: [Expression!] ast_node: [ASTNode!]! } type PathPart { name: String! is_first: Boolean! is_last: Boolean! next: PathPart prev: PathPart } type SpecificImport { """ Name in original file """ original_name: String! """ Aliased name, in "import {X as Y} from 'source'", this would be Y, but in "import {A} from 'source'" this owuld be A """ local_name: String! span: Span! } type DefaultImport { local_name: String! span: Span! } interface Import { from_path: String! entire_span: Span! """ Only gives specific imports, not default imports or (import *)'s """ specific_import: [SpecificImport!]! default_import: [DefaultImport!]! } interface AssignmentType implements HasSpan { """ if the left side has exactly one name. No destructuring. ie: const apple = 1; let orange = 'a'; var blue; """ assignment_to_variable_name: String span: Span! } """ A single VariableDeclarator. (const/let/var)! If you have multiple variables assigned at once with commas, this will fire once per assignment. """ interface VariableDeclaration implements HasSpan { left: AssignmentType! # HasSpan span: Span! } type SearchParameter { key: String! value: String! } type URL { search_parameter: [SearchParameter!]! } interface JSXAttribute { name: String! """ Only non-null if the string can be trivially coerced to a constant string ie , , and """ value_as_constant_string: String """ If the value is an expression ie: or """ value_as_expression: Expression """ If value_as_constant_string is not null, then this will try to parse that to a url """ value_as_url: URL span: Span! } type JSXSpreadAttribute { span: Span! } type JSXOpeningElement { """ Smallest equivalent, removes spaces """ name: String! """ non-spread attributes """ attribute: [JSXAttribute!]! spread_attribute: [JSXSpreadAttribute!]! attribute_count: Int! span: Span! } """ interface A extends B.C {} B.C is always more than one identifier. """ type MemberExtend implements InterfaceExtend { span: Span! } """ interface A extends B {} B is always just one identifier. """ type SimpleExtend implements InterfaceExtend { span: Span! } interface InterfaceExtend { span: Span! } interface Interface { name: String! extend: [InterfaceExtend!]! name_span: Span! entire_span: Span! } type ClassProperty { is_abstract: Boolean! """ public | private | protected """ accessibility: String span: Span! } type ClassMethod { is_abstract: Boolean! """ public | private | protected """ accessibility: String span: Span! } interface Class { name: String is_abstract: Boolean! """ if the extended expression is an identifier, this will give you the name """ extended_class_name: String constructor: [ClassMethod!]! method: [ClassMethod!]! getter: [ClassMethod!]! setter: [ClassMethod!]! property: [ClassProperty!]! # TODO: some way to fall back from name_span to entire_class span """ Doesn't exist on anonymous classes """ name_span: Span entire_class_span: Span! } interface Type { span: Span! } interface TypeAnnotation implements HasSpan { type: Type! span: Span! } type Span { start: Int! end: Int! str: String! } type JSXSpreadChild { span: Span! } type JSXExpressionContainer { span: Span! } type JSXFragment { span: Span! } type JSXText { text: String! span: Span! } interface ArrayElement implements HasSpan { # HasSpan span: Span! } type ArrayElementAST implements HasSpan & ASTNode { # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface Array implements HasSpan & Expression { elements: [ArrayElement!] # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type ArrayAST implements HasSpan & Expression & Array & ASTNode { elements: [ArrayElement!] # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } """ If the number has a negative sign before it, it will not be a `NumberLiteral` """ interface NumberLiteral implements HasSpan & Expression { span: Span! """ Nullable if the number is NaN """ number: Float # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! } type NumberLiteralAST implements HasSpan & ASTNode & Expression & NumberLiteral { span: Span! """ Nullable if the number is NaN """ number: Float # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! } # Expression interface JSXElement implements Expression & HasSpan { opening_element: JSXOpeningElement! """ There are many types of children, however this will only yield JSXElement children """ child_element: [JSXElement!]! child_text: [JSXText!]! child_fragment: [JSXFragment!]! child_expression_container: [JSXExpressionContainer!]! child_spread: [JSXSpreadChild!]! child_count: Int! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } interface ObjectProperty implements HasSpan { # HasSpan span: Span! } interface SpreadIntoObject implements ObjectProperty & HasSpan { value: Expression! # HasSpan span: Span! } type SpreadIntoObjectAST implements ASTNode & SpreadIntoObject & ObjectProperty & HasSpan { value: Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface ObjectEntry implements ObjectProperty & HasSpan { key: Expression! value: Expression! # HasSpan span: Span! } type ObjectEntryAST implements ASTNode & ObjectEntry & ObjectProperty & HasSpan { key: Expression! value: Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface ObjectLiteral implements Expression & HasSpan { value(key: String!): Expression entry: [ObjectProperty!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type ObjectLiteralAST implements ObjectLiteral & Expression & HasSpan & ASTNode { value(key: String!): Expression entry: [ObjectProperty!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface Argument implements HasSpan { is_spread: Boolean! """ Will be VarRef if `is_spread` is `true` """ value: Expression! # HasSpan span: Span! } type ArgumentAST implements Argument & HasSpan & ASTNode { is_spread: Boolean! value: Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface FnCall implements Expression & HasSpan { callee: Expression! argument: [Argument!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type FnCallAST implements FnCall & Expression & HasSpan & ASTNode { callee: Expression! argument: [Argument!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } """ Any assignment that isn't a variable declaration, which means no const/let/var. ie: "a = 1;", "a /= 1;", "a += 1;", etc. """ interface Reassignment implements HasSpan & Expression { """ Only nonnull if the left is not an object or array destructuring. examples that this would be usable: "a = 12;", "a.b = 'apple';" """ left_as_expression: Expression right: Expression! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } """ Any assignment that isn't a variable declaration, which means no const/let/var. ie: "a = 1;", "a /= 1;", "a += 1;", etc. """ type ReassignmentAST implements HasSpan & ASTNode & Reassignment & Expression { """ Only nonnull if the left is not an object or array destructuring. examples that this would be usable: "a = 12;", "a.b = 'apple';" """ left_as_expression: Expression right: Expression! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! # ASTNode parent: ASTNode ancestor: [ASTNode!]! } interface Statement implements HasSpan { # HasSpan span: Span! } interface FunctionBody implements HasSpan { statement: [Statement!]! # HasSpan span: Span! } type FunctionBodyAST implements HasSpan & ASTNode & FunctionBody { statement: [Statement!]! # HasSpan span: Span! # ASTNode parent: ASTNode ancestor: [ASTNode!]! } interface Function implements Expression & HasSpan { is_async: Boolean! is_generator: Boolean! """ Does not include rest parameter if it exists. """ parameter: [Parameter]! # Expression """ Only non-null if the string can be trivially coerced to a constant string ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } interface UnaryExpression implements HasSpan & Expression { """ '+' | '-' | '!' | '~' | 'typeof' | 'void' | 'delete' """ operator: String! value: Expression! # Expression """ Only non-null if the string can be trivially coerced to a constant string ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type UnaryExpressionAST implements UnaryExpression & ASTNode & HasSpan & Expression { """ '+' | '-' | '!' | '~' | 'typeof' | 'void' | 'delete' """ operator: String! value: Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression """ Only non-null if the string can be trivially coerced to a constant string ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } interface LogicalExpression implements HasSpan & Expression { """ '||' | '&&' | '??' """ operator: String! left: Expression! right: Expression! # Expression """ Only non-null if the string can be trivially coerced to a constant string ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type LogicalExpressionAST implements LogicalExpression & ASTNode & HasSpan & Expression { """ '||' | '&&' | '??' """ operator: String! left: Expression! right: Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression """ Only non-null if the string can be trivially coerced to a constant string ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type Parameter implements HasSpan { is_readonly: Boolean! assignment: AssignmentType! type_annotation: TypeAnnotation! # HasSpan span: Span! } type ParameterAST implements ASTNode & HasSpan { is_readonly: Boolean! assignment: AssignmentType! type_annotation: TypeAnnotation! # HasSpan span: Span! # ASTNode parent: ASTNode ancestor: [ASTNode!]! } interface ArrowFunction implements Function & HasSpan & Expression { # Function is_async: Boolean! is_generator: Boolean! """ Does not include rest parameter if it exists. """ parameter: [Parameter]! # Expression """ Only non-null if the string can be trivially coerced to a constant string ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type ArrowFunctionAST implements Function & HasSpan & ArrowFunction & ASTNode & Expression { # Function is_async: Boolean! is_generator: Boolean! """ Does not include rest parameter if it exists. """ parameter: [Parameter]! # Expression """ Only non-null if the string can be trivially coerced to a constant string ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! # ASTNode parent: ASTNode ancestor: [ASTNode!]! } """ A function defined in the sourcecode. """ interface FnDeclaration implements Function & HasSpan & Expression { """ If this function is used an an expression, the name can be omitted. ie: "const a = function() {};" """ name: String # Function is_async: Boolean! is_generator: Boolean! """ Does not include rest parameter if it exists. """ parameter: [Parameter]! # Expression """ Only non-null if the string can be trivially coerced to a constant string ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } """ A function defined in the sourcecode. """ type FnDeclarationAST implements Function & ASTNode & FnDeclaration & HasSpan & Expression { name: String # Function is_async: Boolean! is_generator: Boolean! """ Does not include rest parameter if it exists. """ parameter: [Parameter]! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression """ Only non-null if the string can be trivially coerced to a constant string ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } interface VarRef implements HasSpan & Expression { name: String! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type VarRefAST implements HasSpan & Expression & VarRef & ASTNode { name: String! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } """ Only includes strings declared with ' or " not ` """ interface StringLiteral implements HasSpan & Expression { # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } """ Only includes strings declared with ' or " not ` """ type StringLiteralAST implements HasSpan & Expression & ASTNode & StringLiteral { # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } interface TemplateLiteral implements HasSpan & Expression { # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type TemplateLiteralAST implements HasSpan & Expression & TemplateLiteral & ASTNode { # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } interface Name implements HasSpan { name: String! # HasSpan span: Span! } type NameAST implements ASTNode & Name & HasSpan { name: String! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface DotProperty implements HasSpan & Expression { """ In "data.user.name", this would be "data.user" """ called_on: Expression! """ In "data.user.name", this would be "name" """ accessed_property: Name! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type DotPropertyAST implements DotProperty & ASTNode & HasSpan & Expression { """ In "data.user.name", this would be "data.user" """ called_on: Expression! """ In "data.user.name", this would be "name" """ accessed_property: Name! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } interface Expression implements HasSpan { """ Only non-null if the string can be trivially coerced to a constant string ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } interface ExpressionStatement implements Statement & HasSpan { expression: Expression! # HasSpan span: Span! } type ExpressionStatementAST implements Statement & HasSpan & ASTNode & ExpressionStatement { expression: Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface WhileStatement implements Statement & HasSpan { condition: Expression! body: Statement! # HasSpan span: Span! } type WhileStatementAST implements Statement & HasSpan & ASTNode & WhileStatement { condition: Expression! body: Statement! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface DoWhileStatement implements Statement & HasSpan { condition: Expression! body: Statement! # HasSpan span: Span! } type DoWhileStatementAST implements Statement & HasSpan & ASTNode & DoWhileStatement { condition: Expression! body: Statement! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface ForStatement implements Statement & HasSpan { condition: Expression step: Expression! body: Statement! # HasSpan span: Span! } type ForStatementAST implements Statement & HasSpan & ForStatement & ASTNode { condition: Expression step: Expression! body: Statement! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface BlockStatement implements Statement & HasSpan { statement: [Statement!] # HasSpan span: Span! } type BlockStatementAST implements Statement & HasSpan & ASTNode & BlockStatement { statement: [Statement!] # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } interface TernaryExpression implements Expression & HasSpan { condition: Expression! if_true: Expression! if_false: Expression! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type TernaryExpressionAST implements Expression & HasSpan & ASTNode & TernaryExpression { condition: Expression! if_true: Expression! if_false: Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } interface New implements Expression & HasSpan { callee: Expression! argument: [Argument!] # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type NewAST implements Expression & HasSpan & New & ASTNode { callee: Expression! argument: [Argument!] # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } interface Throw implements Expression & HasSpan { to_throw: Expression! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } type ThrowAST implements Expression & HasSpan & Throw & ASTNode { to_throw: Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # HasSpan span: Span! } """ A single VariableDeclarator. (const/let/var)! If you have multiple variables assigned at once with commas, this will fire once per assignment. """ type VariableDeclarationAST implements VariableDeclaration & ASTNode & HasSpan { left: AssignmentType! right: Expression # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } type TypeAnnotationAST implements TypeAnnotation & ASTNode & HasSpan { type: Type! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } type InterfaceAST implements Interface & ASTNode & HasSpan { name: String! extend: [InterfaceExtend!]! name_span: Span! entire_span: Span! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } type ImportAST implements Import & ASTNode & HasSpan { from_path: String! entire_span: Span! """ Only gives specific imports, not default imports or (import *)'s """ specific_import: [SpecificImport!]! default_import: [DefaultImport!]! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } type JSXElementAST implements JSXElement & Expression & ASTNode & HasSpan { opening_element: JSXOpeningElement! """ There are many types of children, however this will only yield JSXElement children """ child_element: [JSXElement!]! child_text: [JSXText!]! child_fragment: [JSXFragment!]! child_expression_container: [JSXExpressionContainer!]! child_spread: [JSXSpreadChild!]! child_count: Int! # Expression as_constant_string: String """ Strips infinite levels of parens unless `strip_all` is `false`. """ strip_parens(strip_all: Boolean): Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } type ClassAST implements ASTNode & Class & HasSpan { name: String is_abstract: Boolean! """ if the extended expression is an identifier, this will give you the name """ extended_class_name: String constructor: [ClassMethod!]! method: [ClassMethod!]! getter: [ClassMethod!]! setter: [ClassMethod!]! property: [ClassProperty!]! # TODO: some way to fall back from name_span to entire_class span """ Doesn't exist on anonymous classes """ name_span: Span entire_class_span: Span! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } type IfStatementAST implements ASTNode & HasSpan { condition: Expression! # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } type ReturnStatement implements Statement & HasSpan { expression: Expression # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } type ReturnAST implements ASTNode & HasSpan { expression: Expression # ASTNode parent: ASTNode ancestor: [ASTNode!]! # HasSpan span: Span! } # MAKE SURE TO KEEP ANCESTOR&CHILD IN SYNC interface ASTNode implements HasSpan { parent: ASTNode ancestor: [ASTNode!]! span: Span! } interface HasSpan { span: Span! }