• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
3  * Copyright (C) 2011, 2013-2016 The JavaParser Team.
4  *
5  * This file is part of JavaParser.
6  *
7  * JavaParser can be used either under the terms of
8  * a) the GNU Lesser General Public License as published by
9  *     the Free Software Foundation, either version 3 of the License, or
10  *     (at your option) any later version.
11  * b) the terms of the Apache License
12  *
13  * You should have received a copy of both licenses in LICENCE.LGPL and
14  * LICENCE.APACHE. Please refer to those files for details.
15  *
16  * JavaParser is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License for more details.
20  */
21 
22 package com.github.javaparser.resolution.types;
23 
24 import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
25 
26 import java.util.List;
27 import java.util.Map;
28 
29 /**
30  * A wildcard can be:
31  * - unbounded (?)
32  * - have a lower bound (? super Number)
33  * - have an upper bound (? extends Number)
34  * It is not possible to have both a lower and an upper bound at the same time.
35  *
36  * @author Federico Tomassetti
37  */
38 public class ResolvedWildcard implements ResolvedType {
39 
40     public static ResolvedWildcard UNBOUNDED = new ResolvedWildcard(null, null);
41 
42     private BoundType type;
43     private ResolvedType boundedType;
44 
ResolvedWildcard(BoundType type, ResolvedType boundedType)45     private ResolvedWildcard(BoundType type, ResolvedType boundedType) {
46         if (type == null && boundedType != null) {
47             throw new IllegalArgumentException();
48         }
49         if (type != null && boundedType == null) {
50             throw new IllegalArgumentException();
51         }
52         this.type = type;
53         this.boundedType = boundedType;
54     }
55 
superBound(ResolvedType type)56     public static ResolvedWildcard superBound(ResolvedType type) {
57         return new ResolvedWildcard(BoundType.SUPER, type);
58     }
59 
extendsBound(ResolvedType type)60     public static ResolvedWildcard extendsBound(ResolvedType type) {
61         return new ResolvedWildcard(BoundType.EXTENDS, type);
62     }
63 
64     @Override
toString()65     public String toString() {
66         return "WildcardUsage{" +
67                 "type=" + type +
68                 ", boundedType=" + boundedType +
69                 '}';
70     }
71 
isWildcard()72     public boolean isWildcard() {
73         return true;
74     }
75 
asWildcard()76     public ResolvedWildcard asWildcard() {
77         return this;
78     }
79 
80     @Override
equals(Object o)81     public boolean equals(Object o) {
82         if (this == o) return true;
83         if (!(o instanceof ResolvedWildcard)) return false;
84 
85         ResolvedWildcard that = (ResolvedWildcard) o;
86 
87         if (boundedType != null ? !boundedType.equals(that.boundedType) : that.boundedType != null) return false;
88         if (type != that.type) return false;
89 
90         return true;
91     }
92 
93     @Override
hashCode()94     public int hashCode() {
95         int result = type != null ? type.hashCode() : 0;
96         result = 31 * result + (boundedType != null ? boundedType.hashCode() : 0);
97         return result;
98     }
99 
100     @Override
describe()101     public String describe() {
102         if (type == null) {
103             return "?";
104         } else if (type == BoundType.SUPER) {
105             return "? super " + boundedType.describe();
106         } else if (type == BoundType.EXTENDS) {
107             return "? extends " + boundedType.describe();
108         } else {
109             throw new UnsupportedOperationException();
110         }
111     }
112 
isSuper()113     public boolean isSuper() {
114         return type == BoundType.SUPER;
115     }
116 
isExtends()117     public boolean isExtends() {
118         return type == BoundType.EXTENDS;
119     }
120 
isBounded()121     public boolean isBounded() {
122         return isSuper() || isExtends();
123     }
124 
getBoundedType()125     public ResolvedType getBoundedType() {
126         if (boundedType == null) {
127             throw new IllegalStateException();
128         }
129         return boundedType;
130     }
131 
132     @Override
isAssignableBy(ResolvedType other)133     public boolean isAssignableBy(ResolvedType other) {
134         if (boundedType == null) {
135             //return other.isReferenceType() && other.asReferenceType().getQualifiedName().equals(Object.class.getCanonicalName());
136             return false;
137         } else if (type == BoundType.SUPER) {
138             return boundedType.isAssignableBy(other);
139         } else if (type == BoundType.EXTENDS) {
140             return false;
141         } else {
142             throw new RuntimeException();
143         }
144     }
145 
146     @Override
replaceTypeVariables(ResolvedTypeParameterDeclaration tpToReplace, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes)147     public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tpToReplace, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
148         if (replaced == null) {
149             throw new IllegalArgumentException();
150         }
151         if (boundedType == null) {
152             return this;
153         }
154         ResolvedType boundedTypeReplaced = boundedType.replaceTypeVariables(tpToReplace, replaced, inferredTypes);
155         if (boundedTypeReplaced == null) {
156             throw new RuntimeException();
157         }
158         if (boundedTypeReplaced != boundedType) {
159             return new ResolvedWildcard(type, boundedTypeReplaced);
160         } else {
161             return this;
162         }
163     }
164 
165     @Override
mention(List<ResolvedTypeParameterDeclaration> typeParameters)166     public boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) {
167         return boundedType != null && boundedType.mention(typeParameters);
168     }
169 
isUpperBounded()170     public boolean isUpperBounded() {
171         return isSuper();
172     }
173 
isLowerBounded()174     public boolean isLowerBounded() {
175         return isExtends();
176     }
177 
178     public enum BoundType {
179         SUPER,
180         EXTENDS
181     }
182 
183 }
184