mirror of
https://github.com/github/codeql.git
synced 2026-04-27 09:45:15 +02:00
Merge pull request #1362 from calumgrant/cs/cs8/testing
C#: Various small C#8 features
This commit is contained in:
@@ -12,10 +12,12 @@
|
||||
* The following C# 8 features are now extracted:
|
||||
- Range expressions
|
||||
- Recursive patterns
|
||||
* The `unmanaged` type parameter constraint is now extracted.
|
||||
|
||||
## Changes to QL libraries
|
||||
|
||||
* The class `Attribute` has two new predicates: `getConstructorArgument()` and `getNamedArgument()`. The first predicate returns arguments to the underlying constructor call and the latter returns named arguments for initializing fields and properties.
|
||||
* The class `TypeParameterConstraints` has a new predicate `hasUnmanagedTypeConstraint()`, indicating that the type parameter has the `unmanaged` constraint.
|
||||
* The following QL classes have been added to model C# 8 features:
|
||||
- Class `IndexExpr` models from-end index expressions, for example `^1`
|
||||
- Class `PatternExpr` is an `Expr` that appears in a pattern. It has the new subclasses `DiscardPatternExpr`, `LabeledPatternExpr`, `RecursivePatternExpr`, `TypeAccessPatternExpr`, `TypePatternExpr`, and `VariablePatternExpr`.
|
||||
|
||||
@@ -34,6 +34,9 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
if (symbol.HasConstructorConstraint)
|
||||
Context.Emit(Tuples.general_type_parameter_constraints(constraints, 3));
|
||||
|
||||
if(symbol.HasUnmanagedTypeConstraint)
|
||||
Context.Emit(Tuples.general_type_parameter_constraints(constraints, 4));
|
||||
|
||||
ITypeSymbol baseType = symbol.HasValueTypeConstraint ?
|
||||
Context.Compilation.GetTypeByMetadataName(valueTypeName) :
|
||||
Context.Compilation.ObjectType;
|
||||
|
||||
@@ -223,6 +223,9 @@ class TypeParameterConstraints extends Element, @type_parameter_constraints {
|
||||
/** Holds if these constraints include a general value type constraint. */
|
||||
predicate hasValueTypeConstraint() { general_type_parameter_constraints(this, 2) }
|
||||
|
||||
/** Holds if these constraints include an unmanaged type constraint. */
|
||||
predicate hasUnmanagedTypeConstraint() { general_type_parameter_constraints(this, 4) }
|
||||
|
||||
/** Gets a textual representation of these constraints. */
|
||||
override string toString() { result = "where " + this.getTypeParameter().toString() + ": ..." }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
using System;
|
||||
|
||||
class AlternateInterpolatedStrings
|
||||
{
|
||||
string s1 = $@"C:{12}";
|
||||
string s2 = @$"C:{12}";
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
inserts
|
||||
| AlternateInterpolatedStrings.cs:5:17:5:26 | $"..." | 1 | AlternateInterpolatedStrings.cs:5:23:5:24 | 12 |
|
||||
| AlternateInterpolatedStrings.cs:6:17:6:26 | $"..." | 1 | AlternateInterpolatedStrings.cs:6:23:6:24 | 12 |
|
||||
text
|
||||
| AlternateInterpolatedStrings.cs:5:17:5:26 | $"..." | 0 | AlternateInterpolatedStrings.cs:5:20:5:21 | "C:" |
|
||||
| AlternateInterpolatedStrings.cs:6:17:6:26 | $"..." | 0 | AlternateInterpolatedStrings.cs:6:20:6:21 | "C:" |
|
||||
@@ -0,0 +1,9 @@
|
||||
import csharp
|
||||
|
||||
query predicate inserts(InterpolatedStringExpr expr, int i, Expr insert) {
|
||||
insert = expr.getInsert(i)
|
||||
}
|
||||
|
||||
query predicate text(InterpolatedStringExpr expr, int i, StringLiteral literal) {
|
||||
literal = expr.getText(i)
|
||||
}
|
||||
44
csharp/ql/test/library-tests/csharp8/AsyncStreams.cs
Normal file
44
csharp/ql/test/library-tests/csharp8/AsyncStreams.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
// semmle-extractor-options: /r:System.Threading.Tasks.dll /r:System.Threading.Tasks.Extensions.dll /r:netstandard.dll /langversion:preview
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
class AsyncStreams
|
||||
{
|
||||
async IAsyncEnumerable<int> Items() {
|
||||
yield return 1;
|
||||
yield return 2;
|
||||
await Task.Delay(1000);
|
||||
yield return 3;
|
||||
}
|
||||
|
||||
async void F()
|
||||
{
|
||||
await foreach(var item in Items())
|
||||
Console.WriteLine(item);
|
||||
}
|
||||
}
|
||||
|
||||
namespace System
|
||||
{
|
||||
interface IAsyncDisposable
|
||||
{
|
||||
System.Threading.Tasks.ValueTask DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
namespace System.Collections.Generic
|
||||
{
|
||||
interface IAsyncEnumerable<out T>
|
||||
{
|
||||
public System.Collections.Generic.IAsyncEnumerator<T> GetAsyncEnumerator (System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
|
||||
}
|
||||
|
||||
interface IAsyncEnumerator<out T> : IAsyncDisposable
|
||||
{
|
||||
T Current { get; }
|
||||
System.Threading.Tasks.ValueTask<bool> MoveNextAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import csharp
|
||||
|
||||
class DefaultInterfaceMethod extends Method {
|
||||
DefaultInterfaceMethod() {
|
||||
this.hasBody() and
|
||||
this.getDeclaringType() instanceof Interface
|
||||
}
|
||||
}
|
||||
|
||||
query predicate defaultInterfaceMethods(DefaultInterfaceMethod m) { any() }
|
||||
10
csharp/ql/test/library-tests/csharp8/StaticLocalFunction.cs
Normal file
10
csharp/ql/test/library-tests/csharp8/StaticLocalFunction.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
class StaticLocalFunction
|
||||
{
|
||||
int F()
|
||||
{
|
||||
static int G(int x) => x;
|
||||
return G(12);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
|
||||
struct S<T, U> where T: unmanaged
|
||||
{
|
||||
int id;
|
||||
T value1;
|
||||
U value2;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
| UnmanagedGenericStructs.cs:3:10:3:10 | T | This type parameter is unmanaged. |
|
||||
@@ -0,0 +1,5 @@
|
||||
import csharp
|
||||
|
||||
from TypeParameter tp
|
||||
where tp.getConstraints().hasUnmanagedTypeConstraint()
|
||||
select tp, "This type parameter is unmanaged."
|
||||
Reference in New Issue
Block a user