Beispiel #1
0
 public function append_source_with_newlines_increases_line()
 {
     $b = new Buffer();
     $b->append("One\nTwo\nThree");
     $this->assertEquals(3, $b->line);
 }
Beispiel #2
0
 /**
  * Emit method parameters
  *
  * @param   xp.compiler.emit.Buffer b
  * @param   array<string, *>[] parameters
  * @param   string delim
  * @return  xp.compiler.TypeName[] the signature
  */
 protected function emitParameters($b, array $parameters, $delim)
 {
     $signature = [];
     $b->append('(');
     $s = sizeof($parameters) - 1;
     $defer = [];
     $usesGenerics = false;
     $genericParams = '';
     foreach ($parameters as $i => $param) {
         if (isset($param['assign'])) {
             if (null === ($field = $this->resolveType(new TypeName('self'))->getField($param['assign']))) {
                 $this->error('F404', 'Method assignment parameter $this.' . $param['assign'] . ' references non-existant field');
                 $t = TypeName::$VAR;
             } else {
                 $t = $field->type;
             }
             $ptr = $this->resolveType($t);
             $param['name'] = $param['assign'];
             $defer[] = '$this->' . $param['assign'] . '= $' . $param['assign'] . ';';
         } else {
             if (!$param['type']) {
                 $t = TypeName::$VAR;
                 $ptr = new TypeReference($t);
             } else {
                 if (!$usesGenerics && $this->scope[0]->declarations[0]->name->isPlaceHolder($param['type'])) {
                     $usesGenerics = true;
                 }
                 $t = $param['type'];
                 $ptr = $this->resolveType($t);
                 if (!isset($param['check']) || !$param['check'] || isset($param['vararg'])) {
                     // No runtime type checks
                 } else {
                     if ($t->isArray() || $t->isMap()) {
                         $b->append('array ');
                     } else {
                         if ($t->isFunction()) {
                             $b->append('callable ');
                         } else {
                             if ($t->isClass() && !$this->scope[0]->declarations[0]->name->isPlaceHolder($t)) {
                                 $b->append($this->literal($ptr))->append(' ');
                             } else {
                                 if ('{' === $delim) {
                                     $defer[] = (new Buffer('', $b->line))->append('if (NULL !== $')->append($param['name'])->append(' && !is("' . $t->name . '", $')->append($param['name'])->append(')) throw new \\lang\\IllegalArgumentException("Argument ')->append($i + 1)->append(' passed to ".__METHOD__." must be of ')->append($t->name)->append(', ".' . $this->core . '::typeOf($')->append($param['name'])->append(')." given");');
                                 } else {
                                     // No checks in interfaces
                                 }
                             }
                         }
                     }
                 }
             }
         }
         $signature[] = new Parameter($param['name'], new TypeName($ptr->name()), isset($param['default']) ? $param['default'] : null);
         $genericParams .= ', ' . $t->compoundName();
         $this->metadata[0][1][$this->method[0]][DETAIL_ARGUMENTS][$i] = $ptr->name();
         if (isset($param['vararg'])) {
             $genericParams .= '...';
             if ($i > 0) {
                 $defer[] = '$' . $param['name'] . '= array_slice(func_get_args(), ' . $i . ');';
             } else {
                 $defer[] = '$' . $param['name'] . '= func_get_args();';
             }
             $this->scope[0]->setType(new VariableNode($param['name']), new TypeName($t->name . '[]'));
             break;
         }
         $b->append('$' . $param['name']);
         if (isset($param['default'])) {
             $b->append('= ');
             $resolveable = false;
             if ($param['default'] instanceof Resolveable) {
                 try {
                     $init = $param['default']->resolve();
                     $b->append(var_export($init, true));
                     $resolveable = true;
                 } catch (\lang\IllegalStateException $e) {
                 }
             }
             if (!$resolveable) {
                 $b->append('NULL');
                 $init = new Buffer('', $b->line);
                 $init->append('if (func_num_args() < ')->append($i + 1)->append(') { ');
                 $init->append('$')->append($param['name'])->append('= ');
                 $this->emitOne($init, $param['default']);
                 $init->append('; }');
                 $defer[] = $init;
             }
         }
         $i < $s && !isset($parameters[$i + 1]['vararg']) && $b->append(',');
         $this->scope[0]->setType(new VariableNode($param['name']), $t);
     }
     $b->append(')');
     $b->append($delim);
     foreach ($defer as $src) {
         $b->append($src);
     }
     if ($usesGenerics) {
         $this->metadata[0][1][$this->method[0]][DETAIL_ANNOTATIONS]['generic']['params'] = substr($genericParams, 2);
     }
     return $signature;
 }