Source Code Cross Referenced for TypeVariableBinding.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » compiler » lookup » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.compiler.lookup 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.jdt.internal.compiler.lookup;
011:
012:        import org.eclipse.jdt.core.compiler.CharOperation;
013:        import org.eclipse.jdt.internal.compiler.ast.Wildcard;
014:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
015:
016:        /**
017:         * Binding for a type parameter, held by source/binary type or method.
018:         */
019:        public class TypeVariableBinding extends ReferenceBinding {
020:
021:            public Binding declaringElement; // binding of declaring type or method 
022:            public int rank; // declaration rank, can be used to match variable in parameterized type
023:
024:            /**
025:             * Denote the first explicit (binding) bound amongst the supertypes (from declaration in source)
026:             * If no superclass was specified, then it denotes the first superinterface, or null if none was specified.
027:             */
028:            public TypeBinding firstBound;
029:
030:            // actual resolved variable supertypes (if no superclass bound, then associated to Object)
031:            public ReferenceBinding super class;
032:            public ReferenceBinding[] super Interfaces;
033:            public char[] genericTypeSignature;
034:
035:            public TypeVariableBinding(char[] sourceName,
036:                    Binding declaringElement, int rank) {
037:                this .sourceName = sourceName;
038:                this .declaringElement = declaringElement;
039:                this .rank = rank;
040:                this .modifiers = ClassFileConstants.AccPublic
041:                        | ExtraCompilerModifiers.AccGenericSignature; // treat type var as public
042:                this .tagBits |= TagBits.HasTypeVariable;
043:            }
044:
045:            public int kind() {
046:                return TYPE_PARAMETER;
047:            }
048:
049:            /**
050:             * Returns true if the argument type satisfies all bounds of the type parameter
051:             */
052:            public int boundCheck(Substitution substitution,
053:                    TypeBinding argumentType) {
054:
055:                if (argumentType == TypeBinding.NULL || argumentType == this )
056:                    return TypeConstants.OK;
057:                boolean hasSubstitution = substitution != null;
058:                if (!(argumentType instanceof  ReferenceBinding || argumentType
059:                        .isArrayType()))
060:                    return TypeConstants.MISMATCH;
061:                // special case for re-entrant source types (selection, code assist, etc)...
062:                // can request additional types during hierarchy walk that are found as source types that also 'need' to connect their hierarchy
063:                if (this .super class == null)
064:                    return TypeConstants.OK;
065:
066:                if (argumentType.isWildcard()
067:                        && !argumentType.isIntersectionType()) {
068:                    WildcardBinding wildcard = (WildcardBinding) argumentType;
069:                    switch (wildcard.boundKind) {
070:                    case Wildcard.EXTENDS:
071:                        TypeBinding wildcardBound = wildcard.bound;
072:                        if (wildcardBound == this )
073:                            return TypeConstants.OK;
074:                        ReferenceBinding super classBound = hasSubstitution ? (ReferenceBinding) Scope
075:                                .substitute(substitution, this .super class)
076:                                : this .super class;
077:                        boolean isArrayBound = wildcardBound.isArrayType();
078:                        if (!wildcardBound.isInterface()) {
079:                            if (super classBound.id != TypeIds.T_JavaLangObject) {
080:                                if (isArrayBound) {
081:                                    if (!wildcardBound
082:                                            .isCompatibleWith(super classBound))
083:                                        return TypeConstants.MISMATCH;
084:                                } else {
085:                                    TypeBinding match = wildcardBound
086:                                            .findSuperTypeWithSameErasure(super classBound);
087:                                    if (match != null) {
088:                                        if (!match
089:                                                .isIntersectingWith(super classBound)) {
090:                                            return TypeConstants.MISMATCH;
091:                                        }
092:                                    } else {
093:                                        match = super classBound
094:                                                .findSuperTypeWithSameErasure(wildcardBound);
095:                                        if (match != null) {
096:                                            if (!match
097:                                                    .isIntersectingWith(wildcardBound)) {
098:                                                return TypeConstants.MISMATCH;
099:                                            }
100:                                        } else {
101:                                            if (!wildcardBound.isTypeVariable()
102:                                                    && !super classBound
103:                                                            .isTypeVariable()) {
104:                                                return TypeConstants.MISMATCH;
105:                                            }
106:                                        }
107:                                    }
108:                                }
109:                            }
110:                        }
111:                        ReferenceBinding[] super InterfaceBounds = hasSubstitution ? Scope
112:                                .substitute(substitution, this .super Interfaces)
113:                                : this .super Interfaces;
114:                        int length = super InterfaceBounds.length;
115:                        boolean mustImplement = isArrayBound
116:                                || ((ReferenceBinding) wildcardBound).isFinal();
117:                        for (int i = 0; i < length; i++) {
118:                            TypeBinding super InterfaceBound = super InterfaceBounds[i];
119:                            if (isArrayBound) {
120:                                if (!wildcardBound
121:                                        .isCompatibleWith(super InterfaceBound))
122:                                    return TypeConstants.MISMATCH;
123:                            } else {
124:                                TypeBinding match = wildcardBound
125:                                        .findSuperTypeWithSameErasure(super InterfaceBound);
126:                                if (match != null) {
127:                                    if (!match
128:                                            .isIntersectingWith(super InterfaceBound)) {
129:                                        return TypeConstants.MISMATCH;
130:                                    }
131:                                } else if (mustImplement) {
132:                                    return TypeConstants.MISMATCH; // cannot be extended further to satisfy missing bounds
133:                                }
134:                            }
135:
136:                        }
137:                        break;
138:
139:                    case Wildcard.SUPER:
140:                        return boundCheck(substitution, wildcard.bound);
141:
142:                    case Wildcard.UNBOUND:
143:                        break;
144:                    }
145:                    return TypeConstants.OK;
146:                }
147:                boolean unchecked = false;
148:                if (this .super class.id != TypeIds.T_JavaLangObject) {
149:                    TypeBinding super Type = this .super class;
150:                    if (super Type != argumentType) { // check identity before substituting (104649)
151:                        TypeBinding substitutedSuperType = hasSubstitution ? Scope
152:                                .substitute(substitution, super Type)
153:                                : super Type;
154:                        if (!argumentType
155:                                .isCompatibleWith(substitutedSuperType)) {
156:                            return TypeConstants.MISMATCH;
157:                        }
158:                        TypeBinding match = argumentType
159:                                .findSuperTypeWithSameErasure(substitutedSuperType);
160:                        if (match != null) {
161:                            // Enum#RAW is not a substitute for <E extends Enum<E>> (86838)
162:                            if (match.isRawType()
163:                                    && substitutedSuperType
164:                                            .isBoundParameterizedType())
165:                                unchecked = true;
166:                        }
167:                    }
168:                }
169:                for (int i = 0, length = this .super Interfaces.length; i < length; i++) {
170:                    TypeBinding super Type = this .super Interfaces[i];
171:                    if (super Type != argumentType) { // check identity before substituting (104649)
172:                        TypeBinding substitutedSuperType = hasSubstitution ? Scope
173:                                .substitute(substitution, super Type)
174:                                : super Type;
175:                        if (!argumentType
176:                                .isCompatibleWith(substitutedSuperType)) {
177:                            return TypeConstants.MISMATCH;
178:                        }
179:                        TypeBinding match = argumentType
180:                                .findSuperTypeWithSameErasure(substitutedSuperType);
181:                        if (match != null) {
182:                            // Enum#RAW is not a substitute for <E extends Enum<E>> (86838)
183:                            if (match.isRawType()
184:                                    && substitutedSuperType
185:                                            .isBoundParameterizedType())
186:                                unchecked = true;
187:                        }
188:                    }
189:                }
190:                return unchecked ? TypeConstants.UNCHECKED : TypeConstants.OK;
191:            }
192:
193:            /**
194:             * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#canBeInstantiated()
195:             */
196:            public boolean canBeInstantiated() {
197:                return false;
198:            }
199:
200:            /**
201:             * Collect the substitutes into a map for certain type variables inside the receiver type
202:             * e.g.   Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
203:             * Constraints:
204:             *   A << F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_EXTENDS (1))
205:             *   A = F   corresponds to:      F.collectSubstitutes(..., A, ..., CONSTRAINT_EQUAL (0))
206:             *   A >> F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_SUPER (2))
207:             */
208:            public void collectSubstitutes(Scope scope, TypeBinding actualType,
209:                    InferenceContext inferenceContext, int constraint) {
210:
211:                //	only infer for type params of the generic method
212:                if (this .declaringElement != inferenceContext.genericMethod)
213:                    return;
214:
215:                // cannot infer anything from a null type
216:                switch (actualType.kind()) {
217:                case Binding.BASE_TYPE:
218:                    if (actualType == TypeBinding.NULL)
219:                        return;
220:                    TypeBinding boxedType = scope.environment()
221:                            .computeBoxingType(actualType);
222:                    if (boxedType == actualType)
223:                        return;
224:                    actualType = boxedType;
225:                    break;
226:                case Binding.WILDCARD_TYPE:
227:                    WildcardBinding actualWildcard = (WildcardBinding) actualType;
228:                    if (actualWildcard.otherBounds != null)
229:                        break; // intersection type
230:                    return; // wildcards are not true type expressions (JLS 15.12.2.7, p.453 2nd discussion)
231:                }
232:
233:                // reverse constraint, to reflect variable on rhs:   A << T --> T >: A
234:                int variableConstraint;
235:                switch (constraint) {
236:                case TypeConstants.CONSTRAINT_EQUAL:
237:                    variableConstraint = TypeConstants.CONSTRAINT_EQUAL;
238:                    break;
239:                case TypeConstants.CONSTRAINT_EXTENDS:
240:                    variableConstraint = TypeConstants.CONSTRAINT_SUPER;
241:                    break;
242:                default:
243:                    //case CONSTRAINT_SUPER :
244:                    variableConstraint = TypeConstants.CONSTRAINT_EXTENDS;
245:                    break;
246:                }
247:                inferenceContext.recordSubstitute(this , actualType,
248:                        variableConstraint);
249:            }
250:
251:            public char[] constantPoolName() { /* java/lang/Object */
252:                if (this .firstBound != null) {
253:                    return this .firstBound.constantPoolName();
254:                }
255:                return this .super class.constantPoolName(); // java/lang/Object
256:            }
257:
258:            /*
259:             * declaringUniqueKey : genericTypeSignature
260:             * p.X<T> { ... } --> Lp/X;:TT;
261:             * p.X { <T> void foo() {...} } --> Lp/X;.foo()V:TT;
262:             */
263:            public char[] computeUniqueKey(boolean isLeaf) {
264:                StringBuffer buffer = new StringBuffer();
265:                Binding declaring = this .declaringElement;
266:                if (!isLeaf && declaring.kind() == Binding.METHOD) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=97902
267:                    MethodBinding methodBinding = (MethodBinding) declaring;
268:                    ReferenceBinding declaringClass = methodBinding.declaringClass;
269:                    buffer.append(declaringClass
270:                            .computeUniqueKey(false/*not a leaf*/));
271:                    buffer.append(':');
272:                    MethodBinding[] methods = declaringClass.methods();
273:                    if (methods != null)
274:                        for (int i = 0, length = methods.length; i < length; i++) {
275:                            MethodBinding binding = methods[i];
276:                            if (binding == methodBinding) {
277:                                buffer.append(i);
278:                                break;
279:                            }
280:                        }
281:                } else {
282:                    buffer.append(declaring
283:                            .computeUniqueKey(false/*not a leaf*/));
284:                    buffer.append(':');
285:                }
286:                buffer.append(genericTypeSignature());
287:                int length = buffer.length();
288:                char[] uniqueKey = new char[length];
289:                buffer.getChars(0, length, uniqueKey, 0);
290:                return uniqueKey;
291:            }
292:
293:            /**
294:             * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#debugName()
295:             */
296:            public String debugName() {
297:                return new String(this .sourceName);
298:            }
299:
300:            public TypeBinding erasure() {
301:                if (this .firstBound != null) {
302:                    return this .firstBound.erasure();
303:                }
304:                return this .super class; // java/lang/Object
305:            }
306:
307:            /**
308:             * T::Ljava/util/Map;:Ljava/io/Serializable;
309:             * T:LY<TT;>
310:             */
311:            public char[] genericSignature() {
312:                StringBuffer sig = new StringBuffer(10);
313:                sig.append(this .sourceName).append(':');
314:                int interfaceLength = this .super Interfaces == null ? 0
315:                        : this .super Interfaces.length;
316:                if (interfaceLength == 0 || this .firstBound == this .super class) {
317:                    if (this .super class != null)
318:                        sig.append(this .super class.genericTypeSignature());
319:                }
320:                for (int i = 0; i < interfaceLength; i++) {
321:                    sig.append(':').append(
322:                            this .super Interfaces[i].genericTypeSignature());
323:                }
324:                int sigLength = sig.length();
325:                char[] genericSignature = new char[sigLength];
326:                sig.getChars(0, sigLength, genericSignature, 0);
327:                return genericSignature;
328:            }
329:
330:            /**
331:             * T::Ljava/util/Map;:Ljava/io/Serializable;
332:             * T:LY<TT;>
333:             */
334:            public char[] genericTypeSignature() {
335:                if (this .genericTypeSignature != null)
336:                    return this .genericTypeSignature;
337:                return this .genericTypeSignature = CharOperation.concat('T',
338:                        this .sourceName, ';');
339:            }
340:
341:            /**
342:             * Returns true if the type variable is directly bound to a given type
343:             */
344:            public boolean isErasureBoundTo(TypeBinding type) {
345:                if (this .super class.erasure() == type)
346:                    return true;
347:                for (int i = 0, length = this .super Interfaces.length; i < length; i++) {
348:                    if (this .super Interfaces[i].erasure() == type)
349:                        return true;
350:                }
351:                return false;
352:            }
353:
354:            /**
355:             * Returns true if the 2 variables are playing exact same role: they have
356:             * the same bounds, providing one is substituted with the other: <T1 extends
357:             * List<T1>> is interchangeable with <T2 extends List<T2>>.
358:             */
359:            public boolean isInterchangeableWith(
360:                    TypeVariableBinding otherVariable, Substitution substitute) {
361:                if (this  == otherVariable)
362:                    return true;
363:                int length = this .super Interfaces.length;
364:                if (length != otherVariable.super Interfaces.length)
365:                    return false;
366:
367:                if (this .super class != Scope.substitute(substitute,
368:                        otherVariable.super class))
369:                    return false;
370:
371:                next: for (int i = 0; i < length; i++) {
372:                    TypeBinding super Type = Scope.substitute(substitute,
373:                            otherVariable.super Interfaces[i]);
374:                    for (int j = 0; j < length; j++)
375:                        if (super Type == this .super Interfaces[j])
376:                            continue next;
377:                    return false; // not a match
378:                }
379:                return true;
380:            }
381:
382:            /**
383:             * Returns true if the type was declared as a type variable
384:             */
385:            public boolean isTypeVariable() {
386:                return true;
387:            }
388:
389:            /** 
390:             * Returns the original type variable for a given variable.
391:             * Only different from receiver for type variables of generic methods of parameterized types
392:             * e.g. X<U> {   <V1 extends U> U foo(V1)   } --> X<String> { <V2 extends String> String foo(V2)  }  
393:             *         and V2.original() --> V1
394:             */
395:            public TypeVariableBinding original() {
396:                if (this .declaringElement.kind() == Binding.METHOD) {
397:                    MethodBinding originalMethod = ((MethodBinding) this .declaringElement)
398:                            .original();
399:                    if (originalMethod != this .declaringElement) {
400:                        return originalMethod.typeVariables[this .rank];
401:                    }
402:                } else {
403:                    ReferenceBinding originalType = (ReferenceBinding) ((ReferenceBinding) this .declaringElement)
404:                            .erasure();
405:                    if (originalType != this .declaringElement) {
406:                        return originalType.typeVariables()[this .rank];
407:                    }
408:                }
409:                return this ;
410:            }
411:
412:            /**
413:             * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#readableName()
414:             */
415:            public char[] readableName() {
416:                return this .sourceName;
417:            }
418:
419:            ReferenceBinding resolve(LookupEnvironment environment) {
420:                if ((this .modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
421:                    return this ;
422:
423:                TypeBinding oldSuperclass = this .super class, oldFirstInterface = null;
424:                if (this .super class != null)
425:                    this .super class = BinaryTypeBinding.resolveType(
426:                            this .super class, environment, true);
427:                ReferenceBinding[] interfaces = this .super Interfaces;
428:                int length;
429:                if ((length = interfaces.length) != 0) {
430:                    oldFirstInterface = interfaces[0];
431:                    for (int i = length; --i >= 0;) {
432:                        interfaces[i] = BinaryTypeBinding.resolveType(
433:                                interfaces[i], environment, true);
434:                    }
435:                }
436:                // refresh the firstBound in case it changed
437:                if (this .firstBound != null) {
438:                    if (this .firstBound == oldSuperclass) {
439:                        this .firstBound = this .super class;
440:                    } else if (this .firstBound == oldFirstInterface) {
441:                        this .firstBound = interfaces[0];
442:                    }
443:                }
444:                this .modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
445:                return this ;
446:            }
447:
448:            /**
449:             * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#shortReadableName()
450:             */
451:            public char[] shortReadableName() {
452:                return this .readableName();
453:            }
454:
455:            public ReferenceBinding super class() {
456:                return super class;
457:            }
458:
459:            public ReferenceBinding[] super Interfaces() {
460:                return super Interfaces;
461:            }
462:
463:            /**
464:             * @see java.lang.Object#toString()
465:             */
466:            public String toString() {
467:                StringBuffer buffer = new StringBuffer(10);
468:                buffer.append('<').append(this .sourceName);//.append('[').append(this.rank).append(']');
469:                if (this .super class != null
470:                        && this .firstBound == this .super class) {
471:                    buffer
472:                            .append(" extends ").append(this .super class.debugName()); //$NON-NLS-1$
473:                }
474:                if (this .super Interfaces != null
475:                        && this .super Interfaces != Binding.NO_SUPERINTERFACES) {
476:                    if (this .firstBound != this .super class) {
477:                        buffer.append(" extends "); //$NON-NLS-1$
478:                    }
479:                    for (int i = 0, length = this .super Interfaces.length; i < length; i++) {
480:                        if (i > 0 || this .firstBound == this .super class) {
481:                            buffer.append(" & "); //$NON-NLS-1$
482:                        }
483:                        buffer.append(this .super Interfaces[i].debugName());
484:                    }
485:                }
486:                buffer.append('>');
487:                return buffer.toString();
488:            }
489:
490:            /**
491:             * Upper bound doesn't perform erasure
492:             */
493:            public TypeBinding upperBound() {
494:                if (this .firstBound != null) {
495:                    return this .firstBound;
496:                }
497:                return this .super class; // java/lang/Object
498:            }
499:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.