/**
  * Called when compilation fails
  *
  * @param   xp.compiler.io.Source src
  * @param   lang.Throwable reason
  */
 public function compilationFailed(Source $src, \lang\Throwable $reason)
 {
     $this->writer->write('F');
     $this->failed++;
     $this->messages[$src->getURI()] = $reason->compoundMessage();
 }
 /**
  * Returns a file the compiled type should be written to.
  *
  * The file name will be calculated by replacing dots (".") in the 
  * type's fully qualified name by the operating system's directory 
  * separator and by append xp::CLASS_FILE_EXT. For example:
  * <pre>
  *   de.thekid.demo.Value => de/thekid/demo/Value.class.php
  * </pre>
  *
  * This is how this method behaves.
  * <ul>
  *   <li>If an output folder is set on this instance, returns a file
  *       located in the output folder. This can be changed by the 
  *       compiler's "-o" option.
  *   </li>
  *   <li>If a source is given, this method will return a file in the
  *       folder the source file resides in.
  *   </li>
  *   <li>If neither a source nor an output folder is given, the 
  *       current directory is used as a base.
  *    </li>
  * <ul>
  *
  * @param   xp.compiler.emit.EmitterResult r
  * @param   xp.compiler.io.Source source
  * @return  io.File target
  */
 public function getTarget($r, Source $source = null)
 {
     $mapped = strtr($r->type()->name(), '.', DIRECTORY_SEPARATOR);
     if ($this->output) {
         $base = $this->output;
     } else {
         if ($source) {
             $name = str_replace('/', DIRECTORY_SEPARATOR, $source->getURI());
             return new File(str_replace(strstr(basename($name), '.'), $r->extension(), $name));
         } else {
             $base = new Folder('.');
         }
     }
     return new File($base, $mapped . $r->extension());
 }