KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > lookup > InferenceContext


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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 package org.eclipse.jdt.internal.compiler.lookup;
12
13 /**
14  * Context used during type inference for a generic method invocation
15  */

16 public class InferenceContext {
17     
18     private TypeBinding[][][] collectedSubstitutes;
19     MethodBinding genericMethod;
20     int depth;
21     int status;
22     TypeBinding expectedType;
23     boolean hasExplicitExpectedType; // indicates whether the expectedType (if set) was explicit in code, or set by default
24
TypeBinding[] substitutes;
25     final static int FAILED = 1;
26     final static int RAW_SUBSTITUTION = 2;
27     
28 public InferenceContext(MethodBinding genericMethod) {
29     this.genericMethod = genericMethod;
30     TypeVariableBinding[] typeVariables = genericMethod.typeVariables;
31     int varLength = typeVariables.length;
32     this.collectedSubstitutes = new TypeBinding[varLength][3][];
33     this.substitutes = new TypeBinding[varLength];
34 }
35
36 public boolean checkRawSubstitution() {
37     // only at first level, during inference from arguments
38
if (depth > 0) return false;
39 // if (this.argumentIndex < 0 || this.depth != 0) {
40
// return false;
41
// }
42
this.status = RAW_SUBSTITUTION;
43     return true;
44 }
45
46 public TypeBinding[] getSubstitutes(TypeVariableBinding typeVariable, int constraint) {
47     return this.collectedSubstitutes[typeVariable.rank][constraint];
48 }
49
50 /**
51  * Returns true if any unresolved variable is detected, i.e. any variable is substituted with itself
52  */

53 public boolean hasUnresolvedTypeArgument() {
54     for (int i = 0, varLength = this.substitutes.length; i <varLength; i++) {
55         if (this.substitutes[i] == null) {
56             return true;
57         }
58     }
59     return false;
60 }
61
62 public void recordSubstitute(TypeVariableBinding typeVariable, TypeBinding actualType, int constraint) {
63     TypeBinding[][] variableSubstitutes = this.collectedSubstitutes[typeVariable.rank];
64     insertLoop: {
65         TypeBinding[] constraintSubstitutes = variableSubstitutes[constraint];
66         int length;
67         if (constraintSubstitutes == null) {
68             length = 0;
69             constraintSubstitutes = new TypeBinding[1];
70         } else {
71             length = constraintSubstitutes.length;
72             for (int i = 0; i < length; i++) {
73                 TypeBinding substitute = constraintSubstitutes[i];
74                 if (substitute == actualType) return; // already there
75
if (substitute == null) {
76                     constraintSubstitutes[i] = actualType;
77                     break insertLoop;
78                 }
79             }
80             // no free spot found, need to grow by one
81
System.arraycopy(constraintSubstitutes, 0, constraintSubstitutes = new TypeBinding[length+1], 0, length);
82         }
83         constraintSubstitutes[length] = actualType;
84         variableSubstitutes[constraint] = constraintSubstitutes;
85     }
86 }
87 public String JavaDoc toString() {
88     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(20);
89     buffer.append("InferenceContex for ");//$NON-NLS-1$
90
for (int i = 0, length = this.genericMethod.typeVariables.length; i < length; i++) {
91         buffer.append(this.genericMethod.typeVariables[i]);
92     }
93     buffer.append(this.genericMethod);
94     buffer.append("\n\t[status=");//$NON-NLS-1$
95
switch(this.status) {
96         case 0 :
97             buffer.append("ok]");//$NON-NLS-1$
98
break;
99         case FAILED :
100             buffer.append("failed]");//$NON-NLS-1$
101
break;
102         case RAW_SUBSTITUTION :
103             buffer.append("raw-subst]");//$NON-NLS-1$
104
break;
105     }
106     if (this.expectedType == null) {
107         buffer.append(" [expectedType=null]"); //$NON-NLS-1$
108
} else {
109         buffer.append(" [expectedType=").append(this.expectedType.shortReadableName()).append(']'); //$NON-NLS-1$
110
}
111     buffer.append(" [depth=").append(this.depth).append(']'); //$NON-NLS-1$
112
buffer.append("\n\t[collected={");//$NON-NLS-1$
113
for (int i = 0, length = this.collectedSubstitutes == null ? 0 : this.collectedSubstitutes.length; i < length; i++) {
114         TypeBinding[][] collected = this.collectedSubstitutes[i];
115         for (int j = TypeConstants.CONSTRAINT_EQUAL; j <= TypeConstants.CONSTRAINT_SUPER; j++) {
116             TypeBinding[] constraintCollected = collected[j];
117             if (constraintCollected != null) {
118                 for (int k = 0, clength = constraintCollected.length; k < clength; k++) {
119                     buffer.append("\n\t\t").append(this.genericMethod.typeVariables[i].sourceName); //$NON-NLS-1$
120
switch (j) {
121                         case TypeConstants.CONSTRAINT_EQUAL :
122                             buffer.append("="); //$NON-NLS-1$
123
break;
124                         case TypeConstants.CONSTRAINT_EXTENDS :
125                             buffer.append("<:"); //$NON-NLS-1$
126
break;
127                         case TypeConstants.CONSTRAINT_SUPER :
128                             buffer.append(">:"); //$NON-NLS-1$
129
break;
130                     }
131                     if (constraintCollected[k] != null) {
132                         buffer.append(constraintCollected[k].shortReadableName());
133                     }
134                 }
135             }
136         }
137     }
138     buffer.append("}]");//$NON-NLS-1$
139
buffer.append("\n\t[inferred=");//$NON-NLS-1$
140
int count = 0;
141     for (int i = 0, length = this.substitutes == null ? 0 : this.substitutes.length; i < length; i++) {
142         if (this.substitutes[i] == null) continue;
143         count++;
144         buffer.append('{').append(this.genericMethod.typeVariables[i].sourceName);
145         buffer.append("=").append(this.substitutes[i].shortReadableName()).append('}'); //$NON-NLS-1$
146
}
147     if (count == 0) buffer.append("{}"); //$NON-NLS-1$
148
buffer.append(']');
149     return buffer.toString();
150 }
151 }
152
Popular Tags