AST: HereDoc

This commit is contained in:
Arthur Baars
2021-02-16 14:14:12 +01:00
parent 1e19904342
commit 167574d82f
6 changed files with 166 additions and 17 deletions

View File

@@ -143,7 +143,7 @@ class StringComponent extends AstNode {
* "foo#{ bar() } baz"
* ```
*/
class StringTextComponent extends StringComponent, @token_string_content {
class StringTextComponent extends StringComponent, StringTextComponent::StringContentToken {
final override StringTextComponent::Range range;
final override string getAPrimaryQlClass() { result = "StringTextComponent" }
@@ -304,6 +304,50 @@ class CharacterLiteral extends Literal, @token_character {
final override string getAPrimaryQlClass() { result = "CharacterLiteral" }
}
/**
* A "here document". For example:
* ```rb
* query = <<SQL
* SELECT * FROM person
* WHERE age > 21
* ```
*/
class HereDoc extends StringlikeLiteral {
final override HereDoc::Range range;
final override string getAPrimaryQlClass() { result = "HereDoc" }
/**
* Holds if this here document is executed in a subshell.
* ```rb
* <<`COMMAND`
* echo "Hello world!"
* COMMAND
* ```
*/
final predicate isSubShell() { getQuoteStyle() = "`" }
/**
* Gets the quotation mark (`"`, `'` or `` ` ``) that surrounds the here document identifier, if any.
* ```rb
* <<"IDENTIFIER"
* <<'IDENTIFIER'
* <<`IDENTIFIER`
* ```
*/
final string getQuoteStyle() { result = range.getQuoteStyle() }
/**
* Gets the indentation modifier (`-` or `~`) of the here document identifier, if any.
* ```rb
* <<~IDENTIFIER
* <<-IDENTIFIER
* <<IDENTIFIER
* ```
*/
final string getIndentationModifier() { result = range.getIndentationModifier() }
}
/**
* An array literal.
*

View File

@@ -30,12 +30,6 @@ module AstNode {
this instanceof Generated::RestAssignment
or
this instanceof Generated::Superclass
or
this instanceof Generated::HeredocBody
or
this instanceof Generated::HeredocBeginning
or
this instanceof Generated::HeredocEnd
}
override string toString() { result = "AstNode" }

View File

@@ -94,8 +94,10 @@ module StringComponent {
}
module StringTextComponent {
class Range extends StringComponent::Range, @token_string_content {
final override Generated::StringContent generated;
class StringContentToken = @token_string_content or @token_heredoc_content;
class Range extends StringComponent::Range, StringContentToken {
final override Generated::Token generated;
final override string toString() { result = generated.getValue() }
@@ -287,6 +289,52 @@ module CharacterLiteral {
}
}
module HereDoc {
private Generated::HeredocBody heredoc(Generated::HeredocBeginning start) {
exists(int i, File f |
start =
rank[i](Generated::HeredocBeginning b |
f = b.getLocation().getFile()
|
b order by b.getLocation().getStartLine(), b.getLocation().getStartColumn()
) and
result =
rank[i](Generated::HeredocBody b |
f = b.getLocation().getFile()
|
b order by b.getLocation().getStartLine(), b.getLocation().getStartColumn()
)
)
}
class Range extends StringlikeLiteral::Range, @token_heredoc_beginning {
final override Generated::HeredocBeginning generated;
private Generated::HeredocBody body;
Range() { body = heredoc(this) }
final override StringComponent::Range getComponent(int n) { result = body.getChild(n) }
final string getQuoteStyle() {
exists(string s |
s = generated.getValue() and
s.charAt(s.length() - 1) = result and
result = ["'", "`", "\""]
)
}
final string getIndentationModifier() {
exists(string s |
s = generated.getValue() and
s.charAt(2) = result and
result = ["-", "~"]
)
}
final override string toString() { result = generated.getValue() }
}
}
module ArrayLiteral {
abstract class Range extends Literal::Range {
final override string getValueText() { none() }