/**
  * @return ConcreteMethod
  */
 protected function generateCallMethod()
 {
     $this->typeCheck->generateCallMethod(func_get_args());
     $method = new ConcreteMethod(new Identifier('__call'), AccessModifier::PUBLIC_());
     $method->addParameter(new Parameter(new Identifier('name')));
     $method->addParameter(new Parameter(new Identifier('arguments'), new ArrayTypeHint()));
     return $method;
 }
 /**
  * @return ConcreteMethod
  */
 protected function generateExpectedTypeMethod()
 {
     $this->typeCheck->generateExpectedTypeMethod(func_get_args());
     $expectedTypeIdentifier = new Identifier('expectedType');
     $method = new ConcreteMethod($expectedTypeIdentifier, AccessModifier::PUBLIC_());
     $method->statementBlock()->add(new ReturnStatement(new Member(new Variable(new Identifier('this')), new Constant($expectedTypeIdentifier))));
     return $method;
 }
 /**
  * @return ConcreteMethod
  */
 protected function generateStreamTypeMethod()
 {
     $this->typeCheck->generateStreamTypeMethod(func_get_args());
     $valueIdentifier = new Identifier('value');
     $valueVariable = new Variable($valueIdentifier);
     $metaDataVariable = new Variable(new Identifier('metaData'));
     $metaDataModeSubscript = new Subscript($metaDataVariable, new Literal('mode'));
     $readableVariable = new Variable(new Identifier('readable'));
     $writableVariable = new Variable(new Identifier('writable'));
     $method = new ConcreteMethod(new Identifier('streamType'), AccessModifier::PROTECTED_());
     $method->addParameter(new Parameter($valueIdentifier));
     $streamGetMetaDataCall = new Call(QualifiedIdentifier::fromString('\\stream_get_meta_data'));
     $streamGetMetaDataCall->add($valueVariable);
     $method->statementBlock()->add(new ExpressionStatement(new Assign($metaDataVariable, $streamGetMetaDataCall)));
     $readablePregMatchCall = new Call(QualifiedIdentifier::fromString('\\preg_match'));
     $readablePregMatchCall->add(new Literal('/[r+]/'));
     $readablePregMatchCall->add($metaDataModeSubscript);
     $readableIf = new IfStatement($readablePregMatchCall, new StatementBlock(), new StatementBlock());
     $readableIf->trueBranch()->add(new ExpressionStatement(new Assign($readableVariable, new Literal('true'))));
     $readableIf->falseBranch()->add(new ExpressionStatement(new Assign($readableVariable, new Literal('false'))));
     $method->statementBlock()->add($readableIf);
     $writablePregMatchCall = new Call(QualifiedIdentifier::fromString('\\preg_match'));
     $writablePregMatchCall->add(new Literal('/[waxc+]/'));
     $writablePregMatchCall->add($metaDataModeSubscript);
     $writableIf = new IfStatement($writablePregMatchCall, new StatementBlock(), new StatementBlock());
     $writableIf->trueBranch()->add(new ExpressionStatement(new Assign($writableVariable, new Literal('true'))));
     $writableIf->falseBranch()->add(new ExpressionStatement(new Assign($writableVariable, new Literal('false'))));
     $method->statementBlock()->add($writableIf);
     $sprintfCall = new Call(QualifiedIdentifier::fromString('\\sprintf'));
     $sprintfCall->add(new Literal('stream {readable: %s, writable: %s}'));
     $sprintfCall->add($readableVariable);
     $sprintfCall->add($writableVariable);
     $method->statementBlock()->add(new ReturnStatement($sprintfCall));
     return $method;
 }
