Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,18 @@ public static AnnotatedTypeSymbol GetType(this Context cx, Microsoft.CodeAnalysi
return new AnnotatedTypeSymbol(info.Type.DisambiguateType(), info.Nullability.Annotation);
}

/// <summary>
/// Gets the converted type of a syntax node, or default if it could not be determined.
/// </summary>
/// <param name="cx">Extractor context.</param>
/// <param name="node">The syntax node to determine the converted type for.</param>
/// <returns>The converted type symbol of the node, or default.</returns>
public static AnnotatedTypeSymbol GetConvertedType(this Context cx, Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode node)
{
var info = GetTypeInfo(cx, node);
return new AnnotatedTypeSymbol(info.ConvertedType.DisambiguateType(), info.ConvertedNullability.Annotation);
}

/// <summary>
/// Gets the annotated type arguments of an INamedTypeSymbol.
/// This has not yet been exposed on the public API.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class BinaryPattern : Expression
{
public BinaryPattern(Context cx, BinaryPatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), GetKind(syntax.OperatorToken, syntax), parent, child, isCompilerGenerated: false, null))
base(new ExpressionInfo(cx, cx.GetConvertedType(syntax), cx.CreateLocation(syntax.GetLocation()), GetKind(syntax.OperatorToken, syntax), parent, child, isCompilerGenerated: false, null))
{
Pattern.Create(cx, syntax.Left, this, 0);
Pattern.Create(cx, syntax.Right, this, 1);
Expand All @@ -24,4 +24,4 @@ private static ExprKind GetKind(SyntaxToken operatorToken, BinaryPatternSyntax s
};
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class ListPattern : Expression
{
internal ListPattern(Context cx, ListPatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.LIST_PATTERN, parent, child, isCompilerGenerated: false, null))
base(new ExpressionInfo(cx, cx.GetConvertedType(syntax), cx.CreateLocation(syntax.GetLocation()), ExprKind.LIST_PATTERN, parent, child, isCompilerGenerated: false, null))
{
syntax.Patterns.ForEach((p, i) => Pattern.Create(cx, p, this, i));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal class RecursivePattern : Expression
/// <param name="parent">The parent pattern/expression.</param>
/// <param name="child">The child index of this pattern.</param>
public RecursivePattern(Context cx, RecursivePatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, isCompilerGenerated: false, null))
base(new ExpressionInfo(cx, cx.GetConvertedType(syntax), cx.CreateLocation(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, isCompilerGenerated: false, null))
{
// Extract the type access
if (syntax.Type is TypeSyntax t)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class RelationalPattern : Expression
{
public RelationalPattern(Context cx, RelationalPatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), GetKind(syntax.OperatorToken), parent, child, isCompilerGenerated: false, null))
base(new ExpressionInfo(cx, cx.GetConvertedType(syntax), cx.CreateLocation(syntax.GetLocation()), GetKind(syntax.OperatorToken), parent, child, isCompilerGenerated: false, null))
{
Expression.Create(cx, syntax.Expression, this, 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class SlicePattern : Expression
{
public SlicePattern(Context cx, SlicePatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.SLICE_PATTERN, parent, child, isCompilerGenerated: false, null))
base(new ExpressionInfo(cx, cx.GetConvertedType(syntax), cx.CreateLocation(syntax.GetLocation()), ExprKind.SLICE_PATTERN, parent, child, isCompilerGenerated: false, null))
{
if (syntax.Pattern is not null)
{
Pattern.Create(cx, syntax.Pattern, this, 0);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
internal class UnaryPattern : Expression
{
public UnaryPattern(Context cx, UnaryPatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.NOT_PATTERN, parent, child, isCompilerGenerated: false, null))
base(new ExpressionInfo(cx, cx.GetConvertedType(syntax), cx.CreateLocation(syntax.GetLocation()), ExprKind.NOT_PATTERN, parent, child, isCompilerGenerated: false, null))
{
Pattern.Create(cx, syntax.Pattern, this, 0);
}
}
}
}
58 changes: 58 additions & 0 deletions csharp/ql/test/library-tests/csharp11/patternExprTypes.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
| ListPattern.cs:7:18:7:19 | [ ... ] | Int32[] |
| ListPattern.cs:8:18:8:20 | [ ... ] | Int32[] |
| ListPattern.cs:8:19:8:19 | 1 | Int32 |
| ListPattern.cs:9:18:9:23 | [ ... ] | Int32[] |
| ListPattern.cs:9:19:9:19 | _ | Int32 |
| ListPattern.cs:9:22:9:22 | 2 | Int32 |
| ListPattern.cs:10:18:10:30 | [ ... ] | Int32[] |
| ListPattern.cs:10:19:10:23 | Int32 y | Int32 |
| ListPattern.cs:10:26:10:26 | 3 | Int32 |
| ListPattern.cs:10:29:10:29 | 4 | Int32 |
| ListPattern.cs:11:18:11:31 | [ ... ] | Int32[] |
| ListPattern.cs:11:19:11:19 | 5 | Int32 |
| ListPattern.cs:11:19:11:24 | ... or ... | Int32 |
| ListPattern.cs:11:24:11:24 | 6 | Int32 |
| ListPattern.cs:11:27:11:27 | _ | Int32 |
| ListPattern.cs:11:30:11:30 | 7 | Int32 |
| ListPattern.cs:12:18:12:31 | [ ... ] | Int32[] |
| ListPattern.cs:12:19:12:23 | Int32 a | Int32 |
| ListPattern.cs:12:26:12:27 | .. | Int32[] |
| ListPattern.cs:12:30:12:30 | 2 | Int32 |
| ListPattern.cs:13:18:13:50 | [ ... ] | Int32[] |
| ListPattern.cs:13:19:13:23 | Int32 b | Int32 |
| ListPattern.cs:13:26:13:46 | .. | Int32[] |
| ListPattern.cs:13:29:13:46 | { ... } | Int32[] |
| ListPattern.cs:13:29:13:46 | { ... } | null |
| ListPattern.cs:13:39:13:39 | 2 | Int32 |
| ListPattern.cs:13:39:13:44 | ... or ... | Int32 |
| ListPattern.cs:13:44:13:44 | 5 | Int32 |
| ListPattern.cs:13:49:13:49 | 2 | Int32 |
| ListPattern.cs:20:18:20:19 | [ ... ] | String[] |
| ListPattern.cs:22:18:22:22 | [ ... ] | String[] |
| ListPattern.cs:22:19:22:21 | "A" | String |
| ListPattern.cs:24:18:24:25 | [ ... ] | String[] |
| ListPattern.cs:24:19:24:19 | _ | String |
| ListPattern.cs:24:22:24:24 | "B" | String |
| ListPattern.cs:26:18:26:34 | [ ... ] | String[] |
| ListPattern.cs:26:19:26:23 | String y | String |
| ListPattern.cs:26:26:26:28 | "C" | String |
| ListPattern.cs:26:31:26:33 | "D" | String |
| ListPattern.cs:28:18:28:37 | [ ... ] | String[] |
| ListPattern.cs:28:19:28:21 | "E" | String |
| ListPattern.cs:28:19:28:28 | ... or ... | String |
| ListPattern.cs:28:26:28:28 | "F" | String |
| ListPattern.cs:28:31:28:31 | _ | String |
| ListPattern.cs:28:34:28:36 | "G" | String |
| ListPattern.cs:30:18:30:33 | [ ... ] | String[] |
| ListPattern.cs:30:19:30:23 | String a | String |
| ListPattern.cs:30:26:30:27 | .. | String[] |
| ListPattern.cs:30:30:30:32 | "H" | String |
| ListPattern.cs:32:18:32:39 | [ ... ] | String[] |
| ListPattern.cs:32:19:32:23 | String b | String |
| ListPattern.cs:32:26:32:33 | .. | String[] |
| ListPattern.cs:32:29:32:33 | String[] c | String[] |
| ListPattern.cs:32:36:32:38 | "I" | String |
| PatternMatchSpan.cs:8:19:8:23 | "ABC" | String |
| PatternMatchSpan.cs:15:18:15:22 | "DEF" | String |
| Strings.cs:10:13:10:14 | 42 | Int32 |
| Strings.cs:11:13:11:13 | _ | Int32 |
4 changes: 4 additions & 0 deletions csharp/ql/test/library-tests/csharp11/patternExprTypes.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import csharp

from PatternExpr pattern
select pattern, pattern.getType().toString()
150 changes: 137 additions & 13 deletions csharp/ql/test/library-tests/csharp8/patterns.expected
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,140 @@ labeledPatternExpr
| patterns.cs:129:27:129:28 | 10 | X |
| patterns.cs:142:31:142:32 | 10 | X |
tupleTypes
| patterns.cs:59:18:59:27 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:86:15:86:19 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:91:16:91:20 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:108:9:108:20 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:108:24:108:31 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:110:22:110:26 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:111:22:111:26 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:115:9:115:16 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:115:20:115:27 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:117:27:117:33 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:118:28:118:34 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:119:33:119:38 | (..., ...) | file://:0:0:0:0 | (Int32,Int32) |
| patterns.cs:131:13:131:22 | (..., ...) | file://:0:0:0:0 | (Int32,Object) |
| patterns.cs:59:18:59:27 | (..., ...) | (Int32,Int32) |
| patterns.cs:86:15:86:19 | (..., ...) | (Int32,Int32) |
| patterns.cs:91:16:91:20 | (..., ...) | (Int32,Int32) |
| patterns.cs:108:9:108:20 | (..., ...) | (Int32,Int32) |
| patterns.cs:108:24:108:31 | (..., ...) | (Int32,Int32) |
| patterns.cs:110:22:110:26 | (..., ...) | (Int32,Int32) |
| patterns.cs:111:22:111:26 | (..., ...) | (Int32,Int32) |
| patterns.cs:115:9:115:16 | (..., ...) | (Int32,Int32) |
| patterns.cs:115:20:115:27 | (..., ...) | (Int32,Int32) |
| patterns.cs:117:27:117:33 | (..., ...) | (Int32,Int32) |
| patterns.cs:118:28:118:34 | (..., ...) | (Int32,Int32) |
| patterns.cs:119:33:119:38 | (..., ...) | (Int32,Int32) |
| patterns.cs:131:13:131:22 | (..., ...) | (Int32,Object) |
patternExprTypes
| patterns.cs:9:18:9:29 | MyStruct ms1 | MyStruct |
| patterns.cs:13:18:13:25 | access to type MyStruct | MyStruct |
| patterns.cs:13:18:13:40 | MyStruct s | MyStruct |
| patterns.cs:13:18:13:40 | { ... } | MyStruct |
| patterns.cs:13:27:13:38 | { ... } | null |
| patterns.cs:13:32:13:36 | Int32 x | Int32 |
| patterns.cs:17:18:17:19 | { ... } | null |
| patterns.cs:17:18:17:21 | Object p | Object |
| patterns.cs:17:18:17:21 | { ... } | Object |
| patterns.cs:22:18:22:25 | access to type MyStruct | MyStruct |
| patterns.cs:22:18:22:53 | { ... } | MyStruct |
| patterns.cs:22:27:22:53 | { ... } | null |
| patterns.cs:22:31:22:32 | 12 | Int32 |
| patterns.cs:22:38:22:51 | { ... } | MyStruct |
| patterns.cs:22:38:22:51 | { ... } | null |
| patterns.cs:22:42:22:49 | Int32 subX | Int32 |
| patterns.cs:27:18:27:25 | access to type MyStruct | MyStruct |
| patterns.cs:27:18:27:58 | { ... } | MyStruct |
| patterns.cs:27:27:27:58 | { ... } | null |
| patterns.cs:27:31:27:32 | 12 | Int32 |
| patterns.cs:27:38:27:45 | access to type MyStruct | MyStruct |
| patterns.cs:27:38:27:56 | MyStruct ms | MyStruct |
| patterns.cs:27:38:27:56 | { ... } | MyStruct |
| patterns.cs:27:47:27:53 | { ... } | null |
| patterns.cs:27:51:27:51 | _ | Int32 |
| patterns.cs:38:18:38:29 | MyStruct ms1 | MyStruct |
| patterns.cs:41:18:41:29 | MyStruct ms2 | MyStruct |
| patterns.cs:48:18:48:25 | access to type MyStruct | MyStruct |
| patterns.cs:48:18:48:38 | { ... } | MyStruct |
| patterns.cs:48:27:48:38 | { ... } | null |
| patterns.cs:48:32:48:36 | Int32 x | Int32 |
| patterns.cs:51:18:51:25 | access to type MyStruct | MyStruct |
| patterns.cs:51:18:51:38 | MyStruct ms | MyStruct |
| patterns.cs:51:18:51:38 | { ... } | MyStruct |
| patterns.cs:51:27:51:35 | { ... } | null |
| patterns.cs:51:32:51:33 | 10 | Int32 |
| patterns.cs:54:18:54:30 | { ... } | MyStruct |
| patterns.cs:54:18:54:30 | { ... } | null |
| patterns.cs:54:23:54:28 | Int32 x2 | Int32 |
| patterns.cs:57:18:57:23 | ( ... ) | null |
| patterns.cs:57:18:57:23 | { ... } | MyStruct |
| patterns.cs:57:19:57:19 | 1 | Int32 |
| patterns.cs:57:22:57:22 | 2 | Int32 |
| patterns.cs:59:18:59:27 | (..., ...) | (Int32,Int32) |
| patterns.cs:59:23:59:23 | Int32 x | Int32 |
| patterns.cs:59:26:59:26 | Int32 y | Int32 |
| patterns.cs:67:18:67:25 | access to type MyStruct | MyStruct |
| patterns.cs:67:18:67:38 | { ... } | MyStruct |
| patterns.cs:67:27:67:38 | { ... } | null |
| patterns.cs:67:32:67:36 | Int32 x | Int32 |
| patterns.cs:70:18:70:25 | access to type MyStruct | MyStruct |
| patterns.cs:70:18:70:38 | MyStruct ms | MyStruct |
| patterns.cs:70:18:70:38 | { ... } | MyStruct |
| patterns.cs:70:27:70:35 | { ... } | null |
| patterns.cs:70:32:70:33 | 10 | Int32 |
| patterns.cs:78:18:78:33 | ( ... ) | null |
| patterns.cs:78:18:78:33 | { ... } | ITuple |
| patterns.cs:78:19:78:23 | Int32 x | Int32 |
| patterns.cs:78:26:78:32 | Single y | Single |
| patterns.cs:80:18:80:19 | ( ... ) | null |
| patterns.cs:80:18:80:19 | { ... } | ITuple |
| patterns.cs:82:18:82:19 | { ... } | Object |
| patterns.cs:82:18:82:19 | { ... } | null |
| patterns.cs:88:18:88:23 | ( ... ) | null |
| patterns.cs:88:18:88:23 | { ... } | (Int32,Int32) |
| patterns.cs:88:19:88:19 | 1 | Int32 |
| patterns.cs:88:22:88:22 | 2 | Int32 |
| patterns.cs:93:18:93:27 | ( ... ) | null |
| patterns.cs:93:18:93:27 | { ... } | (Int32,Int32) |
| patterns.cs:93:19:93:19 | 1 | Int32 |
| patterns.cs:93:22:93:26 | Int32 x | Int32 |
| patterns.cs:94:18:94:23 | ( ... ) | null |
| patterns.cs:94:18:94:23 | { ... } | (Int32,Int32) |
| patterns.cs:94:19:94:19 | 2 | Int32 |
| patterns.cs:94:22:94:22 | _ | Int32 |
| patterns.cs:101:13:101:17 | Int32 y | Int32 |
| patterns.cs:102:13:102:13 | _ | Int32 |
| patterns.cs:110:13:110:17 | ( ... ) | null |
| patterns.cs:110:13:110:17 | { ... } | (Int32,Int32) |
| patterns.cs:110:14:110:14 | 0 | Int32 |
| patterns.cs:110:16:110:16 | 1 | Int32 |
| patterns.cs:111:13:111:17 | ( ... ) | null |
| patterns.cs:111:13:111:17 | { ... } | (Int32,Int32) |
| patterns.cs:111:14:111:14 | 1 | Int32 |
| patterns.cs:111:16:111:16 | 0 | Int32 |
| patterns.cs:117:13:117:22 | ( ... ) | null |
| patterns.cs:117:13:117:22 | { ... } | (Int32,Int32) |
| patterns.cs:117:14:117:14 | 0 | Int32 |
| patterns.cs:117:16:117:21 | Int32 y2 | Int32 |
| patterns.cs:118:13:118:23 | ( ... ) | null |
| patterns.cs:118:13:118:23 | { ... } | (Int32,Int32) |
| patterns.cs:118:14:118:19 | Int32 x2 | Int32 |
| patterns.cs:118:22:118:22 | 0 | Int32 |
| patterns.cs:119:13:119:28 | ( ... ) | null |
| patterns.cs:119:13:119:28 | { ... } | (Int32,Int32) |
| patterns.cs:119:14:119:19 | Int32 x2 | Int32 |
| patterns.cs:119:22:119:27 | Int32 y2 | Int32 |
| patterns.cs:128:13:128:20 | access to type MyStruct | MyStruct |
| patterns.cs:128:13:128:33 | { ... } | MyStruct |
| patterns.cs:128:22:128:33 | { ... } | null |
| patterns.cs:128:27:128:31 | Int32 x | Int32 |
| patterns.cs:129:13:129:20 | access to type MyStruct | MyStruct |
| patterns.cs:129:13:129:33 | MyStruct ms | MyStruct |
| patterns.cs:129:13:129:33 | { ... } | MyStruct |
| patterns.cs:129:22:129:30 | { ... } | null |
| patterns.cs:129:27:129:28 | 10 | Int32 |
| patterns.cs:130:13:130:18 | ( ... ) | null |
| patterns.cs:130:13:130:18 | { ... } | MyStruct |
| patterns.cs:130:14:130:14 | 1 | Int32 |
| patterns.cs:130:17:130:17 | 2 | Int32 |
| patterns.cs:131:13:131:22 | (..., ...) | (Int32,Object) |
| patterns.cs:131:18:131:18 | Int32 x | Int32 |
| patterns.cs:131:21:131:21 | _ | null |
| patterns.cs:138:17:138:17 | 1 | Int32 |
| patterns.cs:139:17:139:17 | 2 | Int32 |
| patterns.cs:140:17:140:24 | Object y | Object |
| patterns.cs:140:36:140:37 | { ... } | Object |
| patterns.cs:140:36:140:37 | { ... } | null |
| patterns.cs:141:17:141:22 | access to type String | String |
| patterns.cs:142:17:142:24 | access to type MyStruct | MyStruct |
| patterns.cs:142:17:142:36 | { ... } | MyStruct |
| patterns.cs:142:26:142:34 | { ... } | null |
| patterns.cs:142:31:142:32 | 10 | Int32 |
6 changes: 5 additions & 1 deletion csharp/ql/test/library-tests/csharp8/patterns.ql
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,8 @@ query predicate isRecursivePatternExprWithDecl(

query predicate labeledPatternExpr(LabeledPatternExpr e, string s) { s = e.getLabel() }

query predicate tupleTypes(TupleExpr te, Type t) { te.getType() = t }
query predicate tupleTypes(TupleExpr te, string type) { te.getType().toString() = type }

query predicate patternExprTypes(PatternExpr pattern, string type) {
pattern.getType().toString() = type
}
Loading
Loading