Skip to content

Commit

Permalink
Ensure that GwtSerialization support works in the presence of AutoVal…
Browse files Browse the repository at this point in the history
…ue extensions.

RELNOTES=GwtSerialization support now works in the presence of AutoValue extensions.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=205880303
  • Loading branch information
eamonnmcmanus authored and ronshapiro committed Jul 31, 2018
1 parent 588bc05 commit 9cc04ec
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 7 deletions.
16 changes: 10 additions & 6 deletions value/src/it/functional/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@
<artifactId>auto-value</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
<version>1.0-rc4</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.5-jre</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
Expand All @@ -60,12 +70,6 @@
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.5-jre</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-testlib</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright (C) 2018 Google, Inc.
*
* 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.auto.value.gwt;

import static java.util.stream.Collectors.joining;

import com.google.auto.service.AutoService;
import com.google.auto.value.extension.AutoValueExtension;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.escapevelocity.Template;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.TypeMirror;

/**
* An AutoValue extension that generates a subclass that does nothing useful.
*/
@AutoService(AutoValueExtension.class)
public class EmptyExtension extends AutoValueExtension {
// TODO(emcmanus): it is way too difficult to write a trivial extension. Problems we have here:
// (1) We have to generate a constructor that calls the superclass constructor, which means
// declaring the appropriate constructor parameters and then forwarding them to a super
// call.
// (2) We have to avoid generating variable names that are keywords (we append $ here
// to avoid that).
// (3) We have to concoct appropriate type parameter strings, for example
// final class AutoValue_Foo<K extends Comparable<K>, V> extends $AutoValue_Foo<K, V>.
// These problems show up with the template approach here, but also using JavaPoet as the
// Memoize extension does.
private static final ImmutableList<String> TEMPLATE_LINES =
ImmutableList.of(
"package $package;",
"\n",
"#if ($isFinal) final #end class ${className}${formalTypes}"
+ " extends ${classToExtend}${actualTypes} {\n",
" ${className}(",
" #foreach ($property in $properties.keySet())",
" $properties[$property].returnType ${property}$ #if ($foreach.hasNext) , #end",
" #end",
" ) {",
" super(",
" #foreach ($property in $properties.keySet())",
" ${property}$ #if ($foreach.hasNext) , #end",
" #end",
" );",
" }",
"}");

@Override
public boolean applicable(Context context) {
return true;
}

@Override
public String generateClass(
Context context, String className, String classToExtend, boolean isFinal) {
String templateString = Joiner.on('\n').join(TEMPLATE_LINES);
StringReader templateReader = new StringReader(templateString);
Template template;
try {
template = Template.parseFrom(templateReader);
} catch (IOException e) {
throw new RuntimeException(e);
}
TypeElement autoValueClass = context.autoValueClass();
ImmutableMap<String, Object> vars =
ImmutableMap.<String, Object>builder()
.put("package", context.packageName())
.put("className", className)
.put("classToExtend", classToExtend)
.put("isFinal", isFinal)
.put("properties", context.properties())
.put("formalTypes", formalTypeParametersString(autoValueClass))
.put("actualTypes", actualTypeParametersString(autoValueClass))
.build();
return template.evaluate(vars);
}

private static String actualTypeParametersString(TypeElement type) {
List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();
if (typeParameters.isEmpty()) {
return "";
}
return typeParameters
.stream()
.map(e -> e.getSimpleName().toString())
.collect(joining(", ", "<", ">"));
}

private static String formalTypeParametersString(TypeElement type) {
List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();
if (typeParameters.isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder("<");
String sep = "";
for (TypeParameterElement typeParameter : typeParameters) {
sb.append(sep);
sep = ", ";
appendTypeParameterWithBounds(typeParameter, sb);
}
return sb.append(">").toString();
}

private static void appendTypeParameterWithBounds(
TypeParameterElement typeParameter, StringBuilder sb) {
sb.append(typeParameter.getSimpleName());
String sep = " extends ";
for (TypeMirror bound : typeParameter.getBounds()) {
if (!bound.toString().equals("java.lang.Object")) {
sb.append(sep);
sep = " & ";
sb.append(bound);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void maybeWriteGwtSerializer(AutoValueTemplateVars autoVars) {
if (shouldWriteGwtSerializer()) {
GwtTemplateVars vars = new GwtTemplateVars();
vars.pkg = autoVars.pkg;
vars.subclass = autoVars.subclass;
vars.subclass = autoVars.finalSubclass;
vars.formalTypes = autoVars.formalTypes;
vars.actualTypes = autoVars.actualTypes;
vars.useBuilder = !autoVars.builderTypeName.isEmpty();
Expand Down

0 comments on commit 9cc04ec

Please sign in to comment.