• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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