diff --git a/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs b/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs index 983175f4c17..56a20473fa3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs @@ -80,11 +80,11 @@ internal sealed class StubVisitor : SymbolVisitor stubWriter.Write(explicitInterfaceType.GetQualifiedName()); stubWriter.Write('.'); if (writeName) - stubWriter.Write(explicitInterfaceSymbol.GetName()); + stubWriter.Write(EscapeIdentifier(explicitInterfaceSymbol.GetName())); } else if (writeName) { - stubWriter.Write(symbol.GetName()); + stubWriter.Write(EscapeIdentifier(symbol.GetName())); } } @@ -557,6 +557,9 @@ internal sealed class StubVisitor : SymbolVisitor }); } + private static bool ExcludeMethod(IMethodSymbol symbol) => + symbol.Name == "$"; + private void StubMethod(IMethodSymbol symbol, IMethodSymbol? explicitInterfaceSymbol, IMethodSymbol? baseCtor) { var methodKind = explicitInterfaceSymbol is null ? symbol.MethodKind : explicitInterfaceSymbol.MethodKind; @@ -568,7 +571,7 @@ internal sealed class StubVisitor : SymbolVisitor MethodKind.Ordinary }; - if (!relevantMethods.Contains(methodKind)) + if (!relevantMethods.Contains(methodKind) || ExcludeMethod(symbol)) return; StubAttributes(symbol.GetAttributes()); diff --git a/csharp/extractor/Semmle.Extraction.Tests/StubGenerator.cs b/csharp/extractor/Semmle.Extraction.Tests/StubGenerator.cs index ea60c60bad6..3fcda88bc32 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/StubGenerator.cs +++ b/csharp/extractor/Semmle.Extraction.Tests/StubGenerator.cs @@ -76,6 +76,26 @@ public int M1(ref readonly Guid guid) => throw null; Assert.Equal(expected, stub); } + [Fact] + public void StubGeneratorEscapeMethodName() + { + // Setup + const string source = @" +public class MyTest { + public int @default() { return 0; } +}"; + + // Execute + var stub = GenerateStub(source); + + // Verify + const string expected = @"public class MyTest { +public int @default() => throw null; +} +"; + Assert.Equal(expected, stub); + } + private static string GenerateStub(string source) { var st = CSharpSyntaxTree.ParseText(source); diff --git a/csharp/ql/test/resources/stubs/ServiceStack.Common/8.0.0/ServiceStack.Common.cs b/csharp/ql/test/resources/stubs/ServiceStack.Common/8.0.0/ServiceStack.Common.cs index 67302ffe2d5..2e13f82b81f 100644 --- a/csharp/ql/test/resources/stubs/ServiceStack.Common/8.0.0/ServiceStack.Common.cs +++ b/csharp/ql/test/resources/stubs/ServiceStack.Common/8.0.0/ServiceStack.Common.cs @@ -1436,10 +1436,14 @@ namespace ServiceStack public long decrBy(long value, long by) => throw null; public long decrement(long value) => throw null; public long decrementBy(long value, long by) => throw null; + public object @default(object returnTarget, object elseReturn) => throw null; public string dirPath(string filePath) => throw null; public System.Collections.Generic.IEnumerable distinct(System.Collections.Generic.IEnumerable items) => throw null; public double div(double lhs, double rhs) => throw null; public double divide(double lhs, double rhs) => throw null; + public object @do(ServiceStack.Script.ScriptScopeContext scope, object expression) => throw null; + public System.Threading.Tasks.Task @do(ServiceStack.Script.ScriptScopeContext scope, object target, object expression) => throw null; + public System.Threading.Tasks.Task @do(ServiceStack.Script.ScriptScopeContext scope, object target, object expression, object scopeOptions) => throw null; public object doIf(object test) => throw null; public object doIf(object ignoreTarget, object test) => throw null; public double doubleAdd(double lhs, double rhs) => throw null; @@ -1558,6 +1562,8 @@ namespace ServiceStack public string httpPathInfo(ServiceStack.Script.ScriptScopeContext scope) => throw null; public string httpRequestUrl(ServiceStack.Script.ScriptScopeContext scope) => throw null; public string humanize(string text) => throw null; + public object @if(object test) => throw null; + public object @if(object returnTarget, object test) => throw null; public object ifDebug(ServiceStack.Script.ScriptScopeContext scope, object ignoreTarget) => throw null; public object ifDebug(ServiceStack.Script.ScriptScopeContext scope) => throw null; public object ifDo(object test) => throw null; @@ -1840,6 +1846,9 @@ namespace ServiceStack public object resolveContextArg(ServiceStack.Script.ScriptScopeContext scope, string name) => throw null; public object resolveGlobal(ServiceStack.Script.ScriptScopeContext scope, string name) => throw null; public object resolvePageArg(ServiceStack.Script.ScriptScopeContext scope, string name) => throw null; + public ServiceStack.Script.StopExecution @return(ServiceStack.Script.ScriptScopeContext scope) => throw null; + public ServiceStack.Script.StopExecution @return(ServiceStack.Script.ScriptScopeContext scope, object returnValue) => throw null; + public ServiceStack.Script.StopExecution @return(ServiceStack.Script.ScriptScopeContext scope, object returnValue, System.Collections.Generic.Dictionary returnArgs) => throw null; public System.Collections.Generic.IEnumerable reverse(ServiceStack.Script.ScriptScopeContext scope, System.Collections.Generic.IEnumerable original) => throw null; public string rightPart(string text, string needle) => throw null; public double round(double value) => throw null; @@ -1930,6 +1939,8 @@ namespace ServiceStack public System.Collections.Generic.IEnumerable thenByDescending(ServiceStack.Script.ScriptScopeContext scope, object target, object expression) => throw null; public System.Collections.Generic.IEnumerable thenByDescending(ServiceStack.Script.ScriptScopeContext scope, object target, object expression, object scopeOptions) => throw null; public static System.Collections.Generic.IEnumerable thenByInternal(string filterName, ServiceStack.Script.ScriptScopeContext scope, object target, object expression, object scopeOptions) => throw null; + public object @throw(ServiceStack.Script.ScriptScopeContext scope, string message) => throw null; + public object @throw(ServiceStack.Script.ScriptScopeContext scope, string message, object options) => throw null; public object throwArgumentException(ServiceStack.Script.ScriptScopeContext scope, string message) => throw null; public object throwArgumentException(ServiceStack.Script.ScriptScopeContext scope, string message, string options) => throw null; public object throwArgumentNullException(ServiceStack.Script.ScriptScopeContext scope, string paramName) => throw null; @@ -3163,6 +3174,7 @@ namespace ServiceStack public ProtectedScripts() => throw null; public ServiceStack.Script.IgnoreResult Decrypt(string path) => throw null; public ServiceStack.Script.IgnoreResult Decrypt(ServiceStack.Script.FileScripts fs, string path) => throw null; + public object @default(string typeName) => throw null; public ServiceStack.Script.IgnoreResult Delete(string path) => throw null; public ServiceStack.Script.IgnoreResult Delete(ServiceStack.Script.IOScript os, string path) => throw null; public string deleteDirectory(string virtualPath) => throw null; @@ -3253,6 +3265,8 @@ namespace ServiceStack public ServiceStack.Script.IgnoreResult Move(string from, string to) => throw null; public ServiceStack.Script.IgnoreResult Move(ServiceStack.Script.IOScript os, string from, string to) => throw null; public string mv(ServiceStack.Script.ScriptScopeContext scope, string from, string to) => throw null; + public object @new(string typeName) => throw null; + public object @new(string typeName, System.Collections.Generic.List constructorArgs) => throw null; public string osPaths(string path) => throw null; public string proc(ServiceStack.Script.ScriptScopeContext scope, string fileName) => throw null; public string proc(ServiceStack.Script.ScriptScopeContext scope, string fileName, System.Collections.Generic.Dictionary options) => throw null; @@ -3284,6 +3298,7 @@ namespace ServiceStack public string textContents(ServiceStack.IO.IVirtualFile file) => throw null; public string touch(ServiceStack.Script.ScriptScopeContext scope, string target) => throw null; public static string TypeNotFoundErrorMessage(string typeName) => throw null; + public System.Type @typeof(string typeName) => throw null; public System.Type typeofProgId(string name) => throw null; public string typeQualifiedName(System.Type type) => throw null; public System.ReadOnlyMemory urlBytesContents(ServiceStack.Script.ScriptScopeContext scope, string url, object options) => throw null; diff --git a/csharp/scripts/stubs/helpers.py b/csharp/scripts/stubs/helpers.py index 3c6bb8bdd3b..aa82ad3f36b 100644 --- a/csharp/scripts/stubs/helpers.py +++ b/csharp/scripts/stubs/helpers.py @@ -3,6 +3,7 @@ import os import subprocess import json import shutil +import re def run_cmd(cmd, msg="Failed to run command"): print('Running ' + ' '.join(cmd)) @@ -191,7 +192,8 @@ class Generator: if 'dependencies' in data['targets'][target][package]: for dependency in data['targets'][target][package]['dependencies'].keys(): - depVersion = data['targets'][target][package]['dependencies'][dependency] + depString = data['targets'][target][package]['dependencies'][dependency] + depVersion = re.search("(\d+\.\d+\.\d+(-[a-z]+)?)", depString).group(0) pf.write(' \n')