You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							164 lines
						
					
					
						
							6.2 KiB
						
					
					
				
			
		
		
	
	
							164 lines
						
					
					
						
							6.2 KiB
						
					
					
				// Copyright (c) AlphaSierraPapa for the SharpDevelop Team | 
						|
//  | 
						|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this | 
						|
// software and associated documentation files (the "Software"), to deal in the Software | 
						|
// without restriction, including without limitation the rights to use, copy, modify, merge, | 
						|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons | 
						|
// to whom the Software is furnished to do so, subject to the following conditions: | 
						|
//  | 
						|
// The above copyright notice and this permission notice shall be included in all copies or | 
						|
// substantial portions of the Software. | 
						|
//  | 
						|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | 
						|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | 
						|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE | 
						|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | 
						|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 
						|
// DEALINGS IN THE SOFTWARE. | 
						|
 | 
						|
using System; | 
						|
using System.Collections.Generic; | 
						|
using System.IO; | 
						|
using System.Linq; | 
						|
using ICSharpCode.NRefactory.CSharp; | 
						|
using ICSharpCode.NRefactory.CSharp.TypeSystem; | 
						|
using ICSharpCode.NRefactory.Editor; | 
						|
using ICSharpCode.NRefactory.TypeSystem; | 
						|
 | 
						|
