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