function convertValueWithRaw(node, type, propertyName) {

	let value;

	if ( node.type === Syntax.Literal ) {

		// 'string' or number or true or false
		return {
			value: node.value,
			raw: node.raw
		};

	} else if ( node.type === Syntax.UnaryExpression
		&& node.prefix
		&& node.argument.type === Syntax.Literal
		&& typeof node.argument.value === 'number'
		&& ( node.operator === '-' || node.operator === '+' )) {

		// -n or +n
		value = node.argument.value;
		return {
			value: node.operator === '-' ? -value : value,
			raw: node.operator + node.argument.raw
		};

	} else if ( node.type === Syntax.MemberExpression && type ) {

		// enum value (a.b.c)
		value = getResolvedObjectName(node);
		if ( value.indexOf(type + ".") === 0 ) {
			// starts with fully qualified enum name -> cut off name
			value = value.slice(type.length + 1);
			return {
				value: value,
				raw: value
			};
//		} else if ( value.indexOf(type.split(".").slice(-1)[0] + ".") === 0 ) {
//			// unqualified name might be a local name (just a guess - would need static code analysis for proper solution)
//			return value.slice(type.split(".").slice(-1)[0].length + 1);
		} else {
			warning(`did not understand default value '${value}'${propertyName ? " of property '" + propertyName + "'" : ""}, falling back to source`);
			let raw = value;
			if ( currentSource && node.range ) {
				raw = currentSource.slice( node.range[0], node.range[1] );
			}
			return {
				value: value,
				raw: raw
			};
		}

	} else if ( node.type === Syntax.Identifier ) {
		if ( node.name === 'undefined') {
			return {
				value: undefined,
				raw: node.name
			};
		}
		const local = currentModule.localNames[node.name];
		if ( typeof local === 'object' && 'value' in local ) {
			// a locally defined constant
			// TODO check type
			return {
				value: local.value,
				raw: local.raw
			};
		}
	} else if ( node.type === Syntax.ArrayExpression ) {

		if ( node.elements.length === 0 ) {
			// empty array literal
			return {
				value: [],
				raw: "[]"
			};
		}

		if ( type && type.slice(-2) === "[]" ) {
			const componentType = type.slice(0,  -2);
			const array = node.elements.map((elem) => convertValueWithRaw(elem, componentType, propertyName));
			return {
				value: array.map((value) => value.value),
				raw: "[" + array.map((value) => value.raw).join(", ") + "]"
			};
		}

	} else if ( node.type === Syntax.ObjectExpression ) {

		if ( node.properties.length === 0 && (type === 'object' || type === 'any') ) {
			return {
				value: {},
				raw: "{}"
			};
		}

	}

	value = "...see text or source";
	warning(`cannot understand default value${
		propertyName ? " of property '" + propertyName + "'" : ""
		} (type='${node.type}', source='${node.toString()}'), falling back to '${value}'`);

	return {
		value: value,
		raw: value
	};
}
/*
 * Analyzes the given AST node that represents a value and returns an object
 * with two properties:
 * - 'value' contains the runtime representation of the value (e.g. a number or a string)
 * - 'raw' contains a source code representation of the value (always string)
 *
 * @param {ASTNode} node Node to analyze
 * @param {string} [type] A type name that might help to analyze the value
 * @param {string} [propertyName] Name of the property for which the anylsis i done, only used for logging
 * @returns {{value:any,raw:string}} An object with a runtime and a source code representation of the value
 */
Analyzes the given AST node that represents a value and returns an object
with two properties:
- 'value' contains the runtime representation of the value
- 'raw' contains a source code representation of the value (always string)

