Merge pull request #3792 from calumgrant/cs/qldoc-coverage1

C#: Improve qldoc coverage
This commit is contained in:
Calum Grant
2020-06-25 16:34:52 +01:00
committed by GitHub
5 changed files with 257 additions and 33 deletions

View File

@@ -1,7 +1,8 @@
// Various utilities for writing concurrency queries.
/** Classes for concurrency queries. */
import csharp
class WaitCall extends MethodCall {
private class WaitCall extends MethodCall {
WaitCall() {
getTarget().hasName("Wait") and
getTarget().getDeclaringType().hasQualifiedName("System.Threading.Monitor")
@@ -10,22 +11,24 @@ class WaitCall extends MethodCall {
Expr getExpr() { result = getArgument(0) }
}
/** An expression statement containing a `Wait` call. */
class WaitStmt extends ExprStmt {
WaitStmt() { getExpr() instanceof WaitCall }
/** Gets the expression that this wait call is waiting on. */
Expr getLock() { result = getExpr().(WaitCall).getExpr() }
// If we are waiting on a variable
/** Gets the variable that this wait call is waiting on, if any. */
Variable getWaitVariable() { result.getAnAccess() = getLock() }
// If we are waiting on 'this'
/** Holds if this wait call waits on `this`. */
predicate isWaitThis() { getLock() instanceof ThisAccess }
// If we are waiting on a typeof()
/** Gets the type that this wait call waits on, if any. */
Type getWaitTypeObject() { result = getLock().(TypeofExpr).getTypeAccess().getTarget() }
}
class SynchronizedMethodAttribute extends Attribute {
private class SynchronizedMethodAttribute extends Attribute {
SynchronizedMethodAttribute() {
getType().hasQualifiedName("System.Runtime.CompilerServices.MethodImplAttribute") and
exists(MemberConstantAccess a, MemberConstant mc |
@@ -37,22 +40,29 @@ class SynchronizedMethodAttribute extends Attribute {
}
}
// A method with attribute [MethodImpl(MethodImplOptions.Synchronized)]
class SynchronizedMethod extends Method {
/** A method with attribute `[MethodImpl(MethodImplOptions.Synchronized)]`. */
private class SynchronizedMethod extends Method {
SynchronizedMethod() { getAnAttribute() instanceof SynchronizedMethodAttribute }
/** Holds if this method locks `this`. */
predicate isLockThis() { not isStatic() }
/** Gets the type that is locked by this method, if any. */
Type getLockTypeObject() { isStatic() and result = getDeclaringType() }
}
/** A block that is locked by a `lock` statement. */
abstract class LockedBlock extends BlockStmt {
/** Holds if the `lock` statement locks `this`. */
abstract predicate isLockThis();
/** Gets the lock variable of the `lock` statement, if any. */
abstract Variable getLockVariable();
/** Gets the locked type of the `lock` statement, if any. */
abstract Type getLockTypeObject();
/** Gets a statement in the scope of this locked block. */
Stmt getALockedStmt() {
// Do this instead of getParent+, because we don't want to escape
// delegates and lambdas
@@ -62,7 +72,7 @@ abstract class LockedBlock extends BlockStmt {
}
}
class LockStmtBlock extends LockedBlock {
private class LockStmtBlock extends LockedBlock {
LockStmtBlock() { exists(LockStmt s | this = s.getBlock()) }
override predicate isLockThis() { exists(LockStmt s | this = s.getBlock() and s.isLockThis()) }
@@ -76,9 +86,7 @@ class LockStmtBlock extends LockedBlock {
}
}
/**
* A call which may take a lock using one of the standard library classes.
*/
/** A call that may take a lock using one of the standard library methods. */
class LockingCall extends MethodCall {
LockingCall() {
this.getTarget() =
@@ -91,7 +99,7 @@ class LockingCall extends MethodCall {
}
}
class SynchronizedMethodBlock extends LockedBlock {
private class SynchronizedMethodBlock extends LockedBlock {
SynchronizedMethodBlock() { exists(SynchronizedMethod m | this = m.getStatementBody()) }
override predicate isLockThis() {

View File

@@ -1,6 +1,8 @@
/** Classes representing documentation comments. */
import csharp
class SourceDeclaration extends Declaration {
private class SourceDeclaration extends Declaration {
SourceDeclaration() { this.isSourceDeclaration() }
}
@@ -59,10 +61,13 @@ predicate isDocumentationNeeded(Modifiable decl) {
class ReturnsXmlComment extends XmlComment {
ReturnsXmlComment() { getOpenTag(_) = "returns" }
/** Holds if the element in this comment has a body at offset `offset`. */
predicate hasBody(int offset) { hasBody("returns", offset) }
/** Holds if the element in this comment is an opening tag at offset `offset`. */
predicate isOpenTag(int offset) { "returns" = getOpenTag(offset) }
/** Holds if the element in this comment is an empty tag at offset `offset`. */
predicate isEmptyTag(int offset) { "returns" = getEmptyTag(offset) }
}
@@ -70,8 +75,10 @@ class ReturnsXmlComment extends XmlComment {
class ExceptionXmlComment extends XmlComment {
ExceptionXmlComment() { getOpenTag(_) = "exception" }
/** Gets a `cref` attribute at offset `offset`, if any. */
string getCref(int offset) { result = getAttribute("exception", "cref", offset) }
/** Holds if the element in this comment has a body at offset `offset`. */
predicate hasBody(int offset) { hasBody("exception", offset) }
}
@@ -79,8 +86,10 @@ class ExceptionXmlComment extends XmlComment {
class ParamXmlComment extends XmlComment {
ParamXmlComment() { getOpenTag(_) = "param" }
/** Gets the name of this parameter at offset `offset`. */
string getName(int offset) { getAttribute("param", "name", offset) = result }
/** Holds if the element in this comment has a body at offset `offset`. */
predicate hasBody(int offset) { hasBody("param", offset) }
}
@@ -88,8 +97,10 @@ class ParamXmlComment extends XmlComment {
class TypeparamXmlComment extends XmlComment {
TypeparamXmlComment() { getOpenTag(_) = "typeparam" }
/** Gets the `name` attribute of this element at offset `offset`. */
string getName(int offset) { getAttribute("typeparam", "name", offset) = result }
/** Holds if the element in this comment has a body at offset `offset`. */
predicate hasBody(int offset) { hasBody("typeparam", offset) }
}
@@ -97,10 +108,13 @@ class TypeparamXmlComment extends XmlComment {
class SummaryXmlComment extends XmlComment {
SummaryXmlComment() { getOpenTag(_) = "summary" }
/** Holds if the element in this comment has a body at offset `offset`. */
predicate hasBody(int offset) { hasBody("summary", offset) }
/** Holds if the element in this comment has an open tag at offset `offset`. */
predicate isOpenTag(int offset) { "summary" = getOpenTag(offset) }
/** Holds if the element in this comment is empty at offset `offset`. */
predicate isEmptyTag(int offset) { "summary" = getEmptyTag(offset) }
}

View File

@@ -1 +1,5 @@
/**
* The default QL library for modeling the Common Intermediate Language (CIL).
*/
import semmle.code.cil.CIL as CIL

View File

@@ -1 +1,5 @@
/**
* The default QL library for modeling .NET definitions for both C# and CIL code.
*/
import semmle.code.dotnet.DotNet as DotNet

File diff suppressed because it is too large Load Diff