@Nullable private JetType lookupNamespaceOrClassObject( @NotNull JetSimpleNameExpression expression, @NotNull ResolutionContext context) { Name referencedName = expression.getReferencedNameAsName(); final ClassifierDescriptor classifier = context.scope.getClassifier(referencedName); if (classifier != null) { JetType classObjectType = classifier.getClassObjectType(); if (classObjectType != null) { context.trace.record(REFERENCE_TARGET, expression, classifier); JetType result = getExtendedClassObjectType(classObjectType, referencedName, classifier, context); if (result == null) { context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); } return DataFlowUtils.checkType(result, expression, context); } } JetType[] result = new JetType[1]; TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create( context.trace, "trace for namespace/class object lookup of name", referencedName); if (furtherNameLookup(expression, result, context.replaceBindingTrace(temporaryTrace))) { temporaryTrace.commit(); return DataFlowUtils.checkType(result[0], expression, context); } // To report NO_CLASS_OBJECT when no namespace found if (classifier != null) { if (classifier instanceof TypeParameterDescriptor) { if (context.expressionPosition == ExpressionPosition.FREE) { context.trace.report( TYPE_PARAMETER_IS_NOT_AN_EXPRESSION.on( expression, (TypeParameterDescriptor) classifier)); } else { context.trace.report( TYPE_PARAMETER_ON_LHS_OF_DOT.on(expression, (TypeParameterDescriptor) classifier)); } } else if (context.expressionPosition == ExpressionPosition.FREE) { context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); } context.trace.record(REFERENCE_TARGET, expression, classifier); JetScope scopeForStaticMembersResolution = classifier instanceof ClassDescriptor ? getStaticNestedClassesScope((ClassDescriptor) classifier) : new JetScopeImpl() { @NotNull @Override public DeclarationDescriptor getContainingDeclaration() { return classifier; } @Override public String toString() { return "Scope for the type parameter on the left hand side of dot"; } }; return new NamespaceType(referencedName, scopeForStaticMembersResolution); } temporaryTrace.commit(); return result[0]; }
@Nullable private JetType lookupNamespaceOrClassObject( @NotNull JetSimpleNameExpression expression, @NotNull ResolutionContext context) { Name referencedName = expression.getReferencedNameAsName(); ClassifierDescriptor classifier = context.scope.getClassifier(referencedName); if (classifier != null) { JetType classObjectType = classifier.getClassObjectType(); if (classObjectType != null) { context.trace.record(REFERENCE_TARGET, expression, classifier); JetType result; if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT && classifier instanceof ClassDescriptor) { JetScope scope = new ChainedScope( classifier, classObjectType.getMemberScope(), getStaticNestedClassesScope((ClassDescriptor) classifier)); result = new NamespaceType(referencedName, scope); } else if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT || classifier.isClassObjectAValue()) { result = classObjectType; } else { context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); result = null; } return DataFlowUtils.checkType(result, expression, context); } } JetType[] result = new JetType[1]; TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create( context.trace, "trace for namespace/class object lookup of name", referencedName); if (furtherNameLookup(expression, result, context.replaceBindingTrace(temporaryTrace))) { temporaryTrace.commit(); return DataFlowUtils.checkType(result[0], expression, context); } // To report NO_CLASS_OBJECT when no namespace found if (classifier != null) { if (context.expressionPosition == ExpressionPosition.FREE) { context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); } context.trace.record(REFERENCE_TARGET, expression, classifier); JetScope scopeForStaticMembersResolution = classifier instanceof ClassDescriptor ? getStaticNestedClassesScope((ClassDescriptor) classifier) : JetScope.EMPTY; return new NamespaceType(referencedName, scopeForStaticMembersResolution); } temporaryTrace.commit(); return result[0]; }
@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 public TypeInfoForCall getCallExpressionTypeInfoForCall( @NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver, @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode) { TypeInfoForCall typeInfoForCall = getCallExpressionTypeInfoForCallWithoutFinalTypeCheck( callExpression, receiver, callOperationNode, context, resolveMode); if (resolveMode == ResolveMode.TOP_LEVEL_CALL) { DataFlowUtils.checkType( typeInfoForCall.getType(), callExpression, context, typeInfoForCall.getDataFlowInfo()); } return typeInfoForCall; }
@NotNull public <D extends CallableDescriptor> JetTypeInfo getCallExpressionTypeInfo( @NotNull JetCallExpression callExpression, @NotNull ReceiverValue receiver, @Nullable ASTNode callOperationNode, @NotNull ResolutionContext context, @NotNull ResolveMode resolveMode, @NotNull ResolutionResultsCache resolutionResultsCache) { JetTypeInfo typeInfo = getCallExpressionTypeInfoWithoutFinalTypeCheck( callExpression, receiver, callOperationNode, context, resolveMode, resolutionResultsCache); if (resolveMode == ResolveMode.TOP_LEVEL_CALL) { DataFlowUtils.checkType( typeInfo.getType(), callExpression, context, typeInfo.getDataFlowInfo()); } return typeInfo; }