Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8324651: Compiler Implementation for Derived Record Creation (Preview) #18509

Closed
wants to merge 36 commits into from
Closed
Changes from 33 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
588030c
A very crude and optimistic experiment on wthrs
lahodaj Sep 1, 2023
5074587
Merge branch 'master' into wthexp
lahodaj Jan 29, 2024
4212f20
Improvements.
lahodaj Feb 2, 2024
3e04899
Fixing handling of with variables inside a guard.
lahodaj Feb 5, 2024
a375020
Fixing a few bugs found by biboudis
lahodaj Feb 5, 2024
01040f3
Produce an error when the expression for the derived instance is not …
lahodaj Feb 5, 2024
e4d0f3b
Adding source level check for withers.
lahodaj Feb 6, 2024
86e9268
Merge branch 'master' into wthexp
lahodaj Mar 20, 2024
309e629
Pre/post-increment/decrement are also assignments.
lahodaj Mar 20, 2024
a8d825d
Cleanup.
lahodaj Mar 25, 2024
e4d8aba
Adding test.
lahodaj Mar 25, 2024
6bf29d1
Cleanup.
lahodaj Mar 25, 2024
c6806fe
Adding missing file.
lahodaj Mar 25, 2024
cff0d11
Merge branch 'master' into wthexp
lahodaj Mar 25, 2024
ac0b968
Javadoc cleanup.
lahodaj Mar 25, 2024
cf80d76
More correct handling of exceptions in derived record creation expres…
lahodaj Mar 26, 2024
96b4214
Adding examples.
lahodaj Mar 27, 2024
871e112
Adding tests.
lahodaj Mar 27, 2024
327ab53
Cleanup, bugfixes.
lahodaj Mar 27, 2024
969938a
Cleanup.
lahodaj Mar 27, 2024
a61682f
Removing whitespace
lahodaj Mar 27, 2024
e1a6183
Fixing support for derived record creation expression in JShell.
lahodaj Mar 28, 2024
73752b9
Renaming visitReconstruction to visitDerivedInstance as suggested.
lahodaj Mar 28, 2024
baaf960
The var declaration can be any JCTree.
lahodaj Mar 28, 2024
7b706ee
Adding tests.
lahodaj Mar 28, 2024
f89501e
Fixing tests.
lahodaj Mar 28, 2024
910b295
Merge branch 'master' into wthexp
lahodaj Apr 5, 2024
409dc6d
Reflecting review feedback.
lahodaj Apr 5, 2024
f9b6c40
Improving the javax.lang.model for component local variables, by darcy.
lahodaj Apr 5, 2024
c91e87f
JavaCompiler cleanup
lahodaj Apr 5, 2024
1465135
Reflecting review feedback:
lahodaj Apr 5, 2024
e093068
Adding tests as suggested.
lahodaj Apr 8, 2024
a05480c
Reflecting review feedback:
lahodaj Apr 9, 2024
16cd427
Merge branch 'master' into wthexp
lahodaj Apr 19, 2024
e8499df
Post-merge fixes.
lahodaj Apr 19, 2024
c97eb8e
Merge branch 'master' into wthexp
lahodaj Apr 29, 2024
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
@@ -81,6 +81,8 @@ public enum Feature {
CLASSFILE_API,
@JEP(number=461, title="Stream Gatherers", status="Preview")
STREAM_GATHERERS,
@JEP(number=468, title="Derived Record Creation", status="Preview")
DERIVED_RECORD_CREATION,
LANGUAGE_MODEL,
/**
* A key for testing.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2024, 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
@@ -25,6 +25,8 @@

package javax.lang.model.element;

import jdk.internal.javac.PreviewFeature;

/**
* The {@code kind} of an element.
*
@@ -121,7 +123,14 @@ public enum ElementKind {
* A binding variable in a pattern.
* @since 16
*/
BINDING_VARIABLE;
BINDING_VARIABLE,

/**
* A local component variable in a derived record creation expression.
* @since 23
*/
@PreviewFeature(feature=PreviewFeature.Feature.DERIVED_RECORD_CREATION, reflective=true)
COMPONENT_LOCAL_VARIABLE;
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we can't just use: LOCAL_VARIABLE

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could, and I was thinking of that. But, then I decided to go with a new kind, as I think it matches better the overall design of the Elements/Kinds. E.g. we have existing EXCEPTION_PARAMETER (used in catch) or BINDING_VARIABLE, rather than using LOCAL_VARIABLE for them.

(Also, many of these variable kinds have some small, but significant differences in semantics from LOCAL_VARIABLE - e.g. some are never blank/are always definitely assigned.)

Copy link
Contributor

Choose a reason for hiding this comment

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

Given the JLS defines "component local variable" I think it makes sense to have a separate kind


// Maintenance note: check if the default implementation of
Copy link
Member

Choose a reason for hiding this comment

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

From a quick look, I don't think Elements.getOutermostTypeElement needs updating for COMPONENT_LOCAL_VARIABLE, but it would be good to add a test case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tests added: e093068

Thanks!

// Elements.getOutermostTypeElement needs updating when new kind
@@ -200,7 +209,8 @@ public boolean isInitializer() {
* Returns {@code true} if this is a kind of variable: including
* {@code ENUM_CONSTANT}, {@code FIELD}, {@code PARAMETER},
* {@code LOCAL_VARIABLE}, {@code EXCEPTION_PARAMETER},
* {@code RESOURCE_VARIABLE}, and {@code BINDING_VARIABLE}.
* {@code RESOURCE_VARIABLE}, {@code BINDING_VARIABLE}, and
* {@code COMPONENT_LOCAL_VARIABLE}.
*
* @return {@code true} if this is a kind of variable
* @since 19
@@ -209,7 +219,7 @@ public boolean isVariable() {
return switch(this) {
case ENUM_CONSTANT, FIELD, PARAMETER,
LOCAL_VARIABLE, EXCEPTION_PARAMETER, RESOURCE_VARIABLE,
BINDING_VARIABLE -> true;
BINDING_VARIABLE, COMPONENT_LOCAL_VARIABLE -> true;
default -> false;
};
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2024, 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
@@ -25,6 +25,8 @@

package javax.lang.model.util;

import jdk.internal.javac.PreviewFeature;

import javax.lang.model.element.*;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
@@ -264,6 +266,9 @@ public R visitVariable(VariableElement e, P p) {
case BINDING_VARIABLE:
return visitVariableAsBindingVariable(e, p);

case COMPONENT_LOCAL_VARIABLE:
return visitVariableAsComponentLocalVariable(e, p);

default:
throw new AssertionError("Bad kind " + k + " for VariableElement" + e);
}
@@ -364,6 +369,22 @@ public R visitVariableAsBindingVariable(VariableElement e, P p) {
return visitUnknown(e, p);
}

/**
* Visits a {@code COMPONENT_LOCAL_VARIABLE} variable element.
*
* @implSpec This implementation calls {@code visitUnknown}.
*
* @param e the element to visit
* @param p a visitor-specified parameter
* @return the result of {@code visitUnknown}
*
* @since 23
*/
@PreviewFeature(feature=PreviewFeature.Feature.DERIVED_RECORD_CREATION, reflective=true)
public R visitVariableAsComponentLocalVariable(VariableElement e, P p) {
return visitUnknown(e, p);
}

/**
* {@inheritDoc ElementVisitor}
*
Original file line number Diff line number Diff line change
@@ -86,4 +86,21 @@ protected ElementKindVisitorPreview() {
protected ElementKindVisitorPreview(R defaultValue) {
super(defaultValue);
}

/**
* {@inheritDoc ElementKindVisitor6}
Copy link
Member

Choose a reason for hiding this comment

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

If possible, would be good to add some minimal testing/use of the element kind visitors on component local variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tests added: e093068

Thanks!

*
* @implSpec This implementation calls {@code defaultAction}.
*
* @param e {@inheritDoc ElementKindVisitor6}
* @param p {@inheritDoc ElementKindVisitor6}
* @return the result of {@code defaultAction}
*
* @since 23
*/
@Override
@PreviewFeature(feature=PreviewFeature.Feature.DERIVED_RECORD_CREATION, reflective=true)
public R visitVariableAsComponentLocalVariable(VariableElement e, P p) {
return defaultAction(e, p);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2024, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/

package com.sun.source.tree;

import jdk.internal.javac.PreviewFeature;

/**
* A tree node for a derived record creation expression.
*
* For example:
* <pre>
* <em>expression</em> with { <em>assignments</em> }
* </pre>
*
* @jls 15.30 Derived Record Creation Expression
*
* @since 23
*/
@PreviewFeature(feature=PreviewFeature.Feature.DERIVED_RECORD_CREATION, reflective=true)
public interface DerivedInstanceTree extends ExpressionTree {
/**
* {@return the origin expression of the derived record creation expression.}
*/
ExpressionTree getExpression();

/**
* {@return the reconstruction block.}
*/
BlockTree getBlock();
}
9 changes: 8 additions & 1 deletion src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2024, 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
@@ -228,6 +228,13 @@ public enum Kind {
*/
PARENTHESIZED(ParenthesizedTree.class),

/**
* Used for instances of {@link DerivedInstanceTree}.
* @since 23
*/
@PreviewFeature(feature=PreviewFeature.Feature.DERIVED_RECORD_CREATION, reflective=true)
DERIVED_INSTANCE(DerivedInstanceTree.class),

/**
* Used for instances of {@link BindingPatternTree}.
*
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2024, 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
@@ -379,6 +379,16 @@ public interface TreeVisitor<R,P> {
*/
R visitParenthesized(ParenthesizedTree node, P p);

/**
* Visits a {@code DerivedInstanceTree} node.
* @param node the node being visited
* @param p a parameter value
* @return a result value
* @since 23
*/
@PreviewFeature(feature=PreviewFeature.Feature.DERIVED_RECORD_CREATION, reflective=true)
R visitDerivedInstance(DerivedInstanceTree node, P p);

/**
* Visits a {@code ReturnTree} node.
* @param node the node being visited
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2024, 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
@@ -544,6 +544,22 @@ public R visitParenthesized(ParenthesizedTree node, P p) {
return defaultAction(node, p);
}

/**
* {@inheritDoc}
*
* @implSpec This implementation calls {@code defaultAction}.
*
* @param node {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of {@code defaultAction}
* @since 23
*/
@Override
@PreviewFeature(feature=PreviewFeature.Feature.DERIVED_RECORD_CREATION, reflective=true)
public R visitDerivedInstance(DerivedInstanceTree node, P p) {
return defaultAction(node, p);
}

/**
* {@inheritDoc}
*
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2024, 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
@@ -662,6 +662,24 @@ public R visitParenthesized(ParenthesizedTree node, P p) {
return scan(node.getExpression(), p);
}

/**
* {@inheritDoc}
*
* @implSpec This implementation scans the children in left to right order.
*
* @param node {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of scanning
* @since 23
*/
@Override
@PreviewFeature(feature=PreviewFeature.Feature.DERIVED_RECORD_CREATION, reflective=true)
public R visitDerivedInstance(DerivedInstanceTree node, P p) {
R r = scan(node.getExpression(), p);
r = scanAndReduce(node.getBlock(), p, r);
return r;
}

/**
* {@inheritDoc}
*
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2024, 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
@@ -389,6 +389,11 @@ public static EnumSet<Flag> asFlagSet(long flags) {
*/
public static final long SEALED = 1L<<62; // ClassSymbols

/**
* Flag to indicate component local variables.
*/
public static final long COMPONENT_LOCAL_VARIABLE = 1L<<62; // VarSymbols

/**
* Flag to indicate restricted method declaration.
*/
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
@@ -210,6 +210,7 @@ public boolean isPreview(Feature feature) {
case STRING_TEMPLATES -> true;
case IMPLICIT_CLASSES -> true;
case SUPER_INIT -> true;
case DERIVED_INSTANCE -> true;
case PRIMITIVE_PATTERNS -> true;
//Note: this is a backdoor which allows to optionally treat all features as 'preview' (for testing).
//When real preview features will be added, this method can be implemented to return 'true'
Original file line number Diff line number Diff line change
@@ -256,6 +256,7 @@ public enum Feature {
UNNAMED_VARIABLES(JDK22, Fragments.FeatureUnnamedVariables, DiagKind.PLURAL),
PRIMITIVE_PATTERNS(JDK23, Fragments.FeaturePrimitivePatterns, DiagKind.PLURAL),
SUPER_INIT(JDK22, Fragments.FeatureSuperInit, DiagKind.NORMAL),
DERIVED_INSTANCE(JDK23, Fragments.FeatureDerivedInstance, DiagKind.NORMAL),
;

enum DiagKind {
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2024, 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
@@ -1763,6 +1763,9 @@ public ElementKind getKind() {
} else if ((flags & MATCH_BINDING) != 0) {
ElementKind kind = ElementKind.BINDING_VARIABLE;
return kind;
} else if ((flags & COMPONENT_LOCAL_VARIABLE) != 0) {
ElementKind kind = ElementKind.COMPONENT_LOCAL_VARIABLE;
return kind;
} else {
return ElementKind.LOCAL_VARIABLE;
}
Loading