namespace ICSharpCode.NRefactory.ConsistencyCheck | 
						|
{ | 
						|
	public class CSharpProject | 
						|
	{ | 
						|
		public readonly Solution Solution; | 
						|
		public readonly string Title; | 
						|
		public readonly string AssemblyName; | 
						|
		public readonly string FileName; | 
						|
		 | 
						|
		public readonly List<CSharpFile> Files = new List<CSharpFile>(); | 
						|
		 | 
						|
		public readonly CompilerSettings CompilerSettings = new CompilerSettings(); | 
						|
		 | 
						|
		public IProjectContent ProjectContent; | 
						|
		 | 
						|
		public ICompilation Compilation { | 
						|
			get { | 
						|
				return Solution.SolutionSnapshot.GetCompilation(ProjectContent); | 
						|
			} | 
						|
		} | 
						|
		 | 
						|
		public CSharpProject(Solution solution, string title, string fileName) | 
						|
		{ | 
						|
			this.Solution = solution; | 
						|
			this.Title = title; | 
						|
			this.FileName = fileName; | 
						|
			 | 
						|
			var p = new Microsoft.Build.Evaluation.Project(fileName); | 
						|
			this.AssemblyName = p.GetPropertyValue("AssemblyName"); | 
						|
			this.CompilerSettings.AllowUnsafeBlocks = GetBoolProperty(p, "AllowUnsafeBlocks") ?? false; | 
						|
			this.CompilerSettings.CheckForOverflow = GetBoolProperty(p, "CheckForOverflowUnderflow") ?? false; | 
						|
			foreach (string symbol in p.GetPropertyValue("DefineConstants").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { | 
						|
				this.CompilerSettings.ConditionalSymbols.Add(symbol.Trim()); | 
						|
			} | 
						|
			foreach (var item in p.GetItems("Compile")) { | 
						|
				Files.Add(new CSharpFile(this, Path.Combine(p.DirectoryPath, item.EvaluatedInclude))); | 
						|
			} | 
						|
			List<IAssemblyReference> references = new List<IAssemblyReference>(); | 
						|
			string mscorlib = FindAssembly(Program.AssemblySearchPaths, "mscorlib"); | 
						|
			if (mscorlib != null) { | 
						|
				references.Add(Program.LoadAssembly(mscorlib)); | 
						|
			} else { | 
						|
				Console.WriteLine("Could not find mscorlib"); | 
						|
			} | 
						|
			bool hasSystemCore = false; | 
						|
			foreach (var item in p.GetItems("Reference")) { | 
						|
				string assemblyFileName = null; | 
						|
				if (item.HasMetadata("HintPath")) { | 
						|
					assemblyFileName = Path.Combine(p.DirectoryPath, item.GetMetadataValue("HintPath")); | 
						|
					if (!File.Exists(assemblyFileName)) | 
						|
						assemblyFileName = null; | 
						|
				} | 
						|
				if (assemblyFileName == null) { | 
						|
					assemblyFileName = FindAssembly(Program.AssemblySearchPaths, item.EvaluatedInclude); | 
						|
				} | 
						|
				if (assemblyFileName != null) { | 
						|
					if (Path.GetFileName(assemblyFileName).Equals("System.Core.dll", StringComparison.OrdinalIgnoreCase)) | 
						|
						hasSystemCore = true; | 
						|
					references.Add(Program.LoadAssembly(assemblyFileName)); | 
						|
				} else { | 
						|
					Console.WriteLine("Could not find referenced assembly " + item.EvaluatedInclude); | 
						|
				} | 
						|
			} | 
						|
			if (!hasSystemCore && FindAssembly(Program.AssemblySearchPaths, "System.Core") != null) | 
						|
				references.Add(Program.LoadAssembly(FindAssembly(Program.AssemblySearchPaths, "System.Core"))); | 
						|
			foreach (var item in p.GetItems("ProjectReference")) { | 
						|
				references.Add(new ProjectReference(item.EvaluatedInclude)); | 
						|
			} | 
						|
			this.ProjectContent = new CSharpProjectContent() | 
						|
				.SetAssemblyName(this.AssemblyName) | 
						|
				.SetCompilerSettings(this.CompilerSettings) | 
						|
				.AddAssemblyReferences(references) | 
						|
				.AddOrUpdateFiles(Files.Select(f => f.UnresolvedFile)); | 
						|
		} | 
						|
		 | 
						|
		string FindAssembly(IEnumerable<string> assemblySearchPaths, string evaluatedInclude) | 
						|
		{ | 
						|
			if (evaluatedInclude.IndexOf(',') >= 0) | 
						|
				evaluatedInclude = evaluatedInclude.Substring(0, evaluatedInclude.IndexOf(',')); | 
						|
			foreach (string searchPath in assemblySearchPaths) { | 
						|
				string assemblyFile = Path.Combine(searchPath, evaluatedInclude + ".dll"); | 
						|
				if (File.Exists(assemblyFile)) | 
						|
					return assemblyFile; | 
						|
			} | 
						|
			return null; | 
						|
		} | 
						|
		 | 
						|
		static bool? GetBoolProperty(Microsoft.Build.Evaluation.Project p, string propertyName) | 
						|
		{ | 
						|
			string val = p.GetPropertyValue(propertyName); | 
						|
			if (val.Equals("true", StringComparison.OrdinalIgnoreCase)) | 
						|
				return true; | 
						|
			if (val.Equals("false", StringComparison.OrdinalIgnoreCase)) | 
						|
				return false; | 
						|
			return null; | 
						|
		} | 
						|
		 | 
						|
		public override string ToString() | 
						|
		{ | 
						|
			return string.Format("[CSharpProject AssemblyName={0}]", AssemblyName); | 
						|
		} | 
						|
		 | 
						|
		public CSharpFile GetFile(string fileName) | 
						|
		{ | 
						|
			return Files.Single(f => f.FileName == fileName); | 
						|
		} | 
						|
	} | 
						|
	 | 
						|
	public class CSharpFile | 
						|
	{ | 
						|
		public readonly CSharpProject Project; | 
						|
		public readonly string FileName; | 
						|
		 | 
						|
		public readonly ITextSource Content; | 
						|
		public readonly int LinesOfCode; | 
						|
		public SyntaxTree SyntaxTree; | 
						|
		public CSharpUnresolvedFile UnresolvedFile; | 
						|
		 | 
						|
		public CSharpFile(CSharpProject project, string fileName) | 
						|
		{ | 
						|
			this.Project = project; | 
						|
			this.FileName = fileName; | 
						|
			this.Content = new StringTextSource(File.ReadAllText(FileName)); | 
						|
			this.LinesOfCode = 1 + this.Content.Text.Count(c => c == '\n'); | 
						|
			 | 
						|
			CSharpParser p = new CSharpParser(project.CompilerSettings); | 
						|
			this.SyntaxTree = p.Parse(Content, fileName); | 
						|
			if (p.HasErrors) { | 
						|
				Console.WriteLine("Error parsing " + fileName + ":"); | 
						|
				foreach (var error in p.ErrorsAndWarnings) { | 
						|
					Console.WriteLine("  " + error.Region + " " + error.Message); | 
						|
				} | 
						|
			} | 
						|
			this.UnresolvedFile = this.SyntaxTree.ToTypeSystem(); | 
						|
		} | 
						|
	} | 
						|
}
 | 
						|
 |