mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
96 lines
3.5 KiB
C#
96 lines
3.5 KiB
C#
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Semmle.Extraction.CSharp.Populators;
|
|
using Semmle.Extraction.Kinds;
|
|
using Microsoft.CodeAnalysis.CSharp;
|
|
using Microsoft.CodeAnalysis;
|
|
using Semmle.Extraction.Entities;
|
|
|
|
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|
{
|
|
abstract class ElementAccess : Expression<ExpressionSyntax>
|
|
{
|
|
protected ElementAccess(ExpressionNodeInfo info, ExpressionSyntax qualifier, BracketedArgumentListSyntax argumentList)
|
|
: base(info.SetKind(GetKind(info.Context, qualifier)))
|
|
{
|
|
Qualifier = qualifier;
|
|
ArgumentList = argumentList;
|
|
}
|
|
|
|
readonly ExpressionSyntax Qualifier;
|
|
readonly BracketedArgumentListSyntax ArgumentList;
|
|
|
|
protected override void Populate()
|
|
{
|
|
if (Kind == ExprKind.POINTER_INDIRECTION)
|
|
{
|
|
var qualifierInfo = new ExpressionNodeInfo(cx, Qualifier, this, 0);
|
|
var add = new Expression(new ExpressionInfo(cx, qualifierInfo.Type, Location, ExprKind.ADD, this, 0, false, null));
|
|
qualifierInfo.SetParent(add, 0);
|
|
CreateFromNode(qualifierInfo);
|
|
PopulateArguments(cx, ArgumentList, 1);
|
|
}
|
|
else
|
|
{
|
|
var child = -1;
|
|
Create(cx, Qualifier, this, child++);
|
|
foreach (var a in ArgumentList.Arguments)
|
|
{
|
|
cx.Extract(a, this, child++);
|
|
}
|
|
|
|
var symbolInfo = cx.GetSymbolInfo(base.Syntax);
|
|
|
|
var indexer = symbolInfo.Symbol as IPropertySymbol;
|
|
if (indexer != null)
|
|
{
|
|
cx.Emit(Tuples.expr_access(this, Indexer.Create(cx, indexer)));
|
|
}
|
|
}
|
|
}
|
|
|
|
public sealed override Microsoft.CodeAnalysis.Location ReportingLocation => base.ReportingLocation;
|
|
|
|
static ExprKind GetKind(Context cx, ExpressionSyntax qualifier)
|
|
{
|
|
var qualifierType = cx.GetType(qualifier);
|
|
|
|
// This is a compilation error, so make a guess and continue.
|
|
if (qualifierType == null) return ExprKind.ARRAY_ACCESS;
|
|
|
|
if (qualifierType.TypeKind == Microsoft.CodeAnalysis.TypeKind.Pointer)
|
|
{
|
|
// Convert expressions of the form a[b] into *(a+b)
|
|
return ExprKind.POINTER_INDIRECTION;
|
|
}
|
|
|
|
return IsDynamic(cx, qualifier) ?
|
|
ExprKind.DYNAMIC_ELEMENT_ACCESS :
|
|
qualifierType.TypeKind == Microsoft.CodeAnalysis.TypeKind.Array ?
|
|
ExprKind.ARRAY_ACCESS :
|
|
ExprKind.INDEXER_ACCESS;
|
|
}
|
|
}
|
|
|
|
class NormalElementAccess : ElementAccess
|
|
{
|
|
NormalElementAccess(ExpressionNodeInfo info)
|
|
: base(info, ((ElementAccessExpressionSyntax)info.Node).Expression, ((ElementAccessExpressionSyntax)info.Node).ArgumentList) { }
|
|
|
|
public static Expression Create(ExpressionNodeInfo info) => new NormalElementAccess(info).TryPopulate();
|
|
}
|
|
|
|
class BindingElementAccess : ElementAccess
|
|
{
|
|
BindingElementAccess(ExpressionNodeInfo info)
|
|
: base(info, FindConditionalQualifier(info.Node), ((ElementBindingExpressionSyntax)info.Node).ArgumentList) { }
|
|
|
|
public static Expression Create(ExpressionNodeInfo info) => new BindingElementAccess(info).TryPopulate();
|
|
|
|
protected override void Populate()
|
|
{
|
|
base.Populate();
|
|
MakeConditional();
|
|
}
|
|
}
|
|
}
|