Exemple #4
0
 /**
  * @param Configuration               $configuration
  * @param ClassDefinition             $classDefinition
  * @param ClassName                   $facadeClassName
  * @param array<Issue\IssueInterface> &$issues
  */
 protected function analyzeClass(Configuration $configuration, ClassDefinition $classDefinition, ClassName $facadeClassName, array &$issues)
 {
     $this->typeCheck->analyzeClass(func_get_args());
     $expectedfacadeClassName = $classDefinition->classNameResolver()->shorten($facadeClassName);
     $hasConstructorInit = false;
     $propertyName = 'typeCheck';
     $hasNonStaticCalls = false;
     if ($classDefinition->hasMethod('__construct')) {
         $methodDefinition = $classDefinition->method('__construct');
         if ($this->methodHasInit($methodDefinition, $expectedfacadeClassName, $propertyName)) {
             $hasConstructorInit = true;
         } elseif (!$this->methodHasConstructorStaticCall($methodDefinition, $expectedfacadeClassName)) {
             $issues[] = new Issue\ClassIssue\MissingConstructorCall($classDefinition);
         }
     }
     foreach ($classDefinition->methods() as $methodDefinition) {
         switch ($methodDefinition->name()) {
             case '__construct':
             case '__wakeup':
                 break;
             case '__destruct':
             case '__toString':
                 if ($this->methodHasCall($methodDefinition, $propertyName) || $this->methodHasStaticCall($methodDefinition, $expectedfacadeClassName)) {
                     $issues[] = new Issue\MethodIssue\InadmissibleMethodCall($classDefinition, $methodDefinition);
                 }
                 break;
             case 'unserialize':
                 if ($this->classImplementsSerializable($classDefinition)) {
                     break;
                 }
             default:
                 if ($methodDefinition->isAbstract()) {
                     break;
                 }
                 $missingCall = false;
                 if ($methodDefinition->isStatic()) {
                     $missingCall = !$this->methodHasStaticCall($methodDefinition, $expectedfacadeClassName);
                 } else {
                     if ($this->methodHasCall($methodDefinition, $propertyName)) {
                         $hasNonStaticCalls = true;
                     } elseif (!$this->methodHasStaticCall($methodDefinition, $expectedfacadeClassName)) {
                         $missingCall = true;
                     }
                 }
                 if ($missingCall) {
                     $issues[] = new Issue\MethodIssue\MissingMethodCall($classDefinition, $methodDefinition);
                 }
         }
         if (!$methodDefinition->isAbstract()) {
             $methodReflector = $methodDefinition->createReflector();
             $blockComment = $methodReflector->getDocComment();
             if (false === $blockComment) {
                 $documentedParameterList = new ParameterList();
             } else {
                 $documentedParameterList = $this->parameterListParser()->parseBlockComment($classDefinition->className(), $methodDefinition->name(), $blockComment);
             }
             $documentedParameterList = $documentedParameterList->accept($this->createClassNameResolver($classDefinition));
             $this->mergeTool()->clearIssues();
             $this->mergeTool()->merge($configuration, $classDefinition, $methodDefinition, $documentedParameterList, $this->parameterListParser()->parseReflector($methodReflector));
             $issues = array_merge($issues, $this->mergeTool()->issues());
         }
     }
     if ($hasNonStaticCalls && !$hasConstructorInit) {
         array_unshift($issues, new Issue\ClassIssue\MissingConstructorCall($classDefinition));
     }
     if ($hasConstructorInit) {
         if ($classDefinition->hasProperty($propertyName)) {
             $typhoonProperty = $classDefinition->property($propertyName);
             $missingProperty = $typhoonProperty->isStatic() || AccessModifier::PRIVATE_() !== $typhoonProperty->accessModifier();
         } else {
             $missingProperty = true;
         }
         if ($missingProperty) {
             $issues[] = new Issue\ClassIssue\MissingProperty($classDefinition);
         }
     }
 }
 /**
  * @return ConcreteMethod
  */
 protected function generateCallMethod()
 {
     $this->typeCheck->generateCallMethod(func_get_args());
     $nameIdentifier = new Identifier('name');
     $nameVariable = new Variable($nameIdentifier);
     $argumentsIdentifier = new Identifier('arguments');
     $validatorMethodNameVariable = new Variable(new Identifier('validatorMethodName'));
     $thisVariable = new Variable(new Identifier('this'));
     $reflectorMember = new Member($thisVariable, new Constant(new Identifier('reflector')));
     $method = new ConcreteMethod(new Identifier('__call'), AccessModifier::PUBLIC_());
     $method->addParameter(new Parameter($nameIdentifier));
     $method->addParameter(new Parameter($argumentsIdentifier, new ArrayTypeHint()));
     $ltrimCall = new Call(QualifiedIdentifier::fromString('\\ltrim'));
     $ltrimCall->add($nameVariable);
     $ltrimCall->add(new Literal('_'));
     $ucfirstCall = new Call(QualifiedIdentifier::fromString('\\ucfirst'));
     $ucfirstCall->add($ltrimCall);
     $validatorMethodNameSprintfCall = new Call(QualifiedIdentifier::fromString('\\sprintf'));
     $validatorMethodNameSprintfCall->add(new Literal('validate%s'));
     $validatorMethodNameSprintfCall->add($ucfirstCall);
     $method->statementBlock()->add(new ExpressionStatement(new Assign($validatorMethodNameVariable, $validatorMethodNameSprintfCall)));
     $reflectorHasMethodCall = new Call(new Member($reflectorMember, new Constant(new Identifier('hasMethod'))));
     $reflectorHasMethodCall->add($validatorMethodNameVariable);
     $undefinedMethodIf = new IfStatement(new LogicalNot($reflectorHasMethodCall));
     $exceptionMessageSprintfCall = new Call(QualifiedIdentifier::fromString('\\sprintf'));
     $exceptionMessageSprintfCall->add(new Literal('Call to undefined method %s::%s().'));
     $exceptionMessageSprintfCall->add(new Constant(new Identifier('__CLASS__')));
     $exceptionMessageSprintfCall->add($nameVariable);
     $newBadMethodCallExceptionCall = new Call(QualifiedIdentifier::fromString('\\BadMethodCallException'));
     $newBadMethodCallExceptionCall->add($exceptionMessageSprintfCall);
     $undefinedMethodIf->trueBranch()->add(new ThrowStatement(new NewOperator($newBadMethodCallExceptionCall)));
     $method->statementBlock()->add($undefinedMethodIf);
     $getMethodCall = new Call(new Member($reflectorMember, new Constant(new Identifier('getMethod'))));
     $getMethodCall->add($validatorMethodNameVariable);
     $invokeArgsCall = new Call(new Member($getMethodCall, new Constant(new Identifier('invokeArgs'))));
     $invokeArgsCall->add($thisVariable);
     $invokeArgsCall->add(new Variable($argumentsIdentifier));
     $method->statementBlock()->add(new ReturnStatement($invokeArgsCall));
     return $method;
 }
