Пример #1
0
 public function resolve(array $components)
 {
     $this->components = $components;
     // First resolve properties
     $this->resolveAllProperties();
     $resolved = new \SplObjectStorage();
     $unresolved = new \SplObjectStorage();
     foreach ($components['variables'] as $op) {
         if (!empty($op->type) && $op->type->type !== Type::TYPE_UNKNOWN) {
             $resolved[$op] = $op->type;
         } elseif ($op instanceof Operand\BoundVariable && $op->scope === Operand\BoundVariable::SCOPE_OBJECT) {
             $resolved[$op] = $op->type = Type::fromDecl($op->extra->value);
         } elseif ($op instanceof Operand\Literal) {
             $resolved[$op] = $op->type = Type::fromValue($op->value);
         } else {
             $unresolved[$op] = Type::unknown();
         }
     }
     if (count($unresolved) === 0) {
         // short-circuit
         return;
     }
     $round = 1;
     do {
         echo "Round " . $round++ . " (" . count($unresolved) . " unresolved variables out of " . count($components['variables']) . ")\n";
         $start = count($resolved);
         $i = 0;
         $toRemove = [];
         foreach ($unresolved as $k => $var) {
             $i++;
             if ($i % 10 === 0) {
                 echo ".";
             }
             if ($i % 800 === 0) {
                 echo "\n";
             }
             $type = $this->resolveVar($var, $resolved);
             if ($type) {
                 $toRemove[] = $var;
                 $resolved[$var] = $type;
             }
         }
         foreach ($toRemove as $remove) {
             $unresolved->detach($remove);
         }
         echo "\n";
     } while (count($unresolved) > 0 && $start < count($resolved));
     foreach ($resolved as $var) {
         $var->type = $resolved[$var];
     }
     foreach ($unresolved as $var) {
         $var->type = $unresolved[$var];
     }
     echo count($unresolved) . " Variables Left Unresolved\n";
 }