Skip to content

Commit

Permalink
Java: introduce separate PsiFragment instead of reusing PsiLiteral (I…
Browse files Browse the repository at this point in the history
…J-CR-110406)

GitOrigin-RevId: d1afe86a28022d13776f98fa2a4f89a051497f80
  • Loading branch information
BasLeijdekkers authored and intellij-monorepo-bot committed Jul 19, 2023
1 parent 69cae6f commit 4923f81
Show file tree
Hide file tree
Showing 24 changed files with 125 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,11 @@ public void visitField(@NotNull PsiField field) {
public void visitForeachPatternStatement(@NotNull PsiForeachPatternStatement statement) {
visitForeachStatementBase(statement);
}

public void visitForeachStatement(@NotNull PsiForeachStatement statement) {
visitForeachStatementBase(statement);
}

public void visitForeachStatementBase(@NotNull PsiForeachStatementBase statement) {
visitStatement(statement);
}
Expand All @@ -171,6 +173,10 @@ public void visitForStatement(@NotNull PsiForStatement statement) {
visitStatement(statement);
}

public void visitFragment(@NotNull PsiFragment fragment) {
visitElement(fragment);
}

public void visitIdentifier(@NotNull PsiIdentifier identifier) {
visitJavaToken(identifier);
}
Expand Down
21 changes: 21 additions & 0 deletions java/java-psi-api/src/com/intellij/psi/PsiFragment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.psi;

import com.intellij.psi.tree.IElementType;

/**
* @author Bas Leijdekkers
*/
public interface PsiFragment extends PsiLiteralValue {

/**
* Returns the type of the token.
* One of the fields STRING_TEMPLATE_BEGIN, STRING_TEMPLATE_MID, STRING_TEMPLATE_END,
* TEXT_BLOCK_TEMPLATE_BEGIN, TEXT_BLOCK_TEMPLATE_MID or TEXT_BLOCK_TEMPLATE_END of JavaTokenType.
*
* @return the token type.
*/
IElementType getTokenType();

boolean isTextBlock();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,4 @@ public interface PsiLiteralExpression extends PsiExpression, PsiLiteral {
default boolean isTextBlock() {
return false;
}

default boolean isFragment() {
return false;
}
}
2 changes: 1 addition & 1 deletion java/java-psi-api/src/com/intellij/psi/PsiTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public interface PsiTemplate extends PsiExpression {
/**
* @return the fragments of this template.
*/
@NotNull List<@NotNull PsiLiteralExpression> getFragments();
@NotNull List<@NotNull PsiFragment> getFragments();

/**
* @return the embedded expression in this template;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public OldExpressionParser(@NotNull JavaParser javaParser) {
public PsiBuilder.Marker parse(@NotNull PsiBuilder builder) {
return parseAssignment(builder);
}

@Nullable
PsiBuilder.Marker parse(@NotNull PsiBuilder builder, final int mode) {
return parseAssignment(builder, mode);
Expand Down Expand Up @@ -393,7 +394,7 @@ else if (dotTokenType == JavaTokenType.STRING_LITERAL || dotTokenType == JavaTok
builder.advanceLexer();
literal.done(JavaElementType.LITERAL_EXPRESSION);
templateExpression.done(JavaElementType.TEMPLATE_EXPRESSION);
expr = templateExpression;
expr = templateExpression;
}
else if (THIS_OR_SUPER.contains(dotTokenType) && exprType(expr) == JavaElementType.REFERENCE_EXPRESSION) {
if (breakPoint == BreakPoint.P2 && builder.getCurrentOffset() == breakOffset) {
Expand Down Expand Up @@ -513,17 +514,17 @@ else if (tokenType == JavaTokenType.DOUBLE_COLON) {
private PsiBuilder.Marker parsePrimaryExpressionStart(final PsiBuilder builder, final int mode) {
IElementType tokenType = builder.getTokenType();

if (tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN || tokenType == JavaTokenType.STRING_TEMPLATE_BEGIN) {
return parseStringTemplate(builder, tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN);
}

if (ElementType.ALL_LITERALS.contains(tokenType)) {
final PsiBuilder.Marker literal = builder.mark();
builder.advanceLexer();
literal.done(JavaElementType.LITERAL_EXPRESSION);
return literal;
}

if (tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN || tokenType == JavaTokenType.STRING_TEMPLATE_BEGIN) {
return parseStringTemplate(builder, tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN);
}

if (tokenType == JavaTokenType.LBRACE) {
return parseArrayInitializer(builder);
}
Expand Down Expand Up @@ -698,9 +699,7 @@ private PsiBuilder.Marker parseStringTemplate(PsiBuilder builder, boolean textBl
final PsiBuilder.Marker template = builder.mark();
IElementType tokenType;
do {
final PsiBuilder.Marker literal = builder.mark();
builder.advanceLexer();
literal.done(JavaElementType.LITERAL_EXPRESSION);
tokenType = builder.getTokenType();
if (textBlock
? tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_MID || tokenType == JavaTokenType.TEXT_BLOCK_TEMPLATE_END
Expand All @@ -716,9 +715,7 @@ private PsiBuilder.Marker parseStringTemplate(PsiBuilder builder, boolean textBl
builder.error(JavaPsiBundle.message("expected.template.fragment"));
}
else {
final PsiBuilder.Marker literal = builder.mark();
builder.advanceLexer();
literal.done(JavaElementType.LITERAL_EXPRESSION);
}
template.done(JavaElementType.TEMPLATE);
return template;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen

TokenSet INTEGER_LITERALS = TokenSet.create(INTEGER_LITERAL, LONG_LITERAL);
TokenSet REAL_LITERALS = TokenSet.create(FLOAT_LITERAL, DOUBLE_LITERAL);
TokenSet STRING_LITERALS = TokenSet.create(STRING_LITERAL, TEXT_BLOCK_LITERAL,
TEXT_BLOCK_TEMPLATE_BEGIN, TEXT_BLOCK_TEMPLATE_MID, TEXT_BLOCK_TEMPLATE_END,
STRING_TEMPLATE_BEGIN, STRING_TEMPLATE_MID, STRING_TEMPLATE_END);
TokenSet STRING_LITERALS = TokenSet.create(STRING_LITERAL, TEXT_BLOCK_LITERAL);
TokenSet TEXT_LITERALS = TokenSet.create(STRING_LITERAL, TEXT_BLOCK_LITERAL, CHARACTER_LITERAL);

TokenSet STRING_TEMPLATE_FRAGMENTS =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.intellij.psi.impl.source.javadoc.PsiDocTagValueImpl;
import com.intellij.psi.impl.source.javadoc.PsiDocTokenImpl;
import com.intellij.psi.impl.source.javadoc.PsiSnippetAttributeValueImpl;
import com.intellij.psi.impl.source.tree.java.PsiFragmentImpl;
import com.intellij.psi.impl.source.tree.java.PsiIdentifierImpl;
import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl;
import com.intellij.psi.impl.source.tree.java.PsiKeywordImpl;
Expand All @@ -31,6 +32,9 @@ public LeafElement createLeaf(@NotNull IElementType type, @NotNull CharSequence
if (ElementType.KEYWORD_BIT_SET.contains(type)) {
return new PsiKeywordImpl(type, text);
}
if (ElementType.STRING_TEMPLATE_FRAGMENTS.contains(type)) {
return new PsiFragmentImpl(type, text);
}
if (type instanceof IJavaElementType) {
return new PsiJavaTokenImpl(type, text);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.psi.impl.source.tree.java;

import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFragment;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* @author Bas Leijdekkers
*/
public final class PsiFragmentImpl extends LeafPsiElement implements PsiFragment {

public PsiFragmentImpl(@NotNull IElementType type, @NotNull CharSequence text) {
super(type, text);
}

@Override
public void accept(@NotNull PsiElementVisitor visitor) {
if (visitor instanceof JavaElementVisitor) {
((JavaElementVisitor)visitor).visitFragment(this);
}
else {
visitor.visitElement(this);
}
}

@Override
public @Nullable Object getValue() {
return null;
}

@Override
public IElementType getTokenType() {
return getElementType();
}

@Override
public boolean isTextBlock() {
final IElementType token = getElementType();
return token == JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN ||
token == JavaTokenType.TEXT_BLOCK_TEMPLATE_MID ||
token == JavaTokenType.TEXT_BLOCK_TEMPLATE_END;
}

@Override
public String toString(){
return "PsiFragment:" + getElementType();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ public class PsiLiteralExpressionImpl
implements PsiLiteralExpression, PsiLanguageInjectionHost, ContributedReferenceHost {

private static final TokenSet NUMERIC_LITERALS = TokenSet.orSet(ElementType.INTEGER_LITERALS, ElementType.REAL_LITERALS);
private static final TokenSet TEXT_BLOCK_LITERALS =
TokenSet.create(JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN, JavaTokenType.TEXT_BLOCK_TEMPLATE_MID, JavaTokenType.TEXT_BLOCK_TEMPLATE_END,
JavaTokenType.TEXT_BLOCK_LITERAL);

public PsiLiteralExpressionImpl(@NotNull PsiLiteralStub stub) {
super(stub, JavaStubElementTypes.LITERAL_EXPRESSION);
Expand Down Expand Up @@ -76,12 +73,7 @@ public PsiType getType() {

@Override
public boolean isTextBlock() {
return TEXT_BLOCK_LITERALS.contains(getLiteralElementType());
}

@Override
public boolean isFragment() {
return ElementType.STRING_TEMPLATE_FRAGMENTS.contains(getLiteralElementType());
return getLiteralElementType() == JavaTokenType.TEXT_BLOCK_LITERAL;
}

public IElementType getLiteralElementType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ public void accept(@NotNull PsiElementVisitor visitor) {
}

@Override
public @NotNull List<@NotNull PsiLiteralExpression> getFragments() {
final List<PsiLiteralExpression> result = new ArrayList<>();
public @NotNull List<@NotNull PsiFragment> getFragments() {
final List<PsiFragment> result = new ArrayList<>();
PsiElement @NotNull [] children = getChildren();
for (int i = 0, length = children.length; i < length; i += 2) {
result.add((PsiLiteralExpression)children[i]);
result.add((PsiFragment)children[i]);
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ PsiJavaFile:StringTemplate2.java
PsiIdentifier:STR('STR')
PsiJavaToken:DOT('.')
PsiTemplate
PsiLiteralExpression:"\{
PsiJavaToken:STRING_TEMPLATE_BEGIN('"\{')
PsiFragment:STRING_TEMPLATE_BEGIN('"\{')
PsiExpression(empty)
<empty list>
PsiLiteralExpression:}"
PsiJavaToken:STRING_TEMPLATE_END('}"')
PsiFragment:STRING_TEMPLATE_END('}"')
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ PsiJavaFile:StringTemplate3.java
PsiIdentifier:STR('STR')
PsiJavaToken:DOT('.')
PsiTemplate
PsiLiteralExpression:"\{
PsiJavaToken:STRING_TEMPLATE_BEGIN('"\{')
PsiFragment:STRING_TEMPLATE_BEGIN('"\{')
PsiWhiteSpace(' ')
PsiLiteralExpression:1
PsiJavaToken:INTEGER_LITERAL('1')
PsiWhiteSpace(' ')
PsiLiteralExpression:}"
PsiJavaToken:STRING_TEMPLATE_END('}"')
PsiFragment:STRING_TEMPLATE_END('}"')
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,17 @@ PsiJavaFile:StringTemplate4.java
PsiIdentifier:STR('STR')
PsiJavaToken:DOT('.')
PsiTemplate
PsiLiteralExpression:"\{
PsiJavaToken:STRING_TEMPLATE_BEGIN('"\{')
PsiFragment:STRING_TEMPLATE_BEGIN('"\{')
PsiWhiteSpace(' ')
PsiParenthesizedExpression:(1)
PsiJavaToken:LPARENTH('(')
PsiLiteralExpression:1
PsiJavaToken:INTEGER_LITERAL('1')
PsiJavaToken:RPARENTH(')')
PsiWhiteSpace(' ')
PsiLiteralExpression:} \{
PsiJavaToken:STRING_TEMPLATE_MID('} \{')
PsiFragment:STRING_TEMPLATE_MID('} \{')
PsiWhiteSpace(' ')
PsiLiteralExpression:"!"
PsiJavaToken:STRING_LITERAL('"!"')
PsiWhiteSpace(' ')
PsiLiteralExpression:}"
PsiJavaToken:STRING_TEMPLATE_END('}"')
PsiFragment:STRING_TEMPLATE_END('}"')
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ PsiJavaFile:StringTemplate5.java
PsiIdentifier:STR('STR')
PsiJavaToken:DOT('.')
PsiTemplate
PsiLiteralExpression:"\{
PsiJavaToken:STRING_TEMPLATE_BEGIN('"\{')
PsiFragment:STRING_TEMPLATE_BEGIN('"\{')
PsiWhiteSpace(' ')
PsiLiteralExpression:"""
!"""
PsiJavaToken:TEXT_BLOCK_LITERAL('"""\n!"""')
PsiWhiteSpace(' ')
PsiLiteralExpression:}"
PsiJavaToken:STRING_TEMPLATE_END('}"')
PsiFragment:STRING_TEMPLATE_END('}"')
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
PsiJavaFile:StringTemplate6.java
PsiTemplate
PsiLiteralExpression:"\{
PsiJavaToken:STRING_TEMPLATE_BEGIN('"\{')
PsiFragment:STRING_TEMPLATE_BEGIN('"\{')
PsiExpression(empty)
<empty list>
PsiLiteralExpression:}"
PsiJavaToken:STRING_TEMPLATE_END('}"')
PsiFragment:STRING_TEMPLATE_END('}"')
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ PsiJavaFile:StringTemplate7.java
PsiIdentifier:STR('STR')
PsiJavaToken:DOT('.')
PsiTemplate
PsiLiteralExpression:"\{
PsiJavaToken:STRING_TEMPLATE_BEGIN('"\{')
PsiFragment:STRING_TEMPLATE_BEGIN('"\{')
PsiExpression(empty)
<empty list>
PsiLiteralExpression:}"
PsiJavaToken:STRING_TEMPLATE_END('}"')
PsiFragment:STRING_TEMPLATE_END('}"')
PsiJavaToken:DOT('.')
PsiReferenceParameterList
<empty list>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ PsiJavaFile:StringTemplate8.java
PsiIdentifier:STR('STR')
PsiJavaToken:DOT('.')
PsiTemplate
PsiLiteralExpression:"\{
PsiJavaToken:STRING_TEMPLATE_BEGIN('"\{')
PsiFragment:STRING_TEMPLATE_BEGIN('"\{')
PsiErrorElement:Template fragment expected
<empty list>
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ PsiJavaFile:TextBlockTemplate2.java
PsiIdentifier:STR('STR')
PsiJavaToken:DOT('.')
PsiTemplate
PsiLiteralExpression:"""
\{
PsiJavaToken:TEXT_BLOCK_TEMPLATE_BEGIN('"""\n\{')
PsiFragment:TEXT_BLOCK_TEMPLATE_BEGIN('"""\n\{')
PsiExpression(empty)
<empty list>
PsiLiteralExpression:}"""
PsiJavaToken:TEXT_BLOCK_TEMPLATE_END('}"""')
PsiFragment:TEXT_BLOCK_TEMPLATE_END('}"""')
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ PsiJavaFile:TextBlockTemplate3.java
PsiIdentifier:STR('STR')
PsiJavaToken:DOT('.')
PsiTemplate
PsiLiteralExpression:"""
\{
PsiJavaToken:TEXT_BLOCK_TEMPLATE_BEGIN('"""\n\{')
PsiFragment:TEXT_BLOCK_TEMPLATE_BEGIN('"""\n\{')
PsiWhiteSpace(' ')
PsiLiteralExpression:1
PsiJavaToken:INTEGER_LITERAL('1')
PsiWhiteSpace(' ')
PsiLiteralExpression:}"""
PsiJavaToken:TEXT_BLOCK_TEMPLATE_END('}"""')
PsiFragment:TEXT_BLOCK_TEMPLATE_END('}"""')
Loading

0 comments on commit 4923f81

Please sign in to comment.