Skip to content

Commit

Permalink
Merge pull request #717 from Shikib/master
Browse files Browse the repository at this point in the history
Issue #686 Fixed
  • Loading branch information
vahdat-ab committed Feb 8, 2016
2 parents 5eb765b + 1105586 commit e8cc020
Show file tree
Hide file tree
Showing 3 changed files with 258 additions and 68 deletions.
115 changes: 83 additions & 32 deletions cruise.umple/src/UmpleInternalParser_CodeClass.ump
Expand Up @@ -27,6 +27,8 @@ class UmpleInternalParser
internal Map<UmpleClassifier,List<Token>> unlinkedExtendsTokensInterface = new HashMap <UmpleClassifier, List<Token>>();
internal Map<UmpleClassifier,List<String>> unlinkedInterfaceExtends = new HashMap<UmpleClassifier,List<String>>();

internal Map<UmpleClassifier,List<Token>> unanalyzedInjectionTokens = new HashMap<UmpleClassifier,List<Token>>();

// List of comments populated by the parser to be added to the next class, attribute, association, method, etc.
internal Comment[] lastComments;

Expand Down Expand Up @@ -373,9 +375,24 @@ class UmpleInternalParser
checkNonReachableStates();
//Issue 610
checkAssociationClassKeys();

//Issue 686
checkCodeInjections();
}
}

//Issue 686
private void checkCodeInjections()
{
for(Map.Entry<UmpleClassifier, List<Token>> entry : unanalyzedInjectionTokens.entrySet())
{
for(Token injectToken : entry.getValue())
{
checkCodeInjectionValidity(injectToken, (UmpleClass) entry.getKey());
}
}
}

