Exemple #1
0
 protected function parseMethodReturnType(ClassMethod $method)
 {
     $return = [];
     $returnTypes = $method->getReturnTypes();
     if ($returnTypes) {
         foreach ($returnTypes as $type) {
             if (isset($type['data-type'])) {
                 $return[] = $type['data-type'] == 'variable' ? 'mixed' : $type['data-type'];
             }
         }
     }
     $returnClassTypes = $method->getReturnClassTypes();
     if ($returnClassTypes) {
         foreach ($returnClassTypes as $key => $returnClassType) {
             if ($this->aliasManager->isAlias($returnClassType)) {
                 $returnClassTypes[$key] = "\\" . $this->aliasManager->getAlias($returnClassType);
             }
         }
         $return = array_merge($return, $returnClassTypes);
     }
     if ($method->hasReturnTypesRaw()) {
         $returnClassTypes = $method->getReturnTypesRaw();
         if (!empty($returnClassTypes['list'])) {
             foreach ($returnClassTypes['list'] as $returnType) {
                 if (empty($returnType['cast']) || !$returnType['collection']) {
                     continue;
                 }
                 $key = $returnType['cast']['value'];
                 $type = $key;
                 if ($this->aliasManager->isAlias($type)) {
                     $type = "\\" . $this->aliasManager->getAlias($type);
                 }
                 $return[$key] = $type . '[]';
             }
         }
     }
     if (!empty($return)) {
         $this->return = [implode('|', $return), ''];
     }
 }
Exemple #2
0
 protected function parseMethodReturnType(ClassMethod $method)
 {
     $return = array();
     $returnTypes = $method->getReturnTypes();
     if ($returnTypes) {
         foreach ($returnTypes as $type) {
             if (isset($type['data-type'])) {
                 $return[] = $type['data-type'] == 'variable' ? 'mixed' : $type['data-type'];
             }
         }
     }
     $returnClassTypes = $method->getReturnClassTypes();
     if ($returnClassTypes) {
         foreach ($returnClassTypes as $key => $returnClassType) {
             if ($this->aliasManager->isAlias($returnClassType)) {
                 $returnClassTypes[$key] = "\\" . $this->aliasManager->getAlias($returnClassType);
             }
         }
         $return = array_merge($return, $returnClassTypes);
     }
     if ($return) {
         $this->return = array(join('|', $return), '');
     }
 }
Exemple #3
0
 /**
  * Pre-compiles a Zephir file. Generates the IR and perform basic validations
  *
  * @param Compiler $compiler
  * @throws ParseException
  * @throws CompilerException
  * @throws Exception
  */
 public function preCompile(Compiler $compiler)
 {
     $ir = $this->genIR($compiler);
     if (!is_array($ir)) {
         throw new Exception("Cannot parse file: " . realpath($this->_filePath));
     }
     if (isset($ir['type']) && $ir['type'] == 'error') {
         throw new ParseException($ir['message'], $ir);
     }
     /**
      * Compilation context stores common objects required by compilation entities
      */
     $compilationContext = new CompilationContext();
     /**
      * Set global compiler in the compilation context
      */
     $compilationContext->compiler = $compiler;
     /**
      * Set global config in the compilation context
      */
     $compilationContext->config = $this->_config;
     /**
      * Set global logger in the compilation context
      */
     $compilationContext->logger = $this->_logger;
     /**
      * Alias manager
      */
     $compilationContext->aliasManager = $this->_aliasManager;
     $compilationContext->backend = $compiler->backend;
     /**
      * Traverse the top level statements looking for the namespace
      */
     $namespace = null;
     foreach ($ir as $topStatement) {
         switch ($topStatement['type']) {
             case 'namespace':
                 if ($namespace !== null) {
                     throw new CompilerException("The namespace must be defined just one time", $topStatement);
                 }
                 $namespace = $topStatement['name'];
                 $this->_namespace = $namespace;
                 if (!preg_match('/^[A-Z]/', $namespace)) {
                     throw new CompilerException("Namespace '" . $namespace . "' must be in camelized-form", $topStatement);
                 }
                 break;
             case 'cblock':
                 $this->_headerCBlocks[] = $topStatement['value'];
                 break;
             case 'function':
                 /* Just do the precompilation of the function */
                 $functionDefinition = new FunctionDefinition($namespace, $topStatement['name'], isset($topStatement['parameters']) ? new ClassMethodParameters($topStatement['parameters']) : null, isset($topStatement['statements']) ? new StatementsBlock($topStatement['statements']) : null, isset($topStatement['return-type']) ? $topStatement['return-type'] : null, $topStatement);
                 $functionDefinition->preCompile($compilationContext);
                 $this->addFunction($compiler, $functionDefinition, $topStatement);
                 break;
         }
     }
     if (!$namespace) {
         throw new CompilerException("A namespace is required", $topStatement);
     }
     /* Set namespace and flag as global, if before namespace declaration */
     foreach ($this->_functionDefinitions as $funcDef) {
         if ($funcDef->getNamespace() == null) {
             $funcDef->setGlobal(true);
             $funcDef->setNamespace($compiler->getConfig()->get('namespace'));
         }
     }
     $class = false;
     $interface = false;
     $lastComment = null;
     foreach ($ir as $topStatement) {
         switch ($topStatement['type']) {
             case 'class':
                 if ($class || $interface) {
                     throw new CompilerException("More than one class/interface defined in the same file", $topStatement);
                 }
                 $class = true;
                 $name = $topStatement['name'];
                 $this->preCompileClass($compilationContext, $namespace, $topStatement, $lastComment);
                 $this->_originalNode = $topStatement;
                 $lastComment = null;
                 break;
             case 'interface':
                 if ($class || $interface) {
                     throw new CompilerException("More than one class/interface defined in the same file", $topStatement);
                 }
                 $interface = true;
                 $name = $topStatement['name'];
                 $this->preCompileInterface($namespace, $topStatement, $lastComment);
                 $this->_originalNode = $topStatement;
                 $lastComment = null;
                 break;
             case 'use':
                 if ($interface || $class) {
                     throw new CompilerException("Aliasing must be done before declaring any class or interface", $topStatement);
                 }
                 $this->_aliasManager->add($topStatement);
                 break;
             case 'comment':
                 $lastComment = $topStatement;
                 break;
         }
     }
     if (!$class && !$interface) {
         throw new CompilerException("Every file must contain at least a class or an interface", $topStatement);
     }
     if (!$this->_external) {
         $expectedPath = strtolower(str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR . $name) . '.zep';
         if (strtolower($this->_filePath) != $expectedPath) {
             $className = str_replace('\\', '/', $namespace) . '\\' . $name;
             $message = 'Unexpected class name ' . $className . ' in file: ' . $this->_filePath . ', expected: ' . $expectedPath;
             throw new CompilerException($message);
         }
     }
     if ($compilationContext->classDefinition) {
         if ($extendsClass = $compilationContext->classDefinition->getExtendsClass()) {
             $compiler->isClass($extendsClass);
         }
         if ($interfaces = $compilationContext->classDefinition->getImplementedInterfaces()) {
             foreach ($interfaces as $interface) {
                 $compiler->isInterface($interface);
             }
         }
     }
     $this->_ir = $ir;
 }