@Nullable public static BinaryCall getRangeAsBinaryCall(@NotNull JetForExpression forExpression) { // We are looking for rangeTo() calls // Other binary operations will succeed too, but will be filtered out later (by examining a // resolvedCall) JetExpression rangeExpression = forExpression.getLoopRange(); assert rangeExpression != null; JetExpression loopRange = JetPsiUtil.deparenthesizeWithNoTypeResolution(rangeExpression); if (loopRange instanceof JetQualifiedExpression) { // a.rangeTo(b) JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) loopRange; JetExpression selector = qualifiedExpression.getSelectorExpression(); if (selector instanceof JetCallExpression) { JetCallExpression callExpression = (JetCallExpression) selector; List<? extends ValueArgument> arguments = callExpression.getValueArguments(); if (arguments.size() == 1) { return new BinaryCall( qualifiedExpression.getReceiverExpression(), callExpression.getCalleeExpression(), arguments.get(0).getArgumentExpression()); } } } else if (loopRange instanceof JetBinaryExpression) { // a rangeTo b // a .. b JetBinaryExpression binaryExpression = (JetBinaryExpression) loopRange; return new BinaryCall( binaryExpression.getLeft(), binaryExpression.getOperationReference(), binaryExpression.getRight()); } return null; }
private static void addNamesForExpression( ArrayList<String> result, JetExpression expression, JetNameValidator validator) { if (expression instanceof JetQualifiedExpression) { JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) expression; JetExpression selectorExpression = qualifiedExpression.getSelectorExpression(); addNamesForExpression(result, selectorExpression, validator); if (selectorExpression != null && selectorExpression instanceof JetCallExpression) { JetExpression calleeExpression = ((JetCallExpression) selectorExpression).getCalleeExpression(); if (calleeExpression != null && calleeExpression instanceof JetSimpleNameExpression) { String name = ((JetSimpleNameExpression) calleeExpression).getReferencedName(); if (name != null && name.equals("sure")) { addNamesForExpression(result, qualifiedExpression.getReceiverExpression(), validator); } } } } else if (expression instanceof JetSimpleNameExpression) { JetSimpleNameExpression reference = (JetSimpleNameExpression) expression; String referenceName = reference.getReferencedName(); if (referenceName == null) return; if (referenceName.equals(referenceName.toUpperCase())) { addName(result, referenceName, validator); } else { addCamelNames(result, referenceName, validator); } } else if (expression instanceof JetCallExpression) { JetCallExpression call = (JetCallExpression) expression; addNamesForExpression(result, call.getCalleeExpression(), validator); } }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { JetCallExpression call = (JetCallExpression) element; ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); Type type = state .getInjector() .getJetTypeMapper() .mapType( resultingDescriptor.getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE); JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(type); if (primitiveType != null) { v.getstatic( primitiveType.getWrapper().getAsmType().getInternalName(), "TYPE", "Ljava/lang/Class;"); } else { v.aconst(type); } return StackValue.onStack(JetTypeMapper.JL_CLASS_TYPE); }
@Nullable private static JetBlockExpression getDSLLambdaBlock(@NotNull PsiElement element, boolean down) { JetCallExpression callExpression = (JetCallExpression) JetPsiUtil.getOutermostDescendantElement(element, down, IS_CALL_EXPRESSION); if (callExpression == null) return null; List<JetExpression> functionLiterals = callExpression.getFunctionLiteralArguments(); if (functionLiterals.isEmpty()) return null; return ((JetFunctionLiteralExpression) functionLiterals.get(0)).getBodyExpression(); }
@Nullable private static Name getCallerName(@NotNull JetFunctionLiteralExpression expression) { JetCallExpression callExpression = getContainingCallExpression(expression); if (callExpression == null) return null; JetExpression calleeExpression = callExpression.getCalleeExpression(); if (calleeExpression instanceof JetSimpleNameExpression) { JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) calleeExpression; return nameExpression.getReferencedNameAsName(); } return null; }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { receiver.put(AsmTypeConstants.OBJECT_TYPE, v); JetCallExpression call = (JetCallExpression) element; FunctionDescriptor funDescriptor = (FunctionDescriptor) codegen .getBindingContext() .get( BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call.getCalleeExpression()); assert funDescriptor != null; ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal(); if (containingDeclaration.equals(JetStandardLibrary.getInstance().getArray())) { v.invokestatic( "jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;)Ljava/util/Iterator;"); return StackValue.onStack(AsmTypeConstants.JET_ITERATOR_TYPE); } else { for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) { PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType(); if (primitiveType.getArrayClassName().is(containingDeclaration)) { String methodSignature = "([" + jvmPrimitiveType.getJvmLetter() + ")" + jvmPrimitiveType.getIterator().getDescriptor(); v.invokestatic("jet/runtime/ArrayIterator", "iterator", methodSignature); return StackValue.onStack(jvmPrimitiveType.getIterator().getAsmType()); } } throw new UnsupportedOperationException(containingDeclaration.toString()); } }
@Override public StackValue generate( ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) { boolean leftNullable = true; JetExpression rightExpr; if (element instanceof JetCallExpression) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); JetCallExpression jetCallExpression = (JetCallExpression) element; JetExpression calleeExpression = jetCallExpression.getCalleeExpression(); if (calleeExpression != null) { JetType leftType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, calleeExpression); if (leftType != null) leftNullable = leftType.isNullable(); } rightExpr = arguments.get(0); } else { JetExpression leftExpr = arguments.get(0); leftNullable = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, leftExpr).isNullable(); codegen.gen(leftExpr).put(JetTypeMapper.TYPE_OBJECT, v); rightExpr = arguments.get(1); } JetType rightType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, rightExpr); codegen.gen(rightExpr).put(JetTypeMapper.TYPE_OBJECT, v); return codegen.generateEqualsForExpressionsOnStack( JetTokens.EQEQ, JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_OBJECT, leftNullable, rightType.isNullable()); }
@NotNull public TypeInfoForCall getCallExpressionTypeInfoForCallWithoutFinalTypeCheck( @NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver, @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode) { boolean[] result = new boolean[1]; Call call = CallMaker.makeCall(receiver, callOperationNode, callExpression); TemporaryBindingTrace traceForFunction = TemporaryBindingTrace.create( context.trace, "trace to resolve as function call", callExpression); ResolvedCall<FunctionDescriptor> resolvedCall = getResolvedCallForFunction( call, callExpression, receiver, context.replaceBindingTrace(traceForFunction), resolveMode, result); if (result[0]) { FunctionDescriptor functionDescriptor = resolvedCall != null ? resolvedCall.getResultingDescriptor() : null; traceForFunction.commit(); if (callExpression.getValueArgumentList() == null && callExpression.getFunctionLiteralArguments().isEmpty()) { // there are only type arguments boolean hasValueParameters = functionDescriptor == null || functionDescriptor.getValueParameters().size() > 0; context.trace.report( FUNCTION_CALL_EXPECTED.on(callExpression, callExpression, hasValueParameters)); } if (functionDescriptor == null) { return TypeInfoForCall.create(null, context.dataFlowInfo); } JetType type = functionDescriptor.getReturnType(); return TypeInfoForCall.create( type, resolvedCall.getDataFlowInfo(), resolvedCall, call, context, resolveMode); } JetExpression calleeExpression = callExpression.getCalleeExpression(); if (calleeExpression instanceof JetSimpleNameExpression && callExpression.getTypeArgumentList() == null) { TemporaryBindingTrace traceForVariable = TemporaryBindingTrace.create( context.trace, "trace to resolve as variable with 'invoke' call", callExpression); JetType type = getVariableType( (JetSimpleNameExpression) calleeExpression, receiver, callOperationNode, context.replaceBindingTrace(traceForVariable), result); if (result[0]) { traceForVariable.commit(); context.trace.report( FUNCTION_EXPECTED.on( (JetReferenceExpression) calleeExpression, calleeExpression, type != null ? type : ErrorUtils.createErrorType(""))); return TypeInfoForCall.create(null, context.dataFlowInfo); } } traceForFunction.commit(); return TypeInfoForCall.create(null, context.dataFlowInfo); }