Merge pull request #11177 from github/redsun82/swift-decls

Swift: extract `PoundDiagnosticDecl` and `MissingMemberDecl`
This commit is contained in:
Paolo Tranquilli
2022-11-09 14:54:57 +01:00
committed by GitHub
17 changed files with 134 additions and 31 deletions

View File

@@ -1,4 +1,5 @@
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
private import codeql.swift.generated.decl.MissingMemberDecl
class MissingMemberDecl extends Generated::MissingMemberDecl { }
class MissingMemberDecl extends Generated::MissingMemberDecl {
override string toString() { result = this.getName() + " (missing)" }
}

View File

@@ -2,6 +2,12 @@ private import codeql.swift.generated.decl.PoundDiagnosticDecl
class PoundDiagnosticDecl extends Generated::PoundDiagnosticDecl {
override string toString() {
result = "#..." // TODO: Once we extract whether this is an error or a warning we can improve this.
this.isError() and result = "#error(...)"
or
this.isWarning() and result = "#warning(...)"
}
predicate isError() { this.getKind() = 1 }
predicate isWarning() { this.getKind() = 2 }
}

View File

@@ -373,14 +373,17 @@ private module Impl {
private Element getImmediateChildOfPoundDiagnosticDecl(
PoundDiagnosticDecl e, int index, string partialPredicateCall
) {
exists(int b, int bDecl, int n |
exists(int b, int bDecl, int n, int nMessage |
b = 0 and
bDecl = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfDecl(e, i, _)) | i) and
n = bDecl and
nMessage = n + 1 and
(
none()
or
result = getImmediateChildOfDecl(e, index - b, partialPredicateCall)
or
index = n and result = e.getImmediateMessage() and partialPredicateCall = "Message()"
)
)
}

View File

@@ -115,6 +115,8 @@ module Raw {
class MissingMemberDecl extends @missing_member_decl, Decl {
override string toString() { result = "MissingMemberDecl" }
string getName() { missing_member_decls(this, result) }
}
class OperatorDecl extends @operator_decl, Decl {
@@ -131,6 +133,10 @@ module Raw {
class PoundDiagnosticDecl extends @pound_diagnostic_decl, Decl {
override string toString() { result = "PoundDiagnosticDecl" }
int getKind() { pound_diagnostic_decls(this, result, _) }
StringLiteralExpr getMessage() { pound_diagnostic_decls(this, _, result) }
}
class PrecedenceGroupDecl extends @precedence_group_decl, Decl {

View File

@@ -4,7 +4,17 @@ private import codeql.swift.generated.Raw
import codeql.swift.elements.decl.Decl
module Generated {
/**
* A placeholder for missing declarations that can arise on object deserialization.
*/
class MissingMemberDecl extends Synth::TMissingMemberDecl, Decl {
override string getAPrimaryQlClass() { result = "MissingMemberDecl" }
/**
* Gets the name of this missing member declaration.
*/
string getName() {
result = Synth::convertMissingMemberDeclToRaw(this).(Raw::MissingMemberDecl).getName()
}
}
}

View File

@@ -2,9 +2,38 @@
private import codeql.swift.generated.Synth
private import codeql.swift.generated.Raw
import codeql.swift.elements.decl.Decl
import codeql.swift.elements.expr.StringLiteralExpr
module Generated {
/**
* A diagnostic directive, which is either `#error` or `#warning`.
*/
class PoundDiagnosticDecl extends Synth::TPoundDiagnosticDecl, Decl {
override string getAPrimaryQlClass() { result = "PoundDiagnosticDecl" }
/**
* Gets the This is 1 for `#error` and 2 for `#warning`.
*/
int getKind() {
result = Synth::convertPoundDiagnosticDeclToRaw(this).(Raw::PoundDiagnosticDecl).getKind()
}
/**
* Gets the message of this pound diagnostic declaration.
*
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
* behavior of both the `Immediate` and non-`Immediate` versions.
*/
StringLiteralExpr getImmediateMessage() {
result =
Synth::convertStringLiteralExprFromRaw(Synth::convertPoundDiagnosticDeclToRaw(this)
.(Raw::PoundDiagnosticDecl)
.getMessage())
}
/**
* Gets the message of this pound diagnostic declaration.
*/
final StringLiteralExpr getMessage() { result = getImmediateMessage().resolve() }
}
}

View File

@@ -254,7 +254,8 @@ import_decl_declarations( //dir=decl
);
missing_member_decls( //dir=decl
unique int id: @missing_member_decl
unique int id: @missing_member_decl,
string name: string ref
);
@operator_decl =
@@ -288,7 +289,9 @@ pattern_binding_decl_patterns( //dir=decl
);
pound_diagnostic_decls( //dir=decl
unique int id: @pound_diagnostic_decl
unique int id: @pound_diagnostic_decl,
int kind: int ref,
int message: @string_literal_expr_or_none ref
);
precedence_group_decls( //dir=decl
@@ -2450,6 +2453,11 @@ variadic_sequence_types( //dir=type
| @unspecified_element
;
@string_literal_expr_or_none =
@string_literal_expr
| @unspecified_element
;
@tap_expr_or_none =
@tap_expr
| @unspecified_element

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
After a swift source file is added in this directory and codegen/codegen.py is run again, test queries
will appear and this file will be deleted

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
After a swift source file is added in this directory and codegen/codegen.py is run again, test queries
will appear and this file will be deleted

View File

@@ -0,0 +1,2 @@
| diagnostics.swift:2:1:2:25 | #warning(...) | getModule: | file://:0:0:0:0 | diagnostics | getKind: | 2 | getMessage: | diagnostics.swift:2:10:2:10 | I'm a warning |
| diagnostics.swift:3:1:3:26 | #error(...) | getModule: | file://:0:0:0:0 | diagnostics | getKind: | 1 | getMessage: | diagnostics.swift:3:8:3:8 | And I'm an error |

View File

@@ -0,0 +1,12 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from PoundDiagnosticDecl x, ModuleDecl getModule, int getKind, StringLiteralExpr getMessage
where
toBeTested(x) and
not x.isUnknown() and
getModule = x.getModule() and
getKind = x.getKind() and
getMessage = x.getMessage()
select x, "getModule:", getModule, "getKind:", getKind, "getMessage:", getMessage

View File

@@ -0,0 +1,3 @@
//codeql-extractor-expected-status: 1
#warning("I'm a warning")
#error("And I'm an error")