Skip to content

Instantly share code, notes, and snippets.

@saeta-eth
Last active July 4, 2025 09:47
Show Gist options
  • Save saeta-eth/56bf04f3dd8795cfaf89baad54eb1b6e to your computer and use it in GitHub Desktop.
Save saeta-eth/56bf04f3dd8795cfaf89baad54eb1b6e to your computer and use it in GitHub Desktop.

Slang Query Language Documentation

Overview

Slang is a modular Solidity compiler tooling library that provides a declarative Query API for pattern matching in Solidity Abstract Syntax Trees (ASTs). This document covers all the expressions and patterns that can be used with the Slang Query API.

Note: All node types and examples in this documentation have been verified against the Slang v1.2.0 version to ensure accuracy.

Table of Contents

  1. Basic Query Syntax
  2. Node Types
  3. Pattern Matching
  4. Query Execution
  5. Common Patterns
  6. Examples
  7. Best Practices

Basic Query Syntax

A query is a pattern that matches a certain set of nodes in a tree. The expression to match a given node consists of a pair of brackets ([]) containing two things:

  1. The node's kind - The type of AST node to match
  2. Optional child patterns - Patterns that match the node's children

Basic Structure

[NodeKind];

With Child Patterns

[NodeKind[ChildNodeKind][AnotherChildNodeKind]];

With Labels

[NodeKind
  label: [ChildNodeKind]
  [AnotherChildNodeKind]
]

With Text Content

[NodeKind['specific_text']];

Wildcard Matching

[
  NodeKind[_], // Matches any node kind
];

Node Types

Core Solidity Node Types

All node types listed below have been verified to work with Slang v1.2.0.

Definitions

  • ConstantDefinition - Constant declarations
  • ConstructorDefinition - Constructor declarations
  • ContractDefinition - Contract declarations
  • EnumDefinition - Enum declarations
  • ErrorDefinition - Error declarations
  • EventDefinition - Event declarations
  • FallbackFunctionDefinition - Fallback function declarations
  • FunctionDefinition - Function declarations
  • InterfaceDefinition - Interface declarations
  • LibraryDefinition - Library declarations
  • ModifierDefinition - Modifier declarations
  • ReceiveFunctionDefinition - Receive function declarations
  • StateVariableDefinition - State variable declarations
  • StructDefinition - Struct declarations
  • UnnamedFunctionDefinition - Unnamed function declarations
  • UserDefinedValueTypeDefinition - Custom value type declarations
  • YulFunctionDefinition - Yul (assembly) function declarations

Statements

  • AssemblyStatement - Assembly blocks
  • BreakStatement - Break statements
  • ContinueStatement - Continue statements
  • DoWhileStatement - Do-while loops
  • EmitStatement - Emit statements
  • ExpressionStatement - Expression statements
  • ForStatement - For loops
  • IfStatement - If statements
  • ReturnStatement - Return statements
  • RevertStatement - Revert statements
  • Statement - Generic statement (abstract)
  • ThrowStatement - Throw statements (deprecated)
  • TryStatement - Try statements
  • TupleDeconstructionStatement - Tuple destructuring
  • VariableDeclarationStatement - Variable declarations
  • WhileStatement - While loops
  • YulBreakStatement - Yul break statements
  • YulContinueStatement - Yul continue statements
  • YulForStatement - Yul for loops
  • YulIfStatement - Yul if statements
  • YulLeaveStatement - Yul leave statements
  • YulStackAssignmentStatement - Yul stack assignments
  • YulStatement - Generic Yul statement
  • YulSwitchStatement - Yul switch statements
  • YulVariableAssignmentStatement - Yul variable assignments
  • YulVariableDeclarationStatement - Yul variable declarations

Expressions

  • AdditiveExpression - Addition and subtraction
  • AssignmentExpression - Assignment operations
  • CallOptionsExpression - Call options (value, gas)
  • ConditionalExpression - Ternary operator
  • ExponentiationExpression - Exponentiation
  • Expression - Generic expression (abstract)
  • FunctionCallExpression - Function calls
  • IndexAccessExpression - Array/mapping access
  • MemberAccessExpression - Member access (dot notation)
  • MultiplicativeExpression - Multiplication, division, modulo
  • NewExpression - New keyword expressions
  • PostfixExpression - Postfix operations (++, --)
  • PrefixExpression - Prefix operations (++, --, !, ~, -, +)ß
  • TypeExpression - Type expressions
  • VersionExpression - Version expressions (pragma)
  • YulExpression - Generic Yul expression
  • YulFunctionCallExpression - Yul function calls

Logical and Bitwise Expressions

  • AndExpression - Logical AND (&&)
  • OrExpression - Logical OR (||)
  • EqualityExpression - Equality operations (==, !=)
  • InequalityExpression - Inequality operations (<, >, <=, >=)
  • BitwiseAndExpression - Bitwise AND (&)
  • BitwiseOrExpression - Bitwise OR (|)
  • BitwiseXorExpression - Bitwise XOR (^)
  • ShiftExpression - Bit shift operations (<<, >>)

Primary Expressions and Literals

  • ArrayExpression - Array literals
  • DecimalNumberExpression - Decimal numbers
  • HexNumberExpression - Hexadecimal numbers
  • HexStringLiteral - Hex string literals
  • HexStringLiterals - Multiple hex string literals
  • IdentifierPath - Identifier paths (qualified names)
  • NumberUnit - Number units (wei, ether, etc.)
  • SimpleVersionLiteral - Simple version literals
  • StringExpression - String expressions
  • StringLiteral - String literal tokens
  • StringLiterals - Multiple string literals
  • TupleExpression - Tuple expressions
  • UnicodeStringLiteral - Unicode string literals
  • UnicodeStringLiterals - Multiple unicode string literals
  • VersionLiteral - Version literals
  • YulLiteral - Yul literals

