mirror of
https://github.com/github/codeql.git
synced 2026-05-03 04:39:29 +02:00
Extract pragma warning directives
This commit is contained in:
@@ -380,6 +380,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
var csNode = (CSharpSyntaxNode)root;
|
||||
csNode.Accept(new CompilationUnitVisitor(cx));
|
||||
csNode.Accept(new DirectiveVisitor(cx));
|
||||
cx.PopulateAll();
|
||||
CommentPopulator.ExtractCommentBlocks(cx, cx.CommentGenerator);
|
||||
cx.PopulateAll();
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal interface IPreprocessorDirective { }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Entities;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class PragmaWarningDirective : FreshEntity, IPreprocessorDirective
|
||||
{
|
||||
private readonly PragmaWarningDirectiveTriviaSyntax trivia;
|
||||
|
||||
public PragmaWarningDirective(Context cx, PragmaWarningDirectiveTriviaSyntax trivia)
|
||||
: base(cx)
|
||||
{
|
||||
this.trivia = trivia;
|
||||
TryPopulate();
|
||||
}
|
||||
|
||||
protected override void Populate(TextWriter trapFile)
|
||||
{
|
||||
trapFile.pragma_warnings(this, trivia.DisableOrRestoreKeyword.IsKind(SyntaxKind.DisableKeyword) ? 0 : 1);
|
||||
|
||||
var childIndex = 0;
|
||||
foreach (var code in trivia.ErrorCodes)
|
||||
{
|
||||
trapFile.pragma_warning_error_codes(this, code.ToString(), childIndex++);
|
||||
}
|
||||
|
||||
trapFile.preprocessor_directive_location(this, cx.Create(ReportingLocation));
|
||||
|
||||
if (!cx.Extractor.Standalone)
|
||||
{
|
||||
var assembly = Assembly.CreateOutputAssembly(cx);
|
||||
trapFile.preprocessor_directive_assembly(this, assembly);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override Microsoft.CodeAnalysis.Location ReportingLocation => trivia.GetLocation();
|
||||
|
||||
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.OptionalLabel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Populators
|
||||
{
|
||||
internal class DirectiveVisitor : CSharpSyntaxWalker
|
||||
{
|
||||
private readonly Context cx;
|
||||
|
||||
public DirectiveVisitor(Context cx) : base(SyntaxWalkerDepth.StructuredTrivia)
|
||||
{
|
||||
this.cx = cx;
|
||||
}
|
||||
|
||||
public override void VisitPragmaWarningDirectiveTrivia(PragmaWarningDirectiveTriviaSyntax node)
|
||||
{
|
||||
new Entities.PragmaWarningDirective(cx, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -590,5 +590,25 @@ namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
trapFile.WriteTuple("using_static_directives", @using, type);
|
||||
}
|
||||
|
||||
internal static void preprocessor_directive_location(this TextWriter trapFile, IPreprocessorDirective directive, Location location)
|
||||
{
|
||||
trapFile.WriteTuple("preprocessor_directive_location", directive, location);
|
||||
}
|
||||
|
||||
internal static void preprocessor_directive_assembly(this TextWriter trapFile, IPreprocessorDirective directive, Assembly assembly)
|
||||
{
|
||||
trapFile.WriteTuple("preprocessor_directive_assembly", directive, assembly);
|
||||
}
|
||||
|
||||
internal static void pragma_warnings(this TextWriter trapFile, PragmaWarningDirective pragma, int kind)
|
||||
{
|
||||
trapFile.WriteTuple("pragma_warnings", pragma, kind);
|
||||
}
|
||||
|
||||
internal static void pragma_warning_error_codes(this TextWriter trapFile, PragmaWarningDirective pragma, string errorCode, int child)
|
||||
{
|
||||
trapFile.WriteTuple("pragma_warning_error_codes", pragma, errorCode, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import semmle.code.csharp.Type
|
||||
import semmle.code.csharp.Using
|
||||
import semmle.code.csharp.Variable
|
||||
import semmle.code.csharp.XML
|
||||
import semmle.code.csharp.Preprocessor
|
||||
import semmle.code.csharp.exprs.Access
|
||||
import semmle.code.csharp.exprs.ArithmeticOperation
|
||||
import semmle.code.csharp.exprs.Assignment
|
||||
|
||||
30
csharp/ql/src/semmle/code/csharp/Preprocessor.qll
Normal file
30
csharp/ql/src/semmle/code/csharp/Preprocessor.qll
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Provides all preprocessor directive classes.
|
||||
*/
|
||||
|
||||
import Element
|
||||
|
||||
class PreprocessorDirective extends Element, @preprocessor_directive {
|
||||
override Location getALocation() { preprocessor_directive_location(this, result) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `#pragma warning` directive.
|
||||
*/
|
||||
class PragmaWarningDirective extends PreprocessorDirective, @pragma_warning {
|
||||
/** Holds if this is a `#pragma warning restore` directive. */
|
||||
predicate restore() { pragma_warnings(this, 1) }
|
||||
|
||||
/** Holds if this is a `#pragma warning disable` directive. */
|
||||
predicate disable() { pragma_warnings(this, 0) }
|
||||
|
||||
/** Holds if this directive specifies error codes. */
|
||||
predicate hasErrorCodes() { exists(string s | pragma_warning_error_codes(this, s, _)) }
|
||||
|
||||
/** Gets a specified error code from this directive. */
|
||||
string getAnErrorCode() { pragma_warning_error_codes(this, result, _) }
|
||||
|
||||
override string toString() { result = "#pragma warning ..." }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "PragmaWarningDirective" }
|
||||
}
|
||||
@@ -217,7 +217,7 @@ tokens(
|
||||
|
||||
@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration
|
||||
| @using_directive | @type_parameter_constraints | @external_element
|
||||
| @xmllocatable | @asp_element | @namespace;
|
||||
| @xmllocatable | @asp_element | @namespace | @preprocessor_directive;
|
||||
|
||||
@declaration = @callable | @generic | @assignable | @namespace;
|
||||
|
||||
@@ -331,6 +331,26 @@ using_directive_location(
|
||||
unique int id: @using_directive ref,
|
||||
int loc: @location ref);
|
||||
|
||||
@preprocessor_directive = @pragma_warning;
|
||||
|
||||
pragma_warnings(
|
||||
unique int id: @pragma_warning,
|
||||
int kind: int ref /* 0 = disable, 1 = restore */);
|
||||
|
||||
#keyset[id, index]
|
||||
pragma_warning_error_codes(
|
||||
int id: @pragma_warning ref,
|
||||
string errorCode: string ref,
|
||||
int index: int ref);
|
||||
|
||||
preprocessor_directive_location(
|
||||
unique int id: @preprocessor_directive ref,
|
||||
int loc: @location ref);
|
||||
|
||||
preprocessor_directive_assembly(
|
||||
unique int id: @preprocessor_directive ref,
|
||||
int loc: @assembly ref);
|
||||
|
||||
/** TYPES **/
|
||||
|
||||
types(
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
disable
|
||||
| trivia.cs:12:1:12:35 | #pragma warning ... |
|
||||
restore
|
||||
| trivia.cs:23:1:23:23 | #pragma warning ... |
|
||||
errorCodes
|
||||
| trivia.cs:12:1:12:35 | #pragma warning ... | 414 |
|
||||
| trivia.cs:12:1:12:35 | #pragma warning ... | CS3021 |
|
||||
9
csharp/ql/test/library-tests/comments/PragmaWarnings.ql
Normal file
9
csharp/ql/test/library-tests/comments/PragmaWarnings.ql
Normal file
@@ -0,0 +1,9 @@
|
||||
import csharp
|
||||
|
||||
query predicate disable(PragmaWarningDirective pragma) { pragma.disable() }
|
||||
|
||||
query predicate restore(PragmaWarningDirective pragma) { pragma.restore() }
|
||||
|
||||
query predicate errorCodes(PragmaWarningDirective pragma, string code) {
|
||||
pragma.hasErrorCodes() and code = pragma.getAnErrorCode()
|
||||
}
|
||||
Reference in New Issue
Block a user