diff options
author | Manoj Palat | 2020-09-07 06:44:42 +0000 |
---|---|---|
committer | Manoj Palat | 2020-09-07 17:32:56 +0000 |
commit | 2008d1b41d6ec1497a22d7e4757c68851fe81899 (patch) | |
tree | 113d7ec24b8f47c85850e4fa45ab52d0d7f7ae28 | |
parent | ad13fa01cc09ee2baa3a67fcc1148cf2c5d2874c (diff) | |
download | eclipse.jdt.core-2008d1b41d6ec1497a22d7e4757c68851fe81899.tar.gz eclipse.jdt.core-2008d1b41d6ec1497a22d7e4757c68851fe81899.tar.xz eclipse.jdt.core-2008d1b41d6ec1497a22d7e4757c68851fe81899.zip |
Bug 566715 - Assertion/NPE with local records incorrectly having an
outer class type param
Change-Id: Iaf4d01500fb8a7a3a8090dd0596c0431ececc64b
5 files changed, 107 insertions, 32 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalStaticsTest_15.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalStaticsTest_15.java index 269614665b..4aea306525 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalStaticsTest_15.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalStaticsTest_15.java @@ -33,7 +33,7 @@ public class LocalStaticsTest_15 extends AbstractRegressionTest { static { // TESTS_NUMBERS = new int [] { 40 }; // TESTS_RANGE = new int[] { 1, -1 }; -// TESTS_NAMES = new String[] { "testBug566284"}; +// TESTS_NAMES = new String[] { "testBug566715_003"}; } public static Class<?> testClass() { @@ -400,4 +400,75 @@ public class LocalStaticsTest_15 extends AbstractRegressionTest { }, ""); } + // 6.5.5.1 + public void testBug566715_001() { + runNegativeTest( + new String[] { + "X.java", + "public class X<T> {\n"+ + " static void foo() {\n"+ + " interface I {\n"+ + " X<T> supply();\n"+ + " }\n"+ + " }\n"+ + "}\n" + }, + "----------\n"+ + "1. WARNING in X.java (at line 3)\n" + + " interface I {\n" + + " ^\n" + + "The type I is never used locally\n" + + "----------\n" + + "2. ERROR in X.java (at line 4)\n" + + " X<T> supply();\n" + + " ^\n" + + "Cannot make a static reference to the non-static type T\n" + + "----------\n" + ); + } + // 6.5.5.1 + public void testBug566715_002() { + runNegativeTest( + new String[] { + "X.java", + "public class X<T> {\n"+ + " void foo() {\n"+ + " interface I {\n"+ + " X<T> supply();\n"+ + " }\n"+ + " }\n"+ + "}\n" + }, + "----------\n"+ + "1. WARNING in X.java (at line 3)\n" + + " interface I {\n" + + " ^\n" + + "The type I is never used locally\n" + + "----------\n" + + "2. ERROR in X.java (at line 4)\n" + + " X<T> supply();\n" + + " ^\n" + + "Cannot make a static reference to the non-static type T\n" + + "----------\n" + ); + } + // 6.5.5.1 + public void testBug566715_003() { + runNegativeTest( + new String[] { + "X.java", + "public class X<T> {\n"+ + " void foo() {\n"+ + " record R(X<T> x) {}\n"+ + " }\n"+ + "}\n" + }, + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " record R(X<T> x) {}\n" + + " ^\n" + + "Cannot make a static reference to the non-static type T\n" + + "----------\n" + ); + } }
\ No newline at end of file diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java index 578882b37a..1b2b9554ff 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java @@ -588,8 +588,8 @@ public class ClassFile implements TypeConstants, TypeIds { if (fieldDeclaration.isARecordComponent) { long rcMask = TagBits.AnnotationForField | TagBits.AnnotationForTypeUse; RecordComponent comp = getRecordComponent(fieldBinding.declaringClass, fieldBinding.name); - assert comp != null; - fieldDeclaration.annotations = ASTNode.getRelevantAnnotations(comp.annotations, rcMask, null); + if (comp != null) + fieldDeclaration.annotations = ASTNode.getRelevantAnnotations(comp.annotations, rcMask, null); } Annotation[] annotations = fieldDeclaration.annotations; if (annotations != null) { @@ -4116,21 +4116,22 @@ public class ClassFile implements TypeConstants, TypeIds { // record component (field) accessor method ReferenceBinding declaringClass = methodBinding.declaringClass; RecordComponent comp = getRecordComponent(declaringClass, methodBinding.selector); - assert comp != null; - Annotation[] annotations = ASTNode.getRelevantAnnotations(comp.annotations, rcMask, null); - if (annotations != null) { - assert !methodBinding.isConstructor(); - attributesNumber += generateRuntimeAnnotations(annotations, TagBits.AnnotationForMethod); - // Now type annotations - Supplier<List<AnnotationContext>> collector = () -> { - List<AnnotationContext> allTypeAnnotationContexts = new ArrayList<>(); - comp.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts); - return allTypeAnnotationContexts; - }; - attributesNumber = completeRuntimeTypeAnnotations(attributesNumber, - comp, - (node) -> (comp.bits & ASTNode.HasTypeAnnotations) != 0, - collector); + if (comp != null) { + Annotation[] annotations = ASTNode.getRelevantAnnotations(comp.annotations, rcMask, null); + if (annotations != null) { + assert !methodBinding.isConstructor(); + attributesNumber += generateRuntimeAnnotations(annotations, TagBits.AnnotationForMethod); + // Now type annotations + Supplier<List<AnnotationContext>> collector = () -> { + List<AnnotationContext> allTypeAnnotationContexts = new ArrayList<>(); + comp.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts); + return allTypeAnnotationContexts; + }; + attributesNumber = completeRuntimeTypeAnnotations(attributesNumber, + comp, + (node) -> (comp.bits & ASTNode.HasTypeAnnotations) != 0, + collector); + } } } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java index 9d64eecafd..c5b76d8ebf 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java @@ -107,8 +107,10 @@ public class Argument extends LocalDeclaration { assert (sourceTypeBinding.isRecord()); // CHECK: Is this really necessary? sourceTypeBinding.components(); RecordComponentBinding recordComponentBinding = sourceTypeBinding.getRecordComponent(this.name); - RecordComponent recordComponent = recordComponentBinding.sourceRecordComponent(); - return recordComponent.annotations; + if (recordComponentBinding != null) { + RecordComponent recordComponent = recordComponentBinding.sourceRecordComponent(); + return recordComponent.annotations; + } } } return null; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java index bcabd645d0..553a7251e9 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java @@ -2424,6 +2424,8 @@ public ModuleBinding module() { public boolean hasEnclosingInstanceContext() { if (isMemberType() && !isStatic()) return true; + if (isLocalType() && isStatic()) + return false; MethodBinding enclosingMethod = enclosingMethod(); if (enclosingMethod != null) return !enclosingMethod.isStatic(); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java index 5caa2a0114..b7c2772fb0 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java @@ -67,6 +67,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ASTVisitor; @@ -920,8 +921,8 @@ public List<MethodBinding> checkAndAddSyntheticRecordComponentAccessors(MethodBi int missingCount = filteredComponents.size(); for (int i = 0; i < missingCount; ++i) { RecordComponentBinding rcb = this.getRecordComponent(filteredComponents.get(i).toCharArray()); - assert rcb != null; - implicitMethods.add(addSyntheticRecordComponentAccessor(rcb, i)); + if (rcb != null) + implicitMethods.add(addSyntheticRecordComponentAccessor(rcb, i)); } accessors.addAll(implicitMethods); this.recordComponentAccessors = accessors.toArray(new MethodBinding[0]); @@ -2550,9 +2551,9 @@ public FieldBinding resolveTypeFor(FieldBinding field) { // copy annotations from record component if applicable if (field.isRecordComponent()) { RecordComponentBinding rcb = getRecordComponent(field.name); - assert rcb != null; - relevantRecordComponentAnnotations = ASTNode.copyRecordComponentAnnotations(initializationScope, - field, rcb.sourceRecordComponent().annotations); + if (rcb != null) + relevantRecordComponentAnnotations = ASTNode.copyRecordComponentAnnotations(initializationScope, + field, rcb.sourceRecordComponent().annotations); } } if (sourceLevel >= ClassFileConstants.JDK1_8) { @@ -3474,15 +3475,13 @@ public MethodBinding getRecordComponentAccessor(char[] name) { return accessor; } public void computeRecordComponents() { - if (this.implicitComponentFields != null) + if (!this.isRecord() || this.implicitComponentFields != null) return; - RecordComponent[] recComps = this.scope.referenceContext.recordComponents; + List<String> recordComponentNames = Stream.of(this.components) + .map(arg -> new String(arg.name)) + .collect(Collectors.toList()); List<FieldBinding> list = new ArrayList<>(); - if (recComps != null && recComps.length > 0 && this.fields != null) { - List<String> recordComponentNames = new ArrayList<>(0); - recordComponentNames = Arrays.stream(recComps) - .map(arg -> new String(arg.name)) - .collect(Collectors.toList()); + if (recordComponentNames != null && recordComponentNames.size() > 0 && this.fields != null) { for (String rc : recordComponentNames) { for (FieldBinding f : this.fields) { if (rc.equals(new String(f.name))) { |