181
229
if (projectFile != null)
182
230
QueueParseJob (wrapper, new [] { projectFile });
233
if (cachedAssemblyContents.TryGetValue (file.FileName, out ctx))
234
CheckModifiedFile (ctx);
238
foreach (var content in projectContents.Values.ToArray ()) {
239
var files = new List<ProjectFile> ();
240
foreach (var file in e) {
241
var f = content.Project.GetProjectFile (file.FileName);
242
if (f == null || f.BuildAction != BuildAction.Compile)
247
QueueParseJob (content, files);
251
if (IdeApp.ProjectOperations != null) {
252
IdeApp.ProjectOperations.EndBuild += HandleEndBuild;
254
if (IdeApp.Workspace != null) {
255
IdeApp.Workspace.ActiveConfigurationChanged += HandleActiveConfigurationChanged;
259
static void HandleActiveConfigurationChanged (object sender, EventArgs e)
261
foreach (var pr in projectContents.Keys.ToArray ()) {
262
var project = pr as DotNetProject;
264
CheckProjectOutput (project, true);
268
static List<string> outputTrackedProjects =new List<string> ();
269
static void CheckProjectOutput (DotNetProject project, bool autoUpdate)
272
throw new ArgumentNullException ("project");
273
if (outputTrackedProjects.Contains (project.ProjectType, StringComparer.OrdinalIgnoreCase)) {
274
var fileName = project.GetOutputFileName (IdeApp.Workspace.ActiveConfiguration);
276
bool update = GetProjectContentWrapper (project).UpdateTrackedOutputAssembly (fileName);
277
if (autoUpdate && update) {
278
ReloadAllReferences (projectContents.Values.ToArray ());
281
foreach (var openDocument in IdeApp.Workbench.Documents) {
282
openDocument.ReparseDocument ();
288
static void HandleEndBuild (object sender, BuildEventArgs args)
290
var project = args.SolutionItem as DotNetProject;
293
CheckProjectOutput (project, true);
189
public static ITypeSystemParser GetParser (string mimeType)
296
public static TypeSystemParser GetParser (string mimeType, string buildAction = BuildAction.Compile)
191
var provider = Parsers.FirstOrDefault (p => p.CanParse (mimeType));
298
var provider = Parsers.FirstOrDefault (p => p.CanParse (mimeType, buildAction));
192
299
return provider != null ? provider.Parser : null;
195
static TypeSystemParserNode GetTypeSystemParserNode (string mimeType)
302
static TypeSystemParserNode GetTypeSystemParserNode (string mimeType, string buildAction)
197
return Parsers.FirstOrDefault (p => p.CanParse (mimeType));
304
return Parsers.FirstOrDefault (p => p.CanParse (mimeType, buildAction));
200
307
static List<MimeTypeExtensionNode> foldingParsers;
737
909
public void UpdateContent (Func<IProjectContent, IProjectContent> updateFunc)
740
if (content is LazyProjectLoader) {
741
((LazyProjectLoader)content).ContextTask.Wait ();
912
if (Content is LazyProjectLoader) {
913
((LazyProjectLoader)Content).ContextTask.Wait ();
743
content = updateFunc (content);
915
Content = updateFunc (Content);
916
// Need to clear this compilation & all compilations that reference this directly or indirectly
917
foreach (var wrapper in projectContents.Values)
918
wrapper.compilation = null;
745
919
WasChanged = true;
923
public void InformFileRemoved (ParsedFileEventArgs e)
925
var handler = FileRemoved;
930
public void InformFileAdded (ParsedFileEventArgs e)
932
var handler = FileAdded;
937
public EventHandler<ParsedFileEventArgs> FileAdded;
938
public EventHandler<ParsedFileEventArgs> FileRemoved;
749
941
public bool WasChanged = false;
752
944
ICompilation compilation = null;
754
946
public ICompilation Compilation {
756
if (compilation == null) {
757
compilation = Content.CreateCompilation ();
949
if (compilation == null) {
950
compilation = Content.CreateCompilation ();
902
1129
return Content.SetAssemblyName (newAssemblyName);
1132
IProjectContent IProjectContent.SetLocation (string newLocation)
1134
return Content.SetLocation (newLocation);
905
1137
IProjectContent IProjectContent.AddAssemblyReferences (IEnumerable<IAssemblyReference> references)
907
1139
return Content.AddAssemblyReferences (references);
1142
IProjectContent IProjectContent.AddAssemblyReferences (params IAssemblyReference[] references)
1144
return Content.AddAssemblyReferences (references);
910
1147
IProjectContent IProjectContent.RemoveAssemblyReferences (IEnumerable<IAssemblyReference> references)
912
1149
return Content.RemoveAssemblyReferences (references);
915
IProjectContent IProjectContent.UpdateProjectContent (IParsedFile oldFile, IParsedFile newFile)
1152
IProjectContent IProjectContent.RemoveAssemblyReferences (params IAssemblyReference[] references)
1154
return Content.RemoveAssemblyReferences (references);
1157
#pragma warning disable 618
1158
IProjectContent IProjectContent.UpdateProjectContent (IUnresolvedFile oldFile, IUnresolvedFile newFile)
917
1160
return Content.UpdateProjectContent (oldFile, newFile);
920
public IProjectContent UpdateProjectContent (IEnumerable<IParsedFile> oldFiles, IEnumerable<IParsedFile> newFiles)
1163
public IProjectContent UpdateProjectContent (IEnumerable<IUnresolvedFile> oldFiles, IEnumerable<IUnresolvedFile> newFiles)
922
1165
return Content.UpdateProjectContent (oldFiles, newFiles);
925
IEnumerable<IParsedFile> IProjectContent.Files {
1167
#pragma warning restore 618
1169
public IProjectContent AddOrUpdateFiles (IEnumerable<IUnresolvedFile> newFiles)
1171
return Content.AddOrUpdateFiles (newFiles);
1174
public IProjectContent AddOrUpdateFiles (params IUnresolvedFile[] newFiles)
1176
return Content.AddOrUpdateFiles (newFiles);
1179
IEnumerable<IUnresolvedFile> IProjectContent.Files {
927
1181
return Content.Files;
933
1187
return Content.AssemblyReferences;
1191
IProjectContent IProjectContent.SetProjectFileName (string newProjectFileName)
1193
return Content.SetProjectFileName (newProjectFileName);
1196
IProjectContent IProjectContent.RemoveFiles (IEnumerable<string> fileNames)
1198
return Content.RemoveFiles (fileNames);
1201
IProjectContent IProjectContent.RemoveFiles (params string[] fileNames)
1203
return Content.RemoveFiles (fileNames);
1207
object compilerSettings;
1208
public IProjectContent SetCompilerSettings (object compilerSettings)
1210
this.compilerSettings = compilerSettings;
1214
public object CompilerSettings {
1216
return compilerSettings;
940
bool HasCyclicRefs (ProjectContentWrapper wrapper)
1221
bool HasCyclicRefs (ProjectContentWrapper wrapper, HashSet<Project> nonCyclicCache)
1223
if (nonCyclicCache.Contains (wrapper.Project))
942
1225
foreach (var referencedProject in wrapper.ReferencedProjects) {
943
1226
ProjectContentWrapper w;
944
if (referencedProject == Project || projectContents.TryGetValue (referencedProject, out w) && HasCyclicRefs (w)) {
1227
if (referencedProject == Project || referencedProject == wrapper.Project || projectContents.TryGetValue (referencedProject, out w) && HasCyclicRefs (w, nonCyclicCache)) {
1231
nonCyclicCache.Add (wrapper.Project);
951
public void ReloadAssemblyReferences (Project project)
1235
public void ReconnectAssemblyReferences ()
953
var netProject = project as DotNetProject;
1237
var netProject = this.Project as DotNetProject;
954
1238
if (netProject == null)
957
1241
var contexts = new List<IAssemblyReference> ();
1242
var nonCyclicCache =new HashSet<Project> ();
958
1243
foreach (var referencedProject in ReferencedProjects) {
959
1244
ProjectContentWrapper wrapper;
960
1245
if (projectContents.TryGetValue (referencedProject, out wrapper)) {
961
if (HasCyclicRefs (wrapper))
1246
if (HasCyclicRefs (wrapper, nonCyclicCache))
963
1248
contexts.Add (new UnresolvedAssemblyDecorator (wrapper));
1296
static object projectContentLock = new object ();
1009
1297
static Dictionary<Project, ProjectContentWrapper> projectContents = new Dictionary<Project, ProjectContentWrapper> ();
1010
static Dictionary<Project, int> referenceCounter = new Dictionary<Project, int> ();
1012
1299
public static ProjectContentWrapper LoadProject (Project project)
1014
1301
if (IncLoadCount (project) != 1)
1303
lock (projectContentLock) {
1017
1304
if (projectContents.ContainsKey (project))
1307
Counters.ParserService.ProjectsLoaded++;
1020
1308
ProjectContentWrapper wrapper;
1021
1309
projectContents [project] = wrapper = new ProjectContentWrapper (project);
1022
referenceCounter [project] = 1;
1023
OnProjectContentLoaded (new ProjectContentEventArgs (project, wrapper.Content));
1310
var dotNetProject = project as DotNetProject;
1311
if (dotNetProject != null)
1312
CheckProjectOutput (dotNetProject, false);
1024
1314
project.FileAddedToProject += OnFileAdded;
1025
1315
project.FileRemovedFromProject += OnFileRemoved;
1026
1316
project.FileRenamedInProject += OnFileRenamed;
1027
1317
project.Modified += OnProjectModified;
1318
var files = project.Files.ToArray ();
1028
1319
Task.Factory.StartNew (delegate {
1029
CheckModifiedFiles (project, wrapper);
1320
CheckModifiedFiles (project, files, wrapper);
1323
if (dotNetProject != null) {
1324
Task.Factory.StartNew (delegate {
1325
GetFrameworkLookup (dotNetProject);
1329
OnProjectContentLoaded (new ProjectContentEventArgs (project, wrapper.Content));
1032
1330
return wrapper;
1033
1331
} catch (Exception ex) {
1034
1332
LoggingService.LogError ("Parser database for project '" + project.Name + " could not be loaded", ex);
1428
class LazyAssemblyLoader
1745
internal class LazyAssemblyLoader : IUnresolvedAssembly
1747
class LazyAssembly : IAssembly
1749
readonly LazyAssemblyLoader loader;
1750
readonly ITypeResolveContext context;
1753
IAssembly Assembly {
1756
if (assembly == null) {
1757
loader.EnsureAssemblyLoaded ();
1758
assembly = loader.assembly.Resolve (context);
1765
public LazyAssembly (LazyAssemblyLoader loader, ITypeResolveContext context)
1767
this.loader = loader;
1768
this.context = context;
1772
#region IAssembly implementation
1773
bool IAssembly.InternalsVisibleTo (IAssembly assembly)
1775
return Assembly.InternalsVisibleTo (assembly);
1778
ITypeDefinition IAssembly.GetTypeDefinition (TopLevelTypeName typeName)
1780
return Assembly.GetTypeDefinition (typeName);
1783
IUnresolvedAssembly IAssembly.UnresolvedAssembly {
1785
return Assembly.UnresolvedAssembly;
1789
bool IAssembly.IsMainAssembly {
1791
return Assembly.IsMainAssembly;
1795
string IAssembly.AssemblyName {
1797
return Assembly.AssemblyName;
1801
string IAssembly.FullAssemblyName {
1803
return Assembly.FullAssemblyName;
1807
IList<IAttribute> IAssembly.AssemblyAttributes {
1809
return Assembly.AssemblyAttributes;
1813
IList<IAttribute> IAssembly.ModuleAttributes {
1815
return Assembly.ModuleAttributes;
1819
INamespace IAssembly.RootNamespace {
1821
return Assembly.RootNamespace;
1825
IEnumerable<ITypeDefinition> IAssembly.TopLevelTypeDefinitions {
1827
return Assembly.TopLevelTypeDefinitions;
1833
#region ICompilationProvider implementation
1834
ICompilation ICompilationProvider.Compilation {
1836
return Assembly.Compilation;
1842
#region IAssemblyReference implementation
1844
IAssembly IAssemblyReference.Resolve (ITypeResolveContext context)
1846
if (assembly != null)
1847
return assembly.Resolve (context);
1848
return new LazyAssembly (this, context);
1853
#region IUnresolvedAssembly implementation
1855
string IUnresolvedAssembly.AssemblyName {
1858
EnsureAssemblyLoaded ();
1859
return assembly.AssemblyName;
1864
string IUnresolvedAssembly.FullAssemblyName {
1867
EnsureAssemblyLoaded ();
1868
return assembly.FullAssemblyName;
1873
string IUnresolvedAssembly.Location {
1876
EnsureAssemblyLoaded ();
1877
return assembly.Location;
1882
IEnumerable<IUnresolvedAttribute> IUnresolvedAssembly.AssemblyAttributes {
1885
EnsureAssemblyLoaded ();
1886
return assembly.AssemblyAttributes;
1891
IEnumerable<IUnresolvedAttribute> IUnresolvedAssembly.ModuleAttributes {
1894
EnsureAssemblyLoaded ();
1895
return assembly.ModuleAttributes;
1900
IEnumerable<IUnresolvedTypeDefinition> IUnresolvedAssembly.TopLevelTypeDefinitions {
1903
EnsureAssemblyLoaded ();
1904
return assembly.TopLevelTypeDefinitions;
1430
1911
string fileName;
1433
1914
IUnresolvedAssembly assembly;
1435
void EnsureAssemblyLoaded ()
1916
internal void EnsureAssemblyLoaded ()
1438
if (assembly != null)
1440
assembly = LoadAssembly () ?? new DefaultUnresolvedAssembly (fileName);
1918
if (assembly != null)
1920
assembly = LoadAssembly () ?? new DefaultUnresolvedAssembly (fileName);
1444
public IUnresolvedAssembly Assembly {
1447
EnsureAssemblyLoaded ();
1453
1923
public LazyAssemblyLoader (string fileName, string cache)
1455
1925
this.fileName = fileName;
2004
static object assemblyContextLock = new object ();
1536
2005
static AssemblyContext LoadAssemblyContext (string fileName)
1538
2007
AssemblyContext loadedContext;
1539
if (cachedAssemblyContents.TryGetValue (fileName, out loadedContext))
2008
if (cachedAssemblyContents.TryGetValue (fileName, out loadedContext)) {
2009
CheckModifiedFile (loadedContext);
1540
2010
return loadedContext;
1541
2012
if (!File.Exists (fileName))
1543
string cache = GetCacheDirectory (fileName);
1544
if (cache != null) {
1546
var deserialized = DeserializeObject <AssemblyContext> (Path.Combine (cache, "assembly.descriptor"));
1547
if (deserialized != null) {
1548
deserialized.CtxLoader = new LazyAssemblyLoader (fileName, cache);
1549
cachedAssemblyContents [fileName] = deserialized;
1550
return deserialized;
1552
RemoveCache (cache);
1555
cache = CreateCacheDirectory (fileName);
1558
var result = new AssemblyContext () {
1559
FileName = fileName,
1560
LastWriteTimeUtc = File.GetLastWriteTimeUtc (fileName)
1562
SerializeObject (Path.Combine (cache, "assembly.descriptor"), result);
1564
result.CtxLoader = new LazyAssemblyLoader (fileName, cache);
1565
cachedAssemblyContents [fileName] = result;
1567
} catch (Exception ex) {
1568
LoggingService.LogError ("Error loading assembly " + fileName, ex);
2014
lock (assemblyContextLock) {
2015
if (cachedAssemblyContents.TryGetValue (fileName, out loadedContext)) {
2016
CheckModifiedFile (loadedContext);
2017
return loadedContext;
2020
string cache = GetCacheDirectory (fileName);
2021
if (cache != null) {
2023
var deserialized = DeserializeObject <AssemblyContext> (Path.Combine (cache, "assembly.descriptor"));
2024
if (deserialized != null) {
2025
deserialized.CtxLoader = new LazyAssemblyLoader (fileName, cache);
2026
CheckModifiedFile (deserialized);
2027
var newcachedAssemblyContents = new Dictionary<string, AssemblyContext> (cachedAssemblyContents);
2028
newcachedAssemblyContents [fileName] = deserialized;
2029
cachedAssemblyContents = newcachedAssemblyContents;
2030
OnAssemblyLoaded (new AssemblyLoadedEventArgs (deserialized.CtxLoader));
2031
return deserialized;
2033
RemoveCache (cache);
2036
cache = CreateCacheDirectory (fileName);
2039
var result = new AssemblyContext () {
2040
FileName = fileName,
2041
LastWriteTimeUtc = File.GetLastWriteTimeUtc (fileName)
2043
SerializeObject (Path.Combine (cache, "assembly.descriptor"), result);
2045
result.CtxLoader = new LazyAssemblyLoader (fileName, cache);
2046
var newcachedAssemblyContents = new Dictionary<string, AssemblyContext> (cachedAssemblyContents);
2047
newcachedAssemblyContents [fileName] = result;
2048
cachedAssemblyContents = newcachedAssemblyContents;
2049
OnAssemblyLoaded (new AssemblyLoadedEventArgs (result.CtxLoader));
2051
} catch (Exception ex) {
2052
LoggingService.LogError ("Error loading assembly " + fileName, ex);
2059
internal static event EventHandler<AssemblyLoadedEventArgs> AssemblyLoaded;
2061
static void OnAssemblyLoaded (AssemblyLoadedEventArgs e)
2063
var handler = AssemblyLoaded;
2064
if (handler != null)
1573
2068
public static IUnresolvedAssembly LoadAssemblyContext (MonoDevelop.Core.Assemblies.TargetRuntime runtime, MonoDevelop.Core.Assemblies.TargetFramework fx, string fileName)
1595
2090
var content = GetProjectContentWrapper (project);
1596
2091
return content.Compilation;
2094
public static ICompilation GetCompilation (SystemAssembly assembly, ICompilation compilation)
2096
var ctx = LoadAssemblyContext (assembly.Location);
2097
var list = compilation.ReferencedAssemblies.Select (r => r.UnresolvedAssembly).ToList ();
2098
list.Add (compilation.MainAssembly.UnresolvedAssembly);
2099
var result = new SimpleCompilation (ctx, list);
2103
public static readonly Version FrameworkLookupVersion = new Version (1, 0, 0);
2106
public class FrameworkLookup
2108
public Version Version {
2113
Dictionary<string, List<AssemblyLookup>> typeLookup = new Dictionary<string, List<AssemblyLookup>> ();
2114
Dictionary<string, List<AssemblyLookup>> extensionMethodLookup = new Dictionary<string, List<AssemblyLookup>> ();
2116
public int ItemCount {
2118
return typeLookup.Count + extensionMethodLookup.Count;
2122
public FrameworkLookup ()
2124
this.Version = FrameworkLookupVersion;
2127
void AddExtensionMethodlookup(IUnresolvedMethod method, SystemAssembly assembly)
2129
List<AssemblyLookup> list;
2130
if (!extensionMethodLookup.TryGetValue (method.Name, out list)) {
2131
list = new List<AssemblyLookup> ();
2132
extensionMethodLookup [method.Name] = list;
2134
var assemblyLookup = new AssemblyLookup (assembly, method.DeclaringTypeDefinition.Namespace);
2135
if (!list.Any (a => a.Equals (assemblyLookup))) {
2136
list.Add (assemblyLookup);
2141
public IEnumerable<AssemblyLookup> LookupExtensionMethod (string identifier)
2143
List<AssemblyLookup> list;
2144
if (!extensionMethodLookup.TryGetValue (identifier, out list))
2145
return Enumerable.Empty<AssemblyLookup> ();
2149
public void AddLookup (IUnresolvedTypeDefinition type, SystemAssembly assembly)
2151
List<AssemblyLookup> list;
2152
var id = GetIdentifier (type.Name, type.TypeParameters.Count);
2153
if (!typeLookup.TryGetValue (id, out list)) {
2154
list = new List<AssemblyLookup> ();
2155
typeLookup [id] = list;
2157
var assemblyLookup = new AssemblyLookup (assembly, type.Namespace);
2158
if (!list.Any (a => a.Equals (assemblyLookup))) {
2159
list.Add (assemblyLookup);
2161
if (type.IsSealed || type.IsStatic) {
2162
foreach (var method in type.Methods) {
2163
var m = method as DefaultUnresolvedMethod;
2164
if (m == null || !m.IsExtensionMethod)
2166
AddExtensionMethodlookup (method, assembly);
2172
static string GetIdentifier (string identifier, int tc)
2176
return identifier + "`" + tc;
2179
public IEnumerable<AssemblyLookup> LookupIdentifier (string name, int typeParameterCount)
2181
var identifier = GetIdentifier (name, typeParameterCount);
2182
List<AssemblyLookup> list;
2183
if (!typeLookup.TryGetValue (identifier, out list))
2184
return Enumerable.Empty<AssemblyLookup> ();
2189
public class AssemblyLookup
2191
public string Namespace { get; set; }
2192
public string FullName { get; set; }
2193
public string Package { get; set; }
2195
public AssemblyLookup (SystemAssembly assembly, string ns)
2197
FullName = assembly.FullName;
2198
Package = assembly.Package.Name;
2202
public override string ToString ()
2204
return string.Format ("[AssemblyLookup: Namespace={0}, FullName={1}, Package={2}]", Namespace, FullName, Package);
2207
public override bool Equals (object obj)
2211
if (ReferenceEquals (this, obj))
2213
if (obj.GetType () != typeof(AssemblyLookup))
2215
AssemblyLookup other = (AssemblyLookup)obj;
2216
return Namespace == other.Namespace && FullName == other.FullName && Package == other.Package;
2219
public override int GetHashCode ()
2222
return (Namespace != null ? Namespace.GetHashCode () : 0) ^ (FullName != null ? FullName.GetHashCode () : 0) ^ (Package != null ? Package.GetHashCode () : 0);
2228
static IEnumerable<SystemAssembly> GetFrameworkAssemblies (DotNetProject netProject)
2230
var assemblies = new Dictionary<string, SystemAssembly> ();
2231
foreach (var systemPackage in netProject.AssemblyContext.GetPackages ()) {
2232
foreach (var assembly in systemPackage.Assemblies) {
2233
SystemAssembly existing;
2234
if (assemblies.TryGetValue (assembly.Name, out existing)) {
2236
if (!Version.TryParse (existing.Version, out v1))
2238
if (!Version.TryParse (assembly.Version, out v2))
2243
assemblies [assembly.Name] = assembly;
2246
return assemblies.Values;
2249
readonly static Dictionary<string, FrameworkLookup> frameworkLookup = new Dictionary<string, FrameworkLookup> ();
2250
public static FrameworkLookup GetFrameworkLookup (DotNetProject netProject)
2252
FrameworkLookup result;
2254
lock (frameworkLookup) {
2255
if (frameworkLookup.TryGetValue (netProject.TargetFramework.Name, out result))
2257
var cache = GetCacheDirectory (netProject.TargetFramework);
2258
fileName = Path.Combine (cache, "FrameworkLookup_" + FrameworkLookupVersion + ".dat");
2260
if (File.Exists (fileName)) {
2261
result = DeserializeObject<FrameworkLookup> (fileName);
2262
if (result.ItemCount > 0) {
2263
frameworkLookup [netProject.TargetFramework.Name] = result;
2264
if (result.Version == FrameworkLookupVersion)
2268
} catch (Exception e) {
2269
LoggingService.LogWarning ("Can't read framework cache - recreating...", e);
2271
result = new FrameworkLookup ();
2272
frameworkLookup [netProject.TargetFramework.Name] = result;
2273
foreach (var assembly in GetFrameworkAssemblies (netProject)) {
2274
var ctx = LoadAssemblyContext (assembly.Location);
2275
foreach (var type in ctx.Ctx.GetAllTypeDefinitions ()) {
2278
result.AddLookup (type, assembly);
2281
SerializeObject (fileName, result);
1599
2286
public static ProjectContentWrapper GetProjectContentWrapper (Project project)
1601
2288
if (project == null)
1602
2289
throw new ArgumentNullException ("project");
1603
2290
ProjectContentWrapper content;
1604
2291
if (projectContents.TryGetValue (project, out content)) {
1605
if (content.Content != null)
1606
content.Content.Location = project.FileName;
1607
2292
return content;
1609
2294
return new ProjectContentWrapper (project);
1671
2355
public void Run (IProgressMonitor monitor)
1673
2357
TypeSystemParserNode node = null;
1674
ITypeSystemParser parser = null;
1675
lock (FilesSkippedInParseThread) {
2358
TypeSystemParser parser = null;
2359
var tags = Context.GetExtensionObject <ProjectCommentTags> ();
2360
Context.InLoad = true;
1676
2362
foreach (var file in (FileList ?? Context.Project.Files)) {
1677
if (!string.Equals (file.BuildAction, "compile", StringComparison.OrdinalIgnoreCase))
1679
2363
var fileName = file.FilePath;
1680
if (FilesSkippedInParseThread.Contains (fileName))
2364
if (filesSkippedInParseThread.Any (f => f == fileName))
1682
if (node == null || !node.CanParse (fileName)) {
1683
node = TypeSystemService.GetTypeSystemParserNode (DesktopService.GetMimeTypeForUri (fileName));
2366
if (node == null || !node.CanParse (fileName, file.BuildAction)) {
2367
node = TypeSystemService.GetTypeSystemParserNode (DesktopService.GetMimeTypeForUri (fileName), file.BuildAction);
1684
2368
parser = node != null ? node.Parser : null;
1686
2370
if (parser == null)
1688
using (var stream = new System.IO.StreamReader (fileName)) {
1689
var parsedDocument = parser.Parse (false, fileName, stream, Context.Project);
1690
UpdateParsedDocument (Context, parsedDocument);
1691
Context.UpdateContent (c => c.UpdateProjectContent (c.GetFile (fileName), parsedDocument.ParsedFile));
2372
var parsedDocument = parser.Parse (false, fileName, Context.Project);
2374
tags.UpdateTags (Context.Project, parsedDocument.FileName, parsedDocument.TagComments);
2375
var oldFile = Context.Content.GetFile (fileName);
2376
Context.UpdateContent (c => c.AddOrUpdateFiles (parsedDocument.ParsedFile));
2377
if (oldFile != null)
2378
Context.InformFileRemoved (new ParsedFileEventArgs (oldFile));
2379
Context.InformFileAdded (new ParsedFileEventArgs (parsedDocument.ParsedFile));
2382
Context.InLoad = false;
1698
static void UpdateParsedDocument (ProjectContentWrapper context, ParsedDocument parsedDocument)
2387
static void UpdateProjectCommentTasks (ProjectContentWrapper context, ParsedDocument parsedDocument)
1700
2389
var tags = context.GetExtensionObject <ProjectCommentTags> ();
1702
tags = new ProjectCommentTags ();
1703
context.UpdateExtensionObject (tags);
1704
tags.Update (context.Project);
1706
tags.UpdateTags (context.Project, parsedDocument.FileName, parsedDocument.TagComments);
2390
if (tags != null) // When tags are not there they're updated first time the tasks are requested.
2391
tags.UpdateTags (context.Project, parsedDocument.FileName, parsedDocument.TagComments);
1709
public static event EventHandler<ProjectFileEventArgs> FileParsed;
2394
// public static event EventHandler<ProjectFileEventArgs> FileParsed;
1711
2396
static object parseQueueLock = new object ();
1712
2397
static AutoResetEvent parseEvent = new AutoResetEvent (false);
1840
static bool IsFileModified (ProjectFile file, IParsedFile parsedFile)
2526
static bool IsFileModified (ProjectFile file, IUnresolvedFile parsedFile)
1842
2528
if (parsedFile == null)
1844
return System.IO.File.GetLastWriteTimeUtc (file.FilePath) > parsedFile.LastWriteTime;
2531
return System.IO.File.GetLastWriteTimeUtc (file.FilePath) > parsedFile.LastWriteTime;
2532
} catch (Exception) {
1847
static void CheckModifiedFiles (Project project, ProjectContentWrapper content)
2537
static void CheckModifiedFiles (Project project, ProjectFile[] projectFiles, ProjectContentWrapper content)
1849
List<ProjectFile> modifiedFiles = null;
1850
foreach (var file in project.Files) {
1851
if (!string.Equals (file.BuildAction, "compile", StringComparison.OrdinalIgnoreCase))
1853
var fileName = file.Name;
1854
// if the file is already inside the content a parser exists for it, if not check if it can be parsed.
1855
var oldFile = content.Content.GetFile (fileName);
1856
if (oldFile == null) {
1857
var parser = TypeSystemService.GetParser (DesktopService.GetMimeTypeForUri (fileName));
1861
if (!IsFileModified (file, oldFile))
1863
if (modifiedFiles == null)
1864
modifiedFiles = new List<ProjectFile> ();
1865
modifiedFiles.Add (file);
1868
// check if file needs to be removed from project content
1869
foreach (var file in content.Content.Files) {
1870
if (project.GetProjectFile (file.FileName) == null)
1871
content.UpdateContent (c => c.UpdateProjectContent (file, null));
1874
if (modifiedFiles == null)
1876
QueueParseJob (content, modifiedFiles);
2540
var modifiedFiles = new List<ProjectFile> ();
2541
var oldFileNewFile = new List<Tuple<ProjectFile, IUnresolvedFile>> ();
2543
lock (projectWrapperUpdateLock) {
2544
foreach (var file in projectFiles) {
2545
if (file.BuildAction == null)
2547
// if the file is already inside the content a parser exists for it, if not check if it can be parsed.
2548
var oldFile = content.Content.GetFile (file.Name);
2549
oldFileNewFile.Add (Tuple.Create (file, oldFile));
2553
// This is disk intensive and slow
2554
oldFileNewFile.RemoveAll (t => !IsFileModified (t.Item1, t.Item2));
2556
lock (projectWrapperUpdateLock) {
2557
foreach (var v in oldFileNewFile) {
2559
var oldFile = v.Item2;
2560
if (oldFile == null) {
2561
var parser = TypeSystemService.GetParser (DesktopService.GetMimeTypeForUri (file.Name), file.BuildAction);
2565
modifiedFiles.Add (file);
2568
// check if file needs to be removed from project content
2569
foreach (var file in content.Content.Files) {
2570
if (project.GetProjectFile (file.FileName) == null) {
2571
content.UpdateContent (c => c.RemoveFiles (file.FileName));
2572
content.InformFileRemoved (new ParsedFileEventArgs (file));
2576
if (modifiedFiles.Count > 0)
2577
QueueParseJob (content, modifiedFiles);
2579
} catch (Exception e) {
2580
LoggingService.LogError ("Exception in check modified files.", e);
1879
2584
static void CheckModifiedFile (AssemblyContext context)