/**
  * This method may transform the supplied source and return a new replacement for it
  *
  * @param StreamMetaData $metadata Metadata for source
  * @return void
  */
 public function transform(StreamMetaData $metadata)
 {
     $fileName = $metadata->uri;
     if (!$this->isAllowedToTransform($fileName)) {
         return;
     }
     try {
         CleanableMemory::enterProcessing();
         $parsedSource = $this->broker->processString($metadata->source, $fileName, true);
     } catch (FileProcessingException $e) {
         // TODO: collect this exception and make a record in the modified source
         // TODO: Maybe just ask a developer to add this file into exclude list?
         CleanableMemory::leaveProcessing();
         return;
     }
     /** @var $namespaces ParsedFileNamespace[] */
     $namespaces = $parsedSource->getNamespaces();
     $lineOffset = 0;
     foreach ($namespaces as $namespace) {
         /** @var $classes ParsedClass[] */
         $classes = $namespace->getClasses();
         foreach ($classes as $class) {
             $parentClassNames = array_merge($class->getParentClassNameList(), $class->getInterfaceNames(), $class->getTraitNames());
             foreach ($parentClassNames as $parentClassName) {
                 class_exists($parentClassName);
                 // trigger autoloading of class/interface/trait
             }
             // Skip interfaces and aspects
             if ($class->isInterface() || in_array('Go\\Aop\\Aspect', $class->getInterfaceNames())) {
                 continue;
             }
             $this->processSingleClass($metadata, $class, $lineOffset);
         }
         $this->processFunctions($metadata, $namespace);
     }
     CleanableMemory::leaveProcessing();
 }
 /**
  * This method may transform the supplied source and return a new replacement for it
  *
  * @param StreamMetaData $metadata Metadata for source
  * @return void|bool Return false if transformation should be stopped
  */
 public function transform(StreamMetaData $metadata)
 {
     $totalTransformations = 0;
     $fileName = $metadata->uri;
     try {
         CleanableMemory::enterProcessing();
         $parsedSource = $this->broker->processString($metadata->source, $fileName, true);
     } catch (FileProcessingException $e) {
         CleanableMemory::leaveProcessing();
         return false;
     }
     // Check if we have some new aspects that weren't loaded yet
     $unloadedAspects = $this->aspectLoader->getUnloadedAspects();
     if ($unloadedAspects) {
         $this->loadAndRegisterAspects($unloadedAspects);
     }
     $advisors = $this->container->getByTag('advisor');
     /** @var $namespaces ParsedFileNamespace[] */
     $namespaces = $parsedSource->getNamespaces();
     $lineOffset = 0;
     foreach ($namespaces as $namespace) {
         /** @var $classes ParsedClass[] */
         $classes = $namespace->getClasses();
         foreach ($classes as $class) {
             $parentClassNames = array_merge($class->getParentClassNameList(), $class->getInterfaceNames(), $class->getTraitNames());
             foreach ($parentClassNames as $parentClassName) {
                 class_exists($parentClassName);
                 // trigger autoloading of class/interface/trait
             }
             // Skip interfaces and aspects
             if ($class->isInterface() || in_array('Go\\Aop\\Aspect', $class->getInterfaceNames())) {
                 continue;
             }
             $wasClassProcessed = $this->processSingleClass($advisors, $metadata, $class, $lineOffset);
             $totalTransformations += (int) $wasClassProcessed;
         }
         $wasFunctionsProcessed = $this->processFunctions($advisors, $metadata, $namespace);
         $totalTransformations += (int) $wasFunctionsProcessed;
     }
     CleanableMemory::leaveProcessing();
     // If we return false this will indicate no more transformation for following transformers
     return $totalTransformations > 0;
 }