/**
 * Base class for all LARA join points.
 *
 * @class
 */
 
function JoinPoint(astNode) {
	this.astNode = astNode;
}

JoinPoint.prototype.instanceOf = function(joinPointType) {
	return joinPointType === 'joinpoint';
	// return joinPointType === this.joinPointType;
}

/**
 * @return an Iterator with the types of this join point.
 */
JoinPoint.prototype.types = function(joinPointType) {
	return ['joinpoint'].values();
}

JoinPoint.prototype.sameTypeAs = function(joinPoint) {
    if(typeof joinPoint !== typeof this)
        return false;
        
	if(joinPoint.joinPointType !== this.joinPointType)
        return false;
	
	return true;    
}

JoinPoint.prototype.toString = function() {
	return "CommonJp<" + this.joinPointType + ">";
}

_lara_dummy_ = Object.defineProperty(JoinPoint.prototype, 'joinPointType', {
	configurable: true,
	get: function () { return 'joinpoint'; }
});

_lara_dummy_ = Object.defineProperty(JoinPoint.prototype, 'parent', {
	configurable: true,
	get: function () { 
		return LCLJoinPoints.getParent(this);
	}
});

_lara_dummy_ = Object.defineProperty(JoinPoint.prototype, '_children', {
	configurable: true,
	get: function () {
		return LCLJoinPoints.getChildren(this);
	}
});

_lara_dummy_ = Object.defineProperty(JoinPoint.prototype, 'children', {
	configurable: true,
	get: function () {
		return this._children;
	}
});

_lara_dummy_ = Object.defineProperty(JoinPoint.prototype, '_descendants', {
	configurable: true,
	get: function () {
		return LCLJoinPoints.getDescendants(this);	
	}
});

_lara_dummy_ = Object.defineProperty(JoinPoint.prototype, 'descendants', {
	configurable: true,
	get: function () {
		return this._descendants;
	}
});

JoinPoint.prototype._descendantsPrivate = function(accum) {
	    for(child of this.children){
	    	accum.push(child);
			child._descendantsPrivate(accum);
	    }
}

JoinPoint.prototype.descendantsIt = function*() {
	for(child of this.children){
		yield child;
		
		yield *child.descendantsIt();
	}
}


JoinPoint.prototype.ancestor = function(type) {

	var ancestor = this.parent;
	
	while(ancestor!== undefined && !ancestor.instanceOf(type)){
		ancestor=ancestor.parent;
	}

	return ancestor;    
}

_lara_dummy_ = Object.defineProperty(JoinPoint.prototype, 'hasChildren', {
	configurable: true,
	get: function () {
		return this.children && this.children.length > 0; 
	}
});

JoinPoint.prototype.hasAncestor = function(type) {

	var ancestor = this.parent;
	
	while(ancestor!== undefined && !ancestor.instanceOf(type)){
		ancestor=ancestor.parent;
	}
	
	return ancestor===undefined?false:true;    
}

