Skip to content
This repository has been archived by the owner on Jul 26, 2021. It is now read-only.

About my proposal to open ptok use with a hook system #12

Closed
llaville opened this issue Jan 26, 2011 · 1 comment
Closed

About my proposal to open ptok use with a hook system #12

llaville opened this issue Jan 26, 2011 · 1 comment

Comments

@llaville
Copy link

I don't know, if either :

  • you don't have time to have a look on my proposal
  • forget the mail
  • other reasons

So I choose now to put it here.
Here are the patch on an old copy of your master branch (to give you an idea)

I've already installed/used it on my version of PHP_CompatInfo 2.0.0RC1 with some changes to have ability to get all features that are still pending in you repository (since v1.0.1)

https://github.com/llaville/php-compat-info

Regards
Laurent Laville

@@ -120,21 +120,87 @@
     /**
      * @var array
      */
     protected $includes;
+
+    /**
+     * @var array
+     */
+    protected $parserElements = array();
+
+    /**
+     * @var array
+     */
+    private $data = array();

     /**
      * Constructor.
      *
      * @param string $sourceCode
+     * @param array  $options    OPTIONAL
      */
-    public function __construct($sourceCode)
+    public function __construct($sourceCode, $options = null)
     {
         if (is_file($sourceCode)) {
             $sourceCode = file_get_contents($sourceCode);
+        }
+
+        if (is_array($options)) {
+            foreach ($options as $elementName => $parser) {
+                if (is_array($parser) && count($parser) == 2) {
+                    $this->connectParserElement(
+                        $elementName, $parser[0], $parser[1]
+                    );
+                }
+            }
         }

         $this->scan($sourceCode);
+    }
+
+    /**
+     * @param string $elementName  Token name element (PHP_Token_STRING for example)
+     * @param mixed  $callback     A PHP callable function
+     * @param string $classElement Class that should implement the token element
+     *
+     * @throws RuntimeException
+     */
+    private function connectParserElement($elementName, $callback, $classElement)
+    {
+        if (!class_exists($elementName, true)) {
+            throw new RuntimeException(
+                "Invalid element name provided. " .
+                "Expected string beginning by 'PHP_Token_'"
+            );
+        }
+
+        if (!is_callable($callback)) {
+            if (is_array($callback)) {
+                if (is_string($callback[0])) {
+                    $cb = implode('::', $callback);
+                } elseif (is_object($callback[0])) {
+                    $cb = get_class($callback[0]) . '::' . (string)$callback[1];
+                } else {
+                    $cb = null;
+                }
+            } else {
+                $cb = $callback;
+            }
+            throw new RuntimeException(
+                "cannot call function $cb"
+            );
+        }
+
+        if (!class_exists($classElement, true)) {
+            throw new RuntimeException(
+                "Unknown class element '" . (string)$classElement .  "'"
+            );
+        }
+
+        $this->parserElements[$elementName] = array(
+            'callback' => $callback,
+            'alias'    => $classElement,
+        );
     }

     /**
      * Scans the source for sequences of characters and converts them into a
@@ -157,8 +223,12 @@
                 $tokenClass = 'PHP_Token_' . substr(token_name($token[0]), 2);
             } else {
                 $text       = $token;
                 $tokenClass = self::$customTokens[$token];
+            }
+
+            if (isset($this->parserElements[$tokenClass])) {
+                $tokenClass = $this->parserElements[$tokenClass]['alias'];
             }

             $this->tokens[] = new $tokenClass($text, $line, $this, $i);
             $lines          = substr_count($text, "\n");
@@ -317,9 +387,15 @@
         $interface        = FALSE;
         $interfaceEndLine = FALSE;

         foreach ($this->tokens as $token) {
-            switch (get_class($token)) {
+            $context = array(
+                'class'     => $class,
+                'interface' => $interface,
+                'token'     => $token
+            );
+            $tokenName = get_class($token);
+            switch ($tokenName) {
                 case 'PHP_Token_HALT_COMPILER': {
                     return;
                 }
                 break;
@@ -385,8 +461,23 @@
                     if ($interfaceEndLine !== FALSE &&
                         $interfaceEndLine == $token->getLine()) {
                         $interface        = FALSE;
                         $interfaceEndLine = FALSE;
+                    }
+                }
+                break;
+
+                default: {
+                    // is there a callback connected to a particular token
+                    foreach ($this->parserElements as $name => $element) {
+                        if ($element['alias'] === $tokenName) {
+                            // proceed
+                            call_user_func_array(
+                                $this->parserElements[$name]['callback'],
+                                array(&$this, $context)
+                            );
+                            break;
+                        }
                     }
                 }
                 break;
             }
@@ -443,35 +534,52 @@
      * @param mixed $offset
      */
     public function offsetExists($offset)
     {
-        return isset($this->tokens[$offset]);
+        if (is_numeric($offset)) {
+            return isset($this->tokens[$offset]);
+        }
+        return isset($this->data[$offset]);
     }

     /**
      * @param  mixed $offset
      * @return mixed
      */
     public function offsetGet($offset)
     {
-        return $this->tokens[$offset];
+        if (is_numeric($offset)) {
+            return $this->tokens[$offset];
+        }
+        if ($this->functions === NULL) {
+            $this->parseClassesFunctions();
+        }
+        return (isset($this->data[$offset]) ? $this->data[$offset] : NULL);
     }

     /**
      * @param mixed $offset
      * @param mixed $value
      */
     public function offsetSet($offset, $value)
     {
-        $this->tokens[$offset] = $value;
+        if (is_numeric($offset)) {
+            $this->tokens[$offset] = $value;
+        } else {
+            $this->data[$offset] = $value;
+        }
     }

     /**
      * @param mixed $offset
      */
     public function offsetUnset($offset)
     {
-        unset($this->tokens[$offset]);
+        if (is_numeric($offset)) {
+            unset($this->tokens[$offset]);
+        } else {
+            unset($this->data[$offset]);
+        }
     }

     /**
      * Seek to an absolute position.
@sebastianbergmann
Copy link
Owner

Not sure what this is about, sorry. Please send a pull request with more detailed information if this is still relevant.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants