• 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.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