Esempio n. 1
0
        protected void AddClassToNamespaceListInternal(IClass addClass)
        {
            // Freeze the class when adding it to the project content
            addClass.Freeze();

            Debug.Assert(!(addClass is CompoundClass));
            Debug.Assert(!addClass.HasCompoundClass);

            string fullyQualifiedName = addClass.FullyQualifiedName;
            IClass existingClass      = GetClassInternal(fullyQualifiedName, addClass.TypeParameters.Count, language);

            if (existingClass != null && existingClass.TypeParameters.Count == addClass.TypeParameters.Count)
            {
                LoggingService.Debug("Adding existing class " + addClass.Name + " from " + Path.GetFileName(addClass.CompilationUnit.FileName));
                CompoundClass compound = existingClass as CompoundClass;
                if (compound != null)
                {
                    // mark the class as partial
                    // (VB allows specifying the 'partial' modifier only on one part)
                    addClass.HasCompoundClass = true;

                    // add the new class to the compound class
                    List <IClass> newParts = new List <IClass>(compound.Parts);
                    newParts.Add(addClass);
                    // construct a replacement CompoundClass with the new part list
                    addClass = CompoundClass.Create(newParts);
                    LoggingService.Debug("Added new part (old part count=" + compound.Parts.Count + ", new part count=" + newParts.Count + ")");
                }
                else
                {
                    // Instead of overwriting a class with another, treat both parts as partial.
                    // This fixes SD2-1217.

                    if (!(addClass.IsPartial || language.ImplicitPartialClasses))
                    {
                        LoggingService.Info("Duplicate class " + fullyQualifiedName + ", creating compound");
                    }
                    else
                    {
                        LoggingService.Debug("Creating compound for " + fullyQualifiedName);
                    }

                    // Merge existing non-partial class with addClass
                    addClass.HasCompoundClass      = true;
                    existingClass.HasCompoundClass = true;

                    addClass = CompoundClass.Create(new[] { addClass, existingClass });
                }
            }
            AddClassToNamespaceListInternal2(addClass);
        }
