8222369: ExecutableElement.getReceiverType returns null instead of NOTYPE

Reviewed-by: jjg
This commit is contained in:
Joe Darcy 2019-06-13 16:39:20 -07:00
parent 31249c3c09
commit 51cf24fcc0
3 changed files with 127 additions and 2 deletions

View File

@ -2063,7 +2063,8 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
@DefinedBy(Api.LANGUAGE_MODEL)
public Type getReceiverType() {
return asType().getReceiverType();
Type result = asType().getReceiverType();
return (result == null) ? Type.noType : result;
}
@DefinedBy(Api.LANGUAGE_MODEL)

View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8222369
* @summary Test behavior of ExecutableElement.getReceiverType
* @library /tools/javac/lib
* @build JavacTestingAbstractProcessor TestExecutableReceiverType
* @compile -processor TestExecutableReceiverType -proc:only TestExecutableReceiverType.java
*/
import java.util.Set;
import java.lang.annotation.*;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
import javax.lang.model.util.*;
import static javax.tools.Diagnostic.Kind.*;
/**
* Verify that proper type objects are returned from ExecutableElement.getReceiverType
*/
public class TestExecutableReceiverType extends JavacTestingAbstractProcessor {
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
if (!roundEnv.processingOver()) {
int count = 0;
count += testType(elements.getTypeElement("MethodHost"));
count += testType(elements.getTypeElement("MethodHost.Nested"));
if (count == 0) {
messager.printMessage(ERROR, "No executables visited.");
}
}
return true;
}
int testType(TypeElement typeElement) {
int count = 0;
for (ExecutableElement executable :
ElementFilter.constructorsIn(typeElement.getEnclosedElements())) {
count += testExecutable(executable);
}
for (ExecutableElement executable :
ElementFilter.methodsIn(typeElement.getEnclosedElements())) {
count += testExecutable(executable);
}
return count;
}
int testExecutable(ExecutableElement executable) {
TypeKind expectedKind = executable.getAnnotation(ReceiverTypeKind.class).value();
TypeKind actualKind = executable.getReceiverType().getKind();
if (actualKind != expectedKind) {
messager.printMessage(ERROR,
String.format("Unexpected TypeKind on receiver of %s:" +
" expected %s\t got %s%n",
executable, expectedKind, actualKind));
}
return 1;
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface ReceiverTypeKind {
TypeKind value();
}
/**
* Class to host various methods, etc.
*/
class MethodHost {
@ReceiverTypeKind(TypeKind.NONE)
public MethodHost() {}
@ReceiverTypeKind(TypeKind.NONE)
public static void foo() {return;}
@ReceiverTypeKind(TypeKind.NONE)
public void bar() {return;}
@ReceiverTypeKind(TypeKind.DECLARED)
public void quux(MethodHost this) {return;}
private class Nested {
@ReceiverTypeKind(TypeKind.DECLARED)
public Nested(MethodHost MethodHost.this) {}
}
}

View File

@ -409,7 +409,7 @@ public class ElementStructureTest {
for (VariableElement param : e.getParameters()) {
visit(param, p);
}
out.write(String.valueOf(e.getReceiverType()));
out.write(String.valueOf(typeMirrorTranslate(e.getReceiverType())));
write(e.getReturnType());
out.write(e.getSimpleName().toString());
writeTypes(e.getThrownTypes());
@ -425,6 +425,18 @@ public class ElementStructureTest {
return null;
}
/**
* Original implementation of getReceiverType returned null
* for many cases where TypeKind.NONE was specified; translate
* back to null to compare against old hashes.
*/
private TypeMirror typeMirrorTranslate(TypeMirror type) {
if (type.getKind() == javax.lang.model.type.TypeKind.NONE)
return null;
else
return type;
}
@Override
public Void visitPackage(PackageElement e, Void p) {
List<Element> types = new ArrayList<>(e.getEnclosedElements());