File: Named.h

package info (click to toggle)
storm-lang 0.7.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,028 kB
  • sloc: ansic: 261,471; cpp: 140,432; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (232 lines) | stat: -rw-r--r-- 8,925 bytes parent folder | download
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#pragma once
#include "Core/Array.h"
#include "Thread.h"
#include "NamedFlags.h"
#include "Value.h"
#include "Visibility.h"
#include "Scope.h"
#include "Doc.h"
#include "ReplaceContext.h"
#include "ReplaceTasks.h"

namespace storm {
	STORM_PKG(core.lang);

	class Named;
	class NameSet;
	class SimpleName;
	class SimplePart;

	/**
	 * Interface for objects that can look up names.
	 */
	class NameLookup : public ObjectOn<Compiler> {
		STORM_CLASS;
	public:
		STORM_CTOR NameLookup();
		STORM_CTOR NameLookup(NameLookup *parent);

		// Find a named entity that corresponds to the specified `SimplePart` in this object.
		// Returns `null` if it is not found. The parameter `source` indicates in what context the
		// name lookup is performed, and it is used to determine the visibility of entities.
		virtual MAYBE(Named *) STORM_FN find(SimplePart *part, Scope source);

		// Convenience overloads for `find`.
		MAYBE(Named *) STORM_FN find(Str *name, Array<Value> *params, Scope source);
		MAYBE(Named *) STORM_FN find(Str *name, Value param, Scope source);
		MAYBE(Named *) STORM_FN find(Str *name, Scope source);
		MAYBE(Named *) find(const wchar *name, Array<Value> *params, Scope source);
		MAYBE(Named *) find(const wchar *name, Value param, Scope source);
		MAYBE(Named *) find(const wchar *name, Scope source);

		// Check if this entity has a particular parent, either directly or indirectly. If `parent`
		// is null, then false is always returned.
		Bool STORM_FN hasParent(MAYBE(NameLookup *) parent) const;

		// Get the parent object to this lookup, or `null` if none.
		virtual MAYBE(NameLookup *) STORM_FN parent() const;

		// Parent name lookup. This should be set by the parent. If it is `null`, the default
		// `parent` implementation asserts. Therefore, root objects need to override `parent` in
		// order to return `null`.
		MAYBE(NameLookup *) STORM_FN parentLookup() const { return pLookup; }
		void STORM_ASSIGN parentLookup(MAYBE(NameLookup *) parent);

	protected:
		// Called when `parentLookup` was changed. The parameter indicates whether or not we have
		// been added to a `NameSet` before or not.
		virtual void STORM_FN onNewParent(MAYBE(NameLookup *) parent, Bool addedToNameSet);

		// Set the parent of `other` to `this`. This is done with the intention of making `other`
		// into a child that is kept track of and traversed as appropriately.
		void STORM_FN makeChild(NameLookup *other);

	private:
		// The actual parent lookup.
		MAYBE(NameLookup *) pLookup;
	};

	// Find the first instance of a specific type of thing.
	MAYBE(NameLookup *) STORM_FN findTopmost(NameLookup *at, Type *type) ON(Compiler);


	/**
	 * An extension of NameLookup with a position.
	 *
	 * This is useful to build linked structures for a Scope in order to indicate that we're at a
	 * particular location, which is useful for name lookups etc.
	 */
	class LookupPos : public NameLookup {
		STORM_CLASS;
	public:
		// Create.
		STORM_CTOR LookupPos();
		STORM_CTOR LookupPos(SrcPos pos);
		STORM_CTOR LookupPos(MAYBE(NameLookup *) parent, SrcPos pos);

		// Our location in source code.
		SrcPos pos;
	};


	/**
	 * Denotes a named object in the compiler. Named objects are for example functions, types.
	 */
	class Named : public LookupPos {
		STORM_CLASS;
	public:
		// Create without parameters.
		STORM_CTOR Named(Str *name);
		STORM_CTOR Named(SrcPos pos, Str *name);

		// Create with parameters.
		STORM_CTOR Named(Str *name, Array<Value> *params);
		STORM_CTOR Named(SrcPos pos, Str *name, Array<Value> *params);

		// Our name. Note: may be null for a while during compiler startup.
		Str *name;

		// Our parameters. Note: may be null for a while during compiler startup.
		Array<Value> *params;

		// Visibility. 'null' means 'visible from everywhere'.
		MAYBE(Visibility *) visibility;

		// Documentation (if present).
		MAYBE(NamedDoc *) documentation;

