KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > generics > ParametricStructureComputer


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jdt.internal.corext.refactoring.generics;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Arrays JavaDoc;
16 import java.util.Collection JavaDoc;
17 import java.util.Collections JavaDoc;
18 import java.util.HashSet JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Stack JavaDoc;
22
23 import org.eclipse.core.runtime.Assert;
24
25 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.GenericType;
26 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TType;
27 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.CollectionElementVariable2;
28 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ConstraintVariable2;
29 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.SubTypeConstraint2;
30 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.TypeEquivalenceSet;
31
32
33 public class ParametricStructureComputer {
34     public static class ParametricStructure {
35         
36         public static final ParametricStructure NONE= new ParametricStructure();
37         
38         private final GenericType fBase;
39         private final ParametricStructure[] fParameters;
40         
41         public ParametricStructure(GenericType base) {
42             if (base == null)
43                 throw new NullPointerException JavaDoc();
44             fBase= base;
45             fParameters= new ParametricStructure[base.getTypeParameters().length];
46         }
47
48         private ParametricStructure() {
49             fBase= null;
50             fParameters= new ParametricStructure[0];
51         }
52
53         public ParametricStructure[] getParameters() {
54             return fParameters;
55         }
56         
57         public GenericType getBase() {
58             return fBase;
59         }
60         
61         public String JavaDoc toString() {
62             if (this == NONE)
63                 return "NONE"; //$NON-NLS-1$
64
else
65                 return "ParamStructure " + fBase.toString() + '<' + Arrays.asList(fParameters) + '>'; //$NON-NLS-1$
66
}
67     }
68     
69     
70     private static final boolean DEBUG_INITIALIZATION= false;
71     
72     /**
73      * Maps each ConstraintVariable2 onto an IType that is either an instance
74      * of AbstractTypeParameter, if the ConstraintVariable2 cannot possibly
75      * refer to a parametric type, or an instance of ParametricStructure with
76      * the appropriate sub-structure (if any) if it can.
77      */

78     private final ElementStructureEnvironment fElemStructureEnv= new ElementStructureEnvironment();
79     private final ConstraintVariable2[] fAllConstraintVariables;
80     private InferTypeArgumentsTCModel fTCModel;
81
82     public ParametricStructureComputer(ConstraintVariable2[] allConstraintVariables, InferTypeArgumentsTCModel tcModel) {
83         fAllConstraintVariables= allConstraintVariables;
84         fTCModel= tcModel;
85     }
86     
87     public ElementStructureEnvironment getElemStructureEnv() {
88         return fElemStructureEnv;
89     }
90     
91     private void dumpContainerStructure() {
92         System.out.println("\n*** Container Structure: ***\n"); //$NON-NLS-1$
93
for (int i= 0; i < fAllConstraintVariables.length; i++) {
94             ConstraintVariable2 v= fAllConstraintVariables[i];
95             if (elemStructure(v) != null && !(elemStructure(v) == ParametricStructure.NONE))
96                 System.out.println("elemStructure(" + v.toString() + ") = " + elemStructure(v)); //$NON-NLS-1$ //$NON-NLS-2$
97
}
98         System.out.println();
99     }
100
101     
102     private Stack JavaDoc/*<ConstraintVariable2>*/ fWorkList2= new Stack JavaDoc();
103
104
105     private void setStructureAndPush(ConstraintVariable2 v, ParametricStructure structure) {
106         setElemStructure(v, structure);
107         fWorkList2.push(v);
108     }
109     
110     //TODO hard-wired to collections
111
private void initializeContainerStructure(){
112         if (DEBUG_INITIALIZATION)
113             System.out.println(" *** Seeding container structure ***"); //$NON-NLS-1$
114
for (int i= 0; i < fAllConstraintVariables.length; i++) {
115             ConstraintVariable2 v= fAllConstraintVariables[i];
116             TType varType= declaredTypeOf(v);
117
118             if (varType != null) {
119                 // rmf 11/30/2004 - Added isUnmodifiableFieldOrMethod() test to
120
// avoid unifying element types of container actual arguments
121
// with formal arguments of binary methods, to permit passing
122
// List<String> to a binary method taking a raw List.
123
if (isParametricType(varType) && !isUnmodifiableFieldOrMethod(v)) {
124                     if (DEBUG_INITIALIZATION) System.out.println("Entity has container structure: " + v); //$NON-NLS-1$
125
setStructureAndPush(v, newParametricType(varType));
126                 } else if (varType != null && !mightBeParametric(varType)) {
127                     // Not a supertype of any container type - can't have container structure
128
if (DEBUG_INITIALIZATION) System.out.println("Entity DOES NOT have container structure: " + v); //$NON-NLS-1$
129
setStructureAndPush(v, ParametricStructure.NONE);
130                 }
131                 // else we're not sure yet whether this has container structure
132
} else {
133 // TType exprType= v.getType(); // TODO: always null!
134
//
135
// if (isArrayAccess(v)) {
136
// if (DEBUG_INITIALIZATION) System.out.println("Entity DOES NOT have container structure: " + v);
137
// setStructureAndPush(v, NO_STRUCTURE); // definitely not container structure, Java 1.5 says no generics inside arrays
138
// } else if (isParametricType(exprType)) {
139
// if (DEBUG_INITIALIZATION) System.out.println("Entity has container structure: " + v);
140
// setStructureAndPush(v, newParametricType(exprType));
141
// } else if (exprType != null && !mightBeParametric(exprType)) {
142
// // Not a supertype of any container type - can't have container structure
143
// if (DEBUG_INITIALIZATION) System.out.println("Entity DOES NOT have container structure: " + v);
144
// setStructureAndPush(v, NO_STRUCTURE);
145
// }
146

147                 // TODO Markus: the following just updates the set of child element variables of the parent variable of 'v'.
148
// You already maintain this information automatically, so the code below is not needed...
149
// if (v instanceof CollectionElementVariable2) {
150
// CollectionElementVariable2 ev= (CollectionElementVariable2) v;
151
// int idx= ev.getDeclarationTypeVariableIndex(); //TODO : INDEX IS -1 IF THE TYPE VARIABLE COMES FROM A SUPERTYPE!!!
152
//
153
// Collection/*<ConstraintVariable2>*/ vars= fTCModel.getElementVariables(ev).values();
154
//
155
// if (vars == null) vars= new ConstraintVariable2[ev.getNumContainerTypeParams()];
156
// vars[idx]= ev;
157
// fVariableElementEnv.setElementVariables(ev.getParentConstraintVariable(), vars);
158
// }
159
// else we're not sure yet whether this has container structure
160
}
161         }
162         // Every variable v in fAllVariables is now in one of 3 states:
163
// - elemStructure(v) == some parametric type: definitely container structure, but we may not know the sub-structure yet
164
// - elemStructure(v) == some AbstractTypeParameter: definitely not container structure
165
// - elemStructure(v) == null: we know nothing yet about its structure
166
}
167
168     protected static TType declaredTypeOf(ConstraintVariable2 cv) {
169         //TODO: record original type of CollectionElementVariable2 iff source already had type parameter
170
return cv.getType();
171         
172 // if (v instanceof ContextualExpressionVariable) {
173
// ContextualExpressionVariable ev= (ContextualExpressionVariable) v;
174
//
175
// return ev.getBinding();
176
// } else if (v instanceof ReturnTypeVariable) {
177
// ReturnTypeVariable rv= (ReturnTypeVariable) v;
178
//
179
// return rv.getBinding();
180
// } else if (v instanceof RawBindingVariable) {
181
// RawBindingVariable rv= (RawBindingVariable) v;
182
//
183
// return rv.getBinding();
184
// } else if (v instanceof ParameterTypeVariable) {
185
// ParameterTypeVariable pv= (ParameterTypeVariable) v;
186
//
187
// return pv.getBinding();
188
// } else
189
// return null;
190
}
191     
192     private boolean mightBeParametric(TType type) {
193         return isParametricType(type);//TODO check this is the only case?
194
}
195
196     private void computeContainerStructure() {
197         if (DEBUG_INITIALIZATION)
198             System.out.println("\n*** Computing Container Structure ***\n"); //$NON-NLS-1$
199

200         initializeContainerStructure();
201
202         if (DEBUG_INITIALIZATION)
203             dumpContainerStructure();
204
205         while (!fWorkList2.isEmpty()) {
206             ConstraintVariable2 v= (ConstraintVariable2) fWorkList2.pop();
207             List JavaDoc/*<ITypeConstraint>*/ usedIn= fTCModel.getUsedIn(v);
208             
209             for(Iterator JavaDoc/*<ITypeConstraint>*/ iter= usedIn.iterator(); iter.hasNext(); ) {
210                 SubTypeConstraint2 stc= (SubTypeConstraint2) iter.next();
211
212                 ConstraintVariable2 lhs= stc.getLeft();
213                 ConstraintVariable2 rhs= stc.getRight();
214
215                 unifyContainerStructure(lhs, rhs);
216             }
217             
218             TypeEquivalenceSet typeEquivalenceSet= v.getTypeEquivalenceSet();
219             if (typeEquivalenceSet != null) {
220                 ConstraintVariable2[] contributingVariables= typeEquivalenceSet.getContributingVariables();
221                 for (int i= 0; i + 1 < contributingVariables.length; i++) {
222                     ConstraintVariable2 first= contributingVariables[i];
223                     ConstraintVariable2 second= contributingVariables[i + 1];
224                     
225                     unifyContainerStructure(first, second);
226                 }
227             }
228         }
229         if (DEBUG_INITIALIZATION)
230             dumpContainerStructure();
231     }
232
233     private void unifyContainerStructure(ConstraintVariable2 lhs, ConstraintVariable2 rhs) {
234         // RMF 8/19/2004 - exclude propagation through unmodifiable fields/methods
235
if (isUnmodifiableFieldOrMethod(lhs) || isUnmodifiableFieldOrMethod(rhs))
236             return;
237
238         if (DEBUG_INITIALIZATION)
239             System.out.println("Examining constraint " + lhs + " {" + elemStructure(lhs) + "} <= " + rhs + " {" + elemStructure(rhs) + "}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
240

241         if (updateStructureOfVar(lhs, elemStructure(rhs), TypeOperator.SubType)) {
242             if (lhs instanceof CollectionElementVariable2)
243                 updateParentContainerStructureFrom((CollectionElementVariable2) lhs, rhs);
244             updateElementVarStructureFromParent(lhs);
245         }
246         if (updateStructureOfVar(rhs, elemStructure(lhs), TypeOperator.SuperType)) {
247             if (rhs instanceof CollectionElementVariable2)
248                 updateParentContainerStructureFrom((CollectionElementVariable2) rhs, lhs);
249             updateElementVarStructureFromParent(rhs);
250         }
251     }
252
253     private ParametricStructure newParametricType(TType varType) {
254         //TODO: create CollectionElementVariable2s if necessary?
255
GenericType genericType= (GenericType) varType.getTypeDeclaration();
256         return new ParametricStructure(genericType);
257     }
258
259     private boolean isUnmodifiableFieldOrMethod(ConstraintVariable2 v) {
260         return false; //TODO: find out whether it's declared in a binary type
261
}
262
263     private boolean isParametricType(TType type) {
264         return type.isParameterizedType()
265                 || type.isGenericType()
266                 || (type.isRawType() && type.getTypeDeclaration().isGenericType()) ;
267     }
268
269     /**
270      * Updates the structure of the i'th type parameter of the given ParametricStructure
271      * to be consistent with that of 'otherStructure'.
272      */

273     private boolean updateStructureOfIthParamFrom(ParametricStructure structure1, int i, ParametricStructure otherStructure) {
274         if ((otherStructure == null)) // no structure info to use to update 'structure1'
275
return false;
276
277         Assert.isTrue(structure1 != otherStructure, "updateStructureOfIthParamFrom(): attempt to unify ith param of a parametric type with itself!"); //$NON-NLS-1$
278

279         ParametricStructure param1= structure1.getParameters()[i];
280         boolean param1Unknown= (param1 == null);
281
282         if (param1Unknown) {
283             if (DEBUG_INITIALIZATION)
284                 System.out.println(" setting param " + i + " of " + structure1 + " to " + otherStructure); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
285
structure1.getParameters()[i]= otherStructure;
286             return true;
287         }
288
289         boolean paramStructured= !(param1 == ParametricStructure.NONE);
290         boolean otherStructured= !(otherStructure == ParametricStructure.NONE);
291
292         if (paramStructured && otherStructured) { // both parametric
293
// rmf 12/15/2004 - handle cases where different parametric types (e.g.
294
// List and Map) flow into the same place. If base types are different,
295
// conservatively make the type param of structure1 unstructured.
296
if (param1.getBase().equals(otherStructure.getBase()))
297                 return updateStructureOfType(param1, otherStructure);
298             else {
299                 structure1.getParameters()[i]= ParametricStructure.NONE;
300                 return true;
301             }
302         }
303
304         return false;
305     }
306
307     /**
308      * Updates the structure of any subsidiary element variables (if any) for
309      * the given ConstraintVariable2 (if it is in fact a container).
310      */

311     private void updateElementVarStructureFromParent(ConstraintVariable2 v) {
312         // Propagate structure from container variable to any subsidiary element variables
313
if (elemStructure(v) != ParametricStructure.NONE && fTCModel.getElementVariables(v).size() > 0) {
314             ParametricStructure t= elemStructure(v);
315             for(Iterator JavaDoc iterator=fTCModel.getElementVariables(v).values().iterator(); iterator.hasNext(); ) {
316                 CollectionElementVariable2 typeVar= (CollectionElementVariable2) iterator.next();
317                 int declarationTypeVariableIndex= typeVar.getDeclarationTypeVariableIndex();
318
319                 if (declarationTypeVariableIndex != CollectionElementVariable2.NOT_DECLARED_TYPE_VARIABLE_INDEX)
320                     updateStructureOfVar(typeVar, t.getParameters()[declarationTypeVariableIndex], TypeOperator.Equals);
321             }
322         }
323     }
324
325     /**
326      * Updates the structure of the parent container variable of the given
327      * CollectionElementVariable2 from the structure of 'v1'.
328      * @param elemVar
329      * @param v1
330      */

331     private void updateParentContainerStructureFrom(CollectionElementVariable2 elemVar, ConstraintVariable2 v1) {
332         ConstraintVariable2 elemContainer= elemVar.getParentConstraintVariable();
333
334         // This could be something that appears like it should have container
335
// structure, but doesn't, e.g., an array access for an array of containers
336
// (JDK 1.5 disallows arrays of parametric types). So if it doesn't have
337
// container structure, ignore it.
338
ParametricStructure elemContainerStructure= elemStructure(elemContainer);
339         if (elemContainerStructure == ParametricStructure.NONE)
340             return;
341
342         if (false) {
343             if (v1 instanceof CollectionElementVariable2) {
344                 // if v1's container no longer has structure, remove structure from elemContainer
345
CollectionElementVariable2 ev1= (CollectionElementVariable2) v1;
346                 ConstraintVariable2 v1Container= ev1.getParentConstraintVariable();
347
348                 if (elemStructure(v1Container) == ParametricStructure.NONE)
349                     setStructureAndPush(elemContainer, ParametricStructure.NONE);
350                 return;
351             }
352         }
353
354         if (elemContainerStructure == null) { // handle clone()
355
elemContainerStructure= newParametricType(elemContainer.getType());
356             setStructureAndPush(elemContainer, elemContainerStructure);
357         }
358         ParametricStructure v1Structure= elemStructure(v1);
359         int parmIdx= elemVar.getDeclarationTypeVariableIndex(); //TODO: index is NOT_DECLARED_TYPE_VARIABLE_INDEX if the type variable comes from a supertype!!!
360
if (parmIdx == CollectionElementVariable2.NOT_DECLARED_TYPE_VARIABLE_INDEX)
361             return; //TODO: ParametricStructure should use type variable keys instead of index
362

363         if (elemContainerStructure == v1Structure || containsSubStructure(v1Structure, elemContainerStructure)) { // avoid creating cyclic structure
364
if (!(elemStructure(elemVar) == ParametricStructure.NONE))
365                 setStructureAndPush(elemVar, ParametricStructure.NONE);
366             if (elemContainerStructure.getParameters()[parmIdx] == null) {
367                 elemContainerStructure.getParameters()[parmIdx]= ParametricStructure.NONE;
368                 fWorkList2.push(elemContainer);
369             }
370         } else if (updateStructureOfIthParamFrom(elemContainerStructure, parmIdx, v1Structure)) {
371             setStructureAndPush(elemVar, elemContainerStructure.getParameters()[parmIdx]);
372             fWorkList2.push(elemContainer);
373             if (DEBUG_INITIALIZATION)
374                 System.out.println(" updated structure of " + elemContainer + " to " + elemContainerStructure); //$NON-NLS-1$ //$NON-NLS-2$
375
}
376     }
377
378     private boolean containsSubStructure(ParametricStructure containingStructure, ParametricStructure subStructure) {
379         if (containingStructure == null)
380             return false;
381         
382         ParametricStructure[] parameters= containingStructure.getParameters();
383         for (int i= 0; i < parameters.length; i++) {
384             ParametricStructure parameter= parameters[i];
385             if (parameter == subStructure)
386                 return true;
387             else if (containsSubStructure(parameter, subStructure))
388                 return true;
389         }
390         return false;
391     }
392
393     /**
394      * Make type1's sub-structure at least as detailed as that of type2 by
395      * copying the structure of type2's parameters (or its parameters' parameters)
396      * into type1's parameters.
397      */

398     private boolean updateStructureOfType(ParametricStructure type1, ParametricStructure type2) {
399         if (type1 == null || type2 == null)
400             return false;
401
402         ParametricStructure[] parms1= type1.getParameters();
403         ParametricStructure[] parms2= type2.getParameters();
404         boolean someChange= false;
405
406         Assert.isTrue(parms1.length == parms2.length);
407
408         for(int i=0; i < parms1.length; i++) {
409             if (type1 == parms2[i]) { // avoid creating cyclic structures!
410
if (parms1[i] != ParametricStructure.NONE) {
411                     parms1[i]= ParametricStructure.NONE;
412                     someChange= true;
413                 }
414             } else if (updateStructureOfIthParamFrom(type1, i, parms2[i]))
415                 someChange= true;
416         }
417         return someChange;
418     }
419
420     static class TypeOperator {
421         // This could be a ConstraintOperator, if that had supertype
422
private final String JavaDoc fOp;
423         private TypeOperator(String JavaDoc op) {
424             fOp= op;
425         }
426         static public TypeOperator Equals= new TypeOperator("=^="); //$NON-NLS-1$
427
static public TypeOperator SubType= new TypeOperator("<="); //$NON-NLS-1$
428
static public TypeOperator SuperType= new TypeOperator("=>"); //$NON-NLS-1$
429
public String JavaDoc toString() {
430             return fOp;
431         }
432     }
433
434     /**
435      * Updates the structure of the given ConstraintVariable to be consistent
436      * with the structure of 'type2', in accordance with the given TypeOperator.
437      * If any changes are made, pushes the variable onto fWorkList2.
438      */

439     private boolean updateStructureOfVar(ConstraintVariable2 v, ParametricStructure type2, TypeOperator op) {
440         if ((type2 == null)) // no structure info to use to update 'v'
441
return false ;
442
443         ParametricStructure vStructure= elemStructure(v);
444         boolean vStructureUnknown= (vStructure == null);
445         boolean type2Structured= type2 != ParametricStructure.NONE;
446
447         if (vStructureUnknown) {
448             if (DEBUG_INITIALIZATION)
449                 System.out.println(" setting structure of " + v + " to " + type2); //$NON-NLS-1$ //$NON-NLS-2$
450
setStructureAndPush(v, type2);
451             return true;
452         }
453
454         boolean vStructured= vStructure != ParametricStructure.NONE;
455
456         if (vStructured && !type2Structured) {
457             // If the relation is <=, then it's ok for v to have structure while
458
// type2 doesn't. On the other hand, if the relation is >= or ==, 'v'
459
// must be made unstructured, since it cannot be structured and be a
460
// supertype (or equal to) something unstructured.
461
if (op == TypeOperator.Equals || op == TypeOperator.SuperType) {
462                 setStructureAndPush(v, type2);
463                 return true;
464             }
465         } else if (vStructured && type2Structured) { // both are structured (parametric types)
466
// rmf 12/15/2004 - handle cases where different parametric types (e.g.
467
// List and Map) flow into the same place. If base types are different,
468
// conservatively make v unstructured.
469
if (!vStructure.getBase().equals(type2.getBase())) { // different parametric types?
470
if (op == TypeOperator.SuperType) { // if (v >= other), v can't have parametric structure
471
setStructureAndPush(v, ParametricStructure.NONE);
472                     return true;
473                 }
474             } else if (updateStructureOfType(vStructure, type2)) {
475                 fWorkList2.push(v);
476                 return true;
477             }
478         }
479         return false;
480     }
481     
482     private void setElemStructure(ConstraintVariable2 v, ParametricStructure t) {
483         fElemStructureEnv.setElemStructure(v, t);
484     }
485
486     private ParametricStructure elemStructure(ConstraintVariable2 v) {
487         return fElemStructureEnv.elemStructure(v);
488     }
489
490     public Collection JavaDoc/*<CollectionElementVariable2>*/ createElemConstraintVariables() {
491         Collection JavaDoc newVars= new HashSet JavaDoc();
492
493         computeContainerStructure();
494
495         if (DEBUG_INITIALIZATION)
496             System.out.println("\n*** Creating Element Variables: ***\n"); //$NON-NLS-1$
497

498         for(int i= 0; i < fAllConstraintVariables.length; i++) {
499             newVars.addAll(createVariablesFor(fAllConstraintVariables[i]));
500         }
501
502 // // rmf 12/1/2004 - Add all the non-binary created vars to candidates for
503
// // rewriting; handles the case where a derived class overrides nothing
504
// // and therefore no constraint explicitly ties that class' type parameters
505
// // to anything else. Without what follows, the only variables that go into
506
// // the candidate list are those that appear in constraints.
507
// for(Iterator iter= newVars.iterator(); iter.hasNext(); ) {
508
// CollectionElementVariable2 v= (CollectionElementVariable2) iter.next();
509
//
510
// if (!isUnmodifiableFieldOrMethod(v.getParentConstraintVariable()))
511
// fCandidateVariables.add(v);
512
// }
513
//
514
// fAllConstraintVariables.addAll(newVars);
515
return newVars;
516     }
517
518     private Collection JavaDoc/*ConstraintVariable2*/ createVariablesFor(ConstraintVariable2 v) {
519         ParametricStructure t= elemStructure(v);
520
521         if (t == null || t == ParametricStructure.NONE)
522             return Collections.EMPTY_LIST;
523
524         ParametricStructure parmType= t;
525         TType base = parmType.getBase();
526         if (isParametricType(base)) {
527             return createAndInitVars(v, parmType);
528         }
529         throw new IllegalStateException JavaDoc("Attempt to create element variables for parametric variable of unknown type: " + parmType); //$NON-NLS-1$
530
}
531
532     private Collection JavaDoc/*<ConstraintVariable2>*/ getElementVariables(GenericType base, ConstraintVariable2 parent) {
533         fTCModel.makeElementVariables(parent, base);
534         return fTCModel.getElementVariables(parent).values();
535     }
536
537     private Collection JavaDoc/*ConstraintVariable2*/ createAndInitVars(ConstraintVariable2 v, ParametricStructure parmType) {
538 //TODO (->): in InferTypeArgumentsConstraintsSolver#createInitialEstimate(..)
539
//-> fTypeEstimates.setEstimateOf(v, SubTypesOfSingleton.create(ParametricStructure.getBaseContainerType(parmType.getBase(), sHierarchy)));
540
Collection JavaDoc/*<ConstraintVariable2>*/ elementVars= getElementVariables(parmType.getBase(), v);
541 //-> setNewTypeParamEstimateForEach(elementVars);
542
Collection JavaDoc result= createVars(elementVars, parmType.getParameters());
543         return result;
544     }
545     
546     private Collection JavaDoc/*ConstraintVariable2*/ createVars(Collection JavaDoc/*ConstraintVariable2>*/ cvs, ParametricStructure[] parms) {
547         if (parms.length > 0) { // happens, e.g., for Properties (non-parametric)
548
// Assert.isTrue(cvs.size() == parms.length, "cvs.length==" + cvs.size() + " parms.length=" + parms.length); //assumption is wrong in presence of NOT_DECLARED_TYPE_VARIABLE_INDEX
549
for (Iterator JavaDoc iter= cvs.iterator(); iter.hasNext(); ) {
550                 CollectionElementVariable2 childVar= (CollectionElementVariable2) iter.next();
551                 int declarationTypeVariableIndex= childVar.getDeclarationTypeVariableIndex();
552
553                 if (declarationTypeVariableIndex != CollectionElementVariable2.NOT_DECLARED_TYPE_VARIABLE_INDEX)
554                     setElemStructure(childVar, parms[declarationTypeVariableIndex]);
555             }
556         } else {
557             for (Iterator JavaDoc iter= cvs.iterator(); iter.hasNext(); ) {
558                 CollectionElementVariable2 childVar= (CollectionElementVariable2) iter.next();
559                 int declarationTypeVariableIndex= childVar.getDeclarationTypeVariableIndex();
560
561                 if (declarationTypeVariableIndex != CollectionElementVariable2.NOT_DECLARED_TYPE_VARIABLE_INDEX)
562                     setElemStructure(childVar, ParametricStructure.NONE);
563             }
564         }
565         List JavaDoc result= new ArrayList JavaDoc(cvs.size() * 2);//roughly
566
for (Iterator JavaDoc iter= cvs.iterator(); iter.hasNext(); ) {
567             CollectionElementVariable2 childVar= (CollectionElementVariable2) iter.next();
568             int declarationTypeVariableIndex= childVar.getDeclarationTypeVariableIndex();
569
570             if (declarationTypeVariableIndex != CollectionElementVariable2.NOT_DECLARED_TYPE_VARIABLE_INDEX) {
571                 result.add(childVar);
572                 result.addAll(createVariablesFor(childVar));
573             }
574         }
575         return result;
576     }
577 }
578
Popular Tags