Exemple #6
0
 /**
  * @param RuntimeConfiguration $configuration
  *
  * @return ConcreteMethod
  */
 protected function generateConfigurationMethod(RuntimeConfiguration $configuration)
 {
     $this->typeCheck->generateConfigurationMethod(func_get_args());
     $method = new ConcreteMethod(new Identifier('configuration'), AccessModifier::PROTECTED_(), true);
     $method->statementBlock()->add(new ReturnStatement($this->configurationGenerator()->generate($configuration)));
     return $method;
 }
Exemple #7
0
 /**
  * @param tuple<integer,string,integer> $token
  * @param array<string|array>           &$tokens
  * @param null                          &$accessModifier
  * @param null                          &$isStatic
  * @param null                          &$isAbstract
  * @param null                          &$source
  *
  * @return tuple<integer|string,string,integer|null>
  */
 protected function parseClassMemberModifiers(array $token, array &$tokens, &$accessModifier, &$isStatic, &$isAbstract, &$source)
 {
     $this->typeCheck->parseClassMemberModifiers(func_get_args());
     $isStatic = false;
     $isAbstract = false;
     $source = '';
     while ($token) {
         $token = $this->normalizeToken($token);
         $source .= $token[1];
         if (T_FUNCTION === $token[0] || T_VARIABLE === $token[0]) {
             break;
         } elseif (T_PUBLIC === $token[0] || T_PROTECTED === $token[0] || T_PRIVATE === $token[0]) {
             $accessModifier = AccessModifier::instanceByValue(strtolower($token[1]));
         } elseif (T_STATIC === $token[0]) {
             $isStatic = true;
         } elseif (T_ABSTRACT === $token[0]) {
             $isAbstract = true;
         }
         $token = next($tokens);
     }
     return $token;
 }
 /**
  * @return ConcreteMethod
  */
 protected function generateConstructor()
 {
     $this->typeCheck->generateConstructor(func_get_args());
     $messageIdentifier = new Identifier('message');
     $previousIdentifier = new Identifier('previous');
     $method = new ConcreteMethod(new Identifier('__construct'), AccessModifier::PUBLIC_());
     $method->addParameter(new Parameter($messageIdentifier));
     $previousParameter = new Parameter($previousIdentifier, new ObjectTypeHint(QualifiedIdentifier::fromString('\\Exception')));
     $previousParameter->setDefaultValue(new Literal(null));
     $method->addParameter($previousParameter);
     $parentConstructCall = new Call(new StaticMember(new Constant(new Identifier('parent')), new Constant(new Identifier('__construct'))));
     $parentConstructCall->add(new Variable($messageIdentifier));
     $parentConstructCall->add(new Literal(0));
     $parentConstructCall->add(new Variable($previousIdentifier));
     $method->statementBlock()->add(new ExpressionStatement($parentConstructCall));
     return $method;
 }