/** * Gibt den Namen der EntityRelationMeta zurück * * @return string */ public function getName() { if (isset($this->alias)) { return $this->alias; } else { return $this->gClass->getClassName(); } }
public function createClassMetadata(GClass $gClass) { // da wir gClass mehrmals im Test evalen könnten, erzeugen wir einen unique hash für den classname und übergeben den // der class metadata $className = uniqid($gClass->getClassName()); $gClass->setClassName($className); $gClass->createDocBlock()->addAnnotation(Annotation::createDC('Entity')); $classWriter = new ClassWriter($gClass); $classWriter->setUseStyle('lines'); $classWriter->addImport(new GClass('Doctrine\\ORM\\Mapping'), 'ORM'); // braucht einen AnnotationReader nicht SimpleAnnotationReader $classWriter->write($file = $this->newFile('entity.' . $gClass->getClassName() . '.php')); require $file; $cm = new ClassMetadata($gClass->getFQN()); $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService()); $this->annotationDriver->loadMetadataForClass($gClass->getFQN(), $cm); $file->delete(); return $cm; }
/** * Gibt die Klasse als PHP Code zurück * * die Klasse ist noch nicht mit Namespace vor class notiert! * Eingerückt wird mit 2 whitespaces. * Em Ende befindet sich hinter der schließenden Klammer ein LF */ public function php() { $cr = "\n"; $php = $this->phpDocBlock(0); $ms = array(self::MODIFIER_ABSTRACT => 'abstract', self::MODIFIER_FINAL => 'final'); foreach ($ms as $const => $modifier) { if (($const & $this->modifiers) == $const) { $php .= $modifier . ' '; } } $php .= 'class ' . $this->getClassName() . ' '; /* Extends */ if (isset($this->parentClass)) { if ($this->parentClass->getNamespace() === $this->getNamespace()) { $php .= 'extends ' . $this->parentClass->getClassName() . ' '; // don't prefix namespace } else { $php .= 'extends ' . '\\' . $this->parentClass->getFQN() . ' '; } } /* Interfaces */ if (count($this->getInterfaces()) > 0) { $php .= 'implements '; $that = $this; $php .= A::implode($this->getInterfaces(), ', ', function (GClass $iClass) use($that) { if ($that->getNamespace() === $iClass->getNamespace()) { return $iClass->getClassName(); } else { return '\\' . $iClass->getFQN(); } }); $php .= ' '; } $php .= '{' . $cr; /* Die Funktionen machen immer den Abstand nach oben. Also vor jedem Property und jeder Methode macht dies ein "\n" */ /* Constants */ $php .= A::joinc($this->getConstants(), ' ' . $cr . '%s;' . $cr, function ($constant) { return $constant->php(2); }); /* Properties */ $php .= A::joinc($this->getProperties(), ' ' . $cr . '%s;' . $cr, function ($property) { return $property->php(2); // hier jetzt auch wegen DocBlock einrücken }); /* Methods */ $php .= A::joinc($this->getMethods(), ' ' . $cr . '%s' . $cr, function ($method) { return $method->php(2); // rückt selbst zwischen den Klammern ein, aber wir wollen ja den body z.b. auf 4 haben nicht auf 2 }); $php .= '}'; // kein umbruch hinten, immer abstand nach oben! return $php; }
/** * @return Webforge\Common\System\File */ public function getTestFile() { /* zuerst setzen wir den ns in einen relativen pfad um */ $file = Code::mapClassToFile($this->class->getName(), NULL); /* entfernt das erste und zweite verzeichnis (das erste ist der .)*/ $file->getDirectory()->slice(2); /* wir fügen den rest des relativen Verzeichnisses an das tests-Verzeichnis an */ $dir = clone $this->dir; $dir->append($file->getDirectory()); $file = new File($dir, $this->class->getClassName() . 'Test'); $file->setExtension('.php'); return $file; }
/** * Fügt dem Writer für die aktuelle Klasse einen weiteren Import hinzu * * dies wird bei setClass() jedoch verworfen, also nach setClass aufrufen * wird kein Alias gesetzt wird der Klassename als Alias benutzt (dies entspricht dem Verhalten von PHP) */ public function addImport(GClass $import, $alias = NULL) { $explicit = TRUE; if ($alias === NULL) { $explicit = FALSE; $alias = $import->getClassName(); } if (array_key_exists($alias, $this->foundImports) && !$this->foundImports[$alias]->equals($import)) { throw new Exception(sprintf("Alias: '%s' wurde doppelt requested von: '%s' (%s) und '%s' ", $alias, $import->getFQN(), $explicit ? 'explizit' : 'implizit', $this->foundImports[$alias]->getFQN())); } $this->foundImports[$alias] = $import; return $this; }
/** * @TODO test interfaces und extends! */ public function testClass() { $cr = "\n"; $class = GClass::factory(__NAMESPACE__ . '\\TestClass'); $this->assertInstanceOf('Psc\\Code\\Generate\\GMethod', $class->getMethod('method2')); $this->assertInstanceOf('Psc\\Code\\Generate\\GProperty', $class->getProperty('prop1')); $gClass = new GClass('Psc\\Code\\Generate\\GClass'); $this->assertEquals('GClass', $gClass->getClassName()); $this->assertEquals('\\Psc\\Code\\Generate', $gClass->getNamespace()); $this->assertEquals('Psc\\Code\\Generate\\GClass', $gClass->getFQN()); /* test final + abstract zeuch */ $this->assertFalse($gClass->isFinal()); $this->assertFalse($gClass->isAbstract()); $gClass->setFinal(TRUE); $this->assertTrue($gClass->isFinal()); $gClass->setAbstract(TRUE); $this->assertTrue($gClass->isAbstract()); $gClass->setModifier(GClass::MODIFIER_ABSTRACT, FALSE); $gClass->setModifier(GClass::MODIFIER_FINAL, FALSE); $this->assertFalse($gClass->isAbstract()); $this->assertFalse($gClass->isFinal()); /* testClass (denn da wissen wir die line-nummern besser und die ist auch abstract */ $testClass = new GClass(new ReflectionClass(__NAMESPACE__ . '\\TestClass')); $this->assertTrue($testClass->isAbstract()); $this->assertFalse($testClass->isFinal()); $this->assertEquals(self::$startLine, $testClass->getStartLine()); $this->assertEquals(self::$endLine, $testClass->getEndLine()); $testHint = new GClass('SomeClassForAHint'); $this->assertEquals('class SomeClassForAHint {' . $cr . '}', $testHint->php(), sprintf("output: '%s'", $testHint->php())); //file_put_contents('D:\fixture.txt', self::$testClassCode); //file_put_contents('D:\compiled.txt',$testClass->php()); $this->assertEquals(self::$testClassCode, $testClass->php(), 'Code für Klasse ist nicht identisch'); //identisch bis auf whitespaces! (das ist irgendwie ein bissl variabel, aber okay // geiler wäre halt assertEqualsCode, hmmm das ginge sogar mit token_get_all und so? }
public function inferFile(GClass $class) { if ($class->getNamespace() === $this->module->getEntitiesNamespace()) { $file = $this->module->getEntitiesPath()->getFile($class->getClassName() . '.php'); } else { $file = Code::mapClassToFile($class->getFQN(), $this->module->getProject()->dir('lib')); } return $file; }
public function createEntityBuilder($entityName) { if ($entityName instanceof ClassInterface) { $entityClass = $entityName; } else { $entityClass = new GClass($this->getDefaultNamespace() . '\\' . ltrim($entityName, '\\')); } $this->originalEntityClass = $entityClass; $this->originalEntityName = $entityClass->getClassName(); $compiledEntityClass = clone $entityClass; $compiledEntityClass->setClassName('Compiled' . ucfirst($this->originalEntityName)); $eb = new EntityBuilder($compiledEntityClass, $this->module, $this->classWriter, NULL, $this->getLanguages()); $file = $eb->inferFile($eb->getGClass()); if ($file->exists()) { $file->delete(); } return $eb; }