@param {ASTNode} node Node to analyze
@param {string} [type] A type name that might help to analyze the value
@param {string} [propertyName] Name of the property for which the anylsis i done, only used for logging
@returns {{value:any,raw:string}} An object with a runtime and a source code representation of the value
Analyzes the given AST node that represents a value and returns an object with two properties : - ' value ' contains the runtime representation of the value - ' raw ' contains a source code representation of the value ( always string ) @param { ASTNode } node Node to analyze @param { string } [ type ] A type name that might help to analyze the value @param { string } [ propertyName ] Name of the property for which the anylsis i done only used for logging @returns {{ value : any raw : string }} An object with a runtime and a source code representation of the value
function convertValueWithRaw(node, type, propertyName) {
	let value;
	if ( node.type === Syntax.Literal ) {
		return {
			value: node.value,
			raw: node.raw
		};
	} else if ( node.type === Syntax.UnaryExpression
		&& node.prefix
		&& node.argument.type === Syntax.Literal
		&& typeof node.argument.value === 'number'
		&& ( node.operator === '-' || node.operator === '+' )) {
		value = node.argument.value;
		return {
			value: node.operator === '-' ? -value : value,
			raw: node.operator + node.argument.raw
		};
	} else if ( node.type === Syntax.MemberExpression && type ) {
		value = getResolvedObjectName(node);
		if ( value.indexOf(type + ".") === 0 ) {
			value = value.slice(type.length + 1);
			return {
				value: value,
				raw: value
			};
		} else {
			warning(`did not understand default value '${value}'${propertyName ? " of property '" + propertyName + "'" : ""}, falling back to source`);
			let raw = value;
			if ( currentSource && node.range ) {
				raw = currentSource.slice( node.range[0], node.range[1] );
			}
			return {
				value: value,
				raw: raw
			};
		}
	} else if ( node.type === Syntax.Identifier ) {
		if ( node.name === 'undefined') {
			return {
				value: undefined,
				raw: node.name
			};
		}
		const local = currentModule.localNames[node.name];
		if ( typeof local === 'object' && 'value' in local ) {
			return {
				value: local.value,
				raw: local.raw
			};
		}
	} else if ( node.type === Syntax.ArrayExpression ) {
		if ( node.elements.length === 0 ) {
			return {
				value: [],
				raw: "[]"
			};
		}
		if ( type && type.slice(-2) === "[]" ) {
			const componentType = type.slice(0,  -2);
			const array = node.elements.map((elem) => convertValueWithRaw(elem, componentType, propertyName));
			return {
				value: array.map((value) => value.value),
				raw: "[" + array.map((value) => value.raw).join(", ") + "]"
			};
		}
	} else if ( node.type === Syntax.ObjectExpression ) {
		if ( node.properties.length === 0 && (type === 'object' || type === 'any') ) {
			return {
				value: {},
				raw: "{}"
			};
		}
	}
	value = "...see text or source";
	warning(`cannot understand default value${
		propertyName ? " of property '" + propertyName + "'" : ""
		} (type='${node.type}', source='${node.toString()}'), falling back to '${value}'`);
	return {
		value: value,
		raw: value
	};
}
function convertValueWithRaw ( node , type , propertyName ) { let value ; if ( node . type === Syntax . Literal ) { return { value : node . value , raw : node . raw } ; } else if ( node . type === Syntax . UnaryExpression && node . prefix && node . argument . type === Syntax . Literal && typeof node . argument . value === 'number' && ( node . operator === '-' || node . operator === '+' ) ) { value = node . argument . value ; return { value : node . operator === '-' ? - value : value , raw : node . operator + node . argument . raw } ; } else if ( node . type === Syntax . MemberExpression && type ) { value = getResolvedObjectName ( node ) ; if ( value . indexOf ( type + "." ) === 0 ) { value = value . slice ( type . length + 1 ) ; return { value : value , raw : value } ; } else { warning ( ` ${ value } ${ propertyName ? " of property '" + propertyName + "'" : "" } ` ) ; let raw = value ; if ( currentSource && node . range ) { raw = currentSource . slice ( node . range [ 0 ] , node . range [ 1 ] ) ; } return { value : value , raw : raw } ; } } else if ( node . type === Syntax . Identifier ) { if ( node . name === 'undefined' ) { return { value : undefined , raw : node . name } ; } const local = currentModule . localNames [ node . name ] ; if ( typeof local === 'object' && 'value' in local ) { return { value : local . value , raw : local . raw } ; } } else if ( node . type === Syntax . ArrayExpression ) { if ( node . elements . length === 0 ) { return { value : [ ] , raw : "[]" } ; } if ( type && type . slice ( - 2 ) === "[]" ) { const componentType = type . slice ( 0 , - 2 ) ; const array = node . elements . map ( ( elem ) => convertValueWithRaw ( elem , componentType , propertyName ) ) ; return { value : array . map ( ( value ) => value . value ) , raw : "[" + array . map ( ( value ) => value . raw ) . join ( ", " ) + "]" } ; } } else if ( node . type === Syntax . ObjectExpression ) { if ( node . properties . length === 0 && ( type === 'object' || type === 'any' ) ) { return { value : { } , raw : "{}" } ; } } value = "...see text or source" ; warning ( ` ${ propertyName ? " of property '" + propertyName + "'" : "" } ${ node . type } ${ node . toString ( ) } ${ value } ` ) ; return { value : value , raw : value } ; }
Analyzes the given AST node that represents a value and returns an object
 with two properties:
 - 'value' contains the runtime representation of the value (e.g.
Analyzes the given AST node that represents a value and returns an object with two properties : - ' value ' contains the runtime representation of the value ( e . g .
// 'string' or number or true or false // -n or +n // enum value (a.b.c) // starts with fully qualified enum name -> cut off name //		} else if ( value.indexOf(type.split(".").slice(-1)[0] + ".") === 0 ) { //			// unqualified name might be a local name (just a guess - would need static code analysis for proper solution) //			return value.slice(type.split(".").slice(-1)[0].length + 1); // a locally defined constant // TODO check type // empty array literal