@Override public void visitClassObject(@NotNull JetClassObject classObject) { JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration(); DeclarationDescriptor container = owner.getOwnerForChildren(); MutableClassDescriptor classObjectDescriptor = createClassDescriptorForSingleton( objectDeclaration, getClassObjectName(container.getName()), ClassKind.CLASS_OBJECT); PackageLikeBuilder.ClassObjectStatus status = isEnumEntry(container) || isObject(container) || c.getTopDownAnalysisParameters().isDeclaredLocally() ? PackageLikeBuilder.ClassObjectStatus.NOT_ALLOWED : owner.setClassObjectDescriptor(classObjectDescriptor); switch (status) { case DUPLICATE: trace.report(MANY_CLASS_OBJECTS.on(classObject)); break; case NOT_ALLOWED: trace.report(CLASS_OBJECT_NOT_ALLOWED.on(classObject)); break; case OK: // Everything is OK so no errors to trace. break; } }
private static String getJvmInternalFQNameImpl( BindingTrace bindingTrace, DeclarationDescriptor descriptor) { if (descriptor instanceof FunctionDescriptor) { throw new IllegalStateException("requested fq name for function: " + descriptor); } if (descriptor.getContainingDeclaration() instanceof ModuleDescriptor || descriptor instanceof ScriptDescriptor) { return ""; } if (descriptor instanceof ModuleDescriptor) { throw new IllegalStateException("missed something"); } if (descriptor instanceof ClassDescriptor) { ClassDescriptor klass = (ClassDescriptor) descriptor; if (klass.getKind() == ClassKind.OBJECT || klass.getKind() == ClassKind.CLASS_OBJECT) { if (klass.getContainingDeclaration() instanceof ClassDescriptor) { ClassDescriptor containingKlass = (ClassDescriptor) klass.getContainingDeclaration(); if (containingKlass.getKind() == ClassKind.ENUM_CLASS) { return getJvmInternalName(bindingTrace, containingKlass).getInternalName(); } else { return getJvmInternalName(bindingTrace, containingKlass).getInternalName() + JvmAbi.CLASS_OBJECT_SUFFIX; } } } JvmClassName name = bindingTrace.getBindingContext().get(FQN, descriptor); if (name != null) { return name.getInternalName(); } } DeclarationDescriptor container = descriptor.getContainingDeclaration(); if (container == null) { throw new IllegalStateException("descriptor has no container: " + descriptor); } Name name = descriptor.getName(); String baseName = getJvmInternalName(bindingTrace, container).getInternalName(); if (!baseName.isEmpty()) { return baseName + (container instanceof NamespaceDescriptor ? "/" : "$") + name.getIdentifier(); } return name.getIdentifier(); }
@NotNull public static JvmClassName getJvmInternalName( BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) { descriptor = descriptor.getOriginal(); JvmClassName name = bindingTrace.getBindingContext().get(FQN, descriptor); if (name != null) { return name; } name = JvmClassName.byInternalName(getJvmInternalFQNameImpl(bindingTrace, descriptor)); assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, name); bindingTrace.record(FQN, descriptor, name); return name; }
@NotNull /*package*/ OverloadResolutionResultsImpl<FunctionDescriptor> resolveFunctionCall( @NotNull BasicCallResolutionContext context) { ProgressIndicatorProvider.checkCanceled(); List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> prioritizedTasks; JetExpression calleeExpression = context.call.getCalleeExpression(); JetReferenceExpression functionReference; if (calleeExpression instanceof JetSimpleNameExpression) { JetSimpleNameExpression expression = (JetSimpleNameExpression) calleeExpression; functionReference = expression; ExpressionTypingUtils.checkCapturingInClosure(expression, context.trace, context.scope); Name name = expression.getReferencedNameAsName(); prioritizedTasks = TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasks( context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES); ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck = new ResolutionTask.DescriptorCheckStrategy() { @Override public <D extends CallableDescriptor> boolean performAdvancedChecks( D descriptor, BindingTrace trace, TracingStrategy tracing) { if (descriptor instanceof ConstructorDescriptor) { Modality modality = ((ConstructorDescriptor) descriptor).getContainingDeclaration().getModality(); if (modality == Modality.ABSTRACT) { tracing.instantiationOfAbstractClass(trace); return false; } } return true; } }; for (ResolutionTask task : prioritizedTasks) { task.setCheckingStrategy(abstractConstructorCheck); } } else { JetValueArgumentList valueArgumentList = context.call.getValueArgumentList(); PsiElement reportAbsenceOn = valueArgumentList == null ? context.call.getCallElement() : valueArgumentList; if (calleeExpression instanceof JetConstructorCalleeExpression) { assert !context.call.getExplicitReceiver().exists(); JetConstructorCalleeExpression expression = (JetConstructorCalleeExpression) calleeExpression; functionReference = expression.getConstructorReferenceExpression(); if (functionReference == null) { return checkArgumentTypesAndFail(context); // No type there } JetTypeReference typeReference = expression.getTypeReference(); assert typeReference != null; JetType constructedType = typeResolver.resolveType(context.scope, typeReference, context.trace, true); if (constructedType.isError()) { return checkArgumentTypesAndFail(context); } DeclarationDescriptor declarationDescriptor = constructedType.getConstructor().getDeclarationDescriptor(); if (declarationDescriptor instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors(); if (constructors.isEmpty()) { context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn)); return checkArgumentTypesAndFail(context); } Collection<ResolutionCandidate<CallableDescriptor>> candidates = TaskPrioritizer.<CallableDescriptor>convertWithImpliedThis( context.scope, Collections.<ReceiverValue>singletonList(NO_RECEIVER), constructors); prioritizedTasks = TaskPrioritizer .<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates( context, functionReference, candidates, null); } else { context.trace.report(NOT_A_CLASS.on(calleeExpression)); return checkArgumentTypesAndFail(context); } } else if (calleeExpression instanceof JetThisReferenceExpression) { functionReference = (JetThisReferenceExpression) calleeExpression; DeclarationDescriptor containingDeclaration = context.scope.getContainingDeclaration(); if (containingDeclaration instanceof ConstructorDescriptor) { containingDeclaration = containingDeclaration.getContainingDeclaration(); } assert containingDeclaration instanceof ClassDescriptor; ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors(); if (constructors.isEmpty()) { context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn)); return checkArgumentTypesAndFail(context); } List<ResolutionCandidate<CallableDescriptor>> candidates = ResolutionCandidate.<CallableDescriptor>convertCollection( constructors, JetPsiUtil.isSafeCall(context.call)); prioritizedTasks = Collections.singletonList( new ResolutionTask<CallableDescriptor, FunctionDescriptor>( candidates, functionReference, context)); // !! DataFlowInfo.EMPTY } else if (calleeExpression != null) { // Here we handle the case where the callee expression must be something of type function, // e.g. (foo.bar())(1, 2) JetType calleeType = expressionTypingServices.safeGetType( context.scope, calleeExpression, NO_EXPECTED_TYPE, context.dataFlowInfo, context .trace); // We are actually expecting a function, but there seems to be no easy // way of expressing this if (!KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(calleeType)) { // checkTypesWithNoCallee(trace, scope, call); if (!calleeType.isError()) { context.trace.report(CALLEE_NOT_A_FUNCTION.on(calleeExpression, calleeType)); } return checkArgumentTypesAndFail(context); } FunctionDescriptorImpl functionDescriptor = new ExpressionAsFunctionDescriptor( context.scope.getContainingDeclaration(), Name.special("<for expression " + calleeExpression.getText() + ">"), calleeExpression); FunctionDescriptorUtil.initializeFromFunctionType( functionDescriptor, calleeType, NO_RECEIVER_PARAMETER, Modality.FINAL, Visibilities.LOCAL); ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create( functionDescriptor, JetPsiUtil.isSafeCall(context.call)); resolutionCandidate.setReceiverArgument(context.call.getExplicitReceiver()); resolutionCandidate.setExplicitReceiverKind(ExplicitReceiverKind.RECEIVER_ARGUMENT); // strictly speaking, this is a hack: // we need to pass a reference, but there's no reference in the PSI, // so we wrap what we have into a fake reference and pass it on (unwrap on the other end) functionReference = new JetFakeReference(calleeExpression); prioritizedTasks = Collections.singletonList( new ResolutionTask<CallableDescriptor, FunctionDescriptor>( Collections.singleton(resolutionCandidate), functionReference, context)); } else { // checkTypesWithNoCallee(trace, scope, call); return checkArgumentTypesAndFail(context); } } return doResolveCallOrGetCachedResults( ResolutionResultsCache.FUNCTION_MEMBER_TYPE, context, prioritizedTasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference); }