/** * @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); } } }
/** * @param RuntimeConfiguration $configuration * @param null &$className * * @return SyntaxTree */ public function generateSyntaxTree(RuntimeConfiguration $configuration, &$className = null) { $this->typeCheck->generateSyntaxTree(func_get_args()); $className = $configuration->validatorNamespace()->joinAtoms('Exception', 'MissingArgumentException'); $classDefinition = new ClassDefinition(new Identifier($className->shortName()->string()), ClassModifier::FINAL_()); $classDefinition->setParentName(QualifiedIdentifier::fromString('UnexpectedInputException')); $classDefinition->add($this->generateConstructor()); $classDefinition->add($this->generateParameterNameMethod()); $classDefinition->add($this->generateIndexMethod()); $classDefinition->add($this->generateExpectedTypeMethod()); $classDefinition->add(new Property(new Identifier('parameterName'), AccessModifier::PRIVATE_())); $classDefinition->add(new Property(new Identifier('index'), AccessModifier::PRIVATE_())); $classDefinition->add(new Property(new Identifier('expectedType'), AccessModifier::PRIVATE_())); $primaryBlock = new PhpBlock(); $primaryBlock->add(new NamespaceStatement(QualifiedIdentifier::fromString($className->parent()->toRelative()->string()))); $primaryBlock->add($classDefinition); $syntaxTree = new SyntaxTree(); $syntaxTree->add($primaryBlock); return $syntaxTree; }
/** * @param RuntimeConfiguration $configuration * @param null &$className * * @return SyntaxTree */ public function generateSyntaxTree(RuntimeConfiguration $configuration, &$className = null) { $this->typeCheck->generateSyntaxTree(func_get_args()); $className = $configuration->validatorNamespace()->joinAtoms('TypeCheck'); $classDefinition = new ClassDefinition(new Identifier($className->shortName()->string()), ClassModifier::ABSTRACT_()); $classDefinition->add($this->generateGetMethod()); $classDefinition->add($this->generateInstallMethod()); $classDefinition->add($this->generateSetRuntimeGenerationMethod()); $classDefinition->add($this->generateRuntimeGenerationMethod()); $classDefinition->add($this->generateCreateValidatorMethod($configuration)); $classDefinition->add($this->generateDefineValidatorMethod($configuration)); $classDefinition->add($this->generateConfigurationMethod($configuration)); $instancesProperty = new Property(new Identifier('instances'), AccessModifier::PRIVATE_(), true); $instancesProperty->setDefaultValue(new ArrayLiteral()); $classDefinition->add($instancesProperty); $dummyModeProperty = new Property(new Identifier('dummyMode'), AccessModifier::PRIVATE_(), true); $dummyModeProperty->setDefaultValue(new Literal(false)); $classDefinition->add($dummyModeProperty); $runtimeGenerationProperty = new Property(new Identifier('runtimeGeneration'), AccessModifier::PRIVATE_(), true); $runtimeGenerationProperty->setDefaultValue(new Literal(false)); $classDefinition->add($runtimeGenerationProperty); $primaryBlock = new PhpBlock(); $primaryBlock->add(new NamespaceStatement(QualifiedIdentifier::fromString($className->parent()->toRelative()->string()))); $primaryBlock->add($classDefinition); $syntaxTree = new SyntaxTree(); $syntaxTree->add($primaryBlock); return $syntaxTree; }