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
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
22 #include "charptrless.h"
23 #include "sourcelocation.h"
24 #include "identifier.h"
25 #include "Shapes_Ast_decls.h"
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
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_
;
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.
70 std::stack
< const FileID
* > fileIDs_
;
71 std::stack
< RefCountPtr
< const Ast::NamespacePath
> > namespacePaths_
;
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
);
85 class NamespaceDirectory
;
88 class NamespaceDirectoryEntry
92 const Ast::NamespaceDirectory
* parent_
;
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
111 RefCountPtr
< const Ast::NamespacePath
> namespacePath_
;
112 std::string filesystemPath_
;
114 std::map
< std::string
, NamespaceDirectoryEntry
* > entries_
;
115 std::vector
< NamespaceDirectoryEntry
* > loadOrder_
;
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
);
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_
;
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_
;
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
);
161 bool addDirectory( const std::string
& nsName
, const std::string
& dir
); /* Returns true if dir is a namespace directory. */