Skip to content

Commit

Permalink
Implement TypeElement.getRecordComponents
Browse files Browse the repository at this point in the history
  • Loading branch information
cushon authored and Javac Team committed Aug 26, 2024
1 parent 781a49a commit 3df8d68
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 20 deletions.
3 changes: 2 additions & 1 deletion java/com/google/turbine/processing/ModelFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import javax.lang.model.element.Element;
import javax.lang.model.element.RecordComponentElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.NoType;
import javax.lang.model.type.NullType;
Expand Down Expand Up @@ -270,7 +271,7 @@ VariableElement parameterElement(ParamSymbol sym) {
return paramCache.computeIfAbsent(sym, k -> new TurbineParameterElement(this, sym));
}

VariableElement recordComponentElement(RecordComponentSymbol sym) {
RecordComponentElement recordComponentElement(RecordComponentSymbol sym) {
return recordComponentCache.computeIfAbsent(
sym, k -> new TurbineRecordComponentElement(this, sym));
}
Expand Down
80 changes: 63 additions & 17 deletions java/com/google/turbine/processing/TurbineElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
Expand Down Expand Up @@ -63,6 +64,7 @@
import java.util.ArrayList;
import java.util.Deque;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -78,6 +80,7 @@
import javax.lang.model.element.Name;
import javax.lang.model.element.NestingKind;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.RecordComponentElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.element.VariableElement;
Expand Down Expand Up @@ -559,6 +562,48 @@ private boolean isAnnotationInherited(ClassSymbol sym) {
}
return false;
}

private final Supplier<ImmutableMap<RecordComponentSymbol, MethodSymbol>> recordAccessors =
memoize(
new Supplier<ImmutableMap<RecordComponentSymbol, MethodSymbol>>() {
@Override
public ImmutableMap<RecordComponentSymbol, MethodSymbol> get() {
Map<String, MethodSymbol> methods = new HashMap<>();
for (MethodInfo method : info().methods()) {
if (method.parameters().isEmpty()) {
methods.put(method.name(), method.sym());
}
}
ImmutableMap.Builder<RecordComponentSymbol, MethodSymbol> result =
ImmutableMap.builder();
for (RecordComponentInfo component : info().components()) {
result.put(component.sym(), methods.get(component.name()));
}
return result.buildOrThrow();
}
});

ExecutableElement recordAccessor(RecordComponentSymbol component) {
return factory.executableElement(recordAccessors.get().get(component));
}

private final Supplier<ImmutableList<RecordComponentElement>> recordComponents =
memoize(
new Supplier<ImmutableList<RecordComponentElement>>() {
@Override
public ImmutableList<RecordComponentElement> get() {
ImmutableList.Builder<RecordComponentElement> result = ImmutableList.builder();
for (RecordComponentInfo component : info().components()) {
result.add(factory.recordComponentElement(component.sym()));
}
return result.build();
}
});

@Override
public List<? extends RecordComponentElement> getRecordComponents() {
return recordComponents.get();
}
}

/** A {@link TypeParameterElement} implementation backed by a {@link TyVarSymbol}. */
Expand Down Expand Up @@ -1214,7 +1259,8 @@ protected ImmutableList<AnnoInfo> annos() {
}

/** A {@link VariableElement} implementation for a record info. */
static class TurbineRecordComponentElement extends TurbineElement implements VariableElement {
static class TurbineRecordComponentElement extends TurbineElement
implements RecordComponentElement {

@Override
public RecordComponentSymbol sym() {
Expand Down Expand Up @@ -1257,11 +1303,6 @@ public TurbineRecordComponentElement(ModelFactory factory, RecordComponentSymbol
this.sym = sym;
}

@Override
public Object getConstantValue() {
return null;
}

private final Supplier<TypeMirror> type =
memoize(
new Supplier<TypeMirror>() {
Expand All @@ -1278,18 +1319,9 @@ public TypeMirror asType() {

@Override
public ElementKind getKind() {
return RECORD_COMPONENT.get();
return ElementKind.RECORD_COMPONENT;
}

private static final Supplier<ElementKind> RECORD_COMPONENT =
Suppliers.memoize(
new Supplier<ElementKind>() {
@Override
public ElementKind get() {
return ElementKind.valueOf("RECORD_COMPONENT");
}
});

@Override
public Set<Modifier> getModifiers() {
return asModifierSet(ModifierOwner.PARAMETER, info().access());
Expand All @@ -1300,6 +1332,20 @@ public Name getSimpleName() {
return new TurbineName(sym.name());
}

private final Supplier<ExecutableElement> accessor =
Suppliers.memoize(
new Supplier<ExecutableElement>() {
@Override
public ExecutableElement get() {
return factory.typeElement(sym.owner()).recordAccessor(sym);
}
});

@Override
public ExecutableElement getAccessor() {
return accessor.get();
}

@Override
public Element getEnclosingElement() {
return factory.typeElement(sym.owner());
Expand All @@ -1312,7 +1358,7 @@ public List<? extends Element> getEnclosedElements() {

@Override
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
return v.visitVariable(this, p);
return v.visitRecordComponent(this, p);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.RecordComponentElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
Expand Down Expand Up @@ -819,6 +820,55 @@ public void missingAnnotationType() throws IOException {
assertThat(messages).containsExactly("A(ERROR)");
}

@SupportedAnnotationTypes("*")
public static class RecordComponentProcessor extends AbstractProcessor {
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {

ImmutableList<RecordComponentElement> components =
typesIn(roundEnv.getRootElements()).stream()
.flatMap(t -> t.getRecordComponents().stream())
.collect(toImmutableList());
for (RecordComponentElement c : components) {
processingEnv
.getMessager()
.printMessage(
Diagnostic.Kind.ERROR,
String.format(
"enclosing: %s, name: %s, accessor: %s %s",
c.getEnclosingElement(),
c.getSimpleName(),
c.getAccessor(),
c.getAccessor().getAnnotationMirrors()));
}
return false;
}
}

@Test
public void recordComponents() {
ImmutableList<Tree.CompUnit> units =
parseUnit(
"=== C.java ===", //
"abstract class C {",
" abstract int x();",
" abstract int t();",
"}",
"=== R.java ===", //
"record R(int x, @Deprecated int y) {",
"}");
TurbineError e = runProcessors(units, new RecordComponentProcessor());
assertThat(e.diagnostics().stream().map(d -> d.message()))
.containsExactly(
"enclosing: R, name: x, accessor: x() []",
"enclosing: R, name: y, accessor: y() [@java.lang.Deprecated]");
}

private TurbineError runProcessors(ImmutableList<Tree.CompUnit> units, Processor... processors) {
return assertThrows(
TurbineError.class,
Expand Down
21 changes: 19 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
<configuration>
<source>8</source>
<target>8</target>
<source>16</source>
<target>16</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-parameters</arg>
Expand All @@ -202,6 +202,23 @@
</path>
</annotationProcessorPaths>
</configuration>
<executions>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<compilerArgs combine.children="append">
<arg>--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
<arg>--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
<arg>--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
<arg>--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
</compilerArgs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
Expand Down

0 comments on commit 3df8d68

Please sign in to comment.