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); } }
@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; }
@NotNull public TypeInfoForCall getQualifiedExpressionExtendedTypeInfo( @NotNull JetQualifiedExpression expression, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode) { // TODO : functions as values JetExpression selectorExpression = expression.getSelectorExpression(); JetExpression receiverExpression = expression.getReceiverExpression(); JetTypeInfo receiverTypeInfo = expressionTypingServices.getTypeInfoWithNamespaces( receiverExpression, context.scope, NO_EXPECTED_TYPE, context.dataFlowInfo, context.trace); JetType receiverType = receiverTypeInfo.getType(); if (selectorExpression == null) return TypeInfoForCall.create(null, context.dataFlowInfo); if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText()); context = context.replaceDataFlowInfo(receiverTypeInfo.getDataFlowInfo()); if (selectorExpression instanceof JetSimpleNameExpression) { ConstantUtils.propagateConstantValues( expression, context.trace, (JetSimpleNameExpression) selectorExpression); } TypeInfoForCall selectorReturnTypeInfo = getSelectorReturnTypeInfo( new ExpressionReceiver(receiverExpression, receiverType), expression.getOperationTokenNode(), selectorExpression, context, resolveMode); JetType selectorReturnType = selectorReturnTypeInfo.getType(); // TODO move further if (!(receiverType instanceof NamespaceType) && expression.getOperationSign() == JetTokens.SAFE_ACCESS) { if (selectorReturnType != null && !selectorReturnType.isNullable() && !KotlinBuiltIns.getInstance().isUnit(selectorReturnType)) { if (receiverType.isNullable()) { selectorReturnType = TypeUtils.makeNullable(selectorReturnType); } } } // TODO : this is suspicious: remove this code? if (selectorReturnType != null) { context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, selectorReturnType); } JetTypeInfo typeInfo = JetTypeInfo.create(selectorReturnType, selectorReturnTypeInfo.getDataFlowInfo()); if (resolveMode == ResolveMode.TOP_LEVEL_CALL) { DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo()); } return TypeInfoForCall.create(typeInfo, selectorReturnTypeInfo); }
@NotNull private JetTypeInfo getSelectorReturnTypeInfo( @NotNull ReceiverValue receiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression selectorExpression, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode, @NotNull ResolutionResultsCache resolutionResultsCache) { if (selectorExpression instanceof JetCallExpression) { return getCallExpressionTypeInfoWithoutFinalTypeCheck( (JetCallExpression) selectorExpression, receiver, callOperationNode, context, resolveMode, resolutionResultsCache); } else if (selectorExpression instanceof JetSimpleNameExpression) { return getSimpleNameExpressionTypeInfo( (JetSimpleNameExpression) selectorExpression, receiver, callOperationNode, context); } else if (selectorExpression instanceof JetQualifiedExpression) { JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) selectorExpression; JetExpression newReceiverExpression = qualifiedExpression.getReceiverExpression(); JetTypeInfo newReceiverTypeInfo = getSelectorReturnTypeInfo( receiver, callOperationNode, newReceiverExpression, context.replaceExpectedType(NO_EXPECTED_TYPE), resolveMode, resolutionResultsCache); JetType newReceiverType = newReceiverTypeInfo.getType(); DataFlowInfo newReceiverDataFlowInfo = newReceiverTypeInfo.getDataFlowInfo(); JetExpression newSelectorExpression = qualifiedExpression.getSelectorExpression(); if (newReceiverType != null && newSelectorExpression != null) { ExpressionReceiver expressionReceiver = new ExpressionReceiver(newReceiverExpression, newReceiverType); return getSelectorReturnTypeInfo( expressionReceiver, qualifiedExpression.getOperationTokenNode(), newSelectorExpression, context.replaceDataFlowInfo(newReceiverDataFlowInfo), resolveMode, resolutionResultsCache); } } else { context.trace.report(ILLEGAL_SELECTOR.on(selectorExpression, selectorExpression.getText())); } return JetTypeInfo.create(null, context.dataFlowInfo); }
@NotNull public Collection<? extends DeclarationDescriptor> lookupDescriptorsForQualifiedExpression( @NotNull JetQualifiedExpression importedReference, @NotNull JetScope outerScope, @NotNull JetScope scopeToCheckVisibility, @NotNull BindingTrace trace, @NotNull LookupMode lookupMode, boolean storeResult) { JetExpression receiverExpression = importedReference.getReceiverExpression(); Collection<? extends DeclarationDescriptor> declarationDescriptors; if (receiverExpression instanceof JetQualifiedExpression) { declarationDescriptors = lookupDescriptorsForQualifiedExpression( (JetQualifiedExpression) receiverExpression, outerScope, scopeToCheckVisibility, trace, lookupMode, storeResult); } else { assert receiverExpression instanceof JetSimpleNameExpression; declarationDescriptors = lookupDescriptorsForSimpleNameReference( (JetSimpleNameExpression) receiverExpression, outerScope, scopeToCheckVisibility, trace, lookupMode, true, storeResult); } JetExpression selectorExpression = importedReference.getSelectorExpression(); if (!(selectorExpression instanceof JetSimpleNameExpression)) { return Collections.emptyList(); } JetSimpleNameExpression selector = (JetSimpleNameExpression) selectorExpression; JetSimpleNameExpression lastReference = JetPsiUtil.getLastReference(receiverExpression); if (lastReference == null || !canImportMembersFrom(declarationDescriptors, lastReference, trace, lookupMode)) { return Collections.emptyList(); } return lookupSelectorDescriptors( selector, declarationDescriptors, trace, scopeToCheckVisibility, lookupMode, storeResult); }