Types

  • AddressType - Address type with optional payable
  • ArrayTypeName - Array types
  • ElementaryType - Basic types (uint, address, bool, etc.)
  • FunctionType - Function types
  • FunctionTypeAttribute - Function type attributes
  • FunctionTypeAttributes - Multiple function type attributes
  • InheritanceType - Inheritance type specifications
  • InheritanceTypes - Multiple inheritance types
  • MappingKeyType - Mapping key types
  • MappingType - Mapping types
  • TypeName - Generic type name (abstract)
  • TypedTupleMember - Typed tuple members
  • VariableDeclarationType - Variable declaration types

Abstract Node Types

The following are abstract base types that can match multiple specific node types:

  • Expression - Any expression type
  • Statement - Any statement type
  • TypeName - Any type name

Note: These abstract types are useful for broad pattern matching when you don't need to match specific expression or statement types.

Top-Level Constructs

  • ImportDirective - Import statements
  • PragmaDirective - Pragma directives
  • SourceUnit - Root node of a Solidity file
  • UsingDirective - Using statements

Edge Labels for Query Patterns

Edge labels are used to specify relationships between parent and child nodes in query patterns. Here are the available edge labels:

Common Labels:

  • name - Node name/identifier
  • body - Function/contract body
  • parameters - Function parameters
  • arguments - Function call arguments
  • expression - Expression content
  • condition - Conditional expressions
  • statements - Statement blocks
  • members - Contract/struct members
  • attributes - Node attributes
  • operator - Operators in expressions
  • operand - Expression operands
  • leftOperand, rightOperand - Binary expression operands

All Available Edge Labels (138 total):

Common Pattern Labels:

  • name - Node name/identifier
  • body - Function/contract body
  • parameters - Function parameters
  • arguments - Function call arguments
  • expression - Expression content
  • condition - Conditional expressions
  • statements - Statement blocks
  • members - Contract/struct members
  • attributes - Node attributes
  • operator - Operators in expressions
  • operand - Expression operands
  • leftOperand, rightOperand - Binary expression operands

Keyword Labels:

  • AbicoderKeyword - abicoder keyword label
  • AbstractKeyword - abstract keyword label
  • AddressKeyword - address keyword label
  • AnonymousKeyword - anonymous keyword label
  • AsKeyword - as keyword label
  • AssemblyKeyword - assembly keyword label
  • AtKeyword - at keyword label
  • BreakKeyword - break keyword label
  • CaseKeyword - case keyword label
  • CatchKeyword - catch keyword label
  • ConstantKeyword - constant keyword label
  • ConstructorKeyword - constructor keyword label
  • ContinueKeyword - continue keyword label
  • ContractKeyword - contract keyword label
  • DefaultKeyword - default keyword label
  • DoKeyword - do keyword label
  • ElseKeyword - else keyword label
  • EmitKeyword - emit keyword label
  • EnumKeyword - enum keyword label
  • ErrorKeyword - error keyword label
  • EventKeyword - event keyword label
  • ExperimentalKeyword - experimental keyword label
  • FallbackKeyword - fallback keyword label
  • ForKeyword - for keyword label
  • FromKeyword - from keyword label
  • FunctionKeyword - function keyword label
  • GlobalKeyword - global keyword label
  • IfKeyword - if keyword label
  • ImportKeyword - import keyword label
  • IndexedKeyword - indexed keyword label
  • InterfaceKeyword - interface keyword label
  • IsKeyword - is keyword label
  • LayoutKeyword - layout keyword label
  • LeaveKeyword - leave keyword label
  • LetKeyword - let keyword label
  • LibraryKeyword - library keyword label
  • MappingKeyword - mapping keyword label
  • ModifierKeyword - modifier keyword label
  • NewKeyword - new keyword label
  • OverrideKeyword - override keyword label
  • PayableKeyword - payable keyword label
  • PragmaKeyword - pragma keyword label
  • ReceiveKeyword - receive keyword label
  • ReturnKeyword - return keyword label
  • ReturnsKeyword - returns keyword label
  • RevertKeyword - revert keyword label
  • SolidityKeyword - solidity keyword label
  • StructKeyword - struct keyword label
  • SwitchKeyword - switch keyword label
  • ThrowKeyword - throw keyword label
  • TryKeyword - try keyword label
  • TypeKeyword - type keyword label
  • UncheckedKeyword - unchecked keyword label
  • UsingKeyword - using keyword label
  • VarKeyword - var keyword label
  • WhileKeyword - while keyword label

