public void checkRedeclarationsInInnerClassNames(@NotNull TopDownAnalysisContext c) { for (ClassDescriptorWithResolutionScopes classDescriptor : c.getDeclaredClasses().values()) { if (classDescriptor.getKind() == ClassKind.CLASS_OBJECT) { // Class objects should be considered during analysing redeclarations in classes continue; } Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors(); ClassDescriptorWithResolutionScopes classObj = classDescriptor.getClassObjectDescriptor(); if (classObj != null) { Collection<DeclarationDescriptor> classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors(); if (!classObjDescriptors.isEmpty()) { allDescriptors = Lists.newArrayList(allDescriptors); allDescriptors.addAll(classObjDescriptors); } } Multimap<Name, DeclarationDescriptor> descriptorMap = HashMultimap.create(); for (DeclarationDescriptor desc : allDescriptors) { if (desc instanceof ClassDescriptor || desc instanceof PropertyDescriptor) { descriptorMap.put(desc.getName(), desc); } } reportRedeclarations(descriptorMap); } }
private static List<FunctionDescriptor> getSuperFunctionsForMethod( @NotNull PsiMethodWrapper method, @NotNull BindingTrace trace, @NotNull ClassDescriptor containingClass) { List<FunctionDescriptor> superFunctions = Lists.newArrayList(); Map<ClassDescriptor, JetType> superclassToSupertype = getSuperclassToSupertypeMap(containingClass); Multimap<FqName, Pair<FunctionDescriptor, PsiMethod>> superclassToFunctions = getSuperclassToFunctionsMultimap(method, trace.getBindingContext(), containingClass); for (HierarchicalMethodSignature superSignature : method.getPsiMethod().getHierarchicalMethodSignature().getSuperSignatures()) { PsiMethod superMethod = superSignature.getMethod(); PsiClass psiClass = superMethod.getContainingClass(); assert psiClass != null; String classFqNameString = psiClass.getQualifiedName(); assert classFqNameString != null; FqName classFqName = new FqName(classFqNameString); if (!JavaToKotlinClassMap.getInstance().mapPlatformClass(classFqName).isEmpty()) { for (FunctionDescriptor superFun : JavaToKotlinMethodMap.INSTANCE.getFunctions(superMethod, containingClass)) { superFunctions.add(substituteSuperFunction(superclassToSupertype, superFun)); } continue; } DeclarationDescriptor superFun = superMethod instanceof JetClsMethod ? trace.get( BindingContext.DECLARATION_TO_DESCRIPTOR, ((JetClsMethod) superMethod).getOrigin()) : findSuperFunction(superclassToFunctions.get(classFqName), superMethod); if (superFun == null) { reportCantFindSuperFunction(method); continue; } assert superFun instanceof FunctionDescriptor : superFun.getClass().getName(); superFunctions.add( substituteSuperFunction(superclassToSupertype, (FunctionDescriptor) superFun)); } // sorting for diagnostic stability Collections.sort( superFunctions, new Comparator<FunctionDescriptor>() { @Override public int compare(FunctionDescriptor fun1, FunctionDescriptor fun2) { FqNameUnsafe fqName1 = getFQName(fun1.getContainingDeclaration()); FqNameUnsafe fqName2 = getFQName(fun2.getContainingDeclaration()); return fqName1.getFqName().compareTo(fqName2.getFqName()); } }); return superFunctions; }
private String renderDefaultType(JetType type, boolean shortNamesOnly) { StringBuilder sb = new StringBuilder(); ClassifierDescriptor cd = type.getConstructor().getDeclarationDescriptor(); Object typeNameObject; if (cd == null || cd instanceof TypeParameterDescriptor) { typeNameObject = type.getConstructor(); } else { if (shortNamesOnly) { // for nested classes qualified name should be used typeNameObject = cd.getName(); DeclarationDescriptor parent = cd.getContainingDeclaration(); while (parent instanceof ClassDescriptor) { typeNameObject = parent.getName() + "." + typeNameObject; parent = parent.getContainingDeclaration(); } } else { typeNameObject = DescriptorUtils.getFQName(cd); } } sb.append(typeNameObject); if (!type.getArguments().isEmpty()) { sb.append("<"); appendTypeProjections(sb, type.getArguments(), shortNamesOnly); sb.append(">"); } if (type.isNullable()) { sb.append("?"); } return sb.toString(); }
@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; } }
@NotNull private static FqNameUnsafe getFqNameUnsafe(@NotNull DeclarationDescriptor descriptor) { DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); assert containingDeclaration != null : "Not package/module descriptor doesn't have containing declaration: " + descriptor; return getFqName(containingDeclaration).child(descriptor.getName()); }
@NotNull public static FqName getFqNameFromTopLevelClass(@NotNull DeclarationDescriptor descriptor) { DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); Name name = descriptor.getName(); if (!(containingDeclaration instanceof ClassDescriptor)) { return FqName.topLevel(name); } return getFqNameFromTopLevelClass(containingDeclaration).child(name); }
/** Descriptor may be local itself or have a local ancestor */ public static boolean isLocal(@NotNull DeclarationDescriptor descriptor) { DeclarationDescriptor current = descriptor; while (current != null) { if (isAnonymousObject(current) || isDescriptorWithLocalVisibility(current)) { return true; } current = current.getContainingDeclaration(); } return false; }
@Nullable public static ClassDescriptor getContainingClass(@NotNull DeclarationDescriptor descriptor) { DeclarationDescriptor containing = descriptor.getContainingDeclaration(); while (containing != null) { if (containing instanceof ClassDescriptor && !isCompanionObject(containing)) { return (ClassDescriptor) containing; } containing = containing.getContainingDeclaration(); } return null; }
private String doCompareNamespaces( @NotNull NamespaceDescriptor nsa, @NotNull NamespaceDescriptor nsb) { StringBuilder sb = new StringBuilder(); Assert.assertEquals(nsa.getName(), nsb.getName()); sb.append("namespace " + nsa.getName() + "\n\n"); Assert.assertTrue(!nsa.getMemberScope().getAllDescriptors().isEmpty()); Set<String> classifierNames = new HashSet<String>(); Set<String> propertyNames = new HashSet<String>(); Set<String> functionNames = new HashSet<String>(); for (DeclarationDescriptor ad : nsa.getMemberScope().getAllDescriptors()) { if (ad instanceof ClassifierDescriptor) { classifierNames.add(ad.getName()); } else if (ad instanceof PropertyDescriptor) { propertyNames.add(ad.getName()); } else if (ad instanceof FunctionDescriptor) { functionNames.add(ad.getName()); } else { throw new AssertionError("unknown member: " + ad); } } for (String name : classifierNames) { ClassifierDescriptor ca = nsa.getMemberScope().getClassifier(name); ClassifierDescriptor cb = nsb.getMemberScope().getClassifier(name); Assert.assertTrue(ca != null); Assert.assertTrue(cb != null); compareClassifiers(ca, cb, sb); } for (String name : propertyNames) { Set<VariableDescriptor> pa = nsa.getMemberScope().getProperties(name); Set<VariableDescriptor> pb = nsb.getMemberScope().getProperties(name); compareDeclarationSets(pa, pb, sb); Assert.assertTrue( nsb.getMemberScope().getFunctions(PropertyCodegen.getterName(name)).isEmpty()); Assert.assertTrue( nsb.getMemberScope().getFunctions(PropertyCodegen.setterName(name)).isEmpty()); } for (String name : functionNames) { Set<FunctionDescriptor> fa = nsa.getMemberScope().getFunctions(name); Set<FunctionDescriptor> fb = nsb.getMemberScope().getFunctions(name); compareDeclarationSets(fa, fb, sb); } return sb.toString(); }
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(); }
public static boolean isAncestor( @Nullable DeclarationDescriptor ancestor, @NotNull DeclarationDescriptor declarationDescriptor, boolean strict) { if (ancestor == null) return false; DeclarationDescriptor descriptor = strict ? declarationDescriptor.getContainingDeclaration() : declarationDescriptor; while (descriptor != null) { if (ancestor == descriptor) return true; descriptor = descriptor.getContainingDeclaration(); } return false; }
private void appendDescriptor(DeclarationDescriptor descriptor, String indent) { int startOffset = myBuilder.length(); myBuilder.append(DescriptorRenderer.COMPACT.render(descriptor)); int endOffset = myBuilder.length(); if (descriptor instanceof FunctionDescriptor || descriptor instanceof PropertyDescriptor) { if (((CallableMemberDescriptor) descriptor).getModality() != Modality.ABSTRACT) { if (descriptor instanceof FunctionDescriptor) { myBuilder.append(" { ").append(DECOMPILED_COMMENT).append(" }"); endOffset = myBuilder.length(); } else { // descriptor instanceof PropertyDescriptor if (((PropertyDescriptor) descriptor).getModality() != Modality.ABSTRACT) { myBuilder.append(" ").append(DECOMPILED_COMMENT); } } } } else if (descriptor instanceof ClassDescriptor) { myBuilder.append(" {\n"); ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; boolean firstPassed = false; String subindent = indent + " "; if (classDescriptor.getClassObjectDescriptor() != null) { firstPassed = true; myBuilder.append(subindent).append("class "); appendDescriptor(classDescriptor.getClassObjectDescriptor(), subindent); } for (DeclarationDescriptor member : sortDeclarations(classDescriptor.getDefaultType().getMemberScope().getAllDescriptors())) { if (member.getContainingDeclaration() == descriptor) { if (firstPassed) { myBuilder.append("\n"); } else { firstPassed = true; } myBuilder.append(subindent); appendDescriptor(member, subindent); } } myBuilder.append(indent).append("}"); endOffset = myBuilder.length(); } myBuilder.append("\n"); PsiElement clsMember = myBindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); if (clsMember != null) { myClsMembersToRanges.put(clsMember, new TextRange(startOffset, endOffset)); } }
private static boolean isSameClass( @NotNull KotlinType type, @NotNull DeclarationDescriptor other) { DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); if (descriptor != null) { DeclarationDescriptor originalDescriptor = descriptor.getOriginal(); if (originalDescriptor instanceof ClassifierDescriptor && other instanceof ClassifierDescriptor && ((ClassifierDescriptor) other) .getTypeConstructor() .equals(((ClassifierDescriptor) originalDescriptor).getTypeConstructor())) { return true; } } return false; }
public static CodegenContext getContext(DeclarationDescriptor descriptor, GenerationState state) { if (descriptor instanceof PackageFragmentDescriptor) { return new PackageContext( (PackageFragmentDescriptor) descriptor, state.getRootContext(), null); } CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state); if (descriptor instanceof ClassDescriptor) { OwnerKind kind = DescriptorUtils.isInterface(descriptor) ? OwnerKind.DEFAULT_IMPLS : OwnerKind.IMPLEMENTATION; return parent.intoClass((ClassDescriptor) descriptor, kind, state); } else if (descriptor instanceof ScriptDescriptor) { ClassDescriptor classDescriptorForScript = state.getBindingContext().get(CLASS_FOR_SCRIPT, (ScriptDescriptor) descriptor); assert classDescriptorForScript != null : "Can't find class for script: " + descriptor; List<ScriptDescriptor> earlierScripts = state.getEarlierScriptsForReplInterpreter(); return parent.intoScript( (ScriptDescriptor) descriptor, earlierScripts == null ? Collections.emptyList() : earlierScripts, classDescriptorForScript); } else if (descriptor instanceof FunctionDescriptor) { return parent.intoFunction((FunctionDescriptor) descriptor); } throw new IllegalStateException("Couldn't build context for " + descriptorName(descriptor)); }
@Nullable @SuppressWarnings("unchecked") public static <D extends DeclarationDescriptor> D getParentOfType( @Nullable DeclarationDescriptor descriptor, @NotNull Class<D> aClass, boolean strict) { if (descriptor == null) return null; if (strict) { descriptor = descriptor.getContainingDeclaration(); } while (descriptor != null) { if (aClass.isInstance(descriptor)) { return (D) descriptor; } descriptor = descriptor.getContainingDeclaration(); } return null; }
private static boolean isIllegalNestedClass(@NotNull DeclarationDescriptor descriptor) { if (!(descriptor instanceof ClassDescriptor)) return false; DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (!(containingDeclaration instanceof ClassDescriptor)) return false; ClassDescriptor containingClass = (ClassDescriptor) containingDeclaration; return containingClass.isInner() || containingClass.getContainingDeclaration() instanceof FunctionDescriptor; }
private void checkRedeclarationsInPackages(@NotNull TopDownAnalysisContext c) { for (MutablePackageFragmentDescriptor packageFragment : Sets.newHashSet(c.getPackageFragments().values())) { PackageViewDescriptor packageView = packageFragment.getContainingDeclaration().getPackage(packageFragment.getFqName()); JetScope packageViewScope = packageView.getMemberScope(); Multimap<Name, DeclarationDescriptor> simpleNameDescriptors = packageFragment.getMemberScope().getDeclaredDescriptorsAccessibleBySimpleName(); for (Name name : simpleNameDescriptors.keySet()) { // Keep only properties with no receiver Collection<DeclarationDescriptor> descriptors = Collections2.filter( simpleNameDescriptors.get(name), new Predicate<DeclarationDescriptor>() { @Override public boolean apply(@Nullable DeclarationDescriptor descriptor) { if (descriptor instanceof PropertyDescriptor) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; return propertyDescriptor.getReceiverParameter() == null; } return true; } }); ContainerUtil.addIfNotNull(descriptors, packageViewScope.getPackage(name)); if (descriptors.size() > 1) { for (DeclarationDescriptor declarationDescriptor : descriptors) { for (PsiElement declaration : getDeclarationsByDescriptor(declarationDescriptor)) { assert declaration != null : "Null declaration for descriptor: " + declarationDescriptor + " " + (declarationDescriptor != null ? DescriptorRenderer.FQ_NAMES_IN_TYPES.render(declarationDescriptor) : ""); trace.report( REDECLARATION.on(declaration, declarationDescriptor.getName().asString())); } } } } } }
private static boolean containsAnnotation( DeclarationDescriptor descriptor, FqName annotationClassFqName) { DeclarationDescriptor original = descriptor.getOriginal(); Annotations annotations = original.getAnnotations(); if (annotations.findAnnotation(annotationClassFqName) != null) return true; AnnotationUseSiteTarget associatedUseSiteTarget = AnnotationUseSiteTarget.Companion.getAssociatedUseSiteTarget(descriptor); if (associatedUseSiteTarget != null) { if (Annotations.Companion.findUseSiteTargetedAnnotation( annotations, associatedUseSiteTarget, annotationClassFqName) != null) { return true; } } return false; }
@NotNull protected static Set<String> getDeclarationLabels( @Nullable PsiElement lambdaOrFun, @NotNull DeclarationDescriptor descriptor) { Set<String> result = new HashSet<String>(); if (lambdaOrFun != null) { Name label = LabelResolver.INSTANCE.getLabelNameIfAny(lambdaOrFun); if (label != null) { result.add(label.asString()); } } if (!isFunctionLiteral(descriptor)) { if (!descriptor.getName().isSpecial()) { result.add(descriptor.getName().asString()); } result.add(InlineCodegenUtil.FIRST_FUN_LABEL); } return result; }
@NotNull @Override public String render(@NotNull DeclarationDescriptor declarationDescriptor) { StringBuilder stringBuilder = new StringBuilder(); declarationDescriptor.accept(new RenderDeclarationDescriptorVisitor(), stringBuilder); if (withDefinedIn) { appendDefinedIn(declarationDescriptor, stringBuilder); } return stringBuilder.toString(); }
@NotNull private String renderClassName(@NotNull ClassDescriptor klass) { if (ErrorUtils.isError(klass)) { return klass.getTypeConstructor().toString(); } if (shortNames) { List<Name> qualifiedNameElements = Lists.newArrayList(); // for nested classes qualified name should be used DeclarationDescriptor current = klass; do { if (((ClassDescriptor) current).getKind() != ClassKind.CLASS_OBJECT) { qualifiedNameElements.add(current.getName()); } current = current.getContainingDeclaration(); } while (current instanceof ClassDescriptor); Collections.reverse(qualifiedNameElements); return renderFqName(qualifiedNameElements); } return renderFqName(DescriptorUtils.getFQName(klass)); }
/* METHODS FOR ALL KINDS OF DESCRIPTORS */ private void appendDefinedIn( @NotNull DeclarationDescriptor descriptor, @NotNull StringBuilder builder) { if (descriptor instanceof ModuleDescriptor) { builder.append(" is a module"); return; } builder.append(" ").append(renderMessage("defined in")).append(" "); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (containingDeclaration != null) { FqNameUnsafe fqName = DescriptorUtils.getFQName(containingDeclaration); builder.append(FqName.ROOT.equalsTo(fqName) ? "root package" : renderFqName(fqName)); } }
/*descriptor is null for captured vars*/ public boolean shouldPutValue( @NotNull Type type, @Nullable StackValue stackValue, @Nullable ValueParameterDescriptor descriptor) { if (stackValue == null) { // default or vararg return true; } // remap only inline functions (and maybe non primitives) // TODO - clean asserion and remapping logic if (isPrimitive(type) != isPrimitive(stackValue.type)) { // don't remap boxing/unboxing primitives - lost identity and perfomance return true; } if (stackValue instanceof StackValue.Local) { return false; } StackValue field = stackValue; if (stackValue instanceof StackValue.FieldForSharedVar) { field = ((StackValue.FieldForSharedVar) stackValue).receiver; } // check that value corresponds to captured inlining parameter if (field instanceof StackValue.Field) { DeclarationDescriptor varDescriptor = ((StackValue.Field) field).descriptor; // check that variable is inline function parameter return !(varDescriptor instanceof ParameterDescriptor && InlineUtil.isInlineLambdaParameter((ParameterDescriptor) varDescriptor) && InlineUtil.isInline(varDescriptor.getContainingDeclaration())); } return true; }
private void reportRedeclarations(@NotNull Multimap<Name, DeclarationDescriptor> descriptorMap) { Set<Pair<PsiElement, Name>> redeclarations = Sets.newHashSet(); for (Name name : descriptorMap.keySet()) { Collection<DeclarationDescriptor> descriptors = descriptorMap.get(name); if (descriptors.size() > 1) { // We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at // OverloadResolver for (DeclarationDescriptor descriptor : descriptors) { if (descriptor instanceof ClassDescriptor) { for (DeclarationDescriptor descriptor2 : descriptors) { if (descriptor == descriptor2) { continue; } redeclarations.add( Pair.create( BindingContextUtils.classDescriptorToDeclaration( trace.getBindingContext(), (ClassDescriptor) descriptor), descriptor.getName())); if (descriptor2 instanceof PropertyDescriptor) { redeclarations.add( Pair.create( BindingContextUtils.descriptorToDeclaration( trace.getBindingContext(), descriptor2), descriptor2.getName())); } } } } } } for (Pair<PsiElement, Name> redeclaration : redeclarations) { trace.report( REDECLARATION.on(redeclaration.getFirst(), redeclaration.getSecond().asString())); } }
@Nullable public static ModuleDescriptor getContainingModuleOrNull( @NotNull DeclarationDescriptor descriptor) { while (descriptor != null) { if (descriptor instanceof ModuleDescriptor) { return (ModuleDescriptor) descriptor; } if (descriptor instanceof PackageViewDescriptor) { return ((PackageViewDescriptor) descriptor).getModule(); } //noinspection ConstantConditions descriptor = descriptor.getContainingDeclaration(); } return null; }
@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; }
public boolean isMemberOfAny(@NotNull DeclarationDescriptor descriptor) { return descriptor.getContainingDeclaration() == getAny(); }
/** * @return true if descriptor is a class inside another class and does not have access to the * outer class */ public static boolean isStaticNestedClass(@NotNull DeclarationDescriptor descriptor) { DeclarationDescriptor containing = descriptor.getContainingDeclaration(); return descriptor instanceof ClassDescriptor && containing instanceof ClassDescriptor && !((ClassDescriptor) descriptor).isInner(); }
public static boolean isAnonymousObject(@NotNull DeclarationDescriptor descriptor) { return isClass(descriptor) && descriptor.getName().equals(SpecialNames.NO_NAME_PROVIDED); }
public static boolean isTopLevelDeclaration(@Nullable DeclarationDescriptor descriptor) { return descriptor != null && descriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor; }