ProjectEntry DoParse(ITextSource fileContent, IProject parentProject, bool fullParseInformationRequested, CancellationToken cancellationToken) { if (parser == null) { return(default(ProjectEntry)); } if (fileContent == null) { // No file content was specified. Because the callers of this method already check for currently open files, // we can assume that the file isn't open and simply read it from disk. try { fileContent = SD.FileService.GetFileContentFromDisk(fileName, cancellationToken); } catch (IOException) { // It is possible that the file gets deleted/becomes inaccessible while a background parse // operation is enqueued, so we have to handle IO exceptions. return(default(ProjectEntry)); } catch (UnauthorizedAccessException) { return(default(ProjectEntry)); } } ProjectEntry result; rwLock.EnterUpgradeableReadLock(); try { int index = FindIndexForProject(parentProject); int versionComparison = CompareVersions(fileContent.Version); if (versionComparison > 0 || index < 0) { // We're going backwards in time, or are requesting a project that is not an owner // for this entry. var parseInfo = ParseWithExceptionHandling(fileContent, fullParseInformationRequested, parentProject, cancellationToken); FreezableHelper.Freeze(parseInfo.UnresolvedFile); return(new ProjectEntry(parentProject, parseInfo.UnresolvedFile, parseInfo)); } else { if (versionComparison == 0 && index >= 0) { // Ensure we have parse info for the specified project (entry.UnresolvedFile is null for newly registered projects) // If full parse info is requested, ensure we have full parse info. if (entries[index].UnresolvedFile != null && !(fullParseInformationRequested && entries[index].CachedParseInformation == null)) { // We already have the requested version parsed, just return it: return(entries[index]); } } } ParseInformationEventArgs[] results = new ParseInformationEventArgs[entries.Count]; for (int i = 0; i < entries.Count; i++) { var parseInfo = ParseWithExceptionHandling(fileContent, fullParseInformationRequested, entries[i].Project, cancellationToken); if (parseInfo == null) { throw new NullReferenceException(parser.GetType().Name + ".Parse() returned null"); } if (fullParseInformationRequested && !parseInfo.IsFullParseInformation) { throw new InvalidOperationException(parser.GetType().Name + ".Parse() did not return full parse info as requested."); } OnDiskTextSourceVersion onDiskVersion = fileContent.Version as OnDiskTextSourceVersion; if (onDiskVersion != null) { parseInfo.UnresolvedFile.LastWriteTime = onDiskVersion.LastWriteTime; } FreezableHelper.Freeze(parseInfo.UnresolvedFile); results[i] = new ParseInformationEventArgs(entries[i].Project, entries[i].UnresolvedFile, parseInfo); } // Only if all parse runs succeeded, register the parse information. rwLock.EnterWriteLock(); try { currentVersion = fileContent.Version; for (int i = 0; i < entries.Count; i++) { if (fullParseInformationRequested || (entries[i].CachedParseInformation != null && results[i].NewParseInformation.IsFullParseInformation)) { entries[i] = new ProjectEntry(entries[i].Project, results[i].NewUnresolvedFile, results[i].NewParseInformation); } else { entries[i] = new ProjectEntry(entries[i].Project, results[i].NewUnresolvedFile, null); } if (entries[i].Project != null) { entries[i].Project.OnParseInformationUpdated(results[i]); } parserService.RaiseParseInformationUpdated(results[i]); } result = entries[index]; } finally { rwLock.ExitWriteLock(); } } finally { rwLock.ExitUpgradeableReadLock(); } parserService.RegisterForCacheExpiry(this); return(result); }
void FreezeInternal() { attributes = FreezableHelper.FreezeListAndElements(attributes); FreezableHelper.Freeze(defaultValue); }
protected override void FreezeInternal() { FreezableHelper.Freeze(constantValue); base.FreezeInternal(); }