Skip to content

Commit d5d0077

Browse files
authored
Hoist declarations, reduce nesting refactorings
1 parent f95d803 commit d5d0077

File tree

4 files changed

+311
-10
lines changed

4 files changed

+311
-10
lines changed

BehaviouralFeature.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11162,17 +11162,17 @@ public void hoistLocalDeclarations()
1116211162
ModelElement.lookupByName(vname, parameters);
1116311163

1116411164
if (par != null)
11165-
{ System.err.println("!! Warning: " + vname + " is both a parameter and local variable!");
11165+
{ System.err.println("!! Code Smell (MDV): " + vname + " is both a parameter and a local variable!");
1116611166
continue;
1116711167
}
1116811168

1116911169
if (varnames.contains(vname))
11170-
{ System.err.println("!! Warning: multiple declarations for variable " + vname);
11170+
{ System.err.println("!! Code Smell (MDV): multiple declarations in same scope for variable " + vname);
1117111171
continue;
1117211172
}
1117311173

1117411174
varnames.add(vname);
11175-
initialDecs.add(cs);
11175+
initialDecs.add(cs.defaultVersion());
1117611176
}
1117711177

1117811178
if (varnames.size() == 0)
@@ -11186,6 +11186,23 @@ public void hoistLocalDeclarations()
1118611186
System.out.println(">>> New activity: " + ss);
1118711187
activity = ss;
1118811188
}
11189+
11190+
public void reduceCodeNesting()
11191+
{ // Replace each conditional
11192+
// if cond then stats1 else stats2
11193+
// by
11194+
// if cond then stats1 else skip; stats2
11195+
// where all code paths in stats1 end with a return.
11196+
11197+
if (activity == null)
11198+
{ return; }
11199+
11200+
Statement newactivity =
11201+
Statement.replaceElseBySequence(activity);
11202+
11203+
System.out.println(">>> New activity: " + newactivity);
11204+
activity = newactivity;
11205+
}
1118911206
}
1119011207

1119111208

Statement.java

Lines changed: 168 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,55 @@ public static Vector getReturnValues(Statement st)
193193
return res;
194194
} // Other cases, for all other forms of statement.
195195

196+
public static boolean endsWithReturn(Statement st)
197+
{ if (st == null)
198+
{ return false; }
199+
200+
if (st instanceof SequenceStatement)
201+
{ SequenceStatement sq = (SequenceStatement) st;
202+
Vector stats = sq.getStatements();
203+
Statement stat = (Statement) stats.get(stats.size()-1);
204+
return Statement.endsWithReturn(stat);
205+
}
206+
207+
if (st instanceof ReturnStatement)
208+
{ return true; }
209+
210+
if (st instanceof ConditionalStatement)
211+
{ ConditionalStatement cs = (ConditionalStatement) st;
212+
if (Statement.endsWithReturn(cs.ifPart()))
213+
{ return Statement.endsWithReturn(cs.elsePart()); }
214+
return false;
215+
}
216+
217+
if (st instanceof WhileStatement)
218+
{ return false; }
219+
220+
if (st instanceof TryStatement)
221+
{ TryStatement ts = (TryStatement) st;
222+
223+
if (Statement.endsWithReturn(ts.getBody()))
224+
{ Vector stats = ts.getClauses();
225+
for (int i = 0; i < stats.size(); i++)
226+
{ if (stats.get(i) instanceof Statement)
227+
{ Statement stat = (Statement) stats.get(i);
228+
if (Statement.endsWithReturn(stat)) { }
229+
else
230+
{ return false; }
231+
}
232+
else
233+
{ return false; }
234+
}
235+
}
236+
else
237+
{ return false; }
238+
if (ts.getEndStatement() == null) { return false; }
239+
return Statement.endsWithReturn(ts.getEndStatement());
240+
}
241+
242+
return false;
243+
} // Other cases, for all other forms of statement.
244+
196245
public static Statement replaceReturnBySkip(Statement st)
197246
{ if (st == null)
198247
{ return st; }
@@ -269,8 +318,101 @@ public static Statement replaceReturnBySkip(Statement st)
269318
return st;
270319
} // Other cases, for all other forms of statement.
271320

