예제 #1
0
        public async Task PinvokeMethodReferences_VB()
        {
            var tree = Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTree.ParseText(
                @"
Module Module1
        Declare Function CreateDirectory Lib ""kernel32"" Alias ""CreateDirectoryA"" (ByVal lpPathName As String) As Integer
 
        Private prop As Integer
        Property Prop1 As Integer
            Get
                Return prop
            End Get
            Set(value As Integer)
                CreateDirectory(""T"")  ' Method Call 1
                prop = value
                prop = Nothing
            End Set
        End Property

        Sub Main()
          CreateDirectory(""T"") 'Method Call 2            
          NormalMethod() ' Method Call 1
          NormalMethod() ' Method Call 2
       End Sub

       Sub NormalMethod()
       End Sub
 End Module
            ");

            var prj1Id = ProjectId.CreateNewId();
            var docId  = DocumentId.CreateNewId(prj1Id);

            var sln = new AdhocWorkspace().CurrentSolution
                      .AddProject(prj1Id, "testDeclareReferences", "testAssembly", LanguageNames.VisualBasic)
                      .AddMetadataReference(prj1Id, MscorlibRef)
                      .AddDocument(docId, "testFile", tree.GetText());

            var prj = sln.GetProject(prj1Id).WithCompilationOptions(new VisualBasic.VisualBasicCompilationOptions(OutputKind.ConsoleApplication, embedVbCoreRuntime: true));

            tree = await prj.GetDocument(docId).GetSyntaxTreeAsync();

            var comp = await prj.GetCompilationAsync();

            var semanticModel = comp.GetSemanticModel(tree);

            SyntaxNode declareMethod = tree.GetRoot().DescendantNodes().OfType <Microsoft.CodeAnalysis.VisualBasic.Syntax.DeclareStatementSyntax>().FirstOrDefault();
            SyntaxNode normalMethod  = tree.GetRoot().DescendantNodes().OfType <Microsoft.CodeAnalysis.VisualBasic.Syntax.MethodStatementSyntax>().ToList()[1];

            // declared method calls
            var symbol     = semanticModel.GetDeclaredSymbol(declareMethod);
            var references = await SymbolFinder.FindReferencesAsync(symbol, prj.Solution);

            Assert.Equal(expected: 2, actual: references.ElementAt(0).Locations.Count());

            // normal method calls
            symbol     = semanticModel.GetDeclaredSymbol(normalMethod);
            references = await SymbolFinder.FindReferencesAsync(symbol, prj.Solution);

            Assert.Equal(expected: 2, actual: references.ElementAt(0).Locations.Count());
        }
예제 #2
0
        public async Task PinvokeMethodReferences_CS()
        {
            var tree = Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(
                @"

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
static class Module1
{
	[DllImport(""kernel32"", EntryPoint = ""CreateDirectoryA"", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern int CreateDirectory(string lpPathName);

        private static int prop;
        public static int Prop1
        {
            get { return prop; }
            set
            {
                CreateDirectory(""T"");
                // Method Call 1
                prop = value;
                prop = null;
            }
        }

        public static void Main()
        {
            CreateDirectory(""T""); // Method Call 2            
            NormalMethod(); // Method Call 1
            NormalMethod(); // Method Call 2
        }

        public static void NormalMethod()
        {
        }
    }
                ");

            var prj1Id = ProjectId.CreateNewId();
            var docId  = DocumentId.CreateNewId(prj1Id);

            var sln = new AdhocWorkspace().CurrentSolution
                      .AddProject(prj1Id, "testDeclareReferences", "testAssembly", LanguageNames.CSharp)
                      .AddMetadataReference(prj1Id, MscorlibRef)
                      .AddDocument(docId, "testFile", tree.GetText());

            var prj = sln.GetProject(prj1Id).WithCompilationOptions(new CSharp.CSharpCompilationOptions(OutputKind.ConsoleApplication));

            tree = await prj.GetDocument(docId).GetSyntaxTreeAsync();

            var comp = await prj.GetCompilationAsync();

            var semanticModel = comp.GetSemanticModel(tree);

            var        methodlist    = tree.GetRoot().DescendantNodes().OfType <Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax>().ToList();
            SyntaxNode declareMethod = methodlist.ElementAt(0);
            SyntaxNode normalMethod  = methodlist.ElementAt(2);

            // pinvoke method calls
            var symbol     = semanticModel.GetDeclaredSymbol(declareMethod);
            var references = await SymbolFinder.FindReferencesAsync(symbol, prj.Solution);

            Assert.Equal(2, references.ElementAt(0).Locations.Count());

            // normal method calls
            symbol     = semanticModel.GetDeclaredSymbol(normalMethod);
            references = await SymbolFinder.FindReferencesAsync(symbol, prj.Solution);

            Assert.Equal(2, references.ElementAt(0).Locations.Count());
        }
        /// <summary>
        /// Creates a solution that will be used as parent for the sources that need to be checked.
        /// </summary>
        /// <param name="projectId">The project identifier to use.</param>
        /// <param name="language">The language for which the solution is being created.</param>
        /// <returns>The created solution.</returns>
        protected virtual Solution CreateSolution(ProjectId projectId, string language)
        {
            var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true);

            Solution solution = new AdhocWorkspace()
                                .CurrentSolution
                                .AddProject(projectId, TestProjectName, TestProjectName, language)
                                .WithProjectCompilationOptions(projectId, compilationOptions)
                                .AddMetadataReference(projectId, MetadataReferences.CorlibReference)
                                .AddMetadataReference(projectId, MetadataReferences.SystemReference)
                                .AddMetadataReference(projectId, MetadataReferences.SystemCoreReference)
                                .AddMetadataReference(projectId, MetadataReferences.CSharpSymbolsReference)
                                .AddMetadataReference(projectId, MetadataReferences.CodeAnalysisReference);

            solution.Workspace.Options =
                solution.Workspace.Options
                .WithChangedOption(FormattingOptions.IndentationSize, language, this.IndentationSize)
                .WithChangedOption(FormattingOptions.TabSize, language, this.TabSize)
                .WithChangedOption(FormattingOptions.UseTabs, language, this.UseTabs);

            var settings = this.GetSettings();

            StyleCopSettings defaultSettings = new StyleCopSettings();

            if (this.IndentationSize != defaultSettings.Indentation.IndentationSize ||
                this.UseTabs != defaultSettings.Indentation.UseTabs ||
                this.TabSize != defaultSettings.Indentation.TabSize)
            {
                var indentationSettings = $@"
{{
  ""settings"": {{
    ""indentation"": {{
      ""indentationSize"": {this.IndentationSize},
      ""useTabs"": {this.UseTabs.ToString().ToLowerInvariant()},
      ""tabSize"": {this.TabSize}
    }}
  }}
}}
";

                if (string.IsNullOrEmpty(settings))
                {
                    settings = indentationSettings;
                }
                else
                {
                    JObject mergedSettings = JsonConvert.DeserializeObject <JObject>(settings);
                    mergedSettings.Merge(JsonConvert.DeserializeObject <JObject>(indentationSettings));
                    settings = JsonConvert.SerializeObject(mergedSettings);
                }
            }

            if (!string.IsNullOrEmpty(settings))
            {
                var documentId = DocumentId.CreateNewId(projectId);
                solution = solution.AddAdditionalDocument(documentId, SettingsHelper.SettingsFileName, settings);
            }

            ParseOptions parseOptions = solution.GetProject(projectId).ParseOptions;

            return(solution.WithProjectParseOptions(projectId, parseOptions.WithDocumentationMode(DocumentationMode.Diagnose)));
        }
        /// <summary>
        /// Create a project using the inputted strings as sources.
        /// </summary>
        /// <param name="sources">Classes in the form of strings</param>
        /// <param name="language">The language the source code is in</param>
        /// <param name="framework">The targed unit test framework.</param>
        /// <returns>A Project created out of the Documents created from the source strings</returns>
        private Project CreateProject(string[] sources, string language, UnitTestFramework framework)
        {
            string fileNamePrefix     = DefaultFilePathPrefix;
            string fileExt            = language == LanguageNames.CSharp ? CSharpDefaultFileExt : VisualBasicDefaultExt;
            var    compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true);

            var projectId = ProjectId.CreateNewId(debugName: TestProjectName);

            MetadataReference corlibReference;
            MetadataReference unitTestFrameworkReference;

            switch (framework)
            {
            case UnitTestFramework.MSTest:
                unitTestFrameworkReference = MsTestReference;
                corlibReference            = CorlibReference;
                break;

            case UnitTestFramework.Xunit:
                unitTestFrameworkReference = XunitReference;
                corlibReference            = PortableCorlibReference;
                break;

            case UnitTestFramework.NUnit:
                unitTestFrameworkReference = NUnitReference;
                corlibReference            = CorlibReference;
                break;

            default:
                throw new ArgumentException("The provided value is not supported", nameof(framework));
            }

            var solution = new AdhocWorkspace()
                           .CurrentSolution
                           .AddProject(projectId, TestProjectName, TestProjectName, language)
                           .WithProjectCompilationOptions(projectId, compilationOptions)
                           .AddMetadataReference(projectId, corlibReference)
                           .AddMetadataReference(projectId, SystemCoreReference)
                           .AddMetadataReference(projectId, CSharpSymbolsReference)
                           .AddMetadataReference(projectId, CodeAnalysisReference)
                           .AddMetadataReference(projectId, ThisProjectReference)
                           .AddMetadataReference(projectId, unitTestFrameworkReference);

            var settings = this.GetSettings();

            if (!string.IsNullOrEmpty(settings))
            {
                var documentId = DocumentId.CreateNewId(projectId);
                solution = solution.AddAdditionalDocument(documentId, SettingsFileName, settings);
            }

            ParseOptions parseOptions = solution.GetProject(projectId).ParseOptions;

#pragma warning disable RS1014 // Do not ignore values returned by methods on immutable objects.
            solution.WithProjectParseOptions(projectId, parseOptions.WithDocumentationMode(DocumentationMode.Diagnose));
#pragma warning restore RS1014 // Do not ignore values returned by methods on immutable objects.

            int count = 0;
            foreach (var source in sources)
            {
                var newFileName = fileNamePrefix + count + "." + fileExt;
                var documentId  = DocumentId.CreateNewId(projectId, debugName: newFileName);
                solution = solution.AddDocument(documentId, newFileName, SourceText.From(source));
                count++;
            }

            return(solution.GetProject(projectId));
        }
    private Task <Project> CreateProject()
    {
        var fileNamePrefix  = "Test";
        var fileExt         = ".cs";
        var testProjectName = "TestProject";

        var projectId = ProjectId.CreateNewId(debugName: testProjectName);

        switch (TargetFramework)
        {
        case TargetFramework.NetStandard2_0:
            AddNuGetReference("NETStandard.Library", "2.0.3", "build/netstandard2.0/ref/");
            break;

        case TargetFramework.NetStandard2_1:
            AddNuGetReference("NETStandard.Library.Ref", "2.1.0", "ref/netstandard2.1/");
            break;

        case TargetFramework.Net4_8:
            AddNuGetReference("Microsoft.NETFramework.ReferenceAssemblies.net48", "1.0.0", "build/.NETFramework/v4.8/");
            break;

        case TargetFramework.Net5_0:
            AddNuGetReference("Microsoft.NETCore.App.Ref", "5.0.0", "ref/net5.0/");
            break;

        case TargetFramework.Net6_0:
            AddNuGetReference("Microsoft.NETCore.App.Ref", "6.0.0", "ref/net6.0/");
            break;

        case TargetFramework.Net7_0:
            AddNuGetReference("Microsoft.NETCore.App.Ref", "7.0.0-preview.3.22175.4", "ref/net7.0/");
            break;

        case TargetFramework.AspNetCore5_0:
            AddNuGetReference("Microsoft.NETCore.App.Ref", "5.0.0", "ref/net5.0/");
            AddNuGetReference("Microsoft.AspNetCore.App.Ref", "5.0.0", "ref/net5.0/");
            break;

        case TargetFramework.AspNetCore6_0:
            AddNuGetReference("Microsoft.NETCore.App.Ref", "6.0.0", "ref/net6.0/");
            AddNuGetReference("Microsoft.AspNetCore.App.Ref", "6.0.0", "ref/net6.0/");
            break;

        case TargetFramework.WindowsDesktop5_0:
            AddNuGetReference("Microsoft.WindowsDesktop.App.Ref", "5.0.0", "ref/net5.0/");
            break;
        }

        AddNuGetReference("System.Collections.Immutable", "1.5.0", "lib/netstandard2.0/");
        AddNuGetReference("System.Numerics.Vectors", "4.5.0", "ref/netstandard2.0/");
        AddNuGetReference("Microsoft.CSharp", "4.7.0", "lib/netstandard2.0/");  // To support dynamic type

        var solution = new AdhocWorkspace()
                       .CurrentSolution
                       .AddProject(projectId, testProjectName, testProjectName, LanguageNames.CSharp)
                       .WithProjectParseOptions(projectId, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion))
                       .AddMetadataReferences(projectId, References);

        var count = 0;

        AppendFile(FileName, SourceCode);

        foreach (var source in ApiReferences)
        {
            var newFileName = fileNamePrefix + count + fileExt;
            AppendFile(newFileName, source);
        }

        return(Task.FromResult(solution.GetProject(projectId)));

        void AppendFile(string filename, string content)
        {
            filename ??= fileNamePrefix + count + fileExt;
            var documentId = DocumentId.CreateNewId(projectId, debugName: filename);

            solution = solution.AddDocument(documentId, filename, SourceText.From(content), filePath: filename);
            count++;
        }
    }
        /// <summary>
        /// Create a project using the inputted strings as sources.
        /// </summary>
        /// <param name="sources">Classes in the form of strings</param>
        /// <param name="language">The language the source code is in</param>
        /// <param name="hasEntrypoint"><c>true</c> to set the compiler in a mode as if it were compiling an exe (as opposed to a dll).</param>
        /// <returns>A Project created out of the Documents created from the source strings</returns>
        protected static Project CreateProject(string[] sources, string language = LanguageNames.CSharp, bool hasEntrypoint = false)
        {
            string fileNamePrefix = DefaultFilePathPrefix;
            string fileExt        = language == LanguageNames.CSharp ? CSharpDefaultFileExt : VisualBasicDefaultExt;

            var projectId = ProjectId.CreateNewId(debugName: TestProjectName);

            var solution = new AdhocWorkspace()
                           .CurrentSolution
                           .AddProject(projectId, TestProjectName, TestProjectName, language)
                           .AddMetadataReference(projectId, CorlibReference)
                           .AddMetadataReference(projectId, SystemReference)
                           .AddMetadataReference(projectId, SystemCoreReference)
                           .AddMetadataReference(projectId, CSharpSymbolsReference)
                           .AddMetadataReference(projectId, CodeAnalysisReference)
                           .AddMetadataReference(projectId, ThreadingReference)
                           .AddMetadataReference(projectId, WindowsBaseReference)
                           .AddMetadataReference(projectId, OleInteropReference)
                           .WithProjectCompilationOptions(
                projectId,
                new CSharpCompilationOptions(
                    hasEntrypoint ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary,
                    specificDiagnosticOptions: new Dictionary <string, ReportDiagnostic>
            {
                { "CS1701", ReportDiagnostic.Suppress },             // we don't reference mscorlib, which can cause assembly reference ambiguities
            }))
                           .WithProjectParseOptions(projectId, new CSharpParseOptions(LanguageVersion.Latest));

            var pathToLibs = ToolLocationHelper.GetPathToStandardLibraries(".NETFramework", "v4.5.1", string.Empty);

            if (!string.IsNullOrEmpty(pathToLibs))
            {
                var facades = Path.Combine(pathToLibs, "Facades");
                if (Directory.Exists(facades))
                {
                    var facadesAssemblies = new List <MetadataReference>();
                    foreach (var path in Directory.EnumerateFiles(facades, "*.dll"))
                    {
                        facadesAssemblies.Add(MetadataReference.CreateFromFile(path));
                    }

                    solution = solution.AddMetadataReferences(projectId, facadesAssemblies);
                }
            }

            string nugetPackageRoot = Path.Combine(
                Environment.GetEnvironmentVariable("USERPROFILE"),
                ".nuget",
                "packages");
            var vssdkReferences = VSSDKPackageReferences.Select(e =>
                                                                MetadataReference.CreateFromFile(Path.Combine(nugetPackageRoot, e)));

            solution = solution.AddMetadataReferences(projectId, vssdkReferences);

            int count = 0;

            foreach (var source in sources)
            {
                var newFileName = fileNamePrefix + count + "." + fileExt;
                var documentId  = DocumentId.CreateNewId(projectId, debugName: newFileName);
                solution = solution.AddDocument(documentId, newFileName, SourceText.From(source));
                count++;
            }

            return(solution.GetProject(projectId));
        }
예제 #7
0
        static int Main(string[] args)
        {
            var options = new Options();

            if (!Parser.Default.ParseArguments(args, options))
            {
                return(-1089286372);
            }

            if (!Parser.Default.ParseAdditionalSettings(options))
            {
                return(1369264027);
            }


            Console.WriteLine("Download '{0}'...", options.CSharpFaqFileRawUrl);
            var csFaqSource   = new WebClient().DownloadString(options.CSharpFaqFileRawUri);
            var csFaqFileName = Path.GetFileName(options.CSharpFaqFileRawUri.LocalPath);


            Console.WriteLine("Parse '{0}'...", csFaqFileName);
            var projectId  = ProjectId.CreateNewId();
            var documentId = DocumentId.CreateNewId(projectId);

            var solution = new AdhocWorkspace().CurrentSolution.
                           AddProject(projectId, "Project", "Project", LanguageNames.CSharp).
                           AddMetadataReference(projectId, Mscorlib).
                           AddDocument(documentId, csFaqFileName, csFaqSource).
                           WithProjectCompilationOptions(projectId, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            var project  = solution.GetProject(projectId);
            var document = project.GetDocument(documentId);

            var root       = document.GetSyntaxRootAsync().Result;
            var model      = document.GetSemanticModelAsync().Result;
            var faqAttrSym = model.GetDeclaredSymbol(root.DescendantNodes().OfType <TypeDeclarationSyntax>().Single(_ => _.Identifier.ValueText == "FAQAttribute"));
            var query      = from methodDecl in root.DescendantNodes().OfType <MethodDeclarationSyntax>()
                             let methodSym = model.GetDeclaredSymbol(methodDecl)
                                             where methodSym.GetAttributes().Any(_ => _.AttributeClass == faqAttrSym)
                                             let appliedFaqAttr = methodSym.GetAttributes().First(_ => _.AttributeClass == faqAttrSym)
                                                                  select new { Id = (int)appliedFaqAttr.ConstructorArguments[0].Value, MethodSymbol = methodSym };
            var faqAppliedMethodSyms = query.ToDictionary(_ => _.Id, _ => _.MethodSymbol);


            Console.WriteLine("Arrange '{0}'...", options.MarkdownFaqFilePath);
            var mdFaqSource = File.ReadAllText(options.MarkdownFaqFilePath);

            mdFaqSource = FaqRegex.Replace(mdFaqSource, m =>
            {
                var idStr = m.Groups["id"].Value;
                var id    = int.Parse(idStr);
                var faqAppliedMethodSym = faqAppliedMethodSyms[id];
                var location            = faqAppliedMethodSym.Locations.First();
                var lineSpan            = location.GetLineSpan();
                return(string.Format("[{0}]({1}#L{2})", m.Value, options.CSharpFaqFileUri, lineSpan.StartLinePosition.Line + 1));
            });
            mdFaqSource = UnneededTagRegex.Replace(mdFaqSource, "");


            Console.WriteLine("Output '{0}'...", options.OutputPath);
            File.WriteAllText(options.OutputPath, mdFaqSource);
            return(0);
        }