PSI getter fixed: left-hand side of a binary expression can now be null
EA-35976 - IAE: FqNameUnsafe.validateFqName
This commit is contained in:
@@ -38,11 +38,18 @@ public class JetBinaryExpression extends JetExpressionImpl implements JetOperati
|
||||
return visitor.visitBinaryExpression(this, data);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable @IfNotParsed
|
||||
public JetExpression getLeft() {
|
||||
JetExpression left = findChildByClass(JetExpression.class);
|
||||
assert left != null;
|
||||
return left;
|
||||
ASTNode node = getOperationReference().getNode().getTreePrev();
|
||||
while (node != null) {
|
||||
PsiElement psi = node.getPsi();
|
||||
if (psi instanceof JetExpression) {
|
||||
return (JetExpression) psi;
|
||||
}
|
||||
node = node.getTreePrev();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @IfNotParsed
|
||||
|
||||
+3
-2
@@ -175,9 +175,10 @@ public class TracingStrategyImpl implements TracingStrategy {
|
||||
Name.identifier(operationReference.getText()) :
|
||||
OperatorConventions.getNameForOperationSymbol((JetToken) operationReference.getReferencedNameElementType());
|
||||
|
||||
JetExpression left = binaryExpression.getLeft();
|
||||
JetExpression right = binaryExpression.getRight();
|
||||
if (right != null) {
|
||||
trace.report(UNSAFE_INFIX_CALL.on(reference, binaryExpression.getLeft().getText(), operationString.getName(), right.getText()));
|
||||
if (left != null && right != null) {
|
||||
trace.report(UNSAFE_INFIX_CALL.on(reference, left.getText(), operationString.getName(), right.getText()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+25
-12
@@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.calls.context.ExpressionPosition;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.ResolutionResultsCache;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.ResolveMode;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsUtil;
|
||||
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.jet.lang.resolve.constants.*;
|
||||
@@ -753,8 +754,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
JetExpression right = expression.getRight();
|
||||
IElementType operationType = operationSign.getReferencedNameElementType();
|
||||
|
||||
JetTypeInfo leftTypeInfo = left != null
|
||||
? facade.getTypeInfo(left, context)
|
||||
: JetTypeInfo.create(null, context.dataFlowInfo);
|
||||
|
||||
JetType result = null;
|
||||
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
||||
|
||||
if (operationType == JetTokens.IDENTIFIER) {
|
||||
Name referencedName = operationSign.getReferencedNameAsName();
|
||||
JetTypeInfo typeInfo = getTypeInfoForBinaryCall(context.scope, referencedName, context, expression);
|
||||
@@ -792,10 +798,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
else {
|
||||
JetType booleanType = KotlinBuiltIns.getInstance().getBooleanType();
|
||||
if (OperatorConventions.EQUALS_OPERATIONS.contains(operationType)) {
|
||||
if (right != null) {
|
||||
if (right != null && left != null) {
|
||||
ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context);
|
||||
|
||||
dataFlowInfo = facade.getTypeInfo(left, context).getDataFlowInfo();
|
||||
dataFlowInfo = leftTypeInfo.getDataFlowInfo();
|
||||
ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
|
||||
|
||||
OverloadResolutionResults<FunctionDescriptor> resolutionResults = resolveFakeCall(
|
||||
@@ -830,7 +836,6 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
else if (OperatorConventions.IN_OPERATIONS.contains(operationType)) {
|
||||
if (right == null) {
|
||||
result = ErrorUtils.createErrorType("No right argument"); // TODO
|
||||
return JetTypeInfo.create(null, dataFlowInfo);
|
||||
}
|
||||
JetTypeInfo typeInfo = checkInExpression(expression, expression.getOperationReference(), left, right, context);
|
||||
@@ -838,7 +843,6 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
result = typeInfo.getType();
|
||||
}
|
||||
else if (OperatorConventions.BOOLEAN_OPERATIONS.containsKey(operationType)) {
|
||||
JetTypeInfo leftTypeInfo = facade.getTypeInfo(left, context);
|
||||
JetType leftType = leftTypeInfo.getType();
|
||||
dataFlowInfo = leftTypeInfo.getDataFlowInfo();
|
||||
|
||||
@@ -852,7 +856,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
JetType rightType = right == null
|
||||
? null
|
||||
: facade.getTypeInfo(right, context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope)).getType();
|
||||
if (leftType != null && !isBoolean(leftType)) {
|
||||
if (left != null && leftType != null && !isBoolean(leftType)) {
|
||||
context.trace.report(TYPE_MISMATCH.on(left, booleanType, leftType));
|
||||
}
|
||||
if (rightType != null && !isBoolean(rightType)) {
|
||||
@@ -861,11 +865,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
result = booleanType;
|
||||
}
|
||||
else if (operationType == JetTokens.ELVIS) {
|
||||
JetTypeInfo leftTypeInfo = facade.getTypeInfo(left, context);
|
||||
JetType leftType = leftTypeInfo.getType();
|
||||
dataFlowInfo = leftTypeInfo.getDataFlowInfo();
|
||||
|
||||
if (leftType != null) {
|
||||
if (left != null && leftType != null) {
|
||||
if (isKnownToBeNotNull(left, leftType, context)) {
|
||||
context.trace.report(USELESS_ELVIS.on(left, leftType));
|
||||
}
|
||||
@@ -918,6 +921,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
private void ensureNonemptyIntersectionOfOperandTypes(JetBinaryExpression expression, ExpressionTypingContext context) {
|
||||
JetExpression left = expression.getLeft();
|
||||
if (left == null) return;
|
||||
|
||||
JetExpression right = expression.getRight();
|
||||
|
||||
// TODO : duplicated effort for == and !=
|
||||
@@ -994,12 +999,20 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
) {
|
||||
ExpressionTypingContext context = contextWithOldScope.replaceScope(scope);
|
||||
JetExpression left = binaryExpression.getLeft();
|
||||
DataFlowInfo dataFlowInfo = facade.getTypeInfo(left, context).getDataFlowInfo();
|
||||
|
||||
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, left, context);
|
||||
DataFlowInfo dataFlowInfo = context.dataFlowInfo;
|
||||
if (left != null) {
|
||||
dataFlowInfo = facade.getTypeInfo(left, context).getDataFlowInfo();
|
||||
}
|
||||
ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
|
||||
OverloadResolutionResults<FunctionDescriptor> resolutionResults =
|
||||
getResolutionResultsForBinaryCall(scope, name, contextWithDataFlow, binaryExpression, receiver);
|
||||
|
||||
OverloadResolutionResults<FunctionDescriptor> resolutionResults;
|
||||
if (left != null) {
|
||||
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, left, context);
|
||||
resolutionResults = getResolutionResultsForBinaryCall(scope, name, contextWithDataFlow, binaryExpression, receiver);
|
||||
}
|
||||
else {
|
||||
resolutionResults = OverloadResolutionResultsImpl.nameNotFound();
|
||||
}
|
||||
|
||||
JetExpression right = binaryExpression.getRight();
|
||||
if (right != null) {
|
||||
|
||||
@@ -73,6 +73,7 @@ public class DataFlowUtils {
|
||||
}
|
||||
else {
|
||||
JetExpression left = expression.getLeft();
|
||||
if (left == null) return;
|
||||
JetExpression right = expression.getRight();
|
||||
if (right == null) return;
|
||||
|
||||
|
||||
+1
@@ -85,6 +85,7 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
|
||||
return getTypeInfo(expression, context, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public final JetTypeInfo getTypeInfo(@NotNull JetExpression expression, ExpressionTypingContext context, boolean isStatement) {
|
||||
if (!isStatement) return getTypeInfo(expression, context);
|
||||
|
||||
+13
-7
@@ -208,12 +208,15 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
|
||||
JetSimpleNameExpression operationSign = expression.getOperationReference();
|
||||
IElementType operationType = operationSign.getReferencedNameElementType();
|
||||
JetTypeInfo leftInfo = facade.getTypeInfo(expression.getLeft(), context);
|
||||
JetExpression leftOperand = expression.getLeft();
|
||||
JetTypeInfo leftInfo = leftOperand != null
|
||||
? facade.getTypeInfo(leftOperand, context)
|
||||
: JetTypeInfo.create(null, context.dataFlowInfo);
|
||||
JetType leftType = leftInfo.getType();
|
||||
DataFlowInfo dataFlowInfo = leftInfo.getDataFlowInfo();
|
||||
|
||||
JetExpression right = expression.getRight();
|
||||
JetExpression left = JetPsiUtil.deparenthesizeWithNoTypeResolution(expression.getLeft());
|
||||
JetExpression left = leftOperand == null ? null : JetPsiUtil.deparenthesizeWithNoTypeResolution(leftOperand);
|
||||
if (right == null || left == null) {
|
||||
temporaryBindingTrace.commit();
|
||||
return JetTypeInfo.create(null, dataFlowInfo);
|
||||
@@ -271,7 +274,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
basic.resolveArrayAccessSetMethod((JetArrayAccessExpression) left, right, contextForResolve, context.trace);
|
||||
}
|
||||
dataFlowInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo)).getDataFlowInfo();
|
||||
BasicExpressionTypingVisitor.checkLValue(context.trace, expression.getLeft());
|
||||
BasicExpressionTypingVisitor.checkLValue(context.trace, leftOperand);
|
||||
}
|
||||
temporaryBindingTrace.commit();
|
||||
return JetTypeInfo.create(checkAssignmentType(type, expression, contextWithExpectedType), dataFlowInfo);
|
||||
@@ -280,7 +283,8 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
@NotNull
|
||||
protected JetTypeInfo visitAssignment(JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
|
||||
ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceScope(scope);
|
||||
JetExpression left = context.expressionTypingServices.deparenthesize(expression.getLeft(), context);
|
||||
JetExpression leftOperand = expression.getLeft();
|
||||
JetExpression left = leftOperand == null ? null : context.expressionTypingServices.deparenthesize(leftOperand, context);
|
||||
JetExpression right = expression.getRight();
|
||||
if (left instanceof JetArrayAccessExpression) {
|
||||
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) left;
|
||||
@@ -290,15 +294,17 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
return JetTypeInfo.create(checkAssignmentType(typeInfo.getType(), expression, contextWithExpectedType),
|
||||
typeInfo.getDataFlowInfo());
|
||||
}
|
||||
JetTypeInfo leftInfo = facade.getTypeInfo(expression.getLeft(), context);
|
||||
JetTypeInfo leftInfo = leftOperand != null
|
||||
? facade.getTypeInfo(leftOperand, context)
|
||||
: JetTypeInfo.create(null, context.dataFlowInfo);
|
||||
JetType leftType = leftInfo.getType();
|
||||
DataFlowInfo dataFlowInfo = leftInfo.getDataFlowInfo();
|
||||
if (right != null) {
|
||||
JetTypeInfo rightInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(dataFlowInfo).replaceExpectedType(leftType));
|
||||
dataFlowInfo = rightInfo.getDataFlowInfo();
|
||||
}
|
||||
if (leftType != null) { //if leftType == null, some another error has been generated
|
||||
BasicExpressionTypingVisitor.checkLValue(context.trace, expression.getLeft());
|
||||
if (leftType != null && leftOperand != null) { //if leftType == null, some other error has been generated
|
||||
BasicExpressionTypingVisitor.checkLValue(context.trace, leftOperand);
|
||||
}
|
||||
return DataFlowUtils.checkStatementType(expression, contextWithExpectedType, dataFlowInfo);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
fun import() {
|
||||
<!FUNCTION_CALL_EXPECTED!>import<!> <!UNRESOLVED_REFERENCE!>a<!><!SYNTAX!>.<!><!DEBUG_INFO_MISSING_UNRESOLVED!>*<!><!SYNTAX!><!>
|
||||
}
|
||||
|
||||
fun composite() {
|
||||
val <!UNUSED_VARIABLE!>s<!> = 13+<!SYNTAX!>~<!><!DEBUG_INFO_MISSING_UNRESOLVED!>/<!>12
|
||||
}
|
||||
|
||||
fun html() {
|
||||
<!SYNTAX!><<!><!FUNCTION_CALL_EXPECTED!>html<!><!UNRESOLVED_REFERENCE!>><!><!SYNTAX!><<!><!DEBUG_INFO_MISSING_UNRESOLVED!>/<!><!FUNCTION_CALL_EXPECTED!>html<!><!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>><!><!SYNTAX!><!>
|
||||
}
|
||||
|
||||
fun html1() {
|
||||
<!SYNTAX!><<!><!FUNCTION_CALL_EXPECTED!>html<!><!UNRESOLVED_REFERENCE!>><!><!SYNTAX!><<!><!DEBUG_INFO_MISSING_UNRESOLVED!>/<!><!FUNCTION_CALL_EXPECTED!>html<!><!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>><!><!FUNCTION_CALL_EXPECTED!>html<!>
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fun import() {
|
||||
import a.*
|
||||
}
|
||||
|
||||
fun composite() {
|
||||
val s = 13+~/12
|
||||
}
|
||||
|
||||
fun html() {
|
||||
<html></html>
|
||||
}
|
||||
|
||||
fun html1() {
|
||||
<html></html>html
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
JetFile: AbsentLeftHandSide.kt
|
||||
NAMESPACE_HEADER
|
||||
<empty list>
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('import')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('import')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
BINARY_EXPRESSION
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(DOT)('.')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(MUL)('*')
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('composite')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('s')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
BINARY_EXPRESSION
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('13')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUS)('+')
|
||||
BINARY_EXPRESSION
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(BAD_CHARACTER)('~')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(DIV)('/')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('12')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('html')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(LT)('<')
|
||||
BINARY_EXPRESSION
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('html')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(GT)('>')
|
||||
BINARY_EXPRESSION
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(LT)('<')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(DIV)('/')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('html')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(GT)('>')
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('html1')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(LT)('<')
|
||||
BINARY_EXPRESSION
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('html')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(GT)('>')
|
||||
BINARY_EXPRESSION
|
||||
PsiErrorElement:Expecting an element
|
||||
PsiElement(LT)('<')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(DIV)('/')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('html')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(GT)('>')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('html')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -33,7 +33,7 @@ import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve;
|
||||
@InnerTestClasses({JetDiagnosticsTestGenerated.Tests.class, JetDiagnosticsTestGenerated.Script.class})
|
||||
public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEagerResolve {
|
||||
@TestMetadata("compiler/testData/diagnostics/tests")
|
||||
@InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.SmartCasts.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.ThisAndSuper.class, Tests.Varargs.class})
|
||||
@InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Recovery.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.SmartCasts.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.ThisAndSuper.class, Tests.Varargs.class})
|
||||
public static class Tests extends AbstractDiagnosticsTestWithEagerResolve {
|
||||
@TestMetadata("Abstract.kt")
|
||||
public void testAbstract() throws Exception {
|
||||
@@ -3399,6 +3399,19 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/recovery")
|
||||
public static class Recovery extends AbstractDiagnosticsTestWithEagerResolve {
|
||||
@TestMetadata("absentLeftHandSide.kt")
|
||||
public void testAbsentLeftHandSide() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/recovery/absentLeftHandSide.kt");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInRecovery() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/recovery"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/redeclarations")
|
||||
public static class Redeclarations extends AbstractDiagnosticsTestWithEagerResolve {
|
||||
public void testAllFilesPresentInRedeclarations() throws Exception {
|
||||
@@ -4503,6 +4516,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
suite.addTestSuite(OperatorsOverloading.class);
|
||||
suite.addTestSuite(Overload.class);
|
||||
suite.addTestSuite(Override.class);
|
||||
suite.addTestSuite(Recovery.class);
|
||||
suite.addTestSuite(Redeclarations.class);
|
||||
suite.addTestSuite(Regressions.class);
|
||||
suite.addTestSuite(Resolve.class);
|
||||
|
||||
@@ -45,8 +45,11 @@ public class ReplaceInfixCallFix extends JetIntentionAction<JetBinaryExpression>
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
String newText = element.getLeft().getText() + "?." + element.getOperationReference().getText()
|
||||
+ "(" + element.getRight().getText() + ")";
|
||||
JetExpression left = element.getLeft();
|
||||
JetExpression right = element.getRight();
|
||||
assert left != null && right != null : "Preconditions checked by factory";
|
||||
String newText = left.getText() + "?." + element.getOperationReference().getText()
|
||||
+ "(" + right.getText() + ")";
|
||||
JetQualifiedExpression newElement = (JetQualifiedExpression) JetPsiFactory.createExpression(project, newText);
|
||||
element.replace(newElement);
|
||||
}
|
||||
@@ -61,6 +64,9 @@ public class ReplaceInfixCallFix extends JetIntentionAction<JetBinaryExpression>
|
||||
@Override
|
||||
public IntentionAction createAction(Diagnostic diagnostic) {
|
||||
JetBinaryExpression expression = QuickFixUtil.getParentElementOfType(diagnostic, JetBinaryExpression.class);
|
||||
if (expression == null) return null;
|
||||
if (expression.getLeft() == null) return null;
|
||||
if (expression.getRight() == null) return null;
|
||||
return new ReplaceInfixCallFix(expression);
|
||||
}
|
||||
};
|
||||
|
||||
+4
-1
@@ -23,6 +23,7 @@ import com.google.dart.compiler.backend.js.ast.JsLiteral;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -69,7 +70,9 @@ public final class EqualsIntrinsic implements BinaryOperationIntrinsic {
|
||||
}
|
||||
|
||||
private static boolean canUseSimpleEquals(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context) {
|
||||
Name typeName = JsDescriptorUtils.getNameIfStandardType(expression.getLeft(), context);
|
||||
JetExpression left = expression.getLeft();
|
||||
assert left != null : "No left-hand side: " + expression.getText();
|
||||
Name typeName = JsDescriptorUtils.getNameIfStandardType(left, context);
|
||||
return typeName != null && NamePredicate.PRIMITIVE_NUMBERS.apply(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -19,6 +19,7 @@ package org.jetbrains.k2js.translate.operation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
@@ -61,7 +62,9 @@ public abstract class AssignmentTranslator extends AbstractTranslator {
|
||||
super(context);
|
||||
this.expression = expression;
|
||||
this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
|
||||
this.accessTranslator = AccessTranslationUtils.getAccessTranslator(expression.getLeft(), context());
|
||||
JetExpression left = expression.getLeft();
|
||||
assert left != null : "No left-hand side: " + expression.getText();
|
||||
this.accessTranslator = AccessTranslationUtils.getAccessTranslator(left, context());
|
||||
this.right = translateRightExpression(context(), expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,9 @@ public final class TranslationUtils {
|
||||
@NotNull
|
||||
public static JsExpression translateLeftExpression(@NotNull TranslationContext context,
|
||||
@NotNull JetBinaryExpression expression) {
|
||||
return Translation.translateAsExpression(expression.getLeft(), context);
|
||||
JetExpression left = expression.getLeft();
|
||||
assert left != null : "Binary expression should have a left expression: " + expression.getText();
|
||||
return Translation.translateAsExpression(left, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user