using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Linq; namespace Semmle.Extraction.CSharp.Entities { class Property : CachedSymbol, 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().ToArray() : Enumerable.Empty(); 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(). 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 { public static readonly PropertyFactory Instance = new PropertyFactory(); public Property Create(Context cx, IPropertySymbol init) => new Property(cx, init); } public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.PushesLabel; } }