Esempio n. 2
0
        protected void RemoveClass(IClass @class)
        {
            string fullyQualifiedName = @class.FullyQualifiedName;
            int    typeParameterCount = @class.TypeParameters.Count;

            if (@class.HasCompoundClass)
            {
                LoggingService.Debug("Removing part " + @class.CompilationUnit.FileName + " from compound class " + @class.FullyQualifiedName);

                // remove a part of a partial class
                // Use "as" cast to fix SD2-680: the stored class might be a part not marked as partial
                CompoundClass compound = GetClassInternal(fullyQualifiedName, typeParameterCount, language) as CompoundClass;
                if (compound == null)
                {
                    LoggingService.Warn("compound class not found");
                    return;
                }
                typeParameterCount = compound.TypeParameters.Count;

                List <IClass> newParts = new List <IClass>(compound.Parts);
                newParts.Remove(@class);
                if (newParts.Count > 1)
                {
                    LoggingService.Debug("Part removed, old part count = " + compound.Parts.Count + ", new part count=" + newParts.Count);
                    AddClassToNamespaceListInternal2(CompoundClass.Create(newParts));
                    return;
                }
                else if (newParts.Count == 1)
                {
                    LoggingService.Debug("Second-to-last part removed (old part count = " + compound.Parts.Count + "), overwriting compound with last part");
                    newParts[0].HasCompoundClass = false;
                    AddClassToNamespaceListInternal2(newParts[0]);
                    return;
                }
                else                     // newParts.Count == 0
                                         // this should not be possible, the compound should have been destroyed when there was only 1 part left
                {
                    LoggingService.Warn("All parts removed, remove compound");
                    @class = compound;                     // all parts removed, remove compound class
                }
            }

            IClass classInDictionary;

            if (!GetClasses(language).TryGetValue(fullyQualifiedName, out classInDictionary))
            {
                return;
            }

            GenericClassContainer gcc = classInDictionary as GenericClassContainer;

            if (gcc != null)
            {
                gcc.Remove(typeParameterCount);
                if (gcc.RealClassCount > 0)
                {
                    return;
                }
            }

            foreach (Dictionary <string, IClass> classes in ClassLists)
            {
                classes.Remove(fullyQualifiedName);
            }

            string nSpace = @class.Namespace;

            if (nSpace == null)
            {
                nSpace = String.Empty;
            }

            // Remove class from namespace lists
            List <IClass> classList = GetNamespaces(this.language)[nSpace].Classes;

            for (int i = 0; i < classList.Count; i++)
            {
                if (language.NameComparer.Equals(classList[i].FullyQualifiedName, fullyQualifiedName))
                {
                    classList.RemoveAt(i);
                    break;
                }
            }
            if (classList.Count == 0)
            {
                RemoveEmptyNamespace(nSpace);
            }
        }
        protected void AddClassToNamespaceListInternal(IClass addClass)
        {
            string fullyQualifiedName = addClass.FullyQualifiedName;
            IClass existingClass      = GetClassInternal(fullyQualifiedName, addClass.TypeParameters.Count, language);

            if (existingClass != null && existingClass.TypeParameters.Count == addClass.TypeParameters.Count)
            {
                //LoggingService.Debug("Adding partial class " + addClass.Name + " from " + Path.GetFileName(addClass.CompilationUnit.FileName));
                CompoundClass compound = existingClass as CompoundClass;
                if (compound != null)
                {
                    // mark the class as partial
                    // (VB allows specifying the 'partial' modifier only on one part)
                    addClass.IsPartial = true;

                    // possibly replace existing class (look for CU with same filename)
                    lock (compound) {
                        for (int i = 0; i < compound.parts.Count; i++)
                        {
                            if (compound.parts[i].CompilationUnit.FileName == addClass.CompilationUnit.FileName)
                            {
                                compound.parts[i] = addClass;
                                compound.UpdateInformationFromParts();
                                //LoggingService.Debug("Replaced old part!");
                                return;
                            }
                        }
                        compound.parts.Add(addClass);
                        compound.UpdateInformationFromParts();
                    }
                    //LoggingService.Debug("Added new part!");
                    return;
                }
                else if (addClass.IsPartial || language.ImplicitPartialClasses)
                {
                    // Merge existing non-partial class with addClass

                    // Ensure partial modifier is set everywhere:
                    addClass.IsPartial      = true;
                    existingClass.IsPartial = true;

                    addClass = compound = new CompoundClass(addClass);
                    compound.parts.Add(existingClass);
                    compound.UpdateInformationFromParts();
                }
            }
            else if (addClass.IsPartial)
            {
                addClass = new CompoundClass(addClass);
                //LoggingService.Debug("Compound created!");
            }

            IClass oldDictionaryClass;

            if (GetClasses(language).TryGetValue(fullyQualifiedName, out oldDictionaryClass))
            {
                GenericClassContainer gcc = oldDictionaryClass as GenericClassContainer;
                if (gcc != null)
                {
                    gcc.Set(addClass);
                    return;
                }
                else if (oldDictionaryClass.TypeParameters.Count != addClass.TypeParameters.Count)
                {
                    gcc = new GenericClassContainer(fullyQualifiedName);
                    gcc.Set(addClass);
                    gcc.Set(oldDictionaryClass);
                    addClass = gcc;
                }
            }

            foreach (Dictionary <string, IClass> classes in ClassLists)
            {
                classes[addClass.FullyQualifiedName] = addClass;
            }
            string nSpace = addClass.Namespace;

            if (nSpace == null)
            {
                nSpace = String.Empty;
            }
            CreateNamespace(nSpace);
            List <IClass> classList = GetNamespaces(this.language)[nSpace].Classes;

            for (int i = 0; i < classList.Count; i++)
            {
                if (classList[i].FullyQualifiedName == addClass.FullyQualifiedName)
                {
                    classList[i] = addClass;
                    return;
                }
            }
            classList.Add(addClass);
        }
        void RemoveClass(IClass @class)
        {
            string fullyQualifiedName = @class.FullyQualifiedName;
            int    typeParameterCount = @class.TypeParameters.Count;

            if (@class.IsPartial)
            {
                // remove a part of a partial class
                // Use "as" cast to fix SD2-680: the stored class might be a part not marked as partial
                CompoundClass compound = GetClassInternal(fullyQualifiedName, typeParameterCount, language) as CompoundClass;
                if (compound == null)
                {
                    return;
                }
                typeParameterCount = compound.TypeParameters.Count;
                lock (compound) {
                    compound.parts.Remove(@class);
                    if (compound.parts.Count > 0)
                    {
                        compound.UpdateInformationFromParts();
                        return;
                    }
                    else
                    {
                        @class = compound;                         // all parts removed, remove compound class
                    }
                }
            }

            IClass classInDictionary;

            if (!GetClasses(language).TryGetValue(fullyQualifiedName, out classInDictionary))
            {
                return;
            }

            GenericClassContainer gcc = classInDictionary as GenericClassContainer;

            if (gcc != null)
            {
                gcc.Remove(typeParameterCount);
                if (gcc.RealClassCount > 0)
                {
                    return;
                }
            }

            foreach (Dictionary <string, IClass> classes in ClassLists)
            {
                classes.Remove(fullyQualifiedName);
            }

            string nSpace = @class.Namespace;

            if (nSpace == null)
            {
                nSpace = String.Empty;
            }

            // Remove class from namespace lists
            List <IClass> classList = GetNamespaces(this.language)[nSpace].Classes;

            for (int i = 0; i < classList.Count; i++)
            {
                if (language.NameComparer.Equals(classList[i].FullyQualifiedName, fullyQualifiedName))
                {
                    classList.RemoveAt(i);
                    break;
                }
            }
            if (classList.Count == 0)
            {
                RemoveEmptyNamespace(nSpace);
            }
        }
		protected void AddClassToNamespaceListInternal(IClass addClass)
		{
			string fullyQualifiedName = addClass.FullyQualifiedName;
			IClass existingClass = GetClassInternal(fullyQualifiedName, addClass.TypeParameters.Count, language);
			if (existingClass != null && existingClass.TypeParameters.Count == addClass.TypeParameters.Count) {
				//LoggingService.Debug("Adding partial class " + addClass.Name + " from " + Path.GetFileName(addClass.CompilationUnit.FileName));
				CompoundClass compound = existingClass as CompoundClass;
				if (compound != null) {
					// mark the class as partial
					// (VB allows specifying the 'partial' modifier only on one part)
					addClass.IsPartial = true;
					
					// possibly replace existing class (look for CU with same filename)
					lock (compound) {
						for (int i = 0; i < compound.parts.Count; i++) {
							if (compound.parts[i].CompilationUnit.FileName == addClass.CompilationUnit.FileName) {
								compound.parts[i] = addClass;
								compound.UpdateInformationFromParts();
								//LoggingService.Debug("Replaced old part!");
								return;
							}
						}
						compound.parts.Add(addClass);
						compound.UpdateInformationFromParts();
					}
					//LoggingService.Debug("Added new part!");
					return;
				} else if (addClass.IsPartial || language.ImplicitPartialClasses) {
					// Merge existing non-partial class with addClass
					
					// Ensure partial modifier is set everywhere:
					addClass.IsPartial = true;
					existingClass.IsPartial = true;
					
					addClass = compound = new CompoundClass(addClass);
					compound.parts.Add(existingClass);
					compound.UpdateInformationFromParts();
				}
			} else if (addClass.IsPartial) {
				addClass = new CompoundClass(addClass);
				//LoggingService.Debug("Compound created!");
			}
			
			IClass oldDictionaryClass;
			if (GetClasses(language).TryGetValue(fullyQualifiedName, out oldDictionaryClass)) {
				GenericClassContainer gcc = oldDictionaryClass as GenericClassContainer;
				if (gcc != null) {
					gcc.Set(addClass);
					return;
				} else if (oldDictionaryClass.TypeParameters.Count != addClass.TypeParameters.Count) {
					gcc = new GenericClassContainer(fullyQualifiedName);
					gcc.Set(addClass);
					gcc.Set(oldDictionaryClass);
					addClass = gcc;
				}
			}
			
			foreach (Dictionary<string, IClass> classes in ClassLists) {
				classes[addClass.FullyQualifiedName] = addClass;
			}
			string nSpace = addClass.Namespace;
			if (nSpace == null) {
				nSpace = String.Empty;
			}
			CreateNamespace(nSpace);
			List<IClass> classList = GetNamespaces(this.language)[nSpace].Classes;
			for (int i = 0; i < classList.Count; i++) {
				if (classList[i].FullyQualifiedName == addClass.FullyQualifiedName) {
					classList[i] = addClass;
					return;
				}
			}
			classList.Add(addClass);
		}