/** * This method will parse a static default value as it is used for a * parameter, property or constant declaration. * * @return \PDepend\Source\AST\ASTValue * @since 0.9.5 */ protected function parseStaticValue() { $defaultValue = new ASTValue(); $this->consumeComments(); // By default all parameters positive signed $signed = 1; $tokenType = $this->tokenizer->peek(); while ($tokenType !== Tokenizer::T_EOF) { switch ($tokenType) { case Tokens::T_COMMA: case Tokens::T_SEMICOLON: case Tokens::T_PARENTHESIS_CLOSE: if ($defaultValue->isValueAvailable() === true) { return $defaultValue; } throw new MissingValueException($this->tokenizer); case Tokens::T_NULL: $this->consumeToken(Tokens::T_NULL); $defaultValue->setValue(null); break; case Tokens::T_TRUE: $this->consumeToken(Tokens::T_TRUE); $defaultValue->setValue(true); break; case Tokens::T_FALSE: $this->consumeToken(Tokens::T_FALSE); $defaultValue->setValue(false); break; case Tokens::T_LNUMBER: $token = $this->consumeToken(Tokens::T_LNUMBER); $defaultValue->setValue($signed * (int) $token->image); break; case Tokens::T_DNUMBER: $token = $this->consumeToken(Tokens::T_DNUMBER); $defaultValue->setValue($signed * (double) $token->image); break; case Tokens::T_CONSTANT_ENCAPSED_STRING: $token = $this->consumeToken(Tokens::T_CONSTANT_ENCAPSED_STRING); $defaultValue->setValue(substr($token->image, 1, -1)); break; case Tokens::T_DOUBLE_COLON: $this->consumeToken(Tokens::T_DOUBLE_COLON); break; case Tokens::T_CLASS_FQN: $this->consumeToken(Tokens::T_CLASS_FQN); break; case Tokens::T_PLUS: $this->consumeToken(Tokens::T_PLUS); break; case Tokens::T_MINUS: $this->consumeToken(Tokens::T_MINUS); $signed *= -1; break; case Tokens::T_DOUBLE_QUOTE: $defaultValue->setValue($this->parseStringSequence($tokenType)); break; case Tokens::T_DIR: case Tokens::T_FILE: case Tokens::T_LINE: case Tokens::T_SELF: case Tokens::T_NS_C: case Tokens::T_FUNC_C: case Tokens::T_PARENT: case Tokens::T_STRING: case Tokens::T_STATIC: case Tokens::T_CLASS_C: case Tokens::T_METHOD_C: case Tokens::T_BACKSLASH: case Tokens::T_SQUARED_BRACKET_OPEN: case Tokens::T_SQUARED_BRACKET_CLOSE: // There is a default value but we don't handle it at the moment. $defaultValue->setValue(null); $this->consumeToken($tokenType); break; case Tokens::T_START_HEREDOC: $defaultValue->setValue($this->parseHeredoc()->getChild(0)->getImage()); break; default: return $this->parseStaticValueVersionSpecific($defaultValue); } $this->consumeComments(); $tokenType = $this->tokenizer->peek(); } // We should never reach this, so throw an exception throw new TokenStreamEndException($this->tokenizer); }
/** * testSetValueMutatesInternalStateOnlyOnce * * @return void */ public function testSetValueMutatesInternalStateOnlyOnce() { $value = new ASTValue(); $value->setValue(42); $value->setValue(23); $this->assertEquals(42, $value->getValue()); }
private function isBooleanValue(ASTValue $value = null) { return $value && $value->isValueAvailable() && ($value->getValue() === true || $value->getValue() === false); }
/** * Parses additional static values that are valid in the supported php version. * * @param \PDepend\Source\AST\ASTValue $value * @return \PDepend\Source\AST\ASTValue * @throws \PDepend\Source\Parser\UnexpectedTokenException */ protected function parseStaticValueVersionSpecific(ASTValue $value) { $expressions = array(); while (($tokenType = $this->tokenizer->peek()) != Tokenizer::T_EOF) { $expr = null; switch ($tokenType) { case Tokens::T_COMMA: case Tokens::T_CLOSE_TAG: case Tokens::T_COLON: case Tokens::T_DOUBLE_ARROW: case Tokens::T_END_HEREDOC: case Tokens::T_PARENTHESIS_CLOSE: case Tokens::T_SEMICOLON: case Tokens::T_SQUARED_BRACKET_CLOSE: break 2; case Tokens::T_SELF: case Tokens::T_STRING: case Tokens::T_PARENT: case Tokens::T_STATIC: case Tokens::T_DOLLAR: case Tokens::T_VARIABLE: case Tokens::T_BACKSLASH: case Tokens::T_NAMESPACE: $expressions[] = $this->parseVariableOrConstantOrPrimaryPrefix(); break; case $this->isArrayStartDelimiter(): $expressions[] = $this->doParseArray(true); break; case Tokens::T_NULL: case Tokens::T_TRUE: case Tokens::T_FALSE: case Tokens::T_LNUMBER: case Tokens::T_DNUMBER: case Tokens::T_BACKTICK: case Tokens::T_DOUBLE_QUOTE: case Tokens::T_CONSTANT_ENCAPSED_STRING: $expressions[] = $this->parseLiteralOrString(); break; case Tokens::T_QUESTION_MARK: $expressions[] = $this->parseConditionalExpression(); break; case Tokens::T_BOOLEAN_AND: $expressions[] = $this->parseBooleanAndExpression(); break; case Tokens::T_BOOLEAN_OR: $expressions[] = $this->parseBooleanOrExpression(); break; case Tokens::T_LOGICAL_AND: $expressions[] = $this->parseLogicalAndExpression(); break; case Tokens::T_LOGICAL_OR: $expressions[] = $this->parseLogicalOrExpression(); break; case Tokens::T_LOGICAL_XOR: $expressions[] = $this->parseLogicalXorExpression(); break; case Tokens::T_PARENTHESIS_OPEN: $expressions[] = $this->parseParenthesisExpressionOrPrimaryPrefix(); break; case Tokens::T_START_HEREDOC: $expressions[] = $this->parseHeredoc(); break; case Tokens::T_SL: $expressions[] = $this->parseShiftLeftExpression(); break; case Tokens::T_SR: $expressions[] = $this->parseShiftRightExpression(); break; case Tokens::T_STRING_VARNAME: // TODO: Implement this // TODO: Implement this case Tokens::T_PLUS: // TODO: Make this a arithmetic expression // TODO: Make this a arithmetic expression case Tokens::T_MINUS: case Tokens::T_MUL: case Tokens::T_DIV: case Tokens::T_MOD: case Tokens::T_IS_EQUAL: // TODO: Implement compare expressions // TODO: Implement compare expressions case Tokens::T_IS_NOT_EQUAL: case Tokens::T_IS_IDENTICAL: case Tokens::T_IS_NOT_IDENTICAL: case Tokens::T_BITWISE_OR: case Tokens::T_BITWISE_AND: case Tokens::T_BITWISE_NOT: case Tokens::T_BITWISE_XOR: case Tokens::T_IS_GREATER_OR_EQUAL: case Tokens::T_IS_SMALLER_OR_EQUAL: case Tokens::T_ANGLE_BRACKET_OPEN: case Tokens::T_ANGLE_BRACKET_CLOSE: case Tokens::T_EMPTY: case Tokens::T_CONCAT: $token = $this->consumeToken($tokenType); $expr = $this->builder->buildAstExpression($token->image); $expr->configureLinesAndColumns($token->startLine, $token->endLine, $token->startColumn, $token->endColumn); $expressions[] = $expr; break; case Tokens::T_EQUAL: case Tokens::T_OR_EQUAL: case Tokens::T_SL_EQUAL: case Tokens::T_SR_EQUAL: case Tokens::T_AND_EQUAL: case Tokens::T_DIV_EQUAL: case Tokens::T_MOD_EQUAL: case Tokens::T_MUL_EQUAL: case Tokens::T_XOR_EQUAL: case Tokens::T_PLUS_EQUAL: case Tokens::T_MINUS_EQUAL: case Tokens::T_CONCAT_EQUAL: $expressions[] = $this->parseAssignmentExpression(array_pop($expressions)); break; case Tokens::T_DIR: case Tokens::T_FILE: case Tokens::T_LINE: case Tokens::T_NS_C: case Tokens::T_FUNC_C: case Tokens::T_CLASS_C: case Tokens::T_METHOD_C: $expressions[] = $this->parseConstant(); break; // TODO: Handle comments here // TODO: Handle comments here case Tokens::T_COMMENT: case Tokens::T_DOC_COMMENT: $this->consumeToken($tokenType); break; case Tokens::T_AT: case Tokens::T_EXCLAMATION_MARK: $token = $this->consumeToken($tokenType); $expr = $this->builder->buildAstUnaryExpression($token->image); $expr->configureLinesAndColumns($token->startLine, $token->endLine, $token->startColumn, $token->endColumn); $expressions[] = $expr; break; default: throw new UnexpectedTokenException($this->tokenizer->next(), $this->tokenizer->getSourceFile()); } } $expressions = $this->reduce($expressions); $count = count($expressions); if ($count == 0) { return null; } elseif ($count == 1) { // @todo ASTValue must be a valid node. $value->setValue($expressions[0]); return $value; } $expr = $this->builder->buildAstExpression(); foreach ($expressions as $node) { $expr->addChild($node); } $expr->configureLinesAndColumns($expressions[0]->getStartLine(), $expressions[$count - 1]->getEndLine(), $expressions[0]->getStartColumn(), $expressions[$count - 1]->getEndColumn()); // @todo ASTValue must be a valid node. $value->setValue($expr); return $value; }