Пример #1
0
 public void Add(RootPackage pack)
 {
     if (pack != null && !packs.Contains(pack))
     {
         packs.Add(pack);
     }
 }
Пример #2
0
        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));
        }
Пример #3
0
 public ParsingFinishedEventArgs(string dir, RootPackage pack, long duration, long parseDuration, int fileCount)
 {
     Directory     = dir;
     Package       = pack;
     Duration      = duration;
     ParseDuration = parseDuration;
     FileAmount    = fileCount;
 }
Пример #4
0
		public ParsingFinishedEventArgs (string dir, RootPackage pack, long duration, long parseDuration, int fileCount)
		{
			Directory = dir;
			Package = pack;
			Duration = duration;
			ParseDuration = parseDuration;
			FileAmount = fileCount;
		}
Пример #5
0
        public void Clear(bool parseDirectories = false)
        {
            Root = null;
            if (parseDirectories)
            {
                ParsedDirectories = null;
            }

            Root = new RootPackage();
        }
Пример #6
0
        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);
        }
Пример #7
0
        public void ResolveWithCurrentContext(ResolveContext rc)
        {
            foreach (var attr in moduleAttributes)
            {
                VSharpAttribute a = (VSharpAttribute)attr;
                a.DoResolve(rc);
                resolvedAttributes.Add(a.ResolvedAttribute);
            }



            RootPackage.DoResolve(rc);
        }
Пример #8
0
        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();
                }
            }
        }
Пример #9
0
        public bool DoResolve(ResolveContext rc)
        {
            ResolveContext previousResolver = rc;

            try
            {
                rc = rc.WithCurrentUsingScope(RootPackage.ResolveScope(rc.Compilation));

                ResolveWithCurrentContext(rc);
            }
            finally
            {
                rc = previousResolver;
            }

            return(true);
        }
Пример #10
0
        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;
        }
Пример #11
0
        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));
            }
        }
Пример #12
0
		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 ();
				}
			}
		}
Пример #13
0
			public ParseIntermediate (StatIntermediate im, RootPackage r, string f)
			{
				this.im = im;
				root = r;
				file = f;
			}
Пример #14
0
 public void Add(RootPackage pack)
 {
     if (pack != null && !packs.Contains(pack))
         packs.Add(pack);
 }
Пример #15
0
 public UFCSCache(RootPackage root)
 {
     this.Root = root;
 }
Пример #16
0
		public UFCSCache(RootPackage root)
		{
			this.Root = root;
		}
Пример #17
0
        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();
                }
            }
        }
Пример #18
0
 public ParseIntermediate(StatIntermediate im, RootPackage r, string f)
 {
     this.im = im;
     root    = r;
     file    = f;
 }
Пример #19
0
        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));
            }
        }