Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,20 @@ public void visitIdent(JCIdent tree) {
analyzeSymbol(tree);
}

boolean isIndexed = false;

@Override
public void visitIndexed(JCArrayAccess tree) {
boolean previewIsIndexed = isIndexed;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean previousIsIndexed?

try {
isIndexed = true;
scan(tree.indexed);
} finally {
isIndexed = previewIsIndexed;
}
scan(tree.index);
}

@Override
public void visitSelect(JCFieldAccess tree) {
SelectScanner ss = new SelectScanner();
Expand Down Expand Up @@ -1434,7 +1448,9 @@ void analyzeSymbol(JCTree tree) {
}
// Field may not have an initializer
if ((sym.flags() & HASINIT) != 0) {
reportPrologueError(tree, sym, true);
if (!sym.type.hasTag(ARRAY) || !isIndexed) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work for complex ones like (this.a = stuff)[b] = 5?

Maybe we can try updating isInLHS to point to a JCTree and all the tests to be something like tree == isInLHS so this just won't run for array indexed trees?

reportPrologueError(tree, sym, true);
}
return;
}
// cant reference an instance field before a this constructor
Expand Down
99 changes: 11 additions & 88 deletions test/langtools/tools/javac/SuperInit/ValueClassSuperInitGood.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
* @bug 8324873
* @summary Test valid placements of super()/this() in constructors
* @enablePreview
* @ignore fails at execution time because of Optional
*/

import java.util.ArrayList;
import java.util.List;

public value class ValueClassSuperInitGood {

ValueClassSuperInitGood(Object obj) {
Expand Down Expand Up @@ -78,10 +80,10 @@ static value class Test3 {
Test3() {
new Object().hashCode();
new Object().hashCode();
super();
this.x = new Object().hashCode();
this.y = new Object().hashCode() % 17;
this.z = this.x + this.y;
super();
}
}

Expand All @@ -101,9 +103,9 @@ abstract value class Test5 extends Test5Abstract {
// Initialization blocks
value class Test6 {
final long startTime;
final int x;
List<String> l = new ArrayList<>();
{
this.x = 12;
l.add("");
}
Test6() {
long now = System.nanoTime();
Expand All @@ -116,8 +118,8 @@ value class Test6 {
break;
}
}
super();
this.startTime = now;
super();
}
}

Expand Down Expand Up @@ -234,26 +236,6 @@ class Bar {
}
}

// Initializer in initializer block
public static value class Test14 {
final int x; // initialized in constructor
final int y; // initialized in initialization block
final int z = 13; // initialized with intializer value
public Test14() {
this(0);
}
public Test14(boolean z) {
this.x = z ? 1 : 0;
}
public Test14(int x) {
super();
this.x = x;
}
{
this.y = -1;
}
}

// Qualified super() invocation with superclass instance
public static abstract value class Test15 {

Expand Down Expand Up @@ -382,32 +364,6 @@ public final V get() {
}
}

// Exceptions thrown by initializer block
public static value class Test18 extends AR<Object> {

{
if ((this.get().hashCode() % 3) == 0)
throw new MyException();
}

public Test18(Object obj) throws MyException {
super(obj);
}

public Test18(boolean fail) throws MyException {
Object obj;
for (obj = new Object(); true; obj = new Object()) {
if (((obj.hashCode() % 3) == 0) != fail)
continue;
break;
}
this(obj);
}

public static class MyException extends Exception {
}
}

// super()/this() within outer try block but inside inner class
public static value class Test19 {
public Test19(int x) {
Expand All @@ -424,29 +380,12 @@ public int hashCode() {
}
}

// local class declared before super(), but not used until after super()
public static value class Test20 {
public Test20() {
class Foo {
Foo() {
Test20.this.hashCode();
}
private final int[] data = new int[10];
Test20() {
for (int i = 0; i < data.length; i++) {
data[i] = i; // OK we are assigning to an array component
}
super();
new Foo();
}
}

// local class inside super() parameter list
public static value class Test21 extends AR<Object> {
private int x = 1;
public Test21() {
super(switch ("foo".hashCode()) {
default -> {
class Nested {{ System.out.println(x); }} // class is NOT instantiated - OK
yield "bar";
}
});
}
}

Expand All @@ -466,10 +405,6 @@ public static void main(String[] args) {
new Test11(9);
new Test12();
new Test13();
Test14 t14 = new Test14();
assert t14.x == 0 && t14.y == -1 && t14.z == 13;
t14 = new Test14(7);
assert t14.x == 7 && t14.y == -1 && t14.z == 13;
new Test15c(new Test15("foo"){}, "bar");
new Test16().run();
new Test17.StringHolder("foo");
Expand All @@ -479,19 +414,7 @@ public static void main(String[] args) {
} catch (NullPointerException e) {
// expected
}
try {
new Test18(true);
assert false : "expected exception";
} catch (Test18.MyException e) {
// expected
}
try {
new Test18(false);
} catch (Test18.MyException e) {
assert false : "unexpected exception: " + e;
}
new Test19(123);
new Test20();
new Test21();
}
}