1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
#pragma once
#include "NameSet.h"
#include "Core/Io/Url.h"
#include "Core/PODArray.h"
namespace storm {
STORM_PKG(core.lang);
class PkgReader;
class PkgFiles;
/**
* Defines the contents of a package. A package is a NameSet associated with a path, which
* allows it to load things from there.
*/
class Package : public NameSet {
STORM_CLASS;
public:
// Create a virtual package, ie. a package that is not present on disk. These packages must
// be eagerly loaded by 'add'ing things to them.
STORM_CTOR Package(Str *name);
// Create a package located in 'path'.
STORM_CTOR Package(Url *path);
// Create a package located in 'path' with the given name.
STORM_CTOR Package(Str *name, Url *path);
// Get parent.
virtual MAYBE(NameLookup *) STORM_FN parent() const;
// Get an `Url` that represents the location where this package loads code from. If the
// package is virtual, returns `null`.
virtual MAYBE(Url *) STORM_FN url() const;
// Set url. Only done by Engine during startup and is therefore not exposed to storm.
void setUrl(Url *to);
// Check for exact matches.
virtual MAYBE(Named *) STORM_FN has(Named *item) const;
// Add elements and templates.
virtual void STORM_FN add(Named *item);
virtual void STORM_FN add(Template *item);
// Remove items and templates.
virtual Bool STORM_FN remove(Named *item);
virtual Bool STORM_FN remove(Template *item);
// Find an element, take exported packages into account when looking up names.
virtual MAYBE(Named *) STORM_FN find(SimplePart *part, Scope source);
using NameSet::find;
// Get iterators to the begin and end of the contents.
virtual NameSet::Iter STORM_FN begin() const;
virtual NameSet::Iter STORM_FN end() const;
// Lazy-loading.
virtual Bool STORM_FN loadName(SimplePart *part);
virtual Bool STORM_FN loadAll();
// Add an exported package.
// This is most useful when creating virtual packages. Non-virtual packages read this
// information automatically as necessary.
void STORM_FN STORM_NAME(addExport, export)(Package *pkg);
// Get all exports for this package.
Array<Package *> *STORM_FN exports();
// Get all exports from this package, taking recursive exports into account.
Array<Package *> *STORM_FN recursiveExports();
// Call before the package is loaded to inhibit `discardSource` messages from being called
// after the package is loaded. This is necessary if you are planning to extract source
// listings from function entities in this package, for example. This only applies for this
// particular package, and not child packages.
void STORM_FN retainSource();
// We don't need to propagate the discard source message in general.
virtual void STORM_FN discardSource();
// Output.
virtual void STORM_FN toS(StrBuf *to) const;
// Reload all files in the current package.
void STORM_FN reload();
// Reload a single file. Convenient wrapper over the array version.
void STORM_FN reload(Url *file);
// Reload source code from a subset of source files. 'files' is a list of the files that
// shall be examined, and all of them are assumed to be located in the current package. Any
// files not in 'files' are assumed to be unchanged, and their contents will remain
// untouched. Does not handle removals of source code, use 'reload(Array<Url>, Bool)' for that.
void STORM_FN reload(Array<Url *> *files);
// Reload source code from a subset of source files. 'files' is a list of the files that
// shall be examined, and all of them are assumed to be located in the current package. Any
// files not in 'files' are assumed to be unchanged, and their contents will remain
// untouched. If 'complete' is true, then 'files' are assumed to contain all files (not
// directories) in the current package. Thus, any files not in 'files' are assumed to have
// been removed.
void STORM_FN reload(Array<Url *> *files, Bool complete);
private:
// Our path. Points to null if we're a virtual package.
MAYBE(Url *) pkgPath;
// Exports for this package. Might be null.
Array<Package *> *exported;
// NameSet we're using as a temporary storage for currently loading entities during a load
// or a reload operation. Whenever non-null, new entities are added to this name set instead
// of the package itself, and name queries are resolved against 'loading' if able and then
// against the package. If 'loadingAllowDuplicates' is false, we check for duplicates before
// adding to 'loading'.
MAYBE(NameSet *) loading;
// Allow duplicates when adding entities to 'loading'?
Bool loadingAllowDuplicates;
// Are exported packages loaded?
Bool exportedLoaded;
/**
* Loading of sub-packages.
*/
// Load all files given.
void loadFiles(Array<Url *> *files);
// Create a reader for each element in 'readers'.
Array<PkgReader *> *createReaders(Map<Str *, PkgFiles *> *readers);
// Try to load a sub-package. Returns null on failure.
Package *loadPackage(Str *name);
// Load exports if necessary.
void loadExports();
// Type for keeping track of recursive package lookups. Pre-allocated enough so that we
// won't have to heap allocate too often. Typically, this should not be very large. If it
// would be, then we would need a set instead for performance.
typedef PODArray<Package *, 32> ExportSet;
};
/**
* Documentation for a package.
*
* Looks for a file named README and uses the text in that file as documentation.
*/
class PackageDoc : public NamedDoc {
STORM_CLASS;
public:
// Create.
STORM_CTOR PackageDoc(Package *pkg);
// Generate documentation.
virtual Doc *STORM_FN get();
private:
// Owner.
Package *pkg;
};
// Find a package from a path.
MAYBE(Package *) STORM_FN package(Url *path);
// Get the root package.
Package *STORM_FN rootPkg(EnginePtr e);
}
|