public void Add(RootPackage pack) { if (pack != null && !packs.Contains(pack)) { packs.Add(pack); } }
public static ModulePackage GetOrCreatePackageByDirectory(string physicalPackagePath, bool create = false) { RootPackage root = null; foreach (var kv in ParsedDirectories) { if (!physicalPackagePath.StartsWith(kv.Key)) { continue; } root = kv.Value; physicalPackagePath = physicalPackagePath.Substring(kv.Key.Length); break; } if (root == null) { return(null); } physicalPackagePath = physicalPackagePath.Trim(Path.DirectorySeparatorChar); if (physicalPackagePath == string.Empty) { return(root); } return(root.GetOrCreateSubPackage(physicalPackagePath.Replace(Path.DirectorySeparatorChar, '.'), create)); }
public ParsingFinishedEventArgs(string dir, RootPackage pack, long duration, long parseDuration, int fileCount) { Directory = dir; Package = pack; Duration = duration; ParseDuration = parseDuration; FileAmount = fileCount; }
public ParsingFinishedEventArgs (string dir, RootPackage pack, long duration, long parseDuration, int fileCount) { Directory = dir; Package = pack; Duration = duration; ParseDuration = parseDuration; FileAmount = fileCount; }
public void Clear(bool parseDirectories = false) { Root = null; if (parseDirectories) { ParsedDirectories = null; } Root = new RootPackage(); }
public static ParsePerformanceData Parse(string directory, RootPackage rootPackage) { var ppd = new ParsePerformanceData { BaseDirectory = directory }; /* * 1) List all files * 2) Create module packages * 3) Enlist all file-package pairs in the queue * 4) Start parse threads * 5) Wait for all to join */ var tpd = new ThreadedDirectoryParser { baseDirectory = directory }; // 1), 2), 3) tpd.PrepareQueue(rootPackage); ppd.AmountFiles = tpd.queue.Count; var sw = new Stopwatch(); sw.Start(); // 4) var threads = new Thread[numThreads]; for (int i = 0; i < numThreads; i++) { var th = threads[i] = new Thread(tpd.ParseThread) { IsBackground = true, Priority = ThreadPriority.Lowest, Name = "Parser thread #" + i + " (" + directory + ")" }; th.Start(); } // 5) for (int i = 0; i < numThreads; i++) { if (threads[i].IsAlive) { threads[i].Join(10000); } } sw.Stop(); ppd.TotalDuration = sw.Elapsed.TotalSeconds; return(ppd); }
public void ResolveWithCurrentContext(ResolveContext rc) { foreach (var attr in moduleAttributes) { VSharpAttribute a = (VSharpAttribute)attr; a.DoResolve(rc); resolvedAttributes.Add(a.ResolvedAttribute); } RootPackage.DoResolve(rc); }
void parseDg(object o) { var tup = (Tuple <IEnumerable <string>, List <ParsePerformanceData> >)o; var parsedDirs = new List <string>(); var newRoot = new RootPackage(); foreach (var dir in tup.Item1) { parsedDirs.Add(dir); var dir_abs = dir; if (!Path.IsPathRooted(dir)) { dir_abs = Path.Combine(FallbackPath, dir_abs); } var ppd = ThreadedDirectoryParser.Parse(dir_abs, newRoot); if (ppd != null) { tup.Item2.Add(ppd); } } UfcsCache.Clear(); ParsedDirectories = parsedDirs; Root = newRoot; // For performance boost, pre-resolve the object class HandleObjectModule(GetModule("object")); if (FinishedParsing != null) { FinishedParsing(tup.Item2.ToArray()); } if (EnableUfcsCaching) { UfcsCache.Update(ParseCacheList.Create(this)); if (FinishedUfcsCaching != null) { FinishedUfcsCaching(); } } }
public bool DoResolve(ResolveContext rc) { ResolveContext previousResolver = rc; try { rc = rc.WithCurrentUsingScope(RootPackage.ResolveScope(rc.Compilation)); ResolveWithCurrentContext(rc); } finally { rc = previousResolver; } return(true); }
public static ParsePerformanceData Parse(string directory, RootPackage rootPackage) { var ppd = new ParsePerformanceData { BaseDirectory = directory }; /* * 1) List all files * 2) Create module packages * 3) Enlist all file-package pairs in the queue * 4) Start parse threads * 5) Wait for all to join */ var tpd = new ThreadedDirectoryParser { baseDirectory = directory }; // 1), 2), 3) tpd.PrepareQueue(rootPackage); ppd.AmountFiles = tpd.queue.Count; var sw = new Stopwatch(); sw.Start(); // 4) var threads = new Thread[numThreads]; for (int i = 0; i < numThreads; i++) { var th = threads[i] = new Thread(tpd.ParseThread) { IsBackground = true, Priority= ThreadPriority.Lowest, Name = "Parser thread #"+i+" ("+directory+")" }; th.Start(); } // 5) for (int i = 0; i < numThreads; i++) if (threads[i].IsAlive) threads[i].Join(10000); sw.Stop(); ppd.TotalDuration = sw.Elapsed.TotalSeconds; return ppd; }
void PrepareQueue(RootPackage root) { if (!Directory.Exists(baseDirectory)) { return; } //ISSUE: wild card character ? seems to behave differently across platforms // msdn: -> Exactly zero or one character. // monodocs: -> Exactly one character. var dFiles = Directory.GetFiles(baseDirectory, "*.d", SearchOption.AllDirectories); var diFiles = Directory.GetFiles(baseDirectory, "*.di", SearchOption.AllDirectories); var files = new string[dFiles.Length + diFiles.Length]; Array.Copy(dFiles, 0, files, 0, dFiles.Length); Array.Copy(diFiles, 0, files, dFiles.Length, diFiles.Length); var lastPack = (ModulePackage)root; var lastDir = baseDirectory; bool isPhobosRoot = this.baseDirectory.EndsWith(Path.DirectorySeparatorChar + "phobos"); foreach (var file in files) { var modulePath = DModule.GetModuleName(baseDirectory, file); if (lastDir != (lastDir = Path.GetDirectoryName(file))) { isPhobosRoot = this.baseDirectory.EndsWith(Path.DirectorySeparatorChar + "phobos"); var packName = ModuleNameHelper.ExtractPackageName(modulePath); lastPack = root.GetOrCreateSubPackage(packName, true); } // Skip index.d (D2) || phobos.d (D2|D1) if (isPhobosRoot && (file.EndsWith("index.d") || file.EndsWith("phobos.d"))) { continue; } queue.Push(new KeyValuePair <string, ModulePackage>(file, lastPack)); } }
static void preparationTh () { while (true) { if (basePathQueue.IsEmpty && !preparationThreadStartEvent.WaitOne (ThreadWaitTimeout)) return; PathQueueArgs tup; while (basePathQueue.TryPop(out tup)) { if (stopParsing) break; var path = tup.basePath; if (!Directory.Exists (path)) continue; // Is it okay to directly skip it w/o calling noticeFinished? StatIntermediate statIm; // Check if path is being parsed currently. { criticalPreparationSection.WaitOne (); if (ParseStatistics.TryGetValue (path, out statIm)) { if(tup.finished_untilCount != null) statIm.parseSubTasksUntilFinished.Add (tup.finished_untilCount); if (Interlocked.Decrement (ref parsingThreads) < 1) throw new InvalidOperationException ("Race-condition during parse process: There must be two or more parse tasks active!"); criticalPreparationSection.Set (); continue; } ParseStatistics [path] = statIm = new StatIntermediate { skipFunctionBodies = tup.skipFunctionBodies, basePath = path, }; if(tup.finished_untilCount != null) statIm.parseSubTasksUntilFinished.Add (tup.finished_untilCount); criticalPreparationSection.Set (); } // Check if it's necessary to reparse the directory RootPackage oldRoot; if (ParsedDirectories.TryGetValue (path, out oldRoot) && oldRoot.LastParseTime >= Directory.GetLastWriteTimeUtc (path)) { noticeFinish (new ParseIntermediate (statIm, oldRoot, string.Empty)); continue; } statIm.sw.Restart (); //ISSUE: wild card character ? seems to behave differently across platforms // msdn: -> Exactly zero or one character. // monodocs: -> Exactly one character. var files = Directory.GetFiles (path, "*.d", SearchOption.AllDirectories); var ifiles = Directory.GetFiles (path, "*.di", SearchOption.AllDirectories); statIm.totalFiles = statIm.remainingFiles = files.Length + ifiles.Length; var newRoot = new RootPackage { LastParseTime = Directory.GetLastWriteTimeUtc(path) }; if (statIm.totalFiles == 0) { noticeFinish (new ParseIntermediate (statIm, newRoot, string.Empty)); continue; } parseThreadStartEvent.Set (); LaunchParseThreads (); if (files.Length != 0) foreach (string file in files) queue.Push (new ParseIntermediate (statIm, newRoot, file)); if (ifiles.Length != 0) foreach (string ifile in ifiles) queue.Push (new ParseIntermediate (statIm, newRoot,ifile)); parseThreadStartEvent.Reset (); } } }
public ParseIntermediate (StatIntermediate im, RootPackage r, string f) { this.im = im; root = r; file = f; }
public void Add(RootPackage pack) { if (pack != null && !packs.Contains(pack)) packs.Add(pack); }
public UFCSCache(RootPackage root) { this.Root = root; }
static void preparationTh() { while (true) { if (basePathQueue.IsEmpty && !preparationThreadStartEvent.WaitOne(ThreadWaitTimeout)) { return; } PathQueueArgs tup; while (basePathQueue.TryPop(out tup)) { if (stopParsing) { break; } var path = tup.basePath; if (!Directory.Exists(path)) { continue; // Is it okay to directly skip it w/o calling noticeFinished? } StatIntermediate statIm; // Check if path is being parsed currently. { criticalPreparationSection.WaitOne(); if (ParseStatistics.TryGetValue(path, out statIm)) { if (tup.finished_untilCount != null) { statIm.parseSubTasksUntilFinished.Add(tup.finished_untilCount); } if (Interlocked.Decrement(ref parsingThreads) < 1) { throw new InvalidOperationException("Race-condition during parse process: There must be two or more parse tasks active!"); } criticalPreparationSection.Set(); continue; } ParseStatistics [path] = statIm = new StatIntermediate { skipFunctionBodies = tup.skipFunctionBodies, basePath = path, }; if (tup.finished_untilCount != null) { statIm.parseSubTasksUntilFinished.Add(tup.finished_untilCount); } criticalPreparationSection.Set(); } // Check if it's necessary to reparse the directory RootPackage oldRoot; if (ParsedDirectories.TryGetValue(path, out oldRoot) && oldRoot.LastParseTime >= Directory.GetLastWriteTimeUtc(path)) { noticeFinish(new ParseIntermediate(statIm, oldRoot, string.Empty)); continue; } statIm.sw.Restart(); //ISSUE: wild card character ? seems to behave differently across platforms // msdn: -> Exactly zero or one character. // monodocs: -> Exactly one character. var files = Directory.GetFiles(path, "*.d", SearchOption.AllDirectories); var ifiles = Directory.GetFiles(path, "*.di", SearchOption.AllDirectories); statIm.totalFiles = statIm.remainingFiles = files.Length + ifiles.Length; var newRoot = new RootPackage { LastParseTime = Directory.GetLastWriteTimeUtc(path) }; if (statIm.totalFiles == 0) { noticeFinish(new ParseIntermediate(statIm, newRoot, string.Empty)); continue; } parseThreadStartEvent.Set(); LaunchParseThreads(); if (files.Length != 0) { foreach (string file in files) { queue.Push(new ParseIntermediate(statIm, newRoot, file)); } } if (ifiles.Length != 0) { foreach (string ifile in ifiles) { queue.Push(new ParseIntermediate(statIm, newRoot, ifile)); } } parseThreadStartEvent.Reset(); } } }
public ParseIntermediate(StatIntermediate im, RootPackage r, string f) { this.im = im; root = r; file = f; }
void PrepareQueue(RootPackage root) { if (!Directory.Exists(baseDirectory)) return; //ISSUE: wild card character ? seems to behave differently across platforms // msdn: -> Exactly zero or one character. // monodocs: -> Exactly one character. var dFiles = Directory.GetFiles(baseDirectory, "*.d", SearchOption.AllDirectories); var diFiles = Directory.GetFiles(baseDirectory, "*.di", SearchOption.AllDirectories); var files = new string[dFiles.Length + diFiles.Length]; Array.Copy(dFiles, 0, files, 0, dFiles.Length); Array.Copy(diFiles, 0, files, dFiles.Length, diFiles.Length); var lastPack = (ModulePackage)root; var lastDir = baseDirectory; bool isPhobosRoot = this.baseDirectory.EndsWith(Path.DirectorySeparatorChar + "phobos"); foreach (var file in files) { var modulePath = DModule.GetModuleName(baseDirectory, file); if (lastDir != (lastDir = Path.GetDirectoryName(file))) { isPhobosRoot = this.baseDirectory.EndsWith(Path.DirectorySeparatorChar + "phobos"); var packName = ModuleNameHelper.ExtractPackageName(modulePath); lastPack = root.GetOrCreateSubPackage(packName, true); } // Skip index.d (D2) || phobos.d (D2|D1) if (isPhobosRoot && (file.EndsWith("index.d") || file.EndsWith("phobos.d"))) continue; queue.Push(new KeyValuePair<string, ModulePackage>(file, lastPack)); } }