1 /* 2 * Copyright 2016 Google Inc. All Rights Reserved. 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 com.google.turbine.binder.bound; 18 19 import com.google.common.collect.ImmutableList; 20 import com.google.common.collect.ImmutableMap; 21 import com.google.turbine.binder.sym.ClassSymbol; 22 import com.google.turbine.binder.sym.FieldSymbol; 23 import com.google.turbine.binder.sym.MethodSymbol; 24 import com.google.turbine.binder.sym.ParamSymbol; 25 import com.google.turbine.binder.sym.RecordComponentSymbol; 26 import com.google.turbine.binder.sym.TyVarSymbol; 27 import com.google.turbine.model.Const; 28 import com.google.turbine.model.TurbineFlag; 29 import com.google.turbine.tree.Tree; 30 import com.google.turbine.tree.Tree.MethDecl; 31 import com.google.turbine.type.AnnoInfo; 32 import com.google.turbine.type.Type; 33 import com.google.turbine.type.Type.IntersectionTy; 34 import com.google.turbine.type.Type.MethodTy; 35 import org.jspecify.annotations.Nullable; 36 37 /** A bound node that augments {@link HeaderBoundClass} with type information. */ 38 public interface TypeBoundClass extends HeaderBoundClass { 39 40 /** The super-class type. */ superClassType()41 @Nullable Type superClassType(); 42 43 /** Implemented interface types. */ interfaceTypes()44 ImmutableList<Type> interfaceTypes(); 45 46 /** The permitted direct subclasses. */ permits()47 ImmutableList<ClassSymbol> permits(); 48 typeParameterTypes()49 ImmutableMap<TyVarSymbol, TyVarInfo> typeParameterTypes(); 50 51 /** Declared fields. */ fields()52 ImmutableList<FieldInfo> fields(); 53 54 /** Declared methods. */ methods()55 ImmutableList<MethodInfo> methods(); 56 57 /** Record components. */ components()58 ImmutableList<RecordComponentInfo> components(); 59 60 /** 61 * Annotation metadata, e.g. from {@link java.lang.annotation.Target}, {@link 62 * java.lang.annotation.Retention}, and {@link java.lang.annotation.Repeatable}. 63 */ annotationMetadata()64 @Nullable AnnotationMetadata annotationMetadata(); 65 66 /** Declaration annotations. */ annotations()67 ImmutableList<AnnoInfo> annotations(); 68 69 /** A type parameter declaration. */ 70 class TyVarInfo { 71 private final IntersectionTy upperBound; 72 private final @Nullable Type lowerBound; 73 private final ImmutableList<AnnoInfo> annotations; 74 TyVarInfo( IntersectionTy upperBound, @Nullable Type lowerBound, ImmutableList<AnnoInfo> annotations)75 public TyVarInfo( 76 IntersectionTy upperBound, @Nullable Type lowerBound, ImmutableList<AnnoInfo> annotations) { 77 this.upperBound = upperBound; 78 if (lowerBound != null) { 79 throw new IllegalArgumentException("TODO(cushon): support lower bounds"); 80 } 81 this.lowerBound = lowerBound; 82 this.annotations = annotations; 83 } 84 85 /** The upper bound. */ upperBound()86 public IntersectionTy upperBound() { 87 return upperBound; 88 } 89 90 /** The lower bound. */ lowerBound()91 public @Nullable Type lowerBound() { 92 return lowerBound; 93 } 94 95 /** Type parameter declaration annotations. */ annotations()96 public ImmutableList<AnnoInfo> annotations() { 97 return annotations; 98 } 99 } 100 101 /** A field declaration. */ 102 class FieldInfo { 103 private final FieldSymbol sym; 104 private final Type type; 105 private final int access; 106 private final ImmutableList<AnnoInfo> annotations; 107 108 private final Tree.@Nullable VarDecl decl; 109 private final Const.@Nullable Value value; 110 FieldInfo( FieldSymbol sym, Type type, int access, ImmutableList<AnnoInfo> annotations, Tree.@Nullable VarDecl decl, Const.@Nullable Value value)111 public FieldInfo( 112 FieldSymbol sym, 113 Type type, 114 int access, 115 ImmutableList<AnnoInfo> annotations, 116 Tree.@Nullable VarDecl decl, 117 Const.@Nullable Value value) { 118 this.sym = sym; 119 this.type = type; 120 this.access = access; 121 this.annotations = annotations; 122 this.decl = decl; 123 this.value = value; 124 } 125 126 /** The field symbol. */ sym()127 public FieldSymbol sym() { 128 return sym; 129 } 130 131 /** The field name. */ name()132 public String name() { 133 return sym.name(); 134 } 135 136 /** The field type. */ type()137 public Type type() { 138 return type; 139 } 140 141 /** Access bits. */ access()142 public int access() { 143 return access; 144 } 145 146 /** The field's declaration. */ decl()147 public Tree.@Nullable VarDecl decl() { 148 return decl; 149 } 150 151 /** The constant field value. */ value()152 public Const.@Nullable Value value() { 153 return value; 154 } 155 156 /** Declaration annotations. */ annotations()157 public ImmutableList<AnnoInfo> annotations() { 158 return annotations; 159 } 160 } 161 162 /** A declared method. */ 163 class MethodInfo { 164 private final MethodSymbol sym; 165 private final ImmutableMap<TyVarSymbol, TyVarInfo> tyParams; 166 private final Type returnType; 167 private final ImmutableList<ParamInfo> parameters; 168 private final ImmutableList<Type> exceptions; 169 private final int access; 170 private final @Nullable Const defaultValue; 171 private final @Nullable MethDecl decl; 172 private final ImmutableList<AnnoInfo> annotations; 173 private final @Nullable ParamInfo receiver; 174 MethodInfo( MethodSymbol sym, ImmutableMap<TyVarSymbol, TyVarInfo> tyParams, Type returnType, ImmutableList<ParamInfo> parameters, ImmutableList<Type> exceptions, int access, @Nullable Const defaultValue, @Nullable MethDecl decl, ImmutableList<AnnoInfo> annotations, @Nullable ParamInfo receiver)175 public MethodInfo( 176 MethodSymbol sym, 177 ImmutableMap<TyVarSymbol, TyVarInfo> tyParams, 178 Type returnType, 179 ImmutableList<ParamInfo> parameters, 180 ImmutableList<Type> exceptions, 181 int access, 182 @Nullable Const defaultValue, 183 @Nullable MethDecl decl, 184 ImmutableList<AnnoInfo> annotations, 185 @Nullable ParamInfo receiver) { 186 this.sym = sym; 187 this.tyParams = tyParams; 188 this.returnType = returnType; 189 this.parameters = parameters; 190 this.exceptions = exceptions; 191 this.access = access; 192 this.defaultValue = defaultValue; 193 this.decl = decl; 194 this.annotations = annotations; 195 this.receiver = receiver; 196 } 197 198 /** The method symbol. */ sym()199 public MethodSymbol sym() { 200 return sym; 201 } 202 203 /** The method name. */ name()204 public String name() { 205 return sym.name(); 206 } 207 208 /** The type parameters */ tyParams()209 public ImmutableMap<TyVarSymbol, TyVarInfo> tyParams() { 210 return tyParams; 211 } 212 213 /** Type return type, possibly {#link Type#VOID}. */ returnType()214 public Type returnType() { 215 return returnType; 216 } 217 218 /** The formal parameters. */ parameters()219 public ImmutableList<ParamInfo> parameters() { 220 return parameters; 221 } 222 223 /** Thrown exceptions. */ exceptions()224 public ImmutableList<Type> exceptions() { 225 return exceptions; 226 } 227 228 /** Access bits. */ access()229 public int access() { 230 return access; 231 } 232 233 /** The default value of an annotation interface method. */ defaultValue()234 public @Nullable Const defaultValue() { 235 return defaultValue; 236 } 237 238 /** 239 * Returns true for annotation members with a default value. The default value may not have been 240 * bound yet, in which case {@link #defaultValue} may still return {@code null}. 241 */ hasDefaultValue()242 public boolean hasDefaultValue() { 243 return decl() != null ? decl().defaultValue().isPresent() : defaultValue() != null; 244 } 245 246 /** The declaration. */ decl()247 public @Nullable MethDecl decl() { 248 return decl; 249 } 250 251 /** Declaration annotations. */ annotations()252 public ImmutableList<AnnoInfo> annotations() { 253 return annotations; 254 } 255 256 /** Receiver parameter (see JLS 8.4.1), or {@code null}. */ receiver()257 public @Nullable ParamInfo receiver() { 258 return receiver; 259 } 260 asType()261 public MethodTy asType() { 262 return MethodTy.create( 263 tyParams.keySet(), 264 returnType, 265 receiver != null ? receiver.type() : null, 266 asTypes(parameters), 267 exceptions); 268 } 269 asTypes(ImmutableList<ParamInfo> parameters)270 private static ImmutableList<Type> asTypes(ImmutableList<ParamInfo> parameters) { 271 ImmutableList.Builder<Type> result = ImmutableList.builder(); 272 for (ParamInfo param : parameters) { 273 if (!param.synthetic()) { 274 result.add(param.type()); 275 } 276 } 277 return result.build(); 278 } 279 } 280 281 /** A formal parameter declaration. */ 282 class ParamInfo { 283 private final ParamSymbol sym; 284 private final Type type; 285 private final int access; 286 private final ImmutableList<AnnoInfo> annotations; 287 ParamInfo(ParamSymbol sym, Type type, ImmutableList<AnnoInfo> annotations, int access)288 public ParamInfo(ParamSymbol sym, Type type, ImmutableList<AnnoInfo> annotations, int access) { 289 this.sym = sym; 290 this.type = type; 291 this.access = access; 292 this.annotations = annotations; 293 } 294 295 /** The parameter's symbol. */ sym()296 public ParamSymbol sym() { 297 return sym; 298 } 299 300 /** The parameter type. */ type()301 public Type type() { 302 return type; 303 } 304 305 /** 306 * Returns true if the parameter is synthetic, e.g. the enclosing instance parameter in an inner 307 * class constructor. 308 */ synthetic()309 public boolean synthetic() { 310 return (access & (TurbineFlag.ACC_SYNTHETIC | TurbineFlag.ACC_MANDATED)) != 0; 311 } 312 313 /** Parameter annotations. */ annotations()314 public ImmutableList<AnnoInfo> annotations() { 315 return annotations; 316 } 317 318 /** The parameter's name. */ name()319 public String name() { 320 return sym.name(); 321 } 322 323 /** The parameter's modifiers. */ access()324 public int access() { 325 return access; 326 } 327 } 328 329 /** A record component. */ 330 class RecordComponentInfo { 331 private final RecordComponentSymbol sym; 332 private final Type type; 333 private final int access; 334 private final ImmutableList<AnnoInfo> annotations; 335 RecordComponentInfo( RecordComponentSymbol sym, Type type, ImmutableList<AnnoInfo> annotations, int access)336 public RecordComponentInfo( 337 RecordComponentSymbol sym, Type type, ImmutableList<AnnoInfo> annotations, int access) { 338 this.sym = sym; 339 this.type = type; 340 this.access = access; 341 this.annotations = annotations; 342 } 343 344 /** The record component's symbol. */ sym()345 public RecordComponentSymbol sym() { 346 return sym; 347 } 348 349 /** The record component type. */ type()350 public Type type() { 351 return type; 352 } 353 354 /** Record component annotations. */ annotations()355 public ImmutableList<AnnoInfo> annotations() { 356 return annotations; 357 } 358 359 /** The Record component's name. */ name()360 public String name() { 361 return sym.name(); 362 } 363 364 /** The Record component's modifiers. */ access()365 public int access() { 366 return access; 367 } 368 } 369 } 370