Structural Labels:

  • Alias - Alias specifications
  • Arguments - Function call arguments
  • Assignment - Assignment operations
  • Asterisk - Asterisk operators
  • Attributes - Node attributes
  • Block - Code blocks
  • Body - Function/contract bodies
  • Cases - Switch cases
  • CatchClauses - Try-catch clauses
  • Clause - Generic clauses
  • CloseBrace - Closing braces
  • CloseBracket - Closing brackets
  • CloseParen - Closing parentheses
  • Colon - Colon punctuation
  • Condition - Conditional expressions
  • Elements - Array/tuple elements
  • ElseBranch - Else branches
  • End - End markers
  • Equal - Equality operators
  • EqualGreaterThan - Mapping arrows (=>)
  • Error - Error specifications
  • Event - Event specifications
  • Expression - Expression content
  • FalseExpression - False expressions
  • Feature - Feature specifications
  • Flags - Flag specifications
  • Identifier - Identifiers
  • Index - Array indices
  • Inheritance - Inheritance specifications
  • Initialization - Initialization expressions
  • Item - Generic items
  • Items - Collections of items
  • Iterator - Loop iterators
  • KeyType - Mapping key types
  • Label - Labels
  • LeadingTrivia - Leading whitespace/comments
  • LeftOperand - Left operands
  • Literal - Literal values
  • Member - Member specifications
  • Members - Collections of members
  • Minus - Minus operators
  • MinusGreaterThan - Function arrows (->)
  • Missing - Missing elements
  • Name - Names/identifiers
  • OpenBrace - Opening braces
  • OpenBracket - Opening brackets
  • OpenParen - Opening parentheses
  • Operand - Generic operands
  • Operator - Operators
  • Options - Option specifications
  • Overridden - Override specifications
  • Parameters - Function parameters
  • Path - Import/using paths
  • Paths - Collections of paths
  • Period - Period punctuation
  • Pragma - Pragma directives
  • QuestionMark - Question mark operators
  • Returns - Return specifications
  • RightOperand - Right operands
  • Root - Root nodes
  • Semicolon - Semicolon punctuation
  • Separator - Separators
  • Sets - Collections/sets
  • Specifiers - Various specifiers
  • Start - Start markers
  • Statements - Statement collections
  • StorageLocation - Storage location specifications
  • Symbols - Symbol collections
  • Target - Target specifications
  • TrailingTrivia - Trailing whitespace/comments
  • TrueExpression - True expressions
  • TypeName - Type names
  • Types - Type collections
  • Unit - Units
  • Unrecognized - Unrecognized elements
  • Value - Values
  • ValueType - Value types
  • Variable - Variable specifications
  • VariableType - Variable types
  • Variables - Variable collections
  • Variant - Variants
  • Version - Version specifications

Terminal Kinds (Tokens/Keywords)

Terminal kinds represent the actual tokens, keywords, and operators in Solidity code. There are 296 terminal kinds available:

Basic Keywords:

  • AbicoderKeyword - abicoder keyword
  • AbstractKeyword - abstract keyword
  • AddressKeyword - address keyword
  • AfterKeyword - after keyword
  • AliasKeyword - alias keyword
  • AnonymousKeyword - anonymous keyword
  • ApplyKeyword - apply keyword
  • AsKeyword - as keyword
  • AssemblyKeyword - assembly keyword
  • AtKeyword - at keyword
  • AutoKeyword - auto keyword
  • BoolKeyword - bool keyword
  • BreakKeyword - break keyword
  • ByteKeyword - byte keyword
  • BytesKeyword - bytes keyword
  • CallDataKeyword - calldata keyword
  • CaseKeyword - case keyword
  • CatchKeyword - catch keyword
  • ConstantKeyword - constant keyword
  • ConstructorKeyword - constructor keyword
  • ContinueKeyword - continue keyword
  • ContractKeyword - contract keyword
  • CopyOfKeyword - copyof keyword
  • DaysKeyword - days keyword
  • DefaultKeyword - default keyword
  • DefineKeyword - define keyword
  • DeleteKeyword - delete keyword
  • DoKeyword - do keyword
  • ElseKeyword - else keyword
  • EmitKeyword - emit keyword
  • EnumKeyword - enum keyword
  • ErrorKeyword - error keyword
  • EtherKeyword - ether keyword
  • EventKeyword - event keyword
  • ExperimentalKeyword - experimental keyword
  • ExternalKeyword - external keyword
  • FallbackKeyword - fallback keyword
  • FalseKeyword - false keyword
  • FinalKeyword - final keyword
  • FinneyKeyword - finney keyword
  • FixedKeyword - fixed keyword
  • ForKeyword - for keyword
  • FromKeyword - from keyword
  • FunctionKeyword - function keyword
  • GlobalKeyword - global keyword
  • GweiKeyword - gwei keyword
  • HexKeyword - hex keyword
  • HoursKeyword - hours keyword
  • IfKeyword - if keyword
  • ImmutableKeyword - immutable keyword
  • ImplementsKeyword - implements keyword
  • ImportKeyword - import keyword
  • InKeyword - in keyword
  • IndexedKeyword - indexed keyword
  • InlineKeyword - inline keyword
  • IntKeyword - int keyword
  • InterfaceKeyword - interface keyword
  • InternalKeyword - internal keyword
  • IsKeyword - is keyword
  • LayoutKeyword - layout keyword
  • LetKeyword - let keyword
  • LibraryKeyword - library keyword
  • MacroKeyword - macro keyword
  • MappingKeyword - mapping keyword
  • MatchKeyword - match keyword
  • MemoryKeyword - memory keyword
  • MinutesKeyword - minutes keyword
  • ModifierKeyword - modifier keyword
  • MutableKeyword - mutable keyword
  • NewKeyword - new keyword
  • NullKeyword - null keyword
  • OfKeyword - of keyword
  • OverrideKeyword - override keyword
  • PartialKeyword - partial keyword
  • PayableKeyword - payable keyword
  • PragmaKeyword - pragma keyword
  • PrivateKeyword - private keyword
  • PromiseKeyword - promise keyword
  • PublicKeyword - public keyword
  • PureKeyword - pure keyword
  • ReceiveKeyword - receive keyword
  • ReferenceKeyword - reference keyword
  • RelocatableKeyword - relocatable keyword
  • ReturnKeyword - return keyword
  • ReturnsKeyword - returns keyword
  • RevertKeyword - revert keyword
  • SealedKeyword - sealed keyword
  • SecondsKeyword - seconds keyword
  • SizeOfKeyword - sizeof keyword
  • SolidityKeyword - solidity keyword
  • StaticKeyword - static keyword
  • StorageKeyword - storage keyword
  • StringKeyword - string keyword
  • StructKeyword - struct keyword
  • SuperKeyword - super keyword
  • SupportsKeyword - supports keyword
  • SwitchKeyword - switch keyword
  • SzaboKeyword - szabo keyword
  • ThisKeyword - this keyword
  • ThrowKeyword - throw keyword
  • TransientKeyword - transient keyword
  • TrueKeyword - true keyword
  • TryKeyword - try keyword
  • TypeDefKeyword - typedef keyword
  • TypeKeyword - type keyword
  • TypeOfKeyword - typeof keyword
  • UfixedKeyword - ufixed keyword
  • UintKeyword - uint keyword
  • UncheckedKeyword - unchecked keyword
  • UsingKeyword - using keyword
  • VarKeyword - var keyword
  • ViewKeyword - view keyword
  • VirtualKeyword - virtual keyword
  • WeeksKeyword - weeks keyword
  • WeiKeyword - wei keyword
  • WhileKeyword - while keyword
  • YearsKeyword - years keyword