public void analyzeInvariants()
{
for(UmpleClassifier uClass:unanalyzedInvariants.keySet())
Expand Down Expand Up @@ -1178,17 +1195,18 @@ class UmpleInternalParser
{
for (AssociationVariable av : unlinkedAssociationVariables)
{

UmpleClass aClass = model.getUmpleClass(av.getType());
UmpleClass bClass = model.getUmpleClass(av.getRelatedAssociation().getType());

if (aClass == null || bClass == null){ //Association is between Class and Interface
continue;
}

Association assoc = bClass.getAssociation(bClass.indexOfAssociationVariable(av));

boolean added = aClass.addAssociationVariable(av.getRelatedAssociation());

if (!added)
{
if ((!aClass.isImmutable() && !av.getRelatedAssociation().getIsNavigable()) || (!bClass.isImmutable() && !av.getIsNavigable()))
Expand Down Expand Up @@ -2556,69 +2574,102 @@ class UmpleInternalParser
return value;
}

//TODO I changed the parameter's type. please remove this comment;
private void analyzeInjectionCode(Token injectToken, UmpleClassifier uClassifier)
private String getOperationName(Token aToken)
{
String type = injectToken.is("beforeCode") ? "before" : "after";
CodeBlock cb = new CodeBlock();
StringBuilder operationName = new StringBuilder();
String comma = "";
for(Token subToken:injectToken.getSubTokens())
for(Token subToken : aToken.getSubTokens())
{
if(subToken.is("operationName"))
{
operationName.append(comma+subToken.getValue());
comma = ",";
}
}
CodeInjection injection = new CodeInjection(type,operationName.toString(),"",uClassifier);
return operationName.toString();
}

//TODO I changed the parameter's type. please remove this comment;
private void analyzeInjectionCode(Token injectToken, UmpleClassifier uClassifier)
{
String type = injectToken.is("beforeCode") ? "before" : "after";
CodeBlock cb = new CodeBlock();
String operationName = getOperationName(injectToken);

CodeInjection injection = new CodeInjection(type,operationName,"",uClassifier);
makeCodeInject(injectToken,injection,cb,uClassifier);
injection.setSnippet(cb);
if (uClassifier instanceof UmpleClass) {
checkCodeInjectionValidity(injectToken, operationName.toString(), uClassifier);
((UmpleClass)uClassifier).addCodeInjection(injection);
((UmpleClass)uClassifier).addCodeInjection(injection);

if(!unanalyzedInjectionTokens.containsKey(uClassifier))
{
unanalyzedInjectionTokens.put(uClassifier, new ArrayList<Token>());
}

List<Token> currentTokens = unanalyzedInjectionTokens.get(uClassifier);
currentTokens.add(injectToken);
} else if (uClassifier instanceof UmpleTrait){
((UmpleTrait)uClassifier).addCodeInjection(injection);
}
}

private boolean checkCodeInjectionValidity(Token injectToken, String operationName, UmpleClassifier uClassifier) {
for(String operation : operationName.split(","))
private boolean checkCodeInjectionValidity(Token injectToken, UmpleClass uClass) {
ArrayList<String> methodNames = new ArrayList<String>();
String operationName = getOperationName(injectToken);

ArrayList<String> todoExtendedClasses = new ArrayList<String>();
ArrayList<String> todoInheritedInterfaces = new ArrayList<String>();

todoExtendedClasses.add(uClass.getName());
while(!todoExtendedClasses.isEmpty())
{
Boolean matches = false;
UmpleClass uClass = (UmpleClass) uClassifier;
String className = todoExtendedClasses.get(0);
todoExtendedClasses.remove(className);

UmpleClass eClass = model.getUmpleClass(className);

ArrayList<String> methodNames = new ArrayList<String>();
for(Method aMethod : uClass.getMethods())
if(eClass == null)
{
methodNames.add(aMethod.getName());
todoInheritedInterfaces.add(className);
continue;
}

for(Attribute attr : uClass.getAttributes())
todoExtendedClasses.remove(className);
if(unlinkedExtends.get(eClass) != null)
{
methodNames.addAll(attr.getMethodNames());
todoExtendedClasses.addAll(unlinkedExtends.get(eClass));
}

for(AssociationVariable av : uClass.getAssociationVariables())
methodNames.addAll(eClass.getMethodNames());
}

while(!todoInheritedInterfaces.isEmpty())
{
String interfaceName = todoInheritedInterfaces.get(0);
todoInheritedInterfaces.remove(interfaceName);

UmpleInterface eInterface = model.getUmpleInterface(interfaceName);

if(eInterface == null)
{
methodNames.addAll(av.getMethodNames());
continue;
}

for(StateMachine sm : uClass.getStateMachines())
if(unlinkedInterfaceExtends.get(eInterface) != null)
{
String stateMachineName = sm.getName().substring(0, 1).toUpperCase() + sm.getName().substring(1);
methodNames.add("set" + stateMachineName);
methodNames.add("get" + stateMachineName);
todoInheritedInterfaces.addAll(unlinkedInterfaceExtends.get(eInterface));
}

for(Event ev : sm.getEvents())
{
methodNames.add(ev.getName());
}
for(Method m : eInterface.getMethods())
{
methodNames.add(m.getName());
}
}

methodNames.add("constructor");
methodNames.add("delete");
methodNames.add("toString");
for(String operation : operationName.split(","))
{
Boolean matches = false;

for(String methodName : methodNames)
{
Expand Down
43 changes: 43 additions & 0 deletions cruise.umple/src/Umple_Code.ump
Expand Up @@ -1178,6 +1178,43 @@ class UmpleClass
return all;
}

public ArrayList<String> getMethodNames()
{
ArrayList<String> methodNames = new ArrayList<String>();
for(Method aMethod : this.getMethods())
{
methodNames.add(aMethod.getName());
}

for(Attribute attr : this.getAttributes())
{
methodNames.addAll(attr.getMethodNames());
}

for(AssociationVariable av : this.getAssociationVariables())
{
methodNames.addAll(av.getMethodNames());
}

for(StateMachine sm : this.getStateMachines())
{
String stateMachineName = sm.getName().substring(0, 1).toUpperCase() + sm.getName().substring(1);
methodNames.add("set" + stateMachineName);
methodNames.add("get" + stateMachineName);

for(Event ev : sm.getEvents())
{
methodNames.add(ev.getName());
}
}

methodNames.add("constructor");
methodNames.add("delete");
methodNames.add("toString");

return methodNames;
}

public Boolean matchOperationMethod(String fullOperation, String method) {
String formattedMethod = StringFormatter.toUnderscore(method);
TriState isMatch = new TriState(false);
Expand Down Expand Up @@ -3083,8 +3120,14 @@ class AssociationVariable

public ArrayList<String> getMethodNames()
{
if(!getIsNavigable())
{
return new ArrayList<String>();
}

ArrayList<String> methodNames = new ArrayList<String>();
String attributeCapitalizedName = this.getUpperCaseName();

String singularName = getUmpleClass().getSourceModel().getGlossary().getSingular(this.getName());
String singularCapitalizedName = singularName.substring(0, 1).toUpperCase() + singularName.substring(1);

Expand Down

0 comments on commit e8cc020

Please sign in to comment.