<commit_before><?php

namespace Webforge\Doctrine\Compiler;

use Webforge\Code\Generator\GClass;
use Webforge\Code\Generator\GProperty;
use Webforge\Code\Generator\GParameter;
use Webforge\Code\Generator\GFunctionBody;
use Webforge\Code\Generator\GMethod;
use stdClass;
use Webforge\Types\PersistentCollectionType;
use Webforge\Types\EntityType;

class AssociationsAPIGenerator {

  protected $entity;
  protected $inflector;

  public function __construct(Inflector $inflector, GeneratedEntity $entity) {
    $this->inflector = $inflector;
    $this->entity = $entity;
  }

  public function generateFor(stdClass $associationsPair, GeneratedProperty $property) {
    if ($this->entity->equals($associationsPair->owning->entity)) {
      $association = $associationsPair->owning;
    } else {
      $association = $associationsPair->inverse;
    }
    
    if ($property->isEntity()) {
      $this->injectIntoSetter($property, $association);
    }
    
    if ($property->isEntityCollection()) {
      $this->generateDoer('add', $property, $association);
      $this->generateDoer('remove', $property, $association);
      $this->generateDoer('has', $property, $association);
    }
  }

  protected function generateDoer($type, GeneratedProperty $property, ModelAssociation $association) {
    $collectionName = $property->getName();

    // writtenPosts => writtenPost
    $paramName = $this->inflector->getItemNameFromCollectionName($collectionName, $property->getDefinition());

    $parameter = new GParameter(
      $paramName,
      new EntityType($association->referencedEntity->getGClass()),
      $property->getDefinition()->nullable ? NULL : GParameter::UNDEFINED
    );

    $updateOtherside = $association->shouldUpdateOtherSide();

    $body = array();
    switch ($type) {
      case 'add':
        $body[] = sprintf('if (!$this->%s->contains($%s)) {', $collectionName, $parameter->getName());
        $body[] = sprintf('  $this->%s->add($%s);', $collectionName, $parameter->getName());
        if ($updateOtherside) {
          $body[] = sprintf('  $%s->%s($this);', $parameter->getName(), $association->referencedProperty->getCollectionDoerName('add'));
        }
        $body[] = '}';
        $body[] = 'return $this;';
        break;

      case 'remove':
        $body[] = sprintf('if ($this->%s->contains($%s)) {', $collectionName, $parameter->getName());
        $body[] = sprintf('  $this->%s->remove($%s);', $collectionName, $parameter->getName());
        if ($updateOtherside) {
          $body[] = sprintf('  $%s->%s($this);', $parameter->getName(), $association->referencedProperty->getCollectionDoerName('remove'));
        }
        $body[] = '}';
        $body[] = 'return $this;';
        break;

      case 'has':
        $body = array(
          sprintf('return $this->%s->contains($%s);', $collectionName, $parameter->getName()),
        );
        break;
    }

    $this->entity->gClass->createMethod(
      $property->getCollectionDoerName($type),
      array(
        $parameter
      ),
      GFunctionBody::create($body),
      GMethod::MODIFIER_PUBLIC
    );
  }

  protected function injectIntoSetter(GeneratedProperty $property, ModelAssociation $association) {
    if ($association->shouldUpdateOtherSide()) {
      $setter = $this->entity->gClass->getMethod($property->getSetterName());

      $code[] = sprintf('$%s->%s($this);', $setter->getParameterByIndex(0)->getName(), $association->referencedProperty->getCollectionDoerName('add'));

      $setter->getBody()->insertBody($code, 1);
    }
  }
}
<commit_msg>change remove into the correct removeElement() in associations -api<commit_after><?php

namespace Webforge\Doctrine\Compiler;

use Webforge\Code\Generator\GClass;
use Webforge\Code\Generator\GProperty;
use Webforge\Code\Generator\GParameter;
use Webforge\Code\Generator\GFunctionBody;
use Webforge\Code\Generator\GMethod;
use stdClass;
use Webforge\Types\PersistentCollectionType;
use Webforge\Types\EntityType;

class AssociationsAPIGenerator {

  protected $entity;
  protected $inflector;

  public function __construct(Inflector $inflector, GeneratedEntity $entity) {
    $this->inflector = $inflector;
    $this->entity = $entity;
  }

  public function generateFor(stdClass $associationsPair, GeneratedProperty $property) {
    if ($this->entity->equals($associationsPair->owning->entity)) {
      $association = $associationsPair->owning;
    } else {
      $association = $associationsPair->inverse;
    }
    
    if ($property->isEntity()) {
      $this->injectIntoSetter($property, $association);
    }
    
    if ($property->isEntityCollection()) {
      $this->generateDoer('add', $property, $association);
      $this->generateDoer('remove', $property, $association);
      $this->generateDoer('has', $property, $association);
    }
  }

  protected function generateDoer($type, GeneratedProperty $property, ModelAssociation $association) {
    $collectionName = $property->getName();

    // writtenPosts => writtenPost
    $paramName = $this->inflector->getItemNameFromCollectionName($collectionName, $property->getDefinition());

    $parameter = new GParameter(
      $paramName,
      new EntityType($association->referencedEntity->getGClass()),
      $property->getDefinition()->nullable ? NULL : GParameter::UNDEFINED
    );

    $updateOtherside = $association->shouldUpdateOtherSide();

    $body = array();
    switch ($type) {
      case 'add':
        $body[] = sprintf('if (!$this->%s->contains($%s)) {', $collectionName, $parameter->getName());
        $body[] = sprintf('  $this->%s->add($%s);', $collectionName, $parameter->getName());
        if ($updateOtherside) {
          $body[] = sprintf('  $%s->%s($this);', $parameter->getName(), $association->referencedProperty->getCollectionDoerName('add'));
        }
        $body[] = '}';
        $body[] = 'return $this;';
        break;

      case 'remove':
        $body[] = sprintf('if ($this->%s->contains($%s)) {', $collectionName, $parameter->getName());
        $body[] = sprintf('  $this->%s->removeElement($%s);', $collectionName, $parameter->getName());
        if ($updateOtherside) {
          $body[] = sprintf('  $%s->%s($this);', $parameter->getName(), $association->referencedProperty->getCollectionDoerName('remove'));
        }
        $body[] = '}';
        $body[] = 'return $this;';
        break;

      case 'has':
        $body = array(
          sprintf('return $this->%s->contains($%s);', $collectionName, $parameter->getName()),
        );
        break;
    }

    $this->entity->gClass->createMethod(
      $property->getCollectionDoerName($type),
      array(
        $parameter
      ),
      GFunctionBody::create($body),
      GMethod::MODIFIER_PUBLIC
    );
  }

  protected function injectIntoSetter(GeneratedProperty $property, ModelAssociation $association) {
    if ($association->shouldUpdateOtherSide()) {
      $setter = $this->entity->gClass->getMethod($property->getSetterName());

      $code[] = sprintf('$%s->%s($this);', $setter->getParameterByIndex(0)->getName(), $association->referencedProperty->getCollectionDoerName('add'));

      $setter->getBody()->insertBody($code, 1);
    }
  }
}

{'fraction_non_alphanumeric': 0.1748154339044435, 'fraction_numerical': 0.0005571806658308956, 'mean_word_length': 3.7612732095490715, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 129, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2650585', 'n_tokens_mistral': 2157, 'n_tokens_neox': 2116, 'n_words': 350}