// This file is part of the AspectC++ compiler 'ac++'.
// Copyright (C) 1999-2003  The 'ac++' developers (see aspectc.org)
//                                                                
// This program is free software;  you can redistribute it and/or 
// modify it under the terms of the GNU General Public License as 
// published by the Free Software Foundation; either version 2 of 
// the License, or (at your option) any later version.            
//                                                                
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
// GNU General Public License for more details.                   
//                                                                
// You should have received a copy of the GNU General Public      
// License along with this program; if not, write to the Free     
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
// MA  02111-1307  USA                                            

#include "Condition.h"

void Condition::PrintVisitor::visit(const Condition &obj) {
  if (obj)
    obj.accept(*this);
  else
    out_ << "no condition";
}

void Condition::PrintVisitor::visit(const That &obj) {
  out_ << "that(\"" << obj.name() << "\")";
}

void Condition::PrintVisitor::visit(const Target &obj) {
  out_ << "target(\"" << obj.name() << "\")";
}

void Condition::PrintVisitor::visit(const CFlow &obj) {
  out_ << "cflow[" << obj.index() << "]";
}

void Condition::PrintVisitor::visit(const And &obj) {
  out_ << "(";
  obj.left().accept(*this);
  out_ << " && ";
  obj.right().accept(*this);
  out_ << ")";
}

void Condition::PrintVisitor::visit(const Or &obj) {
  out_ << "(";
  obj.left().accept(*this);
  out_ << " || ";
  obj.right().accept(*this);
  out_ << ")";
}

void Condition::PrintVisitor::visit(const Not &obj) {
  out_ << "!";
  obj.arg().accept(*this);
}

void Condition::PrintVisitor::visit(const NeededShortCircuitArg &obj) {
  out_ << "{" << obj.index_of_needed_sc_arg() << "th argument is needed}";
}

// create a 'that' condition, i.e. the current object is an instance
// of a specific class that matches the argument of 'that'
// Each 'that' condition must have a unique name. It should represent
// the class in which the check takes place and the checked type(s).
void Condition::that (const string &unique_name) {
  _cond = new That (unique_name);
}

// the target object is an instance of a specific class
void Condition::target (const string &unique_name) {
  _cond = new Target (unique_name);
}

void Condition::matches (const ACM_Class &cls_loc) {
  // this is a hack! I assume that the top-level node is a TypeCond.
  if (_cond)
    ((TypeCond*)_cond)->matches (&cls_loc);
}
