switch to spaces only..
[IRC.git] / Robust / src / Analysis / SSJava / FlowDownCheck.java
1 package Analysis.SSJava;
2
3 import java.util.HashSet;
4 import java.util.Hashtable;
5 import java.util.Iterator;
6 import java.util.Map;
7 import java.util.Set;
8 import java.util.StringTokenizer;
9 import java.util.Vector;
10
11 import IR.AnnotationDescriptor;
12 import IR.ClassDescriptor;
13 import IR.Descriptor;
14 import IR.FieldDescriptor;
15 import IR.MethodDescriptor;
16 import IR.NameDescriptor;
17 import IR.Operation;
18 import IR.State;
19 import IR.SymbolTable;
20 import IR.TypeDescriptor;
21 import IR.VarDescriptor;
22 import IR.Tree.ArrayAccessNode;
23 import IR.Tree.AssignmentNode;
24 import IR.Tree.BlockExpressionNode;
25 import IR.Tree.BlockNode;
26 import IR.Tree.BlockStatementNode;
27 import IR.Tree.CreateObjectNode;
28 import IR.Tree.DeclarationNode;
29 import IR.Tree.ExpressionNode;
30 import IR.Tree.FieldAccessNode;
31 import IR.Tree.IfStatementNode;
32 import IR.Tree.Kind;
33 import IR.Tree.LiteralNode;
34 import IR.Tree.LoopNode;
35 import IR.Tree.MethodInvokeNode;
36 import IR.Tree.NameNode;
37 import IR.Tree.OpNode;
38 import IR.Tree.SubBlockNode;
39 import IR.Tree.TertiaryNode;
40 import IR.Tree.TreeNode;
41 import Util.Lattice;
42
43 public class FlowDownCheck {
44
45   static State state;
46   HashSet toanalyze;
47   Hashtable<Descriptor, Location> td2loc; // mapping from 'type descriptor'
48                                           // to 'location'
49   Hashtable<String, ClassDescriptor> id2cd; // mapping from 'locID' to 'class
50                                             // descriptor'
51
52   public FlowDownCheck(State state) {
53     this.state = state;
54     this.toanalyze = new HashSet();
55     this.td2loc = new Hashtable<Descriptor, Location>();
56     init();
57   }
58
59   public void init() {
60     id2cd = new Hashtable<String, ClassDescriptor>();
61     Hashtable cd2lattice = state.getCd2LocationOrder();
62
63     Set cdSet = cd2lattice.keySet();
64     for (Iterator iterator = cdSet.iterator(); iterator.hasNext(); ) {
65       ClassDescriptor cd = (ClassDescriptor) iterator.next();
66       Lattice<String> lattice = (Lattice<String>)cd2lattice.get(cd);
67
68       Set<String> locIdSet = lattice.getKeySet();
69       for (Iterator iterator2 = locIdSet.iterator(); iterator2.hasNext(); ) {
70         String locID = (String) iterator2.next();
71         id2cd.put(locID, cd);
72       }
73     }
74
75   }
76
77   public void flowDownCheck() {
78     SymbolTable classtable = state.getClassSymbolTable();
79
80     // phase 1 : checking declaration node and creating mapping of 'type
81     // desciptor' & 'location'
82     toanalyze.addAll(classtable.getValueSet());
83     toanalyze.addAll(state.getTaskSymbolTable().getValueSet());
84     while (!toanalyze.isEmpty()) {
85       Object obj = toanalyze.iterator().next();
86       ClassDescriptor cd = (ClassDescriptor) obj;
87       toanalyze.remove(cd);
88 //      if (cd.isClassLibrary()) {
89       // doesn't care about class libraries now
90 //        continue;
91 //      }
92       checkDeclarationInClass(cd);
93       for (Iterator method_it = cd.getMethods(); method_it.hasNext(); ) {
94         MethodDescriptor md = (MethodDescriptor) method_it.next();
95         try {
96           checkDeclarationInMethodBody(cd, md);
97         } catch (Error e) {
98           System.out.println("Error in " + md);
99           throw e;
100         }
101       }
102     }
103
104     // post-processing for delta location
105     // for a nested delta location, assigning a concrete reference to delta
106     // operand
107     Set<Descriptor> tdSet = td2loc.keySet();
108     for (Iterator iterator = tdSet.iterator(); iterator.hasNext(); ) {
109       Descriptor td = (Descriptor) iterator.next();
110       Location loc = td2loc.get(td);
111
112       if (loc.getType() == Location.DELTA) {
113         // if it contains delta reference pointing to another location element
114         CompositeLocation compLoc = (CompositeLocation) loc;
115
116         Location locElement = compLoc.getTuple().at(0);
117         assert(locElement instanceof DeltaLocation);
118
119         DeltaLocation delta = (DeltaLocation) locElement;
120         Descriptor refType = delta.getRefLocationId();
121         if (refType != null) {
122           Location refLoc = td2loc.get(refType);
123
124           assert(refLoc instanceof CompositeLocation);
125           CompositeLocation refCompLoc = (CompositeLocation) refLoc;
126
127           assert(refCompLoc.getTuple().at(0) instanceof DeltaLocation);
128           DeltaLocation refDelta = (DeltaLocation) refCompLoc.getTuple().at(0);
129
130           delta.addDeltaOperand(refDelta);
131           // compLoc.addLocation(refDelta);
132         }
133
134       }
135     }
136
137     // phase2 : checking assignments
138     toanalyze.addAll(classtable.getValueSet());
139     toanalyze.addAll(state.getTaskSymbolTable().getValueSet());
140     while (!toanalyze.isEmpty()) {
141       Object obj = toanalyze.iterator().next();
142       ClassDescriptor cd = (ClassDescriptor) obj;
143       toanalyze.remove(cd);
144 //      if (cd.isClassLibrary()) {
145       // doesn't care about class libraries now
146 //        continue;
147 //      }
148       checkClass(cd);
149       for (Iterator method_it = cd.getMethods(); method_it.hasNext(); ) {
150         MethodDescriptor md = (MethodDescriptor) method_it.next();
151         try {
152           checkMethodBody(cd, md);
153         } catch (Error e) {
154           System.out.println("Error in " + md);
155           throw e;
156         }
157       }
158     }
159
160   }
161
162   public Hashtable getMap() {
163     return td2loc;
164   }
165
166   private void checkDeclarationInMethodBody(ClassDescriptor cd, MethodDescriptor md) {
167     BlockNode bn = state.getMethodBody(md);
168     for (int i = 0; i < md.numParameters(); i++) {
169       // process annotations on method parameters
170       VarDescriptor vd = (VarDescriptor) md.getParameter(i);
171       assignLocationOfVarDescriptor(vd, md, md.getParameterTable(), bn);
172     }
173     checkDeclarationInBlockNode(md, md.getParameterTable(), bn);
174   }
175
176   private void checkDeclarationInBlockNode(MethodDescriptor md, SymbolTable nametable, BlockNode bn) {
177     bn.getVarTable().setParent(nametable);
178     for (int i = 0; i < bn.size(); i++) {
179       BlockStatementNode bsn = bn.get(i);
180       checkDeclarationInBlockStatementNode(md, bn.getVarTable(), bsn);
181     }
182   }
183
184   private void checkDeclarationInBlockStatementNode(MethodDescriptor md, SymbolTable nametable,
185                                                     BlockStatementNode bsn) {
186
187     switch (bsn.kind()) {
188     case Kind.SubBlockNode:
189       checkDeclarationInSubBlockNode(md, nametable, (SubBlockNode) bsn);
190       return;
191
192     case Kind.DeclarationNode:
193       checkDeclarationNode(md, nametable, (DeclarationNode) bsn);
194       break;
195
196     case Kind.LoopNode:
197       checkDeclarationInLoopNode(md, nametable, (LoopNode) bsn);
198       break;
199     }
200   }
201
202   private void checkDeclarationInLoopNode(MethodDescriptor md, SymbolTable nametable, LoopNode ln) {
203
204     if (ln.getType() == LoopNode.FORLOOP) {
205       // check for loop case
206       ClassDescriptor cd = md.getClassDesc();
207       BlockNode bn = ln.getInitializer();
208       for (int i = 0; i < bn.size(); i++) {
209         BlockStatementNode bsn = bn.get(i);
210         checkDeclarationInBlockStatementNode(md, nametable, bsn);
211       }
212     }
213
214     // check loop body
215     checkDeclarationInBlockNode(md, nametable, ln.getBody());
216   }
217
218   private void checkMethodBody(ClassDescriptor cd, MethodDescriptor md) {
219     BlockNode bn = state.getMethodBody(md);
220     checkLocationFromBlockNode(md, md.getParameterTable(), bn);
221   }
222
223   private CompositeLocation checkLocationFromBlockNode(MethodDescriptor md, SymbolTable nametable,
224                                                        BlockNode bn) {
225     // it will return the lowest location in the block node
226     CompositeLocation lowestLoc = null;
227     for (int i = 0; i < bn.size(); i++) {
228       BlockStatementNode bsn = bn.get(i);
229       CompositeLocation bLoc = checkLocationFromBlockStatementNode(md, bn.getVarTable(), bsn);
230
231       if (lowestLoc == null) {
232         lowestLoc = bLoc;
233       } else {
234         if (CompositeLattice.isGreaterThan(lowestLoc, bLoc, md.getClassDesc())) {
235           lowestLoc = bLoc;
236         }
237       }
238     }
239     return lowestLoc;
240   }
241
242   private CompositeLocation checkLocationFromBlockStatementNode(MethodDescriptor md,
243                                                                 SymbolTable nametable, BlockStatementNode bsn) {
244
245     CompositeLocation compLoc = null;
246     switch (bsn.kind()) {
247     case Kind.BlockExpressionNode:
248       compLoc = checkLocationFromBlockExpressionNode(md, nametable, (BlockExpressionNode) bsn);
249       break;
250
251     case Kind.DeclarationNode:
252       compLoc = checkLocationFromDeclarationNode(md, nametable, (DeclarationNode) bsn);
253       break;
254
255     case Kind.IfStatementNode:
256       compLoc = checkLocationFromIfStatementNode(md, nametable, (IfStatementNode) bsn);
257       break;
258
259     case Kind.LoopNode:
260       compLoc = checkLocationFromLoopNode(md, nametable, (LoopNode) bsn);
261       break;
262
263     case Kind.ReturnNode:
264       // checkLocationFromReturnNode(md, nametable, (ReturnNode) bsn);
265       return null;
266
267     case Kind.SubBlockNode:
268       compLoc = checkLocationFromSubBlockNode(md, nametable, (SubBlockNode) bsn);
269       break;
270
271       // case Kind.ContinueBreakNode:
272       // checkLocationFromContinueBreakNode(md, nametable,(ContinueBreakNode)
273       // bsn);
274       // return null;
275     }
276     return compLoc;
277   }
278
279   private CompositeLocation checkLocationFromLoopNode(MethodDescriptor md, SymbolTable nametable,
280                                                       LoopNode ln) {
281
282     ClassDescriptor cd = md.getClassDesc();
283     if (ln.getType() == LoopNode.WHILELOOP || ln.getType() == LoopNode.DOWHILELOOP) {
284
285       CompositeLocation condLoc =
286         checkLocationFromExpressionNode(md, nametable, ln.getCondition(), new CompositeLocation(
287                                           cd));
288       addTypeLocation(ln.getCondition().getType(), (condLoc));
289
290       CompositeLocation bodyLoc = checkLocationFromBlockNode(md, nametable, ln.getBody());
291
292       if (!CompositeLattice.isGreaterThan(condLoc, bodyLoc, cd)) {
293         // loop condition should be higher than loop body
294         throw new Error(
295           "The location of the while-condition statement is lower than the loop body at "
296           + cd.getSourceFileName() + ":" + ln.getCondition().getNumLine());
297       }
298
299       return bodyLoc;
300
301     } else {
302       // check for loop case
303       BlockNode bn = ln.getInitializer();
304
305       // calculate glb location of condition and update statements
306       CompositeLocation condLoc =
307         checkLocationFromExpressionNode(md, bn.getVarTable(), ln.getCondition(),
308                                         new CompositeLocation(cd));
309       addTypeLocation(ln.getCondition().getType(), condLoc);
310
311       CompositeLocation updateLoc =
312         checkLocationFromBlockNode(md, bn.getVarTable(), ln.getUpdate());
313
314       Set<CompositeLocation> glbInputSet = new HashSet<CompositeLocation>();
315       glbInputSet.add(condLoc);
316       glbInputSet.add(updateLoc);
317
318       CompositeLocation glbLocOfForLoopCond = CompositeLattice.calculateGLB(cd, glbInputSet, cd);
319       CompositeLocation blockLoc = checkLocationFromBlockNode(md, bn.getVarTable(), ln.getBody());
320
321       if (blockLoc == null) {
322         // when there is no statement in the loop body
323         return glbLocOfForLoopCond;
324       }
325
326       if (!CompositeLattice.isGreaterThan(glbLocOfForLoopCond, blockLoc, cd)) {
327         throw new Error(
328           "The location of the for-condition statement is lower than the for-loop body at "
329           + cd.getSourceFileName() + ":" + ln.getCondition().getNumLine());
330       }
331       return blockLoc;
332     }
333
334   }
335
336   private CompositeLocation checkLocationFromSubBlockNode(MethodDescriptor md,
337                                                           SymbolTable nametable, SubBlockNode sbn) {
338     CompositeLocation compLoc = checkLocationFromBlockNode(md, nametable, sbn.getBlockNode());
339     return compLoc;
340   }
341
342   private CompositeLocation checkLocationFromIfStatementNode(MethodDescriptor md,
343                                                              SymbolTable nametable, IfStatementNode isn) {
344
345     ClassDescriptor localCD = md.getClassDesc();
346     Set<CompositeLocation> glbInputSet = new HashSet<CompositeLocation>();
347
348     CompositeLocation condLoc =
349       checkLocationFromExpressionNode(md, nametable, isn.getCondition(), new CompositeLocation(
350                                         localCD));
351     addTypeLocation(isn.getCondition().getType(), condLoc);
352     glbInputSet.add(condLoc);
353
354     CompositeLocation locTrueBlock = checkLocationFromBlockNode(md, nametable, isn.getTrueBlock());
355     glbInputSet.add(locTrueBlock);
356
357     // here, the location of conditional block should be higher than the
358     // location of true/false blocks
359
360     if (!CompositeLattice.isGreaterThan(condLoc, locTrueBlock, localCD)) {
361       // error
362       throw new Error(
363         "The location of the if-condition statement is lower than the conditional block at "
364         + localCD.getSourceFileName() + ":" + isn.getCondition().getNumLine());
365     }
366
367     if (isn.getFalseBlock() != null) {
368       CompositeLocation locFalseBlock =
369         checkLocationFromBlockNode(md, nametable, isn.getFalseBlock());
370       glbInputSet.add(locFalseBlock);
371
372       if (!CompositeLattice.isGreaterThan(condLoc, locFalseBlock, localCD)) {
373         // error
374         throw new Error(
375           "The location of the if-condition statement is lower than the conditional block at "
376           + localCD.getSourceFileName() + ":" + isn.getCondition().getNumLine());
377       }
378
379     }
380
381     // return GLB location of condition, true, and false block
382     CompositeLocation glbLoc = CompositeLattice.calculateGLB(localCD, glbInputSet, localCD);
383
384     return glbLoc;
385   }
386
387   private CompositeLocation checkLocationFromDeclarationNode(MethodDescriptor md,
388                                                              SymbolTable nametable, DeclarationNode dn) {
389     VarDescriptor vd = dn.getVarDescriptor();
390
391     Location destLoc = td2loc.get(vd);
392
393     ClassDescriptor localCD = md.getClassDesc();
394     if (dn.getExpression() != null) {
395       CompositeLocation expressionLoc =
396         checkLocationFromExpressionNode(md, nametable, dn.getExpression(), new CompositeLocation(
397                                           localCD));
398       addTypeLocation(dn.getExpression().getType(), expressionLoc);
399
400       if (expressionLoc != null) {
401         // checking location order
402         if (!CompositeLattice.isGreaterThan(expressionLoc, destLoc, localCD)) {
403           throw new Error("The value flow from " + expressionLoc + " to " + destLoc
404                           + " does not respect location hierarchy on the assignment " + dn.printNode(0));
405         }
406       }
407       return expressionLoc;
408
409     } else {
410       return null;
411     }
412
413   }
414
415   private void checkDeclarationInSubBlockNode(MethodDescriptor md, SymbolTable nametable,
416                                               SubBlockNode sbn) {
417     checkDeclarationInBlockNode(md, nametable, sbn.getBlockNode());
418   }
419
420   private CompositeLocation checkLocationFromBlockExpressionNode(MethodDescriptor md,
421                                                                  SymbolTable nametable, BlockExpressionNode ben) {
422     CompositeLocation compLoc =
423       checkLocationFromExpressionNode(md, nametable, ben.getExpression(), null);
424     addTypeLocation(ben.getExpression().getType(), compLoc);
425     return compLoc;
426   }
427
428   private CompositeLocation checkLocationFromExpressionNode(MethodDescriptor md,
429                                                             SymbolTable nametable, ExpressionNode en, CompositeLocation loc) {
430
431     CompositeLocation compLoc = null;
432     switch (en.kind()) {
433
434     case Kind.AssignmentNode:
435       compLoc = checkLocationFromAssignmentNode(md, nametable, (AssignmentNode) en, loc);
436       break;
437
438     case Kind.FieldAccessNode:
439       compLoc = checkLocationFromFieldAccessNode(md, nametable, (FieldAccessNode) en, loc);
440       break;
441
442     case Kind.NameNode:
443       compLoc = checkLocationFromNameNode(md, nametable, (NameNode) en, loc);
444       break;
445
446     case Kind.OpNode:
447       compLoc = checkLocationFromOpNode(md, nametable, (OpNode) en);
448       break;
449
450     case Kind.CreateObjectNode:
451       compLoc = checkLocationFromCreateObjectNode(md, nametable, (CreateObjectNode) en);
452       break;
453
454     case Kind.ArrayAccessNode:
455       compLoc = checkLocationFromArrayAccessNode(md, nametable, (ArrayAccessNode) en);
456       break;
457
458     case Kind.LiteralNode:
459       compLoc = checkLocationFromLiteralNode(md, nametable, (LiteralNode) en, loc);
460       break;
461
462     case Kind.MethodInvokeNode:
463       compLoc = checkLocationFromMethodInvokeNode(md, nametable, (MethodInvokeNode) en);
464       break;
465
466     case Kind.TertiaryNode:
467       compLoc = checkLocationFromTertiaryNode(md, nametable, (TertiaryNode) en);
468       break;
469
470     // case Kind.InstanceOfNode:
471     // checkInstanceOfNode(md, nametable, (InstanceOfNode) en, td);
472     // return null;
473
474     // case Kind.ArrayInitializerNode:
475     // checkArrayInitializerNode(md, nametable, (ArrayInitializerNode) en,
476     // td);
477     // return null;
478
479     // case Kind.ClassTypeNode:
480     // checkClassTypeNode(md, nametable, (ClassTypeNode) en, td);
481     // return null;
482
483     // case Kind.OffsetNode:
484     // checkOffsetNode(md, nametable, (OffsetNode)en, td);
485     // return null;
486
487     default:
488       return null;
489
490     }
491
492     addTypeLocation(en.getType(), compLoc);
493     return compLoc;
494
495   }
496
497   private CompositeLocation checkLocationFromTertiaryNode(MethodDescriptor md,
498                                                           SymbolTable nametable, TertiaryNode tn) {
499     ClassDescriptor cd = md.getClassDesc();
500
501     CompositeLocation condLoc =
502       checkLocationFromExpressionNode(md, nametable, tn.getCond(), new CompositeLocation(cd));
503     addTypeLocation(tn.getCond().getType(), condLoc);
504     CompositeLocation trueLoc =
505       checkLocationFromExpressionNode(md, nametable, tn.getTrueExpr(), new CompositeLocation(cd));
506     addTypeLocation(tn.getTrueExpr().getType(), trueLoc);
507     CompositeLocation falseLoc =
508       checkLocationFromExpressionNode(md, nametable, tn.getFalseExpr(), new CompositeLocation(cd));
509     addTypeLocation(tn.getFalseExpr().getType(), falseLoc);
510
511     // check if condLoc is higher than trueLoc & falseLoc
512     if (!CompositeLattice.isGreaterThan(condLoc, trueLoc, cd)) {
513       throw new Error(
514         "The location of the condition expression is lower than the true expression at "
515         + cd.getSourceFileName() + ":" + tn.getCond().getNumLine());
516     }
517
518     if (!CompositeLattice.isGreaterThan(condLoc, falseLoc, cd)) {
519       throw new Error(
520         "The location of the condition expression is lower than the true expression at "
521         + cd.getSourceFileName() + ":" + tn.getCond().getNumLine());
522     }
523
524     // then, return glb of trueLoc & falseLoc
525     Set<CompositeLocation> glbInputSet = new HashSet<CompositeLocation>();
526     glbInputSet.add(trueLoc);
527     glbInputSet.add(falseLoc);
528
529     return CompositeLattice.calculateGLB(cd, glbInputSet, cd);
530   }
531
532   private CompositeLocation checkLocationFromMethodInvokeNode(MethodDescriptor md,
533                                                               SymbolTable nametable, MethodInvokeNode min) {
534
535     ClassDescriptor cd = md.getClassDesc();
536
537     if (min.numArgs() > 1) {
538
539       // caller needs to guarantee that it passes arguments in regarding to
540       // callee's hierarchy
541
542       for (int i = 0; i < min.numArgs(); i++) {
543         ExpressionNode en = min.getArg(i);
544         CompositeLocation callerArg1 =
545           checkLocationFromExpressionNode(md, nametable, en, new CompositeLocation(cd));
546
547         ClassDescriptor calleecd = min.getMethod().getClassDesc();
548         VarDescriptor calleevd = (VarDescriptor) min.getMethod().getParameter(i);
549         Location calleeLoc1 = td2loc.get(calleevd);
550
551         if (!callerArg1.getLocation(cd).isTop()) {
552           // here, check if ordering relations among caller's args respect
553           // ordering relations in-between callee's args
554           for (int currentIdx = 0; currentIdx < min.numArgs(); currentIdx++) {
555             if (currentIdx != i) { // skip itself
556               ExpressionNode argExp = min.getArg(currentIdx);
557               CompositeLocation callerArg2 =
558                 checkLocationFromExpressionNode(md, nametable, argExp, new CompositeLocation(cd));
559
560               VarDescriptor calleevd2 = (VarDescriptor) min.getMethod().getParameter(currentIdx);
561               Location calleeLoc2 = td2loc.get(calleevd2);
562               boolean callerResult = CompositeLattice.isGreaterThan(callerArg1, callerArg2, cd);
563               boolean calleeResult =
564                 CompositeLattice.isGreaterThan(calleeLoc1, calleeLoc2, calleecd);
565
566               if (calleeResult && !callerResult) {
567                 // in callee, calleeLoc1 is higher than calleeLoc2
568                 // then, caller should have same ordering relation in-bet
569                 // callerLoc1 & callerLoc2
570
571                 throw new Error("Caller doesn't respect ordering relations among method arguments:"
572                                 + cd.getSourceFileName() + ":" + min.getNumLine());
573               }
574
575             }
576           }
577         }
578
579       }
580
581     }
582
583     // all arguments should be higher than the location of return value
584
585     // first, calculate glb of arguments
586     Set<CompositeLocation> argLocSet = new HashSet<CompositeLocation>();
587     for (int i = 0; i < min.numArgs(); i++) {
588       ExpressionNode en = min.getArg(i);
589       CompositeLocation argLoc =
590         checkLocationFromExpressionNode(md, nametable, en, new CompositeLocation(cd));
591       addTypeLocation(en.getType(), argLoc);
592       argLocSet.add(argLoc);
593     }
594
595     if (argLocSet.size() > 0) {
596       CompositeLocation argGLBLoc = CompositeLattice.calculateGLB(cd, argLocSet, cd);
597       return argGLBLoc;
598     } else {
599       // if there are no arguments,
600       CompositeLocation returnLoc = new CompositeLocation(cd);
601       returnLoc.addLocation(Location.createTopLocation(cd));
602       return returnLoc;
603     }
604   }
605
606   private CompositeLocation checkLocationFromArrayAccessNode(MethodDescriptor md,
607                                                              SymbolTable nametable, ArrayAccessNode aan) {
608
609     // return glb location of array itself and index
610
611     ClassDescriptor cd = md.getClassDesc();
612
613     Set<CompositeLocation> glbInputSet = new HashSet<CompositeLocation>();
614
615     CompositeLocation arrayLoc =
616       checkLocationFromExpressionNode(md, nametable, aan.getExpression(), new CompositeLocation(
617                                         cd));
618     addTypeLocation(aan.getExpression().getType(), arrayLoc);
619     glbInputSet.add(arrayLoc);
620
621     CompositeLocation indexLoc =
622       checkLocationFromExpressionNode(md, nametable, aan.getIndex(), new CompositeLocation(cd));
623     glbInputSet.add(indexLoc);
624     addTypeLocation(aan.getIndex().getType(), indexLoc);
625
626     CompositeLocation glbLoc = CompositeLattice.calculateGLB(cd, glbInputSet, cd);
627     return glbLoc;
628   }
629
630   private CompositeLocation checkLocationFromCreateObjectNode(MethodDescriptor md,
631                                                               SymbolTable nametable, CreateObjectNode con) {
632
633     ClassDescriptor cd = md.getClassDesc();
634
635     // check arguments
636     Set<CompositeLocation> glbInputSet = new HashSet<CompositeLocation>();
637     for (int i = 0; i < con.numArgs(); i++) {
638       ExpressionNode en = con.getArg(i);
639       CompositeLocation argLoc =
640         checkLocationFromExpressionNode(md, nametable, en, new CompositeLocation(cd));
641       glbInputSet.add(argLoc);
642       addTypeLocation(en.getType(), argLoc);
643     }
644
645     // check array initializers
646     // if ((con.getArrayInitializer() != null)) {
647     // checkLocationFromArrayInitializerNode(md, nametable,
648     // con.getArrayInitializer());
649     // }
650
651     if (glbInputSet.size() > 0) {
652       return CompositeLattice.calculateGLB(cd, glbInputSet, cd);
653     }
654
655     CompositeLocation compLoc = new CompositeLocation(cd);
656     compLoc.addLocation(Location.createTopLocation(cd));
657     return compLoc;
658
659   }
660
661   private CompositeLocation checkLocationFromOpNode(MethodDescriptor md, SymbolTable nametable,
662                                                     OpNode on) {
663
664     ClassDescriptor cd = md.getClassDesc();
665     CompositeLocation leftLoc = new CompositeLocation(cd);
666     leftLoc = checkLocationFromExpressionNode(md, nametable, on.getLeft(), leftLoc);
667     addTypeLocation(on.getLeft().getType(), leftLoc);
668
669     CompositeLocation rightLoc = new CompositeLocation(cd);
670     if (on.getRight() != null) {
671       rightLoc = checkLocationFromExpressionNode(md, nametable, on.getRight(), rightLoc);
672       addTypeLocation(on.getRight().getType(), rightLoc);
673     }
674
675     System.out.println("checking op node=" + on.printNode(0));
676     System.out.println("left loc=" + leftLoc + " from " + on.getLeft().getClass());
677     System.out.println("right loc=" + rightLoc);
678
679     Operation op = on.getOp();
680
681     switch (op.getOp()) {
682
683     case Operation.UNARYPLUS:
684     case Operation.UNARYMINUS:
685     case Operation.LOGIC_NOT:
686       // single operand
687       on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
688       break;
689
690     case Operation.LOGIC_OR:
691     case Operation.LOGIC_AND:
692     case Operation.COMP:
693     case Operation.BIT_OR:
694     case Operation.BIT_XOR:
695     case Operation.BIT_AND:
696     case Operation.ISAVAILABLE:
697     case Operation.EQUAL:
698     case Operation.NOTEQUAL:
699     case Operation.LT:
700     case Operation.GT:
701     case Operation.LTE:
702     case Operation.GTE:
703     case Operation.ADD:
704     case Operation.SUB:
705     case Operation.MULT:
706     case Operation.DIV:
707     case Operation.MOD:
708     case Operation.LEFTSHIFT:
709     case Operation.RIGHTSHIFT:
710     case Operation.URIGHTSHIFT:
711
712       Set<CompositeLocation> inputSet = new HashSet<CompositeLocation>();
713       inputSet.add(leftLoc);
714       inputSet.add(rightLoc);
715       CompositeLocation glbCompLoc = CompositeLattice.calculateGLB(cd, inputSet, cd);
716       return glbCompLoc;
717
718     default:
719       throw new Error(op.toString());
720     }
721
722     return null;
723
724   }
725
726   private CompositeLocation checkLocationFromLiteralNode(MethodDescriptor md,
727                                                          SymbolTable nametable, LiteralNode en, CompositeLocation loc) {
728
729     // literal value has the top location so that value can be flowed into any
730     // location
731     Location literalLoc = Location.createTopLocation(md.getClassDesc());
732     loc.addLocation(literalLoc);
733     return loc;
734
735   }
736
737   private CompositeLocation checkLocationFromNameNode(MethodDescriptor md, SymbolTable nametable,
738                                                       NameNode nn, CompositeLocation loc) {
739
740     NameDescriptor nd = nn.getName();
741     if (nd.getBase() != null) {
742       loc = checkLocationFromExpressionNode(md, nametable, nn.getExpression(), loc);
743       addTypeLocation(nn.getExpression().getType(), loc);
744     } else {
745
746       String varname = nd.toString();
747       Descriptor d = (Descriptor) nametable.get(varname);
748
749       Location localLoc = null;
750       if (d instanceof VarDescriptor) {
751         VarDescriptor vd = (VarDescriptor) d;
752         localLoc = td2loc.get(vd);
753       } else if (d instanceof FieldDescriptor) {
754         FieldDescriptor fd = (FieldDescriptor) d;
755         localLoc = td2loc.get(fd);
756       }
757       assert(localLoc != null);
758
759       if (localLoc instanceof CompositeLocation) {
760         loc = (CompositeLocation) localLoc;
761       } else {
762         loc.addLocation(localLoc);
763       }
764     }
765
766     return loc;
767   }
768
769   private CompositeLocation checkLocationFromFieldAccessNode(MethodDescriptor md,
770                                                              SymbolTable nametable, FieldAccessNode fan, CompositeLocation loc) {
771
772     FieldDescriptor fd = fan.getField();
773     Location fieldLoc = td2loc.get(fd);
774     loc.addLocation(fieldLoc);
775
776     ExpressionNode left = fan.getExpression();
777     CompositeLocation compLoc = checkLocationFromExpressionNode(md, nametable, left, loc);
778     addTypeLocation(left.getType(), compLoc);
779     return compLoc;
780   }
781
782   private CompositeLocation checkLocationFromAssignmentNode(MethodDescriptor md,
783                                                             SymbolTable nametable, AssignmentNode an, CompositeLocation loc) {
784     ClassDescriptor cd = md.getClassDesc();
785
786     boolean postinc = true;
787     if (an.getOperation().getBaseOp() == null
788         || (an.getOperation().getBaseOp().getOp() != Operation.POSTINC && an.getOperation()
789             .getBaseOp().getOp() != Operation.POSTDEC))
790       postinc = false;
791
792     CompositeLocation destLocation =
793       checkLocationFromExpressionNode(md, nametable, an.getDest(), new CompositeLocation(cd));
794
795     CompositeLocation srcLocation = new CompositeLocation(cd);
796     if (!postinc) {
797       srcLocation = new CompositeLocation(cd);
798       srcLocation = checkLocationFromExpressionNode(md, nametable, an.getSrc(), srcLocation);
799
800       if (!CompositeLattice.isGreaterThan(srcLocation, destLocation, cd)) {
801         throw new Error("The value flow from " + srcLocation + " to " + destLocation
802                         + " does not respect location hierarchy on the assignment " + an.printNode(0));
803       }
804     } else {
805       destLocation =
806         srcLocation = checkLocationFromExpressionNode(md, nametable, an.getDest(), srcLocation);
807
808       if (!((Set<String>)state.getCd2LocationPropertyMap().get(cd)).contains(destLocation
809                                                                              .getLocation(cd).getLocIdentifier())) {
810         throw new Error("Location " + destLocation + " is not allowed to have spinning values at "
811                         + cd.getSourceFileName() + ":" + an.getNumLine());
812       }
813
814     }
815     if(an.getSrc()!=null) {
816       addTypeLocation(an.getSrc().getType(), srcLocation);
817     }
818     addTypeLocation(an.getDest().getType(), destLocation);
819
820     return destLocation;
821   }
822
823   private void assignLocationOfVarDescriptor(VarDescriptor vd, MethodDescriptor md,
824                                              SymbolTable nametable, TreeNode n) {
825
826     ClassDescriptor cd = md.getClassDesc();
827     Vector<AnnotationDescriptor> annotationVec = vd.getType().getAnnotationMarkers();
828
829     // currently enforce every variable to have corresponding location
830     if (annotationVec.size() == 0) {
831       throw new Error("Location is not assigned to variable " + vd.getSymbol() + " in the method "
832                       + md.getSymbol() + " of the class " + cd.getSymbol());
833     }
834
835     if (annotationVec.size() > 1) {
836       // variable can have at most one location
837       throw new Error(vd.getSymbol() + " has more than one location.");
838     }
839
840     AnnotationDescriptor ad = annotationVec.elementAt(0);
841
842     if (ad.getType() == AnnotationDescriptor.MARKER_ANNOTATION) {
843
844       // check if location is defined
845       String locationID = ad.getMarker();
846       Lattice<String> lattice = (Lattice<String>)state.getCd2LocationOrder().get(cd);
847
848       if (lattice == null || (!lattice.containsKey(locationID))) {
849         throw new Error("Location " + locationID
850                         + " is not defined in the location hierarchy of class " + cd.getSymbol() + ".");
851       }
852
853       Location loc = new Location(cd, locationID);
854       td2loc.put(vd, loc);
855       addTypeLocation(vd.getType(), loc);
856
857     } else if (ad.getType() == AnnotationDescriptor.SINGLE_ANNOTATION) {
858       if (ad.getMarker().equals(SSJavaAnalysis.DELTA)) {
859
860         CompositeLocation compLoc = new CompositeLocation(cd);
861
862         if (ad.getData().length() == 0) {
863           throw new Error("Delta function of " + vd.getSymbol() + " does not have any locations: "
864                           + cd.getSymbol() + ".");
865         }
866
867         String deltaStr = ad.getData();
868         if (deltaStr.startsWith("LOC(")) {
869
870           if (!deltaStr.endsWith(")")) {
871             throw new Error("The declaration of the delta location is wrong at "
872                             + cd.getSourceFileName() + ":" + n.getNumLine());
873           }
874           String locationOperand = deltaStr.substring(4, deltaStr.length() - 1);
875
876           nametable.get(locationOperand);
877           Descriptor d = (Descriptor) nametable.get(locationOperand);
878
879           if (d instanceof VarDescriptor) {
880             VarDescriptor varDescriptor = (VarDescriptor) d;
881             DeltaLocation deltaLoc = new DeltaLocation(cd, varDescriptor);
882             // td2loc.put(vd.getType(), compLoc);
883             compLoc.addLocation(deltaLoc);
884           } else if (d instanceof FieldDescriptor) {
885             throw new Error("Applying delta operation to the field " + locationOperand
886                             + " is not allowed at " + cd.getSourceFileName() + ":" + n.getNumLine());
887           }
888         } else {
889           StringTokenizer token = new StringTokenizer(deltaStr, ",");
890           DeltaLocation deltaLoc = new DeltaLocation(cd);
891
892           while (token.hasMoreTokens()) {
893             String deltaOperand = token.nextToken();
894             ClassDescriptor deltaCD = id2cd.get(deltaOperand);
895             if (deltaCD == null) {
896               // delta operand is not defined in the location hierarchy
897               throw new Error("Delta operand '" + deltaOperand + "' of declaration node '" + vd
898                               + "' is not defined by location hierarchies.");
899             }
900
901             Location loc = new Location(deltaCD, deltaOperand);
902             deltaLoc.addDeltaOperand(loc);
903           }
904           compLoc.addLocation(deltaLoc);
905
906         }
907
908         td2loc.put(vd, compLoc);
909         addTypeLocation(vd.getType(), compLoc);
910
911       }
912     }
913
914   }
915
916   private void checkDeclarationNode(MethodDescriptor md, SymbolTable nametable, DeclarationNode dn) {
917     VarDescriptor vd = dn.getVarDescriptor();
918     assignLocationOfVarDescriptor(vd, md, nametable, dn);
919   }
920
921   private void checkClass(ClassDescriptor cd) {
922     // Check to see that methods respects ss property
923     for (Iterator method_it = cd.getMethods(); method_it.hasNext(); ) {
924       MethodDescriptor md = (MethodDescriptor) method_it.next();
925       checkMethodDeclaration(cd, md);
926     }
927   }
928
929   private void checkDeclarationInClass(ClassDescriptor cd) {
930     // Check to see that fields are okay
931     for (Iterator field_it = cd.getFields(); field_it.hasNext(); ) {
932       FieldDescriptor fd = (FieldDescriptor) field_it.next();
933       checkFieldDeclaration(cd, fd);
934     }
935   }
936
937   private void checkMethodDeclaration(ClassDescriptor cd, MethodDescriptor md) {
938     // TODO
939   }
940
941   private void checkFieldDeclaration(ClassDescriptor cd, FieldDescriptor fd) {
942
943     Vector<AnnotationDescriptor> annotationVec = fd.getType().getAnnotationMarkers();
944
945     // currently enforce every variable to have corresponding location
946     if (annotationVec.size() == 0) {
947       throw new Error("Location is not assigned to the field " + fd.getSymbol() + " of the class "
948                       + cd.getSymbol());
949     }
950
951     if (annotationVec.size() > 1) {
952       // variable can have at most one location
953       throw new Error("Field " + fd.getSymbol() + " of class " + cd
954                       + " has more than one location.");
955     }
956
957     // check if location is defined
958     AnnotationDescriptor ad = annotationVec.elementAt(0);
959     if (ad.getType() == AnnotationDescriptor.MARKER_ANNOTATION) {
960       String locationID = annotationVec.elementAt(0).getMarker();
961       Lattice<String> lattice = (Lattice<String>)state.getCd2LocationOrder().get(cd);
962
963       if (lattice == null || (!lattice.containsKey(locationID))) {
964         throw new Error("Location " + locationID
965                         + " is not defined in the location hierarchy of class " + cd.getSymbol() + ".");
966       }
967
968       Location localLoc = new Location(cd, locationID);
969       td2loc.put(fd, localLoc);
970       addTypeLocation(fd.getType(), localLoc);
971
972     } else if (ad.getType() == AnnotationDescriptor.SINGLE_ANNOTATION) {
973       if (ad.getMarker().equals(SSJavaAnalysis.DELTA)) {
974
975         if (ad.getData().length() == 0) {
976           throw new Error("Delta function of " + fd.getSymbol() + " does not have any locations: "
977                           + cd.getSymbol() + ".");
978         }
979
980         CompositeLocation compLoc = new CompositeLocation(cd);
981         DeltaLocation deltaLoc = new DeltaLocation(cd);
982
983         StringTokenizer token = new StringTokenizer(ad.getData(), ",");
984         while (token.hasMoreTokens()) {
985           String deltaOperand = token.nextToken();
986           ClassDescriptor deltaCD = id2cd.get(deltaOperand);
987           if (deltaCD == null) {
988             // delta operand is not defined in the location hierarchy
989             throw new Error("Delta operand '" + deltaOperand + "' of field node '" + fd
990                             + "' is not defined by location hierarchies.");
991           }
992
993           Location loc = new Location(deltaCD, deltaOperand);
994           deltaLoc.addDeltaOperand(loc);
995         }
996         compLoc.addLocation(deltaLoc);
997         td2loc.put(fd, compLoc);
998         addTypeLocation(fd.getType(), compLoc);
999
1000       }
1001     }
1002
1003   }
1004
1005   private void addTypeLocation(TypeDescriptor type, Location loc) {
1006     if (type != null) {
1007       type.setExtension(loc);
1008     }
1009   }
1010
1011   static class CompositeLattice {
1012
1013     public static boolean isGreaterThan(Location loc1, Location loc2, ClassDescriptor priorityCD) {
1014
1015       // System.out.println("isGreaterThan=" + loc1 + " ? " + loc2);
1016       CompositeLocation compLoc1;
1017       CompositeLocation compLoc2;
1018
1019       if (loc1 instanceof CompositeLocation) {
1020         compLoc1 = (CompositeLocation) loc1;
1021       } else {
1022         // create a bogus composite location for a single location
1023         compLoc1 = new CompositeLocation(loc1.getClassDescriptor());
1024         compLoc1.addLocation(loc1);
1025       }
1026
1027       if (loc2 instanceof CompositeLocation) {
1028         compLoc2 = (CompositeLocation) loc2;
1029       } else {
1030         // create a bogus composite location for a single location
1031         compLoc2 = new CompositeLocation(loc2.getClassDescriptor());
1032         compLoc2.addLocation(loc2);
1033       }
1034
1035       // comparing two composite locations
1036       // System.out.println("compare base location=" + compLoc1 + " ? " +
1037       // compLoc2);
1038
1039       int baseCompareResult = compareBaseLocationSet(compLoc1, compLoc2, priorityCD);
1040       if (baseCompareResult == ComparisonResult.EQUAL) {
1041         if (compareDelta(compLoc1, compLoc2) == ComparisonResult.GREATER) {
1042           return true;
1043         } else {
1044           return false;
1045         }
1046       } else if (baseCompareResult == ComparisonResult.GREATER) {
1047         return true;
1048       } else {
1049         return false;
1050       }
1051
1052     }
1053
1054     private static int compareDelta(CompositeLocation compLoc1, CompositeLocation compLoc2) {
1055       if (compLoc1.getNumofDelta() < compLoc2.getNumofDelta()) {
1056         return ComparisonResult.GREATER;
1057       } else {
1058         return ComparisonResult.LESS;
1059       }
1060     }
1061
1062     private static int compareBaseLocationSet(CompositeLocation compLoc1,
1063                                               CompositeLocation compLoc2, ClassDescriptor priorityCD) {
1064
1065       // if compLoc1 is greater than compLoc2, return true
1066       // else return false;
1067
1068       Map<ClassDescriptor, Location> cd2loc1 = compLoc1.getCd2Loc();
1069       Map<ClassDescriptor, Location> cd2loc2 = compLoc2.getCd2Loc();
1070
1071       // compare first the priority loc elements
1072       Location priorityLoc1 = cd2loc1.get(priorityCD);
1073       Location priorityLoc2 = cd2loc2.get(priorityCD);
1074
1075       assert(priorityLoc1.getClassDescriptor().equals(priorityLoc2.getClassDescriptor()));
1076
1077       ClassDescriptor cd = priorityLoc1.getClassDescriptor();
1078       Lattice<String> locationOrder = (Lattice<String>)state.getCd2LocationOrder().get(cd);
1079
1080       if (priorityLoc1.getLocIdentifier().equals(priorityLoc2.getLocIdentifier())) {
1081         // have the same level of local hierarchy
1082
1083         Set<String> spinSet = (Set<String>)state.getCd2LocationPropertyMap().get(cd);
1084         if (spinSet != null && spinSet.contains(priorityLoc1.getLocIdentifier())) {
1085           // this location can be spinning
1086           return ComparisonResult.GREATER;
1087         }
1088
1089       } else if (locationOrder.isGreaterThan(priorityLoc1.getLocIdentifier(),
1090                                              priorityLoc2.getLocIdentifier())) {
1091         // if priority loc of compLoc1 is higher than compLoc2
1092         // then, compLoc 1 is higher than compLoc2
1093         return ComparisonResult.GREATER;
1094       } else {
1095         // if priority loc of compLoc1 is NOT higher than compLoc2
1096         // then, compLoc 1 is NOT higher than compLoc2
1097         return ComparisonResult.LESS;
1098       }
1099
1100       // compare base locations except priority by class descriptor
1101       Set<ClassDescriptor> keySet1 = cd2loc1.keySet();
1102       int numEqualLoc = 0;
1103
1104       for (Iterator iterator = keySet1.iterator(); iterator.hasNext(); ) {
1105         ClassDescriptor cd1 = (ClassDescriptor) iterator.next();
1106
1107         Location loc1 = cd2loc1.get(cd1);
1108         Location loc2 = cd2loc2.get(cd1);
1109
1110         if (priorityLoc1.equals(loc1)) {
1111           continue;
1112         }
1113
1114         if (loc2 == null) {
1115           // if comploc2 doesn't have corresponding location,
1116           // then we determines that comploc1 is lower than comploc 2
1117           return ComparisonResult.LESS;
1118         }
1119
1120         System.out.println("lattice comparison:" + loc1.getLocIdentifier() + " ? "
1121                            + loc2.getLocIdentifier());
1122         locationOrder = (Lattice<String>)state.getCd2LocationOrder().get(cd1);
1123         if (loc1.getLocIdentifier().equals(loc2.getLocIdentifier())) {
1124           // have the same level of local hierarchy
1125           numEqualLoc++;
1126         } else if (!locationOrder.isGreaterThan(loc1.getLocIdentifier(), loc2.getLocIdentifier())) {
1127           // if one element of composite location 1 is not higher than composite
1128           // location 2
1129           // then, composite loc 1 is not higher than composite loc 2
1130
1131           System.out.println(compLoc1 + " < " + compLoc2);
1132           return ComparisonResult.LESS;
1133         }
1134
1135       }
1136
1137       if (numEqualLoc == (compLoc1.getBaseLocationSize() - 1)) {
1138         return ComparisonResult.EQUAL;
1139       }
1140
1141       System.out.println(compLoc1 + " > " + compLoc2);
1142       return ComparisonResult.GREATER;
1143     }
1144
1145     public static CompositeLocation calculateGLB(ClassDescriptor cd,
1146                                                  Set<CompositeLocation> inputSet, ClassDescriptor priorityCD) {
1147
1148       CompositeLocation glbCompLoc = new CompositeLocation(cd);
1149       int maxDeltaFunction = 0;
1150
1151       // calculate GLB of priority element first
1152
1153       Hashtable<ClassDescriptor, Set<Location>> cd2locSet =
1154         new Hashtable<ClassDescriptor, Set<Location>>();
1155
1156       // creating mapping from class to set of locations
1157       for (Iterator iterator = inputSet.iterator(); iterator.hasNext(); ) {
1158         CompositeLocation compLoc = (CompositeLocation) iterator.next();
1159
1160         int numOfDelta = compLoc.getNumofDelta();
1161         if (numOfDelta > maxDeltaFunction) {
1162           maxDeltaFunction = numOfDelta;
1163         }
1164
1165         Set<Location> baseLocationSet = compLoc.getBaseLocationSet();
1166         for (Iterator iterator2 = baseLocationSet.iterator(); iterator2.hasNext(); ) {
1167           Location locElement = (Location) iterator2.next();
1168           ClassDescriptor locCD = locElement.getClassDescriptor();
1169
1170           Set<Location> locSet = cd2locSet.get(locCD);
1171           if (locSet == null) {
1172             locSet = new HashSet<Location>();
1173           }
1174           locSet.add(locElement);
1175
1176           cd2locSet.put(locCD, locSet);
1177
1178         }
1179       }
1180
1181       Set<Location> locSetofClass = cd2locSet.get(priorityCD);
1182       Set<String> locIdentifierSet = new HashSet<String>();
1183
1184       for (Iterator<Location> locIterator = locSetofClass.iterator(); locIterator.hasNext(); ) {
1185         Location locElement = locIterator.next();
1186         locIdentifierSet.add(locElement.getLocIdentifier());
1187       }
1188
1189       Lattice<String> locOrder = (Lattice<String>)state.getCd2LocationOrder().get(priorityCD);
1190       String glbLocIdentifer = locOrder.getGLB(locIdentifierSet);
1191
1192       Location priorityGLB = new Location(priorityCD, glbLocIdentifer);
1193
1194       Set<CompositeLocation> sameGLBLoc = new HashSet<CompositeLocation>();
1195
1196       for (Iterator<CompositeLocation> iterator = inputSet.iterator(); iterator.hasNext(); ) {
1197         CompositeLocation inputComploc = iterator.next();
1198         Location locElement = inputComploc.getLocation(priorityCD);
1199
1200         if (locElement.equals(priorityGLB)) {
1201           sameGLBLoc.add(inputComploc);
1202         }
1203       }
1204       glbCompLoc.addLocation(priorityGLB);
1205       if (sameGLBLoc.size() > 0) {
1206         // if more than one location shares the same priority GLB
1207         // need to calculate the rest of GLB loc
1208
1209         Set<Location> glbElementSet = new HashSet<Location>();
1210
1211         for (Iterator<ClassDescriptor> iterator = cd2locSet.keySet().iterator(); iterator.hasNext(); ) {
1212           ClassDescriptor localCD = iterator.next();
1213           if (!localCD.equals(priorityCD)) {
1214             Set<Location> localLocSet = cd2locSet.get(localCD);
1215             Set<String> LocalLocIdSet = new HashSet<String>();
1216
1217             for (Iterator<Location> locIterator = localLocSet.iterator(); locIterator.hasNext(); ) {
1218               Location locElement = locIterator.next();
1219               LocalLocIdSet.add(locElement.getLocIdentifier());
1220             }
1221
1222             Lattice<String> localOrder = (Lattice<String>)state.getCd2LocationOrder().get(localCD);
1223             Location localGLBLoc = new Location(localCD, localOrder.getGLB(LocalLocIdSet));
1224             glbCompLoc.addLocation(localGLBLoc);
1225           }
1226         }
1227       } else {
1228         // if priority glb loc is lower than all of input loc
1229         // assign top location to the rest of loc element
1230
1231         for (Iterator<ClassDescriptor> iterator = cd2locSet.keySet().iterator(); iterator.hasNext(); ) {
1232           ClassDescriptor localCD = iterator.next();
1233           if (!localCD.equals(priorityCD)) {
1234             Location localGLBLoc = Location.createTopLocation(localCD);
1235             glbCompLoc.addLocation(localGLBLoc);
1236           }
1237
1238         }
1239
1240       }
1241
1242       return glbCompLoc;
1243
1244     }
1245
1246   }
1247
1248   class ComparisonResult {
1249
1250     public static final int GREATER = 0;
1251     public static final int EQUAL = 1;
1252     public static final int LESS = 2;
1253     int result;
1254
1255   }
1256
1257 }