		// Get a 'Doc' object for this entity. Uses 'documentation' if available, otherwise
		// generates a dummy object. This could be a fairly expensive operation, since all
		// documentation is generally *not* held in main memory.
		Doc *STORM_FN findDoc();

		// Check if this named entity is visible from 'source'.
		Bool STORM_FN visibleFrom(Scope source);
		Bool STORM_FN visibleFrom(MAYBE(NameLookup *) source);

		// Flags for this named object.
		NamedFlags flags;

		// Late initialization. Called twice during startup. Once after the system has advanced far
		// enough to use templates, and again when it has advanced far enough to use packages.
		virtual void lateInit();

		// Compute a path to this entity. Utilizes the parent pointers to traverse the name tree.
		// Will assert if not properly added to the name tree.
		SimpleName *STORM_FN path() const;

		// Compute a path to this entity. Ignores the case where some parent was not found, and
		// provides a truncated name in such cases. This is useful for messages, where it is not
		// important that the name can be used to find the same entity again.
		SimpleName *safePath() const;

		// Get a human-readable identifier for this named object. May return an incomplete
		// identifier if the entity is not properly added to the name tree.
		virtual Str *STORM_FN identifier() const;

		// Get a short version of the identifier. Only includes the name at this level with parameters.
		virtual Str *STORM_FN shortIdentifier() const;

		// Better asserts for 'parent'.
		virtual MAYBE(NameLookup *) STORM_FN parent() const;

		// Receive notifications from NameSet objects. (TODO: Move into separate class?)
		virtual void STORM_FN notifyAdded(NameSet *to, Named *added);

		// Receive notifications from NameSet objects. (TODO: Move into semarate class?)
		virtual void STORM_FN notifyRemoved(NameSet *to, Named *removed);

		// Force compilation of this entity (and any sub-objects contained in here).
		virtual void STORM_FN compile();

		// Discard references to source code stored in here. This is used to discard information
		// required to re-compile the entity from source to save memory. Packages and types do this
		// automatically unless instructed otherwise.
		virtual void STORM_FN discardSource();

		// Called when looking for equivalent types during a replacement. Should call 'addEq' for
		// all equivalent types in the supplied context.
		virtual void STORM_FN findEquivalentTypes(Named *old, ReplaceContext *ctx);

		// See if this named entity is able to replace 'old'. If possible, null is returned. If not,
		// a string containing an appropriate error message is returned. If this function does not
		// return an error, it shall be safe to call 'replace' without errors. May also throw an
		// exception to inhibit the system to try other approaches that would be tried if this
		// function were to return an error message.
		virtual MAYBE(Str *) STORM_FN canReplace(Named *old, ReplaceContext *ctx);

		// Make this entity replace 'old'. If 'canReplace' did not return an error, this shall
		// succeed without issues. Override 'doReplace' to customize the behavior of this function.
		// Do not expect 'old' to be in a functional state after having been replaced.
		void STORM_FN replace(Named *old, ReplaceTasks *tasks, ReplaceContext *ctx);

		// Automatic replace: called by the system when entities marked with `namedAllowReplace` are
		// replaced by the system. This does not happen during an operation requested by the system,
		// which is why it is handled differently from regular calls to `replace`. Currently, this
		// is more or less only used when the system silently inserts custom overrides of functions
		// from TObject, when they are replaced with something user-defined. As such, we don't have
		// to make sure that changes are immediate in this case (as is the case with the more
		// advanced replacement mechanisms).
		virtual void STORM_FN automaticReplace(Named *old);

		// String representation.
		virtual void STORM_FN toS(StrBuf *buf) const;

		// Output the visibility to a string buffer.
		void STORM_FN putVisibility(StrBuf *to) const;

	protected:
		// Called by 'replace' after verifying that 'canReplace' did not return an error.
		virtual void STORM_FN doReplace(Named *old, ReplaceTasks *tasks, ReplaceContext *ctx);

		// Keep track of when our parent lookup changes, so that we can discard our source as
		// appropriate.
		virtual void STORM_FN onNewParent(MAYBE(NameLookup *) parent, Bool addedToNameSet);

	private:
		// Find closest named parent.
		MAYBE(Named *) closestNamed() const;
		MAYBE(Named *) safeClosestNamed() const;
	};

	/**
	 * A pair of named items. Used to remember what to update during a reload.
	 */
	class NamedPair {
		STORM_VALUE;
	public:
		STORM_CTOR NamedPair(Named *from, Named *to) {
			this->from = from;
			this->to = to;
		}

		Named *from;
		Named *to;

		// Output.
		inline void STORM_FN toS(StrBuf *to) const {
			*to << from << S(" -> ") << to;
		}
	};

}