/** * @param StreamType $type * * @return LogicalAnd|Closure */ public function visitStreamType(StreamType $type) { $this->typeCheck->visitStreamType(func_get_args()); $isResourceCall = new Call(QualifiedIdentifier::fromString('\\is_resource')); $isResourceCall->add($this->valueExpression()); $getResourceTypeCall = new Call(QualifiedIdentifier::fromString('\\get_resource_type')); $getResourceTypeCall->add($this->valueExpression()); $isStreamExpression = new LogicalAnd($isResourceCall, new StrictEquals($getResourceTypeCall, new Literal('stream'))); if (null === $type->readable() && null === $type->writable()) { return $isStreamExpression; } $closure = new Closure(); $closure->addParameter(new Parameter(new Identifier('value'))); $ifStatement = new IfStatement(new LogicalNot($isStreamExpression)); $ifStatement->trueBranch()->add(new ReturnStatement(new Literal(false))); $closure->statementBlock()->add($ifStatement); $streamMetaDataVariable = new Variable(new Identifier('streamMetaData')); $streamModeExpression = new Subscript($streamMetaDataVariable, new Literal('mode')); $streamGetMetaDataCall = new Call(QualifiedIdentifier::fromString('stream_get_meta_data')); $streamGetMetaDataCall->add($this->valueExpression()); $closure->statementBlock()->add(new ExpressionStatement(new Assign($streamMetaDataVariable, $streamGetMetaDataCall))); if (null !== $type->readable()) { $strpbrkCall = new Call(QualifiedIdentifier::fromString('\\strpbrk')); $strpbrkCall->add($streamModeExpression); $strpbrkCall->add(new Literal('r+')); $isReadableExpression = new StrictNotEquals($strpbrkCall, new Literal(false)); if (null === $type->writable()) { if ($type->readable()) { $closure->statementBlock()->add(new ReturnStatement($isReadableExpression)); } else { $closure->statementBlock()->add(new ReturnStatement(new LogicalNot($isReadableExpression))); } } else { if ($type->readable()) { $ifStatement = new IfStatement(new LogicalNot($isReadableExpression)); $ifStatement->trueBranch()->add(new ReturnStatement(new Literal(false))); } else { $ifStatement = new IfStatement($isReadableExpression); $ifStatement->trueBranch()->add(new ReturnStatement(new Literal(false))); } $closure->statementBlock()->add($ifStatement); } } if (null !== $type->writable()) { $strpbrkCall = new Call(QualifiedIdentifier::fromString('\\strpbrk')); $strpbrkCall->add($streamModeExpression); $strpbrkCall->add(new Literal('waxc+')); $isWritableExpression = new StrictNotEquals($strpbrkCall, new Literal(false)); if ($type->writable()) { $closure->statementBlock()->add(new ReturnStatement($isWritableExpression)); } else { $closure->statementBlock()->add(new ReturnStatement(new LogicalNot($isWritableExpression))); } } return $closure; }
/** * Visit a stream type. * * @param StreamType $type The type. * * @return mixed The result of visitation. */ public function visitStreamType(StreamType $type) { $attributes = ''; if (null !== $type->readable()) { if ($type->readable()) { $attributes = 'readable:true'; } else { $attributes = 'readable:false'; } } if (null !== $type->writable()) { if ('' !== $attributes) { $attributes .= ','; } if ($type->writable()) { $attributes .= 'writable:true'; } else { $attributes .= 'writable:false'; } } if ('' !== $attributes) { $attributes = sprintf('{%s}', $attributes); } return 'stream' . $attributes; }