Update suitable examples and tests to use blank mode
[shapes.git] / source / namespacedirectory.h
blob3e84fe592a00830aa01cac60c5edf454bca3153c
1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * any later version.
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2015 Henrik Tidefelt
19 #pragma once
21 #include "refcount.h"
22 #include "charptrless.h"
23 #include "sourcelocation.h"
24 #include "identifier.h"
25 #include "Shapes_Ast_decls.h"
27 #include <list>
28 #include <stack>
29 #include <map>
30 #include <set>
31 #include <string>
32 #include <iostream>
34 namespace Shapes
36 namespace Ast /* Not necessarily the ideal home for these classes. */
39 class NamespaceDirectoryEntry;
41 /* Model of a Shapes-Namespace.txt file.
42 * Used during initialization of NamespaceDirectory.
44 class NamespaceDeclarations
46 bool encapsulated_;
47 std::map< std::string, std::set< std::string > > orderGraph_; /* All entries in orderGraph_[x] precede x. */
48 std::set< std::string > preludeSet_;
49 std::set< std::string > ignoreSet_;
51 public:
52 NamespaceDeclarations( );
54 void setEncapsulated( ) { encapsulated_ = true; }
55 void addPrelude( const std::string & entry );
56 void addIgnore( const std::string & entry );
57 void addPrecedes( const std::set< std::string > & x, const std::set< std::string > & y );
59 bool encapsulated( ) const { return encapsulated_; }
60 bool inIgnoreSet( const std::string & name ) const { return ignoreSet_.find( name ) != ignoreSet_.end( ); }
61 bool inPreludeSet( const std::string & name ) const { return preludeSet_.find( name ) != preludeSet_.end( ); }
62 void invalidOrderGraphEntries( const std::map< std::string, NamespaceDirectoryEntry * > & entries, std::set< std::string > * invalidEntries ) const;
63 std::string orderEntries( const std::map< std::string, NamespaceDirectoryEntry * > & entries, std::vector< NamespaceDirectoryEntry * > * loadOrder ) const; /* Returns the name of an entry on a cycle, or the empty string if no cycle exists. */
66 /* The load stack contains files waiting to be loaded.
68 class LoadStack
70 std::stack< const FileID * > fileIDs_;
71 std::stack< RefCountPtr< const Ast::NamespacePath > > namespacePaths_;
73 public:
74 LoadStack( );
75 size_t size( ) const { return fileIDs_.size( ); }
76 bool empty( ) const { return fileIDs_.empty( ); }
78 const FileID * topFileID( ) const { return fileIDs_.top( ); }
79 RefCountPtr< const Ast::NamespacePath > topNamespace( ) const { return namespacePaths_.top( ); }
81 void push( const FileID * fileID, const RefCountPtr< const Ast::NamespacePath > & namespacePath );
82 void pop( );
85 class NamespaceDirectory;
86 class NamespaceFile;
88 class NamespaceDirectoryEntry
90 protected:
91 std::string name_;
92 const Ast::NamespaceDirectory * parent_;
93 bool prelude_;
95 public:
96 NamespaceDirectoryEntry( const std::string & name, const Ast::NamespaceDirectory * parent );
97 virtual ~NamespaceDirectoryEntry( );
98 void setPrelude( ) { prelude_ = true; }
99 bool prelude( ) const { return prelude_; }
100 virtual std::string name( ) const = 0;
101 void schedulePrelude( LoadStack * loadStack );
102 void schedule( LoadStack * loadStack );
103 virtual void schedule_impl( LoadStack * loadStack, bool preludeOnly = false ) = 0;
106 /* Model of a filesystem directory corresponding to a namespace.
108 class NamespaceDirectory : public NamespaceDirectoryEntry
110 bool initialized_;
111 RefCountPtr< const Ast::NamespacePath > namespacePath_;
112 std::string filesystemPath_;
113 bool encapsulated_;
114 std::map< std::string, NamespaceDirectoryEntry * > entries_;
115 std::vector< NamespaceDirectoryEntry * > loadOrder_;
117 public:
118 NamespaceDirectory( const RefCountPtr< const Ast::NamespacePath > & namespacePath, const std::string & filesystemPath, const std::string & name, const Ast::NamespaceDirectory * parent );
119 virtual ~NamespaceDirectory( );
120 RefCountPtr< const Ast::NamespacePath > namespacePath( ) const { return namespacePath_; }
121 void scheduleNamespace( const Ast::NamespacePath & namespacePath, const Ast::NamespacePath::const_iterator & nsBegin, LoadStack * loadStack );
122 const FileID * resolveSingleFile( const Ast::NamespacePath & namespacePath, const Ast::NamespacePath::const_iterator & nsBegin, const std::string & filename, const Ast::SourceLocation & loc );
123 virtual std::string name( ) const;
124 virtual void schedule_impl( LoadStack * loadStack, bool preludeOnly );
126 private:
127 void initialize( );
128 bool addDirectory( const std::string & nsName, const std::string & dir, bool prelude ); /* Returns true if dir is a namespace directory. */
131 class NamespaceFile : public NamespaceDirectoryEntry
133 const FileID * fileID_;
135 public:
136 NamespaceFile( const FileID * fileID, const std::string & name, const Ast::NamespaceDirectory * parent );
137 virtual ~NamespaceFile( );
138 const FileID * fileID() const { return fileID_; }
139 virtual std::string name( ) const;
140 virtual void schedule_impl( LoadStack * loadStack, bool preludeOnly );
143 /* The namespace loader keeps track of all namespace directories on the need path,
144 * and is responsible for listing the files to be loaded as part of the prelude
145 * or that correspond to a namespace.
147 class NamespaceLoader
149 std::map< std::string, NamespaceDirectory * > topEntries_;
151 public:
152 NamespaceLoader( );
153 ~NamespaceLoader( );
154 void registerNeedDirectory( const std::string & dir );
156 void pushPreludeFiles( LoadStack * loadStack );
157 void pushNamespaceFiles( const Ast::NamespacePath & namespacePath, LoadStack * loadStack );
158 const Ast::FileID * resolveSingleFile( const Ast::NamespacePath & namespacePath, const std::string & filename, const Ast::SourceLocation & loc );
160 private:
161 bool addDirectory( const std::string & nsName, const std::string & dir ); /* Returns true if dir is a namespace directory. */