From 4f8a103df2424b3897b93dc918b4336ee99102c1 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 21 Jun 2021 14:54:53 +0200 Subject: [PATCH] C#: Add active preprocessor conditions as suffix in all TRAP `.push` instructions --- .../Entities/CommentBlock.cs | 2 - .../Entities/Compilations/Compilation.cs | 2 - .../Entities/Compilations/Diagnostic.cs | 2 - .../Entities/Event.cs | 2 - .../Entities/Namespace.cs | 2 - .../Entities/NamespaceDeclaration.cs | 2 - .../PreprocessorDirectives/DefineDirective.cs | 14 ++++++- .../PreprocessorDirectives/ElifDirective.cs | 28 ++++++++++--- .../PreprocessorDirectives/ElseDirective.cs | 17 ++++++-- .../PreprocessorDirectives/EndIfDirective.cs | 15 +++++-- .../EndRegionDirective.cs | 15 +++++-- .../PreprocessorDirectives/ErrorDirective.cs | 14 ++++++- .../PreprocessorDirectives/IfDirective.cs | 25 ++++++++++-- .../PreprocessorDirectives/LineDirective.cs | 24 +++++++---- .../NullableDirective.cs | 20 +++++++--- .../PragmaChecksumDirective.cs | 16 ++++++-- .../PragmaWarningDirective.cs | 16 ++++++-- .../PreprocessorDirective.cs | 30 +++++++------- .../PreprocessorDirectives/RegionDirective.cs | 14 ++++++- .../UndefineDirective.cs | 14 ++++++- .../WarningDirective.cs | 14 ++++++- .../Entities/Property.cs | 1 - .../Entities/Types/Type.cs | 2 - .../Types/TypeParameterConstraints.cs | 2 - .../Entities/UsingDirective.cs | 2 - .../Extractor/Analyser.cs | 7 +++- .../Populators/DirectiveVisitor.cs | 40 ++++++++++++------- csharp/extractor/Semmle.Extraction/Context.cs | 19 +++++++-- .../Entities/Base/CachedEntity`1.cs | 2 +- .../Entities/Base/FreshEntity.cs | 2 +- .../Entities/ExtractionError.cs | 2 - .../Semmle.Extraction/Entities/File.cs | 2 - .../Semmle.Extraction/Entities/Folder.cs | 2 - .../comments/DefineDirectives.expected | 1 + .../comments/Directives.expected | 14 +++++++ .../comments/IfDirectives.expected | 9 +++++ .../library-tests/comments/PrintAst.expected | 29 ++++++++++++++ .../ql/test/library-tests/comments/trivia.cs | 35 +++++++++++++++- 38 files changed, 350 insertions(+), 109 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs index 6d4a2cf07f9..a564d3e7f16 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs @@ -42,7 +42,5 @@ namespace Semmle.Extraction.CSharp.Entities public override CommentBlock Create(Context cx, Comments.CommentBlock init) => new CommentBlock(cx, init); } - - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs index f3672e4c6e4..75614d3ad1e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs @@ -87,8 +87,6 @@ namespace Semmle.Extraction.CSharp.Entities trapFile.Write(";compilation"); } - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; - public override Location ReportingLocation => throw new NotImplementedException(); public override bool NeedsPopulation => Context.IsAssemblyScope; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Diagnostic.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Diagnostic.cs index def6edbf5ad..a53ee5797f2 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Diagnostic.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Diagnostic.cs @@ -4,8 +4,6 @@ namespace Semmle.Extraction.CSharp.Entities { internal class Diagnostic : FreshEntity { - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; - private readonly Microsoft.CodeAnalysis.Diagnostic diagnostic; public Diagnostic(Context cx, Microsoft.CodeAnalysis.Diagnostic diag) : base(cx) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Event.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Event.cs index ca9753d229b..e88d886efec 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Event.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Event.cs @@ -71,7 +71,5 @@ namespace Semmle.Extraction.CSharp.Entities public override Event Create(Context cx, IEventSymbol init) => new Event(cx, init); } - - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Namespace.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Namespace.cs index 68b108743f3..874d8e1b69f 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Namespace.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Namespace.cs @@ -43,8 +43,6 @@ namespace Semmle.Extraction.CSharp.Entities public override Namespace Create(Context cx, INamespaceSymbol init) => new Namespace(cx, init); } - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; - public override int GetHashCode() => QualifiedName.GetHashCode(); private string QualifiedName => Symbol.ToDisplayString(); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/NamespaceDeclaration.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/NamespaceDeclaration.cs index b9fd57b2cea..bb5a55e19db 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/NamespaceDeclaration.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/NamespaceDeclaration.cs @@ -60,8 +60,6 @@ namespace Semmle.Extraction.CSharp.Entities new NamespaceDeclaration(cx, init.decl, init.parent); } - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; - public override Microsoft.CodeAnalysis.Location ReportingLocation => node.Name.GetLocation(); public override bool NeedsPopulation => true; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/DefineDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/DefineDirective.cs index 2ca967a4864..a11b9d94ab5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/DefineDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/DefineDirective.cs @@ -5,14 +5,24 @@ namespace Semmle.Extraction.CSharp.Entities { internal class DefineDirective : PreprocessorDirective { - public DefineDirective(Context cx, DefineDirectiveTriviaSyntax trivia) + private DefineDirective(Context cx, DefineDirectiveTriviaSyntax trivia) : base(cx, trivia) { } protected override void PopulatePreprocessor(TextWriter trapFile) { - trapFile.directive_defines(this, trivia.Name.ToString()); + trapFile.directive_defines(this, Symbol.Name.ToString()); + } + + public static DefineDirective Create(Context cx, DefineDirectiveTriviaSyntax def) => + DefineDirectiveFactory.Instance.CreateEntity(cx, def, def); + + private class DefineDirectiveFactory : CachedEntityFactory + { + public static DefineDirectiveFactory Instance { get; } = new DefineDirectiveFactory(); + + public override DefineDirective Create(Context cx, DefineDirectiveTriviaSyntax init) => new(cx, init); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElifDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElifDirective.cs index ece87fd1f42..48d13e98db3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElifDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElifDirective.cs @@ -8,21 +8,39 @@ namespace Semmle.Extraction.CSharp.Entities private readonly IfDirective start; private readonly int index; - public ElifDirective(Context cx, ElifDirectiveTriviaSyntax trivia, IfDirective start, int index) - : base(cx, trivia, populateFromBase: false) + private ElifDirective(Context cx, ElifDirectiveTriviaSyntax trivia, IfDirective start, int index) + : base(cx, trivia) { this.start = start; this.index = index; - TryPopulate(); } public bool IsTopLevelParent => true; + public override void WriteId(EscapingTextWriter trapFile) + { + trapFile.WriteSubId(Context.CreateLocation(ReportingLocation)); + trapFile.Write(Symbol.IsActive); + trapFile.Write(','); + trapFile.Write(Symbol.ConditionValue); + trapFile.Write(";trivia"); + } + protected override void PopulatePreprocessor(TextWriter trapFile) { - trapFile.directive_elifs(this, trivia.BranchTaken, trivia.ConditionValue, start, index); + trapFile.directive_elifs(this, Symbol.BranchTaken, Symbol.ConditionValue, start, index); - Expression.Create(Context, trivia.Condition, this, 0); + Expression.Create(Context, Symbol.Condition, this, 0); + } + + public static ElifDirective Create(Context cx, ElifDirectiveTriviaSyntax elif, IfDirective start, int index) => + ElifDirectiveFactory.Instance.CreateEntity(cx, elif, (elif, start, index)); + + private class ElifDirectiveFactory : CachedEntityFactory<(ElifDirectiveTriviaSyntax elif, IfDirective start, int index), ElifDirective> + { + public static ElifDirectiveFactory Instance { get; } = new ElifDirectiveFactory(); + + public override ElifDirective Create(Context cx, (ElifDirectiveTriviaSyntax elif, IfDirective start, int index) init) => new(cx, init.elif, init.start, init.index); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElseDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElseDirective.cs index 7ab7d45b6e9..cd44785547c 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElseDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElseDirective.cs @@ -8,17 +8,26 @@ namespace Semmle.Extraction.CSharp.Entities private readonly IfDirective start; private readonly int index; - public ElseDirective(Context cx, ElseDirectiveTriviaSyntax trivia, IfDirective start, int index) - : base(cx, trivia, populateFromBase: false) + private ElseDirective(Context cx, ElseDirectiveTriviaSyntax trivia, IfDirective start, int index) + : base(cx, trivia) { this.start = start; this.index = index; - TryPopulate(); } protected override void PopulatePreprocessor(TextWriter trapFile) { - trapFile.directive_elses(this, trivia.BranchTaken, start, index); + trapFile.directive_elses(this, Symbol.BranchTaken, start, index); + } + + public static ElseDirective Create(Context cx, ElseDirectiveTriviaSyntax @else, IfDirective start, int index) => + ElseDirectiveFactory.Instance.CreateEntity(cx, @else, (@else, start, index)); + + private class ElseDirectiveFactory : CachedEntityFactory<(ElseDirectiveTriviaSyntax @else, IfDirective start, int index), ElseDirective> + { + public static ElseDirectiveFactory Instance { get; } = new ElseDirectiveFactory(); + + public override ElseDirective Create(Context cx, (ElseDirectiveTriviaSyntax @else, IfDirective start, int index) init) => new(cx, init.@else, init.start, init.index); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndIfDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndIfDirective.cs index 9c349844dc6..eb13b62f757 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndIfDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndIfDirective.cs @@ -7,16 +7,25 @@ namespace Semmle.Extraction.CSharp.Entities { private readonly IfDirective start; - public EndIfDirective(Context cx, EndIfDirectiveTriviaSyntax trivia, IfDirective start) - : base(cx, trivia, populateFromBase: false) + private EndIfDirective(Context cx, EndIfDirectiveTriviaSyntax trivia, IfDirective start) + : base(cx, trivia) { this.start = start; - TryPopulate(); } protected override void PopulatePreprocessor(TextWriter trapFile) { trapFile.directive_endifs(this, start); } + + public static EndIfDirective Create(Context cx, EndIfDirectiveTriviaSyntax endif, IfDirective start) => + EndIfDirectiveFactory.Instance.CreateEntity(cx, endif, (endif, start)); + + private class EndIfDirectiveFactory : CachedEntityFactory<(EndIfDirectiveTriviaSyntax endif, IfDirective start), EndIfDirective> + { + public static EndIfDirectiveFactory Instance { get; } = new EndIfDirectiveFactory(); + + public override EndIfDirective Create(Context cx, (EndIfDirectiveTriviaSyntax endif, IfDirective start) init) => new(cx, init.endif, init.start); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndRegionDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndRegionDirective.cs index d4d75470a97..570f9ad61a3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndRegionDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndRegionDirective.cs @@ -7,16 +7,25 @@ namespace Semmle.Extraction.CSharp.Entities { private readonly RegionDirective region; - public EndRegionDirective(Context cx, EndRegionDirectiveTriviaSyntax trivia, RegionDirective region) - : base(cx, trivia, populateFromBase: false) + private EndRegionDirective(Context cx, EndRegionDirectiveTriviaSyntax trivia, RegionDirective region) + : base(cx, trivia) { this.region = region; - TryPopulate(); } protected override void PopulatePreprocessor(TextWriter trapFile) { trapFile.directive_endregions(this, region); } + + public static EndRegionDirective Create(Context cx, EndRegionDirectiveTriviaSyntax end, RegionDirective start) => + EndRegionDirectiveFactory.Instance.CreateEntity(cx, end, (end, start)); + + private class EndRegionDirectiveFactory : CachedEntityFactory<(EndRegionDirectiveTriviaSyntax end, RegionDirective start), EndRegionDirective> + { + public static EndRegionDirectiveFactory Instance { get; } = new EndRegionDirectiveFactory(); + + public override EndRegionDirective Create(Context cx, (EndRegionDirectiveTriviaSyntax end, RegionDirective start) init) => new(cx, init.end, init.start); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ErrorDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ErrorDirective.cs index 2917d077839..b0207769bb3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ErrorDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ErrorDirective.cs @@ -5,14 +5,24 @@ namespace Semmle.Extraction.CSharp.Entities { internal class ErrorDirective : PreprocessorDirective { - public ErrorDirective(Context cx, ErrorDirectiveTriviaSyntax trivia) + private ErrorDirective(Context cx, ErrorDirectiveTriviaSyntax trivia) : base(cx, trivia) { } protected override void PopulatePreprocessor(TextWriter trapFile) { - trapFile.directive_errors(this, trivia.EndOfDirectiveToken.LeadingTrivia.ToString()); + trapFile.directive_errors(this, Symbol.EndOfDirectiveToken.LeadingTrivia.ToString()); + } + + public static ErrorDirective Create(Context cx, ErrorDirectiveTriviaSyntax error) => + ErrorDirectiveFactory.Instance.CreateEntity(cx, error, error); + + private class ErrorDirectiveFactory : CachedEntityFactory + { + public static ErrorDirectiveFactory Instance { get; } = new ErrorDirectiveFactory(); + + public override ErrorDirective Create(Context cx, ErrorDirectiveTriviaSyntax init) => new(cx, init); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/IfDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/IfDirective.cs index 29c6f741620..93b37133cef 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/IfDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/IfDirective.cs @@ -5,18 +5,37 @@ namespace Semmle.Extraction.CSharp.Entities { internal class IfDirective : PreprocessorDirective, IExpressionParentEntity { - public IfDirective(Context cx, IfDirectiveTriviaSyntax trivia) + private IfDirective(Context cx, IfDirectiveTriviaSyntax trivia) : base(cx, trivia) { } public bool IsTopLevelParent => true; + public override void WriteId(EscapingTextWriter trapFile) + { + trapFile.WriteSubId(Context.CreateLocation(ReportingLocation)); + trapFile.Write(Symbol.IsActive); + trapFile.Write(','); + trapFile.Write(Symbol.ConditionValue); + trapFile.Write(";trivia"); + } + protected override void PopulatePreprocessor(TextWriter trapFile) { - trapFile.directive_ifs(this, trivia.BranchTaken, trivia.ConditionValue); + trapFile.directive_ifs(this, Symbol.BranchTaken, Symbol.ConditionValue); - Expression.Create(Context, trivia.Condition, this, 0); + Expression.Create(Context, Symbol.Condition, this, 0); + } + + public static IfDirective Create(Context cx, IfDirectiveTriviaSyntax @if) => + IfDirectiveFactory.Instance.CreateEntity(cx, @if, @if); + + private class IfDirectiveFactory : CachedEntityFactory + { + public static IfDirectiveFactory Instance { get; } = new IfDirectiveFactory(); + + public override IfDirective Create(Context cx, IfDirectiveTriviaSyntax init) => new(cx, init); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/LineDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/LineDirective.cs index 06fafd1e4ce..6afae54a129 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/LineDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/LineDirective.cs @@ -7,34 +7,44 @@ namespace Semmle.Extraction.CSharp.Entities { internal class LineDirective : PreprocessorDirective { - public LineDirective(Context cx, LineDirectiveTriviaSyntax trivia) + private LineDirective(Context cx, LineDirectiveTriviaSyntax trivia) : base(cx, trivia) { } protected override void PopulatePreprocessor(TextWriter trapFile) { - var type = trivia.Line.Kind() switch + var type = Symbol.Line.Kind() switch { SyntaxKind.DefaultKeyword => 0, SyntaxKind.HiddenKeyword => 1, SyntaxKind.NumericLiteralToken => 2, - _ => throw new InternalError(trivia, "Unhandled line token kind") + _ => throw new InternalError(Symbol, "Unhandled line token kind") }; trapFile.directive_lines(this, type); - if (trivia.Line.IsKind(SyntaxKind.NumericLiteralToken)) + if (Symbol.Line.IsKind(SyntaxKind.NumericLiteralToken)) { - var value = (int)trivia.Line.Value!; + var value = (int)Symbol.Line.Value!; trapFile.directive_line_value(this, value); - if (!string.IsNullOrWhiteSpace(trivia.File.ValueText)) + if (!string.IsNullOrWhiteSpace(Symbol.File.ValueText)) { - var file = File.Create(Context, trivia.File.ValueText); + var file = File.Create(Context, Symbol.File.ValueText); trapFile.directive_line_file(this, file); } } } + + public static LineDirective Create(Context cx, LineDirectiveTriviaSyntax line) => + LineDirectiveFactory.Instance.CreateEntity(cx, line, line); + + private class LineDirectiveFactory : CachedEntityFactory + { + public static LineDirectiveFactory Instance { get; } = new LineDirectiveFactory(); + + public override LineDirective Create(Context cx, LineDirectiveTriviaSyntax init) => new(cx, init); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/NullableDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/NullableDirective.cs index e6bb4e79fed..93372c6200d 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/NullableDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/NullableDirective.cs @@ -6,30 +6,40 @@ namespace Semmle.Extraction.CSharp.Entities { internal class NullableDirective : PreprocessorDirective { - public NullableDirective(Context cx, NullableDirectiveTriviaSyntax trivia) + private NullableDirective(Context cx, NullableDirectiveTriviaSyntax trivia) : base(cx, trivia) { } protected override void PopulatePreprocessor(TextWriter trapFile) { - var setting = trivia.SettingToken.Kind() switch + var setting = Symbol.SettingToken.Kind() switch { SyntaxKind.DisableKeyword => 0, SyntaxKind.EnableKeyword => 1, SyntaxKind.RestoreKeyword => 2, - _ => throw new InternalError(trivia, "Unhandled setting token kind") + _ => throw new InternalError(Symbol, "Unhandled setting token kind") }; - var target = trivia.TargetToken.Kind() switch + var target = Symbol.TargetToken.Kind() switch { SyntaxKind.None => 0, SyntaxKind.AnnotationsKeyword => 1, SyntaxKind.WarningsKeyword => 2, - _ => throw new InternalError(trivia, "Unhandled target token kind") + _ => throw new InternalError(Symbol, "Unhandled target token kind") }; trapFile.directive_nullables(this, setting, target); } + + public static NullableDirective Create(Context cx, NullableDirectiveTriviaSyntax nullable) => + NullableDirectiveFactory.Instance.CreateEntity(cx, nullable, nullable); + + private class NullableDirectiveFactory : CachedEntityFactory + { + public static NullableDirectiveFactory Instance { get; } = new NullableDirectiveFactory(); + + public override NullableDirective Create(Context cx, NullableDirectiveTriviaSyntax init) => new(cx, init); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaChecksumDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaChecksumDirective.cs index caa77ceec33..3e06bba104d 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaChecksumDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaChecksumDirective.cs @@ -5,15 +5,25 @@ namespace Semmle.Extraction.CSharp.Entities { internal class PragmaChecksumDirective : PreprocessorDirective { - public PragmaChecksumDirective(Context cx, PragmaChecksumDirectiveTriviaSyntax trivia) + private PragmaChecksumDirective(Context cx, PragmaChecksumDirectiveTriviaSyntax trivia) : base(cx, trivia) { } protected override void PopulatePreprocessor(TextWriter trapFile) { - var file = File.Create(Context, trivia.File.ValueText); - trapFile.pragma_checksums(this, file, trivia.Guid.ToString(), trivia.Bytes.ToString()); + var file = File.Create(Context, Symbol.File.ValueText); + trapFile.pragma_checksums(this, file, Symbol.Guid.ToString(), Symbol.Bytes.ToString()); + } + + public static PragmaChecksumDirective Create(Context cx, PragmaChecksumDirectiveTriviaSyntax p) => + PragmaChecksumDirectiveFactory.Instance.CreateEntity(cx, p, p); + + private class PragmaChecksumDirectiveFactory : CachedEntityFactory + { + public static PragmaChecksumDirectiveFactory Instance { get; } = new PragmaChecksumDirectiveFactory(); + + public override PragmaChecksumDirective Create(Context cx, PragmaChecksumDirectiveTriviaSyntax init) => new(cx, init); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs index 4502fa4a87a..0e4ca37a49f 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs @@ -7,20 +7,30 @@ namespace Semmle.Extraction.CSharp.Entities { internal class PragmaWarningDirective : PreprocessorDirective { - public PragmaWarningDirective(Context cx, PragmaWarningDirectiveTriviaSyntax trivia) + private PragmaWarningDirective(Context cx, PragmaWarningDirectiveTriviaSyntax trivia) : base(cx, trivia) { } protected override void PopulatePreprocessor(TextWriter trapFile) { - trapFile.pragma_warnings(this, trivia.DisableOrRestoreKeyword.IsKind(SyntaxKind.DisableKeyword) ? 0 : 1); + trapFile.pragma_warnings(this, Symbol.DisableOrRestoreKeyword.IsKind(SyntaxKind.DisableKeyword) ? 0 : 1); var childIndex = 0; - foreach (var code in trivia.ErrorCodes) + foreach (var code in Symbol.ErrorCodes) { trapFile.pragma_warning_error_codes(this, code.ToString(), childIndex++); } } + + public static PragmaWarningDirective Create(Context cx, PragmaWarningDirectiveTriviaSyntax p) => + PragmaWarningDirectiveFactory.Instance.CreateEntity(cx, p, p); + + private class PragmaWarningDirectiveFactory : CachedEntityFactory + { + public static PragmaWarningDirectiveFactory Instance { get; } = new PragmaWarningDirectiveFactory(); + + public override PragmaWarningDirective Create(Context cx, PragmaWarningDirectiveTriviaSyntax init) => new(cx, init); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PreprocessorDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PreprocessorDirective.cs index 13e702603ab..dba00d61207 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PreprocessorDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PreprocessorDirective.cs @@ -4,25 +4,16 @@ using System.IO; namespace Semmle.Extraction.CSharp.Entities { - internal abstract class PreprocessorDirective : FreshEntity where TDirective : DirectiveTriviaSyntax + internal abstract class PreprocessorDirective : CachedEntity where TDirective : DirectiveTriviaSyntax { - protected readonly TDirective trivia; + protected PreprocessorDirective(Context cx, TDirective trivia) + : base(cx, trivia) { } - protected PreprocessorDirective(Context cx, TDirective trivia, bool populateFromBase = true) - : base(cx) - { - this.trivia = trivia; - if (populateFromBase) - { - TryPopulate(); - } - } - - protected sealed override void Populate(TextWriter trapFile) + public sealed override void Populate(TextWriter trapFile) { PopulatePreprocessor(trapFile); - trapFile.preprocessor_directive_active(this, trivia.IsActive); + trapFile.preprocessor_directive_active(this, Symbol.IsActive); trapFile.preprocessor_directive_location(this, Context.CreateLocation(ReportingLocation)); if (!Context.Extractor.Standalone) @@ -34,8 +25,17 @@ namespace Semmle.Extraction.CSharp.Entities protected abstract void PopulatePreprocessor(TextWriter trapFile); - public sealed override Microsoft.CodeAnalysis.Location ReportingLocation => trivia.GetLocation(); + public sealed override Microsoft.CodeAnalysis.Location ReportingLocation => Symbol.GetLocation(); + + public override bool NeedsPopulation => true; public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.OptionalLabel; + + public override void WriteId(EscapingTextWriter trapFile) + { + trapFile.WriteSubId(Context.CreateLocation(ReportingLocation)); + trapFile.Write(Symbol.IsActive); + trapFile.Write(";trivia"); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/RegionDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/RegionDirective.cs index b2f017688a3..f8d963d6192 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/RegionDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/RegionDirective.cs @@ -6,14 +6,24 @@ namespace Semmle.Extraction.CSharp.Entities { internal class RegionDirective : PreprocessorDirective { - public RegionDirective(Context cx, RegionDirectiveTriviaSyntax trivia) + private RegionDirective(Context cx, RegionDirectiveTriviaSyntax trivia) : base(cx, trivia) { } protected override void PopulatePreprocessor(TextWriter trapFile) { - trapFile.directive_regions(this, trivia.EndOfDirectiveToken.LeadingTrivia.ToString()); + trapFile.directive_regions(this, Symbol.EndOfDirectiveToken.LeadingTrivia.ToString()); + } + + public static RegionDirective Create(Context cx, RegionDirectiveTriviaSyntax region) => + RegionDirectiveFactory.Instance.CreateEntity(cx, region, region); + + private class RegionDirectiveFactory : CachedEntityFactory + { + public static RegionDirectiveFactory Instance { get; } = new RegionDirectiveFactory(); + + public override RegionDirective Create(Context cx, RegionDirectiveTriviaSyntax init) => new(cx, init); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/UndefineDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/UndefineDirective.cs index d4b976d50c0..3bba6699b88 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/UndefineDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/UndefineDirective.cs @@ -5,14 +5,24 @@ namespace Semmle.Extraction.CSharp.Entities { internal class UndefineDirective : PreprocessorDirective { - public UndefineDirective(Context cx, UndefDirectiveTriviaSyntax trivia) + private UndefineDirective(Context cx, UndefDirectiveTriviaSyntax trivia) : base(cx, trivia) { } protected override void PopulatePreprocessor(TextWriter trapFile) { - trapFile.directive_undefines(this, trivia.Name.ToString()); + trapFile.directive_undefines(this, Symbol.Name.ToString()); + } + + public static UndefineDirective Create(Context cx, UndefDirectiveTriviaSyntax undef) => + UndefineDirectiveFactory.Instance.CreateEntity(cx, undef, undef); + + private class UndefineDirectiveFactory : CachedEntityFactory + { + public static UndefineDirectiveFactory Instance { get; } = new UndefineDirectiveFactory(); + + public override UndefineDirective Create(Context cx, UndefDirectiveTriviaSyntax init) => new(cx, init); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/WarningDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/WarningDirective.cs index 1511be8d28c..2f8d2e277dc 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/WarningDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/WarningDirective.cs @@ -5,14 +5,24 @@ namespace Semmle.Extraction.CSharp.Entities { internal class WarningDirective : PreprocessorDirective { - public WarningDirective(Context cx, WarningDirectiveTriviaSyntax trivia) + private WarningDirective(Context cx, WarningDirectiveTriviaSyntax trivia) : base(cx, trivia) { } protected override void PopulatePreprocessor(TextWriter trapFile) { - trapFile.directive_warnings(this, trivia.EndOfDirectiveToken.LeadingTrivia.ToString()); + trapFile.directive_warnings(this, Symbol.EndOfDirectiveToken.LeadingTrivia.ToString()); + } + + public static WarningDirective Create(Context cx, WarningDirectiveTriviaSyntax warning) => + WarningDirectiveFactory.Instance.CreateEntity(cx, warning, warning); + + private class WarningDirectiveFactory : CachedEntityFactory + { + public static WarningDirectiveFactory Instance { get; } = new WarningDirectiveFactory(); + + public override WarningDirective Create(Context cx, WarningDirectiveTriviaSyntax init) => new(cx, init); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Property.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Property.cs index 9e4a1c79ad2..fd9d0e586fc 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Property.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Property.cs @@ -2,7 +2,6 @@ using System; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Semmle.Extraction.CSharp.Entities.Expressions; -using Semmle.Extraction.Entities; using Semmle.Extraction.Kinds; using System.IO; using System.Linq; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs index 67936f9a913..2b865d79772 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs @@ -341,8 +341,6 @@ namespace Semmle.Extraction.CSharp.Entities } } - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; - public override bool Equals(object? obj) { var other = obj as Type; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TypeParameterConstraints.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TypeParameterConstraints.cs index 04ab78a0f54..e71b618bc71 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TypeParameterConstraints.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TypeParameterConstraints.cs @@ -7,8 +7,6 @@ namespace Semmle.Extraction.CSharp.Entities public TypeParameterConstraints(Context cx) : base(cx) { } - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; - protected override void Populate(TextWriter trapFile) { } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UsingDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UsingDirective.cs index d278d904253..0948e1c31bc 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UsingDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UsingDirective.cs @@ -54,7 +54,5 @@ namespace Semmle.Extraction.CSharp.Entities } public sealed override Microsoft.CodeAnalysis.Location ReportingLocation => node.GetLocation(); - - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs index 3de3a68b656..4551d73c324 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs @@ -212,8 +212,13 @@ namespace Semmle.Extraction.CSharp Entities.File.Create(cx, root.SyntaxTree.FilePath); var csNode = (CSharpSyntaxNode)root; + var directiveVisitor = new DirectiveVisitor(cx); + csNode.Accept(directiveVisitor); + foreach (var condition in directiveVisitor.ActiveConditions) + { + cx.TrapStackSuffix.Add(condition); + } csNode.Accept(new CompilationUnitVisitor(cx)); - csNode.Accept(new DirectiveVisitor(cx)); cx.PopulateAll(); CommentPopulator.ExtractCommentBlocks(cx, cx.CommentGenerator); cx.PopulateAll(); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/DirectiveVisitor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/DirectiveVisitor.cs index 0c400728554..526ad6b7d93 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Populators/DirectiveVisitor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Populators/DirectiveVisitor.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -8,6 +9,13 @@ namespace Semmle.Extraction.CSharp.Populators internal class DirectiveVisitor : CSharpSyntaxWalker { private readonly Context cx; + private readonly List activeConditions = new(); + + /// + /// Gets a list of `#if` and `#elif` entities that are active, and where + /// the condition is `true`. + /// + public IEnumerable ActiveConditions => activeConditions; public DirectiveVisitor(Context cx) : base(SyntaxWalkerDepth.StructuredTrivia) { @@ -16,49 +24,49 @@ namespace Semmle.Extraction.CSharp.Populators public override void VisitPragmaWarningDirectiveTrivia(PragmaWarningDirectiveTriviaSyntax node) { - new Entities.PragmaWarningDirective(cx, node); + Entities.PragmaWarningDirective.Create(cx, node); } public override void VisitPragmaChecksumDirectiveTrivia(PragmaChecksumDirectiveTriviaSyntax node) { - new Entities.PragmaChecksumDirective(cx, node); + Entities.PragmaChecksumDirective.Create(cx, node); } public override void VisitDefineDirectiveTrivia(DefineDirectiveTriviaSyntax node) { - new Entities.DefineDirective(cx, node); + Entities.DefineDirective.Create(cx, node); } public override void VisitUndefDirectiveTrivia(UndefDirectiveTriviaSyntax node) { - new Entities.UndefineDirective(cx, node); + Entities.UndefineDirective.Create(cx, node); } public override void VisitWarningDirectiveTrivia(WarningDirectiveTriviaSyntax node) { - new Entities.WarningDirective(cx, node); + Entities.WarningDirective.Create(cx, node); } public override void VisitErrorDirectiveTrivia(ErrorDirectiveTriviaSyntax node) { - new Entities.ErrorDirective(cx, node); + Entities.ErrorDirective.Create(cx, node); } public override void VisitNullableDirectiveTrivia(NullableDirectiveTriviaSyntax node) { - new Entities.NullableDirective(cx, node); + Entities.NullableDirective.Create(cx, node); } public override void VisitLineDirectiveTrivia(LineDirectiveTriviaSyntax node) { - new Entities.LineDirective(cx, node); + Entities.LineDirective.Create(cx, node); } private readonly Stack regionStarts = new Stack(); public override void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { - var region = new Entities.RegionDirective(cx, node); + var region = Entities.RegionDirective.Create(cx, node); regionStarts.Push(region); } @@ -72,7 +80,7 @@ namespace Semmle.Extraction.CSharp.Populators } var start = regionStarts.Pop(); - new Entities.EndRegionDirective(cx, node, start); + Entities.EndRegionDirective.Create(cx, node, start); } private class IfDirectiveStackElement @@ -91,8 +99,10 @@ namespace Semmle.Extraction.CSharp.Populators public override void VisitIfDirectiveTrivia(IfDirectiveTriviaSyntax node) { - var ifStart = new Entities.IfDirective(cx, node); + var ifStart = Entities.IfDirective.Create(cx, node); ifStarts.Push(new IfDirectiveStackElement(ifStart)); + if (node.IsActive && node.ConditionValue) + activeConditions.Add(ifStart); } public override void VisitEndIfDirectiveTrivia(EndIfDirectiveTriviaSyntax node) @@ -105,7 +115,7 @@ namespace Semmle.Extraction.CSharp.Populators } var start = ifStarts.Pop(); - new Entities.EndIfDirective(cx, node, start.Entity); + Entities.EndIfDirective.Create(cx, node, start.Entity); } public override void VisitElifDirectiveTrivia(ElifDirectiveTriviaSyntax node) @@ -118,7 +128,9 @@ namespace Semmle.Extraction.CSharp.Populators } var start = ifStarts.Peek(); - new Entities.ElifDirective(cx, node, start.Entity, start.SiblingCount++); + var elIf = Entities.ElifDirective.Create(cx, node, start.Entity, start.SiblingCount++); + if (node.IsActive && node.ConditionValue) + activeConditions.Add(elIf); } public override void VisitElseDirectiveTrivia(ElseDirectiveTriviaSyntax node) @@ -131,7 +143,7 @@ namespace Semmle.Extraction.CSharp.Populators } var start = ifStarts.Peek(); - new Entities.ElseDirective(cx, node, start.Entity, start.SiblingCount++); + Entities.ElseDirective.Create(cx, node, start.Entity, start.SiblingCount++); } } } diff --git a/csharp/extractor/Semmle.Extraction/Context.cs b/csharp/extractor/Semmle.Extraction/Context.cs index 410b3c6980a..abbabcdd198 100644 --- a/csharp/extractor/Semmle.Extraction/Context.cs +++ b/csharp/extractor/Semmle.Extraction/Context.cs @@ -30,6 +30,8 @@ namespace Semmle.Extraction /// public bool ShouldAddAssemblyTrapPrefix { get; } + public IList TrapStackSuffix { get; } = new List(); + private int GetNewId() => TrapWriter.IdCounter++; // A recursion guard against writing to the trap file whilst writing an id to the trap file. @@ -270,8 +272,7 @@ namespace Semmle.Extraction return; } - bool duplicationGuard; - bool deferred; + bool duplicationGuard, deferred; switch (entity.TrapStackBehaviour) { @@ -291,14 +292,24 @@ namespace Semmle.Extraction break; case TrapStackBehaviour.PushesLabel: duplicationGuard = true; - deferred = tagStack.Any(); + deferred = duplicationGuard && tagStack.Any(); break; default: throw new InternalError("Unexpected TrapStackBehaviour"); } var a = duplicationGuard && IsEntityDuplicationGuarded(entity, out var loc) - ? (Action)(() => WithDuplicationGuard(new Key(entity, loc), () => entity.Populate(TrapWriter.Writer))) + ? (() => + { + var args = new object[TrapStackSuffix.Count + 2]; + args[0] = entity; + args[1] = loc; + for (var i = 0; i < TrapStackSuffix.Count; i++) + { + args[i + 2] = TrapStackSuffix[i]; + } + WithDuplicationGuard(new Key(args), () => entity.Populate(TrapWriter.Writer)); + }) : (Action)(() => this.Try(null, optionalSymbol, () => entity.Populate(TrapWriter.Writer))); if (deferred) diff --git a/csharp/extractor/Semmle.Extraction/Entities/Base/CachedEntity`1.cs b/csharp/extractor/Semmle.Extraction/Entities/Base/CachedEntity`1.cs index 88506638e17..4ef36362733 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/Base/CachedEntity`1.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/Base/CachedEntity`1.cs @@ -60,7 +60,7 @@ namespace Semmle.Extraction return other?.GetType() == GetType() && Equals(other.Symbol, Symbol); } - public override TrapStackBehaviour TrapStackBehaviour { get; } + public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; } /// diff --git a/csharp/extractor/Semmle.Extraction/Entities/Base/FreshEntity.cs b/csharp/extractor/Semmle.Extraction/Entities/Base/FreshEntity.cs index bdef7ac5f66..7ecdab8086e 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/Base/FreshEntity.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/Base/FreshEntity.cs @@ -33,6 +33,6 @@ namespace Semmle.Extraction public override Microsoft.CodeAnalysis.Location? ReportingLocation => null; - public override TrapStackBehaviour TrapStackBehaviour { get; } + public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; } } diff --git a/csharp/extractor/Semmle.Extraction/Entities/ExtractionError.cs b/csharp/extractor/Semmle.Extraction/Entities/ExtractionError.cs index f7be2995923..99f17537790 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/ExtractionError.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/ExtractionError.cs @@ -17,7 +17,5 @@ namespace Semmle.Extraction.Entities trapFile.extractor_messages(this, msg.Severity, "C# extractor", msg.Text, msg.EntityText ?? string.Empty, msg.Location ?? Context.CreateLocation(), msg.StackTrace ?? string.Empty); } - - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; } } diff --git a/csharp/extractor/Semmle.Extraction/Entities/File.cs b/csharp/extractor/Semmle.Extraction/Entities/File.cs index 11d37c99636..952302360b1 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/File.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/File.cs @@ -24,7 +24,5 @@ namespace Semmle.Extraction.Entities } public override Microsoft.CodeAnalysis.Location? ReportingLocation => null; - - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; } } diff --git a/csharp/extractor/Semmle.Extraction/Entities/Folder.cs b/csharp/extractor/Semmle.Extraction/Entities/Folder.cs index 07e8c805e7f..2826ab49ed1 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/Folder.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/Folder.cs @@ -33,8 +33,6 @@ namespace Semmle.Extraction.Entities public override Folder Create(Context cx, PathTransformer.ITransformedPath init) => new Folder(cx, init); } - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; - public override int GetHashCode() => Symbol.GetHashCode(); public override bool Equals(object? obj) diff --git a/csharp/ql/test/library-tests/comments/DefineDirectives.expected b/csharp/ql/test/library-tests/comments/DefineDirectives.expected index e58b3859d58..79cdc468e92 100644 --- a/csharp/ql/test/library-tests/comments/DefineDirectives.expected +++ b/csharp/ql/test/library-tests/comments/DefineDirectives.expected @@ -1 +1,2 @@ | trivia.cs:4:1:4:13 | #define ... | DEBUG | +| trivia.cs:5:1:5:14 | #define ... | DEBUG2 | diff --git a/csharp/ql/test/library-tests/comments/Directives.expected b/csharp/ql/test/library-tests/comments/Directives.expected index c6d0a12ffb6..01b418ba754 100644 --- a/csharp/ql/test/library-tests/comments/Directives.expected +++ b/csharp/ql/test/library-tests/comments/Directives.expected @@ -1,5 +1,6 @@ directives | trivia.cs:4:1:4:13 | #define ... | trivia.cs:4:1:4:13 | trivia.cs:4:1:4:13 | active | +| trivia.cs:5:1:5:14 | #define ... | trivia.cs:5:1:5:14 | trivia.cs:5:1:5:14 | active | | trivia.cs:6:1:6:12 | #undef ... | trivia.cs:6:1:6:12 | trivia.cs:6:1:6:12 | active | | trivia.cs:12:1:12:35 | #pragma warning ... | trivia.cs:12:1:12:35 | trivia.cs:12:1:12:35 | active | | trivia.cs:13:1:13:103 | #pragma checksum ... | trivia.cs:13:1:13:103 | trivia.cs:13:1:13:103 | active | @@ -29,8 +30,15 @@ directives | trivia.cs:72:1:72:43 | #warning ... | trivia.cs:72:1:72:43 | trivia.cs:72:1:72:43 | active | | trivia.cs:74:1:74:5 | #else | trivia.cs:74:1:74:5 | trivia.cs:74:1:74:5 | active | | trivia.cs:76:1:76:6 | #endif | trivia.cs:76:1:76:6 | trivia.cs:76:1:76:6 | active | +| trivia.cs:82:1:82:10 | #if ... | trivia.cs:82:1:82:10 | trivia.cs:82:1:82:10 | active | +| trivia.cs:86:1:86:6 | #endif | trivia.cs:86:1:86:6 | trivia.cs:86:1:86:6 | active | +| trivia.cs:93:1:93:10 | #if ... | trivia.cs:93:1:93:10 | trivia.cs:93:1:93:10 | active | +| trivia.cs:95:1:95:6 | #endif | trivia.cs:95:1:95:6 | trivia.cs:95:1:95:6 | active | +| trivia.cs:103:1:103:10 | #if ... | trivia.cs:103:1:103:10 | trivia.cs:103:1:103:10 | active | +| trivia.cs:105:1:105:6 | #endif | trivia.cs:105:1:105:6 | trivia.cs:105:1:105:6 | active | comp | trivia.cs:4:1:4:13 | #define ... | compilation | +| trivia.cs:5:1:5:14 | #define ... | compilation | | trivia.cs:6:1:6:12 | #undef ... | compilation | | trivia.cs:12:1:12:35 | #pragma warning ... | compilation | | trivia.cs:13:1:13:103 | #pragma checksum ... | compilation | @@ -60,3 +68,9 @@ comp | trivia.cs:72:1:72:43 | #warning ... | compilation | | trivia.cs:74:1:74:5 | #else | compilation | | trivia.cs:76:1:76:6 | #endif | compilation | +| trivia.cs:82:1:82:10 | #if ... | compilation | +| trivia.cs:86:1:86:6 | #endif | compilation | +| trivia.cs:93:1:93:10 | #if ... | compilation | +| trivia.cs:95:1:95:6 | #endif | compilation | +| trivia.cs:103:1:103:10 | #if ... | compilation | +| trivia.cs:105:1:105:6 | #endif | compilation | diff --git a/csharp/ql/test/library-tests/comments/IfDirectives.expected b/csharp/ql/test/library-tests/comments/IfDirectives.expected index 3a3a24ef798..3b7b24e388a 100644 --- a/csharp/ql/test/library-tests/comments/IfDirectives.expected +++ b/csharp/ql/test/library-tests/comments/IfDirectives.expected @@ -1,6 +1,9 @@ ifDirectives | trivia.cs:65:1:65:9 | #if ... | trivia.cs:76:1:76:6 | #endif | not taken | false | trivia.cs:65:5:65:9 | DEBUG | | trivia.cs:68:1:68:10 | #if ... | trivia.cs:70:1:70:6 | #endif | not taken | false | trivia.cs:68:5:68:10 | NESTED | +| trivia.cs:82:1:82:10 | #if ... | trivia.cs:86:1:86:6 | #endif | taken | true | trivia.cs:82:5:82:10 | DEBUG2 | +| trivia.cs:93:1:93:10 | #if ... | trivia.cs:95:1:95:6 | #endif | taken | true | trivia.cs:93:5:93:10 | DEBUG2 | +| trivia.cs:103:1:103:10 | #if ... | trivia.cs:105:1:105:6 | #endif | taken | true | trivia.cs:103:5:103:10 | DEBUG2 | siblings | trivia.cs:65:1:65:9 | #if ... | trivia.cs:71:1:71:35 | #elif ... | 0 | taken | | trivia.cs:65:1:65:9 | #if ... | trivia.cs:74:1:74:5 | #else | 1 | not taken | @@ -8,6 +11,9 @@ conditionalDirectives | trivia.cs:65:1:65:9 | #if ... | not taken | false | trivia.cs:65:5:65:9 | DEBUG | | trivia.cs:68:1:68:10 | #if ... | not taken | false | trivia.cs:68:5:68:10 | NESTED | | trivia.cs:71:1:71:35 | #elif ... | taken | true | trivia.cs:71:7:71:35 | ... \|\| ... | +| trivia.cs:82:1:82:10 | #if ... | taken | true | trivia.cs:82:5:82:10 | DEBUG2 | +| trivia.cs:93:1:93:10 | #if ... | taken | true | trivia.cs:93:5:93:10 | DEBUG2 | +| trivia.cs:103:1:103:10 | #if ... | taken | true | trivia.cs:103:5:103:10 | DEBUG2 | expressions | trivia.cs:65:5:65:9 | DEBUG | | trivia.cs:68:5:68:10 | NESTED | @@ -17,3 +23,6 @@ expressions | trivia.cs:71:20:71:23 | true | | trivia.cs:71:29:71:35 | !... | | trivia.cs:71:31:71:34 | TEST | +| trivia.cs:82:5:82:10 | DEBUG2 | +| trivia.cs:93:5:93:10 | DEBUG2 | +| trivia.cs:103:5:103:10 | DEBUG2 | diff --git a/csharp/ql/test/library-tests/comments/PrintAst.expected b/csharp/ql/test/library-tests/comments/PrintAst.expected index 71d16cdf134..3861072de89 100644 --- a/csharp/ql/test/library-tests/comments/PrintAst.expected +++ b/csharp/ql/test/library-tests/comments/PrintAst.expected @@ -177,3 +177,32 @@ trivia.cs: # 73| -1: [TypeMention] int # 73| 0: [LocalVariableAccess] access to local variable i # 73| 1: [IntLiteral] 1 +# 80| [Class] Tr5 +# 83| 5: [Method] M1 +# 83| -1: [TypeMention] Void +# 84| 4: [BlockStmt] {...} +# 88| 6: [Method] M2 +# 88| -1: [TypeMention] Void +# 89| 4: [BlockStmt] {...} +# 92| 7: [Field] F1 +# 92| -1: [TypeMention] int +# 92| 1: [AssignExpr] ... = ... +# 92| 0: [FieldAccess] access to field F1 +# 94| 1: [IntLiteral] 10 +# 98| 8: [Field] F2 +# 98| -1: [TypeMention] int +# 98| 1: [AssignExpr] ... = ... +# 98| 0: [FieldAccess] access to field F2 +# 98| 1: [IntLiteral] 0 +# 100| 9: [Property] P1 +# 100| -1: [TypeMention] int +# 102| 3: [Getter] get_P1 +# 104| 4: [Setter] set_P1 +#-----| 2: (Parameters) +# 104| 0: [Parameter] value +# 108| 10: [Property] P2 +# 108| -1: [TypeMention] int +# 108| 3: [Getter] get_P2 +# 108| 4: [Setter] set_P2 +#-----| 2: (Parameters) +# 108| 0: [Parameter] value diff --git a/csharp/ql/test/library-tests/comments/trivia.cs b/csharp/ql/test/library-tests/comments/trivia.cs index be670eac1c4..fe3f217c393 100644 --- a/csharp/ql/test/library-tests/comments/trivia.cs +++ b/csharp/ql/test/library-tests/comments/trivia.cs @@ -2,7 +2,7 @@ // Start of trivia.cs // Unassociated #define DEBUG - +#define DEBUG2 #undef DEBUG using System; @@ -75,4 +75,35 @@ class Tr4 var i = 2; #endif } -} \ No newline at end of file +} + +class Tr5 +{ +#if DEBUG2 + static void M1() + { + } +#endif + + static void M2() + { + } + + public int F1 +#if DEBUG2 += 10 +#endif +; + + public int F2 = 0; + + public int P1 + { + get; +#if DEBUG2 + set; +#endif + } + + public int P2 { get; set; } +}