mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge branch 'main' into redsun82/update-rules_java
This commit is contained in:
106
.github/workflows/build-ripunzip.yml
vendored
106
.github/workflows/build-ripunzip.yml
vendored
@@ -4,20 +4,45 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ripunzip-version:
|
||||
description: "what reference to checktout from google/runzip"
|
||||
description: What reference to checkout from google/ripunzip. Latest by default
|
||||
required: false
|
||||
openssl-version:
|
||||
description: "what reference to checkout from openssl/openssl for Linux"
|
||||
description: What reference to checkout from openssl/openssl for Linux. Latest by default
|
||||
required: false
|
||||
open-pr:
|
||||
description: Open a pull request updating the ripunzip versions committed to lfs
|
||||
required: false
|
||||
default: true # will be false on PRs
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/build-ripunzip.yml
|
||||
env:
|
||||
RIPUNZIP_DEFAULT: v2.0.3
|
||||
OPENSSL_DEFAULT: openssl-3.6.0
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
versions:
|
||||
runs-on: ubuntu-slim
|
||||
outputs:
|
||||
ripunzip-version: ${{ inputs.ripunzip-version || steps.fetch-ripunzip-version.outputs.version }}
|
||||
openssl-version: ${{ inputs.openssl-version || steps.fetch-openssl-version.outputs.version }}
|
||||
steps:
|
||||
- name: Fetch latest ripunzip version
|
||||
id: fetch-ripunzip-version
|
||||
if: "!inputs.ripunzip-version"
|
||||
run: &fetch-version
|
||||
echo "version=$(gh release view --repo $REPO --json tagName --jq .tagName)" | tee -a $GITHUB_OUTPUT
|
||||
env:
|
||||
REPO: "google/ripunzip"
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Fetch latest openssl version
|
||||
id: fetch-openssl-version
|
||||
if: "!inputs.openssl-version"
|
||||
run: *fetch-version
|
||||
env:
|
||||
REPO: "openssl/openssl"
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
build:
|
||||
needs: versions
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -27,7 +52,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
repository: google/ripunzip
|
||||
ref: ${{ inputs.ripunzip-version || env.RIPUNZIP_DEFAULT }}
|
||||
ref: ${{ needs.versions.outputs.ripunzip-version }}
|
||||
# we need to avoid ripunzip dynamically linking into libssl
|
||||
# see https://github.com/sfackler/rust-openssl/issues/183
|
||||
- if: runner.os == 'Linux'
|
||||
@@ -36,7 +61,7 @@ jobs:
|
||||
with:
|
||||
repository: openssl/openssl
|
||||
path: openssl
|
||||
ref: ${{ inputs.openssl-version || env.OPENSSL_DEFAULT }}
|
||||
ref: ${{ needs.versions.outputs.openssl-version }}
|
||||
- if: runner.os == 'Linux'
|
||||
name: build and install openssl with fPIC
|
||||
shell: bash
|
||||
@@ -68,11 +93,74 @@ jobs:
|
||||
lipo -create -output ripunzip-macos \
|
||||
-arch x86_64 target/x86_64-apple-darwin/release/ripunzip \
|
||||
-arch arm64 target/aarch64-apple-darwin/release/ripunzip
|
||||
- uses: actions/upload-artifact@v4
|
||||
- name: Archive
|
||||
shell: bash
|
||||
run: |
|
||||
tar acf ripunzip-$RUNNER_OS.tar.zst ripunzip-$(echo $RUNNER_OS | tr '[:upper:]' '[:lower:]')
|
||||
- name: Upload built binary
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ripunzip-${{ runner.os }}
|
||||
path: ripunzip-*
|
||||
path: ripunzip-${{ runner.os }}.tar.zst
|
||||
retention-days: 5
|
||||
compression: 0
|
||||
- name: Check built binary
|
||||
shell: bash
|
||||
run: |
|
||||
rm -f ripunzip-*.tar.zst
|
||||
./ripunzip-* --version
|
||||
publish:
|
||||
needs: [versions, build]
|
||||
if: inputs.open-pr == 'true'
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-slim
|
||||
steps:
|
||||
# workaround for git-lfs not being installed yet on ubuntu-slim runners
|
||||
- name: Ensure git-lfs is installed
|
||||
shell: bash
|
||||
run: |
|
||||
if which git-lfs &>/dev/null; then
|
||||
echo "git-lfs is already installed"
|
||||
exit 0
|
||||
fi
|
||||
cd $TMP
|
||||
gh release download --repo git-lfs/git-lfs --pattern "git-lfs-linux-amd64-*.tar.gz" --clobber
|
||||
tar xzf git-lfs-linux-amd64-*.tar.gz
|
||||
rm git-lfs-linux-amd64-*.tar.gz
|
||||
cd git-lfs-*
|
||||
pwd | tee -a $GITHUB_PATH
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github
|
||||
misc/ripunzip
|
||||
lfs: true
|
||||
- name: Download built binaries
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
merge-multiple: true
|
||||
path: misc/ripunzip
|
||||
- name: Open PR
|
||||
shell: bash
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git switch -c update-ripunzip
|
||||
git add misc/ripunzip
|
||||
git commit -m "Update ripunzip binaries to version $VERSION"
|
||||
git push --set-upstream origin update-ripunzip --force
|
||||
TITLE="Update ripunzip binaries to version $VERSION"
|
||||
gh pr create \
|
||||
--draft \
|
||||
--title "$TITLE" \
|
||||
--body "Automated update of ripunzip binaries." \
|
||||
--assignee "$ACTOR" ||
|
||||
(gh pr edit --title "$TITLE" --add-assignee "$ACTOR" && gh pr ready --undo)
|
||||
env:
|
||||
ACTOR: ${{ github.actor }}
|
||||
VERSION: ${{ needs.versions.outputs.ripunzip-version }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -273,19 +273,19 @@ lfs_archive = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_archive")
|
||||
|
||||
lfs_archive(
|
||||
name = "ripunzip-linux",
|
||||
src = "//misc/ripunzip:ripunzip-Linux.zip",
|
||||
src = "//misc/ripunzip:ripunzip-Linux.tar.zst",
|
||||
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
|
||||
)
|
||||
|
||||
lfs_archive(
|
||||
name = "ripunzip-windows",
|
||||
src = "//misc/ripunzip:ripunzip-Windows.zip",
|
||||
src = "//misc/ripunzip:ripunzip-Windows.tar.zst",
|
||||
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
|
||||
)
|
||||
|
||||
lfs_archive(
|
||||
name = "ripunzip-macos",
|
||||
src = "//misc/ripunzip:ripunzip-macOS.zip",
|
||||
src = "//misc/ripunzip:ripunzip-macOS.tar.zst",
|
||||
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
|
||||
)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ aliases:
|
||||
display_name: "C#"
|
||||
version: 1.22.1
|
||||
column_kind: "utf16"
|
||||
overlay_support_version: 20250626
|
||||
extra_env_vars:
|
||||
DOTNET_GENERATE_ASPNET_CERTIFICATE: "false"
|
||||
build_modes:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: Delete databaseMetadata and overlayChangedFiles relations
|
||||
compatibility: full
|
||||
databaseMetadata.rel: delete
|
||||
overlayChangedFiles.rel: delete
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Remove @locatable type
|
||||
compatibility: full
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
@@ -53,6 +54,20 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
}
|
||||
|
||||
progressMonitor.MissingSummary(analyser.ExtractionContext!.MissingTypes.Count(), analyser.ExtractionContext!.MissingNamespaces.Count());
|
||||
|
||||
// If extracting a base database, we need to create an empty metadata file.
|
||||
if (EnvironmentVariables.GetBaseMetaDataOutPath() is string baseMetaDataOutPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
analyser.Logger.LogInfo($"Creating base metadata file at {baseMetaDataOutPath}");
|
||||
File.WriteAllText(baseMetaDataOutPath, string.Empty);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
analyser.Logger.LogError($"Failed to create base metadata file: {ex.Message}");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
finally
|
||||
@@ -143,7 +158,8 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
var pathTransformer = new PathTransformer(canonicalPathCache);
|
||||
|
||||
var progressMonitor = new ExtractionProgress(logger);
|
||||
using var analyser = new StandaloneAnalyser(progressMonitor, fileLogger, pathTransformer, canonicalPathCache, false);
|
||||
var overlayInfo = OverlayInfoFactory.Make(logger, options.SrcDir);
|
||||
using var analyser = new StandaloneAnalyser(progressMonitor, fileLogger, pathTransformer, canonicalPathCache, overlayInfo, false);
|
||||
try
|
||||
{
|
||||
var extractionInput = new ExtractionInput(dependencyManager.AllSourceFiles, dependencyManager.ReferenceFiles, dependencyManager.CompilationInfos);
|
||||
|
||||
@@ -57,8 +57,21 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override void Populate(TextWriter trapFile)
|
||||
{
|
||||
// In this case, we don't extract the attribute again, as it was extracted using * ID
|
||||
// originally and we re-use that.
|
||||
if (Context.OnlyScaffold && (ReportingLocation is null || !ReportingLocation.IsInSource))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var type = Type.Create(Context, Symbol.AttributeClass);
|
||||
trapFile.attributes(this, kind, type.TypeRef, entity);
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteLocationToTrap(trapFile.attribute_location, this, Location);
|
||||
|
||||
if (attributeSyntax is not null)
|
||||
|
||||
@@ -10,9 +10,13 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override void Populate(TextWriter trapFile)
|
||||
{
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
trapFile.commentblock(this);
|
||||
WriteLocationToTrap(trapFile.commentblock_location, this, Context.CreateLocation(Symbol.Location));
|
||||
Symbol.CommentLines.ForEach((l, child) => trapFile.commentblock_child(this, l, child));
|
||||
WriteLocationToTrap(trapFile.commentblock_location, this, Context.CreateLocation(Symbol.Location));
|
||||
}
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
@@ -27,6 +31,10 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public void BindTo(Label entity, CommentBinding binding)
|
||||
{
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Context.TrapWriter.Writer.commentblock_binding(this, entity, binding);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,14 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override void Populate(TextWriter trapFile)
|
||||
{
|
||||
location = Context.CreateLocation(Location);
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
trapFile.commentline(this, Type == CommentLineType.MultilineContinuation ? CommentLineType.Multiline : Type, Text, RawText);
|
||||
location = Context.CreateLocation(Location);
|
||||
WriteLocationToTrap(trapFile.commentline_location, this, location);
|
||||
|
||||
}
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation => location?.Symbol;
|
||||
|
||||
@@ -21,6 +21,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
protected override void Populate(TextWriter trapFile)
|
||||
{
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var key = diagnostic.Id;
|
||||
var messageCount = compilation.messageCounts.AddOrUpdate(key, 1, (_, c) => c + 1);
|
||||
if (messageCount > limit)
|
||||
|
||||
@@ -29,9 +29,17 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
ContainingType!.PopulateGenerics();
|
||||
|
||||
trapFile.constructors(this, Symbol.ContainingType.Name, ContainingType, (Constructor)OriginalDefinition);
|
||||
if (Context.ExtractLocation(Symbol) && (!IsDefault || IsBestSourceLocation))
|
||||
|
||||
if (Symbol.IsImplicitlyDeclared)
|
||||
{
|
||||
WriteLocationToTrap(trapFile.constructor_location, this, Location);
|
||||
var lineCounts = new LineCounts() { Total = 2, Code = 1, Comment = 0 };
|
||||
trapFile.numlines(this, lineCounts);
|
||||
}
|
||||
ExtractCompilerGenerated(trapFile);
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (MakeSynthetic)
|
||||
@@ -40,12 +48,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Statements.SyntheticEmptyBlock.Create(Context, this, 0, Location);
|
||||
}
|
||||
|
||||
if (Symbol.IsImplicitlyDeclared)
|
||||
if (Context.ExtractLocation(Symbol) && (!IsDefault || IsBestSourceLocation))
|
||||
{
|
||||
var lineCounts = new LineCounts() { Total = 2, Code = 1, Comment = 0 };
|
||||
trapFile.numlines(this, lineCounts);
|
||||
WriteLocationToTrap(trapFile.constructor_location, this, Location);
|
||||
}
|
||||
ExtractCompilerGenerated(trapFile);
|
||||
|
||||
}
|
||||
|
||||
protected override void ExtractInitializers(TextWriter trapFile)
|
||||
@@ -53,7 +60,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
// Do not extract initializers for constructed types.
|
||||
// Extract initializers for constructors with a body, primary constructors
|
||||
// and default constructors for classes and structs declared in source code.
|
||||
if (Block is null && ExpressionBody is null && !MakeSynthetic)
|
||||
if (Block is null && ExpressionBody is null && !MakeSynthetic || Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -106,6 +113,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
|
||||
var baseConstructorTarget = Create(Context, baseConstructor);
|
||||
|
||||
var info = new ExpressionInfo(Context,
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(baseType),
|
||||
Location,
|
||||
@@ -179,7 +187,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
/// </summary>
|
||||
private bool IsBestSourceLocation => ReportingLocation is not null && Context.IsLocationInContext(ReportingLocation);
|
||||
|
||||
private bool MakeSynthetic => IsPrimary || (IsDefault && IsBestSourceLocation);
|
||||
private bool MakeSynthetic => (IsPrimary || (IsDefault && IsBestSourceLocation)) && !Context.OnlyScaffold;
|
||||
|
||||
[return: NotNullIfNotNull(nameof(constructor))]
|
||||
public static new Constructor? Create(Context cx, IMethodSymbol? constructor)
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
ContainingType!.PopulateGenerics();
|
||||
|
||||
trapFile.destructors(this, $"~{Symbol.ContainingType.Name}", ContainingType, OriginalDefinition(Context, this, Symbol));
|
||||
|
||||
if (Context.ExtractLocation(Symbol))
|
||||
{
|
||||
WriteLocationToTrap(trapFile.destructor_location, this, Location);
|
||||
|
||||
@@ -37,7 +37,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Method.Create(Context, remover);
|
||||
|
||||
PopulateModifiers(trapFile);
|
||||
BindComments();
|
||||
|
||||
var declSyntaxReferences = IsSourceDeclaration
|
||||
? Symbol.DeclaringSyntaxReferences.Select(d => d.GetSyntax()).ToArray()
|
||||
@@ -51,6 +50,13 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier!.Name, this, explicitInterface);
|
||||
}
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BindComments();
|
||||
|
||||
if (Context.ExtractLocation(Symbol))
|
||||
{
|
||||
WriteLocationsToTrap(trapFile.event_location, this, Locations);
|
||||
|
||||
@@ -28,6 +28,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
protected override void Populate(TextWriter trapFile)
|
||||
{
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// For the time being we're counting the number of messages per severity, we could introduce other groupings in the future
|
||||
var key = msg.Severity.ToString();
|
||||
groupedMessageCounts.AddOrUpdate(key, 1, (_, c) => c + 1);
|
||||
|
||||
@@ -49,6 +49,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Context.ExtractLocation(Symbol))
|
||||
{
|
||||
WriteLocationsToTrap(trapFile.field_location, this, Locations);
|
||||
|
||||
@@ -19,10 +19,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
var type = Type.Create(Context, Symbol.Type);
|
||||
trapFile.indexers(this, Symbol.GetName(useMetadataName: true), ContainingType!, type.TypeRef, OriginalDefinition);
|
||||
if (Context.ExtractLocation(Symbol))
|
||||
{
|
||||
WriteLocationsToTrap(trapFile.indexer_location, this, Locations);
|
||||
}
|
||||
|
||||
var getter = BodyDeclaringSymbol.GetMethod;
|
||||
var setter = BodyDeclaringSymbol.SetMethod;
|
||||
@@ -42,20 +38,8 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Parameter.Create(Context, Symbol.Parameters[i], this, original);
|
||||
}
|
||||
|
||||
if (IsSourceDeclaration)
|
||||
{
|
||||
var expressionBody = ExpressionBody;
|
||||
if (expressionBody is not null)
|
||||
{
|
||||
// The expression may need to reference parameters in the getter.
|
||||
// So we need to arrange that the expression is populated after the getter.
|
||||
Context.PopulateLater(() => Expression.CreateFromNode(new ExpressionNodeInfo(Context, expressionBody, this, 0).SetType(Symbol.GetAnnotatedType())));
|
||||
}
|
||||
}
|
||||
|
||||
PopulateAttributes();
|
||||
PopulateModifiers(trapFile);
|
||||
BindComments();
|
||||
|
||||
var declSyntaxReferences = IsSourceDeclaration
|
||||
? Symbol.DeclaringSyntaxReferences.
|
||||
@@ -70,6 +54,28 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier!.Name, this, explicitInterface);
|
||||
}
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Context.ExtractLocation(Symbol))
|
||||
{
|
||||
WriteLocationsToTrap(trapFile.indexer_location, this, Locations);
|
||||
}
|
||||
|
||||
if (IsSourceDeclaration)
|
||||
{
|
||||
var expressionBody = ExpressionBody;
|
||||
if (expressionBody is not null)
|
||||
{
|
||||
// The expression may need to reference parameters in the getter.
|
||||
// So we need to arrange that the expression is populated after the getter.
|
||||
Context.PopulateLater(() => Expression.CreateFromNode(new ExpressionNodeInfo(Context, expressionBody, this, 0).SetType(Symbol.GetAnnotatedType())));
|
||||
}
|
||||
}
|
||||
|
||||
BindComments();
|
||||
|
||||
foreach (var syntax in declSyntaxReferences)
|
||||
TypeMention.Create(Context, syntax.Type, this, type);
|
||||
|
||||
@@ -41,6 +41,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.localvars(this, Kinds.VariableKind.None, Symbol.Name, @var, Type.Create(Context, parent.Type).TypeRef, parent);
|
||||
}
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteLocationToTrap(trapFile.localvar_location, this, Location);
|
||||
|
||||
DefineConstantValue(trapFile);
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
protected virtual void PopulateMethodBody(TextWriter trapFile)
|
||||
{
|
||||
if (!IsSourceDeclaration)
|
||||
if (!IsSourceDeclaration || Context.OnlyScaffold)
|
||||
return;
|
||||
|
||||
var block = Block;
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
var ns = Namespace.Create(Context, @namespace);
|
||||
trapFile.namespace_declarations(this, ns);
|
||||
WriteLocationToTrap(trapFile.namespace_declaration_location, this, Context.CreateLocation(node.Name.GetLocation()));
|
||||
|
||||
var visitor = new Populators.TypeOrNamespaceVisitor(Context, trapFile, this);
|
||||
|
||||
@@ -48,6 +47,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
trapFile.parent_namespace_declaration(this, parent);
|
||||
}
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
WriteLocationToTrap(trapFile.namespace_declaration_location, this, Context.CreateLocation(node.Name.GetLocation()));
|
||||
}
|
||||
|
||||
public static NamespaceDeclaration Create(Context cx, BaseNamespaceDeclarationSyntax decl, NamespaceDeclaration parent)
|
||||
|
||||
@@ -34,6 +34,16 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var returnType = Type.Create(Context, Symbol.ReturnType);
|
||||
trapFile.methods(this, Name, ContainingType, returnType.TypeRef, OriginalDefinition);
|
||||
|
||||
PopulateGenerics(trapFile);
|
||||
Overrides(trapFile);
|
||||
ExtractRefReturn(trapFile, Symbol, this);
|
||||
ExtractCompilerGenerated(trapFile);
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsSourceDeclaration)
|
||||
{
|
||||
foreach (var declaration in Symbol.DeclaringSyntaxReferences.Select(s => s.GetSyntax()).OfType<MethodDeclarationSyntax>())
|
||||
@@ -47,11 +57,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
WriteLocationsToTrap(trapFile.method_location, this, Locations);
|
||||
}
|
||||
|
||||
PopulateGenerics(trapFile);
|
||||
Overrides(trapFile);
|
||||
ExtractRefReturn(trapFile, Symbol, this);
|
||||
ExtractCompilerGenerated(trapFile);
|
||||
}
|
||||
|
||||
private bool IsCompilerGeneratedDelegate() =>
|
||||
|
||||
@@ -115,6 +115,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var type = Type.Create(Context, Symbol.Type);
|
||||
trapFile.@params(this, Name, type.TypeRef, Ordinal, ParamKind, Parent!, Original);
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Context.ExtractLocation(Symbol))
|
||||
{
|
||||
var locations = Context.GetLocations(Symbol);
|
||||
|
||||
@@ -13,10 +13,15 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
PopulatePreprocessor(trapFile);
|
||||
|
||||
trapFile.preprocessor_directive_active(this, Symbol.IsActive);
|
||||
WriteLocationToTrap(trapFile.preprocessor_directive_location, this, Context.CreateLocation(ReportingLocation));
|
||||
|
||||
var compilation = Compilation.Create(Context);
|
||||
trapFile.preprocessor_directive_compilation(this, compilation);
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
WriteLocationToTrap(trapFile.preprocessor_directive_location, this, Context.CreateLocation(ReportingLocation));
|
||||
}
|
||||
|
||||
protected abstract void PopulatePreprocessor(TextWriter trapFile);
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
PopulateAttributes();
|
||||
PopulateModifiers(trapFile);
|
||||
BindComments();
|
||||
PopulateNullability(trapFile, Symbol.GetAnnotatedType());
|
||||
PopulateRefKind(trapFile, Symbol.RefKind);
|
||||
|
||||
@@ -69,6 +68,13 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier!.Name, this, explicitInterface);
|
||||
}
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BindComments();
|
||||
|
||||
if (Context.ExtractLocation(Symbol))
|
||||
{
|
||||
WriteLocationsToTrap(trapFile.property_location, this, Locations);
|
||||
|
||||
@@ -59,6 +59,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
protected override void Populate(TextWriter trapFile)
|
||||
{
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (syntax.Kind())
|
||||
{
|
||||
case SyntaxKind.ArrayType:
|
||||
|
||||
@@ -16,10 +16,14 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
public override void Populate(TextWriter trapFile)
|
||||
{
|
||||
trapFile.types(this, Kinds.TypeKind.DYNAMIC, "dynamic");
|
||||
WriteLocationToTrap(trapFile.type_location, this, Location);
|
||||
|
||||
trapFile.has_modifiers(this, Modifier.Create(Context, "public"));
|
||||
trapFile.parent_namespace(this, Namespace.Create(Context, Context.Compilation.GlobalNamespace));
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
WriteLocationToTrap(trapFile.type_location, this, Location);
|
||||
}
|
||||
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
|
||||
// Class location
|
||||
if (!Symbol.IsGenericType || Symbol.IsReallyUnbound())
|
||||
if ((!Symbol.IsGenericType || Symbol.IsReallyUnbound()) && !Context.OnlyScaffold)
|
||||
{
|
||||
WriteLocationsToTrap(trapFile.type_location, this, Locations);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.tuple_element(this, index++, element);
|
||||
}
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Note: symbol.Locations seems to be very inconsistent
|
||||
// about what locations are available for a tuple type.
|
||||
// Sometimes it's the source code, and sometimes it's empty.
|
||||
|
||||
@@ -222,7 +222,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private IEnumerable<BaseTypeSyntax> GetBaseTypeDeclarations()
|
||||
{
|
||||
if (!IsSourceDeclaration || !Symbol.FromSource())
|
||||
if (!IsSourceDeclaration || !Symbol.FromSource() || Context.OnlyScaffold)
|
||||
{
|
||||
return Enumerable.Empty<BaseTypeSyntax>();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var parentNs = Namespace.Create(Context, Symbol.TypeParameterKind == TypeParameterKind.Method ? Context.Compilation.GlobalNamespace : Symbol.ContainingNamespace);
|
||||
trapFile.parent_namespace(this, parentNs);
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Context.ExtractLocation(Symbol))
|
||||
{
|
||||
var locations = Context.GetLocations(Symbol);
|
||||
|
||||
@@ -26,6 +26,14 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
returnType.TypeRef,
|
||||
(UserOperator)OriginalDefinition);
|
||||
|
||||
ContainingType.PopulateGenerics();
|
||||
Overrides(trapFile);
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Context.ExtractLocation(Symbol))
|
||||
{
|
||||
WriteLocationsToTrap(trapFile.operator_location, this, Locations);
|
||||
@@ -39,9 +47,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
foreach (var declaration in declSyntaxReferences.OfType<ConversionOperatorDeclarationSyntax>())
|
||||
TypeMention.Create(Context, declaration.Type, this, returnType);
|
||||
}
|
||||
|
||||
ContainingType.PopulateGenerics();
|
||||
Overrides(trapFile);
|
||||
}
|
||||
|
||||
public override bool NeedsPopulation => Context.Defines(Symbol) || IsImplicitOperator(out _);
|
||||
|
||||
@@ -20,6 +20,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
protected override void Populate(TextWriter trapFile)
|
||||
{
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// This is guaranteed to be non-null as we only deal with "using namespace" not "using X = Y"
|
||||
var name = node.Name!;
|
||||
|
||||
|
||||
@@ -41,16 +41,20 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
public IPathCache PathCache { get; }
|
||||
|
||||
public IOverlayInfo OverlayInfo { get; }
|
||||
|
||||
protected Analyser(
|
||||
IProgressMonitor pm,
|
||||
ILogger logger,
|
||||
PathTransformer pathTransformer,
|
||||
IPathCache pathCache,
|
||||
IOverlayInfo overlayInfo,
|
||||
bool addAssemblyTrapPrefix)
|
||||
{
|
||||
Logger = logger;
|
||||
PathTransformer = pathTransformer;
|
||||
PathCache = pathCache;
|
||||
OverlayInfo = overlayInfo;
|
||||
this.addAssemblyTrapPrefix = addAssemblyTrapPrefix;
|
||||
this.progressMonitor = pm;
|
||||
|
||||
@@ -158,7 +162,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
if (compilation.GetAssemblyOrModuleSymbol(r) is IAssemblySymbol assembly)
|
||||
{
|
||||
var cx = new Context(ExtractionContext, compilation, trapWriter, new AssemblyScope(assembly, assemblyPath), addAssemblyTrapPrefix);
|
||||
var cx = new Context(ExtractionContext, compilation, trapWriter, new AssemblyScope(assembly, assemblyPath), OverlayInfo, addAssemblyTrapPrefix);
|
||||
|
||||
foreach (var module in assembly.Modules)
|
||||
{
|
||||
@@ -195,7 +199,7 @@ namespace Semmle.Extraction.CSharp
|
||||
var currentTaskId = IncrementTaskCount();
|
||||
ReportProgressTaskStarted(currentTaskId, sourcePath);
|
||||
|
||||
var cx = new Context(ExtractionContext, compilation, trapWriter, new SourceScope(tree), addAssemblyTrapPrefix);
|
||||
var cx = new Context(ExtractionContext, compilation, trapWriter, new SourceScope(tree), OverlayInfo, addAssemblyTrapPrefix);
|
||||
// Ensure that the file itself is populated in case the source file is totally empty
|
||||
var root = tree.GetRoot();
|
||||
Entities.File.Create(cx, root.SyntaxTree.FilePath);
|
||||
@@ -234,7 +238,7 @@ namespace Semmle.Extraction.CSharp
|
||||
var assembly = compilation.Assembly;
|
||||
var trapWriter = transformedAssemblyPath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false);
|
||||
compilationTrapFile = trapWriter; // Dispose later
|
||||
var cx = new Context(ExtractionContext, compilation, trapWriter, new AssemblyScope(assembly, assemblyPath), addAssemblyTrapPrefix);
|
||||
var cx = new Context(ExtractionContext, compilation, trapWriter, new AssemblyScope(assembly, assemblyPath), OverlayInfo, addAssemblyTrapPrefix);
|
||||
|
||||
compilationEntity = Entities.Compilation.Create(cx);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp
|
||||
public class BinaryLogAnalyser : Analyser
|
||||
{
|
||||
public BinaryLogAnalyser(IProgressMonitor pm, ILogger logger, PathTransformer pathTransformer, IPathCache pathCache, bool addAssemblyTrapPrefix)
|
||||
: base(pm, logger, pathTransformer, pathCache, addAssemblyTrapPrefix)
|
||||
: base(pm, logger, pathTransformer, pathCache, new TrivialOverlayInfo(), addAssemblyTrapPrefix)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@ namespace Semmle.Extraction.CSharp
|
||||
/// </summary>
|
||||
public bool ShouldAddAssemblyTrapPrefix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds if trap only should be created for types and member signatures (and not for expressions and statements).
|
||||
/// This is the case for all unchanged files, when running in overlay mode.
|
||||
/// </summary>
|
||||
public bool OnlyScaffold { get; }
|
||||
|
||||
public IList<object> TrapStackSuffix { get; } = new List<object>();
|
||||
|
||||
private int GetNewId() => TrapWriter.IdCounter++;
|
||||
@@ -523,13 +529,16 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal CommentProcessor CommentGenerator { get; } = new CommentProcessor();
|
||||
|
||||
public Context(ExtractionContext extractionContext, Compilation c, TrapWriter trapWriter, IExtractionScope scope, bool shouldAddAssemblyTrapPrefix = false)
|
||||
public Context(ExtractionContext extractionContext, Compilation c, TrapWriter trapWriter, IExtractionScope scope, IOverlayInfo overlayInfo, bool shouldAddAssemblyTrapPrefix = false)
|
||||
{
|
||||
ExtractionContext = extractionContext;
|
||||
TrapWriter = trapWriter;
|
||||
ShouldAddAssemblyTrapPrefix = shouldAddAssemblyTrapPrefix;
|
||||
Compilation = c;
|
||||
this.scope = scope;
|
||||
OnlyScaffold = overlayInfo.IsOverlayMode && (
|
||||
IsAssemblyScope
|
||||
|| (scope is SourceScope ss && overlayInfo.OnlyMakeScaffold(ss.SourceTree.FilePath)));
|
||||
}
|
||||
|
||||
public bool FromSource => scope is SourceScope;
|
||||
@@ -552,7 +561,8 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
public bool ExtractLocation(ISymbol symbol) =>
|
||||
SymbolEqualityComparer.Default.Equals(symbol, symbol.OriginalDefinition) &&
|
||||
scope.InScope(symbol);
|
||||
scope.InScope(symbol) &&
|
||||
!OnlyScaffold;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the locations of the symbol that are either
|
||||
@@ -621,6 +631,10 @@ namespace Semmle.Extraction.CSharp
|
||||
/// <param name="l">Location of the entity.</param>
|
||||
public void BindComments(Entity entity, Microsoft.CodeAnalysis.Location? l)
|
||||
{
|
||||
if (OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var duplicationGuardKey = GetCurrentTagStackKey();
|
||||
CommentGenerator.AddElement(entity.Label, duplicationGuardKey, l);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
public interface IOverlayInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// True, if the extractor is running in overlay mode.
|
||||
/// </summary>
|
||||
bool IsOverlayMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true, if the given file is not in the set of changed files.
|
||||
/// </summary>
|
||||
/// <param name="filePath">A source file path</param>
|
||||
bool OnlyMakeScaffold(string filePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// An instance of this class is used when overlay is not enabled.
|
||||
/// </summary>
|
||||
public class TrivialOverlayInfo : IOverlayInfo
|
||||
{
|
||||
public TrivialOverlayInfo() { }
|
||||
|
||||
public bool IsOverlayMode { get; } = false;
|
||||
|
||||
public bool OnlyMakeScaffold(string filePath) => false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An instance of this class is used for detecting
|
||||
/// (1) Whether overlay is enabled.
|
||||
/// (2) Fetch the changed files that should be fully extracted as a part
|
||||
/// of the overlay extraction.
|
||||
/// </summary>
|
||||
public class OverlayInfo : IOverlayInfo
|
||||
{
|
||||
private readonly ILogger logger;
|
||||
private readonly HashSet<string> changedFiles;
|
||||
private readonly string srcDir;
|
||||
|
||||
public OverlayInfo(ILogger logger, string srcDir, string json)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.srcDir = srcDir;
|
||||
changedFiles = ParseJson(json);
|
||||
}
|
||||
|
||||
public bool IsOverlayMode { get; } = true;
|
||||
|
||||
public bool OnlyMakeScaffold(string filePath) => !changedFiles.Contains(filePath);
|
||||
|
||||
/// <summary>
|
||||
/// Private type only used to parse overlay changes JSON files.
|
||||
///
|
||||
/// The content of such a file has the format
|
||||
/// {
|
||||
/// "changes": [
|
||||
/// "app/controllers/about_controller.xyz",
|
||||
/// "app/models/about.xyz"
|
||||
/// ]
|
||||
/// }
|
||||
/// </summary>
|
||||
private record ChangedFiles
|
||||
{
|
||||
public string[]? Changes { get; set; }
|
||||
}
|
||||
|
||||
private HashSet<string> ParseJson(string json)
|
||||
{
|
||||
try
|
||||
{
|
||||
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
||||
var obj = JsonSerializer.Deserialize<ChangedFiles>(json, options);
|
||||
return obj?.Changes is string[] changes
|
||||
? changes.Select(change => Path.Join(srcDir, change)).ToHashSet()
|
||||
: [];
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
logger.LogError("Overlay: Unable to parse the JSON content from the overlay changes file.");
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class OverlayInfoFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The returned object is used to decide, whether
|
||||
/// (1) The extractor is running in overlay mode.
|
||||
/// (2) Which files to only extract scaffolds for (unchanged files)
|
||||
/// </summary>
|
||||
/// <param name="logger">A logger</param>
|
||||
/// <param name="srcDir">The (overlay) source directory</param>
|
||||
/// <returns>An overlay information object.</returns>
|
||||
public static IOverlayInfo Make(ILogger logger, string srcDir)
|
||||
{
|
||||
if (EnvironmentVariables.GetOverlayChangesFilePath() is string path)
|
||||
{
|
||||
logger.LogInfo($"Overlay: Reading overlay changes from file '{path}'.");
|
||||
try
|
||||
{
|
||||
var json = File.ReadAllText(path);
|
||||
return new OverlayInfo(logger, srcDir, json);
|
||||
}
|
||||
catch
|
||||
{
|
||||
logger.LogError("Overlay: Unexpected error while reading the overlay changes file.");
|
||||
}
|
||||
}
|
||||
|
||||
logger.LogInfo("Overlay: Overlay mode not enabled.");
|
||||
return new TrivialOverlayInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,8 @@ namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
public class StandaloneAnalyser : Analyser
|
||||
{
|
||||
public StandaloneAnalyser(IProgressMonitor pm, ILogger logger, PathTransformer pathTransformer, IPathCache pathCache, bool addAssemblyTrapPrefix)
|
||||
: base(pm, logger, pathTransformer, pathCache, addAssemblyTrapPrefix)
|
||||
public StandaloneAnalyser(IProgressMonitor pm, ILogger logger, PathTransformer pathTransformer, IPathCache pathCache, IOverlayInfo overlayInfo, bool addAssemblyTrapPrefix)
|
||||
: base(pm, logger, pathTransformer, pathCache, overlayInfo, addAssemblyTrapPrefix)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Semmle.Extraction.CSharp
|
||||
private bool init;
|
||||
|
||||
public TracingAnalyser(IProgressMonitor pm, ILogger logger, PathTransformer pathTransformer, IPathCache pathCache, bool addAssemblyTrapPrefix)
|
||||
: base(pm, logger, pathTransformer, pathCache, addAssemblyTrapPrefix)
|
||||
: base(pm, logger, pathTransformer, pathCache, new TrivialOverlayInfo(), addAssemblyTrapPrefix)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@ namespace Semmle.Extraction.CSharp.Populators
|
||||
{
|
||||
public static void ExtractCommentBlocks(Context cx, CommentProcessor gen)
|
||||
{
|
||||
if (cx.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
cx.Try(null, null, () =>
|
||||
{
|
||||
gen.GenerateBindings((entity, duplicationGuardKey, block, binding) =>
|
||||
@@ -34,6 +38,10 @@ namespace Semmle.Extraction.CSharp.Populators
|
||||
|
||||
public static void ExtractComment(Context cx, SyntaxTrivia trivia)
|
||||
{
|
||||
if (cx.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (trivia.Kind())
|
||||
{
|
||||
case SyntaxKind.SingleLineDocumentationCommentTrivia:
|
||||
|
||||
31
csharp/extractor/Semmle.Extraction.Tests/OverlayInfo.cs
Normal file
31
csharp/extractor/Semmle.Extraction.Tests/OverlayInfo.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Xunit;
|
||||
using Semmle.Extraction.CSharp;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.Tests
|
||||
{
|
||||
public class OverlayTests
|
||||
{
|
||||
[Fact]
|
||||
public void TestOverlay()
|
||||
{
|
||||
var logger = new LoggerStub();
|
||||
var json =
|
||||
"""
|
||||
{
|
||||
"changes": [
|
||||
"app/controllers/about_controller.xyz",
|
||||
"app/models/about.xyz"
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
var overlay = new OverlayInfo(logger, "overlay/source/path", json);
|
||||
|
||||
Assert.True(overlay.IsOverlayMode);
|
||||
Assert.False(overlay.OnlyMakeScaffold("overlay/source/path" + Path.DirectorySeparatorChar + "app/controllers/about_controller.xyz"));
|
||||
Assert.False(overlay.OnlyMakeScaffold("overlay/source/path" + Path.DirectorySeparatorChar + "app/models/about.xyz"));
|
||||
Assert.True(overlay.OnlyMakeScaffold("overlay/source/path" + Path.DirectorySeparatorChar + "app/models/unchanged.xyz"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,5 +53,28 @@ namespace Semmle.Util
|
||||
{
|
||||
return Environment.GetEnvironmentVariable(name)?.Split(" ", StringSplitOptions.RemoveEmptyEntries) ?? [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to
|
||||
/// (1) Detect whether the extractor should run in overlay mode.
|
||||
/// (2) Returns the path to the file containing a list of changed files
|
||||
/// in JSON format.
|
||||
///
|
||||
/// The environment variable is only set in case the extraction is supposed to be
|
||||
/// performed in overlay mode. Furthermore, this only applies to buildless extraction.
|
||||
/// </summary>
|
||||
public static string? GetOverlayChangesFilePath()
|
||||
{
|
||||
return Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OVERLAY_CHANGES");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the environment variable is set, the extractor is being called to extract a base database.
|
||||
/// Its value will be a path, and the extractor must create either a file or directory at that location.
|
||||
/// </summary>
|
||||
public static string? GetBaseMetaDataOutPath()
|
||||
{
|
||||
return Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OVERLAY_BASE_METADATA_OUT");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
|
||||
* Initial support for incremental C# databases via `codeql database create --overlay-base`/`--overlay-changes`.
|
||||
@@ -36,6 +36,7 @@ import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
import semmle.code.csharp.dataflow.DataFlow
|
||||
import semmle.code.csharp.dataflow.TaintTracking
|
||||
import semmle.code.csharp.dataflow.SSA
|
||||
private import semmle.code.csharp.internal.Overlay
|
||||
|
||||
/** Whether the source was extracted without a build command. */
|
||||
predicate extractionIsStandalone() { exists(SourceFile f | f.extractedStandalone()) }
|
||||
|
||||
@@ -18,3 +18,4 @@ dataExtensions:
|
||||
- ext/*.model.yml
|
||||
- ext/generated/*.model.yml
|
||||
warnOnImplicitThis: true
|
||||
compileForOverlayEval: true
|
||||
|
||||
@@ -719,6 +719,15 @@ private Type convTypeParameterBase(TypeParameter tp) {
|
||||
result = getATypeParameterFromConstraints+(tp)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Class typeConstraintToBaseType(TypeParameterConstraints tpc) {
|
||||
tpc.hasValueTypeConstraint() and result instanceof SystemValueTypeClass
|
||||
or
|
||||
result = tpc.getATypeConstraint()
|
||||
or
|
||||
tpc.hasRefTypeConstraint() and result instanceof ObjectType
|
||||
}
|
||||
|
||||
/**
|
||||
* 10.1.5: Candidates for the effective base class of type parameter `tp`.
|
||||
*
|
||||
@@ -731,13 +740,9 @@ private Class effectiveBaseClassCandidate(TypeParameter tp) {
|
||||
not hasPrimaryConstraints(tp) and result instanceof ObjectType
|
||||
or
|
||||
exists(TypeParameterConstraints tpc | tpc = tp.getConstraints() |
|
||||
tpc.hasValueTypeConstraint() and result instanceof SystemValueTypeClass
|
||||
or
|
||||
result = tpc.getATypeConstraint()
|
||||
result = typeConstraintToBaseType(tpc)
|
||||
or
|
||||
result = effectiveBaseClassCandidate(tpc.getATypeConstraint())
|
||||
or
|
||||
tpc.hasRefTypeConstraint() and result instanceof ObjectType
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
166
csharp/ql/lib/semmle/code/csharp/internal/Overlay.qll
Normal file
166
csharp/ql/lib/semmle/code/csharp/internal/Overlay.qll
Normal file
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Defines entity discard predicates for C# overlay analysis.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Holds always for the overlay variant and never for the base variant.
|
||||
* This local predicate is used to define local predicates that behave
|
||||
* differently for the base and overlay variant.
|
||||
*/
|
||||
overlay[local]
|
||||
predicate isOverlay() { databaseMetadata("isOverlay", "true") }
|
||||
|
||||
overlay[local]
|
||||
private string getLocationFilePath(@location_default loc) {
|
||||
exists(@file file | locations_default(loc, file, _, _, _, _) | files(file, result))
|
||||
}
|
||||
|
||||
overlay[local]
|
||||
private class DiscardableEntityBase extends @locatable {
|
||||
/** Gets the path to the file in which this element occurs. */
|
||||
abstract string getFilePath();
|
||||
|
||||
/** Holds if this element exists in the base variant. */
|
||||
predicate existsInBase() { not isOverlay() }
|
||||
|
||||
/** Holds if this element exists in the overlay variant. */
|
||||
predicate existsInOverlay() { isOverlay() }
|
||||
|
||||
/** Gets a textual representation of this discardable element. */
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A class of elements that can be discarded from the base.
|
||||
*/
|
||||
overlay[local]
|
||||
private class DiscardableEntity extends DiscardableEntityBase {
|
||||
/** Gets the path to the file in which this element occurs. */
|
||||
override string getFilePath() {
|
||||
exists(@location_default loc | result = getLocationFilePath(loc) |
|
||||
expr_location(this, loc) or
|
||||
stmt_location(this, loc) or
|
||||
using_directive_location(this, loc) or
|
||||
namespace_declaration_location(this, loc) or
|
||||
preprocessor_directive_location(this, loc) or
|
||||
type_location(this, loc) or
|
||||
attribute_location(this, loc) or
|
||||
type_parameter_constraints_location(this, loc) or
|
||||
property_location(this, loc) or
|
||||
indexer_location(this, loc) or
|
||||
accessor_location(this, loc) or
|
||||
event_location(this, loc) or
|
||||
event_accessor_location(this, loc) or
|
||||
operator_location(this, loc) or
|
||||
method_location(this, loc) or
|
||||
constructor_location(this, loc) or
|
||||
destructor_location(this, loc) or
|
||||
field_location(this, loc) or
|
||||
localvar_location(this, loc) or
|
||||
param_location(this, loc) or
|
||||
type_mention_location(this, loc) or
|
||||
commentline_location(this, loc) or
|
||||
commentblock_location(this, loc) or
|
||||
diagnostics(this, _, _, _, _, loc) or
|
||||
extractor_messages(this, _, _, _, _, loc, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class of C# database entities that use `*` IDs.
|
||||
* The rest use named TRAP IDs.
|
||||
*/
|
||||
overlay[local]
|
||||
private class StarEntity =
|
||||
@expr or @stmt or @diagnostic or @extractor_message or @using_directive or @type_mention or
|
||||
@local_variable;
|
||||
|
||||
overlay[discard_entity]
|
||||
private predicate discardStarEntity(@locatable e) {
|
||||
e instanceof StarEntity and
|
||||
// Entities with *-ids can exist either in base or overlay, but not both.
|
||||
e =
|
||||
any(DiscardableEntity de |
|
||||
overlayChangedFiles(de.getFilePath()) and
|
||||
de.existsInBase()
|
||||
)
|
||||
}
|
||||
|
||||
overlay[discard_entity]
|
||||
private predicate discardNamedEntity(@locatable e) {
|
||||
not e instanceof StarEntity and
|
||||
// Entities with named IDs can exist both in base, overlay, or both.
|
||||
e =
|
||||
any(DiscardableEntity de |
|
||||
overlayChangedFiles(de.getFilePath()) and
|
||||
not de.existsInOverlay()
|
||||
)
|
||||
}
|
||||
|
||||
overlay[local]
|
||||
private predicate discardableLocation(@location_default loc, string path) {
|
||||
not isOverlay() and
|
||||
path = getLocationFilePath(loc)
|
||||
}
|
||||
|
||||
// Discard locations that are in changed files from the base variant.
|
||||
overlay[discard_entity]
|
||||
private predicate discardLocation(@location_default loc) {
|
||||
exists(string path | discardableLocation(loc, path) | overlayChangedFiles(path))
|
||||
}
|
||||
|
||||
/**
|
||||
* A class of Xml locatables that can be discarded from the base.
|
||||
*/
|
||||
overlay[local]
|
||||
private class DiscardableXmlEntity extends DiscardableEntityBase instanceof @xmllocatable {
|
||||
/** Gets the path to the file in which this element occurs. */
|
||||
override string getFilePath() {
|
||||
exists(@location_default loc | result = getLocationFilePath(loc) | xmllocations(this, loc))
|
||||
}
|
||||
}
|
||||
|
||||
overlay[local]
|
||||
private predicate overlayXmlExtracted(string file) {
|
||||
exists(DiscardableXmlEntity dxe |
|
||||
dxe.existsInOverlay() and
|
||||
file = dxe.getFilePath() and
|
||||
not files(dxe, _) and
|
||||
not xmlNs(dxe, _, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
overlay[discard_entity]
|
||||
private predicate discardXmlEntity(@xmllocatable xml) {
|
||||
overlayChangedFiles(xml.(DiscardableXmlEntity).getFilePath())
|
||||
or
|
||||
// The XML extractor is not incremental and may extract more
|
||||
// XML files than those included in overlayChangedFiles.
|
||||
overlayXmlExtracted(xml.(DiscardableXmlEntity).getFilePath())
|
||||
}
|
||||
|
||||
overlay[local]
|
||||
private class DiscardableAspEntity extends DiscardableEntityBase instanceof @asp_element {
|
||||
/** Gets the path to the file in which this element occurs. */
|
||||
override string getFilePath() {
|
||||
exists(@location_default loc | result = getLocationFilePath(loc) | asp_elements(this, _, loc))
|
||||
}
|
||||
}
|
||||
|
||||
overlay[local]
|
||||
private predicate overlayAspExtracted(string file) {
|
||||
exists(DiscardableAspEntity dae |
|
||||
dae.existsInOverlay() and
|
||||
file = dae.getFilePath()
|
||||
)
|
||||
}
|
||||
|
||||
overlay[discard_entity]
|
||||
private predicate discardAspEntity(@asp_element asp) {
|
||||
overlayChangedFiles(asp.(DiscardableAspEntity).getFilePath())
|
||||
or
|
||||
// The ASP extractor is not incremental and may extract more
|
||||
// ASP files than those included in overlayChangedFiles.
|
||||
overlayAspExtracted(asp.(DiscardableAspEntity).getFilePath())
|
||||
}
|
||||
@@ -194,6 +194,24 @@ externalData(
|
||||
sourceLocationPrefix(
|
||||
string prefix: string ref);
|
||||
|
||||
/*
|
||||
* Overlay support
|
||||
*/
|
||||
|
||||
/**
|
||||
* The CLI will automatically emit the tuple `databaseMetadata("isOverlay", "true")`,
|
||||
* along with an `overlayChangedFiles` tuple for each new/modified/deleted file,
|
||||
* when building an overlay database, and these can be used by the discard predicates.
|
||||
*/
|
||||
databaseMetadata(
|
||||
string metadataKey : string ref,
|
||||
string value : string ref
|
||||
);
|
||||
|
||||
overlayChangedFiles(
|
||||
string path : string ref
|
||||
);
|
||||
|
||||
/*
|
||||
* C# dbscheme
|
||||
*/
|
||||
@@ -222,6 +240,12 @@ sourceLocationPrefix(
|
||||
|
||||
@location = @location_default | @assembly;
|
||||
|
||||
@locatable = @declaration_with_accessors | @callable_accessor | @declaration_or_directive
|
||||
| @diagnostic | @extractor_message | @preprocessor_directive | @attribute | @type_mention | @type_parameter_constraints
|
||||
| @declaration_with_accessors | @callable_accessor | @operator | @method
|
||||
| @constructor | @destructor | @field | @local_variable | @parameter | @stmt | @expr
|
||||
| @xmllocatable | @commentline | @commentblock | @asp_element
|
||||
|
||||
locations_default(
|
||||
unique int id: @location_default,
|
||||
int file: @file ref,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add @locatable type
|
||||
compatibility: full
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add databaseMetadata and overlayChangedFiles relations
|
||||
compatibility: full
|
||||
@@ -1234,9 +1234,9 @@ StaticInterfaceMembers.cs:
|
||||
# 49| 1: [PropertyCall] access to property Real
|
||||
# 49| -1: [ParameterAccess] access to parameter n
|
||||
# 51| 14: [Method] Inc
|
||||
# 51| -1: [TypeMention] Complex
|
||||
# 51| -1: [TypeMention] INumber<Complex>
|
||||
# 51| 1: [TypeMention] Complex
|
||||
# 51| -1: [TypeMention] Complex
|
||||
#-----| 2: (Parameters)
|
||||
# 51| 0: [Parameter] other
|
||||
# 51| -1: [TypeMention] Complex
|
||||
@@ -1254,9 +1254,9 @@ StaticInterfaceMembers.cs:
|
||||
# 52| 1: [PropertyCall] access to property Imaginary
|
||||
# 52| -1: [ParameterAccess] access to parameter other
|
||||
# 54| 15: [Method] Dec
|
||||
# 54| -1: [TypeMention] Complex
|
||||
# 54| -1: [TypeMention] INumber<Complex>
|
||||
# 54| 1: [TypeMention] Complex
|
||||
# 54| -1: [TypeMention] Complex
|
||||
#-----| 2: (Parameters)
|
||||
# 54| 0: [Parameter] other
|
||||
# 54| -1: [TypeMention] Complex
|
||||
|
||||
@@ -272,8 +272,8 @@ definitions.cs:
|
||||
# 125| 0: [MethodCall] call to method M
|
||||
# 125| -1: [BaseAccess] base access
|
||||
# 128| 6: [Method] M2`1
|
||||
# 128| -1: [TypeMention] Void
|
||||
# 128| -1: [TypeMention] I1
|
||||
# 128| -1: [TypeMention] Void
|
||||
#-----| 1: (Type parameters)
|
||||
# 128| 0: [TypeParameter] T
|
||||
# 128| 4: [BlockStmt] {...}
|
||||
@@ -356,8 +356,8 @@ definitions.cs:
|
||||
# 153| 0: [Parameter] value
|
||||
# 153| 4: [BlockStmt] {...}
|
||||
# 154| 6: [Method] M
|
||||
# 154| -1: [TypeMention] A
|
||||
# 154| -1: [TypeMention] I4
|
||||
# 154| -1: [TypeMention] A
|
||||
# 154| 4: [ThrowExpr] throw ...
|
||||
# 154| 0: [ObjectCreation] object creation of type Exception
|
||||
# 154| 0: [TypeMention] Exception
|
||||
|
||||
66
csharp/ql/test/library-tests/overlay/base/A.cs
Normal file
66
csharp/ql/test/library-tests/overlay/base/A.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
|
||||
namespace ConsoleApp1
|
||||
{
|
||||
public class A
|
||||
{
|
||||
private string name;
|
||||
public A(string x)
|
||||
{
|
||||
name = x;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
~A()
|
||||
{
|
||||
Console.WriteLine("Destructor called!");
|
||||
}
|
||||
|
||||
public string Prop { get; set; } = "Hello";
|
||||
|
||||
public object this[int i]
|
||||
{
|
||||
get { return new object(); }
|
||||
set { }
|
||||
}
|
||||
|
||||
/*
|
||||
* An example event
|
||||
*/
|
||||
public event EventHandler Clicked
|
||||
{
|
||||
add
|
||||
{
|
||||
Console.WriteLine("Handler added");
|
||||
}
|
||||
remove
|
||||
{
|
||||
Console.WriteLine("Handler removed");
|
||||
}
|
||||
}
|
||||
|
||||
public static A operator +(A a, A b)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
[MyObsolete]
|
||||
public void ObsoleteMethod() { }
|
||||
|
||||
public int OldMethod(int x)
|
||||
{
|
||||
var y = x + 1;
|
||||
return y;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var x = $"A: {name}";
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
public class MyObsoleteAttribute : Attribute { }
|
||||
|
||||
public class B { }
|
||||
}
|
||||
65
csharp/ql/test/library-tests/overlay/base/Program.cs
Normal file
65
csharp/ql/test/library-tests/overlay/base/Program.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
|
||||
namespace ConsoleApp1
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
if (args.Length == 0)
|
||||
{
|
||||
Console.WriteLine("Print usage instructions here.");
|
||||
return;
|
||||
}
|
||||
var x = args[0];
|
||||
var a = new A(x);
|
||||
Console.WriteLine(a.ToString());
|
||||
}
|
||||
|
||||
private string programName;
|
||||
|
||||
public Program(string x)
|
||||
{
|
||||
programName = x;
|
||||
}
|
||||
|
||||
// Program destructor
|
||||
~Program()
|
||||
{
|
||||
Console.WriteLine("Program destructor called!");
|
||||
}
|
||||
|
||||
public string ProgramProp { get; set; } = "Hello World!";
|
||||
|
||||
public string this[int i]
|
||||
{
|
||||
get { return string.Empty; }
|
||||
set { }
|
||||
}
|
||||
|
||||
/*
|
||||
* A program event.
|
||||
*/
|
||||
public event EventHandler ProgramClicked
|
||||
{
|
||||
add
|
||||
{
|
||||
Console.WriteLine("Program handler added");
|
||||
}
|
||||
remove
|
||||
{
|
||||
Console.WriteLine("Program handler removed");
|
||||
}
|
||||
}
|
||||
|
||||
public static Program operator -(Program a, Program b)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
[Program]
|
||||
public void AnnotatedMethod() { }
|
||||
}
|
||||
|
||||
public class ProgramAttribute : Attribute { }
|
||||
}
|
||||
1
csharp/ql/test/library-tests/overlay/base/options
Normal file
1
csharp/ql/test/library-tests/overlay/base/options
Normal file
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --standalone
|
||||
276
csharp/ql/test/library-tests/overlay/base/test.expected
Normal file
276
csharp/ql/test/library-tests/overlay/base/test.expected
Normal file
@@ -0,0 +1,276 @@
|
||||
expressions
|
||||
| A.cs:8:16:8:16 | call to constructor Object |
|
||||
| A.cs:10:13:10:16 | access to field name |
|
||||
| A.cs:10:13:10:16 | this access |
|
||||
| A.cs:10:13:10:20 | ... = ... |
|
||||
| A.cs:10:20:10:20 | access to parameter x |
|
||||
| A.cs:16:13:16:19 | access to type Console |
|
||||
| A.cs:16:13:16:51 | call to method WriteLine |
|
||||
| A.cs:16:31:16:50 | "Destructor called!" |
|
||||
| A.cs:19:23:19:26 | access to property Prop |
|
||||
| A.cs:19:23:19:26 | this access |
|
||||
| A.cs:19:42:19:50 | ... = ... |
|
||||
| A.cs:19:44:19:50 | "Hello" |
|
||||
| A.cs:23:26:23:37 | object creation of type Object |
|
||||
| A.cs:34:17:34:23 | access to type Console |
|
||||
| A.cs:34:17:34:50 | call to method WriteLine |
|
||||
| A.cs:34:35:34:49 | "Handler added" |
|
||||
| A.cs:38:17:38:23 | access to type Console |
|
||||
| A.cs:38:17:38:52 | call to method WriteLine |
|
||||
| A.cs:38:35:38:51 | "Handler removed" |
|
||||
| A.cs:44:20:44:20 | access to parameter a |
|
||||
| A.cs:52:17:52:17 | access to local variable y |
|
||||
| A.cs:52:17:52:25 | Int32 y = ... |
|
||||
| A.cs:52:21:52:21 | access to parameter x |
|
||||
| A.cs:52:21:52:25 | ... + ... |
|
||||
| A.cs:52:25:52:25 | 1 |
|
||||
| A.cs:53:20:53:20 | access to local variable y |
|
||||
| A.cs:58:17:58:17 | access to local variable x |
|
||||
| A.cs:58:17:58:32 | String x = ... |
|
||||
| A.cs:58:21:58:32 | $"..." |
|
||||
| A.cs:58:23:58:25 | "A: " |
|
||||
| A.cs:58:26:58:31 | {...} |
|
||||
| A.cs:58:27:58:30 | access to field name |
|
||||
| A.cs:58:27:58:30 | this access |
|
||||
| A.cs:59:20:59:20 | access to local variable x |
|
||||
| A.cs:63:18:63:36 | call to constructor Attribute |
|
||||
| A.cs:65:18:65:18 | call to constructor Object |
|
||||
| Program.cs:9:17:9:20 | access to parameter args |
|
||||
| Program.cs:9:17:9:27 | access to property Length |
|
||||
| Program.cs:9:17:9:32 | ... == ... |
|
||||
| Program.cs:9:32:9:32 | 0 |
|
||||
| Program.cs:11:17:11:23 | access to type Console |
|
||||
| Program.cs:11:17:11:67 | call to method WriteLine |
|
||||
| Program.cs:11:35:11:66 | "Print usage instructions here." |
|
||||
| Program.cs:14:17:14:17 | access to local variable x |
|
||||
| Program.cs:14:17:14:27 | String x = ... |
|
||||
| Program.cs:14:21:14:24 | access to parameter args |
|
||||
| Program.cs:14:21:14:27 | access to array element |
|
||||
| Program.cs:14:26:14:26 | 0 |
|
||||
| Program.cs:15:17:15:17 | access to local variable a |
|
||||
| Program.cs:15:17:15:28 | A a = ... |
|
||||
| Program.cs:15:21:15:28 | object creation of type A |
|
||||
| Program.cs:15:27:15:27 | access to local variable x |
|
||||
| Program.cs:16:13:16:19 | access to type Console |
|
||||
| Program.cs:16:13:16:43 | call to method WriteLine |
|
||||
| Program.cs:16:31:16:31 | access to local variable a |
|
||||
| Program.cs:16:31:16:42 | call to method ToString |
|
||||
| Program.cs:21:16:21:22 | call to constructor Object |
|
||||
| Program.cs:23:13:23:23 | access to field programName |
|
||||
| Program.cs:23:13:23:23 | this access |
|
||||
| Program.cs:23:13:23:27 | ... = ... |
|
||||
| Program.cs:23:27:23:27 | access to parameter x |
|
||||
| Program.cs:29:13:29:19 | access to type Console |
|
||||
| Program.cs:29:13:29:59 | call to method WriteLine |
|
||||
| Program.cs:29:31:29:58 | "Program destructor called!" |
|
||||
| Program.cs:32:23:32:33 | access to property ProgramProp |
|
||||
| Program.cs:32:23:32:33 | this access |
|
||||
| Program.cs:32:49:32:64 | ... = ... |
|
||||
| Program.cs:32:51:32:64 | "Hello World!" |
|
||||
| Program.cs:36:26:36:31 | access to type String |
|
||||
| Program.cs:36:26:36:37 | access to field Empty |
|
||||
| Program.cs:47:17:47:23 | access to type Console |
|
||||
| Program.cs:47:17:47:58 | call to method WriteLine |
|
||||
| Program.cs:47:35:47:57 | "Program handler added" |
|
||||
| Program.cs:51:17:51:23 | access to type Console |
|
||||
| Program.cs:51:17:51:60 | call to method WriteLine |
|
||||
| Program.cs:51:35:51:59 | "Program handler removed" |
|
||||
| Program.cs:57:20:57:20 | access to parameter b |
|
||||
| Program.cs:64:18:64:33 | call to constructor Attribute |
|
||||
statements
|
||||
| A.cs:9:9:11:9 | {...} |
|
||||
| A.cs:10:13:10:21 | ...; |
|
||||
| A.cs:15:9:17:9 | {...} |
|
||||
| A.cs:16:13:16:52 | ...; |
|
||||
| A.cs:23:17:23:40 | {...} |
|
||||
| A.cs:23:19:23:38 | return ...; |
|
||||
| A.cs:24:17:24:19 | {...} |
|
||||
| A.cs:33:13:35:13 | {...} |
|
||||
| A.cs:34:17:34:51 | ...; |
|
||||
| A.cs:37:13:39:13 | {...} |
|
||||
| A.cs:38:17:38:53 | ...; |
|
||||
| A.cs:43:9:45:9 | {...} |
|
||||
| A.cs:44:13:44:21 | return ...; |
|
||||
| A.cs:48:38:48:40 | {...} |
|
||||
| A.cs:51:9:54:9 | {...} |
|
||||
| A.cs:52:13:52:26 | ... ...; |
|
||||
| A.cs:53:13:53:21 | return ...; |
|
||||
| A.cs:57:9:60:9 | {...} |
|
||||
| A.cs:58:13:58:33 | ... ...; |
|
||||
| A.cs:59:13:59:21 | return ...; |
|
||||
| A.cs:63:18:63:36 | {...} |
|
||||
| A.cs:65:18:65:18 | {...} |
|
||||
| Program.cs:8:9:17:9 | {...} |
|
||||
| Program.cs:9:13:13:13 | if (...) ... |
|
||||
| Program.cs:10:13:13:13 | {...} |
|
||||
| Program.cs:11:17:11:68 | ...; |
|
||||
| Program.cs:12:17:12:23 | return ...; |
|
||||
| Program.cs:14:13:14:28 | ... ...; |
|
||||
| Program.cs:15:13:15:29 | ... ...; |
|
||||
| Program.cs:16:13:16:44 | ...; |
|
||||
| Program.cs:22:9:24:9 | {...} |
|
||||
| Program.cs:23:13:23:28 | ...; |
|
||||
| Program.cs:28:9:30:9 | {...} |
|
||||
| Program.cs:29:13:29:60 | ...; |
|
||||
| Program.cs:36:17:36:40 | {...} |
|
||||
| Program.cs:36:19:36:38 | return ...; |
|
||||
| Program.cs:37:17:37:19 | {...} |
|
||||
| Program.cs:46:13:48:13 | {...} |
|
||||
| Program.cs:47:17:47:59 | ...; |
|
||||
| Program.cs:50:13:52:13 | {...} |
|
||||
| Program.cs:51:17:51:61 | ...; |
|
||||
| Program.cs:56:9:58:9 | {...} |
|
||||
| Program.cs:57:13:57:21 | return ...; |
|
||||
| Program.cs:61:39:61:41 | {...} |
|
||||
| Program.cs:64:18:64:33 | {...} |
|
||||
methods
|
||||
| A.cs:48:21:48:34 | ObsoleteMethod |
|
||||
| A.cs:50:20:50:28 | OldMethod |
|
||||
| A.cs:56:32:56:39 | ToString |
|
||||
| Program.cs:7:28:7:31 | Main |
|
||||
| Program.cs:61:21:61:35 | AnnotatedMethod |
|
||||
types
|
||||
| A.cs:5:18:5:18 | A |
|
||||
| A.cs:63:18:63:36 | MyObsoleteAttribute |
|
||||
| A.cs:65:18:65:18 | B |
|
||||
| Program.cs:5:20:5:26 | Program |
|
||||
| Program.cs:64:18:64:33 | ProgramAttribute |
|
||||
parameters
|
||||
| A.cs:8:25:8:25 | x |
|
||||
| A.cs:19:35:19:37 | value |
|
||||
| A.cs:21:32:21:32 | i |
|
||||
| A.cs:21:32:21:32 | i |
|
||||
| A.cs:21:32:21:32 | i |
|
||||
| A.cs:24:13:24:15 | value |
|
||||
| A.cs:32:13:32:15 | value |
|
||||
| A.cs:36:13:36:18 | value |
|
||||
| A.cs:42:38:42:38 | a |
|
||||
| A.cs:42:43:42:43 | b |
|
||||
| A.cs:50:34:50:34 | x |
|
||||
| Program.cs:7:42:7:45 | args |
|
||||
| Program.cs:21:31:21:31 | x |
|
||||
| Program.cs:32:42:32:44 | value |
|
||||
| Program.cs:34:32:34:32 | i |
|
||||
| Program.cs:34:32:34:32 | i |
|
||||
| Program.cs:34:32:34:32 | i |
|
||||
| Program.cs:37:13:37:15 | value |
|
||||
| Program.cs:45:13:45:15 | value |
|
||||
| Program.cs:49:13:49:18 | value |
|
||||
| Program.cs:55:50:55:50 | a |
|
||||
| Program.cs:55:61:55:61 | b |
|
||||
operators
|
||||
| A.cs:42:34:42:34 | + |
|
||||
| Program.cs:55:40:55:40 | - |
|
||||
constructors
|
||||
| A.cs:8:16:8:16 | A |
|
||||
| Program.cs:21:16:21:22 | Program |
|
||||
destructors
|
||||
| A.cs:14:10:14:10 | ~A |
|
||||
| Program.cs:27:10:27:16 | ~Program |
|
||||
fields
|
||||
| A.cs:7:24:7:27 | name |
|
||||
| Program.cs:19:24:19:34 | programName |
|
||||
properties
|
||||
| A.cs:19:23:19:26 | Prop |
|
||||
| Program.cs:32:23:32:33 | ProgramProp |
|
||||
indexers
|
||||
| A.cs:21:23:21:26 | Item |
|
||||
| Program.cs:34:23:34:26 | Item |
|
||||
accessors
|
||||
| A.cs:19:30:19:32 | get_Prop |
|
||||
| A.cs:19:35:19:37 | set_Prop |
|
||||
| A.cs:23:13:23:15 | get_Item |
|
||||
| A.cs:24:13:24:15 | set_Item |
|
||||
| A.cs:32:13:32:15 | add_Clicked |
|
||||
| A.cs:36:13:36:18 | remove_Clicked |
|
||||
| Program.cs:32:37:32:39 | get_ProgramProp |
|
||||
| Program.cs:32:42:32:44 | set_ProgramProp |
|
||||
| Program.cs:36:13:36:15 | get_Item |
|
||||
| Program.cs:37:13:37:15 | set_Item |
|
||||
| Program.cs:45:13:45:15 | add_ProgramClicked |
|
||||
| Program.cs:49:13:49:18 | remove_ProgramClicked |
|
||||
attributes
|
||||
| A.cs:47:10:47:19 | [MyObsolete(...)] |
|
||||
| Program.cs:60:10:60:16 | [Program(...)] |
|
||||
events
|
||||
| A.cs:30:35:30:41 | Clicked |
|
||||
| Program.cs:43:35:43:48 | ProgramClicked |
|
||||
eventAccessors
|
||||
| A.cs:32:13:32:15 | add_Clicked |
|
||||
| A.cs:36:13:36:18 | remove_Clicked |
|
||||
| Program.cs:45:13:45:15 | add_ProgramClicked |
|
||||
| Program.cs:49:13:49:18 | remove_ProgramClicked |
|
||||
usingDirectives
|
||||
| A.cs:1:1:1:13 | using ...; |
|
||||
| Program.cs:1:1:1:13 | using ...; |
|
||||
commentLines
|
||||
| A.cs:13:9:13:21 | // ... |
|
||||
| A.cs:27:9:27:10 | /* ... */ |
|
||||
| A.cs:28:1:28:27 | /* ... */ |
|
||||
| A.cs:29:1:29:11 | /* ... */ |
|
||||
| Program.cs:26:9:26:29 | // ... |
|
||||
| Program.cs:40:9:40:10 | /* ... */ |
|
||||
| Program.cs:41:1:41:27 | /* ... */ |
|
||||
| Program.cs:42:1:42:11 | /* ... */ |
|
||||
commentBlocks
|
||||
| A.cs:13:9:13:21 | // ... |
|
||||
| A.cs:27:9:29:11 | /* ... */ |
|
||||
| Program.cs:26:9:26:29 | // ... |
|
||||
| Program.cs:40:9:42:11 | /* ... */ |
|
||||
typeMentions
|
||||
| A.cs:7:17:7:22 | String |
|
||||
| A.cs:8:18:8:23 | String |
|
||||
| A.cs:16:13:16:19 | Console |
|
||||
| A.cs:19:16:19:21 | String |
|
||||
| A.cs:21:16:21:21 | Object |
|
||||
| A.cs:21:28:21:30 | Int32 |
|
||||
| A.cs:23:30:23:35 | Object |
|
||||
| A.cs:34:17:34:23 | Console |
|
||||
| A.cs:38:17:38:23 | Console |
|
||||
| A.cs:42:23:42:23 | A |
|
||||
| A.cs:42:36:42:36 | A |
|
||||
| A.cs:42:41:42:41 | A |
|
||||
| A.cs:47:10:47:19 | MyObsoleteAttribute |
|
||||
| A.cs:48:16:48:19 | Void |
|
||||
| A.cs:50:16:50:18 | Int32 |
|
||||
| A.cs:50:30:50:32 | Int32 |
|
||||
| A.cs:52:13:52:15 | Int32 |
|
||||
| A.cs:56:25:56:30 | String |
|
||||
| A.cs:58:13:58:15 | String |
|
||||
| A.cs:63:40:63:48 | Attribute |
|
||||
| Program.cs:7:23:7:26 | Void |
|
||||
| Program.cs:7:33:7:38 | String |
|
||||
| Program.cs:7:33:7:40 | String[] |
|
||||
| Program.cs:11:17:11:23 | Console |
|
||||
| Program.cs:14:13:14:15 | String |
|
||||
| Program.cs:15:13:15:15 | A |
|
||||
| Program.cs:15:25:15:25 | A |
|
||||
| Program.cs:16:13:16:19 | Console |
|
||||
| Program.cs:19:17:19:22 | String |
|
||||
| Program.cs:21:24:21:29 | String |
|
||||
| Program.cs:29:13:29:19 | Console |
|
||||
| Program.cs:32:16:32:21 | String |
|
||||
| Program.cs:34:16:34:21 | String |
|
||||
| Program.cs:34:28:34:30 | Int32 |
|
||||
| Program.cs:36:26:36:31 | String |
|
||||
| Program.cs:47:17:47:23 | Console |
|
||||
| Program.cs:51:17:51:23 | Console |
|
||||
| Program.cs:55:23:55:29 | Program |
|
||||
| Program.cs:55:42:55:48 | Program |
|
||||
| Program.cs:55:53:55:59 | Program |
|
||||
| Program.cs:60:10:60:16 | ProgramAttribute |
|
||||
| Program.cs:61:16:61:19 | Void |
|
||||
| Program.cs:64:37:64:45 | Attribute |
|
||||
xmlLocatables
|
||||
| web.changed.config:2:1:12:17 | configuration |
|
||||
| web.changed.config:3:3:4:16 | system.web |
|
||||
| web.changed.config:5:3:11:22 | system.webServer |
|
||||
| web.changed.config:6:5:10:20 | httpProtocol |
|
||||
| web.changed.config:7:7:9:23 | customHeaders |
|
||||
| web.changed.config:8:9:8:42 | add |
|
||||
| web.changed.config:8:9:8:42 | name=MyOption |
|
||||
| web.changed.config:8:9:8:42 | value=1 |
|
||||
| web.unchanged.config:2:1:6:17 | configuration |
|
||||
| web.unchanged.config:3:3:5:16 | system.web |
|
||||
| web.unchanged.config:4:5:4:37 | httpCookies |
|
||||
| web.unchanged.config:4:5:4:37 | requireSSL=true |
|
||||
1
csharp/ql/test/library-tests/overlay/base/test.qlref
Normal file
1
csharp/ql/test/library-tests/overlay/base/test.qlref
Normal file
@@ -0,0 +1 @@
|
||||
query: ../test.ql
|
||||
12
csharp/ql/test/library-tests/overlay/base/web.changed.config
Normal file
12
csharp/ql/test/library-tests/overlay/base/web.changed.config
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<httpProtocol>
|
||||
<customHeaders>
|
||||
<add name="MyOption" value="1" />
|
||||
</customHeaders>
|
||||
</httpProtocol>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpCookies requireSSL="true"/>
|
||||
</system.web>
|
||||
</configuration>
|
||||
3
csharp/ql/test/library-tests/overlay/codeql-test.yml
Normal file
3
csharp/ql/test/library-tests/overlay/codeql-test.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
overlay:
|
||||
base: "base/"
|
||||
overlay: "overlay/"
|
||||
1
csharp/ql/test/library-tests/overlay/options
Normal file
1
csharp/ql/test/library-tests/overlay/options
Normal file
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --standalone
|
||||
70
csharp/ql/test/library-tests/overlay/overlay/A.cs
Normal file
70
csharp/ql/test/library-tests/overlay/overlay/A.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
|
||||
namespace ConsoleApp1
|
||||
{
|
||||
public class C { }
|
||||
|
||||
public class A
|
||||
{
|
||||
private string name;
|
||||
public A(string x)
|
||||
{
|
||||
name = x;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
~A()
|
||||
{
|
||||
Console.WriteLine("Destructor called!");
|
||||
}
|
||||
|
||||
public string Prop { get; set; } = "Hello";
|
||||
|
||||
public object this[int i]
|
||||
{
|
||||
get { return new object(); }
|
||||
set { }
|
||||
}
|
||||
|
||||
/*
|
||||
* An example event
|
||||
*/
|
||||
public event EventHandler Clicked
|
||||
{
|
||||
add
|
||||
{
|
||||
Console.WriteLine("Handler added");
|
||||
}
|
||||
remove
|
||||
{
|
||||
Console.WriteLine("Handler removed");
|
||||
}
|
||||
}
|
||||
|
||||
public static A operator +(A a, A b)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
[MyObsolete]
|
||||
public void ObsoleteMethod() { }
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string y;
|
||||
y = $"Name: {name}";
|
||||
return y;
|
||||
}
|
||||
|
||||
public void NewMethod()
|
||||
{
|
||||
if (name.EndsWith("test"))
|
||||
{
|
||||
name = name.ToUpper();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MyObsoleteAttribute : Attribute { }
|
||||
}
|
||||
65
csharp/ql/test/library-tests/overlay/overlay/Program.cs
Normal file
65
csharp/ql/test/library-tests/overlay/overlay/Program.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
|
||||
namespace ConsoleApp1
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
if (args.Length == 0)
|
||||
{
|
||||
Console.WriteLine("Print usage instructions here.");
|
||||
return;
|
||||
}
|
||||
var x = args[0];
|
||||
var a = new A(x);
|
||||
Console.WriteLine(a.ToString());
|
||||
}
|
||||
|
||||
private string programName;
|
||||
|
||||
public Program(string x)
|
||||
{
|
||||
programName = x;
|
||||
}
|
||||
|
||||
// Program destructor
|
||||
~Program()
|
||||
{
|
||||
Console.WriteLine("Program destructor called!");
|
||||
}
|
||||
|
||||
public string ProgramProp { get; set; } = "Hello World!";
|
||||
|
||||
public string this[int i]
|
||||
{
|
||||
get { return string.Empty; }
|
||||
set { }
|
||||
}
|
||||
|
||||
/*
|
||||
* A program event.
|
||||
*/
|
||||
public event EventHandler ProgramClicked
|
||||
{
|
||||
add
|
||||
{
|
||||
Console.WriteLine("Program handler added");
|
||||
}
|
||||
remove
|
||||
{
|
||||
Console.WriteLine("Program handler removed");
|
||||
}
|
||||
}
|
||||
|
||||
public static Program operator -(Program a, Program b)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
[Program]
|
||||
public void AnnotatedMethod() { }
|
||||
}
|
||||
|
||||
public class ProgramAttribute : Attribute { }
|
||||
}
|
||||
1
csharp/ql/test/library-tests/overlay/overlay/options
Normal file
1
csharp/ql/test/library-tests/overlay/overlay/options
Normal file
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --standalone
|
||||
274
csharp/ql/test/library-tests/overlay/overlay/test.expected
Normal file
274
csharp/ql/test/library-tests/overlay/overlay/test.expected
Normal file
@@ -0,0 +1,274 @@
|
||||
expressions
|
||||
| A.cs:5:18:5:18 | call to constructor Object |
|
||||
| A.cs:10:16:10:16 | call to constructor Object |
|
||||
| A.cs:12:13:12:16 | access to field name |
|
||||
| A.cs:12:13:12:16 | this access |
|
||||
| A.cs:12:13:12:20 | ... = ... |
|
||||
| A.cs:12:20:12:20 | access to parameter x |
|
||||
| A.cs:18:13:18:19 | access to type Console |
|
||||
| A.cs:18:13:18:51 | call to method WriteLine |
|
||||
| A.cs:18:31:18:50 | "Destructor called!" |
|
||||
| A.cs:21:23:21:26 | access to property Prop |
|
||||
| A.cs:21:23:21:26 | this access |
|
||||
| A.cs:21:42:21:50 | ... = ... |
|
||||
| A.cs:21:44:21:50 | "Hello" |
|
||||
| A.cs:25:26:25:37 | object creation of type Object |
|
||||
| A.cs:36:17:36:23 | access to type Console |
|
||||
| A.cs:36:17:36:50 | call to method WriteLine |
|
||||
| A.cs:36:35:36:49 | "Handler added" |
|
||||
| A.cs:40:17:40:23 | access to type Console |
|
||||
| A.cs:40:17:40:52 | call to method WriteLine |
|
||||
| A.cs:40:35:40:51 | "Handler removed" |
|
||||
| A.cs:46:20:46:20 | access to parameter a |
|
||||
| A.cs:55:20:55:20 | String y |
|
||||
| A.cs:56:13:56:13 | access to local variable y |
|
||||
| A.cs:56:13:56:31 | ... = ... |
|
||||
| A.cs:56:17:56:31 | $"..." |
|
||||
| A.cs:56:19:56:24 | "Name: " |
|
||||
| A.cs:56:25:56:30 | {...} |
|
||||
| A.cs:56:26:56:29 | access to field name |
|
||||
| A.cs:56:26:56:29 | this access |
|
||||
| A.cs:57:20:57:20 | access to local variable y |
|
||||
| A.cs:62:17:62:20 | access to field name |
|
||||
| A.cs:62:17:62:20 | this access |
|
||||
| A.cs:62:17:62:37 | call to method EndsWith |
|
||||
| A.cs:62:31:62:36 | "test" |
|
||||
| A.cs:64:17:64:20 | access to field name |
|
||||
| A.cs:64:17:64:20 | this access |
|
||||
| A.cs:64:17:64:37 | ... = ... |
|
||||
| A.cs:64:24:64:27 | access to field name |
|
||||
| A.cs:64:24:64:27 | this access |
|
||||
| A.cs:64:24:64:37 | call to method ToUpper |
|
||||
| A.cs:69:18:69:36 | call to constructor Attribute |
|
||||
| Program.cs:9:17:9:20 | access to parameter args |
|
||||
| Program.cs:9:17:9:27 | access to property Length |
|
||||
| Program.cs:9:17:9:32 | ... == ... |
|
||||
| Program.cs:9:32:9:32 | 0 |
|
||||
| Program.cs:11:17:11:23 | access to type Console |
|
||||
| Program.cs:11:17:11:67 | call to method WriteLine |
|
||||
| Program.cs:11:35:11:66 | "Print usage instructions here." |
|
||||
| Program.cs:14:17:14:17 | access to local variable x |
|
||||
| Program.cs:14:17:14:27 | String x = ... |
|
||||
| Program.cs:14:21:14:24 | access to parameter args |
|
||||
| Program.cs:14:21:14:27 | access to array element |
|
||||
| Program.cs:14:26:14:26 | 0 |
|
||||
| Program.cs:15:17:15:17 | access to local variable a |
|
||||
| Program.cs:15:17:15:28 | A a = ... |
|
||||
| Program.cs:15:21:15:28 | object creation of type A |
|
||||
| Program.cs:15:27:15:27 | access to local variable x |
|
||||
| Program.cs:16:13:16:19 | access to type Console |
|
||||
| Program.cs:16:13:16:43 | call to method WriteLine |
|
||||
| Program.cs:16:31:16:31 | access to local variable a |
|
||||
| Program.cs:16:31:16:42 | call to method ToString |
|
||||
| Program.cs:21:16:21:22 | call to constructor Object |
|
||||
| Program.cs:23:13:23:23 | access to field programName |
|
||||
| Program.cs:23:13:23:23 | this access |
|
||||
| Program.cs:23:13:23:27 | ... = ... |
|
||||
| Program.cs:23:27:23:27 | access to parameter x |
|
||||
| Program.cs:29:13:29:19 | access to type Console |
|
||||
| Program.cs:29:13:29:59 | call to method WriteLine |
|
||||
| Program.cs:29:31:29:58 | "Program destructor called!" |
|
||||
| Program.cs:32:23:32:33 | access to property ProgramProp |
|
||||
| Program.cs:32:23:32:33 | this access |
|
||||
| Program.cs:32:49:32:64 | ... = ... |
|
||||
| Program.cs:32:51:32:64 | "Hello World!" |
|
||||
| Program.cs:36:26:36:31 | access to type String |
|
||||
| Program.cs:36:26:36:37 | access to field Empty |
|
||||
| Program.cs:47:17:47:23 | access to type Console |
|
||||
| Program.cs:47:17:47:58 | call to method WriteLine |
|
||||
| Program.cs:47:35:47:57 | "Program handler added" |
|
||||
| Program.cs:51:17:51:23 | access to type Console |
|
||||
| Program.cs:51:17:51:60 | call to method WriteLine |
|
||||
| Program.cs:51:35:51:59 | "Program handler removed" |
|
||||
| Program.cs:57:20:57:20 | access to parameter b |
|
||||
| Program.cs:64:18:64:33 | call to constructor Attribute |
|
||||
statements
|
||||
| A.cs:5:18:5:18 | {...} |
|
||||
| A.cs:11:9:13:9 | {...} |
|
||||
| A.cs:12:13:12:21 | ...; |
|
||||
| A.cs:17:9:19:9 | {...} |
|
||||
| A.cs:18:13:18:52 | ...; |
|
||||
| A.cs:25:17:25:40 | {...} |
|
||||
| A.cs:25:19:25:38 | return ...; |
|
||||
| A.cs:26:17:26:19 | {...} |
|
||||
| A.cs:35:13:37:13 | {...} |
|
||||
| A.cs:36:17:36:51 | ...; |
|
||||
| A.cs:39:13:41:13 | {...} |
|
||||
| A.cs:40:17:40:53 | ...; |
|
||||
| A.cs:45:9:47:9 | {...} |
|
||||
| A.cs:46:13:46:21 | return ...; |
|
||||
| A.cs:50:38:50:40 | {...} |
|
||||
| A.cs:54:9:58:9 | {...} |
|
||||
| A.cs:55:13:55:21 | ... ...; |
|
||||
| A.cs:56:13:56:32 | ...; |
|
||||
| A.cs:57:13:57:21 | return ...; |
|
||||
| A.cs:61:9:66:9 | {...} |
|
||||
| A.cs:62:13:65:13 | if (...) ... |
|
||||
| A.cs:63:13:65:13 | {...} |
|
||||
| A.cs:64:17:64:38 | ...; |
|
||||
| A.cs:69:18:69:36 | {...} |
|
||||
| Program.cs:8:9:17:9 | {...} |
|
||||
| Program.cs:9:13:13:13 | if (...) ... |
|
||||
| Program.cs:10:13:13:13 | {...} |
|
||||
| Program.cs:11:17:11:68 | ...; |
|
||||
| Program.cs:12:17:12:23 | return ...; |
|
||||
| Program.cs:14:13:14:28 | ... ...; |
|
||||
| Program.cs:15:13:15:29 | ... ...; |
|
||||
| Program.cs:16:13:16:44 | ...; |
|
||||
| Program.cs:22:9:24:9 | {...} |
|
||||
| Program.cs:23:13:23:28 | ...; |
|
||||
| Program.cs:28:9:30:9 | {...} |
|
||||
| Program.cs:29:13:29:60 | ...; |
|
||||
| Program.cs:36:17:36:40 | {...} |
|
||||
| Program.cs:36:19:36:38 | return ...; |
|
||||
| Program.cs:37:17:37:19 | {...} |
|
||||
| Program.cs:46:13:48:13 | {...} |
|
||||
| Program.cs:47:17:47:59 | ...; |
|
||||
| Program.cs:50:13:52:13 | {...} |
|
||||
| Program.cs:51:17:51:61 | ...; |
|
||||
| Program.cs:56:9:58:9 | {...} |
|
||||
| Program.cs:57:13:57:21 | return ...; |
|
||||
| Program.cs:61:39:61:41 | {...} |
|
||||
| Program.cs:64:18:64:33 | {...} |
|
||||
methods
|
||||
| A.cs:50:21:50:34 | ObsoleteMethod |
|
||||
| A.cs:53:32:53:39 | ToString |
|
||||
| A.cs:60:21:60:29 | NewMethod |
|
||||
| Program.cs:7:28:7:31 | Main |
|
||||
| Program.cs:61:21:61:35 | AnnotatedMethod |
|
||||
types
|
||||
| A.cs:5:18:5:18 | C |
|
||||
| A.cs:7:18:7:18 | A |
|
||||
| A.cs:69:18:69:36 | MyObsoleteAttribute |
|
||||
| Program.cs:5:20:5:26 | Program |
|
||||
| Program.cs:64:18:64:33 | ProgramAttribute |
|
||||
parameters
|
||||
| A.cs:10:25:10:25 | x |
|
||||
| A.cs:21:35:21:37 | value |
|
||||
| A.cs:23:32:23:32 | i |
|
||||
| A.cs:23:32:23:32 | i |
|
||||
| A.cs:23:32:23:32 | i |
|
||||
| A.cs:26:13:26:15 | value |
|
||||
| A.cs:34:13:34:15 | value |
|
||||
| A.cs:38:13:38:18 | value |
|
||||
| A.cs:44:38:44:38 | a |
|
||||
| A.cs:44:43:44:43 | b |
|
||||
| Program.cs:7:42:7:45 | args |
|
||||
| Program.cs:21:31:21:31 | x |
|
||||
| Program.cs:32:42:32:44 | value |
|
||||
| Program.cs:34:32:34:32 | i |
|
||||
| Program.cs:34:32:34:32 | i |
|
||||
| Program.cs:34:32:34:32 | i |
|
||||
| Program.cs:37:13:37:15 | value |
|
||||
| Program.cs:45:13:45:15 | value |
|
||||
| Program.cs:49:13:49:18 | value |
|
||||
| Program.cs:55:50:55:50 | a |
|
||||
| Program.cs:55:61:55:61 | b |
|
||||
operators
|
||||
| A.cs:44:34:44:34 | + |
|
||||
| Program.cs:55:40:55:40 | - |
|
||||
constructors
|
||||
| A.cs:10:16:10:16 | A |
|
||||
| Program.cs:21:16:21:22 | Program |
|
||||
destructors
|
||||
| A.cs:16:10:16:10 | ~A |
|
||||
| Program.cs:27:10:27:16 | ~Program |
|
||||
fields
|
||||
| A.cs:9:24:9:27 | name |
|
||||
| Program.cs:19:24:19:34 | programName |
|
||||
properties
|
||||
| A.cs:21:23:21:26 | Prop |
|
||||
| Program.cs:32:23:32:33 | ProgramProp |
|
||||
indexers
|
||||
| A.cs:23:23:23:26 | Item |
|
||||
| Program.cs:34:23:34:26 | Item |
|
||||
accessors
|
||||
| A.cs:21:30:21:32 | get_Prop |
|
||||
| A.cs:21:35:21:37 | set_Prop |
|
||||
| A.cs:25:13:25:15 | get_Item |
|
||||
| A.cs:26:13:26:15 | set_Item |
|
||||
| A.cs:34:13:34:15 | add_Clicked |
|
||||
| A.cs:38:13:38:18 | remove_Clicked |
|
||||
| Program.cs:32:37:32:39 | get_ProgramProp |
|
||||
| Program.cs:32:42:32:44 | set_ProgramProp |
|
||||
| Program.cs:36:13:36:15 | get_Item |
|
||||
| Program.cs:37:13:37:15 | set_Item |
|
||||
| Program.cs:45:13:45:15 | add_ProgramClicked |
|
||||
| Program.cs:49:13:49:18 | remove_ProgramClicked |
|
||||
attributes
|
||||
| A.cs:49:10:49:19 | [MyObsolete(...)] |
|
||||
| Program.cs:60:10:60:16 | [Program(...)] |
|
||||
events
|
||||
| A.cs:32:35:32:41 | Clicked |
|
||||
| Program.cs:43:35:43:48 | ProgramClicked |
|
||||
eventAccessors
|
||||
| A.cs:34:13:34:15 | add_Clicked |
|
||||
| A.cs:38:13:38:18 | remove_Clicked |
|
||||
| Program.cs:45:13:45:15 | add_ProgramClicked |
|
||||
| Program.cs:49:13:49:18 | remove_ProgramClicked |
|
||||
usingDirectives
|
||||
| A.cs:1:1:1:13 | using ...; |
|
||||
| Program.cs:1:1:1:13 | using ...; |
|
||||
commentLines
|
||||
| A.cs:15:9:15:21 | // ... |
|
||||
| A.cs:29:9:29:10 | /* ... */ |
|
||||
| A.cs:30:1:30:27 | /* ... */ |
|
||||
| A.cs:31:1:31:11 | /* ... */ |
|
||||
| Program.cs:26:9:26:29 | // ... |
|
||||
| Program.cs:40:9:40:10 | /* ... */ |
|
||||
| Program.cs:41:1:41:27 | /* ... */ |
|
||||
| Program.cs:42:1:42:11 | /* ... */ |
|
||||
commentBlocks
|
||||
| A.cs:15:9:15:21 | // ... |
|
||||
| A.cs:29:9:31:11 | /* ... */ |
|
||||
| Program.cs:26:9:26:29 | // ... |
|
||||
| Program.cs:40:9:42:11 | /* ... */ |
|
||||
typeMentions
|
||||
| A.cs:9:17:9:22 | String |
|
||||
| A.cs:10:18:10:23 | String |
|
||||
| A.cs:18:13:18:19 | Console |
|
||||
| A.cs:21:16:21:21 | String |
|
||||
| A.cs:23:16:23:21 | Object |
|
||||
| A.cs:23:28:23:30 | Int32 |
|
||||
| A.cs:25:30:25:35 | Object |
|
||||
| A.cs:36:17:36:23 | Console |
|
||||
| A.cs:40:17:40:23 | Console |
|
||||
| A.cs:44:23:44:23 | A |
|
||||
| A.cs:44:36:44:36 | A |
|
||||
| A.cs:44:41:44:41 | A |
|
||||
| A.cs:49:10:49:19 | MyObsoleteAttribute |
|
||||
| A.cs:50:16:50:19 | Void |
|
||||
| A.cs:53:25:53:30 | String |
|
||||
| A.cs:55:13:55:18 | String |
|
||||
| A.cs:60:16:60:19 | Void |
|
||||
| A.cs:69:40:69:48 | Attribute |
|
||||
| Program.cs:7:23:7:26 | Void |
|
||||
| Program.cs:7:33:7:38 | String |
|
||||
| Program.cs:7:33:7:40 | String[] |
|
||||
| Program.cs:11:17:11:23 | Console |
|
||||
| Program.cs:14:13:14:15 | String |
|
||||
| Program.cs:15:13:15:15 | A |
|
||||
| Program.cs:15:25:15:25 | A |
|
||||
| Program.cs:16:13:16:19 | Console |
|
||||
| Program.cs:19:17:19:22 | String |
|
||||
| Program.cs:21:24:21:29 | String |
|
||||
| Program.cs:29:13:29:19 | Console |
|
||||
| Program.cs:32:16:32:21 | String |
|
||||
| Program.cs:34:16:34:21 | String |
|
||||
| Program.cs:34:28:34:30 | Int32 |
|
||||
| Program.cs:36:26:36:31 | String |
|
||||
| Program.cs:47:17:47:23 | Console |
|
||||
| Program.cs:51:17:51:23 | Console |
|
||||
| Program.cs:55:23:55:29 | Program |
|
||||
| Program.cs:55:42:55:48 | Program |
|
||||
| Program.cs:55:53:55:59 | Program |
|
||||
| Program.cs:60:10:60:16 | ProgramAttribute |
|
||||
| Program.cs:61:16:61:19 | Void |
|
||||
| Program.cs:64:37:64:45 | Attribute |
|
||||
xmlLocatables
|
||||
| web.changed.config:2:1:5:17 | configuration |
|
||||
| web.changed.config:3:3:4:16 | system.web |
|
||||
| web.unchanged.config:2:1:6:17 | configuration |
|
||||
| web.unchanged.config:3:3:5:16 | system.web |
|
||||
| web.unchanged.config:4:5:4:37 | httpCookies |
|
||||
| web.unchanged.config:4:5:4:37 | requireSSL=true |
|
||||
1
csharp/ql/test/library-tests/overlay/overlay/test.qlref
Normal file
1
csharp/ql/test/library-tests/overlay/overlay/test.qlref
Normal file
@@ -0,0 +1 @@
|
||||
query: ../test.ql
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.web>
|
||||
<httpCookies requireSSL="true"/>
|
||||
</system.web>
|
||||
</configuration>
|
||||
41
csharp/ql/test/library-tests/overlay/test.ql
Normal file
41
csharp/ql/test/library-tests/overlay/test.ql
Normal file
@@ -0,0 +1,41 @@
|
||||
import csharp
|
||||
|
||||
query predicate expressions(Expr e) { e.fromSource() }
|
||||
|
||||
query predicate statements(Stmt s) { s.fromSource() }
|
||||
|
||||
query predicate methods(Method m) { m.fromSource() }
|
||||
|
||||
query predicate types(Type t) { t.fromSource() }
|
||||
|
||||
query predicate parameters(Parameter p) { p.fromSource() }
|
||||
|
||||
query predicate operators(Operator o) { o.fromSource() }
|
||||
|
||||
query predicate constructors(Constructor c) { c.fromSource() }
|
||||
|
||||
query predicate destructors(Destructor d) { d.fromSource() }
|
||||
|
||||
query predicate fields(Field f) { f.fromSource() }
|
||||
|
||||
query predicate properties(Property p) { p.fromSource() }
|
||||
|
||||
query predicate indexers(Indexer i) { i.fromSource() }
|
||||
|
||||
query predicate accessors(Accessor a) { a.fromSource() }
|
||||
|
||||
query predicate attributes(Attribute a) { a.fromSource() }
|
||||
|
||||
query predicate events(Event ev) { ev.fromSource() }
|
||||
|
||||
query predicate eventAccessors(EventAccessor ea) { ea.fromSource() }
|
||||
|
||||
query predicate usingDirectives(UsingDirective ud) { ud.fromSource() }
|
||||
|
||||
query predicate commentLines(CommentLine cl) { any() }
|
||||
|
||||
query predicate commentBlocks(CommentBlock cb) { any() }
|
||||
|
||||
query predicate typeMentions(TypeMention tm) { any() }
|
||||
|
||||
query predicate xmlLocatables(XmlLocatable xl) { any() }
|
||||
@@ -0,0 +1,5 @@
|
||||
elementsWithMultipleSourceLocations
|
||||
typeMentionsWithMultipleSourceLocations
|
||||
commentLinesWithMultipleSourceLocations
|
||||
commentBlocksWithMultipleSourceLocations
|
||||
removedEntities
|
||||
29
csharp/ql/test/library-tests/overlay/testlocations.ql
Normal file
29
csharp/ql/test/library-tests/overlay/testlocations.ql
Normal file
@@ -0,0 +1,29 @@
|
||||
import csharp
|
||||
|
||||
// This is a consistency check that the overlay mechanism for cleaning up locations
|
||||
// works correctly.
|
||||
query predicate elementsWithMultipleSourceLocations(Element e, SourceLocation loc) {
|
||||
e.fromSource() and
|
||||
not e instanceof Namespace and
|
||||
strictcount(SourceLocation l0 | l0 = e.getALocation()) > 1 and
|
||||
loc = e.getALocation()
|
||||
}
|
||||
|
||||
query predicate typeMentionsWithMultipleSourceLocations(TypeMention tm, SourceLocation loc) {
|
||||
strictcount(SourceLocation l0 | l0 = tm.getLocation()) > 1 and
|
||||
loc = tm.getLocation()
|
||||
}
|
||||
|
||||
query predicate commentLinesWithMultipleSourceLocations(CommentLine cl, SourceLocation loc) {
|
||||
strictcount(SourceLocation l0 | l0 = cl.getLocation()) > 1 and
|
||||
loc = cl.getLocation()
|
||||
}
|
||||
|
||||
query predicate commentBlocksWithMultipleSourceLocations(CommentBlock cb, SourceLocation loc) {
|
||||
strictcount(SourceLocation l0 | l0 = cb.getLocation()) > 1 and
|
||||
loc = cb.getLocation()
|
||||
}
|
||||
|
||||
// This is a consistency check that the entities that are removed as a part of
|
||||
// the changes in the overlay are indeed removed from the database.
|
||||
query predicate removedEntities(Element e) { e.(Method).getName() = "OldMethod" }
|
||||
@@ -21,6 +21,7 @@ file_types:
|
||||
extensions:
|
||||
- .go
|
||||
legacy_qltest_extraction: true
|
||||
overlay_support_version: 20250626
|
||||
options:
|
||||
extract_tests:
|
||||
title: Whether to include Go test files in the CodeQL database.
|
||||
|
||||
@@ -0,0 +1,552 @@
|
||||
/** Auto-generated dbscheme; do not edit. Run `make gen` in directory `go/` to regenerate. */
|
||||
|
||||
|
||||
/** Duplicate code **/
|
||||
|
||||
duplicateCode(
|
||||
unique int id : @duplication,
|
||||
varchar(900) relativePath : string ref,
|
||||
int equivClass : int ref);
|
||||
|
||||
similarCode(
|
||||
unique int id : @similarity,
|
||||
varchar(900) relativePath : string ref,
|
||||
int equivClass : int ref);
|
||||
|
||||
@duplication_or_similarity = @duplication | @similarity;
|
||||
|
||||
tokens(
|
||||
int id : @duplication_or_similarity ref,
|
||||
int offset : int ref,
|
||||
int beginLine : int ref,
|
||||
int beginColumn : int ref,
|
||||
int endLine : int ref,
|
||||
int endColumn : int ref);
|
||||
|
||||
/** External data **/
|
||||
|
||||
externalData(
|
||||
int id : @externalDataElement,
|
||||
varchar(900) path : string ref,
|
||||
int column: int ref,
|
||||
varchar(900) value : string ref
|
||||
);
|
||||
|
||||
snapshotDate(unique date snapshotDate : date ref);
|
||||
|
||||
sourceLocationPrefix(varchar(900) prefix : string ref);
|
||||
|
||||
|
||||
/*
|
||||
* XML Files
|
||||
*/
|
||||
|
||||
xmlEncoding(
|
||||
unique int id: @file ref,
|
||||
string encoding: string ref
|
||||
);
|
||||
|
||||
xmlDTDs(
|
||||
unique int id: @xmldtd,
|
||||
string root: string ref,
|
||||
string publicId: string ref,
|
||||
string systemId: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlElements(
|
||||
unique int id: @xmlelement,
|
||||
string name: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlAttrs(
|
||||
unique int id: @xmlattribute,
|
||||
int elementid: @xmlelement ref,
|
||||
string name: string ref,
|
||||
string value: string ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlNs(
|
||||
int id: @xmlnamespace,
|
||||
string prefixName: string ref,
|
||||
string URI: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlHasNs(
|
||||
int elementId: @xmlnamespaceable ref,
|
||||
int nsId: @xmlnamespace ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlComments(
|
||||
unique int id: @xmlcomment,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlChars(
|
||||
unique int id: @xmlcharacters,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int isCDATA: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
@xmlparent = @file | @xmlelement;
|
||||
@xmlnamespaceable = @xmlelement | @xmlattribute;
|
||||
|
||||
xmllocations(
|
||||
int xmlElement: @xmllocatable ref,
|
||||
int location: @location_default ref
|
||||
);
|
||||
|
||||
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
|
||||
|
||||
compilations(unique int id: @compilation, string cwd: string ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
|
||||
|
||||
#keyset[id, num, kind]
|
||||
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
|
||||
|
||||
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
|
||||
|
||||
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
|
||||
|
||||
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
|
||||
string full_error_message: string ref, int location: @location ref);
|
||||
|
||||
locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref,
|
||||
int endLine: int ref, int endColumn: int ref);
|
||||
|
||||
numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref);
|
||||
|
||||
files(unique int id: @file, string name: string ref);
|
||||
|
||||
folders(unique int id: @folder, string name: string ref);
|
||||
|
||||
containerparent(int parent: @container ref, unique int child: @container ref);
|
||||
|
||||
has_location(unique int locatable: @locatable ref, int location: @location ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref);
|
||||
|
||||
comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref);
|
||||
|
||||
doc_comments(unique int node: @documentable ref, int comment: @comment_group ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref);
|
||||
|
||||
literals(unique int expr: @expr ref, string value: string ref, string raw: string ref);
|
||||
|
||||
constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref);
|
||||
|
||||
fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref);
|
||||
|
||||
typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref);
|
||||
|
||||
scopes(unique int id: @scope, int kind: int ref);
|
||||
|
||||
scopenesting(unique int inner: @scope ref, int outer: @scope ref);
|
||||
|
||||
scopenodes(unique int node: @scopenode ref, int scope: @localscope ref);
|
||||
|
||||
objects(unique int id: @object, int kind: int ref, string name: string ref);
|
||||
|
||||
objectscopes(unique int object: @object ref, int scope: @scope ref);
|
||||
|
||||
objecttypes(unique int object: @object ref, int tp: @type ref);
|
||||
|
||||
methodreceivers(unique int method: @object ref, int receiver: @object ref);
|
||||
|
||||
fieldstructs(unique int field: @object ref, int struct: @structtype ref);
|
||||
|
||||
methodhosts(int method: @object ref, int host: @definedtype ref);
|
||||
|
||||
defs(int ident: @ident ref, int object: @object ref);
|
||||
|
||||
uses(int ident: @ident ref, int object: @object ref);
|
||||
|
||||
types(unique int id: @type, int kind: int ref);
|
||||
|
||||
type_of(unique int expr: @expr ref, int tp: @type ref);
|
||||
|
||||
typename(unique int tp: @type ref, string name: string ref);
|
||||
|
||||
key_type(unique int map: @maptype ref, int tp: @type ref);
|
||||
|
||||
element_type(unique int container: @containertype ref, int tp: @type ref);
|
||||
|
||||
base_type(unique int ptr: @pointertype ref, int tp: @type ref);
|
||||
|
||||
underlying_type(unique int defined: @definedtype ref, int tp: @type ref);
|
||||
|
||||
#keyset[parent, index]
|
||||
component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref);
|
||||
|
||||
#keyset[parent, index]
|
||||
struct_tags(int parent: @structtype ref, int index: int ref, string tag: string ref);
|
||||
|
||||
#keyset[interface, index]
|
||||
interface_private_method_ids(int interface: @interfacetype ref, int index: int ref, string id: string ref);
|
||||
|
||||
array_length(unique int tp: @arraytype ref, string len: string ref);
|
||||
|
||||
type_objects(unique int tp: @type ref, int object: @object ref);
|
||||
|
||||
packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref);
|
||||
|
||||
#keyset[package, idx]
|
||||
errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref,
|
||||
string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref);
|
||||
|
||||
has_ellipsis(int id: @callorconversionexpr ref);
|
||||
|
||||
variadic(int id: @signaturetype ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref,
|
||||
int parent: @typeparamparentobject ref, int idx: int ref);
|
||||
|
||||
@container = @file | @folder;
|
||||
|
||||
@locatable = @xmllocatable | @node | @localscope;
|
||||
|
||||
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent
|
||||
| @scopenode | @comment_group | @comment;
|
||||
|
||||
@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr;
|
||||
|
||||
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec;
|
||||
|
||||
@modexprparent = @file | @modexpr;
|
||||
|
||||
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
|
||||
|
||||
@stmtparent = @funcdef | @stmt | @decl;
|
||||
|
||||
@declparent = @file | @declstmt;
|
||||
|
||||
@typeparamdeclparent = @funcdecl | @typespec;
|
||||
|
||||
@funcdef = @funclit | @funcdecl;
|
||||
|
||||
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
|
||||
|
||||
@location = @location_default;
|
||||
|
||||
@sourceline = @locatable;
|
||||
|
||||
case @comment.kind of
|
||||
0 = @slashslashcomment
|
||||
| 1 = @slashstarcomment;
|
||||
|
||||
case @expr.kind of
|
||||
0 = @badexpr
|
||||
| 1 = @ident
|
||||
| 2 = @ellipsis
|
||||
| 3 = @intlit
|
||||
| 4 = @floatlit
|
||||
| 5 = @imaglit
|
||||
| 6 = @charlit
|
||||
| 7 = @stringlit
|
||||
| 8 = @funclit
|
||||
| 9 = @compositelit
|
||||
| 10 = @parenexpr
|
||||
| 11 = @selectorexpr
|
||||
| 12 = @indexexpr
|
||||
| 13 = @genericfunctioninstantiationexpr
|
||||
| 14 = @generictypeinstantiationexpr
|
||||
| 15 = @sliceexpr
|
||||
| 16 = @typeassertexpr
|
||||
| 17 = @callorconversionexpr
|
||||
| 18 = @starexpr
|
||||
| 19 = @keyvalueexpr
|
||||
| 20 = @arraytypeexpr
|
||||
| 21 = @structtypeexpr
|
||||
| 22 = @functypeexpr
|
||||
| 23 = @interfacetypeexpr
|
||||
| 24 = @maptypeexpr
|
||||
| 25 = @typesetliteralexpr
|
||||
| 26 = @plusexpr
|
||||
| 27 = @minusexpr
|
||||
| 28 = @notexpr
|
||||
| 29 = @complementexpr
|
||||
| 30 = @derefexpr
|
||||
| 31 = @addressexpr
|
||||
| 32 = @arrowexpr
|
||||
| 33 = @lorexpr
|
||||
| 34 = @landexpr
|
||||
| 35 = @eqlexpr
|
||||
| 36 = @neqexpr
|
||||
| 37 = @lssexpr
|
||||
| 38 = @leqexpr
|
||||
| 39 = @gtrexpr
|
||||
| 40 = @geqexpr
|
||||
| 41 = @addexpr
|
||||
| 42 = @subexpr
|
||||
| 43 = @orexpr
|
||||
| 44 = @xorexpr
|
||||
| 45 = @mulexpr
|
||||
| 46 = @quoexpr
|
||||
| 47 = @remexpr
|
||||
| 48 = @shlexpr
|
||||
| 49 = @shrexpr
|
||||
| 50 = @andexpr
|
||||
| 51 = @andnotexpr
|
||||
| 52 = @sendchantypeexpr
|
||||
| 53 = @recvchantypeexpr
|
||||
| 54 = @sendrcvchantypeexpr;
|
||||
|
||||
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
|
||||
|
||||
@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr;
|
||||
|
||||
@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr;
|
||||
|
||||
@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr;
|
||||
|
||||
@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr;
|
||||
|
||||
@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr;
|
||||
|
||||
@logicalunaryexpr = @notexpr;
|
||||
|
||||
@bitwiseunaryexpr = @complementexpr;
|
||||
|
||||
@arithmeticunaryexpr = @plusexpr | @minusexpr;
|
||||
|
||||
@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison;
|
||||
|
||||
@logicalbinaryexpr = @lorexpr | @landexpr;
|
||||
|
||||
@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr;
|
||||
|
||||
@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr;
|
||||
|
||||
@shiftexpr = @shlexpr | @shrexpr;
|
||||
|
||||
@comparison = @equalitytest | @relationalcomparison;
|
||||
|
||||
@equalitytest = @eqlexpr | @neqexpr;
|
||||
|
||||
@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr;
|
||||
|
||||
@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr;
|
||||
|
||||
case @stmt.kind of
|
||||
0 = @badstmt
|
||||
| 1 = @declstmt
|
||||
| 2 = @emptystmt
|
||||
| 3 = @labeledstmt
|
||||
| 4 = @exprstmt
|
||||
| 5 = @sendstmt
|
||||
| 6 = @incstmt
|
||||
| 7 = @decstmt
|
||||
| 8 = @gostmt
|
||||
| 9 = @deferstmt
|
||||
| 10 = @returnstmt
|
||||
| 11 = @breakstmt
|
||||
| 12 = @continuestmt
|
||||
| 13 = @gotostmt
|
||||
| 14 = @fallthroughstmt
|
||||
| 15 = @blockstmt
|
||||
| 16 = @ifstmt
|
||||
| 17 = @caseclause
|
||||
| 18 = @exprswitchstmt
|
||||
| 19 = @typeswitchstmt
|
||||
| 20 = @commclause
|
||||
| 21 = @selectstmt
|
||||
| 22 = @forstmt
|
||||
| 23 = @rangestmt
|
||||
| 24 = @assignstmt
|
||||
| 25 = @definestmt
|
||||
| 26 = @addassignstmt
|
||||
| 27 = @subassignstmt
|
||||
| 28 = @mulassignstmt
|
||||
| 29 = @quoassignstmt
|
||||
| 30 = @remassignstmt
|
||||
| 31 = @andassignstmt
|
||||
| 32 = @orassignstmt
|
||||
| 33 = @xorassignstmt
|
||||
| 34 = @shlassignstmt
|
||||
| 35 = @shrassignstmt
|
||||
| 36 = @andnotassignstmt;
|
||||
|
||||
@incdecstmt = @incstmt | @decstmt;
|
||||
|
||||
@assignment = @simpleassignstmt | @compoundassignstmt;
|
||||
|
||||
@simpleassignstmt = @assignstmt | @definestmt;
|
||||
|
||||
@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt
|
||||
| @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt;
|
||||
|
||||
@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt;
|
||||
|
||||
@switchstmt = @exprswitchstmt | @typeswitchstmt;
|
||||
|
||||
@loopstmt = @forstmt | @rangestmt;
|
||||
|
||||
case @decl.kind of
|
||||
0 = @baddecl
|
||||
| 1 = @importdecl
|
||||
| 2 = @constdecl
|
||||
| 3 = @typedecl
|
||||
| 4 = @vardecl
|
||||
| 5 = @funcdecl;
|
||||
|
||||
@gendecl = @importdecl | @constdecl | @typedecl | @vardecl;
|
||||
|
||||
case @spec.kind of
|
||||
0 = @importspec
|
||||
| 1 = @valuespec
|
||||
| 2 = @typedefspec
|
||||
| 3 = @aliasspec;
|
||||
|
||||
@typespec = @typedefspec | @aliasspec;
|
||||
|
||||
case @object.kind of
|
||||
0 = @pkgobject
|
||||
| 1 = @decltypeobject
|
||||
| 2 = @builtintypeobject
|
||||
| 3 = @declconstobject
|
||||
| 4 = @builtinconstobject
|
||||
| 5 = @declvarobject
|
||||
| 6 = @declfunctionobject
|
||||
| 7 = @builtinfunctionobject
|
||||
| 8 = @labelobject;
|
||||
|
||||
@typeparamparentobject = @decltypeobject | @declfunctionobject;
|
||||
|
||||
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
|
||||
|
||||
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
|
||||
|
||||
@typeobject = @decltypeobject | @builtintypeobject;
|
||||
|
||||
@valueobject = @constobject | @varobject | @functionobject;
|
||||
|
||||
@constobject = @declconstobject | @builtinconstobject;
|
||||
|
||||
@varobject = @declvarobject;
|
||||
|
||||
@functionobject = @declfunctionobject | @builtinfunctionobject;
|
||||
|
||||
case @scope.kind of
|
||||
0 = @universescope
|
||||
| 1 = @packagescope
|
||||
| 2 = @localscope;
|
||||
|
||||
case @type.kind of
|
||||
0 = @invalidtype
|
||||
| 1 = @boolexprtype
|
||||
| 2 = @inttype
|
||||
| 3 = @int8type
|
||||
| 4 = @int16type
|
||||
| 5 = @int32type
|
||||
| 6 = @int64type
|
||||
| 7 = @uinttype
|
||||
| 8 = @uint8type
|
||||
| 9 = @uint16type
|
||||
| 10 = @uint32type
|
||||
| 11 = @uint64type
|
||||
| 12 = @uintptrtype
|
||||
| 13 = @float32type
|
||||
| 14 = @float64type
|
||||
| 15 = @complex64type
|
||||
| 16 = @complex128type
|
||||
| 17 = @stringexprtype
|
||||
| 18 = @unsafepointertype
|
||||
| 19 = @boolliteraltype
|
||||
| 20 = @intliteraltype
|
||||
| 21 = @runeliteraltype
|
||||
| 22 = @floatliteraltype
|
||||
| 23 = @complexliteraltype
|
||||
| 24 = @stringliteraltype
|
||||
| 25 = @nilliteraltype
|
||||
| 26 = @typeparamtype
|
||||
| 27 = @arraytype
|
||||
| 28 = @slicetype
|
||||
| 29 = @structtype
|
||||
| 30 = @pointertype
|
||||
| 31 = @interfacetype
|
||||
| 32 = @tupletype
|
||||
| 33 = @signaturetype
|
||||
| 34 = @maptype
|
||||
| 35 = @sendchantype
|
||||
| 36 = @recvchantype
|
||||
| 37 = @sendrcvchantype
|
||||
| 38 = @definedtype
|
||||
| 39 = @typesetliteraltype;
|
||||
|
||||
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
|
||||
|
||||
@booltype = @boolexprtype | @boolliteraltype;
|
||||
|
||||
@numerictype = @integertype | @floattype | @complextype;
|
||||
|
||||
@integertype = @signedintegertype | @unsignedintegertype;
|
||||
|
||||
@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype;
|
||||
|
||||
@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype;
|
||||
|
||||
@floattype = @float32type | @float64type | @floatliteraltype;
|
||||
|
||||
@complextype = @complex64type | @complex128type | @complexliteraltype;
|
||||
|
||||
@stringtype = @stringexprtype | @stringliteraltype;
|
||||
|
||||
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
|
||||
| @stringliteraltype | @nilliteraltype;
|
||||
|
||||
@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype
|
||||
| @signaturetype | @definedtype | @typesetliteraltype;
|
||||
|
||||
@containertype = @arraytype | @slicetype | @maptype | @chantype;
|
||||
|
||||
@chantype = @sendchantype | @recvchantype | @sendrcvchantype;
|
||||
|
||||
case @modexpr.kind of
|
||||
0 = @modcommentblock
|
||||
| 1 = @modline
|
||||
| 2 = @modlineblock
|
||||
| 3 = @modlparen
|
||||
| 4 = @modrparen;
|
||||
|
||||
case @error.kind of
|
||||
0 = @unknownerror
|
||||
| 1 = @listerror
|
||||
| 2 = @parseerror
|
||||
| 3 = @typeerror;
|
||||
|
||||
@@ -0,0 +1,563 @@
|
||||
/** Auto-generated dbscheme; do not edit. Run `make gen` in directory `go/` to regenerate. */
|
||||
|
||||
|
||||
/** Duplicate code **/
|
||||
|
||||
duplicateCode(
|
||||
unique int id : @duplication,
|
||||
varchar(900) relativePath : string ref,
|
||||
int equivClass : int ref);
|
||||
|
||||
similarCode(
|
||||
unique int id : @similarity,
|
||||
varchar(900) relativePath : string ref,
|
||||
int equivClass : int ref);
|
||||
|
||||
@duplication_or_similarity = @duplication | @similarity;
|
||||
|
||||
tokens(
|
||||
int id : @duplication_or_similarity ref,
|
||||
int offset : int ref,
|
||||
int beginLine : int ref,
|
||||
int beginColumn : int ref,
|
||||
int endLine : int ref,
|
||||
int endColumn : int ref);
|
||||
|
||||
/** External data **/
|
||||
|
||||
externalData(
|
||||
int id : @externalDataElement,
|
||||
varchar(900) path : string ref,
|
||||
int column: int ref,
|
||||
varchar(900) value : string ref
|
||||
);
|
||||
|
||||
snapshotDate(unique date snapshotDate : date ref);
|
||||
|
||||
sourceLocationPrefix(varchar(900) prefix : string ref);
|
||||
|
||||
/** Overlay support **/
|
||||
|
||||
databaseMetadata(
|
||||
string metadataKey: string ref,
|
||||
string value: string ref
|
||||
);
|
||||
|
||||
overlayChangedFiles(
|
||||
string path: string ref
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* XML Files
|
||||
*/
|
||||
|
||||
xmlEncoding(
|
||||
unique int id: @file ref,
|
||||
string encoding: string ref
|
||||
);
|
||||
|
||||
xmlDTDs(
|
||||
unique int id: @xmldtd,
|
||||
string root: string ref,
|
||||
string publicId: string ref,
|
||||
string systemId: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlElements(
|
||||
unique int id: @xmlelement,
|
||||
string name: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlAttrs(
|
||||
unique int id: @xmlattribute,
|
||||
int elementid: @xmlelement ref,
|
||||
string name: string ref,
|
||||
string value: string ref,
|
||||
int idx: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlNs(
|
||||
int id: @xmlnamespace,
|
||||
string prefixName: string ref,
|
||||
string URI: string ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlHasNs(
|
||||
int elementId: @xmlnamespaceable ref,
|
||||
int nsId: @xmlnamespace ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlComments(
|
||||
unique int id: @xmlcomment,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
xmlChars(
|
||||
unique int id: @xmlcharacters,
|
||||
string text: string ref,
|
||||
int parentid: @xmlparent ref,
|
||||
int idx: int ref,
|
||||
int isCDATA: int ref,
|
||||
int fileid: @file ref
|
||||
);
|
||||
|
||||
@xmlparent = @file | @xmlelement;
|
||||
@xmlnamespaceable = @xmlelement | @xmlattribute;
|
||||
|
||||
xmllocations(
|
||||
int xmlElement: @xmllocatable ref,
|
||||
int location: @location_default ref
|
||||
);
|
||||
|
||||
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
|
||||
|
||||
compilations(unique int id: @compilation, string cwd: string ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_args(int id: @compilation ref, int num: int ref, string arg: string ref);
|
||||
|
||||
#keyset[id, num, kind]
|
||||
compilation_time(int id: @compilation ref, int num: int ref, int kind: int ref, float secs: float ref);
|
||||
|
||||
diagnostic_for(unique int diagnostic: @diagnostic ref, int compilation: @compilation ref, int file_number: int ref, int file_number_diagnostic_number: int ref);
|
||||
|
||||
compilation_finished(unique int id: @compilation ref, float cpu_seconds: float ref, float elapsed_seconds: float ref);
|
||||
|
||||
#keyset[id, num]
|
||||
compilation_compiling_files(int id: @compilation ref, int num: int ref, int file: @file ref);
|
||||
|
||||
diagnostics(unique int id: @diagnostic, int severity: int ref, string error_tag: string ref, string error_message: string ref,
|
||||
string full_error_message: string ref, int location: @location ref);
|
||||
|
||||
locations_default(unique int id: @location_default, int file: @file ref, int beginLine: int ref, int beginColumn: int ref,
|
||||
int endLine: int ref, int endColumn: int ref);
|
||||
|
||||
numlines(int element_id: @sourceline ref, int num_lines: int ref, int num_code: int ref, int num_comment: int ref);
|
||||
|
||||
files(unique int id: @file, string name: string ref);
|
||||
|
||||
folders(unique int id: @folder, string name: string ref);
|
||||
|
||||
containerparent(int parent: @container ref, unique int child: @container ref);
|
||||
|
||||
has_location(unique int locatable: @locatable ref, int location: @location ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
comment_groups(unique int id: @comment_group, int parent: @file ref, int idx: int ref);
|
||||
|
||||
comments(unique int id: @comment, int kind: int ref, int parent: @comment_group ref, int idx: int ref, string text: string ref);
|
||||
|
||||
doc_comments(unique int node: @documentable ref, int comment: @comment_group ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
exprs(unique int id: @expr, int kind: int ref, int parent: @exprparent ref, int idx: int ref);
|
||||
|
||||
literals(unique int expr: @expr ref, string value: string ref, string raw: string ref);
|
||||
|
||||
constvalues(unique int expr: @expr ref, string value: string ref, string exact: string ref);
|
||||
|
||||
fields(unique int id: @field, int parent: @fieldparent ref, int idx: int ref);
|
||||
|
||||
typeparamdecls(unique int id: @typeparamdecl, int parent: @typeparamdeclparent ref, int idx: int ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
stmts(unique int id: @stmt, int kind: int ref, int parent: @stmtparent ref, int idx: int ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
decls(unique int id: @decl, int kind: int ref, int parent: @declparent ref, int idx: int ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
specs(unique int id: @spec, int kind: int ref, int parent: @gendecl ref, int idx: int ref);
|
||||
|
||||
scopes(unique int id: @scope, int kind: int ref);
|
||||
|
||||
scopenesting(unique int inner: @scope ref, int outer: @scope ref);
|
||||
|
||||
scopenodes(unique int node: @scopenode ref, int scope: @localscope ref);
|
||||
|
||||
objects(unique int id: @object, int kind: int ref, string name: string ref);
|
||||
|
||||
objectscopes(unique int object: @object ref, int scope: @scope ref);
|
||||
|
||||
objecttypes(unique int object: @object ref, int tp: @type ref);
|
||||
|
||||
methodreceivers(unique int method: @object ref, int receiver: @object ref);
|
||||
|
||||
fieldstructs(unique int field: @object ref, int struct: @structtype ref);
|
||||
|
||||
methodhosts(int method: @object ref, int host: @definedtype ref);
|
||||
|
||||
defs(int ident: @ident ref, int object: @object ref);
|
||||
|
||||
uses(int ident: @ident ref, int object: @object ref);
|
||||
|
||||
types(unique int id: @type, int kind: int ref);
|
||||
|
||||
type_of(unique int expr: @expr ref, int tp: @type ref);
|
||||
|
||||
typename(unique int tp: @type ref, string name: string ref);
|
||||
|
||||
key_type(unique int map: @maptype ref, int tp: @type ref);
|
||||
|
||||
element_type(unique int container: @containertype ref, int tp: @type ref);
|
||||
|
||||
base_type(unique int ptr: @pointertype ref, int tp: @type ref);
|
||||
|
||||
underlying_type(unique int defined: @definedtype ref, int tp: @type ref);
|
||||
|
||||
#keyset[parent, index]
|
||||
component_types(int parent: @compositetype ref, int index: int ref, string name: string ref, int tp: @type ref);
|
||||
|
||||
#keyset[parent, index]
|
||||
struct_tags(int parent: @structtype ref, int index: int ref, string tag: string ref);
|
||||
|
||||
#keyset[interface, index]
|
||||
interface_private_method_ids(int interface: @interfacetype ref, int index: int ref, string id: string ref);
|
||||
|
||||
array_length(unique int tp: @arraytype ref, string len: string ref);
|
||||
|
||||
type_objects(unique int tp: @type ref, int object: @object ref);
|
||||
|
||||
packages(unique int id: @package, string name: string ref, string path: string ref, int scope: @packagescope ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
modexprs(unique int id: @modexpr, int kind: int ref, int parent: @modexprparent ref, int idx: int ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
modtokens(string token: string ref, int parent: @modexpr ref, int idx: int ref);
|
||||
|
||||
#keyset[package, idx]
|
||||
errors(unique int id: @error, int kind: int ref, string msg: string ref, string rawpos: string ref,
|
||||
string file: string ref, int line: int ref, int col: int ref, int package: @package ref, int idx: int ref);
|
||||
|
||||
has_ellipsis(int id: @callorconversionexpr ref);
|
||||
|
||||
variadic(int id: @signaturetype ref);
|
||||
|
||||
#keyset[parent, idx]
|
||||
typeparam(unique int tp: @typeparamtype ref, string name: string ref, int bound: @compositetype ref,
|
||||
int parent: @typeparamparentobject ref, int idx: int ref);
|
||||
|
||||
@container = @file | @folder;
|
||||
|
||||
@locatable = @xmllocatable | @node | @localscope;
|
||||
|
||||
@node = @documentable | @exprparent | @modexprparent | @fieldparent | @stmtparent | @declparent | @typeparamdeclparent
|
||||
| @scopenode | @comment_group | @comment;
|
||||
|
||||
@documentable = @file | @field | @typeparamdecl | @spec | @gendecl | @funcdecl | @modexpr;
|
||||
|
||||
@exprparent = @funcdef | @file | @expr | @field | @stmt | @decl | @typeparamdecl | @spec;
|
||||
|
||||
@modexprparent = @file | @modexpr;
|
||||
|
||||
@fieldparent = @decl | @structtypeexpr | @functypeexpr | @interfacetypeexpr;
|
||||
|
||||
@stmtparent = @funcdef | @stmt | @decl;
|
||||
|
||||
@declparent = @file | @declstmt;
|
||||
|
||||
@typeparamdeclparent = @funcdecl | @typespec;
|
||||
|
||||
@funcdef = @funclit | @funcdecl;
|
||||
|
||||
@scopenode = @file | @functypeexpr | @blockstmt | @ifstmt | @caseclause | @switchstmt | @commclause | @loopstmt;
|
||||
|
||||
@location = @location_default;
|
||||
|
||||
@sourceline = @locatable;
|
||||
|
||||
case @comment.kind of
|
||||
0 = @slashslashcomment
|
||||
| 1 = @slashstarcomment;
|
||||
|
||||
case @expr.kind of
|
||||
0 = @badexpr
|
||||
| 1 = @ident
|
||||
| 2 = @ellipsis
|
||||
| 3 = @intlit
|
||||
| 4 = @floatlit
|
||||
| 5 = @imaglit
|
||||
| 6 = @charlit
|
||||
| 7 = @stringlit
|
||||
| 8 = @funclit
|
||||
| 9 = @compositelit
|
||||
| 10 = @parenexpr
|
||||
| 11 = @selectorexpr
|
||||
| 12 = @indexexpr
|
||||
| 13 = @genericfunctioninstantiationexpr
|
||||
| 14 = @generictypeinstantiationexpr
|
||||
| 15 = @sliceexpr
|
||||
| 16 = @typeassertexpr
|
||||
| 17 = @callorconversionexpr
|
||||
| 18 = @starexpr
|
||||
| 19 = @keyvalueexpr
|
||||
| 20 = @arraytypeexpr
|
||||
| 21 = @structtypeexpr
|
||||
| 22 = @functypeexpr
|
||||
| 23 = @interfacetypeexpr
|
||||
| 24 = @maptypeexpr
|
||||
| 25 = @typesetliteralexpr
|
||||
| 26 = @plusexpr
|
||||
| 27 = @minusexpr
|
||||
| 28 = @notexpr
|
||||
| 29 = @complementexpr
|
||||
| 30 = @derefexpr
|
||||
| 31 = @addressexpr
|
||||
| 32 = @arrowexpr
|
||||
| 33 = @lorexpr
|
||||
| 34 = @landexpr
|
||||
| 35 = @eqlexpr
|
||||
| 36 = @neqexpr
|
||||
| 37 = @lssexpr
|
||||
| 38 = @leqexpr
|
||||
| 39 = @gtrexpr
|
||||
| 40 = @geqexpr
|
||||
| 41 = @addexpr
|
||||
| 42 = @subexpr
|
||||
| 43 = @orexpr
|
||||
| 44 = @xorexpr
|
||||
| 45 = @mulexpr
|
||||
| 46 = @quoexpr
|
||||
| 47 = @remexpr
|
||||
| 48 = @shlexpr
|
||||
| 49 = @shrexpr
|
||||
| 50 = @andexpr
|
||||
| 51 = @andnotexpr
|
||||
| 52 = @sendchantypeexpr
|
||||
| 53 = @recvchantypeexpr
|
||||
| 54 = @sendrcvchantypeexpr;
|
||||
|
||||
@basiclit = @intlit | @floatlit | @imaglit | @charlit | @stringlit;
|
||||
|
||||
@operatorexpr = @logicalexpr | @arithmeticexpr | @bitwiseexpr | @unaryexpr | @binaryexpr;
|
||||
|
||||
@logicalexpr = @logicalunaryexpr | @logicalbinaryexpr;
|
||||
|
||||
@arithmeticexpr = @arithmeticunaryexpr | @arithmeticbinaryexpr;
|
||||
|
||||
@bitwiseexpr = @bitwiseunaryexpr | @bitwisebinaryexpr;
|
||||
|
||||
@unaryexpr = @logicalunaryexpr | @bitwiseunaryexpr | @arithmeticunaryexpr | @derefexpr | @addressexpr | @arrowexpr;
|
||||
|
||||
@logicalunaryexpr = @notexpr;
|
||||
|
||||
@bitwiseunaryexpr = @complementexpr;
|
||||
|
||||
@arithmeticunaryexpr = @plusexpr | @minusexpr;
|
||||
|
||||
@binaryexpr = @logicalbinaryexpr | @bitwisebinaryexpr | @arithmeticbinaryexpr | @comparison;
|
||||
|
||||
@logicalbinaryexpr = @lorexpr | @landexpr;
|
||||
|
||||
@bitwisebinaryexpr = @shiftexpr | @orexpr | @xorexpr | @andexpr | @andnotexpr;
|
||||
|
||||
@arithmeticbinaryexpr = @addexpr | @subexpr | @mulexpr | @quoexpr | @remexpr;
|
||||
|
||||
@shiftexpr = @shlexpr | @shrexpr;
|
||||
|
||||
@comparison = @equalitytest | @relationalcomparison;
|
||||
|
||||
@equalitytest = @eqlexpr | @neqexpr;
|
||||
|
||||
@relationalcomparison = @lssexpr | @leqexpr | @gtrexpr | @geqexpr;
|
||||
|
||||
@chantypeexpr = @sendchantypeexpr | @recvchantypeexpr | @sendrcvchantypeexpr;
|
||||
|
||||
case @stmt.kind of
|
||||
0 = @badstmt
|
||||
| 1 = @declstmt
|
||||
| 2 = @emptystmt
|
||||
| 3 = @labeledstmt
|
||||
| 4 = @exprstmt
|
||||
| 5 = @sendstmt
|
||||
| 6 = @incstmt
|
||||
| 7 = @decstmt
|
||||
| 8 = @gostmt
|
||||
| 9 = @deferstmt
|
||||
| 10 = @returnstmt
|
||||
| 11 = @breakstmt
|
||||
| 12 = @continuestmt
|
||||
| 13 = @gotostmt
|
||||
| 14 = @fallthroughstmt
|
||||
| 15 = @blockstmt
|
||||
| 16 = @ifstmt
|
||||
| 17 = @caseclause
|
||||
| 18 = @exprswitchstmt
|
||||
| 19 = @typeswitchstmt
|
||||
| 20 = @commclause
|
||||
| 21 = @selectstmt
|
||||
| 22 = @forstmt
|
||||
| 23 = @rangestmt
|
||||
| 24 = @assignstmt
|
||||
| 25 = @definestmt
|
||||
| 26 = @addassignstmt
|
||||
| 27 = @subassignstmt
|
||||
| 28 = @mulassignstmt
|
||||
| 29 = @quoassignstmt
|
||||
| 30 = @remassignstmt
|
||||
| 31 = @andassignstmt
|
||||
| 32 = @orassignstmt
|
||||
| 33 = @xorassignstmt
|
||||
| 34 = @shlassignstmt
|
||||
| 35 = @shrassignstmt
|
||||
| 36 = @andnotassignstmt;
|
||||
|
||||
@incdecstmt = @incstmt | @decstmt;
|
||||
|
||||
@assignment = @simpleassignstmt | @compoundassignstmt;
|
||||
|
||||
@simpleassignstmt = @assignstmt | @definestmt;
|
||||
|
||||
@compoundassignstmt = @addassignstmt | @subassignstmt | @mulassignstmt | @quoassignstmt | @remassignstmt
|
||||
| @andassignstmt | @orassignstmt | @xorassignstmt | @shlassignstmt | @shrassignstmt | @andnotassignstmt;
|
||||
|
||||
@branchstmt = @breakstmt | @continuestmt | @gotostmt | @fallthroughstmt;
|
||||
|
||||
@switchstmt = @exprswitchstmt | @typeswitchstmt;
|
||||
|
||||
@loopstmt = @forstmt | @rangestmt;
|
||||
|
||||
case @decl.kind of
|
||||
0 = @baddecl
|
||||
| 1 = @importdecl
|
||||
| 2 = @constdecl
|
||||
| 3 = @typedecl
|
||||
| 4 = @vardecl
|
||||
| 5 = @funcdecl;
|
||||
|
||||
@gendecl = @importdecl | @constdecl | @typedecl | @vardecl;
|
||||
|
||||
case @spec.kind of
|
||||
0 = @importspec
|
||||
| 1 = @valuespec
|
||||
| 2 = @typedefspec
|
||||
| 3 = @aliasspec;
|
||||
|
||||
@typespec = @typedefspec | @aliasspec;
|
||||
|
||||
case @object.kind of
|
||||
0 = @pkgobject
|
||||
| 1 = @decltypeobject
|
||||
| 2 = @builtintypeobject
|
||||
| 3 = @declconstobject
|
||||
| 4 = @builtinconstobject
|
||||
| 5 = @declvarobject
|
||||
| 6 = @declfunctionobject
|
||||
| 7 = @builtinfunctionobject
|
||||
| 8 = @labelobject;
|
||||
|
||||
@typeparamparentobject = @decltypeobject | @declfunctionobject;
|
||||
|
||||
@declobject = @decltypeobject | @declconstobject | @declvarobject | @declfunctionobject;
|
||||
|
||||
@builtinobject = @builtintypeobject | @builtinconstobject | @builtinfunctionobject;
|
||||
|
||||
@typeobject = @decltypeobject | @builtintypeobject;
|
||||
|
||||
@valueobject = @constobject | @varobject | @functionobject;
|
||||
|
||||
@constobject = @declconstobject | @builtinconstobject;
|
||||
|
||||
@varobject = @declvarobject;
|
||||
|
||||
@functionobject = @declfunctionobject | @builtinfunctionobject;
|
||||
|
||||
case @scope.kind of
|
||||
0 = @universescope
|
||||
| 1 = @packagescope
|
||||
| 2 = @localscope;
|
||||
|
||||
case @type.kind of
|
||||
0 = @invalidtype
|
||||
| 1 = @boolexprtype
|
||||
| 2 = @inttype
|
||||
| 3 = @int8type
|
||||
| 4 = @int16type
|
||||
| 5 = @int32type
|
||||
| 6 = @int64type
|
||||
| 7 = @uinttype
|
||||
| 8 = @uint8type
|
||||
| 9 = @uint16type
|
||||
| 10 = @uint32type
|
||||
| 11 = @uint64type
|
||||
| 12 = @uintptrtype
|
||||
| 13 = @float32type
|
||||
| 14 = @float64type
|
||||
| 15 = @complex64type
|
||||
| 16 = @complex128type
|
||||
| 17 = @stringexprtype
|
||||
| 18 = @unsafepointertype
|
||||
| 19 = @boolliteraltype
|
||||
| 20 = @intliteraltype
|
||||
| 21 = @runeliteraltype
|
||||
| 22 = @floatliteraltype
|
||||
| 23 = @complexliteraltype
|
||||
| 24 = @stringliteraltype
|
||||
| 25 = @nilliteraltype
|
||||
| 26 = @typeparamtype
|
||||
| 27 = @arraytype
|
||||
| 28 = @slicetype
|
||||
| 29 = @structtype
|
||||
| 30 = @pointertype
|
||||
| 31 = @interfacetype
|
||||
| 32 = @tupletype
|
||||
| 33 = @signaturetype
|
||||
| 34 = @maptype
|
||||
| 35 = @sendchantype
|
||||
| 36 = @recvchantype
|
||||
| 37 = @sendrcvchantype
|
||||
| 38 = @definedtype
|
||||
| 39 = @typesetliteraltype;
|
||||
|
||||
@basictype = @booltype | @numerictype | @stringtype | @literaltype | @invalidtype | @unsafepointertype;
|
||||
|
||||
@booltype = @boolexprtype | @boolliteraltype;
|
||||
|
||||
@numerictype = @integertype | @floattype | @complextype;
|
||||
|
||||
@integertype = @signedintegertype | @unsignedintegertype;
|
||||
|
||||
@signedintegertype = @inttype | @int8type | @int16type | @int32type | @int64type | @intliteraltype | @runeliteraltype;
|
||||
|
||||
@unsignedintegertype = @uinttype | @uint8type | @uint16type | @uint32type | @uint64type | @uintptrtype;
|
||||
|
||||
@floattype = @float32type | @float64type | @floatliteraltype;
|
||||
|
||||
@complextype = @complex64type | @complex128type | @complexliteraltype;
|
||||
|
||||
@stringtype = @stringexprtype | @stringliteraltype;
|
||||
|
||||
@literaltype = @boolliteraltype | @intliteraltype | @runeliteraltype | @floatliteraltype | @complexliteraltype
|
||||
| @stringliteraltype | @nilliteraltype;
|
||||
|
||||
@compositetype = @typeparamtype | @containertype | @structtype | @pointertype | @interfacetype | @tupletype
|
||||
| @signaturetype | @definedtype | @typesetliteraltype;
|
||||
|
||||
@containertype = @arraytype | @slicetype | @maptype | @chantype;
|
||||
|
||||
@chantype = @sendchantype | @recvchantype | @sendrcvchantype;
|
||||
|
||||
case @modexpr.kind of
|
||||
0 = @modcommentblock
|
||||
| 1 = @modline
|
||||
| 2 = @modlineblock
|
||||
| 3 = @modlparen
|
||||
| 4 = @modrparen;
|
||||
|
||||
case @error.kind of
|
||||
0 = @unknownerror
|
||||
| 1 = @listerror
|
||||
| 2 = @parseerror
|
||||
| 3 = @typeerror;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
description: Add databaseMetadata and overlayChangedFiles relations
|
||||
compatibility: full
|
||||
databaseMetadata.rel: delete
|
||||
overlayChangedFiles.rel: delete
|
||||
1
go/extractor/cli/go-autobuilder/BUILD.bazel
generated
1
go/extractor/cli/go-autobuilder/BUILD.bazel
generated
@@ -12,6 +12,7 @@ go_library(
|
||||
"//go/extractor/autobuilder",
|
||||
"//go/extractor/diagnostics",
|
||||
"//go/extractor/project",
|
||||
"//go/extractor/srcarchive",
|
||||
"//go/extractor/toolchain",
|
||||
"//go/extractor/util",
|
||||
],
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/github/codeql-go/extractor/autobuilder"
|
||||
"github.com/github/codeql-go/extractor/diagnostics"
|
||||
"github.com/github/codeql-go/extractor/project"
|
||||
"github.com/github/codeql-go/extractor/srcarchive"
|
||||
"github.com/github/codeql-go/extractor/toolchain"
|
||||
"github.com/github/codeql-go/extractor/util"
|
||||
)
|
||||
@@ -273,7 +274,7 @@ func createPathTransformerFile(newdir string) *os.File {
|
||||
log.Fatalf("Failed to chdir into %s: %s\n", newdir, err.Error())
|
||||
}
|
||||
|
||||
// set up SEMMLE_PATH_TRANSFORMER to ensure paths in the source archive and the snapshot
|
||||
// set up CODEQL_PATH_TRANSFORMER to ensure paths in the source archive and the snapshot
|
||||
// match the original source location, not the location we moved it to
|
||||
pt, err := os.CreateTemp("", "path-transformer")
|
||||
if err != nil {
|
||||
@@ -283,7 +284,7 @@ func createPathTransformerFile(newdir string) *os.File {
|
||||
}
|
||||
|
||||
// Writes the path transformer file
|
||||
func writePathTransformerFile(pt *os.File, realSrc, root, newdir string) {
|
||||
func writePathTransformerFile(pt *os.File, realSrc, newdir string) {
|
||||
_, err := pt.WriteString("#" + realSrc + "\n" + newdir + "//\n")
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to write path transformer file: %s.", err.Error())
|
||||
@@ -292,9 +293,9 @@ func writePathTransformerFile(pt *os.File, realSrc, root, newdir string) {
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to close path transformer file: %s.", err.Error())
|
||||
}
|
||||
err = os.Setenv("SEMMLE_PATH_TRANSFORMER", pt.Name())
|
||||
err = os.Setenv("CODEQL_PATH_TRANSFORMER", pt.Name())
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to set SEMMLE_PATH_TRANSFORMER environment variable: %s.\n", err.Error())
|
||||
log.Fatalf("Unable to set CODEQL_PATH_TRANSFORMER environment variable: %s.\n", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,7 +448,7 @@ func installDependencies(workspace project.GoWorkspace) {
|
||||
}
|
||||
|
||||
// Run the extractor.
|
||||
func extract(workspace project.GoWorkspace) bool {
|
||||
func extract(workspace project.GoWorkspace, sourceRoot string) bool {
|
||||
extractor, err := util.GetExtractorPath()
|
||||
if err != nil {
|
||||
log.Fatalf("Could not determine path of extractor: %v.\n", err)
|
||||
@@ -458,6 +459,12 @@ func extract(workspace project.GoWorkspace) bool {
|
||||
extractorArgs = append(extractorArgs, workspace.ModMode.ArgsForGoVersion(toolchain.GetEnvGoSemVer())...)
|
||||
}
|
||||
|
||||
if util.IsOverlayExtraction() {
|
||||
// When we are extracting an overlay, pass the source root to the extractor so that it knows
|
||||
// how to resolve the relative paths in the list of changed files.
|
||||
extractorArgs = append(extractorArgs, "--source-root", sourceRoot)
|
||||
}
|
||||
|
||||
if len(workspace.Modules) == 0 {
|
||||
// There may be no modules if we are using e.g. Dep or Glide
|
||||
extractorArgs = append(extractorArgs, "./...")
|
||||
@@ -501,9 +508,6 @@ func installDependenciesAndBuild() {
|
||||
|
||||
srcdir := getSourceDir()
|
||||
|
||||
// we set `SEMMLE_PATH_TRANSFORMER` ourselves in some cases, so blank it out first for consistency
|
||||
os.Setenv("SEMMLE_PATH_TRANSFORMER", "")
|
||||
|
||||
// determine how to install dependencies and whether a GOPATH needs to be set up before
|
||||
// extraction
|
||||
workspaces := project.GetWorkspaceInfo(true)
|
||||
@@ -534,7 +538,21 @@ func installDependenciesAndBuild() {
|
||||
pt := createPathTransformerFile(paths.newdir)
|
||||
defer os.Remove(pt.Name())
|
||||
|
||||
writePathTransformerFile(pt, paths.realSrc, paths.root, paths.newdir)
|
||||
// We're about to create out own path transformer, so that paths containing the
|
||||
// temporary GOPATH point to the right location. However, if there was already an
|
||||
// incoming path transformer, the right location will be what _it_ wanted to transform
|
||||
// paths to.
|
||||
existingPathTransformer, err := srcarchive.LoadProjectLayoutFromEnv()
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to load path transformer: %s.\n", err.Error())
|
||||
}
|
||||
var realSrc string
|
||||
if existingPathTransformer == nil {
|
||||
realSrc = paths.realSrc
|
||||
} else {
|
||||
realSrc = existingPathTransformer.To
|
||||
}
|
||||
writePathTransformerFile(pt, realSrc, paths.newdir)
|
||||
setGopath(paths.root)
|
||||
}
|
||||
}
|
||||
@@ -575,6 +593,12 @@ func installDependenciesAndBuild() {
|
||||
buildWithCustomCommands(inst)
|
||||
}
|
||||
|
||||
// The autobuilder is invoked with its working directory set to the source directory.
|
||||
sourceRoot, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to get current working directory: %s\n", err.Error())
|
||||
}
|
||||
|
||||
// Attempt to extract all workspaces; we will tolerate individual extraction failures here
|
||||
for i, workspace := range workspaces {
|
||||
if workspace.ModMode == project.ModVendor {
|
||||
@@ -595,7 +619,7 @@ func installDependenciesAndBuild() {
|
||||
}
|
||||
}
|
||||
|
||||
workspaces[i].Extracted = extract(workspace)
|
||||
workspaces[i].Extracted = extract(workspace, sourceRoot)
|
||||
|
||||
if !workspaces[i].Extracted {
|
||||
unsuccessfulProjects = append(unsuccessfulProjects, workspace.BaseDir)
|
||||
@@ -620,6 +644,8 @@ func installDependenciesAndBuild() {
|
||||
} else {
|
||||
log.Printf("Success: extraction succeeded for all %d discovered project(s).\n", len(workspaces))
|
||||
}
|
||||
|
||||
util.WriteOverlayBaseMetadata()
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -24,9 +24,10 @@ func usage() {
|
||||
|
||||
// extractTests is set (a) if we were manually commanded to extract tests via the relevant
|
||||
// environment variable / extractor option, or (b) we're mimicking a `go test` command.
|
||||
func parseFlags(args []string, mimic bool, extractTests bool) ([]string, []string, bool) {
|
||||
func parseFlags(args []string, mimic bool, extractTests bool) ([]string, []string, bool, string) {
|
||||
i := 0
|
||||
buildFlags := []string{}
|
||||
var sourceRoot string
|
||||
for ; i < len(args) && strings.HasPrefix(args[i], "-"); i++ {
|
||||
if args[i] == "--" {
|
||||
i++
|
||||
@@ -61,6 +62,18 @@ func parseFlags(args []string, mimic bool, extractTests bool) ([]string, []strin
|
||||
} else {
|
||||
log.Fatalf("--mimic requires an argument, e.g. --mimic go")
|
||||
}
|
||||
case "--source-root":
|
||||
// The extractor can be called by the autobuilder with the working directory set to
|
||||
// the directory containing the workspace we're extracting, and this may be a
|
||||
// subdirectory of the actual source root. This argument lets us resolve paths that
|
||||
// are relative to that source root, e.g. for the list of overlay changed files.
|
||||
if i+1 < len(args) {
|
||||
i++
|
||||
sourceRoot = args[i]
|
||||
log.Printf("Source root is %s", sourceRoot)
|
||||
} else {
|
||||
log.Fatalf("--source-root requires an argument, e.g. --source-root /path/to/root")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,14 +106,14 @@ func parseFlags(args []string, mimic bool, extractTests bool) ([]string, []strin
|
||||
cpuprofile = os.Getenv("CODEQL_EXTRACTOR_GO_CPU_PROFILE")
|
||||
memprofile = os.Getenv("CODEQL_EXTRACTOR_GO_MEM_PROFILE")
|
||||
|
||||
return buildFlags, args[i:], extractTests
|
||||
return buildFlags, args[i:], extractTests, sourceRoot
|
||||
}
|
||||
|
||||
func main() {
|
||||
util.SetLogLevel()
|
||||
|
||||
extractTestsDefault := os.Getenv("CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_TESTS") == "true"
|
||||
buildFlags, patterns, extractTests := parseFlags(os.Args[1:], false, extractTestsDefault)
|
||||
buildFlags, patterns, extractTests, sourceRoot := parseFlags(os.Args[1:], false, extractTestsDefault)
|
||||
|
||||
if cpuprofile != "" {
|
||||
f, err := os.Create(cpuprofile)
|
||||
@@ -120,7 +133,7 @@ func main() {
|
||||
}
|
||||
|
||||
log.Printf("Build flags: '%s'; patterns: '%s'\n", strings.Join(buildFlags, " "), strings.Join(patterns, " "))
|
||||
err := extractor.ExtractWithFlags(buildFlags, patterns, extractTests)
|
||||
err := extractor.ExtractWithFlags(buildFlags, patterns, extractTests, sourceRoot)
|
||||
if err != nil {
|
||||
errString := err.Error()
|
||||
if strings.Contains(errString, "unexpected directory layout:") {
|
||||
|
||||
@@ -43,6 +43,17 @@ externalData(
|
||||
snapshotDate(unique date snapshotDate : date ref);
|
||||
|
||||
sourceLocationPrefix(varchar(900) prefix : string ref);
|
||||
|
||||
/** Overlay support **/
|
||||
|
||||
databaseMetadata(
|
||||
string metadataKey: string ref,
|
||||
string value: string ref
|
||||
);
|
||||
|
||||
overlayChangedFiles(
|
||||
string path: string ref
|
||||
);
|
||||
`)
|
||||
|
||||
// Copied directly from the XML dbscheme
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"go/types"
|
||||
"io"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -58,16 +59,11 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// Extract extracts the packages specified by the given patterns
|
||||
func Extract(patterns []string) error {
|
||||
return ExtractWithFlags(nil, patterns, false)
|
||||
}
|
||||
|
||||
// ExtractWithFlags extracts the packages specified by the given patterns and build flags
|
||||
func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool) error {
|
||||
func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool, sourceRoot string) error {
|
||||
startTime := time.Now()
|
||||
|
||||
extraction := NewExtraction(buildFlags, patterns)
|
||||
extraction := NewExtraction(buildFlags, patterns, sourceRoot)
|
||||
defer extraction.StatWriter.Close()
|
||||
|
||||
modEnabled := os.Getenv("GO111MODULE") != "off"
|
||||
@@ -323,16 +319,17 @@ func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool)
|
||||
type Extraction struct {
|
||||
// A lock for preventing concurrent writes to maps and the stat trap writer, as they are not
|
||||
// thread-safe
|
||||
Lock sync.Mutex
|
||||
LabelKey string
|
||||
Label trap.Label
|
||||
StatWriter *trap.Writer
|
||||
WaitGroup sync.WaitGroup
|
||||
GoroutineSem *semaphore
|
||||
FdSem *semaphore
|
||||
NextFileId int
|
||||
FileInfo map[string]*FileInfo
|
||||
SeenGoMods map[string]bool
|
||||
Lock sync.Mutex
|
||||
LabelKey string
|
||||
Label trap.Label
|
||||
StatWriter *trap.Writer
|
||||
WaitGroup sync.WaitGroup
|
||||
GoroutineSem *semaphore
|
||||
FdSem *semaphore
|
||||
NextFileId int
|
||||
FileInfo map[string]*FileInfo
|
||||
SeenGoMods map[string]bool
|
||||
OverlayChanges map[string]bool
|
||||
}
|
||||
|
||||
type FileInfo struct {
|
||||
@@ -367,7 +364,7 @@ func (extraction *Extraction) GetNextErr(path string) int {
|
||||
return res
|
||||
}
|
||||
|
||||
func NewExtraction(buildFlags []string, patterns []string) *Extraction {
|
||||
func NewExtraction(buildFlags []string, patterns []string, sourceRoot string) *Extraction {
|
||||
hash := md5.New()
|
||||
io.WriteString(hash, "go")
|
||||
for _, buildFlag := range buildFlags {
|
||||
@@ -379,6 +376,22 @@ func NewExtraction(buildFlags []string, patterns []string) *Extraction {
|
||||
}
|
||||
sum := hash.Sum(nil)
|
||||
|
||||
overlayChangeList := util.GetOverlayChanges(sourceRoot)
|
||||
var overlayChanges map[string]bool
|
||||
if overlayChangeList == nil {
|
||||
overlayChanges = nil
|
||||
} else {
|
||||
overlayChanges = make(map[string]bool)
|
||||
for _, changedFilePath := range overlayChangeList {
|
||||
absPath, err := filepath.Abs(changedFilePath)
|
||||
if err != nil {
|
||||
log.Fatalf("Error resolving absolute path of overlay change %s: %s", changedFilePath, err.Error())
|
||||
}
|
||||
overlayChanges[absPath] = true
|
||||
slog.Info("Overlay changed file", "path", absPath)
|
||||
}
|
||||
}
|
||||
|
||||
i := 0
|
||||
var path string
|
||||
// split compilation files into directories to avoid filling a single directory with too many files
|
||||
@@ -438,10 +451,11 @@ func NewExtraction(buildFlags []string, patterns []string) *Extraction {
|
||||
FdSem: newSemaphore(100),
|
||||
// this semaphore is used to limit the number of goroutines spawned, so we
|
||||
// don't run into memory issues
|
||||
GoroutineSem: newSemaphore(MaxGoRoutines),
|
||||
NextFileId: 0,
|
||||
FileInfo: make(map[string]*FileInfo),
|
||||
SeenGoMods: make(map[string]bool),
|
||||
GoroutineSem: newSemaphore(MaxGoRoutines),
|
||||
NextFileId: 0,
|
||||
FileInfo: make(map[string]*FileInfo),
|
||||
SeenGoMods: make(map[string]bool),
|
||||
OverlayChanges: overlayChanges,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,6 +734,16 @@ func (extraction *Extraction) extractFile(ast *ast.File, pkg *packages.Package)
|
||||
return nil
|
||||
}
|
||||
path := normalizedPath(ast, fset)
|
||||
// If we're extracting an overlay, we want to skip extraction of files that haven't changed.
|
||||
// Since some files may be outside the source directory (e.g. files preprocessed by cgo) we
|
||||
// can't easily know if they have changed (or came from source files that changed), so we always
|
||||
// extract a file if it's not in the package directory.
|
||||
if extraction.OverlayChanges != nil &&
|
||||
!extraction.OverlayChanges[path] &&
|
||||
strings.HasPrefix(path+string(filepath.Separator), pkg.Dir) {
|
||||
slog.Info("Skipping unchanged file in overlay extraction", "path", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
extraction.FdSem.acquire(3)
|
||||
|
||||
@@ -791,12 +815,12 @@ func (extraction *Extraction) extractFileInfo(tw *trap.Writer, file string, isDu
|
||||
displayPath = rawPath
|
||||
}
|
||||
if i == len(components)-1 {
|
||||
lbl := tw.Labeler.FileLabelFor(file)
|
||||
lbl := tw.Labeler.FileLabelFor(path)
|
||||
dbscheme.FilesTable.Emit(tw, lbl, displayPath)
|
||||
dbscheme.ContainerParentTable.Emit(tw, parentLbl, lbl)
|
||||
dbscheme.HasLocationTable.Emit(tw, lbl, emitLocation(tw, lbl, 0, 0, 0, 0))
|
||||
extraction.Lock.Lock()
|
||||
slbl := extraction.StatWriter.Labeler.FileLabelFor(file)
|
||||
slbl := extraction.StatWriter.Labeler.FileLabelFor(path)
|
||||
if !isDummy {
|
||||
dbscheme.CompilationCompilingFilesTable.Emit(extraction.StatWriter, extraction.Label, extraction.GetFileIdx(file), slbl)
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ toolchain go1.25.0
|
||||
// when adding or removing dependencies, run
|
||||
// bazel mod tidy
|
||||
require (
|
||||
golang.org/x/mod v0.29.0
|
||||
golang.org/x/tools v0.38.0
|
||||
golang.org/x/mod v0.30.0
|
||||
golang.org/x/tools v0.39.0
|
||||
)
|
||||
|
||||
require golang.org/x/sync v0.17.0 // indirect
|
||||
require golang.org/x/sync v0.18.0 // indirect
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||
|
||||
@@ -20,6 +20,11 @@ func (extraction *Extraction) extractGoMod(path string) error {
|
||||
path = normPath
|
||||
}
|
||||
|
||||
if extraction.OverlayChanges != nil && !extraction.OverlayChanges[path] {
|
||||
// This go.mod did not change since the base was extracted
|
||||
return nil
|
||||
}
|
||||
|
||||
extraction.Lock.Lock()
|
||||
if extraction.SeenGoMods[path] {
|
||||
extraction.Lock.Unlock()
|
||||
|
||||
1
go/extractor/srcarchive/BUILD.bazel
generated
1
go/extractor/srcarchive/BUILD.bazel
generated
@@ -10,6 +10,7 @@ go_library(
|
||||
],
|
||||
importpath = "github.com/github/codeql-go/extractor/srcarchive",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//go/extractor/util"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/github/codeql-go/extractor/util"
|
||||
)
|
||||
|
||||
// ProjectLayout describes a very simple project layout rewriting paths starting
|
||||
@@ -16,7 +18,7 @@ import (
|
||||
// # to
|
||||
// from//
|
||||
type ProjectLayout struct {
|
||||
from, to string
|
||||
From, To string
|
||||
}
|
||||
|
||||
// normaliseSlashes adds an initial slash to `path` if there isn't one, and trims
|
||||
@@ -28,6 +30,25 @@ func normaliseSlashes(path string) string {
|
||||
return strings.TrimSuffix(path, "/")
|
||||
}
|
||||
|
||||
// LoadProjectLayoutFromEnv loads a project layout from the file referenced by the
|
||||
// {CODEQL,SEMMLE}_PATH_TRANSFORMER environment variable. If neither env var is set, returns nil. If
|
||||
// the file cannot be read or does not have the right format, it returns an error.
|
||||
func LoadProjectLayoutFromEnv() (*ProjectLayout, error) {
|
||||
pt := util.Getenv("CODEQL_PATH_TRANSFORMER", "SEMMLE_PATH_TRANSFORMER")
|
||||
if pt == "" {
|
||||
return nil, nil
|
||||
}
|
||||
ptf, err := os.Open(pt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
projLayout, err := LoadProjectLayout(ptf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return projLayout, nil
|
||||
}
|
||||
|
||||
// LoadProjectLayout loads a project layout from the given file, returning an error
|
||||
// if the file does not have the right format
|
||||
func LoadProjectLayout(file *os.File) (*ProjectLayout, error) {
|
||||
@@ -41,7 +62,7 @@ func LoadProjectLayout(file *os.File) (*ProjectLayout, error) {
|
||||
if !strings.HasPrefix(line, "#") {
|
||||
return nil, fmt.Errorf("first line of project layout should start with #, but got %s", line)
|
||||
}
|
||||
res.to = normaliseSlashes(strings.TrimSpace(strings.TrimPrefix(line, "#")))
|
||||
res.To = normaliseSlashes(strings.TrimSpace(strings.TrimPrefix(line, "#")))
|
||||
|
||||
if !scanner.Scan() {
|
||||
return nil, errors.New("empty section in project-layout file")
|
||||
@@ -57,7 +78,7 @@ func LoadProjectLayout(file *os.File) (*ProjectLayout, error) {
|
||||
if strings.HasPrefix(line, "-") || strings.Contains(line, "*") || strings.Contains(line, "//") {
|
||||
return nil, errors.New("unsupported project-layout feature")
|
||||
}
|
||||
res.from = normaliseSlashes(line)
|
||||
res.From = normaliseSlashes(line)
|
||||
|
||||
for scanner.Scan() {
|
||||
if strings.TrimSpace(scanner.Text()) != "" {
|
||||
@@ -71,11 +92,11 @@ func LoadProjectLayout(file *os.File) (*ProjectLayout, error) {
|
||||
// transformString transforms `str` as specified by the project layout: if it starts with the `from`
|
||||
// prefix, that prefix is relaced by `to`; otherwise the string is returned unchanged
|
||||
func (p *ProjectLayout) transformString(str string) string {
|
||||
if str == p.from {
|
||||
return p.to
|
||||
if str == p.From {
|
||||
return p.To
|
||||
}
|
||||
if strings.HasPrefix(str, p.from+"/") {
|
||||
return p.to + "/" + str[len(p.from)+1:]
|
||||
if strings.HasPrefix(str, p.From+"/") {
|
||||
return p.To + "/" + str[len(p.From)+1:]
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
@@ -28,6 +28,32 @@ func mkProjectLayout(projectLayoutSource string, t *testing.T) (*ProjectLayout,
|
||||
return LoadProjectLayout(pt)
|
||||
}
|
||||
|
||||
func mkProjectLayoutFromEnv(projectLayoutSource string, t *testing.T) (*ProjectLayout, error) {
|
||||
pt, err := os.CreateTemp("", "path-transformer-from-env")
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create temporary file for project layout: %s", err.Error())
|
||||
}
|
||||
defer os.Remove(pt.Name())
|
||||
_, err = pt.WriteString(projectLayoutSource)
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to write to temporary file for project layout: %s", err.Error())
|
||||
}
|
||||
err = pt.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to close path transformer file: %s.", err.Error())
|
||||
}
|
||||
|
||||
pt, err = os.Open(pt.Name())
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to open path transformer file: %s.", err.Error())
|
||||
}
|
||||
|
||||
os.Setenv("CODEQL_PATH_TRANSFORMER", pt.Name())
|
||||
defer os.Unsetenv("CODEQL_PATH_TRANSFORMER")
|
||||
|
||||
return LoadProjectLayoutFromEnv()
|
||||
}
|
||||
|
||||
func testTransformation(projectLayout *ProjectLayout, t *testing.T, path string, expected string) {
|
||||
actual := projectLayout.Transform(path)
|
||||
if actual != expected {
|
||||
@@ -35,16 +61,12 @@ func testTransformation(projectLayout *ProjectLayout, t *testing.T, path string,
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidProjectLayout(t *testing.T) {
|
||||
p, err := mkProjectLayout(`
|
||||
const validProjectLayoutSource = `
|
||||
# /opt/src
|
||||
/opt/src/root/src/org/repo//
|
||||
`, t)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading project layout: %s", err.Error())
|
||||
}
|
||||
`
|
||||
|
||||
func testTransformationsForValidProjectLayout(p *ProjectLayout, t *testing.T) {
|
||||
testTransformation(p, t, "/opt/src/root/src/org/repo", "/opt/src")
|
||||
testTransformation(p, t, "/opt/src/root/src/org/repo/", "/opt/src/")
|
||||
testTransformation(p, t, "/opt/src/root/src/org/repo/main.go", "/opt/src/main.go")
|
||||
@@ -53,6 +75,26 @@ func TestValidProjectLayout(t *testing.T) {
|
||||
testTransformation(p, t, "opt/src/root/src/org/repo", "opt/src/root/src/org/repo")
|
||||
}
|
||||
|
||||
func TestValidProjectLayout(t *testing.T) {
|
||||
p, err := mkProjectLayout(validProjectLayoutSource, t)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading project layout: %s", err.Error())
|
||||
}
|
||||
|
||||
testTransformationsForValidProjectLayout(p, t)
|
||||
}
|
||||
|
||||
func TestValidProjectLayoutFromEnv(t *testing.T) {
|
||||
p, err := mkProjectLayoutFromEnv(validProjectLayoutSource, t)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading project layout: %s", err.Error())
|
||||
}
|
||||
|
||||
testTransformationsForValidProjectLayout(p, t)
|
||||
}
|
||||
|
||||
func TestWindowsPaths(t *testing.T) {
|
||||
p, err := mkProjectLayout(`
|
||||
# /c:/virtual
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -12,16 +13,14 @@ import (
|
||||
var pathTransformer *ProjectLayout
|
||||
|
||||
func init() {
|
||||
pt := os.Getenv("SEMMLE_PATH_TRANSFORMER")
|
||||
if pt != "" {
|
||||
ptf, err := os.Open(pt)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to open path transformer %s: %s.\n", pt, err.Error())
|
||||
}
|
||||
pathTransformer, err = LoadProjectLayout(ptf)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to initialize path transformer: %s.\n", err.Error())
|
||||
pt, err := LoadProjectLayoutFromEnv()
|
||||
if err == nil {
|
||||
pathTransformer = pt
|
||||
if pathTransformer != nil {
|
||||
slog.Info("Loaded path transformer", "from", pathTransformer.From, "to", pathTransformer.To)
|
||||
}
|
||||
} else {
|
||||
log.Fatalf("Unable to load path transformer: %s.\n", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +68,7 @@ func srcArchive() (string, error) {
|
||||
return srcArchive, nil
|
||||
}
|
||||
|
||||
// TransformPath applies the transformations specified by `SEMMLE_PATH_TRANSFORMER` (if any) to the
|
||||
// TransformPath applies the transformations specified by `CODEQL_PATH_TRANSFORMER` (if any) to the
|
||||
// given path
|
||||
func TransformPath(path string) string {
|
||||
if pathTransformer != nil {
|
||||
|
||||
@@ -3,7 +3,9 @@ package trap
|
||||
import (
|
||||
"fmt"
|
||||
"go/types"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/github/codeql-go/extractor/srcarchive"
|
||||
"github.com/github/codeql-go/extractor/util"
|
||||
)
|
||||
|
||||
@@ -67,14 +69,14 @@ func (l *Labeler) GlobalID(key string) Label {
|
||||
// FileLabel returns the label for a file with path `path`.
|
||||
func (l *Labeler) FileLabel() Label {
|
||||
if l.fileLabel == InvalidLabel {
|
||||
l.fileLabel = l.FileLabelFor(l.tw.path)
|
||||
l.fileLabel = l.FileLabelFor(srcarchive.TransformPath(l.tw.path))
|
||||
}
|
||||
return l.fileLabel
|
||||
}
|
||||
|
||||
// FileLabelFor returns the label for the file for which the trap writer `tw` is associated
|
||||
func (l *Labeler) FileLabelFor(path string) Label {
|
||||
return l.GlobalID(util.EscapeTrapSpecialChars(path) + ";sourcefile")
|
||||
return l.GlobalID(util.EscapeTrapSpecialChars(filepath.ToSlash(path)) + ";sourcefile")
|
||||
}
|
||||
|
||||
// LocalID associates a label with the given AST node `nd` and returns it
|
||||
|
||||
1
go/extractor/util/BUILD.bazel
generated
1
go/extractor/util/BUILD.bazel
generated
@@ -7,6 +7,7 @@ go_library(
|
||||
srcs = [
|
||||
"extractvendordirs.go",
|
||||
"logging.go",
|
||||
"overlays.go",
|
||||
"registryproxy.go",
|
||||
"semver.go",
|
||||
"util.go",
|
||||
|
||||
70
go/extractor/util/overlays.go
Normal file
70
go/extractor/util/overlays.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func IsOverlayExtraction() bool {
|
||||
_, present := os.LookupEnv("CODEQL_EXTRACTOR_GO_OVERLAY_METADATA_IN")
|
||||
return present
|
||||
}
|
||||
|
||||
// If the relevant environment variable is set, indicating that we are extracting an overlay
|
||||
// database, GetOverlayChanges returns the list of relative paths of files that have changed (or
|
||||
// been deleted). Otherwise, it returns `nil`.
|
||||
func GetOverlayChanges(sourceRoot string) []string {
|
||||
if overlayChangesJsonPath, present := os.LookupEnv("CODEQL_EXTRACTOR_GO_OVERLAY_CHANGES"); present {
|
||||
log.Printf("Reading overlay changes from: %s", overlayChangesJsonPath)
|
||||
|
||||
file, err := os.Open(overlayChangesJsonPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open overlay changes JSON file: %s", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var overlayData struct {
|
||||
Changes []string `json:"changes"`
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(file)
|
||||
if err := decoder.Decode(&overlayData); err != nil {
|
||||
log.Fatalf("Failed to decode overlay changes JSON file: %s", err)
|
||||
}
|
||||
|
||||
absPaths := make([]string, 0, len(overlayData.Changes))
|
||||
if sourceRoot == "" {
|
||||
// This shouldn't happen, because it implies the extractor was invoked in some way other
|
||||
// than from the autobuilder. However, we'll only attempt to build an overlay if there
|
||||
// exists an overlay _base_, and only the autobuilder writes the metadata file that
|
||||
// ensures a database is created as an overlay-base.
|
||||
log.Fatalf("Extractor is running in overlay mode, but --source-root was not provided")
|
||||
}
|
||||
for _, relPath := range overlayData.Changes {
|
||||
absPaths = append(absPaths, filepath.Clean(sourceRoot+"/"+relPath))
|
||||
}
|
||||
|
||||
return absPaths
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WriteOverlayBaseMetadata creates an empty metadata file if we are extracting an overlay base;
|
||||
// otherwise, it does nothing.
|
||||
func WriteOverlayBaseMetadata() {
|
||||
if metadataPath, present := os.LookupEnv("CODEQL_EXTRACTOR_GO_OVERLAY_BASE_METADATA_OUT"); present {
|
||||
log.Printf("Writing overlay base metadata to: %s", metadataPath)
|
||||
|
||||
// In principle, we could store some metadata here and read it back when extracting the
|
||||
// overlay. For now, we don't need to store anything, but the CLI still requires us to write
|
||||
// something, so just create an empty file.
|
||||
file, err := os.Create(metadataPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create overlay base metadata file: %s", err)
|
||||
}
|
||||
file.Close()
|
||||
}
|
||||
}
|
||||
7
go/ql/lib/change-notes/2025-11-11-path-transformer.md
Normal file
7
go/ql/lib/change-notes/2025-11-11-path-transformer.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Some fixes relating to use of path transformers when extracting a database:
|
||||
* Fixed a problem where the path transformer would be ignored when extracting older codebases that predate the use of Go modules.
|
||||
* The environment variable `CODEQL_PATH_TRANSFORMER` is now recognized, in addition to `SEMMLE_PATH_TRANSFORMER`.
|
||||
* Fixed some cases where the extractor emitted paths without applying the path transformer.
|
||||
@@ -36,6 +36,17 @@ snapshotDate(unique date snapshotDate : date ref);
|
||||
|
||||
sourceLocationPrefix(varchar(900) prefix : string ref);
|
||||
|
||||
/** Overlay support **/
|
||||
|
||||
databaseMetadata(
|
||||
string metadataKey: string ref,
|
||||
string value: string ref
|
||||
);
|
||||
|
||||
overlayChangedFiles(
|
||||
string path: string ref
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* XML Files
|
||||
|
||||
@@ -14,3 +14,4 @@ dependencies:
|
||||
dataExtensions:
|
||||
- ext/*.model.yml
|
||||
warnOnImplicitThis: true
|
||||
compileForOverlayEval: true
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Provides classes for working with locations and program elements that have locations. */
|
||||
|
||||
import go
|
||||
private import semmle.go.Overlay
|
||||
|
||||
/**
|
||||
* A location as given by a file, a start line, a start column,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user