Skip to content

Commit

Permalink
Experiment on match-fail.
Browse files Browse the repository at this point in the history
  • Loading branch information
lahodaj committed Jul 12, 2024
1 parent 4804806 commit dba3c8e
Show file tree
Hide file tree
Showing 19 changed files with 256 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2019, 2020, 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;

import java.util.List;

/**
* A tree node for a {@code match} statement.
*
* For example:
* <pre>
* match <em>name</em> ( <em>parameters</em> );
* </pre>
*
* @jls XX.XX The match Statement
*
* @since 23
*/
@PreviewFeature(feature= PreviewFeature.Feature.PATTERN_DECLARATIONS, reflective=true)
public interface MatchFailTree extends StatementTree {
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@
*
* @since 23
*/
@PreviewFeature(feature= PreviewFeature.Feature.PATTERN_DECLARATIONS, reflective=true)
//TODO: maybe MatchSuccessTree?
public interface MatchTree extends StatementTree {

/**
* Returns the expression for this {@code match} statement.
*
* @return the expression
*/
@PreviewFeature(feature= PreviewFeature.Feature.PATTERN_DECLARATIONS, reflective=true)
List<? extends ExpressionTree> getArguments();
}
10 changes: 9 additions & 1 deletion src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,15 @@ public enum Kind {
* @since 23
*/
@PreviewFeature(feature=PreviewFeature.Feature.PATTERN_DECLARATIONS, reflective=true)
MATCH(MatchTree.class);
MATCH(MatchTree.class), //TODO: maybe MATCH_SUCCESS

/**
* Used for instances of {@link MatchFailTree}.
*
* @since 23
*/
@PreviewFeature(feature=PreviewFeature.Feature.PATTERN_DECLARATIONS, reflective=true)
MATCH_FAILED(MatchFailTree.class);

Kind(Class<? extends Tree> intf) {
associatedInterface = intf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,4 +621,12 @@ public interface TreeVisitor<R,P> {
* @return a result value
*/
R visitMatchStatement(MatchTree node, P p);

/**
* Visits an {@code MatchFailTree} node.
* @param node the node being visited
* @param p a parameter value
* @return a result value
*/
R visitMatchFailStatement(MatchFailTree node, P p);
}
Original file line number Diff line number Diff line change
Expand Up @@ -1070,4 +1070,18 @@ public R visitYield(YieldTree node, P p) {
public R visitMatchStatement(MatchTree 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}
*/
@Override
public R visitMatchFailStatement(MatchFailTree node, P p) {
return defaultAction(node, p);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1224,4 +1224,18 @@ public R visitYield(YieldTree node, P p) {
public R visitMatchStatement(MatchTree node, P p) {
return scan(node.getArguments(), p);
}

/**
* {@inheritDoc}
*
* @implSpec This implementation scans the children in left to right order.
*
* @param node {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of scanning
*/
@Override
public R visitMatchFailStatement(MatchFailTree node, P p) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2427,13 +2427,18 @@ public void visitMatch(JCMatch tree) {
args = args.tail;
}

if (tree.clazz != tree.meth.name) {
if (tree.clazz != null && tree.clazz != tree.meth.name) {
log.error(tree.pos(), Errors.MatchPatternNameWrong);
}

result = null;
}

@Override
public void visitMatchFail(JCMatchFail that) {
result = null;
}

public void visitContinue(JCContinue tree) {
tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
result = null;
Expand Down
16 changes: 14 additions & 2 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
Original file line number Diff line number Diff line change
Expand Up @@ -617,8 +617,11 @@ public void visitMethodDef(JCMethodDecl tree) {
scanStat(tree.body);
tree.completesNormally = alive != Liveness.DEAD;

if (alive == Liveness.ALIVE && !tree.sym.type.getReturnType().hasTag(VOID))
if (alive == Liveness.ALIVE && (tree.sym.flags() & PATTERN) != 0) {
log.error(TreeInfo.diagEndPos(tree.body), Errors.MissingMatchStmt);
} else if (alive == Liveness.ALIVE && !tree.sym.type.getReturnType().hasTag(VOID)) {
log.error(TreeInfo.diagEndPos(tree.body), Errors.MissingRetStmt);
}

clearPendingExits(true);
} finally {
Expand All @@ -632,7 +635,7 @@ private void clearPendingExits(boolean inMethod) {
while (exits.nonEmpty()) {
PendingExit exit = exits.head;
exits = exits.tail;
Assert.check((inMethod && (exit.tree.hasTag(RETURN) || exit.tree.hasTag(MATCH))) ||
Assert.check((inMethod && (exit.tree.hasTag(RETURN) || exit.tree.hasTag(MATCH) || exit.tree.hasTag(MATCH_FAIL))) ||
log.hasErrorOn(exit.tree.pos()));
}
}
Expand Down Expand Up @@ -696,6 +699,10 @@ public void visitMatch(JCMatch tree) {
recordExit(new PendingExit(tree));
}

public void visitMatchFail(JCMatchFail tree) {
recordExit(new PendingExit(tree));
}

public void visitForeachLoop(JCEnhancedForLoop tree) {
visitVarDef(tree.var);
ListBuffer<PendingExit> prevPendingExits = pendingExits;
Expand Down Expand Up @@ -1574,6 +1581,7 @@ else if ((tree.sym.flags() & (BLOCK | STATIC)) != BLOCK)
if (!(exit instanceof ThrownPendingExit)) {
Assert.check(exit.tree.hasTag(RETURN) ||
exit.tree.hasTag(MATCH) ||
exit.tree.hasTag(MATCH_FAIL) ||
log.hasErrorOn(exit.tree.pos()));
} else {
// uncaught throws will be reported later
Expand Down Expand Up @@ -1835,6 +1843,10 @@ public void visitMatch(JCMatch tree) {
recordExit(new PendingExit(tree));
}

public void visitMatchFail(JCMatchFail tree) {
recordExit(new PendingExit(tree));
}

public void visitThrow(JCThrow tree) {
scan(tree.expr);
Symbol sym = TreeInfo.symbol(tree.expr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,11 @@ public void visitMatch(JCMatch tree) {
result = make.at(tree.pos).Block(0, stats.toList());
}

@Override
public void visitMatchFail(JCTree.JCMatchFail tree) {
result = make.at(tree.pos).Return(makeNull());
}

private class PrimitiveGenerator extends Types.SignatureGenerator {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2931,6 +2931,26 @@ List<JCStatement> blockStatement() {
List<JCExpression> args = arguments();
accept(SEMI);
return List.of(toP(F.at(pos).Match(name, args)));
} else if (next.kind == SUB) {
Token nextNext = S.token(2);
if (nextNext.kind == IDENTIFIER) {
if (nextNext.name().contentEquals("success")) {
checkSourceLevel(Feature.PATTERN_DECLARATIONS);
nextToken();
nextToken();
nextToken();
List<JCExpression> args = arguments();
accept(SEMI);
return List.of(toP(F.at(pos).Match(null, args)));
} else if (nextNext.name().contentEquals("fail")) {
checkSourceLevel(Feature.PATTERN_DECLARATIONS);
nextToken();
nextToken();
nextToken();
accept(SEMI);
return List.of(toP(F.at(pos).MatchFail()));
}
}
}
} else
if (token.name() == names.yield && allowYieldStatement) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,9 @@ compiler.err.missing.meth.body.or.decl.abstract=\
compiler.err.missing.ret.stmt=\
missing return statement

compiler.err.missing.match.stmt=\
missing match statement

# 0: type
compiler.misc.missing.ret.val=\
missing return value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ public enum Tag {
*/
MATCH,

/** Match fail statements, of type MatchFail.
*/
MATCH_FAIL,

/** Method invocation expressions, of type Apply.
*/
APPLY,
Expand Down Expand Up @@ -1769,6 +1773,28 @@ public Tag getTag() {
}
}

/**
* The match-fail statement
*/
public static class JCMatchFail extends JCStatement implements MatchFailTree {

protected JCMatchFail() {
}
@Override
public void accept(Visitor v) { v.visitMatchFail(this); }

@DefinedBy(Api.COMPILER_TREE)
public Kind getKind() { return Kind.MATCH_FAILED; }
@Override @DefinedBy(Api.COMPILER_TREE)
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
return v.visitMatchFailStatement(this, d);
}
@Override
public Tag getTag() {
return MATCH_FAIL;
}
}

/**
* A continue of a loop.
*/
Expand Down Expand Up @@ -3589,6 +3615,7 @@ public abstract static class Visitor {
public void visitBreak(JCBreak that) { visitTree(that); }
public void visitYield(JCYield that) { visitTree(that); }
public void visitMatch(JCMatch that) { visitTree(that); }
public void visitMatchFail(JCMatchFail that) { visitTree(that); }
public void visitContinue(JCContinue that) { visitTree(that); }
public void visitReturn(JCReturn that) { visitTree(that); }
public void visitThrow(JCThrow that) { visitTree(that); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ public JCTree visitMatchStatement(MatchTree node, P p) {
return M.at(t.pos).Match(t.clazz, args);
}

@DefinedBy(Api.COMPILER_TREE)
public JCTree visitMatchFailStatement(MatchFailTree node, P p) {
JCMatchFail t = (JCMatchFail) node;

return M.at(t.pos).MatchFail();
}

@DefinedBy(Api.COMPILER_TREE)
public JCTree visitCase(CaseTree node, P p) {
JCCase t = (JCCase) node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,12 @@ public JCMatch Match(Name clazz, List<JCExpression> args) {
return tree;
}

public JCMatchFail MatchFail() {
JCMatchFail tree = new JCMatchFail();
tree.pos = pos;
return tree;
}

public JCMethodInvocation Apply(List<JCExpression> typeargs,
JCExpression fn,
List<JCExpression> args)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ public void visitMatch(JCMatch tree) {
scan(tree.args);
}

public void visitMatchFail(JCMatchFail tree) {
}

public void visitContinue(JCContinue tree) {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@ public void visitMatch(JCMatch tree) {
result = tree;
}

@Override
public void visitMatchFail(JCMatchFail tree) {
result = tree;
}

public void visitContinue(JCContinue tree) {
result = tree;
}
Expand Down
Loading

0 comments on commit dba3c8e

Please sign in to comment.