Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManoj Palat2020-08-27 09:50:31 +0000
committerManoj Palat2020-08-27 09:50:31 +0000
commitb7c0e693449f0356f777dbf83361699f2c429633 (patch)
treeba30aed3c2b6b5ca961db5d4b6aa413c172606d3
parent1af7ed636212551f9e571fd281bf99a212c5684e (diff)
downloadeclipse.jdt.core-P20200828-0150.tar.gz
eclipse.jdt.core-P20200828-0150.tar.xz
eclipse.jdt.core-P20200828-0150.zip
Bug 566284 - [15] static reference error in recordP20200828-0150
Change-Id: I187887a9b7dbc6ac22c83022ae0bd2a999f60c86 Signed-off-by: Manoj Palat <manpalat@in.ibm.com>
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalStaticsTest_15.java223
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java1
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java23
3 files changed, 241 insertions, 6 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
new file mode 100644
index 0000000000..3987d68b94
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LocalStaticsTest_15.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2020 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
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.compiler.regression;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+import junit.framework.Test;
+
+public class LocalStaticsTest_15 extends AbstractRegressionTest {
+
+ static {
+// TESTS_NUMBERS = new int [] { 40 };
+// TESTS_RANGE = new int[] { 1, -1 };
+// TESTS_NAMES = new String[] { "testBug566284"};
+ }
+
+ public static Class<?> testClass() {
+ return LocalStaticsTest_15.class;
+ }
+ public static Test suite() {
+ return buildMinimalComplianceTestSuite(testClass(), F_15);
+ }
+ public LocalStaticsTest_15(String testName){
+ super(testName);
+ }
+
+ // Enables the tests to run individually
+ protected Map<String, String> getCompilerOptions() {
+ Map<String, String> defaultOptions = super.getCompilerOptions();
+ defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15); // FIXME
+ defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+ defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+ defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+ defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+ defaultOptions.put(CompilerOptions.OPTION_Store_Annotations, CompilerOptions.ENABLED);
+ return defaultOptions;
+ }
+
+ @Override
+ protected void runConformTest(String[] testFiles, String expectedOutput) {
+ runConformTest(testFiles, expectedOutput, getCompilerOptions());
+ }
+
+ @Override
+ protected void runConformTest(String[] testFiles, String expectedOutput, Map<String, String> customOptions) {
+ Runner runner = new Runner();
+ runner.testFiles = testFiles;
+ runner.expectedOutputString = expectedOutput;
+ runner.vmArguments = new String[] {"--enable-preview"};
+ runner.customOptions = customOptions;
+ runner.javacTestOptions = JavacTestOptions.forReleaseWithPreview("15");
+ runner.runConformTest();
+ }
+ @Override
+ protected void runNegativeTest(String[] testFiles, String expectedCompilerLog) {
+ runNegativeTest(testFiles, expectedCompilerLog, JavacTestOptions.forReleaseWithPreview("15"));
+ }
+ protected void runWarningTest(String[] testFiles, String expectedCompilerLog) {
+ runWarningTest(testFiles, expectedCompilerLog, null);
+ }
+ protected void runWarningTest(String[] testFiles, String expectedCompilerLog, Map<String, String> customOptions) {
+ runWarningTest(testFiles, expectedCompilerLog, customOptions, null);
+ }
+ protected void runWarningTest(String[] testFiles, String expectedCompilerLog,
+ Map<String, String> customOptions, String javacAdditionalTestOptions) {
+
+ Runner runner = new Runner();
+ runner.testFiles = testFiles;
+ runner.expectedCompilerLog = expectedCompilerLog;
+ runner.customOptions = customOptions;
+ runner.vmArguments = new String[] {"--enable-preview"};
+ runner.javacTestOptions = javacAdditionalTestOptions == null ? JavacTestOptions.forReleaseWithPreview("15") :
+ JavacTestOptions.forReleaseWithPreview("15", javacAdditionalTestOptions);
+ runner.runWarningTest();
+ }
+
+ @SuppressWarnings("unused")
+ private static void verifyClassFile(String expectedOutput, String classFileName, int mode)
+ throws IOException, ClassFormatException {
+ File f = new File(OUTPUT_DIR + File.separator + classFileName);
+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f);
+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+ String result = disassembler.disassemble(classFileBytes, "\n", mode);
+ int index = result.indexOf(expectedOutput);
+ if (index == -1 || expectedOutput.length() == 0) {
+ System.out.println(Util.displayString(result, 3));
+ System.out.println("...");
+ }
+ if (index == -1) {
+ assertEquals("Wrong contents", expectedOutput, result);
+ }
+ }
+
+ public void testBug566284_001() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n"+
+ " static void foo() {\n"+
+ " interface F {\n"+
+ " static int create(int lo) {\n"+
+ " I myI = s -> lo;\n"+
+ " return myI.bar(0);\n"+
+ " }\n"+
+ " }\n"+
+ " System.out.println(F.create(0));\n"+
+ " }\n"+
+ " public static void main(String[] args) {\n"+
+ " X.foo();\n"+
+ " }\n"+
+ "}\n"+
+ "\n"+
+ "interface I {\n"+
+ " int bar(int l);\n"+
+ "}"
+ },
+ "0");
+ }
+ public void testBug566284_002() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n"+
+ " static void foo() {\n"+
+ " record R() {\n"+
+ " static int create(int lo) {\n"+
+ " I myI = s -> lo;\n"+
+ " return myI.bar(0);\n"+
+ " }\n"+
+ " }\n"+
+ " System.out.println(R.create(0));\n"+
+ " }\n"+
+ " public static void main(String[] args) {\n"+
+ " X.foo();\n"+
+ " }\n"+
+ "}\n"+
+ "\n"+
+ "interface I {\n"+
+ " int bar(int l);\n"+
+ "}"
+ },
+ "0");
+ }
+ public void testBug566284_003() {
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " static int si;\n"+
+ " int nsi;\n"+
+ "\n"+
+ " void m() {\n"+
+ " int li;\n"+
+ "\n"+
+ " interface F {\n"+
+ " static int fi = 0;\n"+
+ "\n"+
+ " default void foo(int i) {\n"+
+ " System.out.println(li); // error, local variable of method of outer enclosing class\n"+
+ " System.out.println(nsi); // error, non-static member\n"+
+ " System.out.println(fi); // ok, static member of current class\n"+
+ " System.out.println(si); // ok, static member of enclosing class\n"+
+ " System.out.println(i); // ok, local variable of current method\n"+
+ " }\n"+
+ "\n"+
+ " static void bar(int lo) {\n"+
+ " int k = lo; // ok\n"+
+ " int j = fi; // ok\n"+
+ " I myI = s -> lo; // ok, local var of method\n"+
+ " }\n"+
+ "\n"+
+ " static void bar2(int lo) {\n"+
+ " I myI = s -> li; // error - local var of outer class\n"+
+ " }\n"+
+ " }\n"+
+ " }\n"+
+ "}\n"+
+ "\n"+
+ "interface I {\n"+
+ " int bar(int l);\n"+
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 12)\n" +
+ " System.out.println(li); // error, local variable of method of outer enclosing class\n" +
+ " ^^\n" +
+ "Cannot make a static reference to the non-static variable li from a local record\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 13)\n" +
+ " System.out.println(nsi); // error, non-static member\n" +
+ " ^^^\n" +
+ "Cannot make a static reference to the non-static field nsi\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 26)\n" +
+ " I myI = s -> li; // error - local var of outer class\n" +
+ " ^^\n" +
+ "Cannot make a static reference to the non-static variable li from a local record\n" +
+ "----------\n"
+ );
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
index a1840683b0..b0417ace6c 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
@@ -205,6 +205,7 @@ public static Test suite() {
since_15.add(SealedTypes15Tests.class);
since_15.add(ClassFileReaderTest_15.class);
since_15.add(JavadocTest_15.class);
+ since_15.add(LocalStaticsTest_15.class);
// Build final test suite
TestSuite all = new TestSuite(TestAll.class.getName());
all.addTest(new TestSuite(StandAloneASTParserTest.class));
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index 5a054b5ff6..e1cc9a41f5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -1031,12 +1031,7 @@ public TypeBinding resolveType(BlockScope scope) {
if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8) // for 8, defer till effective finality could be ascertained.
scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding)variable, this);
}
- if (this.actualReceiverType.isRecord() && this.actualReceiverType.isLocalType()) {// JLS 14 Sec 14.3
- if ((variable.modifiers & ClassFileConstants.AccStatic) == 0 &&
- (this.bits & ASTNode.IsCapturedOuterLocal) != 0) {
- scope.problemReporter().recordStaticReferenceToOuterLocalVariable((LocalVariableBinding)variable, this);
- }
- }
+ checkLocalStaticClassVariables(scope, variable);
variableType = variable.type;
this.constant = (this.bits & ASTNode.IsStrictlyAssigned) == 0 ? variable.constant(scope) : Constant.NotAConstant;
} else {
@@ -1077,6 +1072,22 @@ public TypeBinding resolveType(BlockScope scope) {
return this.resolvedType = reportError(scope);
}
+private void checkLocalStaticClassVariables(BlockScope scope, VariableBinding variable) {
+ if (this.actualReceiverType.isStatic() && this.actualReceiverType.isLocalType()) {
+ if ((variable.modifiers & ClassFileConstants.AccStatic) == 0 &&
+ (this.bits & ASTNode.IsCapturedOuterLocal) != 0) {
+ BlockScope declaringScope = ((LocalVariableBinding) this.binding).declaringScope;
+ MethodScope declaringMethodScope = declaringScope instanceof MethodScope ? (MethodScope)declaringScope :
+ declaringScope.enclosingMethodScope();
+ MethodScope currentMethodScope = scope instanceof MethodScope ? (MethodScope) scope : scope.enclosingMethodScope();
+ ClassScope declaringClassScope = declaringMethodScope != null ? declaringMethodScope.classScope() : null;
+ ClassScope currentClassScope = currentMethodScope != null ? currentMethodScope.classScope() : null;
+ if (declaringClassScope != currentClassScope)
+ scope.problemReporter().recordStaticReferenceToOuterLocalVariable((LocalVariableBinding)variable, this);
+ }
+ }
+}
+
@Override
public void traverse(ASTVisitor visitor, BlockScope scope) {
visitor.visit(this, scope);

Back to the top