Bug 515759: [9][compiler] Error is not reported when a class
instantiated via an anonymous diamond refers to inaccessible types
Change-Id: I354f1ede26f945f288fa6914fc7431599d6a13ee
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_9.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_9.java
index d3cdb89..6e4e1c4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_9.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_9.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 IBM Corporation.
+ * Copyright (c) 2016, 2017 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -454,6 +454,83 @@
"The method toString(String) of type new Z<X>(){} must override or implement a supertype method\n" +
"----------\n");
}
+// Inaccessible type inferred for anonymous diamond is an error
+public void testBug488663_015() {
+ this.runNegativeTest(
+ new String[] {
+ "Test.java",
+ "public class Test<T> {\n" +
+ " private static class Inner {" +
+ " public Inner(){}\n" +
+ " }\n" +
+ " <R> void print(I<R> i) {}\n" +
+ " public Inner get() {\n" +
+ " return new Inner();\n" +
+ " }\n" +
+ "}\n",
+ "Z.java",
+ "class Z<T> implements I<T> {\n" +
+ " public Z(T t1) {}\n" +
+ " public String toString (T t) {\n" +
+ " return t.toString();\n" +
+ " }\n" +
+ "}",
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " Test<String> t = new Test<>();\n" +
+ " t.print(new Z<>(t.get()) {\n" +
+ " \n" +
+ " });\n" +
+ " }\n" +
+ "}\n" +
+ "interface I<T> {\n" +
+ " String toString();\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " t.print(new Z<>(t.get()) {\n" +
+ " ^^^^^^^^^^^^\n" +
+ "The type Test$Inner is not visible\n" +
+ "----------\n");
+}
+// Inaccessible type inferred for anonymous diamond is an error - interface case
+public void testBug488663_016() {
+ this.runNegativeTest(
+ new String[] {
+ "Test.java",
+ "public class Test<T> {\n" +
+ " private static class Inner {" +
+ " public Inner(){}\n" +
+ " }\n" +
+ " <R extends Inner> void print(I<R> i) {}\n" +
+ " public Inner get() {\n" +
+ " return new Inner();\n" +
+ " }\n" +
+ "}\n",
+ "X.java",
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " Test<String> t = new Test<>();\n" +
+ " t.print(new I<>() {\n" +
+ " public String toString() {\n" +
+ " return \"\";\n" +
+ " }\n" +
+ " });\n" +
+ " }\n" +
+ "}\n" +
+ "interface I<T> {\n" +
+ " String toString();\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " t.print(new I<>() {\n" +
+ " ^^^^^\n" +
+ "The type Test$Inner is not visible\n" +
+ "----------\n");
+}
public static Class testClass() {
return GenericsRegressionTest_9.class;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index b666225..06605ac 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -523,9 +523,8 @@
if (constructorBinding == null)
return null;
this.resolvedType = this.anonymousType.binding;
- // Check that inferred type is denotable
- if (!checkTypeArgumentValidity((ParameterizedTypeBinding) receiverType, scope)) {
- scope.problemReporter().anonymousDiamondWithNonDenotableTypeArguments(this.type, receiverType);
+ // Check that inferred type is valid
+ if (!validate((ParameterizedTypeBinding) receiverType, scope)) {
return this.resolvedType;
}
}
@@ -597,7 +596,7 @@
}
}
- private boolean checkTypeArgumentValidity(final ParameterizedTypeBinding allocationType, final Scope scope) {
+ private boolean validate(final ParameterizedTypeBinding allocationType, final Scope scope) {
class ValidityInspector extends TypeBindingVisitor {
private boolean noErrors;
@@ -607,14 +606,23 @@
public boolean visit(IntersectionTypeBinding18 intersectionTypeBinding18) {
Arrays.sort(intersectionTypeBinding18.intersectingTypes, (t1, t2) -> t1.id - t2.id);
+ scope.problemReporter().anonymousDiamondWithNonDenotableTypeArguments(QualifiedAllocationExpression.this.type, allocationType);
return this.noErrors = false; // stop traversal
}
public boolean visit(TypeVariableBinding typeVariable) {
if (typeVariable.isCapture()) {
+ scope.problemReporter().anonymousDiamondWithNonDenotableTypeArguments(QualifiedAllocationExpression.this.type, allocationType);
return this.noErrors = false; // stop traversal
}
return true; // continue traversal
}
+ public boolean visit(ReferenceBinding ref) {
+ if (!ref.canBeSeenBy(scope)) {
+ scope.problemReporter().invalidType(QualifiedAllocationExpression.this.anonymousType, new ProblemReferenceBinding(ref.compoundName, ref, ProblemReasons.NotVisible));
+ return this.noErrors = false;
+ }
+ return true;
+ }
public boolean isValid() {
TypeBindingVisitor.visit(this, allocationType);
return this.noErrors;