Operators and Punctuation:

  • Ampersand - & (bitwise AND)
  • AmpersandAmpersand - && (logical AND)
  • AmpersandEqual - &= (bitwise AND assignment)
  • Asterisk - * (multiplication)
  • AsteriskAsterisk - ** (exponentiation)
  • AsteriskEqual - *= (multiplication assignment)
  • Bang - ! (logical NOT)
  • BangEqual - != (not equal)
  • Bar - | (bitwise OR)
  • BarBar - || (logical OR)
  • BarEqual - |= (bitwise OR assignment)
  • Caret - ^ (bitwise XOR)
  • CaretEqual - ^= (bitwise XOR assignment)
  • CloseBrace - } (closing brace)
  • CloseBracket - ] (closing bracket)
  • CloseParen - ) (closing parenthesis)
  • Colon - : (colon)
  • ColonEqual - := (assignment in Yul)
  • Comma - , (comma)
  • Equal - = (assignment)
  • EqualColon - =: (Yul assignment)
  • EqualEqual - == (equality)
  • EqualGreaterThan - => (mapping arrow)
  • GreaterThan - > (greater than)
  • GreaterThanEqual - >= (greater than or equal)
  • GreaterThanGreaterThan - >> (right shift)
  • GreaterThanGreaterThanEqual - >>= (right shift assignment)
  • GreaterThanGreaterThanGreaterThan - >>> (unsigned right shift)
  • GreaterThanGreaterThanGreaterThanEqual - >>>= (unsigned right shift assignment)
  • LessThan - < (less than)
  • LessThanEqual - <= (less than or equal)
  • LessThanLessThan - << (left shift)
  • LessThanLessThanEqual - <<= (left shift assignment)
  • Minus - - (subtraction)
  • MinusEqual - -= (subtraction assignment)
  • MinusGreaterThan - -> (function return arrow)
  • MinusMinus - -- (decrement)
  • OpenBrace - { (opening brace)
  • OpenBracket - [ (opening bracket)
  • OpenParen - ( (opening parenthesis)
  • Percent - % (modulo)
  • PercentEqual - %= (modulo assignment)
  • Period - . (dot/member access)
  • Plus - + (addition)
  • PlusEqual - += (addition assignment)
  • PlusPlus - ++ (increment)
  • QuestionMark - ? (ternary operator)
  • Semicolon - ; (semicolon)
  • Slash - / (division)
  • SlashEqual - /= (division assignment)
  • Tilde - ~ (bitwise NOT)

Literals and Identifiers:

  • DecimalLiteral - Decimal number literals
  • DoubleQuotedHexStringLiteral - Double-quoted hex string literals
  • DoubleQuotedStringLiteral - Double-quoted string literals
  • DoubleQuotedUnicodeStringLiteral - Double-quoted unicode string literals
  • DoubleQuotedVersionLiteral - Double-quoted version literals
  • HexLiteral - Hexadecimal literals
  • Identifier - Identifiers (variable/function names)
  • SingleQuotedHexStringLiteral - Single-quoted hex string literals
  • SingleQuotedStringLiteral - Single-quoted string literals
  • SingleQuotedUnicodeStringLiteral - Single-quoted unicode string literals
  • SingleQuotedVersionLiteral - Single-quoted version literals
  • VersionSpecifier - Version specifier tokens

Comments and Whitespace:

  • EndOfLine - End of line tokens
  • MultiLineComment - Multi-line comments
  • MultiLineNatSpecComment - Multi-line NatSpec comments
  • SingleLineComment - Single-line comments
  • SingleLineNatSpecComment - Single-line NatSpec comments
  • Whitespace - Whitespace tokens

Special Tokens:

  • Missing - Missing tokens (for error recovery)
  • Unrecognized - Unrecognized tokens

Yul (Assembly) Keywords: Complete set of Yul/assembly keywords with Yul prefix:

All Solidity keywords in Yul (assembly) context:

  • YulAbstractKeyword - abstract in Yul
  • YulAfterKeyword - after in Yul
  • YulAliasKeyword - alias in Yul
  • YulAnonymousKeyword - anonymous in Yul
  • YulApplyKeyword - apply in Yul
  • YulAsKeyword - as in Yul
  • YulAssemblyKeyword - assembly in Yul
  • YulAutoKeyword - auto in Yul
  • YulBoolKeyword - bool in Yul
  • YulBreakKeyword - break in Yul
  • YulBytesKeyword - bytes in Yul
  • YulCallDataKeyword - calldata in Yul
  • YulCaseKeyword - case in Yul
  • YulCatchKeyword - catch in Yul
  • YulConstantKeyword - constant in Yul
  • YulConstructorKeyword - constructor in Yul
  • YulContinueKeyword - continue in Yul
  • YulContractKeyword - contract in Yul
  • YulCopyOfKeyword - copyof in Yul
  • YulDaysKeyword - days in Yul
  • YulDefaultKeyword - default in Yul
  • YulDefineKeyword - define in Yul
  • YulDeleteKeyword - delete in Yul
  • YulDoKeyword - do in Yul
  • YulElseKeyword - else in Yul
  • YulEmitKeyword - emit in Yul
  • YulEnumKeyword - enum in Yul
  • YulEtherKeyword - ether in Yul
  • YulEventKeyword - event in Yul
  • YulExternalKeyword - external in Yul
  • YulFallbackKeyword - fallback in Yul
  • YulFalseKeyword - false in Yul
  • YulFinalKeyword - final in Yul
  • YulFinneyKeyword - finney in Yul
  • YulFixedKeyword - fixed in Yul
  • YulForKeyword - for in Yul
  • YulFunctionKeyword - function in Yul
  • YulGweiKeyword - gwei in Yul
  • YulHexKeyword - hex in Yul
  • YulHoursKeyword - hours in Yul
  • YulIfKeyword - if in Yul
  • YulImmutableKeyword - immutable in Yul
  • YulImplementsKeyword - implements in Yul
  • YulImportKeyword - import in Yul
  • YulInKeyword - in in Yul
  • YulIndexedKeyword - indexed in Yul
  • YulInlineKeyword - inline in Yul
  • YulIntKeyword - int in Yul
  • YulInterfaceKeyword - interface in Yul
  • YulInternalKeyword - internal in Yul
  • YulIsKeyword - is in Yul
  • YulLeaveKeyword - leave in Yul
  • YulLetKeyword - let in Yul
  • YulLibraryKeyword - library in Yul
  • YulMacroKeyword - macro in Yul
  • YulMappingKeyword - mapping in Yul
  • YulMatchKeyword - match in Yul
  • YulMemoryKeyword - memory in Yul
  • YulMinutesKeyword - minutes in Yul
  • YulModifierKeyword - modifier in Yul
  • YulMutableKeyword - mutable in Yul
  • YulNewKeyword - new in Yul
  • YulNullKeyword - null in Yul
  • YulOfKeyword - of in Yul
  • YulOverrideKeyword - override in Yul
  • YulPartialKeyword - partial in Yul
  • YulPayableKeyword - payable in Yul
  • YulPragmaKeyword - pragma in Yul
  • YulPrivateKeyword - private in Yul
  • YulPromiseKeyword - promise in Yul
  • YulPublicKeyword - public in Yul
  • YulPureKeyword - pure in Yul
  • YulReceiveKeyword - receive in Yul
  • YulReferenceKeyword - reference in Yul
  • YulRelocatableKeyword - relocatable in Yul
  • YulReturnsKeyword - returns in Yul
  • YulSealedKeyword - sealed in Yul
  • YulSecondsKeyword - seconds in Yul
  • YulSizeOfKeyword - sizeof in Yul
  • YulStaticKeyword - static in Yul
  • YulStorageKeyword - storage in Yul
  • YulStringKeyword - string in Yul
  • YulStructKeyword - struct in Yul
  • YulSuperKeyword - super in Yul
  • YulSupportsKeyword - supports in Yul
  • YulSwitchKeyword - switch in Yul
  • YulSzaboKeyword - szabo in Yul
  • YulThisKeyword - this in Yul
  • YulThrowKeyword - throw in Yul
  • YulTrueKeyword - true in Yul
  • YulTryKeyword - try in Yul
  • YulTypeDefKeyword - typedef in Yul
  • YulTypeKeyword - type in Yul
  • YulTypeOfKeyword - typeof in Yul
  • YulUfixedKeyword - ufixed in Yul
  • YulUintKeyword - uint in Yul
  • YulUncheckedKeyword - unchecked in Yul
  • YulUsingKeyword - using in Yul
  • YulVarKeyword - var in Yul
  • YulViewKeyword - view in Yul
  • YulVirtualKeyword - virtual in Yul
  • YulWeeksKeyword - weeks in Yul
  • YulWeiKeyword - wei in Yul
  • YulWhileKeyword - while in Yul
  • YulYearsKeyword - years in Yul
  • YulDecimalLiteral - Decimal literals in Yul
  • YulHexLiteral - Hex literals in Yul
  • YulIdentifier - Identifiers in Yul context

Other Node Types (118 total)

Additional structural node types for specific language constructs:

Parameter and Argument Types:

  • Parameter - Function parameter
  • Parameters - Function parameter list
  • ParametersDeclaration - Parameter declaration block
  • ArgumentsDeclaration - Arguments declaration block
  • NamedArgument - Named function argument
  • NamedArgumentGroup - Group of named arguments
  • NamedArguments - Named argument list
  • NamedArgumentsDeclaration - Named arguments declaration
  • PositionalArguments - Positional argument list
  • PositionalArgumentsDeclaration - Positional arguments declaration

Member and Attribute Types:

  • ContractMember - Single contract member
  • ContractMembers - Contract member list
  • StructMember - Single struct member
  • StructMembers - Struct member list
  • InterfaceMembers - Interface member list
  • LibraryMembers - Library member list
  • EnumMembers - Enum member list
  • ConstructorAttribute - Constructor attribute
  • ConstructorAttributes - Constructor attribute list
  • FunctionAttribute - Function attribute
  • FunctionAttributes - Function attribute list
  • StateVariableAttribute - State variable attribute
  • StateVariableAttributes - State variable attribute list
  • ModifierAttribute - Modifier attribute
  • ModifierAttributes - Modifier attribute list
  • FallbackFunctionAttribute - Fallback function attribute
  • FallbackFunctionAttributes - Fallback function attribute list
  • ReceiveFunctionAttribute - Receive function attribute
  • ReceiveFunctionAttributes - Receive function attribute list
  • UnnamedFunctionAttribute - Unnamed function attribute
  • UnnamedFunctionAttributes - Unnamed function attribute list
  • ModifierInvocation - Modifier invocation

Import and Using Types:

  • ImportClause - Import clause
  • ImportAlias - Import alias
  • ImportDeconstruction - Import deconstruction
  • ImportDeconstructionSymbol - Import deconstruction symbol
  • ImportDeconstructionSymbols - Import deconstruction symbol list
  • PathImport - Path import
  • NamedImport - Named import
  • UsingClause - Using clause
  • UsingTarget - Using target
  • UsingOperator - Using operator
  • UsingAlias - Using alias
  • UsingDeconstruction - Using deconstruction
  • UsingDeconstructionSymbol - Using deconstruction symbol
  • UsingDeconstructionSymbols - Using deconstruction symbol list

Block and Statement Types:

  • Block - Code block
  • UncheckedBlock - Unchecked code block
  • FunctionBody - Function body
  • Statements - Statement list
  • ElseBranch - Else branch
  • ForStatementCondition - For statement condition
  • ForStatementInitialization - For statement initialization

Error and Event Types:

  • ErrorParameter - Error parameter
  • ErrorParameters - Error parameter list
  • ErrorParametersDeclaration - Error parameters declaration
  • EventParameter - Event parameter
  • EventParameters - Event parameter list
  • EventParametersDeclaration - Event parameters declaration
  • CatchClause - Catch clause
  • CatchClauseError - Catch clause error
  • CatchClauses - Catch clause list

Version and Pragma Types:

  • AbicoderPragma - Abicoder pragma
  • ExperimentalPragma - Experimental pragma
  • ExperimentalFeature - Experimental feature
  • VersionPragma - Version pragma (mapped from Pragma)
  • VersionRange - Version range
  • VersionTerm - Version term
  • VersionOperator - Version operator
  • VersionExpressionSet - Version expression set
  • VersionExpressionSets - Version expression sets

Type and Value Types:

  • MappingKey - Mapping key
  • MappingValue - Mapping value
  • ArrayValues - Array values
  • TupleMember - Tuple member
  • TupleValue - Tuple value
  • TupleValues - Tuple values
  • TupleDeconstructionElement - Tuple deconstruction element
  • TupleDeconstructionElements - Tuple deconstruction elements
  • UntypedTupleMember - Untyped tuple member
  • StateVariableDefinitionValue - State variable definition value
  • VariableDeclarationValue - Variable declaration value

Inheritance and Override Types:

  • InheritanceSpecifier - Inheritance specifier
  • ContractSpecifier - Contract specifier
  • ContractSpecifiers - Contract specifier list
  • OverrideSpecifier - Override specifier
  • OverridePaths - Override paths
  • OverridePathsDeclaration - Override paths declaration
  • StorageLayoutSpecifier - Storage layout specifier
  • StorageLocation - Storage location

Assembly and Other Types:

  • AssemblyFlags - Assembly flags
  • AssemblyFlagsDeclaration - Assembly flags declaration
  • CallOptions - Call options
  • IndexAccessEnd - Index access end
  • ReturnsDeclaration - Returns declaration
  • SourceUnitMember - Source unit member
  • SourceUnitMembers - Source unit members
  • FunctionName - Function name

Yul (Assembly) Specific Types:

  • YulArguments - Yul arguments
  • YulAssignmentOperator - Yul assignment operator
  • YulBlock - Yul block
  • YulColonAndEqual - Yul colon and equal (:=)
  • YulDefaultCase - Yul default case
  • YulEqualAndColon - Yul equal and colon (=:)
  • YulLabel - Yul label
  • YulParameters - Yul parameters
  • YulParametersDeclaration - Yul parameters declaration
  • YulPath - Yul path
  • YulPaths - Yul paths
  • YulReturnsDeclaration - Yul returns declaration
  • YulStackAssignmentOperator - Yul stack assignment operator
  • YulStatements - Yul statements
  • YulSwitchCase - Yul switch case
  • YulSwitchCases - Yul switch cases
  • YulValueCase - Yul value case
  • YulVariableDeclarationValue - Yul variable declaration value
  • YulVariableNames - Yul variable names

Pattern Matching

A query is a pattern that matches a certain set of nodes in a tree. The expression to match a given node consists of a pair of brackets ([]) containing two things: the node's kind, and optionally, a series of other patterns that match the node's children. For example, this pattern would match any MultiplicativeExpression node that has two children Expression nodes, with an Asterisk node in between:

[MultiplicativeExpression
  [Expression]
  [Asterisk]
  [Expression]
]

The children of a node can optionally be labeled. The label is a property of the edge from the node to the child, and is not a property of the child. For example, this pattern will match a MultiplicativeExpression node with the two Expression children labeled left_operand and right_operand:

[MultiplicativeExpression
  left_operand: [Expression]
  [Asterisk]
  right_operand: [Expression]
]

You can also match a node's textual content using a string literal. For example, this pattern would match a MultiplicativeExpression with a * operator (for clarity):

[MultiplicativeExpression
  left_operand: [_]
  operator: ["*"]
  right_operand: [_]
]

If you don't care about the kind of a node, you can use an underscore _, which matches any kind. For example, this pattern will match a MultiplicativeExpression node with any two children with any kind, as long as one of them is labeled left_operand:

[MultiplicativeExpression
  left_operand: [_]
  [_]
]

Children can be elided. For example, this would produce multiple matches for a MultiplicativeExpression where at least one of the children is an expression of a StringExpression variant, where each match is associated with each of the StringExpression children:

[MultiplicativeExpression
  [Expression
    [StringExpression]
  ]
]

Trivia nodes (whitespace, comments, etc.) will be skipped over when running a query. Furthermore, trivia nodes cannot be explicitly (or implicitly with _) matched by queries.

Capturing# When matching patterns, you may want to process specific nodes within the pattern. Captures allow you to associate names with specific nodes in a pattern, so that you can later refer to those nodes by those names. Capture names are written before the nodes that they refer to, and start with an @ character.

For example, this pattern would match any struct definition and it would associate the name struct_name with the identifier:

[StructDefinition
  @struct_name name: [Identifier]
]

And this pattern would match all event definitions for a contract, associating the name event_name with the event name, contract_name with the containing contract name:

[ContractDefinition
  @contract_name name: [Identifier]
  members: [ContractMembers
    [ContractMember
      [EventDefinition
        @event_name name: [Identifier]
      ]
    ]
  ]
]

Quantification# You can surround a sequence of patterns in parenthesis (()), followed by a ?, _ or + operator. The ? operator matches zero or one repetitions of a pattern, the _ operator matches zero or more, and the + operator matches one or more.

For example, this pattern would match a sequence of one or more import directives at the top of the file:

[SourceUnit
  members: [
    _
    ([_ @import [ImportDirective]])+
  ]
]

This pattern would match a structure definition with one or more members, capturing their names:

[StructDefinition
  @name name: [_]
  members: [
    _
    ([_ @member [Identifier]])+
  ]
]

This pattern would match all function calls, capturing a string argument if one was present:

[FunctionCallExpression
  arguments: [ArgumentsDeclaration
    variant: [PositionalArgumentsDeclaration
      arguments: [PositionalArguments
        (@arg [Expression variant: [StringExpression]])?
      ]
    ]
  ]
]

Alternation# An alternation is written as a sequence of patterns separated by | and surrounded by parentheses.

For example, this pattern would match a call to either a variable or an object property. In the case of a variable, capture it as @function, and in the case of a property, capture it as @method:

[FunctionCallExpression
  operand: [Expression
    (
        @function variant: [Identifier]
      | @method variant: [MemberAccessExpression]
    )
  ]
]

This pattern would match a set of possible keyword terminals, capturing them as @keyword:

@keyword (
    ["break"]
  | ["delete"]
  | ["else"]
  | ["for"]
  | ["function"]
  | ["if"]
  | ["return"]
  | ["try"]
  | ["while"]
)

Adjacency# By using the adjacency operator . you can constrain a pattern to only match the first or the last child nodes.

For example, the following pattern would match only the first parameter declaration in a function definition:

[FunctionDefinition
  [ParametersDeclaration
    [Parameters
      .
      @first_param [Parameter]
    ]
  ]
]

And conversely the following will match only the last parameter:

[FunctionDefinition
  [ParametersDeclaration
    [Parameters
      @last_param [Parameter]
      .
    ]
  ]
]

If the adjacency operator is used in between two patterns it constrains matches on both patterns to occur consecutively, ie. without any other sibling node in between. For example, this pattern matches pairs of consecutive statements:

[Statements
  @stmt1 [Statement]
  .
  @stmt2 [Statement]
]

Exact Node Matching

// Match any function definition
Query.create(`[FunctionDefinition]`);

// Match any function call
Query.create(`[FunctionCallExpression]`);

Nested Pattern Matching

// Match function calls with member access
Query.create(`
[FunctionCallExpression
  [MemberAccessExpression]
]
`);

Multiple Child Patterns

// Match assignment expressions
Query.create(`
[AssignmentExpression
  [Identifier]
  [Expression]
]
`);

Labeled Children

// Match binary expressions with labeled operands
Query.create(`
[BinaryExpression
  left_operand: [Expression]
  operator: [_]
  right_operand: [Expression]
]
`);

Text Content Matching

// Match specific function calls
Query.create(`
[FunctionCallExpression
  [MemberAccessExpression
    [_]
    ["transfer"]
  ]
]
`);

Wildcard Patterns

// Match any expression with any children
Query.create(`
[Expression
  [_]
]
`);

Query Execution

Creating Queries

import { Query } from '@nomicfoundation/slang/cst';

const query = Query.create(`[FunctionDefinition]`);

Executing Queries

// Single query
const matches = cursor.query([query]);

// Multiple queries
const queries = [
  Query.create(`[FunctionDefinition]`),
  Query.create(`[ContractDefinition]`),
];
const matches = cursor.query(queries);

Processing Results

for (const match of matches) {
  const cursor = match.root;
  const nodeText = cursor.node.unparse();
  const location = cursor.textRange;

  console.log(`Found match: ${nodeText}`);
  console.log(`Location: Line ${location.start.line}`);
}

Common Patterns

External Calls

// Low-level calls
Query.create(`
[FunctionCallExpression
  [MemberAccessExpression
    [_]
    ["call"]
  ]
]
`);

// Delegate calls
Query.create(`
[FunctionCallExpression
  [MemberAccessExpression
    [_]
    ["delegatecall"]
  ]
]
`);

// Transfer calls
Query.create(`
[FunctionCallExpression
  [MemberAccessExpression
    [_]
    ["transfer"]
  ]
]
`);

State Changes

// Assignment expressions
Query.create(`[AssignmentExpression]`);

// State variable modifications
Query.create(`
[AssignmentExpression
  [IndexAccessExpression]
  [_]
]
`);

Access Control

// Require statements
Query.create(`
[FunctionCallExpression
  [Identifier "require"]
]
`);

// Modifier usage
Query.create(`
[ModifierInvocation]
`);

Timestamp Dependencies

// Block timestamp usage
Query.create(`
[MemberAccessExpression
  [Identifier "block"]
  ["timestamp"]
]
`);

// Block number usage
Query.create(`
[MemberAccessExpression
  [Identifier "block"]
  ["number"]
]
`);

Function Patterns

Payable Functions

// Payable functions (look for payable keyword in function attributes)
Query.create(`
[FunctionDefinition
  [FunctionAttributes
    [FunctionAttribute
      [_]
    ]
  ]
]
`);

Fallback and Receive Functions

// Receive functions
Query.create(`[ReceiveFunctionDefinition]`);

// Fallback functions
Query.create(`[FallbackFunctionDefinition]`);

Constructor Functions

// Constructor definitions
Query.create(`[ConstructorDefinition]`);

Error Handling Patterns

// Try statements
Query.create(`[TryStatement]`);

// Revert statements
Query.create(`[RevertStatement]`);

// Custom errors
Query.create(`
[RevertStatement
  [FunctionCallExpression
    [Identifier]
  ]
]
`);

Event Patterns

// Event emissions
Query.create(`[EmitStatement]`);

// Specific event emissions
Query.create(`
[EmitStatement
  [FunctionCallExpression
    [Identifier "Transfer"]
  ]
]
`);

Arithmetic Patterns

// Addition/Subtraction
Query.create(`[AdditiveExpression]`);

// Multiplication/Division
Query.create(`[MultiplicativeExpression]`);

// Exponentiation
Query.create(`[ExponentiationExpression]`);

// All arithmetic operations
const arithmeticQueries = [
  Query.create(`[AdditiveExpression]`),
  Query.create(`[MultiplicativeExpression]`),
  Query.create(`[ExponentiationExpression]`),
];

Examples

Example 1: Finding All Function Calls

import { Query } from '@nomicfoundation/slang/cst';

const functionCallQuery = Query.create(`[FunctionCallExpression]`);
const matches = cursor.query([functionCallQuery]);

for (const match of matches) {
  console.log('Function call:', match.root.node.unparse());
}

Example 2: Finding External Calls with Ether Transfer

const etherTransferQuery = Query.create(`
[CallOptionsExpression
  [NamedArgument
    [Identifier "value"]
    [_]
  ]
]
`);

const matches = cursor.query([etherTransferQuery]);
for (const match of matches) {
  console.log('Ether transfer found:', match.root.node.unparse());
}

Example 3: Finding Unsafe Arithmetic Operations

const unsafeArithmeticQueries = [
  Query.create(`[AdditiveExpression]`),
  Query.create(`[MultiplicativeExpression]`),
  Query.create(`[ExponentiationExpression]`),
];

const matches = cursor.query(unsafeArithmeticQueries);
for (const match of matches) {
  // Check if it's inside an unchecked block
  const text = match.root.node.unparse();
  console.log('Arithmetic operation:', text);
}

Example 4: Finding Access Control Patterns

const accessControlQuery = Query.create(`
[FunctionCallExpression
  [Identifier "require"]
  [_]
]
`);

const matches = cursor.query([accessControlQuery]);
for (const match of matches) {
  const requireCall = match.root.node.unparse();
  if (requireCall.includes('msg.sender') && requireCall.includes('owner')) {
    console.log('Access control found:', requireCall);
  }
}

Example 5: Finding Token Transfer Patterns

const tokenTransferQueries = [
  Query.create(`
  [FunctionCallExpression
    [MemberAccessExpression
      [_]
      ["transfer"]
    ]
  ]
  `),
  Query.create(`
  [FunctionCallExpression
    [MemberAccessExpression
      [_]
      ["transferFrom"]
    ]
  ]
  `),
];

const matches = cursor.query(tokenTransferQueries);
for (const match of matches) {
  console.log('Token transfer:', match.root.node.unparse());
}

Best Practices

1. Use Specific Node Types

Instead of using wildcards everywhere, be specific about the node types you're looking for:

// Good
Query.create(`[FunctionCallExpression]`);

// Less efficient
Query.create(`[_]`);

2. Combine Multiple Queries

When looking for different patterns, combine them in a single query execution:

const queries = [
  Query.create(`[FunctionCallExpression]`),
  Query.create(`[AssignmentExpression]`),
  Query.create(`[EmitStatement]`),
];
const matches = cursor.query(queries);

3. Use Labels for Complex Patterns

When matching complex patterns, use labels to make your queries more readable:

Query.create(`
[FunctionCallExpression
  function: [MemberAccessExpression
    object: [Identifier]
    member: ["transfer"]
  ]
  arguments: [ArgumentList
    [_]
    [_]
  ]
]
`);

4. Handle Query Errors

Always wrap query creation in try-catch blocks:

try {
  const query = Query.create(`[FunctionCallExpression]`);
  const matches = cursor.query([query]);
} catch (error) {
  console.error('Query error:', error.message);
}

5. Optimize for Performance

  • Use the most specific node types possible
  • Avoid deep nesting when not necessary
  • Batch multiple queries together
  • Consider the scope of your search (use cursor.spawn() for subtrees)

6. Validate Query Syntax

Test your queries with simple examples before using them on large codebases:

// Test with a simple contract first
const testSource = `
contract Test {
  function transfer(address to, uint amount) public {
    // test code
  }
}
`;

Error Handling

Common Query Errors

  1. Invalid Node Kind: Using a non-existent node type
  2. Syntax Errors: Malformed query syntax
  3. Nesting Errors: Incorrect child-parent relationships

Error Examples

// This will throw an error - invalid node kind
try {
  Query.create(`[NonExistentNode]`);
} catch (error) {
  console.log(error.message); // 'NonExistentNode' is not a valid node kind
}

// This will throw an error - syntax error
try {
  Query.create(`[FunctionDefinition`); // Missing closing bracket
} catch (error) {
  console.log(error.message); // Parse error
}

Complete Node Type Reference

This documentation covers all 653 components available in Slang v1.2.0:

Summary by Category

Category Count Description
Definitions 17 Contract, function, struct, enum, etc. definitions
Statements 26 Control flow, declarations, Yul statements
Expressions 17 Function calls, assignments, arithmetic, etc.
Logical/Bitwise Expressions 8 Boolean and bitwise operations
Primary Expressions/Literals 16 Identifiers, literals, arrays, tuples
Types 13 Type specifications and declarations
Abstract Node Types 3 Base types for broad matching
Top-Level Constructs 4 File-level constructs
Terminal Kinds 296 Keywords, operators, punctuation
Edge Labels 138 Labels for parent-child relationships
Other Node Types 118 Specialized structural nodes
Total 653 Complete coverage of Slang AST
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment