private static byte[] GetSerializationVersion() { using (new DebugTimer("SerializationVersionInitialization")) { SHA256 sha = SHA256Managed.Create(); StringBuilder sb = new StringBuilder(); var attrs = (AnalysisSerializationSupportedTypeAttribute[])typeof(AnalysisSerializationSupportedTypeAttribute).Assembly.GetCustomAttributes(typeof(AnalysisSerializationSupportedTypeAttribute), false); // we don't want to rely upon the order of reflection here... Array.Sort <AnalysisSerializationSupportedTypeAttribute>( attrs, (Comparison <AnalysisSerializationSupportedTypeAttribute>)((x, y) => String.CompareOrdinal(x.Type.Name, y.Type.Name)) ); foreach (var attr in attrs) { var type = attr.Type; sb.AppendLine(type.FullName); foreach (FieldInfo field in AnalysisSerializer.GetSerializableMembers(type)) { sb.Append(field.FieldType.FullName); sb.Append(' '); sb.Append(field.Name); sb.AppendLine(); } } return(BitConverter.GetBytes(_analyzerVersion) .Concat(sha.ComputeHash(Encoding.UTF8.GetBytes(sb.ToString()))) .ToArray()); } }
private void SaveAnalysis() { if (_implicitProject || _projectFileDir == null || !_saveToDisk) { return; } try { using (new DebugTimer("SaveAnalysis")) { var path = GetAnalysisPath(); var tempPath = path + ".tmp"; bool failed = false; if (File.Exists(tempPath)) { // Create doesn't overwrite hidden files, so delete it File.Delete(tempPath); } using (FileStream fs = new FileStream(tempPath, FileMode.Create)) { new FileInfo(tempPath).Attributes |= FileAttributes.Hidden; fs.Write(DbHeader, 0, DbHeader.Length); try { var serializer = new AnalysisSerializer(); serializer.Serialize(fs, _jsAnalyzer); } catch (Exception e) { Debug.Fail("Failed to save analysis " + e); failed = true; } } if (!failed) { if (File.Exists(path)) { File.Delete(path); } File.Move(tempPath, path); } else { File.Delete(tempPath); } } } catch (IOException) { } catch (UnauthorizedAccessException) { } }
private bool LoadCachedAnalysis(AnalysisLimits limits) { if (_analysisLevel == AnalysisLevel.NodeLsNone || _analysisLevel == AnalysisLevel.Preview) { return false; } string analysisDb = GetAnalysisPath(); if (File.Exists(analysisDb) && ShouldEnqueue()) { FileStream stream = null; bool disposeStream = true; try { stream = new FileStream(analysisDb, FileMode.Open); byte[] header = new byte[DbHeader.Length]; stream.Read(header, 0, header.Length); if (DbHeader.SequenceEqual(header)) { var statusbar = (IVsStatusbar)NodejsPackage.GetGlobalService(typeof(SVsStatusbar)); if (statusbar != null) { statusbar.SetText(SR.GetString(SR.StatusAnalysisLoading)); } Task.Run(() => { try { using (new DebugTimer("LoadAnalysis")) { var serializer = new AnalysisSerializer(); var analyzer = (JsAnalyzer)serializer.Deserialize(stream); AnalysisQueue queue; if (analyzer.Limits.Equals(limits)) { queue = new AnalysisQueue(this); foreach (var entry in analyzer.AllModules) { _projectFiles[entry.FilePath] = new ProjectItem(entry); } _reparseDateTime = new FileInfo(analysisDb).LastWriteTime; _analysisQueue = queue; _jsAnalyzer = analyzer; if (statusbar != null) { statusbar.SetText(SR.GetString(SR.StatusAnalysisLoaded)); } } } } catch (InvalidOperationException) { // corrupt or invalid DB if (statusbar != null) { statusbar.SetText(SR.GetString(SR.StatusAnalysisLoadFailed)); } } catch (Exception e) { Debug.Fail(String.Format("Unexpected exception while loading analysis: {0}", e)); // bug in deserialization if (statusbar != null) { statusbar.SetText(SR.GetString(SR.StatusAnalysisLoadFailed)); } } finally { stream.Dispose(); // apply any changes lock (_loadingDeltas) { if (_jsAnalyzer == null) { // we failed to load the cached analysis, create a new // analyzer now... CreateNewAnalyzer(LoadLimits()); } _fullyLoaded = true; foreach (var delta in _loadingDeltas) { delta(); } } } }).HandleAllExceptions(SR.GetString(SR.NodejsToolsForVisualStudio)).DoNotWait(); disposeStream = false; return true; } } catch (IOException) { } finally { if (stream != null && disposeStream) { stream.Dispose(); } } } return false; }