Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / nikic / php-parser / doc / component / Constant_expression_evaluation.markdown
diff --git a/vendor/nikic/php-parser/doc/component/Constant_expression_evaluation.markdown b/vendor/nikic/php-parser/doc/component/Constant_expression_evaluation.markdown
new file mode 100644 (file)
index 0000000..9ab4f5c
--- /dev/null
@@ -0,0 +1,115 @@
+Constant expression evaluation
+==============================
+
+Initializers for constants, properties, parameters, etc. have limited support for expressions. For
+example:
+
+```php
+<?php
+class Test {
+    const SECONDS_IN_HOUR = 60 * 60;
+    const SECONDS_IN_DAY = 24 * self::SECONDS_IN_HOUR;
+}
+```
+
+PHP-Parser supports evaluation of such constant expressions through the `ConstExprEvaluator` class:
+
+```php
+<?php
+
+use PhpParser\{ConstExprEvaluator, ConstExprEvaluationException};
+
+$evalutator = new ConstExprEvaluator();
+try {
+    $value = $evalutator->evaluateSilently($someExpr);
+} catch (ConstExprEvaluationException $e) {
+    // Either the expression contains unsupported expression types,
+    // or an error occurred during evaluation
+}
+```
+
+Error handling
+--------------
+
+The constant evaluator provides two methods, `evaluateDirectly()` and `evaluateSilently()`, which
+differ in error behavior. `evaluateDirectly()` will evaluate the expression as PHP would, including
+any generated warnings or Errors. `evaluateSilently()` will instead convert warnings and Errors into
+a `ConstExprEvaluationException`. For example:
+
+```php
+<?php
+
+use PhpParser\{ConstExprEvaluator, ConstExprEvaluationException};
+use PhpParser\Node\{Expr, Scalar};
+
+$evaluator = new ConstExprEvaluator();
+
+// 10 / 0
+$expr = new Expr\BinaryOp\Div(new Scalar\LNumber(10), new Scalar\LNumber(0));
+
+var_dump($evaluator->evaluateDirectly($expr)); // float(INF)
+// Warning: Division by zero
+
+try {
+    $evaluator->evaluateSilently($expr);
+} catch (ConstExprEvaluationException $e) {
+    var_dump($e->getPrevious()->getMessage()); // Division by zero
+}
+```
+
+For the purposes of static analysis, you will likely want to use `evaluateSilently()` and leave
+erroring expressions unevaluated.
+
+Unsupported expressions and evaluator fallback
+----------------------------------------------
+
+The constant expression evaluator supports all expression types that are permitted in constant
+expressions, apart from the following:
+
+ * `Scalar\MagicConst\*`
+ * `Expr\ConstFetch` (only null/false/true are handled)
+ * `Expr\ClassConstFetch`
+
+Handling these expression types requires non-local information, such as which global constants are
+defined. By default, the evaluator will throw a `ConstExprEvaluationException` when it encounters
+an unsupported expression type.
+
+It is possible to override this behavior and support resolution for these expression types by
+specifying an evaluation fallback function:
+
+```php
+<?php
+
+use PhpParser\{ConstExprEvaluator, ConstExprEvaluationException};
+use PhpParser\Node\Expr;
+
+$evalutator = new ConstExprEvaluator(function(Expr $expr) {
+    if ($expr instanceof Expr\ConstFetch) {
+        return fetchConstantSomehow($expr);
+    }
+    if ($expr instanceof Expr\ClassConstFetch) {
+        return fetchClassConstantSomehow($expr);
+    }
+    // etc.
+    throw new ConstExprEvaluationException(
+        "Expression of type {$expr->getType()} cannot be evaluated");
+});
+
+try {
+    $evalutator->evaluateSilently($someExpr);
+} catch (ConstExprEvaluationException $e) {
+    // Handle exception
+}
+```
+
+Implementers are advised to ensure that evaluation of indirect constant references cannot lead to
+infinite recursion. For example, the following code could lead to infinite recursion if constant
+lookup is implemented naively.
+
+```php
+<?php
+class Test {
+    const A = self::B;
+    const B = self::A;
+}
+```
\ No newline at end of file