mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
138 lines
5.3 KiB
C#
138 lines
5.3 KiB
C#
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Semmle.Extraction.CSharp.Entities.Expressions;
|
|
using Semmle.Extraction.Entities;
|
|
using Semmle.Extraction.Kinds;
|
|
using System.Linq;
|
|
|
|
namespace Semmle.Extraction.CSharp.Entities
|
|
{
|
|
class Property : CachedSymbol<IPropertySymbol>, IExpressionParentEntity
|
|
{
|
|
protected Property(Context cx, IPropertySymbol init)
|
|
: base(cx, init) { }
|
|
|
|
public override IId Id
|
|
{
|
|
get
|
|
{
|
|
return new Key(tb =>
|
|
{
|
|
tb.Append(ContainingType);
|
|
tb.Append(".");
|
|
Method.AddExplicitInterfaceQualifierToId(Context, tb, symbol.ExplicitInterfaceImplementations);
|
|
tb.Append(symbol.Name);
|
|
tb.Append(";property");
|
|
});
|
|
}
|
|
}
|
|
|
|
public override void Populate()
|
|
{
|
|
ExtractMetadataHandle();
|
|
ExtractAttributes();
|
|
ExtractModifiers();
|
|
BindComments();
|
|
ExtractNullability(symbol.NullableAnnotation);
|
|
ExtractRefKind(symbol.RefKind);
|
|
|
|
var type = Type.Create(Context, symbol.Type);
|
|
Context.Emit(Tuples.properties(this, symbol.GetName(), ContainingType, type.TypeRef, Create(Context, symbol.OriginalDefinition)));
|
|
|
|
var getter = symbol.GetMethod;
|
|
var setter = symbol.SetMethod;
|
|
|
|
if (!(getter is null))
|
|
Method.Create(Context, getter);
|
|
|
|
if (!(setter is null))
|
|
Method.Create(Context, setter);
|
|
|
|
var declSyntaxReferences = IsSourceDeclaration ?
|
|
symbol.DeclaringSyntaxReferences.
|
|
Select(d => d.GetSyntax()).OfType<PropertyDeclarationSyntax>().ToArray()
|
|
: Enumerable.Empty<PropertyDeclarationSyntax>();
|
|
|
|
foreach (var explicitInterface in symbol.ExplicitInterfaceImplementations.Select(impl => Type.Create(Context, impl.ContainingType)))
|
|
{
|
|
Context.Emit(Tuples.explicitly_implements(this, explicitInterface.TypeRef));
|
|
|
|
foreach (var syntax in declSyntaxReferences)
|
|
TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier.Name, this, explicitInterface);
|
|
}
|
|
|
|
foreach (var l in Locations)
|
|
Context.Emit(Tuples.property_location(this, l));
|
|
|
|
if (IsSourceDeclaration && symbol.FromSource())
|
|
{
|
|
var expressionBody = ExpressionBody;
|
|
if (expressionBody != null)
|
|
{
|
|
Context.PopulateLater(() => Expression.Create(Context, expressionBody, this, 0));
|
|
}
|
|
|
|
int child = 1;
|
|
foreach (var initializer in declSyntaxReferences.
|
|
Select(n => n.Initializer).
|
|
Where(i => i != null))
|
|
{
|
|
Context.PopulateLater(() =>
|
|
{
|
|
var loc = Context.Create(initializer.GetLocation());
|
|
var annotatedType = new AnnotatedType(type, TypeAnnotation.None);
|
|
var simpleAssignExpr = new Expression(new ExpressionInfo(Context, annotatedType, loc, ExprKind.SIMPLE_ASSIGN, this, child++, false, null));
|
|
Expression.CreateFromNode(new ExpressionNodeInfo(Context, initializer.Value, simpleAssignExpr, 0));
|
|
var access = new Expression(new ExpressionInfo(Context, annotatedType, Location, ExprKind.PROPERTY_ACCESS, simpleAssignExpr, 1, false, null));
|
|
Context.Emit(Tuples.expr_access(access, this));
|
|
if (!symbol.IsStatic)
|
|
{
|
|
This.CreateImplicit(Context, Type.Create(Context, symbol.ContainingType), Location, access, -1);
|
|
}
|
|
});
|
|
}
|
|
|
|
foreach (var syntax in declSyntaxReferences)
|
|
TypeMention.Create(Context, syntax.Type, this, type);
|
|
}
|
|
}
|
|
|
|
public override Microsoft.CodeAnalysis.Location FullLocation
|
|
{
|
|
get
|
|
{
|
|
return
|
|
symbol.
|
|
DeclaringSyntaxReferences.
|
|
Select(r => r.GetSyntax()).
|
|
OfType<PropertyDeclarationSyntax>().
|
|
Select(s => s.GetLocation()).
|
|
Concat(symbol.Locations).
|
|
First();
|
|
}
|
|
}
|
|
|
|
bool IExpressionParentEntity.IsTopLevelParent => true;
|
|
|
|
public static Property Create(Context cx, IPropertySymbol prop)
|
|
{
|
|
bool isIndexer = prop.IsIndexer || prop.ExplicitInterfaceImplementations.Any(e => e.IsIndexer);
|
|
|
|
return isIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntity(cx, prop);
|
|
}
|
|
|
|
public void VisitDeclaration(Context cx, PropertyDeclarationSyntax p)
|
|
{
|
|
}
|
|
|
|
class PropertyFactory : ICachedEntityFactory<IPropertySymbol, Property>
|
|
{
|
|
public static readonly PropertyFactory Instance = new PropertyFactory();
|
|
|
|
public Property Create(Context cx, IPropertySymbol init) => new Property(cx, init);
|
|
}
|
|
|
|
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.PushesLabel;
|
|
}
|
|
}
|