321+
public static Statement replaceElseBySequence(Statement st)
322+
{ if (st == null)
323+
{ return st; }
324+
325+
if (st instanceof SequenceStatement)
326+
{ SequenceStatement sq = (SequenceStatement) st;
327+
Vector newstats = new Vector();
328+
Vector stats = sq.getStatements();
329+
for (int i = 0; i < stats.size(); i++)
330+
{ if (stats.get(i) instanceof Statement)
331+
{ Statement stat = (Statement) stats.get(i);
332+
Statement newstat =
333+
Statement.replaceElseBySequence(stat);
334+
newstats.add(newstat);
335+
}
336+
}
337+
338+
SequenceStatement newsq =
339+
new SequenceStatement(newstats);
340+
newsq.setBrackets(sq.hasBrackets());
341+
return newsq;
342+
}
343+
344+
if (st instanceof ReturnStatement)
345+
{ return st; }
346+
347+
if (st instanceof ConditionalStatement)
348+
{ ConditionalStatement cs = (ConditionalStatement) st;
349+
Statement newif =
350+
Statement.replaceElseBySequence(cs.ifPart());
351+
Statement newelse =
352+
Statement.replaceElseBySequence(cs.elsePart());
353+
if (Statement.endsWithReturn(newif))
354+
{ ConditionalStatement res =
355+
new ConditionalStatement(cs.getTest(),
356+
newif,
357+
new InvocationStatement("skip"));
358+
SequenceStatement ss = new SequenceStatement();
359+
ss.addStatement(res);
360+
ss.addStatement(newelse);
361+
return ss;
362+
}
363+
else
364+
{ ConditionalStatement res =
365+
new ConditionalStatement(cs.getTest(),
366+
newif,
367+
newelse);
368+
369+
return res;
370+
}
371+
}
372+
373+
if (st instanceof WhileStatement)
374+
{ WhileStatement ws = (WhileStatement) st;
375+
Statement newbody =
376+
Statement.replaceElseBySequence(ws.getLoopBody());
377+
WhileStatement wsnew =
378+
new WhileStatement(ws.getTest(), newbody);
379+
wsnew.loopKind = ws.loopKind;
380+
wsnew.loopVar = ws.loopVar;
381+
wsnew.loopRange = ws.loopRange;
382+
383+
return wsnew;
384+
}
385+
386+
if (st instanceof TryStatement)
387+
{ TryStatement ts = (TryStatement) st;
388+
Statement newbody =
389+
Statement.replaceElseBySequence(ts.getBody());
390+
Vector newclauses = new Vector();
391+
Vector stats = ts.getClauses();
392+
for (int i = 0; i < stats.size(); i++)
393+
{ if (stats.get(i) instanceof Statement)
394+
{ Statement stat = (Statement) stats.get(i);
395+
Statement newstat =
396+
Statement.replaceElseBySequence(stat);
397+
newclauses.add(newstat);
398+
}
399+
}
400+
401+
Statement newend =
402+
Statement.replaceElseBySequence(
403+
ts.getEndStatement());
404+
TryStatement newtry =
405+
new TryStatement(newbody, newclauses, newend);
406+
return newtry;
407+
}
408+
409+
return st;
410+
} // Other cases, for all other forms of statement.
411+
272412
public static Vector getLocalDeclarations(Statement st)
273-
{ Vector res = new Vector();
413+
{ // Local declarations that are not within a loop
414+
415+
Vector res = new Vector();
274416
if (st == null)
275417
{ return res; }
276418

@@ -300,7 +442,7 @@ public static Vector getLocalDeclarations(Statement st)
300442

301443
if (st instanceof WhileStatement)
302444
{ WhileStatement ws = (WhileStatement) st;
303-
res.addAll(getLocalDeclarations(ws.getLoopBody()));
445+
// res.addAll(getLocalDeclarations(ws.getLoopBody()));
304446
return res;
305447
}
306448

@@ -869,7 +1011,7 @@ public static Statement replaceLocalDeclarations(Statement st, Vector vars)
8691011
return res;
8701012
}
8711013

872-
if (st instanceof WhileStatement)
1014+
/* if (st instanceof WhileStatement)
8731015
{ WhileStatement ws = (WhileStatement) st;
8741016
Statement newbody =
8751017
Statement.replaceLocalDeclarations(
@@ -880,7 +1022,7 @@ public static Statement replaceLocalDeclarations(Statement st, Vector vars)
8801022
return res;
8811023
}
8821024
883-
/* if (st instanceof TryStatement)
1025+
if (st instanceof TryStatement)
8841026
{ TryStatement ts = (TryStatement) st;
8851027
res.addAll(getLocalDeclarations(ts.getBody()));
8861028
Vector stats = ts.getClauses();
@@ -5393,6 +5535,19 @@ class CreationStatement extends Statement
53935535
boolean isFrozen = false; // true when a constant is declared.
53945536
Attribute variable = null; // for the LHS
53955537

5538+
public Object clone()
5539+
{ CreationStatement cs =
5540+
new CreationStatement(createsInstanceOf,assignsTo);
5541+
cs.instanceType = instanceType;
5542+
cs.elementType = elementType;
5543+
cs.declarationOnly = declarationOnly;
5544+
cs.initialValue = initialValue;
5545+
cs.initialExpression = (Expression) initialExpression.clone();
5546+
cs.isFrozen = isFrozen;
5547+
cs.variable = variable;
5548+
return cs;
5549+
}
5550+
53965551
public Type getType()
53975552
{ return instanceType; }
53985553

@@ -5449,6 +5604,15 @@ public CreationStatement(Expression vbl, Type typ)
54495604
assignsTo = vbl + "";
54505605
}
54515606

5607+
public CreationStatement defaultVersion()
5608+
{ CreationStatement res = (CreationStatement) clone();
5609+
Expression defaultInit =
5610+
Type.defaultInitialValueExpression(instanceType);
5611+
res.initialExpression = defaultInit;
5612+
res.initialValue = defaultInit + "";
5613+
return res;
5614+
}
5615+
54525616

54535617
/* public CreationStatement(Attribute vbl, Type typ)
54545618
{ createsInstanceOf = typ.getName();
@@ -5577,9 +5741,6 @@ public void setElementType(Type t)
55775741
{ instanceType.setElementType(t); }
55785742
}
55795743

5580-
public Object clone()
5581-
{ return this; }
5582-
55835744
public Statement dereference(BasicExpression var)
55845745
{ return this; }
55855746

UCDArea.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6692,6 +6692,78 @@ else if (effect == stat)
66926692
System.out.println(">> Set activity for operation " + nme + " of entity " + ent);
66936693
}
66946694

6695+
public void hoistOperationLocalDecs(Entity ent)
6696+
{ String nme =
6697+
JOptionPane.showInputDialog("Enter operation name:");
6698+
BehaviouralFeature bf = ent.getOperation(nme);
6699+
if (bf == null)
6700+
{ System.err.println("!! ERROR: No such operation: " + nme);
6701+
return;
6702+
}
6703+
6704+
Statement stat = bf.getActivity();
6705+
bf.hoistLocalDeclarations();
6706+
Statement effect = bf.getActivity();
6707+
6708+
if (effect == null)
6709+
{ System.err.println("!!! ERROR: Syntax error in activity");
6710+
return;
6711+
}
6712+
else if (effect == stat)
6713+
{ System.out.println(">>> No change to activity");
6714+
return;
6715+
}
6716+
6717+
Vector contexts = new Vector();
6718+
contexts.add(ent);
6719+
Vector pars = new Vector();
6720+
6721+
effect.setEntity(ent);
6722+
pars.addAll(bf.getParameters());
6723+
6724+
effect.typeCheck(types,entities,contexts,pars);
6725+
6726+
bf.setActivity(effect);
6727+
updateActivities(ent, bf, effect);
6728+
System.out.println(">> Set activity for operation " + nme + " of entity " + ent);
6729+
}
6730+
6731+
public void reduceCodeNesting(Entity ent)
6732+
{ String nme =
6733+
JOptionPane.showInputDialog("Enter operation name:");
6734+
BehaviouralFeature bf = ent.getOperation(nme);
6735+
if (bf == null)
6736+
{ System.err.println("!! ERROR: No such operation: " + nme);
6737+
return;
6738+
}
6739+
6740+
Statement stat = bf.getActivity();
6741+
bf.reduceCodeNesting();
6742+
Statement effect = bf.getActivity();
6743+
6744+
if (effect == null)
6745+
{ System.err.println("!!! ERROR: Syntax error in activity");
6746+
return;
6747+
}
6748+
else if (effect == stat)
6749+
{ System.out.println(">>> No change to activity");
6750+
return;
6751+
}
6752+
6753+
Vector contexts = new Vector();
6754+
contexts.add(ent);
6755+
Vector pars = new Vector();
6756+
6757+
effect.setEntity(ent);
6758+
pars.addAll(bf.getParameters());
6759+
6760+
effect.typeCheck(types,entities,contexts,pars);
6761+
6762+
bf.setActivity(effect);
6763+
updateActivities(ent, bf, effect);
6764+
System.out.println(">> Set activity for operation " + nme + " of entity " + ent);
6765+
}
6766+
66956767
public void replaceCallsByDefinitions(Entity ent)
66966768
{ String nme =
66976769
JOptionPane.showInputDialog("Name of operation to be replaced by its code:");

0 commit comments

Comments
 (0)