Skip to content

Commit

Permalink
feature: Unnamed Variables & Patterns (JEP 456) (#5848)
Browse files Browse the repository at this point in the history
  • Loading branch information
SirYwell committed Jun 19, 2024
1 parent c7b41ca commit 6179f83
Show file tree
Hide file tree
Showing 36 changed files with 464 additions and 16 deletions.
13 changes: 13 additions & 0 deletions doc/code_elements.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,19 @@ int x = switch(i) { // <-- switch expression
int x=3;
--x; // <-- unary --

```
### CtUnnamedPattern
[(javadoc)](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/code/CtUnnamedPattern.html)

```java

Object obj = new Object();
record X(int i) {}
int i = switch (obj) {
case X(_) -> 0; // an unnamed pattern does neither mention a type nor a name
case null, default -> -1;
};

```
### CtVariableRead
[(javadoc)](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/reflect/code/CtVariableRead.html)
Expand Down
8 changes: 8 additions & 0 deletions qodana.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,11 @@ include:
- name: PointlessBooleanExpression
exclude:
- name: UseOfClone
# Do not check generated code
- name: All
paths:
- src/main/java/spoon/support/visitor/replace/ReplacementVisitor.java
- src/main/java/spoon/reflect/visitor/CtBiScannerDefault.java
- src/main/java/spoon/support/visitor/clone/CloneBuilder.java
- src/main/java/spoon/support/visitor/clone/CloneVisitor.java
- src/main/java/spoon/reflect/meta/impl/ModelRoleHandlers.java
6 changes: 6 additions & 0 deletions spoon-smpl/src/main/java/spoon/smpl/Substitutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtTypePattern;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtUnnamedPattern;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.code.CtVariableWrite;
import spoon.reflect.code.CtWhile;
Expand Down Expand Up @@ -712,6 +713,11 @@ public void visitCtRecordPattern(CtRecordPattern recordPattern) {
throw new NotImplementedException("Not implemented");
}

@Override
public void visitCtUnnamedPattern(CtUnnamedPattern unnamedPattern) {
throw new NotImplementedException("Not implemented");
}

@Override
public void visitCtReceiverParameter(CtReceiverParameter receiverParameter) {
throw new NotImplementedException("Not implemented");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtTypePattern;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtUnnamedPattern;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.code.CtVariableWrite;
import spoon.reflect.code.CtWhile;
Expand Down Expand Up @@ -852,6 +853,11 @@ public void visitCtRecordPattern(CtRecordPattern recordPattern) {
throw new NotImplementedException("Not implemented");
}

@Override
public void visitCtUnnamedPattern(CtUnnamedPattern unnamedPattern) {
throw new NotImplementedException("Not implemented");
}

@Override
public void visitCtReceiverParameter(CtReceiverParameter receiverParameter) {
throw new NotImplementedException("Not implemented");
Expand Down
1 change: 1 addition & 0 deletions src/main/java/spoon/metamodel/Metamodel.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ public static Set<CtType<?>> getAllMetamodelInterfaces() {
result.add(factory.Type().get(spoon.reflect.code.CtTypeAccess.class));
result.add(factory.Type().get(spoon.reflect.code.CtTypePattern.class));
result.add(factory.Type().get(spoon.reflect.code.CtUnaryOperator.class));
result.add(factory.Type().get(spoon.reflect.code.CtUnnamedPattern.class));
result.add(factory.Type().get(spoon.reflect.code.CtVariableAccess.class));
result.add(factory.Type().get(spoon.reflect.code.CtVariableRead.class));
result.add(factory.Type().get(spoon.reflect.code.CtVariableWrite.class));
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/spoon/reflect/code/CtCatchVariable.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ public interface CtCatchVariable<T> extends CtVariable<T>, CtMultiTypedElement,
@UnsettableProperty
<C extends CtVariable<T>> C setDefaultExpression(CtExpression<T> assignedExpression);

/**
* {@return whether this catch variable is <a href="https://openjdk.org/jeps/456">unnamed</a>}
*/
@DerivedProperty
boolean isUnnamed();

/**
* Returns type reference of the exception variable in a catch.
* If type is unknown, or any of the types in a multi-catch is unknown, returns null.
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/spoon/reflect/code/CtLocalVariable.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,32 @@
* @see spoon.reflect.declaration.CtExecutable
*/
public interface CtLocalVariable<T> extends CtStatement, CtVariable<T>, CtRHSReceiver<T>, CtResource<T> {

/**
* The {@link #getSimpleName() simple name} of a local variable that is
* <a href="https://openjdk.org/jeps/456">unnamed</a>.
*/
String UNNAMED_VARIABLE_NAME = "_";

/*
* (non-Javadoc)
*
* @see spoon.reflect.declaration.CtNamedElement#getReference()
*/
/**
* {@inheritDoc}
* If the variable is <a href="https://openjdk.org/jeps/456">unnamed</a>, {@code null} is returned.
*/
@Override
@DerivedProperty
CtLocalVariableReference<T> getReference();

/**
* {@return whether this local variable is <a href="https://openjdk.org/jeps/456">unnamed</a>}
*/
@DerivedProperty
boolean isUnnamed();

/**
* Useful proxy to {@link #getDefaultExpression()}.
*/
Expand Down
46 changes: 46 additions & 0 deletions src/main/java/spoon/reflect/code/CtUnnamedPattern.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* SPDX-License-Identifier: (MIT OR CECILL-C)
*
* Copyright (C) 2006-2023 INRIA and contributors
*
* Spoon is available either under the terms of the MIT License (see LICENSE-MIT.txt) or the Cecill-C License (see LICENSE-CECILL-C.txt). You as the user are entitled to choose the terms under which to adopt Spoon.
*/
package spoon.reflect.code;

import spoon.reflect.reference.CtTypeReference;
import spoon.support.UnsettableProperty;

import java.util.List;

/**
* This code element defines an unnamed pattern, introduced in Java 2
* by <a href=https://openjdk.java.net/jeps/394>JEP 456</a>.
* <p>
* Example:
* <pre>
* Object obj = new Object();
* record X(int i) {}
* int i = switch (obj) {
* case X(_) -> 0; // an unnamed pattern does neither mention a type nor a name
* case null, default -> -1;
* };
* </pre>
*/
public interface CtUnnamedPattern extends CtPattern, CtExpression<Void> {

@Override
CtUnnamedPattern clone();

@Override
@UnsettableProperty
List<CtTypeReference<?>> getTypeCasts();

@Override
@UnsettableProperty
<C extends CtExpression<Void>> C setTypeCasts(List<CtTypeReference<?>> types);

@Override
@UnsettableProperty
<C extends CtExpression<Void>> C addTypeCast(CtTypeReference<?> type);

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public interface CtNamedElement extends CtElement {
<T extends CtNamedElement> T setSimpleName(String simpleName);

/**
* Returns the corresponding reference.
* {@return the corresponding reference}
*/
@DerivedProperty
CtReference getReference();
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/spoon/reflect/declaration/CtParameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ public interface CtParameter<T> extends CtVariable<T>, CtShadowable {
@UnsettableProperty
<C extends CtVariable<T>> C setDefaultExpression(CtExpression<T> assignedExpression);

/**
* {@return whether this parameter is <a href="https://openjdk.org/jeps/456">unnamed</a>}
* Unnamed parameters are always lambda parameters.
*/
@DerivedProperty
boolean isUnnamed();

/**
* Returns true if this parameter is a lambda parameter with type defined using the `var` keyword (since Java 11).
*/
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/spoon/reflect/factory/CoreFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtTypePattern;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtUnnamedPattern;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.code.CtVariableWrite;
import spoon.reflect.code.CtWhile;
Expand Down Expand Up @@ -660,4 +661,9 @@ BodyHolderSourcePosition createBodyHolderSourcePosition(
* @return the created receiver parameter.
*/
CtReceiverParameter createReceiverParameter();

/**
* {@return an unnamed pattern}
*/
CtUnnamedPattern createUnnamedPattern();
}
6 changes: 6 additions & 0 deletions src/main/java/spoon/reflect/visitor/CtAbstractVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtTypePattern;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtUnnamedPattern;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.code.CtVariableWrite;
import spoon.reflect.code.CtWhile;
Expand Down Expand Up @@ -570,4 +571,9 @@ public void visitCtReceiverParameter(CtReceiverParameter receiverParameter) {
public void visitCtRecordPattern(CtRecordPattern recordPattern) {

}

@Override
public void visitCtUnnamedPattern(CtUnnamedPattern unnamedPattern) {

}
}
11 changes: 11 additions & 0 deletions src/main/java/spoon/reflect/visitor/CtBiScannerDefault.java
Original file line number Diff line number Diff line change
Expand Up @@ -1119,4 +1119,15 @@ public void visitCtRecordPattern(spoon.reflect.code.CtRecordPattern recordPatter
biScan(spoon.reflect.path.CtRole.COMMENT, recordPattern.getComments(), other.getComments());
exit(recordPattern);
}

// autogenerated by CtBiScannerGenerator
@java.lang.Override
public void visitCtUnnamedPattern(spoon.reflect.code.CtUnnamedPattern unnamedPattern) {
spoon.reflect.code.CtUnnamedPattern other = ((spoon.reflect.code.CtUnnamedPattern) (this.stack.peek()));
enter(unnamedPattern);
biScan(spoon.reflect.path.CtRole.ANNOTATION, unnamedPattern.getAnnotations(), other.getAnnotations());
biScan(spoon.reflect.path.CtRole.TYPE, unnamedPattern.getType(), other.getType());
biScan(spoon.reflect.path.CtRole.COMMENT, unnamedPattern.getComments(), other.getComments());
exit(unnamedPattern);
}
}
10 changes: 10 additions & 0 deletions src/main/java/spoon/reflect/visitor/CtInheritanceScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtTypePattern;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtUnnamedPattern;
import spoon.reflect.code.CtVariableAccess;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.code.CtVariableWrite;
Expand Down Expand Up @@ -1132,4 +1133,13 @@ public void visitCtReceiverParameter(CtReceiverParameter e) {
scanCtShadowable(e);
}

@Override
public void visitCtUnnamedPattern(CtUnnamedPattern pattern) {
scanCtPattern(pattern);
scanCtExpression(pattern);
scanCtTypedElement(pattern);
scanCtCodeElement(pattern);
scanCtElement(pattern);
scanCtVisitable(pattern);
}
}
10 changes: 10 additions & 0 deletions src/main/java/spoon/reflect/visitor/CtScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtTypePattern;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtUnnamedPattern;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.code.CtVariableWrite;
import spoon.reflect.code.CtWhile;
Expand Down Expand Up @@ -1115,5 +1116,14 @@ public void visitCtRecordPattern(CtRecordPattern recordPattern) {
scan(CtRole.COMMENT, recordPattern.getComments());
exit(recordPattern);
}

@Override
public void visitCtUnnamedPattern(CtUnnamedPattern unnamedPattern) {
enter(unnamedPattern);
scan(CtRole.ANNOTATION, unnamedPattern.getAnnotations());
scan(CtRole.TYPE, unnamedPattern.getType());
scan(CtRole.COMMENT, unnamedPattern.getComments());
exit(unnamedPattern);
}
}

7 changes: 7 additions & 0 deletions src/main/java/spoon/reflect/visitor/CtVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtTypePattern;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtUnnamedPattern;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.code.CtVariableWrite;
import spoon.reflect.code.CtWhile;
Expand Down Expand Up @@ -577,4 +578,10 @@ <T, A extends T> void visitCtOperatorAssignment(
* @param receiverParameter the receiver parameter to visit.
*/
void visitCtReceiverParameter(CtReceiverParameter receiverParameter);

/**
* Visits an unnamed pattern.
* @param unnamedPattern the unnamed pattern to visit.
*/
void visitCtUnnamedPattern(CtUnnamedPattern unnamedPattern);
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtTypePattern;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtUnnamedPattern;
import spoon.reflect.code.CtVariableAccess;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.code.CtVariableWrite;
Expand Down Expand Up @@ -2383,4 +2384,9 @@ public void visitCtReceiverParameter(CtReceiverParameter receiverParameter) {
printer.writeSeparator("this");
}
}

@Override
public void visitCtUnnamedPattern(CtUnnamedPattern unnamedPattern) {
printer.writeKeyword(CtLocalVariable.UNNAMED_VARIABLE_NAME);
}
}
12 changes: 12 additions & 0 deletions src/main/java/spoon/support/DefaultCoreFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtTypePattern;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtUnnamedPattern;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.code.CtVariableWrite;
import spoon.reflect.code.CtWhile;
Expand Down Expand Up @@ -165,6 +166,7 @@
import spoon.support.reflect.code.CtTypeAccessImpl;
import spoon.support.reflect.code.CtTypePatternImpl;
import spoon.support.reflect.code.CtUnaryOperatorImpl;
import spoon.support.reflect.code.CtUnnamedPatternImpl;
import spoon.support.reflect.code.CtVariableReadImpl;
import spoon.support.reflect.code.CtVariableWriteImpl;
import spoon.support.reflect.code.CtWhileImpl;
Expand Down Expand Up @@ -1126,6 +1128,9 @@ public CtElement create(Class<? extends CtElement> klass) {
if (klass.equals(spoon.reflect.declaration.CtReceiverParameter.class)) {
return createReceiverParameter();
}
if (klass.equals(spoon.reflect.code.CtUnnamedPattern.class)) {
return createUnnamedPattern();
}
throw new IllegalArgumentException("not instantiable by CoreFactory(): " + klass);
}

Expand Down Expand Up @@ -1230,4 +1235,11 @@ public CtReceiverParameter createReceiverParameter() {
receiverParameter.setFactory(getMainFactory());
return receiverParameter;
}

@Override
public CtUnnamedPattern createUnnamedPattern() {
CtUnnamedPattern unnamedPattern = new CtUnnamedPatternImpl();
unnamedPattern.setFactory(getMainFactory());
return unnamedPattern;
}
}
Loading

0 comments on commit 6179f83

Please sign in to comment.