1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package signature.model.util; 18 19 import static signature.model.impl.Uninitialized.isInitialized; 20 import signature.model.IClassReference; 21 import signature.model.IGenericDeclaration; 22 import signature.model.ITypeReference; 23 import signature.model.ITypeVariableReference; 24 import signature.model.impl.SigArrayType; 25 import signature.model.impl.SigClassDefinition; 26 import signature.model.impl.SigClassReference; 27 import signature.model.impl.SigParameterizedType; 28 import signature.model.impl.SigTypeVariableDefinition; 29 import signature.model.impl.SigTypeVariableReference; 30 import signature.model.impl.SigWildcardType; 31 32 import java.util.HashMap; 33 import java.util.List; 34 import java.util.Map; 35 36 /** 37 * Pool and factory for all {@link ITypeReference} instances.<br> 38 * Note: This class is not thread save 39 */ 40 public class TypePool implements ITypeFactory { 41 42 /** 43 * Pool for all SigClass objects. Key format: "java.lang.Object", "a.b.C$D 44 */ 45 private Map<String, SigClassDefinition> classPool; 46 /** Pool for all SigTypeVariable objects */ 47 private Map<TypeVariableKey, SigTypeVariableDefinition> typeVariablePool; 48 49 public TypePool() { 50 classPool = new HashMap<String, SigClassDefinition>(); 51 typeVariablePool = 52 new HashMap<TypeVariableKey, SigTypeVariableDefinition>(); 53 } 54 55 public SigClassDefinition getClass(String packageName, String className) { 56 String key = packageName + "<>" + className; 57 SigClassDefinition clazz = classPool.get(key); 58 if (clazz == null) { 59 clazz = new SigClassDefinition(packageName, className); 60 classPool.put(key, clazz); 61 } 62 return clazz; 63 } 64 65 public IClassReference getClassReference(String packageName, 66 String className) { 67 return new SigClassReference(getClass(packageName, className)); 68 } 69 70 public SigArrayType getArrayType(ITypeReference componentType) { 71 assert componentType != null; 72 return new SigArrayType(componentType); 73 } 74 75 public SigParameterizedType getParameterizedType(ITypeReference ownerType, 76 IClassReference rawType, List<ITypeReference> typeArguments) { 77 assert rawType != null; 78 assert typeArguments != null; 79 return new SigParameterizedType(ownerType, rawType, typeArguments); 80 } 81 82 private static class TypeVariableKey { 83 private String name; 84 private IGenericDeclaration genericDeclaration; 85 86 public TypeVariableKey(String name, 87 IGenericDeclaration genericDeclaration) { 88 this.genericDeclaration = genericDeclaration; 89 this.name = name; 90 } 91 92 @Override 93 public int hashCode() { 94 final int prime = 31; 95 int result = 1; 96 result = prime * result + genericDeclaration.hashCode(); 97 result = prime * result + name.hashCode(); 98 return result; 99 } 100 101 @Override 102 public boolean equals(Object obj) { 103 TypeVariableKey other = (TypeVariableKey) obj; 104 if (genericDeclaration != other.genericDeclaration) { 105 return false; 106 } 107 if (!name.equals(other.name)) { 108 return false; 109 } 110 return true; 111 } 112 } 113 114 public boolean containsTypeVariableDefinition(String name, 115 IGenericDeclaration genericDeclaration) { 116 TypeVariableKey key = new TypeVariableKey(name, genericDeclaration); 117 return typeVariablePool.get(key) != null; 118 } 119 120 public SigTypeVariableDefinition getTypeVariable(String name, 121 IGenericDeclaration genericDeclaration) { 122 assert name != null; 123 assert genericDeclaration != null; 124 125 TypeVariableKey key = new TypeVariableKey(name, genericDeclaration); 126 SigTypeVariableDefinition sigTypeVariable = typeVariablePool.get(key); 127 if (sigTypeVariable == null) { 128 sigTypeVariable = new SigTypeVariableDefinition(name, 129 genericDeclaration); 130 typeVariablePool.put(key, sigTypeVariable); 131 } 132 return sigTypeVariable; 133 } 134 135 public ITypeVariableReference getTypeVariableReference(String name, 136 IGenericDeclaration genericDeclaration) { 137 return new SigTypeVariableReference(getTypeVariable(name, 138 genericDeclaration)); 139 } 140 141 public SigWildcardType getWildcardType(ITypeReference lowerBound, 142 List<ITypeReference> upperBounds) { 143 assert upperBounds != null; 144 145 SigWildcardType sigWildcardType = new SigWildcardType(lowerBound, 146 upperBounds); 147 return sigWildcardType; 148 } 149 150 public void replaceAllUninitialiezWithNull() { 151 for (SigClassDefinition clazz : classPool.values()) { 152 replaceUninitializedWithNull(clazz); 153 } 154 } 155 156 private static void replaceUninitializedWithNull( 157 SigClassDefinition clazz) { 158 if (clazz == null) { 159 return; 160 } 161 if (!isInitialized(clazz.getAnnotationFields())) { 162 clazz.setAnnotationFields(null); 163 } 164 if (!isInitialized(clazz.getAnnotations())) { 165 clazz.setAnnotations(null); 166 } 167 if (!isInitialized(clazz.getAnnotations())) { 168 clazz.setAnnotations(null); 169 } 170 if (!isInitialized(clazz.getConstructors())) { 171 clazz.setConstructors(null); 172 } 173 if (!isInitialized(clazz.getDeclaringClass())) { 174 clazz.setDeclaringClass(null); 175 } 176 177 if (!isInitialized(clazz.getEnumConstants())) { 178 clazz.setEnumConstants(null); 179 } 180 if (!isInitialized(clazz.getFields())) { 181 clazz.setFields(null); 182 } 183 if (!isInitialized(clazz.getInnerClasses())) { 184 clazz.setInnerClasses(null); 185 } 186 if (!isInitialized(clazz.getInterfaces())) { 187 clazz.setInterfaces(null); 188 } 189 if (!isInitialized(clazz.getKind())) { 190 clazz.setKind(null); 191 } 192 if (!isInitialized(clazz.getMethods())) { 193 clazz.setMethods(null); 194 } 195 if (!isInitialized(clazz.getModifiers())) { 196 clazz.setModifiers(null); 197 } 198 if (!isInitialized(clazz.getSuperClass())) { 199 clazz.setSuperClass(null); 200 } 201 if (!isInitialized(clazz.getTypeParameters())) { 202 clazz.setTypeParameters(null); 203 } 204 } 205 } 206