1 /*
  2  * 	Copyright (C) 2012-2013 DFKI GmbH
  3  * 	Deutsches Forschungszentrum fuer Kuenstliche Intelligenz
  4  * 	German Research Center for Artificial Intelligence
  5  * 	http://www.dfki.de
  6  * 
  7  * 	Permission is hereby granted, free of charge, to any person obtaining a 
  8  * 	copy of this software and associated documentation files (the 
  9  * 	"Software"), to deal in the Software without restriction, including 
 10  * 	without limitation the rights to use, copy, modify, merge, publish, 
 11  * 	distribute, sublicense, and/or sell copies of the Software, and to 
 12  * 	permit persons to whom the Software is furnished to do so, subject to 
 13  * 	the following conditions:
 14  * 
 15  * 	The above copyright notice and this permission notice shall be included 
 16  * 	in all copies or substantial portions of the Software.
 17  * 
 18  * 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 19  * 	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 20  * 	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
 21  * 	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
 22  * 	CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 23  * 	TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 24  * 	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 25  */
 26 
 27 
 28 /**
 29  * Dependencies:
 30  * 
 31  *  * parser.element (parserModule.js)
 32  *  * OPTIONALLY: ANTLR TokenStream (antlr3-all.js)
 33  *                (if present, the constructor may be able to automatically derive start/end properties from given argument)
 34  * 
 35  * 
 36  * @requires antlr3-all.js as <code>org</code> (see comment above)
 37  * 
 38  */
 39 
 40 define(['parserModule'], 
 41 //this comment is needed by jsdoc2 [copy of comment for: function ParsingResult(...]
 42 /**
 43  * ParsingResult represents an element that was detected during parsing.
 44  * 
 45  * <p>
 46  * The detected element is referenced by the properties <code>start</code> and <code>end</code>
 47  * that refer to the start-index and end-index within the parsed text.
 48  * 
 49  * <p>
 50  * The ParsingResult has a <code>type</code> property which refers to the kind of element
 51  * that was detected (see constants in {@link mmir.parser.element}).
 52  * 
 53  * <p>
 54  * In addition, the ParsingResult may have several properties that depend of its type. In general,
 55  * these properties refer to detected parts of the element (e.g. for a invocation-statement, these
 56  * may refer to its arguments).
 57  * 
 58  * 
 59  * <p>
 60  * Properties for <strong>INCLUDE_SCRIPT</strong> type:
 61  * <ul>
 62  * 	<li><strong>scriptPath</strong>: the path / URL to the resource</li>
 63  * 	<li><strong>scriptPathType</strong>: the type of the <tt>scriptPath</tt>
 64  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
 65  * </ul>
 66  * <p>
 67  * Properties for <strong>INCLUDE_STYLE</strong> type:
 68  * <ul>
 69  * 	<li><strong>stylePath</strong>: </li>
 70  * 	<li><strong>stylePathType</strong>: the type of the <tt>stylePath</tt>
 71  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
 72  * </ul>
 73  * <p>
 74  * Properties for <strong>LOCALIZE</strong> type:
 75  * <ul>
 76  * 	<li><strong>name</strong>: the name/identifier for the localized String</li>
 77  * 	<li><strong>nameType</strong>: the type of the <tt>name</tt>
 78  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
 79  * </ul>
 80  * <p>
 81  * Properties for <strong>YIELD_DECLARATION</strong> type:
 82  * <ul>
 83  * 	<li><strong>name</strong>: the name/identifier for the yield section</li>
 84  * 	<li><strong>nameType</strong>: the type of the <tt>name</tt>
 85  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
 86  * </ul>
 87  * Properties for <strong>BLOCK</strong> type:
 88  * <ul>
 89  * 	<li><strong>scriptContent</strong> {String}: <tt>OPTIONALLY</tt> the script code as a String</li>
 90  * 	<li><strong>scriptEval</strong> {Function}: the compiled script code in form of a function. The 
 91  * 							function takes one argument: the current data-object.</li>
 92  * </ul>
 93  * <p>
 94  * Properties for <strong>STATEMENT</strong> type:
 95  * <ul>
 96  * 	<li><strong>scriptContent</strong> {String}: <tt>OPTIONALLY</tt> the script code as a String</li>
 97  * 	<li><strong>scriptEval</strong> {Function}: the compiled script code in form of a function. The 
 98  * 							function takes one argument: the current data-object.</li>
 99  * </ul>
100  * <p>
101  * Properties for <strong>HELPER</strong> type:
102  * <ul>
103  * 	<li><strong>helper</strong>: the name of the helper function</li>
104  * 	<li><strong>helperType</strong>: the type of the <tt>helper</tt>
105  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
106  * 	<li><strong>argsEval</strong> {Function}: OPTIONALLY compiled getter Function for retrieving the current ARGS 
107  * 			(optional argument) of the helper expression. The function takes one argument: the current data-object.</li>
108  * </ul>
109  * <p>
110  * Properties for <strong>IF</strong> type:
111  * <ul>
112  * 	<li><strong>ifEval</strong> {Function}: the condition statement, that was compiled into a Function. The 
113  * 							function takes one argument: the current data-object.</li>
114  * 	<li><strong>content</strong> {ContentElement}: the HTML / template content that should be render, in case the
115  * 					if-expression evaluates to <code>true</code>.</li>
116  *  <li><strong>elseContent</strong> {@link mmir.parser.ParsingResult}: OPTIONALLY a ParsingResult
117  *  					representing an else-expression, see {@link mmir.parser.element.ELSE}.</li>
118  * </ul>
119  * <p>
120  * Properties for <strong>ELSE</strong> type:
121  * <ul>
122  * 	<li><strong>content</strong> {ContentElement}: the HTML / template content that should be render, in case the
123  * 					if-expression (to which the else-expression belongs) evaluates to <code>false</code>.</li>
124  * </ul>
125  * <p>
126  * Properties for <strong>FOR</strong> type:
127  * <ul>
128  * 	<li><strong>forControlType</strong> {String}: the type of for-loop, either <code>FORITER</code> or <code>FORSTEP</code></li>
129  * 	<li><strong>forInitEval</strong> {Function}: the initialization statement of the for-expression, compiled into
130  * 									a Function. The function takes one argument: the current data-object.</li>
131  * 		
132  * 	<li><code>FORITER</code>: <code>@for(PROP in OBJ){ ... }@</code>
133  * 	 <ul>
134  * 		<li><strong>forIterator</strong> {Object}: an iterator object with functions <code>hasNext() : Boolean</code> and
135  * 					<code>next() : String</code> (which returns the name of the property currently iterated).</li>
136  * 		<li><strong>forPropName</strong> {String}: the variable name for the property which is currently iterated over.</li>
137  * 	 </ul>
138  * 	</li>
139  * 	<li><code>FORSTEP</code>: <code>@for(INIT; CONDITION; INCREMENT){ ... }@</code>
140  * 	 <ul>
141  * 		<li><strong>forConditionEval</strong> {Function}: the condition statement of the for-expression, compiled into
142  * 											a Function. The function takes one argument: the current data-object.</li>
143  * 		<li><strong>forIncrementEval</strong> {Function}: the increment statement of the for-expression, compiled into
144  * 											a Function. The function takes one argument: the current data-object.</li>
145  * 	 </ul>
146  * 	</li>
147  * 	<li><strong>content</strong> {ContentElement}: the HTML / template content that should be rendered
148  * 								 during each iteration of the for-loop.</li>
149  * </ul>
150  * <p>
151  * Properties for <strong>RENDER</strong> type:
152  * <ul>
153  * 	<li><strong>partial</strong>: the name of the partial view</li>
154  * 	<li><strong>partialType</strong>: the type of the <tt>partial</tt>
155  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
156  * 	<li><strong>controller</strong>: the name of the controller, to which the partial view definition belongs</li>
157  * 	<li><strong>controllerType</strong>: the type of the <tt>controller</tt>
158  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
159  * 	<li><strong>argsEval</strong> {Function}: OPTIONALLY compiled getter Function for retrieving the current ARGS 
160  * 								(optional argument) of the render expression. The function takes one argument: the current data-object.</li>
161  * </ul>
162  * <p>
163  * Properties for <strong>ESCAPE_ENTER</strong> type:
164  * <ul>
165  * 	<li><strong>text</strong> {String}: the text that will be rendered (i.e. without the escape-character(s) itself).</li>
166  * </ul>
167  * <p>
168  * Properties for <strong>ESCAPE_EXIT</strong> type:
169  * <ul>
170  * 	<li><strong>text</strong> {String}: the text that will be rendered (i.e. without the escape-character(s) itself).</li>
171  * </ul>
172  * <p>
173  * Properties for <strong>VAR_DECLARATION</strong> type:
174  * <ul>
175  * 	<li><strong>name</strong>: the name for the variable (without the leading <tt>@</tt> of template variables)</li>
176  * 	<li><strong>nameType</strong>: the type of the <tt>name</tt> field: <code>StringLiteral</code></li>
177  * </ul>
178  * 
179  * <p>
180  * 
181  * @param {org.antlr.runtime.CommonTokenStream|org.antlr.runtime.Token} [thetokens] OPTIONAL
182  * 					if <code>org.antlr.runtime.CommonTokenStream</code>:	
183  * 												the TokenStream that corresponds to this parsed element;
184  * 												when provided, the TokenStream is used to set the start- and end-
185  * 												property of the new instance.<br>
186  * 		  			if <code>org.antlr.runtime.Token</code>:
187  * 												if the parameter is a single Token object, then the start- and end-
188  * 												property for the new instance is set by this token object
189  * @class
190  * @name ParsingResult
191  * @memberOf mmir.parser
192  */		
193 function(parser){
194 //set to @ignore in order to avoid doc-duplication in jsdoc3
195 /**
196  * @ignore
197  * 
198  * ParsingResult represents an element that was detected during parsing.
199  * 
200  * <p>
201  * The detected element is referenced by the properties <code>start</code> and <code>end</code>
202  * that refer to the start-index and end-index within the parsed text.
203  * 
204  * <p>
205  * The ParsingResult has a <code>type</code> property which refers to the kind of element
206  * that was detected (see constants in {@link mmir.parser.element}).
207  * 
208  * <p>
209  * In addition, the ParsingResult may have several properties that depend of its type. In general,
210  * these properties refer to detected parts of the element (e.g. for a invocation-statement, these
211  * may refer to its arguments).
212  * 
213  * 
214  * <p>
215  * Properties for <strong>INCLUDE_SCRIPT</strong> type:
216  * <ul>
217  * 	<li><strong>scriptPath</strong>: the path / URL to the resource</li>
218  * 	<li><strong>scriptPathType</strong>: the type of the <tt>scriptPath</tt>
219  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
220  * </ul>
221  * <p>
222  * Properties for <strong>INCLUDE_STYLE</strong> type:
223  * <ul>
224  * 	<li><strong>stylePath</strong>: </li>
225  * 	<li><strong>stylePathType</strong>: the type of the <tt>stylePath</tt>
226  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
227  * </ul>
228  * <p>
229  * Properties for <strong>LOCALIZE</strong> type:
230  * <ul>
231  * 	<li><strong>name</strong>: the name/identifier for the localized String</li>
232  * 	<li><strong>nameType</strong>: the type of the <tt>name</tt>
233  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
234  * </ul>
235  * <p>
236  * Properties for <strong>YIELD_DECLARATION</strong> type:
237  * <ul>
238  * 	<li><strong>name</strong>: the name/identifier for the yield section</li>
239  * 	<li><strong>nameType</strong>: the type of the <tt>name</tt>
240  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
241  * </ul>
242  * Properties for <strong>BLOCK</strong> type:
243  * <ul>
244  * 	<li><strong>scriptContent</strong> {String}: <tt>OPTIONALLY</tt> the script code as a String</li>
245  * 	<li><strong>scriptEval</strong> {Function}: the compiled script code in form of a function. The 
246  * 							function takes one argument: the current data-object.</li>
247  * </ul>
248  * <p>
249  * Properties for <strong>STATEMENT</strong> type:
250  * <ul>
251  * 	<li><strong>scriptContent</strong> {String}: <tt>OPTIONALLY</tt> the script code as a String</li>
252  * 	<li><strong>scriptEval</strong> {Function}: the compiled script code in form of a function. The 
253  * 							function takes one argument: the current data-object.</li>
254  * </ul>
255  * <p>
256  * Properties for <strong>HELPER</strong> type:
257  * <ul>
258  * 	<li><strong>helper</strong>: the name of the helper function</li>
259  * 	<li><strong>helperType</strong>: the type of the <tt>helper</tt>
260  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
261  * 	<li><strong>argsEval</strong> {Function}: OPTIONALLY compiled getter Function for retrieving the current ARGS 
262  * 			(optional argument) of the helper expression. The function takes one argument: the current data-object.</li>
263  * </ul>
264  * <p>
265  * Properties for <strong>IF</strong> type:
266  * <ul>
267  * 	<li><strong>ifEval</strong> {Function}: the condition statement, that was compiled into a Function. The 
268  * 							function takes one argument: the current data-object.</li>
269  * 	<li><strong>content</strong> {ContentElement}: the HTML / template content that should be render, in case the
270  * 					if-expression evaluates to <code>true</code>.</li>
271  *  <li><strong>elseContent</strong> {@link mmir.parser.ParsingResult}: OPTIONALLY a ParsingResult
272  *  					representing an else-expression, see {@link mmir.parser.element.ELSE}.</li>
273  * </ul>
274  * <p>
275  * Properties for <strong>ELSE</strong> type:
276  * <ul>
277  * 	<li><strong>content</strong> {ContentElement}: the HTML / template content that should be render, in case the
278  * 					if-expression (to which the else-expression belongs) evaluates to <code>false</code>.</li>
279  * </ul>
280  * <p>
281  * Properties for <strong>FOR</strong> type:
282  * <ul>
283  * 	<li><strong>forControlType</strong> {String}: the type of for-loop, either <code>FORITER</code> or <code>FORSTEP</code></li>
284  * 	<li><strong>forInitEval</strong> {Function}: the initialization statement of the for-expression, compiled into
285  * 									a Function. The function takes one argument: the current data-object.</li>
286  * 		
287  * 	<li><code>FORITER</code>: <code>@for(PROP in OBJ){ ... }@</code>
288  * 	 <ul>
289  * 		<li><strong>forIterator</strong> {Object}: an iterator object with functions <code>hasNext() : Boolean</code> and
290  * 					<code>next() : String</code> (which returns the name of the property currently iterated).</li>
291  * 		<li><strong>forPropName</strong> {String}: the variable name for the property which is currently iterated over.</li>
292  * 	 </ul>
293  * 	</li>
294  * 	<li><code>FORSTEP</code>: <code>@for(INIT; CONDITION; INCREMENT){ ... }@</code>
295  * 	 <ul>
296  * 		<li><strong>forConditionEval</strong> {Function}: the condition statement of the for-expression, compiled into
297  * 											a Function. The function takes one argument: the current data-object.</li>
298  * 		<li><strong>forIncrementEval</strong> {Function}: the increment statement of the for-expression, compiled into
299  * 											a Function. The function takes one argument: the current data-object.</li>
300  * 	 </ul>
301  * 	</li>
302  * 	<li><strong>content</strong> {ContentElement}: the HTML / template content that should be rendered
303  * 								 during each iteration of the for-loop.</li>
304  * </ul>
305  * <p>
306  * Properties for <strong>RENDER</strong> type:
307  * <ul>
308  * 	<li><strong>partial</strong>: the name of the partial view</li>
309  * 	<li><strong>partialType</strong>: the type of the <tt>partial</tt>
310  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
311  * 	<li><strong>controller</strong>: the name of the controller, to which the partial view definition belongs</li>
312  * 	<li><strong>controllerType</strong>: the type of the <tt>controller</tt>
313  * 		 field: one of <code>StringLiteral</code>, <code>Identifier</code>, <code>IdentifierNameAmpersatStart</code></li>
314  * 	<li><strong>argsEval</strong> {Function}: OPTIONALLY compiled getter Function for retrieving the current ARGS 
315  * 								(optional argument) of the render expression. The function takes one argument: the current data-object.</li>
316  * </ul>
317  * <p>
318  * Properties for <strong>ESCAPE_ENTER</strong> type:
319  * <ul>
320  * 	<li><strong>text</strong> {String}: the text that will be rendered (i.e. without the escape-character(s) itself).</li>
321  * </ul>
322  * <p>
323  * Properties for <strong>ESCAPE_EXIT</strong> type:
324  * <ul>
325  * 	<li><strong>text</strong> {String}: the text that will be rendered (i.e. without the escape-character(s) itself).</li>
326  * </ul>
327  * <p>
328  * Properties for <strong>VAR_DECLARATION</strong> type:
329  * <ul>
330  * 	<li><strong>name</strong>: the name for the variable (without the leading <tt>@</tt> of template variables)</li>
331  * 	<li><strong>nameType</strong>: the type of the <tt>name</tt> field: <code>StringLiteral</code></li>
332  * </ul>
333  * 
334  * <p>
335  * 
336  * @constructs ParsingResult
337  * @param {org.antlr.runtime.CommonTokenStream|org.antlr.runtime.Token} [thetokens] OPTIONAL
338  * 					if <code>org.antlr.runtime.CommonTokenStream</code>:	
339  * 												the TokenStream that corresponds to this parsed element;
340  * 												when provided, the TokenStream is used to set the start- and end-
341  * 												property of the new instance.<br>
342  * 		  			if <code>org.antlr.runtime.Token</code>:
343  * 												if the parameter is a single Token object, then the start- and end-
344  * 												property for the new instance is set by this token object
345  * 
346  */
347 function ParsingResult (thetokens){
348 	var isSet = false;
349 	
350 	//try to extract start-/end-indexes from the argument:
351 	if(thetokens){
352 		
353 		if(typeof org !== 'undefined'){
354 			//NOTE: must invoke getTokens() for initializing size() etc.!
355 			if(thetokens instanceof org.antlr.runtime.CommonTokenStream && thetokens.getTokens() && thetokens.size() > 0){
356 				this.start = thetokens.getTokens()[0].getStartIndex();
357 				this.end = thetokens.getTokens()[thetokens.size()-1].getStopIndex();
358 				
359 				isSet = true;
360 			}
361 			else if(thetokens instanceof org.antlr.runtime.CommonToken || thetokens instanceof org.antlr.runtime.Token){
362 				this.start = thetokens.getStartIndex();
363 				this.end = thetokens.getStopIndex();
364 							
365 				isSet = true;
366 			}
367 		}
368 		
369 		//if not already set, try...
370 		if( isSet === false && typeof thetokens.getToken !== 'undefined' && (typeof thetokens.getToken().getStartIndex !== 'undefined' && typeof thetokens.getToken().getStopIndex !== 'undefined')){
371 			this.start = thetokens.getToken().getStartIndex();
372 			this.end = thetokens.getToken().getStopIndex();
373 						
374 			isSet = true;
375 		}
376 		else if(typeof thetokens.getStartIndex !== 'undefined' && typeof thetokens.getStopIndex !== 'undefined'){
377 			this.start = thetokens.getStartIndex();
378 			this.end = thetokens.getStopIndex();
379 						
380 			isSet = true;
381 		}
382 		else if(isSet === false) {
383 			var type = Object.prototype.toString.call(thetokens);//.match(/^\[object (.*)\]$/)[1];
384 			console.warn('unknown argument type: '+type);//debug
385 		}
386 	}
387 	
388 	if(isSet === false) {
389 		this.start = -1;
390 		this.end   = -1;
391 	}
392 };
393 
394 /**
395  * Set the start position (index) for this parsed element with regard to the TokenStream of the complete input.
396  * 
397  * @function
398  * @param {org.antlr.runtime.CommonTokenStream} thetokens (optional) the TokenStream that corresponds to this parsed element;
399  * 												when provided, the TokenStream is used to set the start-property of this object.
400  * 
401  * @public
402  */
403 ParsingResult.prototype.setStartFrom = function(thetokens){
404 	//NOTE: must invoke getTokens() for initializing size() etc.!
405 	if(thetokens.getTokens() && thetokens.size() > 0){
406 		this.start = thetokens.getTokens()[0].getStartIndex();
407 	} 
408 	else {
409 		this.start = -1;
410 	}
411 };
412 
413 /**
414  * Set the end position (index) for this parsed element with regard to the TokenStream of the complete input.
415  * 
416  * @function
417  * @param {org.antlr.runtime.CommonTokenStream} thetokens (optional) the TokenStream that corresponds to this parsed element;
418  * 												when provided, the TokenStream is used to set the end-property of this object.
419  * 
420  * @public
421  * @alias mmir.parser.ParsingResult
422  */
423 ParsingResult.prototype.setEndFrom = function(thetokens){
424 	//NOTE: must invoke getTokens() for initializing size() etc.!
425 	if(thetokens.getTokens() && thetokens.size() > 0){
426 		this.end = thetokens.getTokens()[thetokens.size()-1].getStopIndex();
427 	} 
428 	else {
429 		this.end = -1;
430 	}
431 };
432 ParsingResult.prototype.getStart = function(){
433 	return this.start;
434 };
435 ParsingResult.prototype.getEnd = function(){
436 	return this.end;
437 };
438 
439 /**
440  * Get the type of this parsed element, i.e. as which type this element was parsed.
441  * 
442  * The type corresponds to one of the type defined in {mmir.parser.element}.
443  * 
444  * @function
445  * @return {mmir.parser.element} the type for this ParsingResult
446  * 
447  * @public
448  */
449 ParsingResult.prototype.getType = function(){
450 	return this.type;
451 };
452 
453 //helper function for converting properties to the correct value.
454 // By default, the ParsingResult only contains "raw" property values.
455 // Which properties are available, depends on the type of the ParsingResult (see templateProcessor.js)
456 ParsingResult.prototype.getValue = function(rawPropertyValue, proptertyType, data){
457 	
458 	if(proptertyType === 'StringLiteral'){
459 		return rawPropertyValue.substring(1, rawPropertyValue.length-1);
460 	}
461 	else if(proptertyType === 'Identifier'){
462 		if(data){
463 			return data['@' + rawPropertyValue];
464 		}
465 		else {
466 			//just return variable name
467 			return rawPropertyValue;
468 		}
469 	}
470 	else if(proptertyType === 'IdentifierNameAmpersatStart'){
471 		if(data){
472 			return data[rawPropertyValue];
473 		}
474 		else {
475 			//just return variable name, but remove leading @:
476 			return rawPropertyValue.substring(1);
477 		}
478 	}
479 	else if(proptertyType === 'OBJECT'){
480 		return rawPropertyValue;//TODO
481 	}
482 	else if(proptertyType === 'DecimalLiteral'){
483 		return parseFloat(rawPropertyValue);
484 	}
485 //	else if(typeof proptertyType === 'undefined'){
486 //		return rawPropertyValue;
487 //	}
488 	else
489 		return rawPropertyValue;
490 };
491 
492 ParsingResult.prototype.hasVarReferences = function(){
493 	return false;//TODO implement this
494 };
495 
496 ParsingResult.prototype.isScriptTag = function(){
497 	if( parser.element.INCLUDE_SCRIPT === this.getType() ){
498 		return true;
499 	}
500 	return false;
501 };
502 
503 ParsingResult.prototype.isStyleTag = function(){
504 	if( parser.element.INCLUDE_STYLE === this.getType() ){
505 		return true;
506 	}
507 	return false;
508 };
509 
510 ParsingResult.prototype.isLocalize = function(){
511 	if( parser.element.LOCALIZE === this.getType() ){
512 		return true;
513 	}
514 	return false;
515 };
516 
517 ParsingResult.prototype.isYield = function(){
518 	if( parser.element.YIELD_DECLARATION === this.getType() ){
519 		return true;
520 	}
521 	return false;
522 };
523 
524 ParsingResult.prototype.isYieldContent = function(){
525 	if( parser.element.YIELD_CONTENT === this.getType() ){
526 		return true;
527 	}
528 	return false;
529 };
530 
531 ParsingResult.prototype.isScriptBlock = function(){
532 	if( parser.element.BLOCK === this.getType() ){
533 		return true;
534 	}
535 	return false;
536 };
537 
538 ParsingResult.prototype.isScriptStatement = function(){
539 	if( parser.element.STATEMENT === this.getType() ){
540 		return true;
541 	}
542 	return false;
543 };
544 
545 ParsingResult.prototype.isHelper = function(){
546 	if( parser.element.HELPER === this.getType() ){
547 		return true;
548 	}
549 	return false;
550 };
551 
552 ParsingResult.prototype.isIf = function(){
553 	if( parser.element.IF === this.getType() ){
554 		return true;
555 	}
556 	return false;
557 };
558 
559 ParsingResult.prototype.hasElse = function(){
560 	if(this.isIf() && typeof this.elseContent != 'undefined'){
561 		return true;
562 	}
563 	return false;
564 };
565 
566 ParsingResult.prototype.isElse = function(){
567 	if( parser.element.ELSE === this.getType() ){
568 		return true;
569 	}
570 	return false;
571 };
572 
573 ParsingResult.prototype.isFor = function(){
574 	if( parser.element.FOR === this.getType() ){
575 		return true;
576 	}
577 	return false;
578 };
579 
580 ParsingResult.prototype.isRender = function(){
581 	if( parser.element.RENDER === this.getType() ){
582 		return true;
583 	}
584 	return false;
585 };
586 
587 ParsingResult.prototype.isEscapeEnter = function(){
588 	if( parser.element.ESCAPE_ENTER === this.getType() ){
589 		return true;
590 	}
591 	return false;
592 };
593 
594 ParsingResult.prototype.isEscapeExit = function(){
595 	if( parser.element.ESCAPE_EXIT === this.getType() ){
596 		return true;
597 	}
598 	return false;
599 };
600 
601 ParsingResult.prototype.isEscape = function(){
602 	return this.isEscapeEnter() || this.isEscapeExit();
603 };
604 
605 /**
606  * WARNING: do use sparingly -- an invocation triggers a list evaluation.
607  * 
608  * @returns {String} a String representation (name) for this ParsingResult's type
609  * 
610  * @see #getType
611  */
612 ParsingResult.prototype.getTypeName = function(){
613 	
614 	if(this.typeName){
615 		return this.typeName;/////////////////// EARLY EXIT //////////////////////////
616 	}
617 	
618 	for(var prop in parser.element){
619 		if(parser.element.hasOwnProperty(prop) && parser.element[prop] === this.getType()){
620 			this.typeName = prop;
621 			return prop;/////////////////// EARLY EXIT //////////////////////////
622 		}
623 	}
624 	
625 	return void(0);
626 };
627 
628 ParsingResult.prototype.hasCallData = function(){
629 	return typeof this.dataPos !== 'undefined';
630 };
631 
632 ParsingResult.prototype.getCallDataStart = function(){
633 	return this.dataPos.start;
634 };
635 
636 ParsingResult.prototype.getCallDataEnd = function(){
637 	return this.dataPos.end;
638 };
639 
640 ParsingResult.prototype.getCallDataType = function(){
641 	return this.dataType;
642 };
643 
644 ParsingResult.prototype.stringify = function(){
645 	
646 	//TODO use constants for lists
647 	
648     //typed properties:
649 	// for each typed properties '<prop>' there is an additional property with name '<prop>Type'
650 	// (both of these properties are Strings themselves)
651 	var typedPropList = [
652 	     'scriptPath',
653 	     'stylePath', 
654 	     'name',
655 	     'helper',
656 	     'partial',
657 	     'controller'
658 	];
659 	
660 	//primitive-type properties:
661 	// write values 'as is' for these properties
662 	var propList = [
663    	     'start',
664 	     'end',
665 	     'type',
666 	     'dataType',
667 	     'text',
668 	     'forControlType',
669 	     'forPropName'
670 	];
671 	
672 	//"stringify-able" object properties:
673 	var strPropList = [
674    	     'content',
675    	     'elseContent'
676    	];
677 	
678 	//function properties:
679 	var funcPropList = [
680    	     'scriptEval',
681    	     'argsEval',
682    	     'ifEval',
683    	     'forInitEval',
684    	     'forIterator',
685    	     'forConditionEval',
686    	     'forIncrementEval'
687    	];
688 	
689 	//default function properties:
690 	// these functions from the prototype may have been overwritten
691 	//  -> if one is overwritten, i.e. not the default implementation, then store that one too
692 	var overwrittenFuncPropList = [
693  	     'getEnd',
694    	     'getStart',
695    	     'getType',
696    	     'getValue',
697    	     'getTypeName',
698    	     'getCallDataStart',
699    	     'getCallDataEnd',
700    	     'getCallDataType'
701    	];
702 	
703 	//function for iterating over the property-list and generating JSON-like entries in the string-buffer
704 	var  appendStringified = parser.appendStringified;
705 
706 	var sb = ['require("storageUtils").restoreObject({ classConstructor: "parsingResult"', ','];
707 
708 	//TODO property dataPos: {start: Number, end: Number}
709 	if(this['dataPos']){
710 		sb.push( 'dataPos:{start:' );
711 		sb.push( this.dataPos.start );
712 		sb.push( ',end:' );
713 		sb.push( this.dataPos.end );
714 		sb.push( '}' );
715 		//NOTE: need to add comma in a separate entry 
716 		//      (-> in order to not break the removal method of last comma, see below)
717 		sb.push( ',' );
718 	}
719 		
720 	
721 	appendStringified(this, typedPropList, sb);
722 	appendStringified(this, typedPropList, sb, 'Type');
723 	appendStringified(this, propList, sb);
724 	//non-primitives with stringify() function:
725 	appendStringified(this, strPropList, sb, null, function stringifyableExtractor(name, value){
726 		return value.stringify();
727 	});
728 	//function definitions
729 	appendStringified(this, funcPropList, sb, null, function functionExtractor(name, value){
730 		return value.toString();
731 	});
732 	//add "overwritten" function definitions
733 	appendStringified(this, overwrittenFuncPropList, sb, null, function nonDefaultFunctionExtractor(name, value){
734 		var instanceImpl = value.toString();
735 		var defaultImpl = ParsingResult.prototype[name].toString();
736 		if(instanceImpl !== defaultImpl){
737 			return instanceImpl;
738 		}
739 		//DEFAULT: return void (will omit this from storage -> use default impl. of the prototype)
740 		return;
741 	});
742 	
743 	//if last element is a comma, remove it
744 	if(sb[sb.length - 1] === ','){
745 		sb.splice( sb.length - 1, 1);
746 	}
747 	
748 	sb.push(' })');
749 	return sb.join('');
750 };
751 
752 parser.ParsingResult = ParsingResult;
753 
754 return parser.ParsingResult;
755 
756 });//END: define(..., function(){