44using System . Linq ;
55using System . Xml ;
66
7- namespace Semmle . BuildAnalyser
7+ namespace Semmle . Extraction . CSharp
88{
99 /// <summary>
1010 /// Represents a .csproj file and reads information from it.
1111 /// </summary>
12- internal class CsProjFile
12+ public class CsProjFile
1313 {
1414 private string Filename { get ; }
1515
@@ -38,14 +38,14 @@ public CsProjFile(FileInfo filename)
3838 // unrecognised content or is the wrong version.
3939 // This currently always fails on Linux because
4040 // Microsoft.Build is not cross platform.
41- ( csFiles , references ) = ReadMsBuildProject ( filename ) ;
41+ ( csFiles , references , projectReferences ) = ReadMsBuildProject ( filename ) ;
4242 }
4343 catch // lgtm[cs/catch-of-all-exceptions]
4444 {
4545 // There was some reason why the project couldn't be loaded.
4646 // Fall back to reading the Xml document directly.
4747 // This method however doesn't handle variable expansion.
48- ( csFiles , references ) = ReadProjectFileAsXml ( filename , Directory ) ;
48+ ( csFiles , references , projectReferences ) = ReadProjectFileAsXml ( filename , Directory ) ;
4949 }
5050 }
5151
@@ -55,7 +55,7 @@ public CsProjFile(FileInfo filename)
5555 /// and there seems to be no way to make it succeed. Fails on Linux.
5656 /// </summary>
5757 /// <param name="filename">The file to read.</param>
58- private static ( string [ ] csFiles , string [ ] references ) ReadMsBuildProject ( FileInfo filename )
58+ private static ( string [ ] csFiles , string [ ] references , string [ ] projectReferences ) ReadMsBuildProject ( FileInfo filename )
5959 {
6060 var msbuildProject = new Microsoft . Build . Execution . ProjectInstance ( filename . FullName ) ;
6161
@@ -64,13 +64,18 @@ private static (string[] csFiles, string[] references) ReadMsBuildProject(FileIn
6464 . Select ( item => item . EvaluatedInclude )
6565 . ToArray ( ) ;
6666
67+ var projectReferences = msbuildProject . Items
68+ . Where ( item => item . ItemType == "ProjectReference" )
69+ . Select ( item => item . EvaluatedInclude )
70+ . ToArray ( ) ;
71+
6772 var csFiles = msbuildProject . Items
6873 . Where ( item => item . ItemType == "Compile" )
6974 . Select ( item => item . GetMetadataValue ( "FullPath" ) )
7075 . Where ( fn => fn . EndsWith ( ".cs" ) )
7176 . ToArray ( ) ;
7277
73- return ( csFiles , references ) ;
78+ return ( csFiles , references , projectReferences ) ;
7479 }
7580
7681 /// <summary>
@@ -79,7 +84,7 @@ private static (string[] csFiles, string[] references) ReadMsBuildProject(FileIn
7984 /// fallback if ReadMsBuildProject() fails.
8085 /// </summary>
8186 /// <param name="fileName">The .csproj file.</param>
82- private static ( string [ ] csFiles , string [ ] references ) ReadProjectFileAsXml ( FileInfo fileName , string directoryName )
87+ private static ( string [ ] csFiles , string [ ] references , string [ ] projectReferences ) ReadProjectFileAsXml ( FileInfo fileName , string directoryName )
8388 {
8489 var projFile = new XmlDocument ( ) ;
8590 var mgr = new XmlNamespaceManager ( projFile . NameTable ) ;
@@ -109,8 +114,16 @@ private static (string[] csFiles, string[] references) ReadProjectFileAsXml(File
109114
110115 var additionalCsFiles = System . IO . Directory . GetFiles ( directoryName , "*.cs" , SearchOption . AllDirectories ) ;
111116
117+ var projectReferences = root
118+ . SelectNodes ( "/Project/ItemGroup/ProjectReference/@Include" , mgr )
119+ ? . NodeList ( )
120+ . Select ( node => node . Value )
121+ . Select ( csproj => GetFullPath ( csproj , projDir ) )
122+ . Where ( s => s is not null )
123+ ?? Enumerable . Empty < string > ( ) ;
124+
112125#nullable disable warnings
113- return ( explicitCsFiles . Concat ( additionalCsFiles ) . ToArray ( ) , Array . Empty < string > ( ) ) ;
126+ return ( explicitCsFiles . Concat ( additionalCsFiles ) . ToArray ( ) , Array . Empty < string > ( ) , projectReferences . ToArray ( ) ) ;
114127#nullable restore warnings
115128 }
116129
@@ -135,7 +148,7 @@ private static (string[] csFiles, string[] references) ReadProjectFileAsXml(File
135148 . ToArray ( ) ;
136149
137150#nullable disable warnings
138- return ( csFiles , references ) ;
151+ return ( csFiles , references , Array . Empty < string > ( ) ) ;
139152#nullable restore warnings
140153 }
141154
@@ -150,13 +163,19 @@ private static (string[] csFiles, string[] references) ReadProjectFileAsXml(File
150163 }
151164
152165 private readonly string [ ] references ;
166+ private readonly string [ ] projectReferences ;
153167 private readonly string [ ] csFiles ;
154168
155169 /// <summary>
156170 /// The list of references as a list of assembly IDs.
157171 /// </summary>
158172 public IEnumerable < string > References => references ;
159173
174+ /// <summary>
175+ /// The list of project references in full path format.
176+ /// </summary>
177+ public IEnumerable < string > ProjectReferences => projectReferences ;
178+
160179 /// <summary>
161180 /// The list of C# source files in full path format.
162181 /// </summary>
0 commit comments