Replaced PrefixExpression with LabeledExpression

where labeled expression is used

Added 'visitLabeledExpression'
This commit is contained in:
Svetlana Isakova
2014-05-15 14:45:41 +04:00
parent 04729f5985
commit f109cfc303
22 changed files with 108 additions and 131 deletions
@@ -2917,23 +2917,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Nullable
private static JetSimpleNameExpression targetLabel(JetExpression expression) {
if (expression.getParent() instanceof JetPrefixExpression) {
JetPrefixExpression parent = (JetPrefixExpression) expression.getParent();
JetSimpleNameExpression operationSign = parent.getOperationReference();
if (operationSign.getReferencedNameElementType() == JetTokens.LABEL_IDENTIFIER) {
return operationSign;
}
if (expression.getParent() instanceof JetLabeledExpression) {
return ((JetLabeledExpression) expression.getParent()).getTargetLabel();
}
return null;
}
@Override
public StackValue visitPrefixExpression(@NotNull JetPrefixExpression expression, StackValue receiver) {
JetSimpleNameExpression operationSign = expression.getOperationReference();
if (operationSign.getReferencedNameElementType() == JetTokens.LABEL_IDENTIFIER) {
return genQualified(receiver, expression.getBaseExpression());
}
public StackValue visitLabeledExpression(
@NotNull JetLabeledExpression expression, StackValue receiver
) {
return genQualified(receiver, expression.getBaseExpression());
}
@Override
public StackValue visitPrefixExpression(@NotNull JetPrefixExpression expression, StackValue receiver) {
DeclarationDescriptor op = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
assert op instanceof FunctionDescriptor : String.valueOf(op);
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
@@ -96,9 +96,9 @@ public class DebugInfoUtil {
if (EXCLUDED.contains(referencedNameElementType)) {
return;
}
if (referencedNameElementType == JetTokens.LABEL_IDENTIFIER) return;
}
else if (nameExpression.getReferencedNameElementType() == JetTokens.THIS_KEYWORD) {
if (elementType == JetNodeTypes.LABEL_REFERENCE ||
nameExpression.getReferencedNameElementType() == JetTokens.THIS_KEYWORD) {
return;
}
}
@@ -229,18 +229,11 @@ public class JetControlFlowProcessor {
}
@Override
public void visitExpressionWithLabelVoid(@NotNull JetExpressionWithLabel expression, CFPContext context) {
String labelName = expression.getLabelName();
JetExpression labeledExpression = expression.getLabeledExpression();
if (labelName != null && labeledExpression != null) {
visitLabeledExpression(labelName, labeledExpression, context);
}
}
private void visitLabeledExpression(@NotNull String labelName, @NotNull JetExpression labeledExpression, CFPContext context) {
JetExpression deparenthesized = JetPsiUtil.deparenthesize(labeledExpression);
if (deparenthesized != null) {
generateInstructions(labeledExpression, context);
public void visitLabeledExpressionVoid(@NotNull JetLabeledExpression expression, CFPContext context) {
mark(expression);
JetExpression baseExpression = expression.getBaseExpression();
if (baseExpression != null) {
generateInstructions(baseExpression, context);
}
}
@@ -374,11 +367,7 @@ public class JetControlFlowProcessor {
IElementType operationType = operationSign.getReferencedNameElementType();
JetExpression baseExpression = expression.getBaseExpression();
if (baseExpression == null) return;
if (operationType == JetTokens.LABEL_IDENTIFIER) {
String referencedName = operationSign.getReferencedName();
visitLabeledExpression(referencedName.substring(1), baseExpression, context);
}
else if (JetTokens.EXCLEXCL == operationType) {
if (JetTokens.EXCLEXCL == operationType) {
generateInstructions(baseExpression, NOT_IN_CONDITION);
builder.predefinedOperation(expression, NOT_NULL_ASSERTION);
}
@@ -102,14 +102,12 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
return null
}
override fun visitPrefixExpression(expression: JetPrefixExpression, expectedType: JetType?): CompileTimeConstant<*>? {
val deparenthesizedExpression = JetPsiUtil.deparenthesize(expression)
return if (deparenthesizedExpression != null && deparenthesizedExpression != expression) {
evaluate(deparenthesizedExpression, expectedType)
}
else {
super.visitPrefixExpression(expression, expectedType)
override fun visitLabeledExpression(expression: JetLabeledExpression, expectedType: JetType?): CompileTimeConstant<*>? {
val baseExpression = expression.getBaseExpression()
if (baseExpression != null) {
return evaluate(baseExpression, expectedType)
}
return null
}
override fun visitStringTemplateExpression(expression: JetStringTemplateExpression, expectedType: JetType?): CompileTimeConstant<*>? {
@@ -76,13 +76,11 @@ public class JetCallExpression extends JetReferenceExpression implements JetCall
if (psi instanceof JetFunctionLiteralExpression) {
result.add((JetFunctionLiteralExpression) psi);
}
else if (psi instanceof JetPrefixExpression) {
JetPrefixExpression prefixExpression = (JetPrefixExpression) psi;
if (prefixExpression.getOperationReference().getReferencedNameElementType() == JetTokens.LABEL_IDENTIFIER) {
JetExpression labeledExpression = prefixExpression.getBaseExpression();
if (labeledExpression instanceof JetFunctionLiteralExpression) {
result.add(prefixExpression);
}
else if (psi instanceof JetLabeledExpression) {
JetLabeledExpression labeledExpression = (JetLabeledExpression) psi;
JetExpression baseExpression = labeledExpression.getBaseExpression();
if (baseExpression instanceof JetFunctionLiteralExpression) {
result.add(labeledExpression);
}
}
node = node.getTreeNext();
@@ -34,15 +34,15 @@ public class JetExpressionWithLabel extends JetExpressionImpl {
return (JetSimpleNameExpression) qualifier.findChildByType(JetNodeTypes.LABEL_REFERENCE);
}
@Nullable @IfNotParsed
public JetExpression getLabeledExpression() {
return findChildByClass(JetExpression.class);
}
@Nullable
public String getLabelName() {
JetSimpleNameExpression labelElement = getTargetLabel();
assert labelElement == null || labelElement.getText().startsWith("@");
return labelElement == null ? null : labelElement.getText().substring(1);
}
@Override
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitExpressionWithLabel(this, data);
}
}
@@ -47,4 +47,9 @@ public class JetLabeledExpression extends JetExpressionWithLabel {
public JetExpression getBaseExpression() {
return findChildByClass(JetExpression.class);
}
@Override
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitLabeledExpression(this, data);
}
}
@@ -107,8 +107,8 @@ public class JetPsiUtil {
}
}
}
else if (expression instanceof JetPrefixExpression) {
JetExpression baseExpression = getBaseExpressionIfLabeledExpression((JetPrefixExpression) expression);
else if (expression instanceof JetLabeledExpression) {
JetExpression baseExpression = ((JetLabeledExpression) expression).getBaseExpression();
if (baseExpression != null) {
expression = baseExpression;
}
@@ -124,26 +124,6 @@ public class JetPsiUtil {
return expression;
}
@Nullable
public static JetExpression getBaseExpressionIfLabeledExpression(@NotNull JetPrefixExpression expression) {
if (isLabeledExpression(expression)) {
return expression.getBaseExpression();
}
return null;
}
public static boolean isLabeledExpression(JetPrefixExpression expression) {
return expression.getOperationReference().getReferencedNameElementType() == JetTokens.LABEL_IDENTIFIER;
}
@NotNull
public static String getLabelName(@NotNull JetPrefixExpression expression) {
assert isLabeledExpression(expression);
String labelName = expression.getOperationReference().getReferencedName();
assert labelName.startsWith("@") : "Incorrect label name " + expression.getText();
return labelName.substring(1);
}
@NotNull
public static Name safeName(@Nullable String name) {
return name == null ? SpecialNames.NO_NAME_PROVIDED : Name.identifier(name);
@@ -571,7 +551,7 @@ public class JetPsiUtil {
return maxPriority - 1;
}
if (expression instanceof JetPrefixExpression) return maxPriority - 2;
if (expression instanceof JetPrefixExpression || expression instanceof JetLabeledExpression) return maxPriority - 2;
if (expression instanceof JetDeclaration || expression instanceof JetStatementExpression || expression instanceof JetIfExpression) {
return 0;
@@ -625,7 +605,7 @@ public class JetPsiUtil {
IElementType parentOperation = getOperation(parentExpression);
// 'return (@label{...})' case
if (parentExpression instanceof JetReturnExpression && innerOperation == JetTokens.LABEL_IDENTIFIER) {
if (parentExpression instanceof JetReturnExpression && innerExpression instanceof JetLabeledExpression) {
return true;
}
@@ -170,6 +170,10 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
return visitExpression(expression, data);
}
public R visitLabeledExpression(@NotNull JetLabeledExpression expression, D data) {
return visitExpressionWithLabel(expression, data);
}
public R visitPrefixExpression(@NotNull JetPrefixExpression expression, D data) {
return visitUnaryExpression(expression, data);
}
@@ -169,6 +169,10 @@ public class JetVisitorVoid extends JetVisitor<Void, Void> {
super.visitReferenceExpression(expression, null);
}
public void visitLabeledExpression(@NotNull JetLabeledExpression expression) {
super.visitLabeledExpression(expression, null);
}
public void visitPrefixExpression(@NotNull JetPrefixExpression expression) {
super.visitPrefixExpression(expression, null);
}
@@ -630,6 +634,12 @@ public class JetVisitorVoid extends JetVisitor<Void, Void> {
return null;
}
@Override
public final Void visitLabeledExpression(@NotNull JetLabeledExpression expression, Void data) {
visitLabeledExpression(expression);
return null;
}
@Override
public final Void visitPrefixExpression(@NotNull JetPrefixExpression expression, Void data) {
visitPrefixExpression(expression);
@@ -170,6 +170,10 @@ public class JetVisitorVoidWithParameter<P> extends JetVisitor<Void, P> {
super.visitReferenceExpression(expression, data);
}
public void visitLabeledExpressionVoid(@NotNull JetLabeledExpression expression, P data) {
super.visitLabeledExpression(expression, data);
}
public void visitPrefixExpressionVoid(@NotNull JetPrefixExpression expression, P data) {
super.visitPrefixExpression(expression, data);
}
@@ -627,6 +631,12 @@ public class JetVisitorVoidWithParameter<P> extends JetVisitor<Void, P> {
return null;
}
@Override
public final Void visitLabeledExpression(@NotNull JetLabeledExpression expression, P data) {
visitLabeledExpressionVoid(expression, data);
return null;
}
@Override
public final Void visitPrefixExpression(@NotNull JetPrefixExpression expression, P data) {
visitPrefixExpressionVoid(expression, data);
@@ -492,8 +492,8 @@ public class CandidateResolver {
}
@Override
public JetExpression visitPrefixExpression(@NotNull JetPrefixExpression expression, Void data) {
return visitInnerExpression(JetPsiUtil.getBaseExpressionIfLabeledExpression(expression));
public JetExpression visitLabeledExpression(@NotNull JetLabeledExpression expression, Void data) {
return visitInnerExpression(expression.getBaseExpression());
}
@Override
@@ -105,16 +105,15 @@ public class InlineCallResolverExtension implements CallResolverExtension {
if (parent instanceof JetValueArgument ||
parent instanceof JetBinaryExpression ||
parent instanceof JetUnaryExpression ||
parent instanceof JetLabeledExpression ||
parent instanceof JetDotQualifiedExpression ||
parent instanceof JetCallExpression ||
parent instanceof JetArrayAccessExpression ||
parent instanceof JetMultiDeclaration) {
if (parent instanceof JetPrefixExpression) {
if (JetPsiUtil.isLabeledExpression((JetPrefixExpression) parent)) {
parent = parent.getParent();
continue;
}
if (parent instanceof JetLabeledExpression) {
parent = parent.getParent();
continue;
}
else if (parent instanceof JetBinaryExpression) {
JetToken token = JetPsiUtil.getOperationToken((JetOperationExpression) parent);
@@ -601,11 +601,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}
@Override
public JetTypeInfo visitUnaryExpression(@NotNull JetUnaryExpression expression, ExpressionTypingContext context) {
return visitUnaryExpression(expression, context, false);
}
public JetTypeInfo visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
public JetTypeInfo visitUnaryExpression(@NotNull JetUnaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
ExpressionTypingContext context = isUnaryExpressionDependentOnExpectedType(expression)
? contextWithExpectedType
: contextWithExpectedType.replaceContextDependency(INDEPENDENT).replaceExpectedType(NO_EXPECTED_TYPE);
@@ -616,10 +612,6 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetSimpleNameExpression operationSign = expression.getOperationReference();
IElementType operationType = operationSign.getReferencedNameElementType();
// If it's a labeled expression
if (operationType == JetTokens.LABEL_IDENTIFIER) {
return visitLabeledExpression(expression, context, isStatement);
}
// Special case for expr!!
if (operationType == JetTokens.EXCLEXCL) {
@@ -741,12 +733,21 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
return JetTypeInfo.create(TypeUtils.makeNotNullable(baseType), dataFlowInfo);
}
private JetTypeInfo visitLabeledExpression(@NotNull JetUnaryExpression expression, @NotNull ExpressionTypingContext context,
boolean isStatement) {
@Override
public JetTypeInfo visitLabeledExpression(
@NotNull JetLabeledExpression expression, ExpressionTypingContext context
) {
return visitLabeledExpression(expression, context, false);
}
@NotNull
public JetTypeInfo visitLabeledExpression(
@NotNull JetLabeledExpression expression,
@NotNull ExpressionTypingContext context,
boolean isStatement
) {
JetExpression baseExpression = expression.getBaseExpression();
assert baseExpression != null;
JetSimpleNameExpression operationSign = expression.getOperationReference();
assert operationSign.getReferencedNameElementType() == JetTokens.LABEL_IDENTIFIER;
if (baseExpression == null) return JetTypeInfo.create(null, context.dataFlowInfo);
return facade.getTypeInfo(baseExpression, context, isStatement);
}
@@ -483,8 +483,7 @@ public class ExpressionTypingUtils {
|| operationType == JetTokens.ELVIS);
}
public static boolean isUnaryExpressionDependentOnExpectedType(@NotNull JetUnaryExpression expression) {
IElementType operationType = expression.getOperationReference().getReferencedNameElementType();
return operationType == JetTokens.LABEL_IDENTIFIER || operationType == JetTokens.EXCLEXCL;
public static boolean isUnaryExpressionDependentOnExpectedType(@NotNull JetUnaryExpression expression) {
return expression.getOperationReference().getReferencedNameElementType() == JetTokens.EXCLEXCL;
}
}
@@ -385,7 +385,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
}
@Override
public JetTypeInfo visitUnaryExpression(@NotNull JetUnaryExpression expression, ExpressionTypingContext context) {
return basic.visitUnaryExpression(expression, context, true);
public JetTypeInfo visitLabeledExpression(@NotNull JetLabeledExpression expression, ExpressionTypingContext context) {
return basic.visitLabeledExpression(expression, context, true);
}
}
@@ -59,13 +59,10 @@ public class LabelResolver {
@Nullable
private Name getLabelNameIfAny(@NotNull PsiElement element) {
if (element instanceof JetPrefixExpression) {
JetPrefixExpression prefixExpression = (JetPrefixExpression) element;
if (JetPsiUtil.isLabeledExpression(prefixExpression)) {
return Name.identifierForLabel(JetPsiUtil.getLabelName(prefixExpression));
}
if (element instanceof JetLabeledExpression) {
return Name.identifierForLabel(((JetLabeledExpression) element).getLabelName());
}
else if (element instanceof JetFunctionLiteralExpression) {
if (element instanceof JetFunctionLiteralExpression) {
return getCallerName((JetFunctionLiteralExpression) element);
}
return null;
@@ -267,7 +267,7 @@ public class JetPositionManager implements PositionManager {
PsiElement valueArgument = functionLiteralExpression;
while (parent instanceof JetParenthesizedExpression ||
parent instanceof JetBinaryExpressionWithTypeRHS ||
parent instanceof JetPrefixExpression && JetPsiUtil.isLabeledExpression((JetPrefixExpression) parent)) {
parent instanceof JetLabeledExpression) {
valueArgument = parent;
parent = parent.getParent();
}
@@ -19,23 +19,13 @@ package org.jetbrains.jet.plugin.highlighter;
import com.intellij.lang.annotation.AnnotationHolder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetExpressionWithLabel;
import org.jetbrains.jet.lang.psi.JetPrefixExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lexer.JetTokens;
class LabelsHighlightingVisitor extends HighlightingVisitor {
LabelsHighlightingVisitor(AnnotationHolder holder) {
super(holder);
}
@Override
public void visitPrefixExpression(@NotNull JetPrefixExpression expression) {
JetSimpleNameExpression operationSign = expression.getOperationReference();
if (operationSign.getReferencedNameElementType() == JetTokens.LABEL_IDENTIFIER) {
JetPsiChecker.highlightName(holder, operationSign, JetHighlightingColors.LABEL);
}
}
@Override
public void visitExpressionWithLabel(@NotNull JetExpressionWithLabel expression) {
JetSimpleNameExpression targetLabel = expression.getTargetLabel();
@@ -86,8 +86,8 @@ class JetInvokeFunctionReference extends JetSimpleReference<JetCallExpression> i
List<JetExpression> functionLiteralArguments = getExpression().getFunctionLiteralArguments();
for (JetExpression functionLiteralArgument : functionLiteralArguments) {
while (functionLiteralArgument instanceof JetPrefixExpression) {
functionLiteralArgument = ((JetPrefixExpression) functionLiteralArgument).getBaseExpression();
while (functionLiteralArgument instanceof JetLabeledExpression) {
functionLiteralArgument = ((JetLabeledExpression) functionLiteralArgument).getBaseExpression();
}
if (functionLiteralArgument instanceof JetFunctionLiteralExpression) {
@@ -46,6 +46,7 @@ public object JetPsiPrecedences {
public fun getPrecedence(expression: JetExpression): Int {
return when (expression) {
is JetAnnotatedExpression,
is JetLabeledExpression,
is JetPrefixExpression -> PRECEDENCE_OF_PREFIX_EXPRESSION
is JetPostfixExpression -> PRECEDENCE_OF_POSTFIX_EXPRESSION
is JetOperationExpression -> {
@@ -291,25 +291,23 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
return QualifiedExpressionTranslator.translateQualifiedExpression(expression, context);
}
@Override
public JsNode visitLabeledExpression(
@NotNull JetLabeledExpression expression, TranslationContext context
) {
JetExpression baseExpression = expression.getBaseExpression();
assert baseExpression != null;
return new JsLabel(context.scope().declareName(getReferencedName(expression.getTargetLabel())),
convertToStatement(baseExpression.accept(this, context))).source(expression);
}
@Override
@NotNull
public JsNode visitPrefixExpression(
@NotNull JetPrefixExpression expression,
@NotNull TranslationContext context
) {
JetSimpleNameExpression operationReference = expression.getOperationReference();
IElementType operationToken = operationReference.getReferencedNameElementType();
JsNode result;
if (operationToken == JetTokens.LABEL_IDENTIFIER) {
JetExpression baseExpression = expression.getBaseExpression();
assert baseExpression != null;
result = new JsLabel(context.scope().declareName(getReferencedName(operationReference)),
convertToStatement(baseExpression.accept(this, context)));
}
else {
result = UnaryOperationTranslator.translate(expression, context);
}
return result.source(expression);
return UnaryOperationTranslator.translate(expression, context).source(expression);
}
@Override