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