| /* |
| * Copyright 2016 Google Inc. All Rights Reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.turbine.binder.bound; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.turbine.binder.sym.FieldSymbol; |
| import com.google.turbine.binder.sym.MethodSymbol; |
| import com.google.turbine.binder.sym.ParamSymbol; |
| import com.google.turbine.binder.sym.TyVarSymbol; |
| import com.google.turbine.model.Const; |
| import com.google.turbine.model.TurbineFlag; |
| import com.google.turbine.tree.Tree; |
| import com.google.turbine.tree.Tree.MethDecl; |
| import com.google.turbine.type.AnnoInfo; |
| import com.google.turbine.type.Type; |
| import com.google.turbine.type.Type.IntersectionTy; |
| import com.google.turbine.type.Type.MethodTy; |
| import org.jspecify.nullness.Nullable; |
| |
| /** A bound node that augments {@link HeaderBoundClass} with type information. */ |
| public interface TypeBoundClass extends HeaderBoundClass { |
| |
| /** The super-class type. */ |
| @Nullable |
| Type superClassType(); |
| |
| /** Implemented interface types. */ |
| ImmutableList<Type> interfaceTypes(); |
| |
| ImmutableMap<TyVarSymbol, TyVarInfo> typeParameterTypes(); |
| |
| /** Declared fields. */ |
| ImmutableList<FieldInfo> fields(); |
| |
| /** Declared methods. */ |
| ImmutableList<MethodInfo> methods(); |
| |
| /** Record components. */ |
| ImmutableList<ParamInfo> components(); |
| |
| /** |
| * Annotation metadata, e.g. from {@link java.lang.annotation.Target}, {@link |
| * java.lang.annotation.Retention}, and {@link java.lang.annotation.Repeatable}. |
| */ |
| @Nullable |
| AnnotationMetadata annotationMetadata(); |
| |
| /** Declaration annotations. */ |
| ImmutableList<AnnoInfo> annotations(); |
| |
| /** A type parameter declaration. */ |
| class TyVarInfo { |
| private final IntersectionTy upperBound; |
| private final @Nullable Type lowerBound; |
| private final ImmutableList<AnnoInfo> annotations; |
| |
| public TyVarInfo( |
| IntersectionTy upperBound, @Nullable Type lowerBound, ImmutableList<AnnoInfo> annotations) { |
| this.upperBound = upperBound; |
| if (lowerBound != null) { |
| throw new IllegalArgumentException("TODO(cushon): support lower bounds"); |
| } |
| this.lowerBound = lowerBound; |
| this.annotations = annotations; |
| } |
| |
| /** The upper bound. */ |
| public IntersectionTy upperBound() { |
| return upperBound; |
| } |
| |
| /** The lower bound. */ |
| public @Nullable Type lowerBound() { |
| return lowerBound; |
| } |
| |
| /** Type parameter declaration annotations. */ |
| public ImmutableList<AnnoInfo> annotations() { |
| return annotations; |
| } |
| } |
| |
| /** A field declaration. */ |
| class FieldInfo { |
| private final FieldSymbol sym; |
| private final Type type; |
| private final int access; |
| private final ImmutableList<AnnoInfo> annotations; |
| |
| private final Tree.@Nullable VarDecl decl; |
| private final Const.@Nullable Value value; |
| |
| public FieldInfo( |
| FieldSymbol sym, |
| Type type, |
| int access, |
| ImmutableList<AnnoInfo> annotations, |
| Tree.@Nullable VarDecl decl, |
| Const.@Nullable Value value) { |
| this.sym = sym; |
| this.type = type; |
| this.access = access; |
| this.annotations = annotations; |
| this.decl = decl; |
| this.value = value; |
| } |
| |
| /** The field symbol. */ |
| public FieldSymbol sym() { |
| return sym; |
| } |
| |
| /** The field name. */ |
| public String name() { |
| return sym.name(); |
| } |
| |
| /** The field type. */ |
| public Type type() { |
| return type; |
| } |
| |
| /** Access bits. */ |
| public int access() { |
| return access; |
| } |
| |
| /** The field's declaration. */ |
| public Tree.@Nullable VarDecl decl() { |
| return decl; |
| } |
| |
| /** The constant field value. */ |
| public Const.@Nullable Value value() { |
| return value; |
| } |
| |
| /** Declaration annotations. */ |
| public ImmutableList<AnnoInfo> annotations() { |
| return annotations; |
| } |
| } |
| |
| /** A declared method. */ |
| class MethodInfo { |
| private final MethodSymbol sym; |
| private final ImmutableMap<TyVarSymbol, TyVarInfo> tyParams; |
| private final Type returnType; |
| private final ImmutableList<ParamInfo> parameters; |
| private final ImmutableList<Type> exceptions; |
| private final int access; |
| private final @Nullable Const defaultValue; |
| private final @Nullable MethDecl decl; |
| private final ImmutableList<AnnoInfo> annotations; |
| private final @Nullable ParamInfo receiver; |
| |
| public 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) { |
| this.sym = sym; |
| this.tyParams = tyParams; |
| this.returnType = returnType; |
| this.parameters = parameters; |
| this.exceptions = exceptions; |
| this.access = access; |
| this.defaultValue = defaultValue; |
| this.decl = decl; |
| this.annotations = annotations; |
| this.receiver = receiver; |
| } |
| |
| /** The method symbol. */ |
| public MethodSymbol sym() { |
| return sym; |
| } |
| |
| /** The method name. */ |
| public String name() { |
| return sym.name(); |
| } |
| |
| /** The type parameters */ |
| public ImmutableMap<TyVarSymbol, TyVarInfo> tyParams() { |
| return tyParams; |
| } |
| |
| /** Type return type, possibly {#link Type#VOID}. */ |
| public Type returnType() { |
| return returnType; |
| } |
| |
| /** The formal parameters. */ |
| public ImmutableList<ParamInfo> parameters() { |
| return parameters; |
| } |
| |
| /** Thrown exceptions. */ |
| public ImmutableList<Type> exceptions() { |
| return exceptions; |
| } |
| |
| /** Access bits. */ |
| public int access() { |
| return access; |
| } |
| |
| /** The default value of an annotation interface method. */ |
| public @Nullable Const defaultValue() { |
| return defaultValue; |
| } |
| |
| /** |
| * Returns true for annotation members with a default value. The default value may not have been |
| * bound yet, in which case {@link #defaultValue} may still return {@code null}. |
| */ |
| public boolean hasDefaultValue() { |
| return decl() != null ? decl().defaultValue().isPresent() : defaultValue() != null; |
| } |
| |
| /** The declaration. */ |
| public @Nullable MethDecl decl() { |
| return decl; |
| } |
| |
| /** Declaration annotations. */ |
| public ImmutableList<AnnoInfo> annotations() { |
| return annotations; |
| } |
| |
| /** Receiver parameter (see JLS 8.4.1), or {@code null}. */ |
| public @Nullable ParamInfo receiver() { |
| return receiver; |
| } |
| |
| public MethodTy asType() { |
| return MethodTy.create( |
| tyParams.keySet(), |
| returnType, |
| receiver != null ? receiver.type() : null, |
| asTypes(parameters), |
| exceptions); |
| } |
| |
| private static ImmutableList<Type> asTypes(ImmutableList<ParamInfo> parameters) { |
| ImmutableList.Builder<Type> result = ImmutableList.builder(); |
| for (ParamInfo param : parameters) { |
| if (!param.synthetic()) { |
| result.add(param.type()); |
| } |
| } |
| return result.build(); |
| } |
| } |
| |
| /** A formal parameter declaration. */ |
| class ParamInfo { |
| private final ParamSymbol sym; |
| private final Type type; |
| private final int access; |
| private final ImmutableList<AnnoInfo> annotations; |
| |
| public ParamInfo(ParamSymbol sym, Type type, ImmutableList<AnnoInfo> annotations, int access) { |
| this.sym = sym; |
| this.type = type; |
| this.access = access; |
| this.annotations = annotations; |
| } |
| |
| /** The parameter's symbol. */ |
| public ParamSymbol sym() { |
| return sym; |
| } |
| |
| /** The parameter type. */ |
| public Type type() { |
| return type; |
| } |
| |
| /** |
| * Returns true if the parameter is synthetic, e.g. the enclosing instance parameter in an inner |
| * class constructor. |
| */ |
| public boolean synthetic() { |
| return (access & (TurbineFlag.ACC_SYNTHETIC | TurbineFlag.ACC_MANDATED)) != 0; |
| } |
| |
| /** Parameter annotations. */ |
| public ImmutableList<AnnoInfo> annotations() { |
| return annotations; |
| } |
| |
| /** The parameter's name. */ |
| public String name() { |
| return sym.name(); |
| } |
| |
| /** The parameter's modifiers. */ |
| public int access() { |
| return access; |
| } |
| } |
| } |