Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate lines produced when a class with a many to many association has subclasses #767

Closed
vahdat-ab opened this Issue Mar 10, 2016 · 8 comments

Comments

Projects
None yet
4 participants
@vahdat-ab
Copy link
Member

commented Mar 10, 2016

what's the reason that Umple generates a code like the following for the method addChild() of the class Analyzer in package cruise.umple.analysis

  public boolean addChild(Analyzer aChild)
  {
    boolean wasAdded = false;
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    if (children.contains(aChild)) { return false; }
    children.add(aChild);
    if (aChild.indexOfParent(this) != -1)
    {
      wasAdded = true;
    }
    else
    {
      wasAdded = aChild.addParent(this);
      if (!wasAdded)
      {
        children.remove(aChild);
      }
    }
    return wasAdded;
  }
@TimLethbridge

This comment has been minimized.

Copy link
Member

commented Mar 11, 2016

This problem is reproducible in the following simple code

class Analyzer
{
0..* parent -- 0..* Analyzer children;
}

class GuardAnalyzer
{
isA Analyzer;
}

class AnotherAnalyser
{
isA Analyzer;
}

One extra line is created for every subclass! In the above case there are three repetitions.

This needs fixing ASAP as it is a dreadful smell. I suspect this was introduced recently.

@TimLethbridge

This comment has been minimized.

Copy link
Member

commented Mar 11, 2016

It would be a good idea to look back at recent versions to find when this started happening. Also it would be good to look at which kinds of associations do this.

@TimLethbridge TimLethbridge changed the title a strange output of code generation Duplicate lines produced when a class with a reflexive association has subclasses Mar 11, 2016

@TimLethbridge

This comment has been minimized.

Copy link
Member

commented Mar 11, 2016

I have verified that this problem dates back well into 2014, so it is not recent.

@TimLethbridge

This comment has been minimized.

Copy link
Member

commented Mar 11, 2016

It first appears in Umple Release 1.20.0.3845 in April 2014. It was not present in December 2013. That should allow searching for changes to the relevant jet files or metamodel changes at that time.

Whoever fixes it should please add tests. it is possible there are bad tests that 'expect' this behaviour.

@TimLethbridge TimLethbridge changed the title Duplicate lines produced when a class with a reflexive association has subclasses Duplicate lines produced when a class with a many to many association has subclasses Mar 11, 2016

@TimLethbridge

This comment has been minimized.

Copy link
Member

commented Mar 11, 2016

It is not just reflexive associations. It seems to be the case with any many to many association. The following also produces the problem.

class X {}

class Analyzer
{
* parent -- * X offspring;
}

class GuardAnalyzer
{
isA Analyzer;
}

class AnotherAnalyser
{
isA Analyzer;
}

@Nava2

This comment has been minimized.

Copy link
Member

commented Mar 11, 2016

git-bisect (link) would probably be helpful if you wanted to really search for it.

@vahdat-ab vahdat-ab assigned vahdat-ab and unassigned vahdat-ab Jun 27, 2016

@TimLethbridge TimLethbridge added the ucosp label Sep 20, 2016

@tlaport4 tlaport4 self-assigned this Sep 23, 2016

@tlaport4

This comment has been minimized.

Copy link
Contributor

commented Sep 24, 2016

The issue was in the prepare(UmpleClass aClass) method in the Generate Class classes. This method would be ran for each class, and there is a code injection part that was executed for each of the classes's associations. When this method was executed for each subclass, it would call it again on the parent of the subclass. So this method would be executed multiple times for the parent class, and this line of code would be added an extra time for each subclass.

I have refactored the method a bit and changed it to only inject this code the first time this call is made on the parent class.

@tlaport4

This comment has been minimized.

Copy link
Contributor

commented Sep 24, 2016

I haven't finished getting the new tests working for this scenario, but will finish it later. I wanted to do a pull request before finishing the code sprint so I just pushed the changes for now.

@vahdat-ab vahdat-ab closed this Oct 13, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.