Пример #1
0
        /// <summary>
        /// Resolves reference from libraries to classes and other libraries.
        /// </summary>
        /// <param name="libraryTable">The table of known libraries.</param>
        /// <param name="resolvedLibraryList">The list of libraries that have been resolved so far.</param>
        /// <param name="importChanged">Indicates that the import specifier has changed.</param>
        /// <param name="errorList">List of errors found.</param>
        /// <returns>True if the method succeeded.</returns>
        public virtual bool Resolve(ISealableDictionary <string, ISealableDictionary <string, ILibrary> > libraryTable, IList <ILibrary> resolvedLibraryList, ref bool importChanged, IErrorList errorList)
        {
            List <IImport> ToRemove = new List <IImport>();
            bool           Success  = true;

            foreach (IImport ImportItem in ImportList)
            {
                // Check the import and obtain the matching library.
                if (!ImportItem.CheckImportConsistency(libraryTable, out ILibrary MatchingLibrary, errorList))
                {
                    Success = false;
                    continue;
                }

                // You can't import the same library twice.
                if (ImportedLibraryList.Contains(MatchingLibrary))
                {
                    Success = false;
                    errorList.AddError(new ErrorDuplicateImport((IIdentifier)ImportItem.LibraryIdentifier, MatchingLibrary.ValidLibraryName, MatchingLibrary.ValidSourceName));
                    continue;
                }

                // If the imported library hasn't been resolved yet, ignore it for now.
                if (!resolvedLibraryList.Contains(MatchingLibrary))
                {
                    continue;
                }

                // The imported library was resolved, merge this import with it.
                if (!MergeImports(ImportedClassTable, ImportItem, MatchingLibrary, errorList))
                {
                    Success = false;
                    continue;
                }

                ImportedLibraryList.Add(MatchingLibrary);
                ToRemove.Add(ImportItem);
                importChanged = true;
            }

            foreach (IImport ImportItem in ToRemove)
            {
                ImportList.Remove(ImportItem);
            }

            Debug.Assert(Success || !errorList.IsEmpty);
            return(Success);
        }
Пример #2
0
        /// <summary>
        /// Validates a class import clauses.
        /// </summary>
        /// <param name="libraryTable">Imported libraries.</param>
        /// <param name="classTable">Imported classes.</param>
        /// <param name="errorList">List of errors found.</param>
        /// <returns>True if imports are valid.</returns>
        public virtual bool CheckClassConsistency(ISealableDictionary <string, ISealableDictionary <string, ILibrary> > libraryTable, ISealableDictionary <string, ISealableDictionary <string, IClass> > classTable, IErrorList errorList)
        {
            bool Success = true;

            // Process all import clauses separately.
            foreach (IImport ImportItem in ImportList)
            {
                if (!ImportItem.CheckImportConsistency(libraryTable, out ILibrary MatchingLibrary, errorList))
                {
                    Success = false;
                    continue;
                }

                if (ImportedLibraryList.Contains(MatchingLibrary))
                {
                    Success = false;
                    errorList.AddError(new ErrorDuplicateImport((IIdentifier)ImportItem.LibraryIdentifier, MatchingLibrary.ValidLibraryName, MatchingLibrary.ValidSourceName));
                    continue;
                }

                if (!Library.MergeImports(ImportedClassTable, ImportItem, MatchingLibrary, errorList))
                {
                    Success = false;
                    continue;
                }

                ImportedLibraryList.Add(MatchingLibrary);
            }

            // Check import specifications.
            foreach (KeyValuePair <string, IImportedClass> Entry in ImportedClassTable)
            {
                IImportedClass Imported = Entry.Value;
                if (Imported.Item == this)
                {
                    string NewName = Entry.Key;

                    if (NewName != ValidClassName)
                    {
                        Success = false;
                        errorList.AddError(new ErrorNameChanged(Imported.ImportLocation, ValidClassName, NewName));
                    }

                    if (Imported.IsTypeAssigned && Imported.ImportType != BaseNode.ImportType.Latest)
                    {
                        Success = false;
                        errorList.AddError(new ErrorImportTypeConflict(Imported.ImportLocation, ValidClassName));
                    }

                    break;
                }
            }

            // If not referenced by an imported library, a class should be able to reference itself.
            if (!ImportedClassTable.ContainsKey(ValidClassName))
            {
                IImportedClass SelfImport = new ImportedClass(this, BaseNode.ImportType.Latest);
                ImportedClassTable.Add(ValidClassName, SelfImport);

#if COVERAGE
                string ImportString = SelfImport.ToString();
#endif
            }

            foreach (KeyValuePair <string, IImportedClass> Entry in ImportedClassTable)
            {
                IImportedClass Imported = Entry.Value;
                Imported.SetParentSource(this);
            }

            ImportedClassTable.Seal();

            Debug.Assert(Success || !errorList.IsEmpty);
            return(Success);
        }