Files

121 lines
4.3 KiB
C#

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
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();
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));
}
foreach (var initializer in declSyntaxReferences.
Select(n => n.Initializer).
Where(i => i != null).
Select(i => i.Value))
{
Context.PopulateLater(() => Expression.Create(Context, initializer, this, 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;
}
}