mirror of
https://github.com/github/codeql.git
synced 2026-02-20 08:53:49 +01:00
Merge pull request #134 from github/literals
Add and expand AST classes for literals
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -599,7 +599,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tree-sitter-ruby"
|
||||
version = "0.17.0"
|
||||
source = "git+https://github.com/tree-sitter/tree-sitter-ruby.git?rev=add8cb36d5fc0a00d4499ba2e8eedc04a38a2488#add8cb36d5fc0a00d4499ba2e8eedc04a38a2488"
|
||||
source = "git+https://github.com/tree-sitter/tree-sitter-ruby.git?rev=2503f005d917c7aa4726dfe19398dc1a4a299d94#2503f005d917c7aa4726dfe19398dc1a4a299d94"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
|
||||
@@ -11,7 +11,7 @@ flate2 = "1.0"
|
||||
node-types = { path = "../node-types" }
|
||||
tree-sitter = "0.17"
|
||||
tree-sitter-embedded-template = { git = "https://github.com/aibaars/tree-sitter-embedded-template", rev = "d4aac29c08aa7c596633d00b5ec2dd2d247eafe4" }
|
||||
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "add8cb36d5fc0a00d4499ba2e8eedc04a38a2488" }
|
||||
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "2503f005d917c7aa4726dfe19398dc1a4a299d94" }
|
||||
clap = "2.33"
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.2", features = ["env-filter"] }
|
||||
|
||||
@@ -10,4 +10,4 @@ edition = "2018"
|
||||
node-types = { path = "../node-types" }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.2", features = ["env-filter"] }
|
||||
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "add8cb36d5fc0a00d4499ba2e8eedc04a38a2488" }
|
||||
tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "2503f005d917c7aa4726dfe19398dc1a4a299d94" }
|
||||
|
||||
91
prepare-db-upgrade.md
Normal file
91
prepare-db-upgrade.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Upgrading the Ruby database schema
|
||||
|
||||
The schema (`ql/src/ruby.dbscheme`) is automatically generated from tree-sitter's `node-types.json`. When the tree-sitter grammar changes, the database schema is likely to change as well, and we need to write an upgrade script. This document explains how to do that.
|
||||
|
||||
## Process Overview
|
||||
|
||||
1. Commit the change to `ruby.dbscheme` (along with any library updates required to work with the change).
|
||||
2. Run `prepare-db-upgrade.sh`.
|
||||
3. Fill in the details in `upgrade.properties`, and add any required upgrade queries.
|
||||
|
||||
It may be helpful to look at some of the existing upgrade scripts, to see how they work.
|
||||
|
||||
## Details
|
||||
|
||||
### Generating a Ruby database upgrade script
|
||||
|
||||
Schema changes need to be accompanied by scripts that allow us to upgrade databases that were generated with older versions of the tools, so they can use new query functionality (albeit with possibly degraded results).
|
||||
|
||||
#### The easy (mostly automatic) way
|
||||
|
||||
The easy way to generate an upgrade script is to run the `prepare-db-upgrade.sh` script. This will generate a skeleton upgrade directory, leaving you to fill out the details in the `upgrade.properties` file.
|
||||
|
||||
#### upgrade.properties
|
||||
|
||||
It will look something like:
|
||||
|
||||
```
|
||||
description: what it does
|
||||
compatibility: partial
|
||||
some_relation.rel: run some_relation.qlo
|
||||
```
|
||||
|
||||
The `description` field is a textual description of the aim of the upgrade.
|
||||
|
||||
The `compatibility` field takes one of four values:
|
||||
|
||||
* **full**: results from the upgraded snapshot will be identical to results from a snapshot built with the new version of the toolchain.
|
||||
|
||||
* **backwards**: the step is safe and preserves the meaning of the old database, but new features may not work correctly on the upgraded snapshot.
|
||||
|
||||
* **partial**: the step is safe and preserves the meaning of the old database, but you would get better results if you rebuilt the snapshot with the new version of the toolchain.
|
||||
|
||||
* **breaking**: the step is unsafe and will prevent certain queries from working.
|
||||
|
||||
The `some_relation.rel` line(s) are the actions required to do the database upgrade. Do a diff on the the new vs old `.dbscheme` file to get an idea of what they have to achieve. Sometimes you won't need any upgrade commands – this happens when the dbscheme has changed in "cosmetic" ways, for example by adding/removing comments or changing union type relationships, but still retains the same on-disk format for all tables; the purpose of the upgrade script is then to document the fact that it's safe to replace the old dbscheme with the new one).
|
||||
|
||||
Some typical upgrade commands look like this:
|
||||
|
||||
```
|
||||
// Delete a relation that has been replaced in the new scheme
|
||||
obsolete.rel: delete
|
||||
|
||||
// Create a new version of a table by applying a simple RA expression to an
|
||||
// existing table. The example duplicates the 'id' column of input.rel as
|
||||
// the last column of etended.rel, perhaps to record our best guess at
|
||||
// newly-populated "source declaration" information.
|
||||
extended.rel: reorder input.rel (int id, string name, int parent) id name parent id
|
||||
|
||||
// Create relationname.rel by running relationname.qlo and writing the query
|
||||
// results as a .rel file. The query file should be named relationname.ql and
|
||||
// should be placed in the upgrade directory. It should avoid using the default
|
||||
// QLL library, and will run in the context of the *old* dbscheme.
|
||||
relationname.rel: run relationname.qlo
|
||||
```
|
||||
|
||||
#### Testing your upgrade script
|
||||
|
||||
Upgrade scripts can be a little bit fiddly, so it's essential that you test them. You might do so as follows:
|
||||
|
||||
1. Create a snapshot of your favourite project using the old version of the code.
|
||||
|
||||
2. Switch to the new version of the code.
|
||||
|
||||
3. Try to run some queries that will depend on your upgrade script working correctly.
|
||||
|
||||
4. Observe the upgrade being performed in the query server log.
|
||||
|
||||
5. Verify that your queries produced sensible results.
|
||||
|
||||
#### Doing the upgrade manually
|
||||
|
||||
To create the upgrade directory manually, without using `prepare-db-upgrade.sh`:
|
||||
|
||||
1. Get a hash of the old `.dbscheme` file, from just before your changes. You can do this by checking out the code prior to your changes and running `git hash-object ql/src/ruby.dbscheme`
|
||||
|
||||
2. Go back to your branch and create an upgrade directory with that hash as its name, for example: `mkdir upgrades/454f1e15151422355049dc4f1f0486a03baeffef`
|
||||
|
||||
3. Copy the old `.dbscheme` file to that directory, using the name old.dbscheme.
|
||||
`cp ql/src/ruby.dbscheme upgrades/454f1e15151422355049dc4f1f0486a03baeffef/old.dbscheme`
|
||||
|
||||
4. Put a copy of your new `.dbscheme` file in that directory and create an `upgrade.properties` file (as described above).
|
||||
106
prepare-db-upgrade.sh
Executable file
106
prepare-db-upgrade.sh
Executable file
@@ -0,0 +1,106 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Prepare the upgrade script directory for a Ruby database schema upgrade.
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
app_name="$(basename "$0")"
|
||||
|
||||
usage()
|
||||
{
|
||||
exit_code="$1"
|
||||
shift
|
||||
|
||||
cat >&2 <<EOF
|
||||
${app_name}: $@
|
||||
${app_name}: Generate skeleton upgrade script.
|
||||
Usage: ${app_name} [--prev_hash <COMMITISH>]"
|
||||
|
||||
--prev-hash <COMMITISH>
|
||||
Hash/branch to use to get SHA1 for previous DB scheme.
|
||||
Default: origin/main
|
||||
|
||||
Must be run within the git repo needing an update.
|
||||
EOF
|
||||
exit "${exit_code}"
|
||||
}
|
||||
|
||||
prev_hash="origin/main"
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-x)
|
||||
set -x
|
||||
;;
|
||||
-h | --help)
|
||||
usage 0
|
||||
;;
|
||||
--prev-hash)
|
||||
if [ $# -eq 1 ]; then
|
||||
usage 2 "--prev-hash requires Commit/Branch option"
|
||||
fi
|
||||
shift
|
||||
prev_hash="$1"
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
usage 2 "Unrecognised option: $1"
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
usage 2 "Unrecognised operand: $1"
|
||||
fi
|
||||
|
||||
scheme_file="ql/src/ruby.dbscheme"
|
||||
upgrade_root="upgrades"
|
||||
|
||||
check_hash_valid()
|
||||
{
|
||||
if [ ${#2} -ne 40 ]; then
|
||||
echo "Did not get expected $1 hash: $2" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
# Get the hash of the previous and current DB Schema files
|
||||
prev_hash="$(git show "${prev_hash}:${scheme_file}" | git hash-object --stdin)"
|
||||
check_hash_valid previous "${prev_hash}"
|
||||
current_hash="$(git hash-object "${scheme_file}")"
|
||||
check_hash_valid current "${current_hash}"
|
||||
if [ "${current_hash}" = "${prev_hash}" ]; then
|
||||
echo "No work to be done."
|
||||
exit
|
||||
fi
|
||||
|
||||
# Copy current and new dbscheme into the upgrade dir
|
||||
upgradedir="${upgrade_root}/${prev_hash}"
|
||||
mkdir -p "${upgradedir}"
|
||||
|
||||
cp "${scheme_file}" "${upgradedir}"
|
||||
git cat-file blob "${prev_hash}" > "${upgradedir}/old.dbscheme"
|
||||
|
||||
# Create the template upgrade.properties file.
|
||||
cat <<EOF > "${upgradedir}/upgrade.properties"
|
||||
description: <INSERT DESCRIPTION HERE>
|
||||
compatibility: full|backwards|partial|breaking
|
||||
EOF
|
||||
|
||||
# Tell user what we've done
|
||||
cat <<EOF
|
||||
Created upgrade directory here:
|
||||
${upgradedir}
|
||||
|
||||
Please update:
|
||||
${upgradedir}/upgrade.properties
|
||||
with appropriate upgrade instructions
|
||||
EOF
|
||||
@@ -3,6 +3,7 @@ import ast.Call
|
||||
import ast.Control
|
||||
import ast.Constant
|
||||
import ast.Expr
|
||||
import ast.Literal
|
||||
import ast.Method
|
||||
import ast.Module
|
||||
import ast.Parameter
|
||||
|
||||
@@ -24,116 +24,6 @@ class Self extends Expr, @token_self {
|
||||
final override string getAPrimaryQlClass() { result = "Self" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A literal.
|
||||
*
|
||||
* This is the QL root class for all literals.
|
||||
*/
|
||||
class Literal extends Expr {
|
||||
override Literal::Range range;
|
||||
|
||||
/** Gets the source text for this literal, if it is constant. */
|
||||
final string getValueText() { result = range.getValueText() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An integer literal.
|
||||
* ```rb
|
||||
* x = 123
|
||||
* y = 0xff
|
||||
* ```
|
||||
*/
|
||||
class IntegerLiteral extends Literal, @token_integer {
|
||||
final override IntegerLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "IntegerLiteral" }
|
||||
}
|
||||
|
||||
/** A `nil` literal. */
|
||||
class NilLiteral extends Literal, @token_nil {
|
||||
final override NilLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "NilLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A Boolean literal.
|
||||
* ```rb
|
||||
* true
|
||||
* false
|
||||
* TRUE
|
||||
* FALSE
|
||||
* ```
|
||||
*/
|
||||
class BooleanLiteral extends Literal, BooleanLiteral::DbUnion {
|
||||
final override BooleanLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "BooleanLiteral" }
|
||||
|
||||
/** Holds if the Boolean literal is `true` or `TRUE`. */
|
||||
predicate isTrue() { range.isTrue() }
|
||||
|
||||
/** Holds if the Boolean literal is `false` or `FALSE`. */
|
||||
predicate isFalse() { range.isFalse() }
|
||||
}
|
||||
|
||||
// TODO: expand this. It's a minimal placeholder so we can test `=~` and `!~`.
|
||||
class RegexLiteral extends Literal, @regex {
|
||||
final override RegexLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "RegexLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A string literal.
|
||||
* ```rb
|
||||
* 'hello'
|
||||
* "hello, #{name}"
|
||||
* ```
|
||||
* TODO: expand this minimal placeholder.
|
||||
*/
|
||||
class StringLiteral extends Literal, @string__ {
|
||||
final override StringLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "StringLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A symbol literal.
|
||||
* ```rb
|
||||
* :foo
|
||||
* :"foo bar"
|
||||
* :"foo bar #{baz}"
|
||||
* ```
|
||||
* TODO: expand this minimal placeholder.
|
||||
*/
|
||||
class SymbolLiteral extends Literal {
|
||||
final override SymbolLiteral::Range range;
|
||||
|
||||
SymbolLiteral() {
|
||||
not any(UndefStmt u).getAMethodName() = this and
|
||||
not any(AliasStmt a).getNewName() = this and
|
||||
not any(AliasStmt a).getOldName() = this
|
||||
}
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "SymbolLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A method name literal. For example:
|
||||
* ```rb
|
||||
* - method_name # a normal name
|
||||
* - + # an operator
|
||||
* - :method_name # a symbol
|
||||
* - :"eval_#{name}" # a complex symbol
|
||||
* ```
|
||||
*/
|
||||
class MethodName extends Literal {
|
||||
final override MethodName::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "MethodName" }
|
||||
}
|
||||
|
||||
/** A sequence of expressions. */
|
||||
class StmtSequence extends Expr {
|
||||
override StmtSequence::Range range;
|
||||
@@ -322,3 +212,52 @@ class RescueModifierExpr extends Expr, @rescue_modifier {
|
||||
*/
|
||||
final Stmt getHandler() { result = range.getHandler() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A concatenation of string literals.
|
||||
*
|
||||
* ```rb
|
||||
* "foo" "bar" "baz"
|
||||
* ```
|
||||
*/
|
||||
class StringConcatenation extends Expr, @chained_string {
|
||||
final override StringConcatenation::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "StringConcatenation" }
|
||||
|
||||
/** Gets the `n`th string literal in this concatenation. */
|
||||
final StringLiteral getString(int n) { result = range.getString(n) }
|
||||
|
||||
/** Gets a string literal in this concatenation. */
|
||||
final StringLiteral getAString() { result = this.getString(_) }
|
||||
|
||||
/** Gets the number of string literals in this concatenation. */
|
||||
final int getNumberOfStrings() { result = count(this.getString(_)) }
|
||||
|
||||
/**
|
||||
* Gets the result of concatenating all the string literals, if and only if
|
||||
* they do not contain any interpolations.
|
||||
*
|
||||
* For the following example, the result is `"foobar"`:
|
||||
*
|
||||
* ```rb
|
||||
* "foo" 'bar'
|
||||
* ```
|
||||
*
|
||||
* And for the following example, where one of the string literals includes
|
||||
* an interpolation, there is no result:
|
||||
*
|
||||
* ```rb
|
||||
* "foo" "bar#{ n }"
|
||||
* ```
|
||||
*/
|
||||
final string getConcatenatedValueText() {
|
||||
forall(StringLiteral c | c = this.getString(_) | exists(c.getValueText())) and
|
||||
result =
|
||||
concat(string valueText, int i |
|
||||
valueText = this.getString(i).getValueText()
|
||||
|
|
||||
valueText order by i
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
410
ql/src/codeql_ruby/ast/Literal.qll
Normal file
410
ql/src/codeql_ruby/ast/Literal.qll
Normal file
@@ -0,0 +1,410 @@
|
||||
private import codeql_ruby.AST
|
||||
private import internal.Literal
|
||||
|
||||
/**
|
||||
* A literal.
|
||||
*
|
||||
* This is the QL root class for all literals.
|
||||
*/
|
||||
class Literal extends Expr {
|
||||
override Literal::Range range;
|
||||
|
||||
/**
|
||||
* Gets the source text for this literal, if this is a simple literal.
|
||||
*
|
||||
* For complex literals, such as arrays, hashes, and strings with
|
||||
* interpolations, this predicate has no result.
|
||||
*/
|
||||
final string getValueText() { result = range.getValueText() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A numeric literal, i.e. an integer, floating-point, rational, or complex
|
||||
* value.
|
||||
*
|
||||
* ```rb
|
||||
* 123
|
||||
* 0xff
|
||||
* 3.14159
|
||||
* 1.0E2
|
||||
* 7r
|
||||
* 1i
|
||||
* ```
|
||||
*/
|
||||
class NumericLiteral extends Literal {
|
||||
override NumericLiteral::Range range;
|
||||
}
|
||||
|
||||
/**
|
||||
* An integer literal.
|
||||
*
|
||||
* ```rb
|
||||
* 123
|
||||
* 0xff
|
||||
* ```
|
||||
*/
|
||||
class IntegerLiteral extends NumericLiteral, @token_integer {
|
||||
final override IntegerLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "IntegerLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A floating-point literal.
|
||||
*
|
||||
* ```rb
|
||||
* 1.3
|
||||
* 2.7e+5
|
||||
* ```
|
||||
*/
|
||||
class FloatLiteral extends NumericLiteral, @token_float {
|
||||
final override FloatLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "FloatLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A rational literal.
|
||||
*
|
||||
* ```rb
|
||||
* 123r
|
||||
* ```
|
||||
*/
|
||||
class RationalLiteral extends NumericLiteral, @rational {
|
||||
final override RationalLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "RationalLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A complex literal.
|
||||
*
|
||||
* ```rb
|
||||
* 1i
|
||||
* ```
|
||||
*/
|
||||
class ComplexLiteral extends NumericLiteral, @token_complex {
|
||||
final override ComplexLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "ComplexLiteral" }
|
||||
}
|
||||
|
||||
/** A `nil` literal. */
|
||||
class NilLiteral extends Literal, @token_nil {
|
||||
final override NilLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "NilLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A Boolean literal.
|
||||
* ```rb
|
||||
* true
|
||||
* false
|
||||
* TRUE
|
||||
* FALSE
|
||||
* ```
|
||||
*/
|
||||
class BooleanLiteral extends Literal, BooleanLiteral::DbUnion {
|
||||
final override BooleanLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "BooleanLiteral" }
|
||||
|
||||
/** Holds if the Boolean literal is `true` or `TRUE`. */
|
||||
predicate isTrue() { range.isTrue() }
|
||||
|
||||
/** Holds if the Boolean literal is `false` or `FALSE`. */
|
||||
predicate isFalse() { range.isFalse() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The base class for a component of a string: `StringTextComponent`,
|
||||
* `StringEscapeSequenceComponent`, or `StringInterpolationComponent`.
|
||||
*/
|
||||
class StringComponent extends AstNode {
|
||||
override StringComponent::Range range;
|
||||
|
||||
/**
|
||||
* Gets the source text for this string component. Has no result if this is
|
||||
* a `StringInterpolationComponent`.
|
||||
*/
|
||||
final string getValueText() { result = range.getValueText() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A component of a string (or string-like) literal that is simply text.
|
||||
*
|
||||
* For example, the following string literals all contain `StringTextComponent`
|
||||
* components whose `getValueText()` returns `"foo"`:
|
||||
*
|
||||
* ```rb
|
||||
* 'foo'
|
||||
* "#{ bar() }foo"
|
||||
* "foo#{ bar() } baz"
|
||||
* ```
|
||||
*/
|
||||
class StringTextComponent extends StringComponent, @token_string_content {
|
||||
final override StringTextComponent::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "StringTextComponent" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An escape sequence component of a string or string-like literal.
|
||||
*/
|
||||
class StringEscapeSequenceComponent extends StringComponent, @token_escape_sequence {
|
||||
final override StringEscapeSequenceComponent::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "StringEscapeSequenceComponent" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An interpolation expression component of a string or string-like literal.
|
||||
*/
|
||||
class StringInterpolationComponent extends StringComponent, StmtSequence, @interpolation {
|
||||
final override StringInterpolationComponent::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "StringInterpolationComponent" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A string, symbol, regex, or subshell literal.
|
||||
*/
|
||||
class StringlikeLiteral extends Literal {
|
||||
override StringlikeLiteral::Range range;
|
||||
|
||||
/**
|
||||
* Gets the `n`th component of this string or string-like literal. The result
|
||||
* will be one of `StringTextComponent`, `StringInterpolationComponent`, and
|
||||
* `StringEscapeSequenceComponent`.
|
||||
*
|
||||
* In the following example, the result for `n = 0` is the
|
||||
* `StringTextComponent` for `foo_`, and the result for `n = 1` is the
|
||||
* `StringInterpolationComponent` for `Time.now`.
|
||||
*
|
||||
* ```rb
|
||||
* "foo_#{ Time.now }"
|
||||
* ```
|
||||
*/
|
||||
final StringComponent getComponent(int n) { result = range.getComponent(n) }
|
||||
|
||||
/**
|
||||
* Gets the number of components in this string or string-like literal.
|
||||
*
|
||||
* For the empty string `""`, the result is 0.
|
||||
*
|
||||
* For the string `"foo"`, the result is 1: there is a single
|
||||
* `StringTextComponent`.
|
||||
*
|
||||
* For the following example, the result is 3: there is a
|
||||
* `StringTextComponent` for the substring `"foo_"`; a
|
||||
* `StringEscapeSequenceComponent` for the escaped quote; and a
|
||||
* `StringInterpolationComponent` for the interpolation.
|
||||
*
|
||||
* ```rb
|
||||
* "foo\"#{bar}"
|
||||
* ```
|
||||
*/
|
||||
final int getNumberOfComponents() { result = count(this.getComponent(_)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A string literal.
|
||||
*
|
||||
* ```rb
|
||||
* 'hello'
|
||||
* "hello, #{name}"
|
||||
* ```
|
||||
*/
|
||||
class StringLiteral extends StringlikeLiteral {
|
||||
final override StringLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "StringLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A regular expression literal.
|
||||
*
|
||||
* ```rb
|
||||
* /[a-z]+/
|
||||
* ```
|
||||
*/
|
||||
class RegexLiteral extends StringlikeLiteral, @regex {
|
||||
final override RegexLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "RegexLiteral" }
|
||||
|
||||
/**
|
||||
* Gets the regex flags as a string.
|
||||
*
|
||||
* ```rb
|
||||
* /foo/ # => ""
|
||||
* /foo/i # => "i"
|
||||
* /foo/imxo # => "imxo"
|
||||
*/
|
||||
final string getFlagString() { result = range.getFlagString() }
|
||||
|
||||
/**
|
||||
* Holds if the regex was specified using the `i` flag to indicate case
|
||||
* insensitivity, as in the following example:
|
||||
*
|
||||
* ```rb
|
||||
* /foo/i
|
||||
* ```
|
||||
*/
|
||||
final predicate hasCaseInsensitiveFlag() { this.getFlagString().charAt(_) = "i" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A symbol literal.
|
||||
*
|
||||
* ```rb
|
||||
* :foo
|
||||
* :"foo bar"
|
||||
* :"foo bar #{baz}"
|
||||
* ```
|
||||
*/
|
||||
class SymbolLiteral extends StringlikeLiteral {
|
||||
final override SymbolLiteral::Range range;
|
||||
|
||||
SymbolLiteral() {
|
||||
not any(UndefStmt u).getAMethodName() = this and
|
||||
not any(AliasStmt a).getNewName() = this and
|
||||
not any(AliasStmt a).getOldName() = this
|
||||
}
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "SymbolLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A subshell literal.
|
||||
*
|
||||
* ```rb
|
||||
* `ls -l`
|
||||
* %x(/bin/sh foo.sh)
|
||||
* ```
|
||||
*/
|
||||
class SubshellLiteral extends StringlikeLiteral, @subshell {
|
||||
final override SubshellLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "SubshellLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A character literal.
|
||||
*
|
||||
* ```rb
|
||||
* ?a
|
||||
* ?\u{61}
|
||||
* ```
|
||||
*/
|
||||
class CharacterLiteral extends Literal, @token_character {
|
||||
final override CharacterLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "CharacterLiteral" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An array literal.
|
||||
*
|
||||
* ```rb
|
||||
* [123, 'foo', bar()]
|
||||
* %w(foo bar)
|
||||
* %i(foo bar)
|
||||
* ```
|
||||
*/
|
||||
class ArrayLiteral extends Literal {
|
||||
final override ArrayLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "ArrayLiteral" }
|
||||
|
||||
/** Gets the `n`th element in this array literal. */
|
||||
final Expr getElement(int n) { result = range.getElement(n) }
|
||||
|
||||
/** Gets an element in this array literal. */
|
||||
final Expr getAnElement() { result = range.getElement(_) }
|
||||
|
||||
/** Gets the number of elements in this array literal. */
|
||||
final int getNumberOfElements() { result = count(range.getElement(_)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A hash literal.
|
||||
*
|
||||
* ```rb
|
||||
* { foo: 123, bar: 456 }
|
||||
* ```
|
||||
*/
|
||||
class HashLiteral extends Literal, @hash {
|
||||
final override HashLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "HashLiteral" }
|
||||
|
||||
/**
|
||||
* Gets the `n`th element in this array literal.
|
||||
*
|
||||
* In the following example, the 0th element is a `Pair`, and the 1st element
|
||||
* is a `HashSplatArgument`.
|
||||
*
|
||||
* ```rb
|
||||
* { foo: 123, **bar }
|
||||
* ```
|
||||
*/
|
||||
final Expr getElement(int n) { result = range.getElement(n) }
|
||||
|
||||
/** Gets an element in this array literal. */
|
||||
final Expr getAnElement() { result = range.getElement(_) }
|
||||
|
||||
/** Gets a key-value `Pair` in this hash literal. */
|
||||
final Pair getAKeyValuePair() { result = this.getAnElement() }
|
||||
|
||||
/** Gets the number of elements in this hash literal. */
|
||||
final int getNumberOfElements() { result = count(range.getElement(_)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A range literal.
|
||||
*
|
||||
* ```rb
|
||||
* (1..10)
|
||||
* (1024...2048)
|
||||
* ```
|
||||
*/
|
||||
class RangeLiteral extends Literal, @range {
|
||||
final override RangeLiteral::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "RangeLiteral" }
|
||||
|
||||
/** Gets the begin expression of this range, if any. */
|
||||
final Expr getBegin() { result = range.getBegin() }
|
||||
|
||||
/** Gets the end expression of this range, if any. */
|
||||
final Expr getEnd() { result = range.getEnd() }
|
||||
|
||||
/**
|
||||
* Holds if the range is inclusive of the end value, i.e. uses the `..`
|
||||
* operator.
|
||||
*/
|
||||
final predicate isInclusive() { range.isInclusive() }
|
||||
|
||||
/**
|
||||
* Holds if the range is exclusive of the end value, i.e. uses the `...`
|
||||
* operator.
|
||||
*/
|
||||
final predicate isExclusive() { range.isExclusive() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A method name literal. For example:
|
||||
* ```rb
|
||||
* method_name # a normal name
|
||||
* + # an operator
|
||||
* :method_name # a symbol
|
||||
* :"eval_#{name}" # a complex symbol
|
||||
* ```
|
||||
*/
|
||||
class MethodName extends Literal {
|
||||
final override MethodName::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "MethodName" }
|
||||
}
|
||||
@@ -29,37 +29,13 @@ module AstNode {
|
||||
or
|
||||
this instanceof Generated::RestAssignment
|
||||
or
|
||||
this instanceof Generated::SymbolArray
|
||||
or
|
||||
this instanceof Generated::Interpolation
|
||||
or
|
||||
this instanceof Generated::StringArray
|
||||
or
|
||||
this instanceof Generated::BareString
|
||||
or
|
||||
this instanceof Generated::Float
|
||||
or
|
||||
this instanceof Generated::Superclass
|
||||
or
|
||||
this instanceof Generated::Hash
|
||||
or
|
||||
this instanceof Generated::Array
|
||||
or
|
||||
this instanceof Generated::Complex
|
||||
or
|
||||
this instanceof Generated::Character
|
||||
or
|
||||
this instanceof Generated::HeredocBody
|
||||
or
|
||||
this instanceof Generated::HeredocBeginning
|
||||
or
|
||||
this instanceof Generated::HeredocEnd
|
||||
or
|
||||
this instanceof Generated::Range
|
||||
or
|
||||
this instanceof Generated::Rational
|
||||
or
|
||||
this instanceof Generated::Subshell
|
||||
}
|
||||
|
||||
override string toString() { result = "AstNode" }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
private import codeql_ruby.AST
|
||||
private import codeql_ruby.ast.internal.Literal
|
||||
private import codeql_ruby.ast.internal.Statement
|
||||
private import codeql_ruby.ast.internal.TreeSitter
|
||||
|
||||
@@ -14,194 +15,6 @@ module Self {
|
||||
}
|
||||
}
|
||||
|
||||
module Literal {
|
||||
abstract class Range extends Expr::Range {
|
||||
abstract string getValueText();
|
||||
|
||||
override string toString() { result = this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module IntegerLiteral {
|
||||
class Range extends Literal::Range, @token_integer {
|
||||
final override Generated::Integer generated;
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module NilLiteral {
|
||||
class Range extends Literal::Range, @token_nil {
|
||||
final override Generated::Nil generated;
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module BooleanLiteral {
|
||||
class DbUnion = @token_true or @token_false;
|
||||
|
||||
class Range extends Literal::Range, DbUnion {
|
||||
final override Generated::Token generated;
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
|
||||
predicate isTrue() { this instanceof @token_true }
|
||||
|
||||
predicate isFalse() { this instanceof @token_false }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: expand this. It's a minimal placeholder so we can test `=~` and `!~`.
|
||||
module RegexLiteral {
|
||||
class Range extends Literal::Range, @regex {
|
||||
final override Generated::Regex generated;
|
||||
|
||||
final override string getValueText() {
|
||||
forall(AstNode n | n = generated.getChild(_) | n instanceof Generated::Token) and
|
||||
result =
|
||||
concat(int i, string s |
|
||||
s = generated.getChild(i).(Generated::Token).getValue()
|
||||
|
|
||||
s order by i
|
||||
)
|
||||
}
|
||||
|
||||
final override string toString() {
|
||||
result =
|
||||
concat(Generated::AstNode c, int i, string s |
|
||||
c = generated.getChild(i) and
|
||||
if c instanceof Generated::Token
|
||||
then s = c.(Generated::Token).getValue()
|
||||
else s = "#{...}"
|
||||
|
|
||||
s order by i
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: expand this minimal placeholder.
|
||||
module StringLiteral {
|
||||
class Range extends Literal::Range, @string__ {
|
||||
final override Generated::String generated;
|
||||
|
||||
final override string getValueText() {
|
||||
strictcount(generated.getChild(_)) = 1 and
|
||||
result = generated.getChild(0).(Generated::Token).getValue()
|
||||
}
|
||||
|
||||
final override string toString() {
|
||||
result =
|
||||
concat(Generated::AstNode c, int i, string s |
|
||||
c = generated.getChild(i) and
|
||||
if c instanceof Generated::Token
|
||||
then s = c.(Generated::Token).getValue()
|
||||
else s = "#{...}"
|
||||
|
|
||||
s order by i
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: expand this minimal placeholder.
|
||||
module SymbolLiteral {
|
||||
abstract class Range extends Literal::Range { }
|
||||
|
||||
class SimpleSymbolRange extends SymbolLiteral::Range {
|
||||
final override Generated::SimpleSymbol generated;
|
||||
|
||||
// Tree-sitter gives us value text including the colon, which we skip.
|
||||
final override string getValueText() { result = generated.getValue().suffix(1) }
|
||||
|
||||
final override string toString() { result = generated.getValue() }
|
||||
}
|
||||
|
||||
abstract private class ComplexSymbolRange extends SymbolLiteral::Range {
|
||||
abstract Generated::AstNode getChild(int i);
|
||||
|
||||
final override string getValueText() {
|
||||
strictcount(this.getChild(_)) = 1 and
|
||||
result = this.getChild(0).(Generated::Token).getValue()
|
||||
}
|
||||
|
||||
private string summaryString() {
|
||||
result =
|
||||
concat(Generated::AstNode c, int i, string s |
|
||||
c = this.getChild(i) and
|
||||
if c instanceof Generated::Token
|
||||
then s = c.(Generated::Token).getValue()
|
||||
else s = "#{...}"
|
||||
|
|
||||
s order by i
|
||||
)
|
||||
}
|
||||
|
||||
final override string toString() {
|
||||
if summaryString().regexpMatch("[a-zA-z_][a-zA-Z_0-9]*")
|
||||
then result = ":" + summaryString()
|
||||
else result = ":\"" + summaryString() + "\""
|
||||
}
|
||||
}
|
||||
|
||||
class DelimitedSymbolRange extends ComplexSymbolRange, @delimited_symbol {
|
||||
final override Generated::DelimitedSymbol generated;
|
||||
|
||||
final override Generated::AstNode getChild(int i) { result = generated.getChild(i) }
|
||||
}
|
||||
|
||||
class BareSymbolRange extends ComplexSymbolRange, @bare_symbol {
|
||||
final override Generated::BareSymbol generated;
|
||||
|
||||
final override Generated::AstNode getChild(int i) { result = generated.getChild(i) }
|
||||
}
|
||||
|
||||
class HashKeySymbolRange extends SymbolLiteral::Range, @token_hash_key_symbol {
|
||||
final override Generated::HashKeySymbol generated;
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = ":" + this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module MethodName {
|
||||
private class TokenTypes =
|
||||
@setter or @token_class_variable or @token_constant or @token_global_variable or
|
||||
@token_identifier or @token_instance_variable or @token_operator;
|
||||
|
||||
abstract class Range extends Literal::Range, @underscore_method_name {
|
||||
Range() {
|
||||
exists(Generated::Undef u | u.getChild(_) = generated)
|
||||
or
|
||||
exists(Generated::Alias a | a.getName() = generated or a.getAlias() = generated)
|
||||
}
|
||||
}
|
||||
|
||||
private class TokenMethodName extends MethodName::Range, TokenTypes {
|
||||
final override Generated::UnderscoreMethodName generated;
|
||||
|
||||
final override string getValueText() {
|
||||
result = generated.(Generated::Token).getValue()
|
||||
or
|
||||
result = generated.(Generated::Setter).getName().getValue() + "="
|
||||
}
|
||||
}
|
||||
|
||||
private class SimpleSymbolMethodName extends MethodName::Range, SymbolLiteral::SimpleSymbolRange,
|
||||
@token_simple_symbol { }
|
||||
|
||||
private class DelimitedSymbolMethodName extends MethodName::Range,
|
||||
SymbolLiteral::DelimitedSymbolRange, @delimited_symbol { }
|
||||
}
|
||||
|
||||
module StmtSequence {
|
||||
abstract class Range extends Expr::Range {
|
||||
abstract Stmt getStmt(int n);
|
||||
@@ -343,3 +156,13 @@ module Pair {
|
||||
final override string toString() { result = "Pair" }
|
||||
}
|
||||
}
|
||||
|
||||
module StringConcatenation {
|
||||
class Range extends Expr::Range, @chained_string {
|
||||
final override Generated::ChainedString generated;
|
||||
|
||||
final StringLiteral::Range getString(int i) { result = generated.getChild(i) }
|
||||
|
||||
final override string toString() { result = "\"...\" \"...\"" }
|
||||
}
|
||||
}
|
||||
|
||||
380
ql/src/codeql_ruby/ast/internal/Literal.qll
Normal file
380
ql/src/codeql_ruby/ast/internal/Literal.qll
Normal file
@@ -0,0 +1,380 @@
|
||||
private import codeql_ruby.AST
|
||||
private import codeql_ruby.ast.internal.AST
|
||||
private import codeql_ruby.ast.internal.Expr
|
||||
private import codeql_ruby.ast.internal.TreeSitter
|
||||
|
||||
module Literal {
|
||||
abstract class Range extends Expr::Range {
|
||||
abstract string getValueText();
|
||||
|
||||
override string toString() { result = this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module NumericLiteral {
|
||||
abstract class Range extends Literal::Range { }
|
||||
}
|
||||
|
||||
module IntegerLiteral {
|
||||
class Range extends NumericLiteral::Range, @token_integer {
|
||||
final override Generated::Integer generated;
|
||||
|
||||
Range() { not any(Generated::Rational r).getChild() = this }
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module FloatLiteral {
|
||||
class Range extends NumericLiteral::Range, @token_float {
|
||||
final override Generated::Float generated;
|
||||
|
||||
Range() { not any(Generated::Rational r).getChild() = this }
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module RationalLiteral {
|
||||
class Range extends NumericLiteral::Range, @rational {
|
||||
final override Generated::Rational generated;
|
||||
|
||||
final override string getValueText() {
|
||||
result = generated.getChild().(Generated::Token).getValue() + "r"
|
||||
}
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module ComplexLiteral {
|
||||
class Range extends NumericLiteral::Range, @token_complex {
|
||||
final override Generated::Complex generated;
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module NilLiteral {
|
||||
class Range extends Literal::Range, @token_nil {
|
||||
final override Generated::Nil generated;
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module BooleanLiteral {
|
||||
class DbUnion = @token_true or @token_false;
|
||||
|
||||
class Range extends Literal::Range, DbUnion {
|
||||
final override Generated::Token generated;
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = this.getValueText() }
|
||||
|
||||
predicate isTrue() { this instanceof @token_true }
|
||||
|
||||
predicate isFalse() { this instanceof @token_false }
|
||||
}
|
||||
}
|
||||
|
||||
module StringComponent {
|
||||
abstract class Range extends AstNode::Range {
|
||||
abstract string getValueText();
|
||||
}
|
||||
}
|
||||
|
||||
module StringTextComponent {
|
||||
class Range extends StringComponent::Range, @token_string_content {
|
||||
final override Generated::StringContent generated;
|
||||
|
||||
final override string toString() { result = generated.getValue() }
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
}
|
||||
}
|
||||
|
||||
module StringEscapeSequenceComponent {
|
||||
class Range extends StringComponent::Range, @token_escape_sequence {
|
||||
final override Generated::EscapeSequence generated;
|
||||
|
||||
final override string toString() { result = generated.getValue() }
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
}
|
||||
}
|
||||
|
||||
module StringInterpolationComponent {
|
||||
class Range extends StringComponent::Range, StmtSequence::Range, @interpolation {
|
||||
final override Generated::Interpolation generated;
|
||||
|
||||
final override string toString() { result = "#{...}" }
|
||||
|
||||
final override Stmt getStmt(int n) {
|
||||
// Generated AST can currently only represent a single statement in an interpolation.
|
||||
n = 0 and
|
||||
result = generated.getChild()
|
||||
}
|
||||
|
||||
final override string getValueText() { none() }
|
||||
}
|
||||
}
|
||||
|
||||
module StringlikeLiteral {
|
||||
abstract class Range extends Literal::Range {
|
||||
abstract StringComponent::Range getComponent(int i);
|
||||
|
||||
string getStartDelimiter() { result = "" }
|
||||
|
||||
string getEndDelimiter() { result = "" }
|
||||
|
||||
final predicate isSimple() { count(this.getComponent(_)) <= 1 }
|
||||
|
||||
override string getValueText() {
|
||||
// 0 components should result in the empty string
|
||||
// if there are any interpolations, there should be no result
|
||||
// otherwise, concatenate all the components
|
||||
forall(StringComponent c | c = this.getComponent(_) |
|
||||
not c instanceof StringInterpolationComponent::Range
|
||||
) and
|
||||
result =
|
||||
concat(StringComponent::Range c, int i |
|
||||
c = this.getComponent(i)
|
||||
|
|
||||
c.getValueText() order by i
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
exists(string full, string summary |
|
||||
full =
|
||||
concat(StringComponent::Range c, int i, string s |
|
||||
c = this.getComponent(i) and
|
||||
if c instanceof Generated::Token
|
||||
then s = c.(Generated::Token).getValue()
|
||||
else s = "#{...}"
|
||||
|
|
||||
s order by i
|
||||
) and
|
||||
(
|
||||
// summary should be 32 chars max (incl. ellipsis)
|
||||
full.length() > 32 and summary = full.substring(0, 29) + "..."
|
||||
or
|
||||
full.length() <= 32 and summary = full
|
||||
) and
|
||||
result = this.getStartDelimiter() + summary + this.getEndDelimiter()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module StringLiteral {
|
||||
abstract class Range extends StringlikeLiteral::Range {
|
||||
final override string getStartDelimiter() { result = "\"" }
|
||||
|
||||
final override string getEndDelimiter() { result = "\"" }
|
||||
}
|
||||
|
||||
private class RegularStringRange extends StringLiteral::Range, @string__ {
|
||||
final override Generated::String generated;
|
||||
|
||||
final override StringComponent::Range getComponent(int i) { result = generated.getChild(i) }
|
||||
}
|
||||
|
||||
private class BareStringRange extends StringLiteral::Range, @bare_string {
|
||||
final override Generated::BareString generated;
|
||||
|
||||
final override StringComponent::Range getComponent(int i) { result = generated.getChild(i) }
|
||||
}
|
||||
}
|
||||
|
||||
module RegexLiteral {
|
||||
class Range extends StringlikeLiteral::Range, @regex {
|
||||
final override Generated::Regex generated;
|
||||
|
||||
final override StringComponent::Range getComponent(int i) { result = generated.getChild(i) }
|
||||
|
||||
final override string getStartDelimiter() { result = "/" }
|
||||
|
||||
final override string getEndDelimiter() { result = "/" }
|
||||
|
||||
final string getFlagString() {
|
||||
// For `/foo/i`, there should be an `/i` token in the database with `this`
|
||||
// as its parents. Strip the delimiter, which can vary.
|
||||
result =
|
||||
max(Generated::Token t |
|
||||
t.getParent() = this
|
||||
|
|
||||
t.getValue().suffix(1) order by t.getParentIndex()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module SymbolLiteral {
|
||||
abstract class Range extends StringlikeLiteral::Range { }
|
||||
|
||||
class SimpleSymbolRange extends SymbolLiteral::Range {
|
||||
final override Generated::SimpleSymbol generated;
|
||||
|
||||
final override StringComponent::Range getComponent(int i) { none() }
|
||||
|
||||
final override string getStartDelimiter() { result = ":" }
|
||||
|
||||
// Tree-sitter gives us value text including the colon, which we skip.
|
||||
final override string getValueText() { result = generated.getValue().suffix(1) }
|
||||
|
||||
final override string toString() { result = generated.getValue() }
|
||||
}
|
||||
|
||||
abstract private class ComplexSymbolRange extends SymbolLiteral::Range {
|
||||
final override string getStartDelimiter() { result = ":\"" }
|
||||
|
||||
final override string getEndDelimiter() { result = "\"" }
|
||||
}
|
||||
|
||||
class DelimitedSymbolRange extends ComplexSymbolRange, @delimited_symbol {
|
||||
final override Generated::DelimitedSymbol generated;
|
||||
|
||||
final override StringComponent::Range getComponent(int i) { result = generated.getChild(i) }
|
||||
}
|
||||
|
||||
class BareSymbolRange extends ComplexSymbolRange, @bare_symbol {
|
||||
final override Generated::BareSymbol generated;
|
||||
|
||||
final override StringComponent::Range getComponent(int i) { result = generated.getChild(i) }
|
||||
}
|
||||
|
||||
class HashKeySymbolRange extends SymbolLiteral::Range, @token_hash_key_symbol {
|
||||
final override Generated::HashKeySymbol generated;
|
||||
|
||||
final override StringComponent::Range getComponent(int i) { none() }
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = ":" + this.getValueText() }
|
||||
}
|
||||
}
|
||||
|
||||
module SubshellLiteral {
|
||||
class Range extends StringlikeLiteral::Range, @subshell {
|
||||
final override Generated::Subshell generated;
|
||||
|
||||
final override StringComponent::Range getComponent(int i) { result = generated.getChild(i) }
|
||||
|
||||
final override string getStartDelimiter() { result = "`" }
|
||||
|
||||
final override string getEndDelimiter() { result = "`" }
|
||||
}
|
||||
}
|
||||
|
||||
module CharacterLiteral {
|
||||
class Range extends Literal::Range, @token_character {
|
||||
final override Generated::Character generated;
|
||||
|
||||
final override string getValueText() { result = generated.getValue() }
|
||||
|
||||
final override string toString() { result = generated.getValue() }
|
||||
}
|
||||
}
|
||||
|
||||
module ArrayLiteral {
|
||||
abstract class Range extends Literal::Range {
|
||||
final override string getValueText() { none() }
|
||||
|
||||
abstract Expr getElement(int i);
|
||||
}
|
||||
|
||||
private class RegularArrayRange extends ArrayLiteral::Range, @array {
|
||||
final override Generated::Array generated;
|
||||
|
||||
final override Expr getElement(int i) { result = generated.getChild(i) }
|
||||
|
||||
final override string toString() { result = "[...]" }
|
||||
}
|
||||
|
||||
private class StringArrayRange extends ArrayLiteral::Range, @string_array {
|
||||
final override Generated::StringArray generated;
|
||||
|
||||
final override Expr getElement(int i) { result = generated.getChild(i) }
|
||||
|
||||
final override string toString() { result = "%w(...)" }
|
||||
}
|
||||
|
||||
private class SymbolArrayRange extends ArrayLiteral::Range, @symbol_array {
|
||||
final override Generated::SymbolArray generated;
|
||||
|
||||
final override Expr getElement(int i) { result = generated.getChild(i) }
|
||||
|
||||
final override string toString() { result = "%i(...)" }
|
||||
}
|
||||
}
|
||||
|
||||
module HashLiteral {
|
||||
class Range extends Literal::Range, @hash {
|
||||
final override Generated::Hash generated;
|
||||
|
||||
final override string getValueText() { none() }
|
||||
|
||||
final Expr getElement(int i) { result = generated.getChild(i) }
|
||||
|
||||
final override string toString() { result = "{...}" }
|
||||
}
|
||||
}
|
||||
|
||||
module RangeLiteral {
|
||||
class Range extends Literal::Range, @range {
|
||||
final override Generated::Range generated;
|
||||
|
||||
final override string getValueText() { none() }
|
||||
|
||||
final override string toString() { result = "_ " + generated.getOperator() + " _" }
|
||||
|
||||
final Expr getBegin() { result = generated.getBegin() }
|
||||
|
||||
final Expr getEnd() { result = generated.getEnd() }
|
||||
|
||||
final predicate isInclusive() { this instanceof @range_dotdot }
|
||||
|
||||
final predicate isExclusive() { this instanceof @range_dotdotdot }
|
||||
}
|
||||
}
|
||||
|
||||
module MethodName {
|
||||
private class TokenTypes =
|
||||
@setter or @token_class_variable or @token_constant or @token_global_variable or
|
||||
@token_identifier or @token_instance_variable or @token_operator;
|
||||
|
||||
abstract class Range extends Literal::Range, @underscore_method_name {
|
||||
Range() {
|
||||
exists(Generated::Undef u | u.getChild(_) = generated)
|
||||
or
|
||||
exists(Generated::Alias a | a.getName() = generated or a.getAlias() = generated)
|
||||
}
|
||||
}
|
||||
|
||||
private class TokenMethodName extends MethodName::Range, TokenTypes {
|
||||
final override Generated::UnderscoreMethodName generated;
|
||||
|
||||
final override string getValueText() {
|
||||
result = generated.(Generated::Token).getValue()
|
||||
or
|
||||
result = generated.(Generated::Setter).getName().getValue() + "="
|
||||
}
|
||||
}
|
||||
|
||||
private class SimpleSymbolMethodName extends MethodName::Range, SymbolLiteral::SimpleSymbolRange,
|
||||
@token_simple_symbol { }
|
||||
|
||||
private class DelimitedSymbolMethodName extends MethodName::Range,
|
||||
SymbolLiteral::DelimitedSymbolRange, @delimited_symbol { }
|
||||
}
|
||||
@@ -1083,15 +1083,25 @@ module Generated {
|
||||
class Range extends @range, AstNode {
|
||||
override string getAPrimaryQlClass() { result = "Range" }
|
||||
|
||||
override Location getLocation() { range_def(this, _, _, result) }
|
||||
override Location getLocation() { range_def(this, _, _, _, result) }
|
||||
|
||||
UnderscoreArg getChild(int i) { range_child(this, i, result) }
|
||||
UnderscoreArg getBegin() { range_begin(this, result) }
|
||||
|
||||
override AstNode getParent() { range_def(this, result, _, _) }
|
||||
UnderscoreArg getEnd() { range_end(this, result) }
|
||||
|
||||
override int getParentIndex() { range_def(this, _, result, _) }
|
||||
string getOperator() {
|
||||
exists(int value | range_def(this, _, _, value, _) |
|
||||
result = ".." and value = 0
|
||||
or
|
||||
result = "..." and value = 1
|
||||
)
|
||||
}
|
||||
|
||||
override AstNode getAFieldOrChild() { range_child(this, _, result) }
|
||||
override AstNode getParent() { range_def(this, result, _, _, _) }
|
||||
|
||||
override int getParentIndex() { range_def(this, _, result, _, _) }
|
||||
|
||||
override AstNode getAFieldOrChild() { range_begin(this, result) or range_end(this, result) }
|
||||
}
|
||||
|
||||
class Rational extends @rational, AstNode {
|
||||
|
||||
@@ -264,7 +264,9 @@ private module Cached {
|
||||
or
|
||||
i = any(Generated::Program x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Range x).getChild(_)
|
||||
i = any(Generated::Range x).getBegin()
|
||||
or
|
||||
i = any(Generated::Range x).getEnd()
|
||||
or
|
||||
i = any(Generated::RescueModifier x).getBody()
|
||||
or
|
||||
|
||||
@@ -965,18 +965,28 @@ program_def(
|
||||
int loc: @location ref
|
||||
);
|
||||
|
||||
#keyset[range, index]
|
||||
range_child(
|
||||
int range: @range ref,
|
||||
int index: int ref,
|
||||
unique int child: @underscore_arg ref
|
||||
range_begin(
|
||||
unique int range: @range ref,
|
||||
unique int begin: @underscore_arg ref
|
||||
);
|
||||
|
||||
range_end(
|
||||
unique int range: @range ref,
|
||||
unique int end: @underscore_arg ref
|
||||
);
|
||||
|
||||
case @range.operator of
|
||||
0 = @range_dotdot
|
||||
| 1 = @range_dotdotdot
|
||||
;
|
||||
|
||||
|
||||
#keyset[parent, parent_index]
|
||||
range_def(
|
||||
unique int id: @range,
|
||||
int parent: @ast_node_parent ref,
|
||||
int parent_index: int ref,
|
||||
int operator: int ref,
|
||||
int loc: @location ref
|
||||
);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -79,7 +79,7 @@ callsWithArguments
|
||||
| calls.rb:14:1:14:11 | call to foo | foo | 0 | calls.rb:14:5:14:5 | 0 |
|
||||
| calls.rb:14:1:14:11 | call to foo | foo | 1 | calls.rb:14:8:14:8 | 1 |
|
||||
| calls.rb:14:1:14:11 | call to foo | foo | 2 | calls.rb:14:11:14:11 | 2 |
|
||||
| calls.rb:25:1:27:3 | call to bar | bar | 0 | calls.rb:25:9:25:13 | foo |
|
||||
| calls.rb:25:1:27:3 | call to bar | bar | 0 | calls.rb:25:9:25:13 | "foo" |
|
||||
| calls.rb:36:3:36:16 | call to yield | yield | 0 | calls.rb:36:9:36:11 | 100 |
|
||||
| calls.rb:36:3:36:16 | call to yield | yield | 1 | calls.rb:36:14:36:16 | 200 |
|
||||
| calls.rb:54:1:54:14 | call to some_func | some_func | 0 | calls.rb:54:11:54:13 | call to foo |
|
||||
@@ -94,7 +94,7 @@ callsWithArguments
|
||||
| calls.rb:275:1:275:13 | call to foo | foo | 0 | calls.rb:275:5:275:12 | **... |
|
||||
| calls.rb:278:1:278:14 | call to foo | foo | 0 | calls.rb:278:5:278:13 | Pair |
|
||||
| calls.rb:279:1:279:17 | call to foo | foo | 0 | calls.rb:279:5:279:16 | Pair |
|
||||
| calls.rb:288:5:288:16 | call to super | super | 0 | calls.rb:288:11:288:16 | blah |
|
||||
| calls.rb:288:5:288:16 | call to super | super | 0 | calls.rb:288:11:288:16 | "blah" |
|
||||
| calls.rb:289:5:289:17 | call to super | super | 0 | calls.rb:289:11:289:11 | 1 |
|
||||
| calls.rb:289:5:289:17 | call to super | super | 1 | calls.rb:289:14:289:14 | 2 |
|
||||
| calls.rb:289:5:289:17 | call to super | super | 2 | calls.rb:289:17:289:17 | 3 |
|
||||
@@ -203,7 +203,7 @@ superCalls
|
||||
| calls.rb:293:5:293:33 | call to super |
|
||||
| calls.rb:305:5:305:9 | call to super |
|
||||
superCallsWithArguments
|
||||
| calls.rb:288:5:288:16 | call to super | 0 | calls.rb:288:11:288:16 | blah |
|
||||
| calls.rb:288:5:288:16 | call to super | 0 | calls.rb:288:11:288:16 | "blah" |
|
||||
| calls.rb:289:5:289:17 | call to super | 0 | calls.rb:289:11:289:11 | 1 |
|
||||
| calls.rb:289:5:289:17 | call to super | 1 | calls.rb:289:14:289:14 | 2 |
|
||||
| calls.rb:289:5:289:17 | call to super | 2 | calls.rb:289:17:289:17 | 3 |
|
||||
|
||||
746
ql/test/library-tests/ast/literals/literals.expected
Normal file
746
ql/test/library-tests/ast/literals/literals.expected
Normal file
@@ -0,0 +1,746 @@
|
||||
allLiterals
|
||||
| literals.rb:2:1:2:3 | nil | NilLiteral | nil |
|
||||
| literals.rb:3:1:3:3 | NIL | NilLiteral | NIL |
|
||||
| literals.rb:4:1:4:5 | false | BooleanLiteral | false |
|
||||
| literals.rb:5:1:5:5 | FALSE | BooleanLiteral | FALSE |
|
||||
| literals.rb:6:1:6:4 | true | BooleanLiteral | true |
|
||||
| literals.rb:7:1:7:4 | TRUE | BooleanLiteral | TRUE |
|
||||
| literals.rb:10:1:10:4 | 1234 | IntegerLiteral | 1234 |
|
||||
| literals.rb:11:1:11:5 | 5_678 | IntegerLiteral | 5_678 |
|
||||
| literals.rb:12:1:12:1 | 0 | IntegerLiteral | 0 |
|
||||
| literals.rb:13:1:13:5 | 0d900 | IntegerLiteral | 0d900 |
|
||||
| literals.rb:16:1:16:6 | 0x1234 | IntegerLiteral | 0x1234 |
|
||||
| literals.rb:17:1:17:10 | 0xdeadbeef | IntegerLiteral | 0xdeadbeef |
|
||||
| literals.rb:18:1:18:11 | 0xF00D_face | IntegerLiteral | 0xF00D_face |
|
||||
| literals.rb:21:1:21:4 | 0123 | IntegerLiteral | 0123 |
|
||||
| literals.rb:22:1:22:5 | 0o234 | IntegerLiteral | 0o234 |
|
||||
| literals.rb:23:1:23:6 | 0O45_6 | IntegerLiteral | 0O45_6 |
|
||||
| literals.rb:26:1:26:10 | 0b10010100 | IntegerLiteral | 0b10010100 |
|
||||
| literals.rb:27:1:27:11 | 0B011_01101 | IntegerLiteral | 0B011_01101 |
|
||||
| literals.rb:30:1:30:5 | 12.34 | FloatLiteral | 12.34 |
|
||||
| literals.rb:31:1:31:7 | 1234e-2 | FloatLiteral | 1234e-2 |
|
||||
| literals.rb:32:1:32:7 | 1.234E1 | FloatLiteral | 1.234E1 |
|
||||
| literals.rb:35:1:35:3 | 23r | RationalLiteral | 23r |
|
||||
| literals.rb:36:1:36:5 | 9.85r | RationalLiteral | 9.85r |
|
||||
| literals.rb:39:1:39:2 | 2i | ComplexLiteral | 2i |
|
||||
| literals.rb:46:1:46:2 | "" | StringLiteral | |
|
||||
| literals.rb:47:1:47:2 | "" | StringLiteral | |
|
||||
| literals.rb:48:1:48:7 | "hello" | StringLiteral | hello |
|
||||
| literals.rb:49:1:49:9 | "goodbye" | StringLiteral | goodbye |
|
||||
| literals.rb:50:1:50:30 | "string with escaped \\" quote" | StringLiteral | string with escaped \\" quote |
|
||||
| literals.rb:51:1:51:21 | "string with " quote" | StringLiteral | string with " quote |
|
||||
| literals.rb:52:1:52:14 | "foo bar baz" | StringLiteral | foo bar baz |
|
||||
| literals.rb:53:1:53:15 | "foo bar baz" | StringLiteral | foo bar baz |
|
||||
| literals.rb:54:1:54:20 | "foo ' bar " baz'" | StringLiteral | foo ' bar " baz' |
|
||||
| literals.rb:55:1:55:20 | "FOO ' BAR " BAZ'" | StringLiteral | FOO ' BAR " BAZ' |
|
||||
| literals.rb:56:1:56:12 | "foo\\ bar" | StringLiteral | foo\\ bar |
|
||||
| literals.rb:57:1:57:12 | "foo\\ bar" | StringLiteral | foo\\ bar |
|
||||
| literals.rb:58:1:58:20 | "2 + 2 = #{...}" | StringLiteral | <none> |
|
||||
| literals.rb:58:13:58:13 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:58:17:58:17 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:59:1:59:22 | "3 + 4 = #{...}" | StringLiteral | <none> |
|
||||
| literals.rb:59:15:59:15 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:59:19:59:19 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:60:1:60:20 | "2 + 2 = #{ 2 + 2 }" | StringLiteral | 2 + 2 = #{ 2 + 2 } |
|
||||
| literals.rb:61:1:61:22 | "3 + 4 = #{ 3 + 4 }" | StringLiteral | 3 + 4 = #{ 3 + 4 } |
|
||||
| literals.rb:62:1:62:5 | "foo" | StringLiteral | foo |
|
||||
| literals.rb:62:7:62:11 | "bar" | StringLiteral | bar |
|
||||
| literals.rb:62:13:62:17 | "baz" | StringLiteral | baz |
|
||||
| literals.rb:63:1:63:7 | "foo" | StringLiteral | foo |
|
||||
| literals.rb:63:9:63:13 | "bar" | StringLiteral | bar |
|
||||
| literals.rb:63:15:63:19 | "baz" | StringLiteral | baz |
|
||||
| literals.rb:64:1:64:5 | "foo" | StringLiteral | foo |
|
||||
| literals.rb:64:7:64:21 | "bar#{...}" | StringLiteral | <none> |
|
||||
| literals.rb:64:14:64:14 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:64:18:64:18 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:64:23:64:27 | "baz" | StringLiteral | baz |
|
||||
| literals.rb:65:1:65:35 | "foo #{...} qux" | StringLiteral | <none> |
|
||||
| literals.rb:65:9:65:28 | "bar #{...} baz" | StringLiteral | <none> |
|
||||
| literals.rb:65:17:65:17 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:65:21:65:21 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:68:1:68:2 | ?x | CharacterLiteral | ?x |
|
||||
| literals.rb:69:1:69:3 | ?\\n | CharacterLiteral | ?\\n |
|
||||
| literals.rb:70:1:70:3 | ?\\s | CharacterLiteral | ?\\s |
|
||||
| literals.rb:71:1:71:3 | ?\\\\ | CharacterLiteral | ?\\\\ |
|
||||
| literals.rb:72:1:72:7 | ?\\u{58} | CharacterLiteral | ?\\u{58} |
|
||||
| literals.rb:73:1:73:5 | ?\\C-a | CharacterLiteral | ?\\C-a |
|
||||
| literals.rb:74:1:74:5 | ?\\M-a | CharacterLiteral | ?\\M-a |
|
||||
| literals.rb:75:1:75:8 | ?\\M-\\C-a | CharacterLiteral | ?\\M-\\C-a |
|
||||
| literals.rb:76:1:76:8 | ?\\C-\\M-a | CharacterLiteral | ?\\C-\\M-a |
|
||||
| literals.rb:79:1:79:3 | :"" | SymbolLiteral | |
|
||||
| literals.rb:80:1:80:6 | :hello | SymbolLiteral | hello |
|
||||
| literals.rb:81:1:81:10 | :"foo bar" | SymbolLiteral | foo bar |
|
||||
| literals.rb:82:1:82:10 | :"bar baz" | SymbolLiteral | bar baz |
|
||||
| literals.rb:83:1:83:14 | {...} | HashLiteral | <none> |
|
||||
| literals.rb:83:3:83:5 | :foo | SymbolLiteral | foo |
|
||||
| literals.rb:83:8:83:12 | "bar" | StringLiteral | bar |
|
||||
| literals.rb:84:1:84:10 | :"wibble" | SymbolLiteral | wibble |
|
||||
| literals.rb:85:1:85:17 | :"wibble wobble" | SymbolLiteral | wibble wobble |
|
||||
| literals.rb:86:1:86:16 | :"foo_#{...}" | SymbolLiteral | <none> |
|
||||
| literals.rb:86:10:86:10 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:86:14:86:14 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:87:1:87:17 | :"foo_#{ 1 + 1 }" | SymbolLiteral | foo_#{ 1 + 1 } |
|
||||
| literals.rb:88:1:88:18 | :"foo_#{ 3 - 2 }" | SymbolLiteral | foo_#{ 3 - 2 } |
|
||||
| literals.rb:91:1:91:2 | [...] | ArrayLiteral | <none> |
|
||||
| literals.rb:92:1:92:9 | [...] | ArrayLiteral | <none> |
|
||||
| literals.rb:92:2:92:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:92:5:92:5 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:92:8:92:8 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:93:1:93:14 | [...] | ArrayLiteral | <none> |
|
||||
| literals.rb:93:2:93:2 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:93:5:93:5 | 5 | IntegerLiteral | 5 |
|
||||
| literals.rb:93:8:93:9 | 12 | IntegerLiteral | 12 |
|
||||
| literals.rb:93:13:93:13 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:94:1:94:11 | [...] | ArrayLiteral | <none> |
|
||||
| literals.rb:94:2:94:2 | 7 | IntegerLiteral | 7 |
|
||||
| literals.rb:94:5:94:10 | [...] | ArrayLiteral | <none> |
|
||||
| literals.rb:94:6:94:6 | 8 | IntegerLiteral | 8 |
|
||||
| literals.rb:94:9:94:9 | 9 | IntegerLiteral | 9 |
|
||||
| literals.rb:97:1:97:4 | %w(...) | ArrayLiteral | <none> |
|
||||
| literals.rb:98:1:98:15 | %w(...) | ArrayLiteral | <none> |
|
||||
| literals.rb:98:4:98:6 | "foo" | StringLiteral | foo |
|
||||
| literals.rb:98:8:98:10 | "bar" | StringLiteral | bar |
|
||||
| literals.rb:98:12:98:14 | "baz" | StringLiteral | baz |
|
||||
| literals.rb:99:1:99:15 | %w(...) | ArrayLiteral | <none> |
|
||||
| literals.rb:99:4:99:6 | "foo" | StringLiteral | foo |
|
||||
| literals.rb:99:8:99:10 | "bar" | StringLiteral | bar |
|
||||
| literals.rb:99:12:99:14 | "baz" | StringLiteral | baz |
|
||||
| literals.rb:100:1:100:21 | %w(...) | ArrayLiteral | <none> |
|
||||
| literals.rb:100:4:100:6 | "foo" | StringLiteral | foo |
|
||||
| literals.rb:100:8:100:16 | "bar#{...}" | StringLiteral | <none> |
|
||||
| literals.rb:100:13:100:13 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:100:15:100:15 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:100:18:100:20 | "baz" | StringLiteral | baz |
|
||||
| literals.rb:101:1:101:21 | %w(...) | ArrayLiteral | <none> |
|
||||
| literals.rb:101:4:101:6 | "foo" | StringLiteral | foo |
|
||||
| literals.rb:101:8:101:16 | "bar#{1+1}" | StringLiteral | bar#{1+1} |
|
||||
| literals.rb:101:18:101:20 | "baz" | StringLiteral | baz |
|
||||
| literals.rb:104:1:104:4 | %i(...) | ArrayLiteral | <none> |
|
||||
| literals.rb:105:1:105:15 | %i(...) | ArrayLiteral | <none> |
|
||||
| literals.rb:105:4:105:6 | :"foo" | SymbolLiteral | foo |
|
||||
| literals.rb:105:8:105:10 | :"bar" | SymbolLiteral | bar |
|
||||
| literals.rb:105:12:105:14 | :"baz" | SymbolLiteral | baz |
|
||||
| literals.rb:106:1:106:15 | %i(...) | ArrayLiteral | <none> |
|
||||
| literals.rb:106:4:106:6 | :"foo" | SymbolLiteral | foo |
|
||||
| literals.rb:106:8:106:10 | :"bar" | SymbolLiteral | bar |
|
||||
| literals.rb:106:12:106:14 | :"baz" | SymbolLiteral | baz |
|
||||
| literals.rb:107:1:107:25 | %i(...) | ArrayLiteral | <none> |
|
||||
| literals.rb:107:4:107:6 | :"foo" | SymbolLiteral | foo |
|
||||
| literals.rb:107:8:107:20 | :"bar#{...}" | SymbolLiteral | <none> |
|
||||
| literals.rb:107:14:107:14 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:107:18:107:18 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:107:22:107:24 | :"baz" | SymbolLiteral | baz |
|
||||
| literals.rb:108:1:108:25 | %i(...) | ArrayLiteral | <none> |
|
||||
| literals.rb:108:4:108:6 | :"foo" | SymbolLiteral | foo |
|
||||
| literals.rb:108:8:108:12 | :"bar#{" | SymbolLiteral | bar#{ |
|
||||
| literals.rb:108:14:108:14 | :"2" | SymbolLiteral | 2 |
|
||||
| literals.rb:108:16:108:16 | :"+" | SymbolLiteral | + |
|
||||
| literals.rb:108:18:108:18 | :"4" | SymbolLiteral | 4 |
|
||||
| literals.rb:108:20:108:20 | :"}" | SymbolLiteral | } |
|
||||
| literals.rb:108:22:108:24 | :"baz" | SymbolLiteral | baz |
|
||||
| literals.rb:111:1:111:2 | {...} | HashLiteral | <none> |
|
||||
| literals.rb:112:1:112:33 | {...} | HashLiteral | <none> |
|
||||
| literals.rb:112:3:112:5 | :foo | SymbolLiteral | foo |
|
||||
| literals.rb:112:8:112:8 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:112:11:112:14 | :bar | SymbolLiteral | bar |
|
||||
| literals.rb:112:19:112:19 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:112:22:112:26 | "baz" | StringLiteral | baz |
|
||||
| literals.rb:112:31:112:31 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:113:1:113:17 | {...} | HashLiteral | <none> |
|
||||
| literals.rb:113:3:113:5 | :foo | SymbolLiteral | foo |
|
||||
| literals.rb:113:8:113:8 | 7 | IntegerLiteral | 7 |
|
||||
| literals.rb:116:2:116:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:116:2:116:6 | _ .. _ | RangeLiteral | <none> |
|
||||
| literals.rb:116:5:116:6 | 10 | IntegerLiteral | 10 |
|
||||
| literals.rb:117:2:117:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:117:2:117:7 | _ ... _ | RangeLiteral | <none> |
|
||||
| literals.rb:117:6:117:7 | 10 | IntegerLiteral | 10 |
|
||||
| literals.rb:118:2:118:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:118:2:118:7 | _ .. _ | RangeLiteral | <none> |
|
||||
| literals.rb:118:7:118:7 | 0 | IntegerLiteral | 0 |
|
||||
| literals.rb:119:2:119:11 | _ .. _ | RangeLiteral | <none> |
|
||||
| literals.rb:119:9:119:9 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:119:11:119:11 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:120:2:120:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:120:2:120:4 | _ .. _ | RangeLiteral | <none> |
|
||||
| literals.rb:121:2:121:4 | _ .. _ | RangeLiteral | <none> |
|
||||
| literals.rb:121:4:121:4 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:122:2:122:2 | 0 | IntegerLiteral | 0 |
|
||||
| literals.rb:122:2:122:4 | _ .. _ | RangeLiteral | <none> |
|
||||
| literals.rb:122:6:122:6 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:125:1:125:7 | `ls -l` | SubshellLiteral | ls -l |
|
||||
| literals.rb:126:1:126:9 | `ls -l` | SubshellLiteral | ls -l |
|
||||
| literals.rb:127:1:127:18 | `du -d #{...}` | SubshellLiteral | <none> |
|
||||
| literals.rb:127:11:127:11 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:127:15:127:15 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:128:1:128:20 | `du -d #{...}` | SubshellLiteral | <none> |
|
||||
| literals.rb:128:13:128:13 | 5 | IntegerLiteral | 5 |
|
||||
| literals.rb:128:17:128:17 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:131:1:131:2 | // | RegexLiteral | |
|
||||
| literals.rb:132:1:132:5 | /foo/ | RegexLiteral | foo |
|
||||
| literals.rb:133:1:133:6 | /foo/ | RegexLiteral | foo |
|
||||
| literals.rb:134:1:134:13 | /foo+\\sbar\\S/ | RegexLiteral | foo+\\sbar\\S |
|
||||
| literals.rb:135:1:135:18 | /foo#{...}bar/ | RegexLiteral | <none> |
|
||||
| literals.rb:135:8:135:8 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:135:12:135:12 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:136:1:136:8 | /foo/ | RegexLiteral | foo |
|
||||
| literals.rb:137:1:137:4 | // | RegexLiteral | |
|
||||
| literals.rb:138:1:138:7 | /foo/ | RegexLiteral | foo |
|
||||
| literals.rb:139:1:139:8 | /foo/ | RegexLiteral | foo |
|
||||
| literals.rb:140:1:140:15 | /foo+\\sbar\\S/ | RegexLiteral | foo+\\sbar\\S |
|
||||
| literals.rb:141:1:141:20 | /foo#{...}bar/ | RegexLiteral | <none> |
|
||||
| literals.rb:141:10:141:10 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:141:14:141:14 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:142:1:142:10 | /foo/ | RegexLiteral | foo |
|
||||
| literals.rb:145:1:145:34 | "abcdefghijklmnopqrstuvwxyzabcdef" | StringLiteral | abcdefghijklmnopqrstuvwxyzabcdef |
|
||||
| literals.rb:146:1:146:35 | "foobarfoobarfoobarfoobarfooba..." | StringLiteral | foobarfoobarfoobarfoobarfoobarfoo |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | StringLiteral | foobar\\\\foobar\\\\foobar\\\\foobar\\\\foobar |
|
||||
stringlikeLiterals
|
||||
| literals.rb:46:1:46:2 | "" | |
|
||||
| literals.rb:47:1:47:2 | "" | |
|
||||
| literals.rb:48:1:48:7 | "hello" | hello |
|
||||
| literals.rb:49:1:49:9 | "goodbye" | goodbye |
|
||||
| literals.rb:50:1:50:30 | "string with escaped \\" quote" | string with escaped \\" quote |
|
||||
| literals.rb:51:1:51:21 | "string with " quote" | string with " quote |
|
||||
| literals.rb:52:1:52:14 | "foo bar baz" | foo bar baz |
|
||||
| literals.rb:53:1:53:15 | "foo bar baz" | foo bar baz |
|
||||
| literals.rb:54:1:54:20 | "foo ' bar " baz'" | foo ' bar " baz' |
|
||||
| literals.rb:55:1:55:20 | "FOO ' BAR " BAZ'" | FOO ' BAR " BAZ' |
|
||||
| literals.rb:56:1:56:12 | "foo\\ bar" | foo\\ bar |
|
||||
| literals.rb:57:1:57:12 | "foo\\ bar" | foo\\ bar |
|
||||
| literals.rb:58:1:58:20 | "2 + 2 = #{...}" | <none> |
|
||||
| literals.rb:59:1:59:22 | "3 + 4 = #{...}" | <none> |
|
||||
| literals.rb:60:1:60:20 | "2 + 2 = #{ 2 + 2 }" | 2 + 2 = #{ 2 + 2 } |
|
||||
| literals.rb:61:1:61:22 | "3 + 4 = #{ 3 + 4 }" | 3 + 4 = #{ 3 + 4 } |
|
||||
| literals.rb:62:1:62:5 | "foo" | foo |
|
||||
| literals.rb:62:7:62:11 | "bar" | bar |
|
||||
| literals.rb:62:13:62:17 | "baz" | baz |
|
||||
| literals.rb:63:1:63:7 | "foo" | foo |
|
||||
| literals.rb:63:9:63:13 | "bar" | bar |
|
||||
| literals.rb:63:15:63:19 | "baz" | baz |
|
||||
| literals.rb:64:1:64:5 | "foo" | foo |
|
||||
| literals.rb:64:7:64:21 | "bar#{...}" | <none> |
|
||||
| literals.rb:64:23:64:27 | "baz" | baz |
|
||||
| literals.rb:65:1:65:35 | "foo #{...} qux" | <none> |
|
||||
| literals.rb:65:9:65:28 | "bar #{...} baz" | <none> |
|
||||
| literals.rb:79:1:79:3 | :"" | |
|
||||
| literals.rb:80:1:80:6 | :hello | hello |
|
||||
| literals.rb:81:1:81:10 | :"foo bar" | foo bar |
|
||||
| literals.rb:82:1:82:10 | :"bar baz" | bar baz |
|
||||
| literals.rb:83:3:83:5 | :foo | foo |
|
||||
| literals.rb:83:8:83:12 | "bar" | bar |
|
||||
| literals.rb:84:1:84:10 | :"wibble" | wibble |
|
||||
| literals.rb:85:1:85:17 | :"wibble wobble" | wibble wobble |
|
||||
| literals.rb:86:1:86:16 | :"foo_#{...}" | <none> |
|
||||
| literals.rb:87:1:87:17 | :"foo_#{ 1 + 1 }" | foo_#{ 1 + 1 } |
|
||||
| literals.rb:88:1:88:18 | :"foo_#{ 3 - 2 }" | foo_#{ 3 - 2 } |
|
||||
| literals.rb:98:4:98:6 | "foo" | foo |
|
||||
| literals.rb:98:8:98:10 | "bar" | bar |
|
||||
| literals.rb:98:12:98:14 | "baz" | baz |
|
||||
| literals.rb:99:4:99:6 | "foo" | foo |
|
||||
| literals.rb:99:8:99:10 | "bar" | bar |
|
||||
| literals.rb:99:12:99:14 | "baz" | baz |
|
||||
| literals.rb:100:4:100:6 | "foo" | foo |
|
||||
| literals.rb:100:8:100:16 | "bar#{...}" | <none> |
|
||||
| literals.rb:100:18:100:20 | "baz" | baz |
|
||||
| literals.rb:101:4:101:6 | "foo" | foo |
|
||||
| literals.rb:101:8:101:16 | "bar#{1+1}" | bar#{1+1} |
|
||||
| literals.rb:101:18:101:20 | "baz" | baz |
|
||||
| literals.rb:105:4:105:6 | :"foo" | foo |
|
||||
| literals.rb:105:8:105:10 | :"bar" | bar |
|
||||
| literals.rb:105:12:105:14 | :"baz" | baz |
|
||||
| literals.rb:106:4:106:6 | :"foo" | foo |
|
||||
| literals.rb:106:8:106:10 | :"bar" | bar |
|
||||
| literals.rb:106:12:106:14 | :"baz" | baz |
|
||||
| literals.rb:107:4:107:6 | :"foo" | foo |
|
||||
| literals.rb:107:8:107:20 | :"bar#{...}" | <none> |
|
||||
| literals.rb:107:22:107:24 | :"baz" | baz |
|
||||
| literals.rb:108:4:108:6 | :"foo" | foo |
|
||||
| literals.rb:108:8:108:12 | :"bar#{" | bar#{ |
|
||||
| literals.rb:108:14:108:14 | :"2" | 2 |
|
||||
| literals.rb:108:16:108:16 | :"+" | + |
|
||||
| literals.rb:108:18:108:18 | :"4" | 4 |
|
||||
| literals.rb:108:20:108:20 | :"}" | } |
|
||||
| literals.rb:108:22:108:24 | :"baz" | baz |
|
||||
| literals.rb:112:3:112:5 | :foo | foo |
|
||||
| literals.rb:112:11:112:14 | :bar | bar |
|
||||
| literals.rb:112:22:112:26 | "baz" | baz |
|
||||
| literals.rb:113:3:113:5 | :foo | foo |
|
||||
| literals.rb:125:1:125:7 | `ls -l` | ls -l |
|
||||
| literals.rb:126:1:126:9 | `ls -l` | ls -l |
|
||||
| literals.rb:127:1:127:18 | `du -d #{...}` | <none> |
|
||||
| literals.rb:128:1:128:20 | `du -d #{...}` | <none> |
|
||||
| literals.rb:131:1:131:2 | // | |
|
||||
| literals.rb:132:1:132:5 | /foo/ | foo |
|
||||
| literals.rb:133:1:133:6 | /foo/ | foo |
|
||||
| literals.rb:134:1:134:13 | /foo+\\sbar\\S/ | foo+\\sbar\\S |
|
||||
| literals.rb:135:1:135:18 | /foo#{...}bar/ | <none> |
|
||||
| literals.rb:136:1:136:8 | /foo/ | foo |
|
||||
| literals.rb:137:1:137:4 | // | |
|
||||
| literals.rb:138:1:138:7 | /foo/ | foo |
|
||||
| literals.rb:139:1:139:8 | /foo/ | foo |
|
||||
| literals.rb:140:1:140:15 | /foo+\\sbar\\S/ | foo+\\sbar\\S |
|
||||
| literals.rb:141:1:141:20 | /foo#{...}bar/ | <none> |
|
||||
| literals.rb:142:1:142:10 | /foo/ | foo |
|
||||
| literals.rb:145:1:145:34 | "abcdefghijklmnopqrstuvwxyzabcdef" | abcdefghijklmnopqrstuvwxyzabcdef |
|
||||
| literals.rb:146:1:146:35 | "foobarfoobarfoobarfoobarfooba..." | foobarfoobarfoobarfoobarfoobarfoo |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | foobar\\\\foobar\\\\foobar\\\\foobar\\\\foobar |
|
||||
stringLiterals
|
||||
| literals.rb:46:1:46:2 | "" | |
|
||||
| literals.rb:47:1:47:2 | "" | |
|
||||
| literals.rb:48:1:48:7 | "hello" | hello |
|
||||
| literals.rb:49:1:49:9 | "goodbye" | goodbye |
|
||||
| literals.rb:50:1:50:30 | "string with escaped \\" quote" | string with escaped \\" quote |
|
||||
| literals.rb:51:1:51:21 | "string with " quote" | string with " quote |
|
||||
| literals.rb:52:1:52:14 | "foo bar baz" | foo bar baz |
|
||||
| literals.rb:53:1:53:15 | "foo bar baz" | foo bar baz |
|
||||
| literals.rb:54:1:54:20 | "foo ' bar " baz'" | foo ' bar " baz' |
|
||||
| literals.rb:55:1:55:20 | "FOO ' BAR " BAZ'" | FOO ' BAR " BAZ' |
|
||||
| literals.rb:56:1:56:12 | "foo\\ bar" | foo\\ bar |
|
||||
| literals.rb:57:1:57:12 | "foo\\ bar" | foo\\ bar |
|
||||
| literals.rb:58:1:58:20 | "2 + 2 = #{...}" | <none> |
|
||||
| literals.rb:59:1:59:22 | "3 + 4 = #{...}" | <none> |
|
||||
| literals.rb:60:1:60:20 | "2 + 2 = #{ 2 + 2 }" | 2 + 2 = #{ 2 + 2 } |
|
||||
| literals.rb:61:1:61:22 | "3 + 4 = #{ 3 + 4 }" | 3 + 4 = #{ 3 + 4 } |
|
||||
| literals.rb:62:1:62:5 | "foo" | foo |
|
||||
| literals.rb:62:7:62:11 | "bar" | bar |
|
||||
| literals.rb:62:13:62:17 | "baz" | baz |
|
||||
| literals.rb:63:1:63:7 | "foo" | foo |
|
||||
| literals.rb:63:9:63:13 | "bar" | bar |
|
||||
| literals.rb:63:15:63:19 | "baz" | baz |
|
||||
| literals.rb:64:1:64:5 | "foo" | foo |
|
||||
| literals.rb:64:7:64:21 | "bar#{...}" | <none> |
|
||||
| literals.rb:64:23:64:27 | "baz" | baz |
|
||||
| literals.rb:65:1:65:35 | "foo #{...} qux" | <none> |
|
||||
| literals.rb:65:9:65:28 | "bar #{...} baz" | <none> |
|
||||
| literals.rb:83:8:83:12 | "bar" | bar |
|
||||
| literals.rb:98:4:98:6 | "foo" | foo |
|
||||
| literals.rb:98:8:98:10 | "bar" | bar |
|
||||
| literals.rb:98:12:98:14 | "baz" | baz |
|
||||
| literals.rb:99:4:99:6 | "foo" | foo |
|
||||
| literals.rb:99:8:99:10 | "bar" | bar |
|
||||
| literals.rb:99:12:99:14 | "baz" | baz |
|
||||
| literals.rb:100:4:100:6 | "foo" | foo |
|
||||
| literals.rb:100:8:100:16 | "bar#{...}" | <none> |
|
||||
| literals.rb:100:18:100:20 | "baz" | baz |
|
||||
| literals.rb:101:4:101:6 | "foo" | foo |
|
||||
| literals.rb:101:8:101:16 | "bar#{1+1}" | bar#{1+1} |
|
||||
| literals.rb:101:18:101:20 | "baz" | baz |
|
||||
| literals.rb:112:22:112:26 | "baz" | baz |
|
||||
| literals.rb:145:1:145:34 | "abcdefghijklmnopqrstuvwxyzabcdef" | abcdefghijklmnopqrstuvwxyzabcdef |
|
||||
| literals.rb:146:1:146:35 | "foobarfoobarfoobarfoobarfooba..." | foobarfoobarfoobarfoobarfoobarfoo |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | foobar\\\\foobar\\\\foobar\\\\foobar\\\\foobar |
|
||||
regexLiterals
|
||||
| literals.rb:131:1:131:2 | // | | |
|
||||
| literals.rb:132:1:132:5 | /foo/ | foo | |
|
||||
| literals.rb:133:1:133:6 | /foo/ | foo | i |
|
||||
| literals.rb:134:1:134:13 | /foo+\\sbar\\S/ | foo+\\sbar\\S | |
|
||||
| literals.rb:135:1:135:18 | /foo#{...}bar/ | <none> | |
|
||||
| literals.rb:136:1:136:8 | /foo/ | foo | oxm |
|
||||
| literals.rb:137:1:137:4 | // | | |
|
||||
| literals.rb:138:1:138:7 | /foo/ | foo | |
|
||||
| literals.rb:139:1:139:8 | /foo/ | foo | i |
|
||||
| literals.rb:140:1:140:15 | /foo+\\sbar\\S/ | foo+\\sbar\\S | |
|
||||
| literals.rb:141:1:141:20 | /foo#{...}bar/ | <none> | |
|
||||
| literals.rb:142:1:142:10 | /foo/ | foo | mxo |
|
||||
symbolLiterals
|
||||
| literals.rb:79:1:79:3 | :"" | |
|
||||
| literals.rb:80:1:80:6 | :hello | hello |
|
||||
| literals.rb:81:1:81:10 | :"foo bar" | foo bar |
|
||||
| literals.rb:82:1:82:10 | :"bar baz" | bar baz |
|
||||
| literals.rb:83:3:83:5 | :foo | foo |
|
||||
| literals.rb:84:1:84:10 | :"wibble" | wibble |
|
||||
| literals.rb:85:1:85:17 | :"wibble wobble" | wibble wobble |
|
||||
| literals.rb:86:1:86:16 | :"foo_#{...}" | <none> |
|
||||
| literals.rb:87:1:87:17 | :"foo_#{ 1 + 1 }" | foo_#{ 1 + 1 } |
|
||||
| literals.rb:88:1:88:18 | :"foo_#{ 3 - 2 }" | foo_#{ 3 - 2 } |
|
||||
| literals.rb:105:4:105:6 | :"foo" | foo |
|
||||
| literals.rb:105:8:105:10 | :"bar" | bar |
|
||||
| literals.rb:105:12:105:14 | :"baz" | baz |
|
||||
| literals.rb:106:4:106:6 | :"foo" | foo |
|
||||
| literals.rb:106:8:106:10 | :"bar" | bar |
|
||||
| literals.rb:106:12:106:14 | :"baz" | baz |
|
||||
| literals.rb:107:4:107:6 | :"foo" | foo |
|
||||
| literals.rb:107:8:107:20 | :"bar#{...}" | <none> |
|
||||
| literals.rb:107:22:107:24 | :"baz" | baz |
|
||||
| literals.rb:108:4:108:6 | :"foo" | foo |
|
||||
| literals.rb:108:8:108:12 | :"bar#{" | bar#{ |
|
||||
| literals.rb:108:14:108:14 | :"2" | 2 |
|
||||
| literals.rb:108:16:108:16 | :"+" | + |
|
||||
| literals.rb:108:18:108:18 | :"4" | 4 |
|
||||
| literals.rb:108:20:108:20 | :"}" | } |
|
||||
| literals.rb:108:22:108:24 | :"baz" | baz |
|
||||
| literals.rb:112:3:112:5 | :foo | foo |
|
||||
| literals.rb:112:11:112:14 | :bar | bar |
|
||||
| literals.rb:113:3:113:5 | :foo | foo |
|
||||
subshellLiterals
|
||||
| literals.rb:125:1:125:7 | `ls -l` | ls -l |
|
||||
| literals.rb:126:1:126:9 | `ls -l` | ls -l |
|
||||
| literals.rb:127:1:127:18 | `du -d #{...}` | <none> |
|
||||
| literals.rb:128:1:128:20 | `du -d #{...}` | <none> |
|
||||
stringComponents
|
||||
| literals.rb:48:1:48:7 | "hello" | StringLiteral | 0 | literals.rb:48:2:48:6 | hello | StringTextComponent |
|
||||
| literals.rb:49:1:49:9 | "goodbye" | StringLiteral | 0 | literals.rb:49:2:49:8 | goodbye | StringTextComponent |
|
||||
| literals.rb:50:1:50:30 | "string with escaped \\" quote" | StringLiteral | 0 | literals.rb:50:2:50:21 | string with escaped | StringTextComponent |
|
||||
| literals.rb:50:1:50:30 | "string with escaped \\" quote" | StringLiteral | 1 | literals.rb:50:22:50:23 | \\" | StringEscapeSequenceComponent |
|
||||
| literals.rb:50:1:50:30 | "string with escaped \\" quote" | StringLiteral | 2 | literals.rb:50:24:50:29 | quote | StringTextComponent |
|
||||
| literals.rb:51:1:51:21 | "string with " quote" | StringLiteral | 0 | literals.rb:51:2:51:20 | string with " quote | StringTextComponent |
|
||||
| literals.rb:52:1:52:14 | "foo bar baz" | StringLiteral | 0 | literals.rb:52:3:52:13 | foo bar baz | StringTextComponent |
|
||||
| literals.rb:53:1:53:15 | "foo bar baz" | StringLiteral | 0 | literals.rb:53:4:53:14 | foo bar baz | StringTextComponent |
|
||||
| literals.rb:54:1:54:20 | "foo ' bar " baz'" | StringLiteral | 0 | literals.rb:54:4:54:19 | foo ' bar " baz' | StringTextComponent |
|
||||
| literals.rb:55:1:55:20 | "FOO ' BAR " BAZ'" | StringLiteral | 0 | literals.rb:55:4:55:19 | FOO ' BAR " BAZ' | StringTextComponent |
|
||||
| literals.rb:56:1:56:12 | "foo\\ bar" | StringLiteral | 0 | literals.rb:56:4:56:11 | foo\\ bar | StringTextComponent |
|
||||
| literals.rb:57:1:57:12 | "foo\\ bar" | StringLiteral | 0 | literals.rb:57:4:57:6 | foo | StringTextComponent |
|
||||
| literals.rb:57:1:57:12 | "foo\\ bar" | StringLiteral | 1 | literals.rb:57:7:57:8 | \\ | StringEscapeSequenceComponent |
|
||||
| literals.rb:57:1:57:12 | "foo\\ bar" | StringLiteral | 2 | literals.rb:57:9:57:11 | bar | StringTextComponent |
|
||||
| literals.rb:58:1:58:20 | "2 + 2 = #{...}" | StringLiteral | 0 | literals.rb:58:2:58:9 | 2 + 2 = | StringTextComponent |
|
||||
| literals.rb:58:1:58:20 | "2 + 2 = #{...}" | StringLiteral | 1 | literals.rb:58:10:58:19 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:59:1:59:22 | "3 + 4 = #{...}" | StringLiteral | 0 | literals.rb:59:4:59:11 | 3 + 4 = | StringTextComponent |
|
||||
| literals.rb:59:1:59:22 | "3 + 4 = #{...}" | StringLiteral | 1 | literals.rb:59:12:59:21 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:60:1:60:20 | "2 + 2 = #{ 2 + 2 }" | StringLiteral | 0 | literals.rb:60:2:60:19 | 2 + 2 = #{ 2 + 2 } | StringTextComponent |
|
||||
| literals.rb:61:1:61:22 | "3 + 4 = #{ 3 + 4 }" | StringLiteral | 0 | literals.rb:61:4:61:21 | 3 + 4 = #{ 3 + 4 } | StringTextComponent |
|
||||
| literals.rb:62:1:62:5 | "foo" | StringLiteral | 0 | literals.rb:62:2:62:4 | foo | StringTextComponent |
|
||||
| literals.rb:62:7:62:11 | "bar" | StringLiteral | 0 | literals.rb:62:8:62:10 | bar | StringTextComponent |
|
||||
| literals.rb:62:13:62:17 | "baz" | StringLiteral | 0 | literals.rb:62:14:62:16 | baz | StringTextComponent |
|
||||
| literals.rb:63:1:63:7 | "foo" | StringLiteral | 0 | literals.rb:63:4:63:6 | foo | StringTextComponent |
|
||||
| literals.rb:63:9:63:13 | "bar" | StringLiteral | 0 | literals.rb:63:10:63:12 | bar | StringTextComponent |
|
||||
| literals.rb:63:15:63:19 | "baz" | StringLiteral | 0 | literals.rb:63:16:63:18 | baz | StringTextComponent |
|
||||
| literals.rb:64:1:64:5 | "foo" | StringLiteral | 0 | literals.rb:64:2:64:4 | foo | StringTextComponent |
|
||||
| literals.rb:64:7:64:21 | "bar#{...}" | StringLiteral | 0 | literals.rb:64:8:64:10 | bar | StringTextComponent |
|
||||
| literals.rb:64:7:64:21 | "bar#{...}" | StringLiteral | 1 | literals.rb:64:11:64:20 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:64:23:64:27 | "baz" | StringLiteral | 0 | literals.rb:64:24:64:26 | baz | StringTextComponent |
|
||||
| literals.rb:65:1:65:35 | "foo #{...} qux" | StringLiteral | 0 | literals.rb:65:2:65:5 | foo | StringTextComponent |
|
||||
| literals.rb:65:1:65:35 | "foo #{...} qux" | StringLiteral | 1 | literals.rb:65:6:65:30 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:65:1:65:35 | "foo #{...} qux" | StringLiteral | 2 | literals.rb:65:31:65:34 | qux | StringTextComponent |
|
||||
| literals.rb:65:9:65:28 | "bar #{...} baz" | StringLiteral | 0 | literals.rb:65:10:65:13 | bar | StringTextComponent |
|
||||
| literals.rb:65:9:65:28 | "bar #{...} baz" | StringLiteral | 1 | literals.rb:65:14:65:23 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:65:9:65:28 | "bar #{...} baz" | StringLiteral | 2 | literals.rb:65:24:65:27 | baz | StringTextComponent |
|
||||
| literals.rb:81:1:81:10 | :"foo bar" | SymbolLiteral | 0 | literals.rb:81:3:81:9 | foo bar | StringTextComponent |
|
||||
| literals.rb:82:1:82:10 | :"bar baz" | SymbolLiteral | 0 | literals.rb:82:3:82:9 | bar baz | StringTextComponent |
|
||||
| literals.rb:83:8:83:12 | "bar" | StringLiteral | 0 | literals.rb:83:9:83:11 | bar | StringTextComponent |
|
||||
| literals.rb:84:1:84:10 | :"wibble" | SymbolLiteral | 0 | literals.rb:84:4:84:9 | wibble | StringTextComponent |
|
||||
| literals.rb:85:1:85:17 | :"wibble wobble" | SymbolLiteral | 0 | literals.rb:85:4:85:16 | wibble wobble | StringTextComponent |
|
||||
| literals.rb:86:1:86:16 | :"foo_#{...}" | SymbolLiteral | 0 | literals.rb:86:3:86:6 | foo_ | StringTextComponent |
|
||||
| literals.rb:86:1:86:16 | :"foo_#{...}" | SymbolLiteral | 1 | literals.rb:86:7:86:15 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:87:1:87:17 | :"foo_#{ 1 + 1 }" | SymbolLiteral | 0 | literals.rb:87:3:87:16 | foo_#{ 1 + 1 } | StringTextComponent |
|
||||
| literals.rb:88:1:88:18 | :"foo_#{ 3 - 2 }" | SymbolLiteral | 0 | literals.rb:88:4:88:17 | foo_#{ 3 - 2 } | StringTextComponent |
|
||||
| literals.rb:98:4:98:6 | "foo" | StringLiteral | 0 | literals.rb:98:4:98:6 | foo | StringTextComponent |
|
||||
| literals.rb:98:8:98:10 | "bar" | StringLiteral | 0 | literals.rb:98:8:98:10 | bar | StringTextComponent |
|
||||
| literals.rb:98:12:98:14 | "baz" | StringLiteral | 0 | literals.rb:98:12:98:14 | baz | StringTextComponent |
|
||||
| literals.rb:99:4:99:6 | "foo" | StringLiteral | 0 | literals.rb:99:4:99:6 | foo | StringTextComponent |
|
||||
| literals.rb:99:8:99:10 | "bar" | StringLiteral | 0 | literals.rb:99:8:99:10 | bar | StringTextComponent |
|
||||
| literals.rb:99:12:99:14 | "baz" | StringLiteral | 0 | literals.rb:99:12:99:14 | baz | StringTextComponent |
|
||||
| literals.rb:100:4:100:6 | "foo" | StringLiteral | 0 | literals.rb:100:4:100:6 | foo | StringTextComponent |
|
||||
| literals.rb:100:8:100:16 | "bar#{...}" | StringLiteral | 0 | literals.rb:100:8:100:10 | bar | StringTextComponent |
|
||||
| literals.rb:100:8:100:16 | "bar#{...}" | StringLiteral | 1 | literals.rb:100:11:100:16 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:100:18:100:20 | "baz" | StringLiteral | 0 | literals.rb:100:18:100:20 | baz | StringTextComponent |
|
||||
| literals.rb:101:4:101:6 | "foo" | StringLiteral | 0 | literals.rb:101:4:101:6 | foo | StringTextComponent |
|
||||
| literals.rb:101:8:101:16 | "bar#{1+1}" | StringLiteral | 0 | literals.rb:101:8:101:16 | bar#{1+1} | StringTextComponent |
|
||||
| literals.rb:101:18:101:20 | "baz" | StringLiteral | 0 | literals.rb:101:18:101:20 | baz | StringTextComponent |
|
||||
| literals.rb:105:4:105:6 | :"foo" | SymbolLiteral | 0 | literals.rb:105:4:105:6 | foo | StringTextComponent |
|
||||
| literals.rb:105:8:105:10 | :"bar" | SymbolLiteral | 0 | literals.rb:105:8:105:10 | bar | StringTextComponent |
|
||||
| literals.rb:105:12:105:14 | :"baz" | SymbolLiteral | 0 | literals.rb:105:12:105:14 | baz | StringTextComponent |
|
||||
| literals.rb:106:4:106:6 | :"foo" | SymbolLiteral | 0 | literals.rb:106:4:106:6 | foo | StringTextComponent |
|
||||
| literals.rb:106:8:106:10 | :"bar" | SymbolLiteral | 0 | literals.rb:106:8:106:10 | bar | StringTextComponent |
|
||||
| literals.rb:106:12:106:14 | :"baz" | SymbolLiteral | 0 | literals.rb:106:12:106:14 | baz | StringTextComponent |
|
||||
| literals.rb:107:4:107:6 | :"foo" | SymbolLiteral | 0 | literals.rb:107:4:107:6 | foo | StringTextComponent |
|
||||
| literals.rb:107:8:107:20 | :"bar#{...}" | SymbolLiteral | 0 | literals.rb:107:8:107:10 | bar | StringTextComponent |
|
||||
| literals.rb:107:8:107:20 | :"bar#{...}" | SymbolLiteral | 1 | literals.rb:107:11:107:20 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:107:22:107:24 | :"baz" | SymbolLiteral | 0 | literals.rb:107:22:107:24 | baz | StringTextComponent |
|
||||
| literals.rb:108:4:108:6 | :"foo" | SymbolLiteral | 0 | literals.rb:108:4:108:6 | foo | StringTextComponent |
|
||||
| literals.rb:108:8:108:12 | :"bar#{" | SymbolLiteral | 0 | literals.rb:108:8:108:12 | bar#{ | StringTextComponent |
|
||||
| literals.rb:108:14:108:14 | :"2" | SymbolLiteral | 0 | literals.rb:108:14:108:14 | 2 | StringTextComponent |
|
||||
| literals.rb:108:16:108:16 | :"+" | SymbolLiteral | 0 | literals.rb:108:16:108:16 | + | StringTextComponent |
|
||||
| literals.rb:108:18:108:18 | :"4" | SymbolLiteral | 0 | literals.rb:108:18:108:18 | 4 | StringTextComponent |
|
||||
| literals.rb:108:20:108:20 | :"}" | SymbolLiteral | 0 | literals.rb:108:20:108:20 | } | StringTextComponent |
|
||||
| literals.rb:108:22:108:24 | :"baz" | SymbolLiteral | 0 | literals.rb:108:22:108:24 | baz | StringTextComponent |
|
||||
| literals.rb:112:22:112:26 | "baz" | StringLiteral | 0 | literals.rb:112:23:112:25 | baz | StringTextComponent |
|
||||
| literals.rb:125:1:125:7 | `ls -l` | SubshellLiteral | 0 | literals.rb:125:2:125:6 | ls -l | StringTextComponent |
|
||||
| literals.rb:126:1:126:9 | `ls -l` | SubshellLiteral | 0 | literals.rb:126:4:126:8 | ls -l | StringTextComponent |
|
||||
| literals.rb:127:1:127:18 | `du -d #{...}` | SubshellLiteral | 0 | literals.rb:127:2:127:7 | du -d | StringTextComponent |
|
||||
| literals.rb:127:1:127:18 | `du -d #{...}` | SubshellLiteral | 1 | literals.rb:127:8:127:17 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:128:1:128:20 | `du -d #{...}` | SubshellLiteral | 0 | literals.rb:128:4:128:9 | du -d | StringTextComponent |
|
||||
| literals.rb:128:1:128:20 | `du -d #{...}` | SubshellLiteral | 1 | literals.rb:128:10:128:19 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:132:1:132:5 | /foo/ | RegexLiteral | 0 | literals.rb:132:2:132:4 | foo | StringTextComponent |
|
||||
| literals.rb:133:1:133:6 | /foo/ | RegexLiteral | 0 | literals.rb:133:2:133:4 | foo | StringTextComponent |
|
||||
| literals.rb:134:1:134:13 | /foo+\\sbar\\S/ | RegexLiteral | 0 | literals.rb:134:2:134:5 | foo+ | StringTextComponent |
|
||||
| literals.rb:134:1:134:13 | /foo+\\sbar\\S/ | RegexLiteral | 1 | literals.rb:134:6:134:7 | \\s | StringEscapeSequenceComponent |
|
||||
| literals.rb:134:1:134:13 | /foo+\\sbar\\S/ | RegexLiteral | 2 | literals.rb:134:8:134:10 | bar | StringTextComponent |
|
||||
| literals.rb:134:1:134:13 | /foo+\\sbar\\S/ | RegexLiteral | 3 | literals.rb:134:11:134:12 | \\S | StringEscapeSequenceComponent |
|
||||
| literals.rb:135:1:135:18 | /foo#{...}bar/ | RegexLiteral | 0 | literals.rb:135:2:135:4 | foo | StringTextComponent |
|
||||
| literals.rb:135:1:135:18 | /foo#{...}bar/ | RegexLiteral | 1 | literals.rb:135:5:135:14 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:135:1:135:18 | /foo#{...}bar/ | RegexLiteral | 2 | literals.rb:135:15:135:17 | bar | StringTextComponent |
|
||||
| literals.rb:136:1:136:8 | /foo/ | RegexLiteral | 0 | literals.rb:136:2:136:4 | foo | StringTextComponent |
|
||||
| literals.rb:138:1:138:7 | /foo/ | RegexLiteral | 0 | literals.rb:138:4:138:6 | foo | StringTextComponent |
|
||||
| literals.rb:139:1:139:8 | /foo/ | RegexLiteral | 0 | literals.rb:139:4:139:6 | foo | StringTextComponent |
|
||||
| literals.rb:140:1:140:15 | /foo+\\sbar\\S/ | RegexLiteral | 0 | literals.rb:140:4:140:7 | foo+ | StringTextComponent |
|
||||
| literals.rb:140:1:140:15 | /foo+\\sbar\\S/ | RegexLiteral | 1 | literals.rb:140:8:140:9 | \\s | StringEscapeSequenceComponent |
|
||||
| literals.rb:140:1:140:15 | /foo+\\sbar\\S/ | RegexLiteral | 2 | literals.rb:140:10:140:12 | bar | StringTextComponent |
|
||||
| literals.rb:140:1:140:15 | /foo+\\sbar\\S/ | RegexLiteral | 3 | literals.rb:140:13:140:14 | \\S | StringEscapeSequenceComponent |
|
||||
| literals.rb:141:1:141:20 | /foo#{...}bar/ | RegexLiteral | 0 | literals.rb:141:4:141:6 | foo | StringTextComponent |
|
||||
| literals.rb:141:1:141:20 | /foo#{...}bar/ | RegexLiteral | 1 | literals.rb:141:7:141:16 | #{...} | StringInterpolationComponent |
|
||||
| literals.rb:141:1:141:20 | /foo#{...}bar/ | RegexLiteral | 2 | literals.rb:141:17:141:19 | bar | StringTextComponent |
|
||||
| literals.rb:142:1:142:10 | /foo/ | RegexLiteral | 0 | literals.rb:142:4:142:6 | foo | StringTextComponent |
|
||||
| literals.rb:145:1:145:34 | "abcdefghijklmnopqrstuvwxyzabcdef" | StringLiteral | 0 | literals.rb:145:2:145:33 | abcdefghijklmnopqrstuvwxyzabcdef | StringTextComponent |
|
||||
| literals.rb:146:1:146:35 | "foobarfoobarfoobarfoobarfooba..." | StringLiteral | 0 | literals.rb:146:2:146:34 | foobarfoobarfoobarfoobarfoobarfoo | StringTextComponent |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | StringLiteral | 0 | literals.rb:147:2:147:7 | foobar | StringTextComponent |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | StringLiteral | 1 | literals.rb:147:8:147:9 | \\\\ | StringEscapeSequenceComponent |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | StringLiteral | 2 | literals.rb:147:10:147:15 | foobar | StringTextComponent |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | StringLiteral | 3 | literals.rb:147:16:147:17 | \\\\ | StringEscapeSequenceComponent |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | StringLiteral | 4 | literals.rb:147:18:147:23 | foobar | StringTextComponent |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | StringLiteral | 5 | literals.rb:147:24:147:25 | \\\\ | StringEscapeSequenceComponent |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | StringLiteral | 6 | literals.rb:147:26:147:31 | foobar | StringTextComponent |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | StringLiteral | 7 | literals.rb:147:32:147:33 | \\\\ | StringEscapeSequenceComponent |
|
||||
| literals.rb:147:1:147:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | StringLiteral | 8 | literals.rb:147:34:147:39 | foobar | StringTextComponent |
|
||||
stringInterpolations
|
||||
| literals.rb:58:10:58:19 | #{...} | 0 | literals.rb:58:13:58:17 | ... + ... | AddExpr |
|
||||
| literals.rb:59:12:59:21 | #{...} | 0 | literals.rb:59:15:59:19 | ... + ... | AddExpr |
|
||||
| literals.rb:64:11:64:20 | #{...} | 0 | literals.rb:64:14:64:18 | ... * ... | MulExpr |
|
||||
| literals.rb:65:6:65:30 | #{...} | 0 | literals.rb:65:9:65:28 | "bar #{...} baz" | StringLiteral |
|
||||
| literals.rb:65:14:65:23 | #{...} | 0 | literals.rb:65:17:65:21 | ... + ... | AddExpr |
|
||||
| literals.rb:86:7:86:15 | #{...} | 0 | literals.rb:86:10:86:14 | ... + ... | AddExpr |
|
||||
| literals.rb:100:11:100:16 | #{...} | 0 | literals.rb:100:13:100:15 | ... + ... | AddExpr |
|
||||
| literals.rb:107:11:107:20 | #{...} | 0 | literals.rb:107:14:107:18 | ... + ... | AddExpr |
|
||||
| literals.rb:127:8:127:17 | #{...} | 0 | literals.rb:127:11:127:15 | ... + ... | AddExpr |
|
||||
| literals.rb:128:10:128:19 | #{...} | 0 | literals.rb:128:13:128:17 | ... - ... | SubExpr |
|
||||
| literals.rb:135:5:135:14 | #{...} | 0 | literals.rb:135:8:135:12 | ... + ... | AddExpr |
|
||||
| literals.rb:141:7:141:16 | #{...} | 0 | literals.rb:141:10:141:14 | ... + ... | AddExpr |
|
||||
concatenatedStrings
|
||||
| literals.rb:62:1:62:17 | "..." "..." | foobarbaz | 0 | literals.rb:62:1:62:5 | "foo" |
|
||||
| literals.rb:62:1:62:17 | "..." "..." | foobarbaz | 1 | literals.rb:62:7:62:11 | "bar" |
|
||||
| literals.rb:62:1:62:17 | "..." "..." | foobarbaz | 2 | literals.rb:62:13:62:17 | "baz" |
|
||||
| literals.rb:63:1:63:19 | "..." "..." | foobarbaz | 0 | literals.rb:63:1:63:7 | "foo" |
|
||||
| literals.rb:63:1:63:19 | "..." "..." | foobarbaz | 1 | literals.rb:63:9:63:13 | "bar" |
|
||||
| literals.rb:63:1:63:19 | "..." "..." | foobarbaz | 2 | literals.rb:63:15:63:19 | "baz" |
|
||||
| literals.rb:64:1:64:27 | "..." "..." | <none> | 0 | literals.rb:64:1:64:5 | "foo" |
|
||||
| literals.rb:64:1:64:27 | "..." "..." | <none> | 1 | literals.rb:64:7:64:21 | "bar#{...}" |
|
||||
| literals.rb:64:1:64:27 | "..." "..." | <none> | 2 | literals.rb:64:23:64:27 | "baz" |
|
||||
arrayLiterals
|
||||
| literals.rb:91:1:91:2 | [...] | 0 |
|
||||
| literals.rb:92:1:92:9 | [...] | 3 |
|
||||
| literals.rb:93:1:93:14 | [...] | 3 |
|
||||
| literals.rb:94:1:94:11 | [...] | 2 |
|
||||
| literals.rb:94:5:94:10 | [...] | 2 |
|
||||
| literals.rb:97:1:97:4 | %w(...) | 0 |
|
||||
| literals.rb:98:1:98:15 | %w(...) | 3 |
|
||||
| literals.rb:99:1:99:15 | %w(...) | 3 |
|
||||
| literals.rb:100:1:100:21 | %w(...) | 3 |
|
||||
| literals.rb:101:1:101:21 | %w(...) | 3 |
|
||||
| literals.rb:104:1:104:4 | %i(...) | 0 |
|
||||
| literals.rb:105:1:105:15 | %i(...) | 3 |
|
||||
| literals.rb:106:1:106:15 | %i(...) | 3 |
|
||||
| literals.rb:107:1:107:25 | %i(...) | 3 |
|
||||
| literals.rb:108:1:108:25 | %i(...) | 7 |
|
||||
arrayLiteralElements
|
||||
| literals.rb:92:1:92:9 | [...] | 0 | literals.rb:92:2:92:2 | 1 | IntegerLiteral |
|
||||
| literals.rb:92:1:92:9 | [...] | 1 | literals.rb:92:5:92:5 | 2 | IntegerLiteral |
|
||||
| literals.rb:92:1:92:9 | [...] | 2 | literals.rb:92:8:92:8 | 3 | IntegerLiteral |
|
||||
| literals.rb:93:1:93:14 | [...] | 0 | literals.rb:93:2:93:2 | 4 | IntegerLiteral |
|
||||
| literals.rb:93:1:93:14 | [...] | 1 | literals.rb:93:5:93:5 | 5 | IntegerLiteral |
|
||||
| literals.rb:93:1:93:14 | [...] | 2 | literals.rb:93:8:93:13 | ... / ... | DivExpr |
|
||||
| literals.rb:94:1:94:11 | [...] | 0 | literals.rb:94:2:94:2 | 7 | IntegerLiteral |
|
||||
| literals.rb:94:1:94:11 | [...] | 1 | literals.rb:94:5:94:10 | [...] | ArrayLiteral |
|
||||
| literals.rb:94:5:94:10 | [...] | 0 | literals.rb:94:6:94:6 | 8 | IntegerLiteral |
|
||||
| literals.rb:94:5:94:10 | [...] | 1 | literals.rb:94:9:94:9 | 9 | IntegerLiteral |
|
||||
| literals.rb:98:1:98:15 | %w(...) | 0 | literals.rb:98:4:98:6 | "foo" | StringLiteral |
|
||||
| literals.rb:98:1:98:15 | %w(...) | 1 | literals.rb:98:8:98:10 | "bar" | StringLiteral |
|
||||
| literals.rb:98:1:98:15 | %w(...) | 2 | literals.rb:98:12:98:14 | "baz" | StringLiteral |
|
||||
| literals.rb:99:1:99:15 | %w(...) | 0 | literals.rb:99:4:99:6 | "foo" | StringLiteral |
|
||||
| literals.rb:99:1:99:15 | %w(...) | 1 | literals.rb:99:8:99:10 | "bar" | StringLiteral |
|
||||
| literals.rb:99:1:99:15 | %w(...) | 2 | literals.rb:99:12:99:14 | "baz" | StringLiteral |
|
||||
| literals.rb:100:1:100:21 | %w(...) | 0 | literals.rb:100:4:100:6 | "foo" | StringLiteral |
|
||||
| literals.rb:100:1:100:21 | %w(...) | 1 | literals.rb:100:8:100:16 | "bar#{...}" | StringLiteral |
|
||||
| literals.rb:100:1:100:21 | %w(...) | 2 | literals.rb:100:18:100:20 | "baz" | StringLiteral |
|
||||
| literals.rb:101:1:101:21 | %w(...) | 0 | literals.rb:101:4:101:6 | "foo" | StringLiteral |
|
||||
| literals.rb:101:1:101:21 | %w(...) | 1 | literals.rb:101:8:101:16 | "bar#{1+1}" | StringLiteral |
|
||||
| literals.rb:101:1:101:21 | %w(...) | 2 | literals.rb:101:18:101:20 | "baz" | StringLiteral |
|
||||
| literals.rb:105:1:105:15 | %i(...) | 0 | literals.rb:105:4:105:6 | :"foo" | SymbolLiteral |
|
||||
| literals.rb:105:1:105:15 | %i(...) | 1 | literals.rb:105:8:105:10 | :"bar" | SymbolLiteral |
|
||||
| literals.rb:105:1:105:15 | %i(...) | 2 | literals.rb:105:12:105:14 | :"baz" | SymbolLiteral |
|
||||
| literals.rb:106:1:106:15 | %i(...) | 0 | literals.rb:106:4:106:6 | :"foo" | SymbolLiteral |
|
||||
| literals.rb:106:1:106:15 | %i(...) | 1 | literals.rb:106:8:106:10 | :"bar" | SymbolLiteral |
|
||||
| literals.rb:106:1:106:15 | %i(...) | 2 | literals.rb:106:12:106:14 | :"baz" | SymbolLiteral |
|
||||
| literals.rb:107:1:107:25 | %i(...) | 0 | literals.rb:107:4:107:6 | :"foo" | SymbolLiteral |
|
||||
| literals.rb:107:1:107:25 | %i(...) | 1 | literals.rb:107:8:107:20 | :"bar#{...}" | SymbolLiteral |
|
||||
| literals.rb:107:1:107:25 | %i(...) | 2 | literals.rb:107:22:107:24 | :"baz" | SymbolLiteral |
|
||||
| literals.rb:108:1:108:25 | %i(...) | 0 | literals.rb:108:4:108:6 | :"foo" | SymbolLiteral |
|
||||
| literals.rb:108:1:108:25 | %i(...) | 1 | literals.rb:108:8:108:12 | :"bar#{" | SymbolLiteral |
|
||||
| literals.rb:108:1:108:25 | %i(...) | 2 | literals.rb:108:14:108:14 | :"2" | SymbolLiteral |
|
||||
| literals.rb:108:1:108:25 | %i(...) | 3 | literals.rb:108:16:108:16 | :"+" | SymbolLiteral |
|
||||
| literals.rb:108:1:108:25 | %i(...) | 4 | literals.rb:108:18:108:18 | :"4" | SymbolLiteral |
|
||||
| literals.rb:108:1:108:25 | %i(...) | 5 | literals.rb:108:20:108:20 | :"}" | SymbolLiteral |
|
||||
| literals.rb:108:1:108:25 | %i(...) | 6 | literals.rb:108:22:108:24 | :"baz" | SymbolLiteral |
|
||||
hashLiterals
|
||||
| literals.rb:83:1:83:14 | {...} | 1 |
|
||||
| literals.rb:111:1:111:2 | {...} | 0 |
|
||||
| literals.rb:112:1:112:33 | {...} | 3 |
|
||||
| literals.rb:113:1:113:17 | {...} | 2 |
|
||||
hashLiteralElements
|
||||
| literals.rb:83:1:83:14 | {...} | 0 | literals.rb:83:3:83:12 | Pair | Pair |
|
||||
| literals.rb:112:1:112:33 | {...} | 0 | literals.rb:112:3:112:8 | Pair | Pair |
|
||||
| literals.rb:112:1:112:33 | {...} | 1 | literals.rb:112:11:112:19 | Pair | Pair |
|
||||
| literals.rb:112:1:112:33 | {...} | 2 | literals.rb:112:22:112:31 | Pair | Pair |
|
||||
| literals.rb:113:1:113:17 | {...} | 0 | literals.rb:113:3:113:8 | Pair | Pair |
|
||||
| literals.rb:113:1:113:17 | {...} | 1 | literals.rb:113:11:113:15 | **... | HashSplatArgument |
|
||||
hashLiteralKeyValuePairs
|
||||
| literals.rb:83:1:83:14 | {...} | literals.rb:83:3:83:12 | Pair | literals.rb:83:3:83:5 | :foo | literals.rb:83:8:83:12 | "bar" |
|
||||
| literals.rb:112:1:112:33 | {...} | literals.rb:112:3:112:8 | Pair | literals.rb:112:3:112:5 | :foo | literals.rb:112:8:112:8 | 1 |
|
||||
| literals.rb:112:1:112:33 | {...} | literals.rb:112:11:112:19 | Pair | literals.rb:112:11:112:14 | :bar | literals.rb:112:19:112:19 | 2 |
|
||||
| literals.rb:112:1:112:33 | {...} | literals.rb:112:22:112:31 | Pair | literals.rb:112:22:112:26 | "baz" | literals.rb:112:31:112:31 | 3 |
|
||||
| literals.rb:113:1:113:17 | {...} | literals.rb:113:3:113:8 | Pair | literals.rb:113:3:113:5 | :foo | literals.rb:113:8:113:8 | 7 |
|
||||
finiteRangeLiterals
|
||||
| literals.rb:116:2:116:6 | _ .. _ | literals.rb:116:2:116:2 | 1 | literals.rb:116:5:116:6 | 10 |
|
||||
| literals.rb:117:2:117:7 | _ ... _ | literals.rb:117:2:117:2 | 1 | literals.rb:117:6:117:7 | 10 |
|
||||
| literals.rb:118:2:118:7 | _ .. _ | literals.rb:118:2:118:2 | 1 | literals.rb:118:7:118:7 | 0 |
|
||||
| literals.rb:119:2:119:11 | _ .. _ | literals.rb:119:2:119:6 | call to start | literals.rb:119:9:119:11 | ... + ... |
|
||||
beginlessRangeLiterals
|
||||
| literals.rb:121:2:121:4 | _ .. _ | literals.rb:121:4:121:4 | 1 |
|
||||
endlessRangeLiterals
|
||||
| literals.rb:120:2:120:4 | _ .. _ | literals.rb:120:2:120:2 | 1 |
|
||||
| literals.rb:122:2:122:4 | _ .. _ | literals.rb:122:2:122:2 | 0 |
|
||||
inclusiveRangeLiterals
|
||||
| literals.rb:116:2:116:6 | _ .. _ |
|
||||
| literals.rb:118:2:118:7 | _ .. _ |
|
||||
| literals.rb:119:2:119:11 | _ .. _ |
|
||||
| literals.rb:120:2:120:4 | _ .. _ |
|
||||
| literals.rb:121:2:121:4 | _ .. _ |
|
||||
| literals.rb:122:2:122:4 | _ .. _ |
|
||||
exclusiveRangeLiterals
|
||||
| literals.rb:117:2:117:7 | _ ... _ |
|
||||
numericLiterals
|
||||
| literals.rb:10:1:10:4 | 1234 | IntegerLiteral | 1234 |
|
||||
| literals.rb:11:1:11:5 | 5_678 | IntegerLiteral | 5_678 |
|
||||
| literals.rb:12:1:12:1 | 0 | IntegerLiteral | 0 |
|
||||
| literals.rb:13:1:13:5 | 0d900 | IntegerLiteral | 0d900 |
|
||||
| literals.rb:16:1:16:6 | 0x1234 | IntegerLiteral | 0x1234 |
|
||||
| literals.rb:17:1:17:10 | 0xdeadbeef | IntegerLiteral | 0xdeadbeef |
|
||||
| literals.rb:18:1:18:11 | 0xF00D_face | IntegerLiteral | 0xF00D_face |
|
||||
| literals.rb:21:1:21:4 | 0123 | IntegerLiteral | 0123 |
|
||||
| literals.rb:22:1:22:5 | 0o234 | IntegerLiteral | 0o234 |
|
||||
| literals.rb:23:1:23:6 | 0O45_6 | IntegerLiteral | 0O45_6 |
|
||||
| literals.rb:26:1:26:10 | 0b10010100 | IntegerLiteral | 0b10010100 |
|
||||
| literals.rb:27:1:27:11 | 0B011_01101 | IntegerLiteral | 0B011_01101 |
|
||||
| literals.rb:30:1:30:5 | 12.34 | FloatLiteral | 12.34 |
|
||||
| literals.rb:31:1:31:7 | 1234e-2 | FloatLiteral | 1234e-2 |
|
||||
| literals.rb:32:1:32:7 | 1.234E1 | FloatLiteral | 1.234E1 |
|
||||
| literals.rb:35:1:35:3 | 23r | RationalLiteral | 23r |
|
||||
| literals.rb:36:1:36:5 | 9.85r | RationalLiteral | 9.85r |
|
||||
| literals.rb:39:1:39:2 | 2i | ComplexLiteral | 2i |
|
||||
| literals.rb:58:13:58:13 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:58:17:58:17 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:59:15:59:15 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:59:19:59:19 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:64:14:64:14 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:64:18:64:18 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:65:17:65:17 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:65:21:65:21 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:86:10:86:10 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:86:14:86:14 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:92:2:92:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:92:5:92:5 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:92:8:92:8 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:93:2:93:2 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:93:5:93:5 | 5 | IntegerLiteral | 5 |
|
||||
| literals.rb:93:8:93:9 | 12 | IntegerLiteral | 12 |
|
||||
| literals.rb:93:13:93:13 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:94:2:94:2 | 7 | IntegerLiteral | 7 |
|
||||
| literals.rb:94:6:94:6 | 8 | IntegerLiteral | 8 |
|
||||
| literals.rb:94:9:94:9 | 9 | IntegerLiteral | 9 |
|
||||
| literals.rb:100:13:100:13 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:100:15:100:15 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:107:14:107:14 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:107:18:107:18 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:112:8:112:8 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:112:19:112:19 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:112:31:112:31 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:113:8:113:8 | 7 | IntegerLiteral | 7 |
|
||||
| literals.rb:116:2:116:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:116:5:116:6 | 10 | IntegerLiteral | 10 |
|
||||
| literals.rb:117:2:117:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:117:6:117:7 | 10 | IntegerLiteral | 10 |
|
||||
| literals.rb:118:2:118:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:118:7:118:7 | 0 | IntegerLiteral | 0 |
|
||||
| literals.rb:119:9:119:9 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:119:11:119:11 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:120:2:120:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:121:4:121:4 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:122:2:122:2 | 0 | IntegerLiteral | 0 |
|
||||
| literals.rb:122:6:122:6 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:127:11:127:11 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:127:15:127:15 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:128:13:128:13 | 5 | IntegerLiteral | 5 |
|
||||
| literals.rb:128:17:128:17 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:135:8:135:8 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:135:12:135:12 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:141:10:141:10 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:141:14:141:14 | 1 | IntegerLiteral | 1 |
|
||||
integerLiterals
|
||||
| literals.rb:10:1:10:4 | 1234 | IntegerLiteral | 1234 |
|
||||
| literals.rb:11:1:11:5 | 5_678 | IntegerLiteral | 5_678 |
|
||||
| literals.rb:12:1:12:1 | 0 | IntegerLiteral | 0 |
|
||||
| literals.rb:13:1:13:5 | 0d900 | IntegerLiteral | 0d900 |
|
||||
| literals.rb:16:1:16:6 | 0x1234 | IntegerLiteral | 0x1234 |
|
||||
| literals.rb:17:1:17:10 | 0xdeadbeef | IntegerLiteral | 0xdeadbeef |
|
||||
| literals.rb:18:1:18:11 | 0xF00D_face | IntegerLiteral | 0xF00D_face |
|
||||
| literals.rb:21:1:21:4 | 0123 | IntegerLiteral | 0123 |
|
||||
| literals.rb:22:1:22:5 | 0o234 | IntegerLiteral | 0o234 |
|
||||
| literals.rb:23:1:23:6 | 0O45_6 | IntegerLiteral | 0O45_6 |
|
||||
| literals.rb:26:1:26:10 | 0b10010100 | IntegerLiteral | 0b10010100 |
|
||||
| literals.rb:27:1:27:11 | 0B011_01101 | IntegerLiteral | 0B011_01101 |
|
||||
| literals.rb:58:13:58:13 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:58:17:58:17 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:59:15:59:15 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:59:19:59:19 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:64:14:64:14 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:64:18:64:18 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:65:17:65:17 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:65:21:65:21 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:86:10:86:10 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:86:14:86:14 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:92:2:92:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:92:5:92:5 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:92:8:92:8 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:93:2:93:2 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:93:5:93:5 | 5 | IntegerLiteral | 5 |
|
||||
| literals.rb:93:8:93:9 | 12 | IntegerLiteral | 12 |
|
||||
| literals.rb:93:13:93:13 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:94:2:94:2 | 7 | IntegerLiteral | 7 |
|
||||
| literals.rb:94:6:94:6 | 8 | IntegerLiteral | 8 |
|
||||
| literals.rb:94:9:94:9 | 9 | IntegerLiteral | 9 |
|
||||
| literals.rb:100:13:100:13 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:100:15:100:15 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:107:14:107:14 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:107:18:107:18 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:112:8:112:8 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:112:19:112:19 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:112:31:112:31 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:113:8:113:8 | 7 | IntegerLiteral | 7 |
|
||||
| literals.rb:116:2:116:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:116:5:116:6 | 10 | IntegerLiteral | 10 |
|
||||
| literals.rb:117:2:117:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:117:6:117:7 | 10 | IntegerLiteral | 10 |
|
||||
| literals.rb:118:2:118:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:118:7:118:7 | 0 | IntegerLiteral | 0 |
|
||||
| literals.rb:119:9:119:9 | 2 | IntegerLiteral | 2 |
|
||||
| literals.rb:119:11:119:11 | 3 | IntegerLiteral | 3 |
|
||||
| literals.rb:120:2:120:2 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:121:4:121:4 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:122:2:122:2 | 0 | IntegerLiteral | 0 |
|
||||
| literals.rb:122:6:122:6 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:127:11:127:11 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:127:15:127:15 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:128:13:128:13 | 5 | IntegerLiteral | 5 |
|
||||
| literals.rb:128:17:128:17 | 4 | IntegerLiteral | 4 |
|
||||
| literals.rb:135:8:135:8 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:135:12:135:12 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:141:10:141:10 | 1 | IntegerLiteral | 1 |
|
||||
| literals.rb:141:14:141:14 | 1 | IntegerLiteral | 1 |
|
||||
floatLiterals
|
||||
| literals.rb:30:1:30:5 | 12.34 | FloatLiteral | 12.34 |
|
||||
| literals.rb:31:1:31:7 | 1234e-2 | FloatLiteral | 1234e-2 |
|
||||
| literals.rb:32:1:32:7 | 1.234E1 | FloatLiteral | 1.234E1 |
|
||||
rationalLiterals
|
||||
| literals.rb:35:1:35:3 | 23r | RationalLiteral | 23r |
|
||||
| literals.rb:36:1:36:5 | 9.85r | RationalLiteral | 9.85r |
|
||||
complexLiterals
|
||||
| literals.rb:39:1:39:2 | 2i | ComplexLiteral | 2i |
|
||||
110
ql/test/library-tests/ast/literals/literals.ql
Normal file
110
ql/test/library-tests/ast/literals/literals.ql
Normal file
@@ -0,0 +1,110 @@
|
||||
import ruby
|
||||
|
||||
query predicate allLiterals(Literal l, string pClass, string valueText) {
|
||||
pClass = l.getAPrimaryQlClass() and
|
||||
(
|
||||
valueText = l.getValueText()
|
||||
or
|
||||
not exists(l.getValueText()) and valueText = "<none>"
|
||||
)
|
||||
}
|
||||
|
||||
query predicate stringlikeLiterals(StringlikeLiteral l, string valueText) {
|
||||
valueText = l.getValueText()
|
||||
or
|
||||
not exists(l.getValueText()) and valueText = "<none>"
|
||||
}
|
||||
|
||||
query predicate stringLiterals(StringLiteral l, string valueText) {
|
||||
stringlikeLiterals(l, valueText)
|
||||
}
|
||||
|
||||
query predicate regexLiterals(RegexLiteral l, string valueText, string flags) {
|
||||
stringlikeLiterals(l, valueText) and flags = l.getFlagString()
|
||||
}
|
||||
|
||||
query predicate symbolLiterals(SymbolLiteral l, string valueText) {
|
||||
stringlikeLiterals(l, valueText)
|
||||
}
|
||||
|
||||
query predicate subshellLiterals(SubshellLiteral l, string valueText) {
|
||||
stringlikeLiterals(l, valueText)
|
||||
}
|
||||
|
||||
query predicate stringComponents(
|
||||
StringlikeLiteral l, string lClass, int i, StringComponent c, string cClass
|
||||
) {
|
||||
lClass = l.getAPrimaryQlClass() and
|
||||
c = l.getComponent(i) and
|
||||
cClass = c.getAPrimaryQlClass()
|
||||
}
|
||||
|
||||
query predicate stringInterpolations(StringInterpolationComponent c, int i, Expr e, string eClass) {
|
||||
e = c.getStmt(i) and eClass = e.getAPrimaryQlClass()
|
||||
}
|
||||
|
||||
query predicate concatenatedStrings(StringConcatenation sc, string valueText, int n, StringLiteral l) {
|
||||
l = sc.getString(n) and
|
||||
(
|
||||
valueText = sc.getConcatenatedValueText()
|
||||
or
|
||||
not exists(sc.getConcatenatedValueText()) and valueText = "<none>"
|
||||
)
|
||||
}
|
||||
|
||||
query predicate arrayLiterals(ArrayLiteral l, int numElements) {
|
||||
numElements = l.getNumberOfElements()
|
||||
}
|
||||
|
||||
query predicate arrayLiteralElements(ArrayLiteral l, int n, Expr elementN, string pClass) {
|
||||
elementN = l.getElement(n) and pClass = elementN.getAPrimaryQlClass()
|
||||
}
|
||||
|
||||
query predicate hashLiterals(HashLiteral l, int numElements) {
|
||||
numElements = l.getNumberOfElements()
|
||||
}
|
||||
|
||||
query predicate hashLiteralElements(HashLiteral l, int n, Expr elementN, string pClass) {
|
||||
elementN = l.getElement(n) and pClass = elementN.getAPrimaryQlClass()
|
||||
}
|
||||
|
||||
query predicate hashLiteralKeyValuePairs(HashLiteral l, Pair p, Expr k, Expr v) {
|
||||
p = l.getAKeyValuePair() and k = p.getKey() and v = p.getValue()
|
||||
}
|
||||
|
||||
query predicate finiteRangeLiterals(RangeLiteral l, Expr begin, Expr end) {
|
||||
begin = l.getBegin() and
|
||||
end = l.getEnd()
|
||||
}
|
||||
|
||||
query predicate beginlessRangeLiterals(RangeLiteral l, Expr end) {
|
||||
not exists(l.getBegin()) and end = l.getEnd()
|
||||
}
|
||||
|
||||
query predicate endlessRangeLiterals(RangeLiteral l, Expr begin) {
|
||||
begin = l.getBegin() and not exists(l.getEnd())
|
||||
}
|
||||
|
||||
query predicate inclusiveRangeLiterals(RangeLiteral l) { l.isInclusive() }
|
||||
|
||||
query predicate exclusiveRangeLiterals(RangeLiteral l) { l.isExclusive() }
|
||||
|
||||
query predicate numericLiterals(NumericLiteral l, string pClass, string valueText) {
|
||||
allLiterals(l, pClass, valueText)
|
||||
}
|
||||
|
||||
query predicate integerLiterals(IntegerLiteral l, string pClass, string valueText) {
|
||||
allLiterals(l, pClass, valueText)
|
||||
}
|
||||
|
||||
query predicate floatLiterals(FloatLiteral l, string pClass, string valueText) {
|
||||
allLiterals(l, pClass, valueText)
|
||||
}
|
||||
|
||||
query predicate rationalLiterals(RationalLiteral l, string pClass, string valueText) {
|
||||
allLiterals(l, pClass, valueText)
|
||||
}
|
||||
|
||||
query predicate complexLiterals(ComplexLiteral l, string pClass, string valueText) {
|
||||
allLiterals(l, pClass, valueText)
|
||||
}
|
||||
147
ql/test/library-tests/ast/literals/literals.rb
Normal file
147
ql/test/library-tests/ast/literals/literals.rb
Normal file
@@ -0,0 +1,147 @@
|
||||
# boolean values and nil
|
||||
nil
|
||||
NIL
|
||||
false
|
||||
FALSE
|
||||
true
|
||||
TRUE
|
||||
|
||||
# decimal integers
|
||||
1234
|
||||
5_678
|
||||
0
|
||||
0d900
|
||||
|
||||
# hexadecimal integers
|
||||
0x1234
|
||||
0xdeadbeef
|
||||
0xF00D_face
|
||||
|
||||
# octal integers
|
||||
0123
|
||||
0o234
|
||||
0O45_6
|
||||
|
||||
# binary integers
|
||||
0b10010100
|
||||
0B011_01101
|
||||
|
||||
# floating-point numbers
|
||||
12.34
|
||||
1234e-2
|
||||
1.234E1
|
||||
|
||||
# rational numbers
|
||||
23r
|
||||
9.85r
|
||||
|
||||
# imaginary/complex numbers
|
||||
2i
|
||||
#3.14i # BAD: parse error
|
||||
|
||||
# imaginary & rational
|
||||
#1.2ri # BAD: parse error
|
||||
|
||||
# strings
|
||||
""
|
||||
''
|
||||
"hello"
|
||||
'goodbye'
|
||||
"string with escaped \" quote"
|
||||
'string with " quote'
|
||||
%(foo bar baz)
|
||||
%q<foo bar baz>
|
||||
%q(foo ' bar " baz')
|
||||
%Q(FOO ' BAR " BAZ')
|
||||
%q(foo\ bar) # "foo\\ bar"
|
||||
%Q(foo\ bar) # "foo bar"
|
||||
"2 + 2 = #{ 2 + 2 }" # interpolation
|
||||
%Q(3 + 4 = #{ 3 + 4 }) # interpolation
|
||||
'2 + 2 = #{ 2 + 2 }' # no interpolation
|
||||
%q(3 + 4 = #{ 3 + 4 }) # no interpolation
|
||||
"foo" 'bar' "baz" # concatenated
|
||||
%q{foo} "bar" 'baz' # concatenated
|
||||
"foo" "bar#{ 1 * 1 }" 'baz' # concatenated, interpolation
|
||||
"foo #{ "bar #{ 2 + 3 } baz" } qux" # interpolation containing string containing interpolation
|
||||
|
||||
# characters
|
||||
?x
|
||||
?\n
|
||||
?\s
|
||||
?\\
|
||||
?\u{58}
|
||||
?\C-a
|
||||
?\M-a
|
||||
?\M-\C-a
|
||||
?\C-\M-a
|
||||
|
||||
# symbols
|
||||
:""
|
||||
:hello
|
||||
:"foo bar"
|
||||
:'bar baz'
|
||||
{ foo: "bar" }
|
||||
%s(wibble)
|
||||
%s[wibble wobble]
|
||||
:"foo_#{ 2 + 2}" # interpolation
|
||||
:'foo_#{ 1 + 1 }' # no interpolation
|
||||
%s(foo_#{ 3 - 2 }) # no interpolation
|
||||
|
||||
# arrays
|
||||
[]
|
||||
[1, 2, 3]
|
||||
[4, 5, 12 / 2]
|
||||
[7, [8, 9]]
|
||||
|
||||
# arrays of strings
|
||||
%w()
|
||||
%w(foo bar baz)
|
||||
%w!foo bar baz!
|
||||
%W[foo bar#{1+1} baz] # interpolation
|
||||
%w[foo bar#{1+1} baz] # no interpolation
|
||||
|
||||
# arrays of symbols
|
||||
%i()
|
||||
%i(foo bar baz)
|
||||
%i@foo bar baz@
|
||||
%I(foo bar#{ 2 + 4 } baz) # interpolation
|
||||
%i(foo bar#{ 2 + 4 } baz) # no interpolation
|
||||
|
||||
# hashes
|
||||
{}
|
||||
{ foo: 1, :bar => 2, 'baz' => 3 }
|
||||
{ foo: 7, **bar } # hash-splat argument
|
||||
|
||||
# ranges
|
||||
(1..10)
|
||||
(1...10)
|
||||
(1 .. 0)
|
||||
(start..2+3)
|
||||
(1..) # 1 to infinity
|
||||
(..1) # -infinity to 1
|
||||
(0..-1) # BAD: parsed as binary with minus endless range on the LHS
|
||||
|
||||
# subshell
|
||||
`ls -l`
|
||||
%x(ls -l)
|
||||
`du -d #{ 1 + 1 }` # interpolation
|
||||
%x@du -d #{ 5 - 4 }@ # interpolation
|
||||
|
||||
# regular expressions
|
||||
//
|
||||
/foo/
|
||||
/foo/i
|
||||
/foo+\sbar\S/
|
||||
/foo#{ 1 + 1 }bar/ # interpolation
|
||||
/foo/oxm
|
||||
%r[]
|
||||
%r(foo)
|
||||
%r:foo:i
|
||||
%r{foo+\sbar\S}
|
||||
%r{foo#{ 1 + 1 }bar} # interpolation
|
||||
%r:foo:mxo
|
||||
|
||||
# long strings
|
||||
'abcdefghijklmnopqrstuvwxyzabcdef' # 32 chars, should not be truncated
|
||||
'foobarfoobarfoobarfoobarfoobarfoo' # 33 chars, should be truncated
|
||||
"foobar\\foobar\\foobar\\foobar\\foobar" # several short components, but long enough overall to be truncated
|
||||
@@ -18,4 +18,4 @@ alias
|
||||
| misc.rb:9:1:9:16 | alias ... | new | misc.rb:9:7:9:11 | super | super | MethodName |
|
||||
| misc.rb:9:1:9:16 | alias ... | old | misc.rb:9:13:9:16 | self | self | MethodName |
|
||||
| misc.rb:10:1:10:24 | alias ... | new | misc.rb:10:7:10:17 | :"\\n#{...}" | (none) | MethodName |
|
||||
| misc.rb:10:1:10:24 | alias ... | old | misc.rb:10:19:10:24 | :foo | foo | MethodName |
|
||||
| misc.rb:10:1:10:24 | alias ... | old | misc.rb:10:19:10:24 | :"foo" | foo | MethodName |
|
||||
|
||||
@@ -22,8 +22,8 @@ binaryOperations
|
||||
| operations.rb:59:1:59:5 | ... < ... | < | operations.rb:59:1:59:1 | a | operations.rb:59:5:59:5 | b | LTExpr |
|
||||
| operations.rb:60:1:60:8 | ... <= ... | <= | operations.rb:60:1:60:1 | 7 | operations.rb:60:6:60:8 | foo | LEExpr |
|
||||
| operations.rb:63:1:63:7 | ... <=> ... | <=> | operations.rb:63:1:63:1 | a | operations.rb:63:7:63:7 | b | SpaceshipExpr |
|
||||
| operations.rb:64:1:64:15 | ... =~ ... | =~ | operations.rb:64:1:64:4 | name | operations.rb:64:9:64:15 | foo.* | RegexMatchExpr |
|
||||
| operations.rb:65:1:65:17 | ... !~ ... | !~ | operations.rb:65:1:65:6 | handle | operations.rb:65:11:65:17 | .*bar | NoRegexMatchExpr |
|
||||
| operations.rb:64:1:64:15 | ... =~ ... | =~ | operations.rb:64:1:64:4 | name | operations.rb:64:9:64:15 | /foo.*/ | RegexMatchExpr |
|
||||
| operations.rb:65:1:65:17 | ... !~ ... | !~ | operations.rb:65:1:65:6 | handle | operations.rb:65:11:65:17 | /.*bar/ | NoRegexMatchExpr |
|
||||
binaryArithmeticOperations
|
||||
| operations.rb:31:1:31:7 | ... + ... | + | operations.rb:31:1:31:1 | w | operations.rb:31:5:31:7 | 234 | AddExpr |
|
||||
| operations.rb:32:1:32:6 | ... - ... | - | operations.rb:32:1:32:1 | x | operations.rb:32:5:32:6 | 17 | SubExpr |
|
||||
@@ -62,6 +62,6 @@ relationalOperations
|
||||
spaceshipExprs
|
||||
| operations.rb:63:1:63:7 | ... <=> ... | <=> | operations.rb:63:1:63:1 | a | operations.rb:63:7:63:7 | b | SpaceshipExpr |
|
||||
regexMatchExprs
|
||||
| operations.rb:64:1:64:15 | ... =~ ... | =~ | operations.rb:64:1:64:4 | name | operations.rb:64:9:64:15 | foo.* | RegexMatchExpr |
|
||||
| operations.rb:64:1:64:15 | ... =~ ... | =~ | operations.rb:64:1:64:4 | name | operations.rb:64:9:64:15 | /foo.*/ | RegexMatchExpr |
|
||||
noRegexMatchExprs
|
||||
| operations.rb:65:1:65:17 | ... !~ ... | !~ | operations.rb:65:1:65:6 | handle | operations.rb:65:11:65:17 | .*bar | NoRegexMatchExpr |
|
||||
| operations.rb:65:1:65:17 | ... !~ ... | !~ | operations.rb:65:1:65:6 | handle | operations.rb:65:11:65:17 | /.*bar/ | NoRegexMatchExpr |
|
||||
|
||||
@@ -87,9 +87,9 @@
|
||||
| operations.rb:63:1:63:7 | ... <=> ... | <=> | operations.rb:63:1:63:1 | a | SpaceshipExpr |
|
||||
| operations.rb:63:1:63:7 | ... <=> ... | <=> | operations.rb:63:7:63:7 | b | SpaceshipExpr |
|
||||
| operations.rb:64:1:64:15 | ... =~ ... | =~ | operations.rb:64:1:64:4 | name | RegexMatchExpr |
|
||||
| operations.rb:64:1:64:15 | ... =~ ... | =~ | operations.rb:64:9:64:15 | foo.* | RegexMatchExpr |
|
||||
| operations.rb:64:1:64:15 | ... =~ ... | =~ | operations.rb:64:9:64:15 | /foo.*/ | RegexMatchExpr |
|
||||
| operations.rb:65:1:65:17 | ... !~ ... | !~ | operations.rb:65:1:65:6 | handle | NoRegexMatchExpr |
|
||||
| operations.rb:65:1:65:17 | ... !~ ... | !~ | operations.rb:65:11:65:17 | .*bar | NoRegexMatchExpr |
|
||||
| operations.rb:65:1:65:17 | ... !~ ... | !~ | operations.rb:65:11:65:17 | /.*bar/ | NoRegexMatchExpr |
|
||||
| operations.rb:68:1:68:8 | ... += ... | += | operations.rb:68:1:68:1 | x | AssignAddExpr |
|
||||
| operations.rb:68:1:68:8 | ... += ... | += | operations.rb:68:6:68:8 | 128 | AssignAddExpr |
|
||||
| operations.rb:69:1:69:7 | ... -= ... | -= | operations.rb:69:1:69:1 | y | AssignSubExpr |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,8 @@
|
||||
| local_dataflow.rb:6:7:6:14 | (... += ...) | local_dataflow.rb:6:3:6:14 | ... = ... |
|
||||
| local_dataflow.rb:6:8:6:13 | ... += ... | local_dataflow.rb:6:7:6:14 | (... += ...) |
|
||||
| local_dataflow.rb:9:1:9:15 | ... = ... | local_dataflow.rb:10:14:10:18 | array |
|
||||
| local_dataflow.rb:9:9:9:15 | [...] | local_dataflow.rb:9:1:9:15 | ... = ... |
|
||||
| local_dataflow.rb:9:9:9:15 | [...] | local_dataflow.rb:9:1:9:15 | ... = ... |
|
||||
| local_dataflow.rb:10:5:13:3 | for ... in ... | local_dataflow.rb:10:1:13:3 | ... = ... |
|
||||
| local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:12:5:12:5 | x |
|
||||
| local_dataflow.rb:10:14:10:18 | array | local_dataflow.rb:10:5:13:3 | for ... in ... |
|
||||
@@ -32,9 +34,9 @@
|
||||
| local_dataflow.rb:24:2:24:8 | break | local_dataflow.rb:23:1:25:3 | while ... |
|
||||
| local_dataflow.rb:24:8:24:8 | 5 | local_dataflow.rb:24:2:24:8 | break |
|
||||
| local_dataflow.rb:28:5:28:26 | M | local_dataflow.rb:28:1:28:26 | ... = ... |
|
||||
| local_dataflow.rb:28:15:28:22 | module | local_dataflow.rb:28:5:28:26 | M |
|
||||
| local_dataflow.rb:28:15:28:22 | "module" | local_dataflow.rb:28:5:28:26 | M |
|
||||
| local_dataflow.rb:30:5:30:24 | C | local_dataflow.rb:30:1:30:24 | ... = ... |
|
||||
| local_dataflow.rb:30:14:30:20 | class | local_dataflow.rb:30:5:30:24 | C |
|
||||
| local_dataflow.rb:30:14:30:20 | "class" | local_dataflow.rb:30:5:30:24 | C |
|
||||
| local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:25 | ... = ... |
|
||||
| local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:25 | ... = ... |
|
||||
| local_dataflow.rb:34:7:34:7 | x | local_dataflow.rb:35:6:35:6 | x |
|
||||
@@ -43,6 +45,6 @@
|
||||
| local_dataflow.rb:43:13:43:13 | 7 | local_dataflow.rb:43:6:43:13 | return |
|
||||
| local_dataflow.rb:45:10:45:10 | 6 | local_dataflow.rb:45:3:45:10 | return |
|
||||
| local_dataflow.rb:49:3:53:3 | <captured> | local_dataflow.rb:50:18:50:18 | x |
|
||||
| local_dataflow.rb:50:8:50:13 | next | local_dataflow.rb:50:3:50:13 | next |
|
||||
| local_dataflow.rb:50:8:50:13 | "next" | local_dataflow.rb:50:3:50:13 | next |
|
||||
| local_dataflow.rb:50:18:50:18 | x | local_dataflow.rb:51:20:51:20 | x |
|
||||
| local_dataflow.rb:51:9:51:15 | break | local_dataflow.rb:51:3:51:15 | break |
|
||||
| local_dataflow.rb:51:9:51:15 | "break" | local_dataflow.rb:51:3:51:15 | break |
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
| local_dataflow.rb:6:3:6:14 | ... = ... |
|
||||
| local_dataflow.rb:32:14:32:21 | method |
|
||||
| local_dataflow.rb:32:14:32:21 | "method" |
|
||||
| local_dataflow.rb:36:6:36:13 | return |
|
||||
| local_dataflow.rb:38:3:38:13 | reachable |
|
||||
| local_dataflow.rb:38:3:38:13 | "reachable" |
|
||||
| local_dataflow.rb:43:6:43:13 | return |
|
||||
| local_dataflow.rb:45:3:45:10 | return |
|
||||
| local_dataflow.rb:50:3:50:13 | next |
|
||||
| local_dataflow.rb:51:3:51:15 | break |
|
||||
| local_dataflow.rb:52:3:52:10 | normal |
|
||||
| local_dataflow.rb:52:3:52:10 | "normal" |
|
||||
|
||||
@@ -41,7 +41,7 @@ def read_sized_xml(xml_file, name):
|
||||
def scale(xml, size, max_size):
|
||||
# Scale up the contents of all the <v> and <cardinality> tags
|
||||
for v in xml.xpath(".//v|.//cardinality"):
|
||||
v.text = str((int(v.text) * max_size) / size)
|
||||
v.text = str((int(v.text) * max_size) // size)
|
||||
|
||||
def do_xml_files(output, scaled_xml_files, unscaled_xml_files, name):
|
||||
# The result starts off empty
|
||||
@@ -55,7 +55,7 @@ def do_xml_files(output, scaled_xml_files, unscaled_xml_files, name):
|
||||
max_size = max([size for (xml, size) in sized_xmls])
|
||||
for (xml, size) in sized_xmls:
|
||||
scale(xml, size, max_size)
|
||||
unsized_xmls = map(etree.parse, unscaled_xml_files)
|
||||
unsized_xmls = list(map(etree.parse, unscaled_xml_files))
|
||||
xmls = [xml for (xml, size) in sized_xmls] + unsized_xmls
|
||||
|
||||
# Put all the stats in a single XML doc so that we can search them
|
||||
@@ -66,22 +66,22 @@ def do_xml_files(output, scaled_xml_files, unscaled_xml_files, name):
|
||||
|
||||
# For each value of <e><k>, take the <e> tag with the biggest <e><v>
|
||||
typesizes = etree.SubElement(result, "typesizes")
|
||||
typenames = set ([ typesize.find("k").text for typesize in merged_xml.xpath("dbstats/typesizes/e")])
|
||||
typenames = sorted(set ([ typesize.find("k").text for typesize in merged_xml.xpath("dbstats/typesizes/e")]))
|
||||
for typename in typenames:
|
||||
xs = merged_xml.xpath("dbstats/typesizes/e[k='" + typename + "']")
|
||||
sized_xs = [(int(x.find("v").text), x) for x in xs]
|
||||
(_, x) = max(sized_xs)
|
||||
(_, x) = max(sized_xs, key = lambda p: p[0])
|
||||
typesizes.append(x)
|
||||
|
||||
# For each value of <relation><name>, take the <relation> tag with
|
||||
# the biggest <relation><cardinality>
|
||||
stats = etree.SubElement(result, "stats")
|
||||
|
||||
relnames = set ([relation.find("name").text for relation in merged_xml.xpath("dbstats/stats/relation") ])
|
||||
relnames = sorted(set ([relation.find("name").text for relation in merged_xml.xpath("dbstats/stats/relation") ]))
|
||||
for relname in relnames:
|
||||
rels = merged_xml.xpath("dbstats/stats/relation[name='" + relname + "']")
|
||||
sized_rels = [(int(rel.find("cardinality").text), rel) for rel in rels]
|
||||
(_, rel) = max(sized_rels)
|
||||
(_, rel) = max(sized_rels, key = lambda p: p[0])
|
||||
stats.append(rel)
|
||||
|
||||
with open(output, 'wb') as f:
|
||||
|
||||
1490
upgrades/880faf3235fbdf1d00fc448d42f591abcd1a62cb/old.dbscheme
Normal file
1490
upgrades/880faf3235fbdf1d00fc448d42f591abcd1a62cb/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
class Range extends @range {
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
class Child extends @underscore_arg {
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
from Range range, Child begin
|
||||
where range_child(range, 0, begin)
|
||||
select range, begin
|
||||
@@ -0,0 +1,17 @@
|
||||
class Range extends @range {
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
class Parent extends @ast_node_parent {
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
class Location extends @location {
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
from Range range, Parent parent, int parentIndex, int operatorKind, Location loc
|
||||
where
|
||||
range_def(range, parent, parentIndex, loc) and
|
||||
operatorKind = 0 // best we can do is assume it was .. and not ...
|
||||
select range, parent, parentIndex, operatorKind, loc
|
||||
@@ -0,0 +1,11 @@
|
||||
class Range extends @range {
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
class Child extends @underscore_arg {
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
from Range range, Child end
|
||||
where range_child(range, 1, end)
|
||||
select range, end
|
||||
1500
upgrades/880faf3235fbdf1d00fc448d42f591abcd1a62cb/ruby.dbscheme
Normal file
1500
upgrades/880faf3235fbdf1d00fc448d42f591abcd1a62cb/ruby.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
description: split range_child table into range_begin and range_end
|
||||
compatibility: partial
|
||||
range_begin.rel: run range_begin.qlo
|
||||
range_end.rel: run range_end.qlo
|
||||
range_def.rel: run range_def.qlo
|
||||
range_child.rel: delete
|
||||
Reference in New Issue
Block a user