private JetDecompiledData build() { myBuilder.append(PsiBundle.message("psi.decompiled.text.header")); myBuilder.append("\n\n"); String packageName = myClsFile.getPackageName(); if (packageName.length() > 0) { myBuilder.append("package ").append(packageName).append("\n\n"); } PsiClass psiClass = myClsFile.getClasses()[0]; if (isKotlinNamespaceClass(psiClass)) { NamespaceDescriptor nd = myJavaDescriptorResolver.resolveNamespace( new FqName(packageName), DescriptorSearchRule.INCLUDE_KOTLIN); if (nd != null) { for (DeclarationDescriptor member : sortDeclarations(nd.getMemberScope().getAllDescriptors())) { if (member instanceof ClassDescriptor || member instanceof NamespaceDescriptor) { continue; } appendDescriptor(member, ""); myBuilder.append("\n"); } } } else { ClassDescriptor cd = myJavaDescriptorResolver.resolveClass(psiClass, DescriptorSearchRule.INCLUDE_KOTLIN); if (cd != null) { appendDescriptor(cd, ""); } } JetFile jetFile = JetDummyClassFileViewProvider.createJetFile( myClsFile.getManager(), myClsFile.getVirtualFile(), myBuilder.toString()); for (Map.Entry<PsiElement, TextRange> clsMemberToRange : myClsMembersToRanges.entrySet()) { PsiElement clsMember = clsMemberToRange.getKey(); assert clsMember instanceof ClsElementImpl; TextRange range = clsMemberToRange.getValue(); JetDeclaration jetDeclaration = PsiTreeUtil.findElementOfClassAtRange( jetFile, range.getStartOffset(), range.getEndOffset(), JetDeclaration.class); assert jetDeclaration != null; myClsElementsToJetElements.put((ClsElementImpl) clsMember, jetDeclaration); } return new JetDecompiledData(jetFile, myClsElementsToJetElements); }
private static Collection<ClassDescriptor> getClassOrObjectDescriptorsByFqName( NamespaceDescriptor packageDescriptor, FqName path, boolean includeObjectDeclarations) { if (path.isRoot()) { return Collections.emptyList(); } Collection<JetScope> scopes = Arrays.asList(packageDescriptor.getMemberScope()); List<Name> names = path.pathSegments(); if (names.size() > 1) { for (Name subName : path.pathSegments().subList(0, names.size() - 1)) { Collection<JetScope> tempScopes = Lists.newArrayList(); for (JetScope scope : scopes) { ClassifierDescriptor classifier = scope.getClassifier(subName); if (classifier instanceof ClassDescriptorBase) { ClassDescriptorBase classDescriptor = (ClassDescriptorBase) classifier; tempScopes.add(classDescriptor.getUnsubstitutedInnerClassesScope()); } } scopes = tempScopes; } } Name shortName = path.shortName(); Collection<ClassDescriptor> resultClassifierDescriptors = Lists.newArrayList(); for (JetScope scope : scopes) { ClassifierDescriptor classifier = scope.getClassifier(shortName); if (classifier instanceof ClassDescriptor) { resultClassifierDescriptors.add((ClassDescriptor) classifier); } if (includeObjectDeclarations) { ClassDescriptor objectDescriptor = scope.getObjectDescriptor(shortName); if (objectDescriptor != null) { resultClassifierDescriptors.add(objectDescriptor); } } } return resultClassifierDescriptors; }
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(); }
@NotNull public Collection<FunctionDescriptor> getTopLevelFunctionDescriptorsByName( @NotNull String name, @NotNull JetSimpleNameExpression expression, @NotNull ResolveSession resolveSession, @NotNull GlobalSearchScope scope) { // name parameter can differ from expression.getReferenceName() when expression contains // completion suffix Name referenceName = expression.getIdentifier() == null ? JetPsiUtil.getConventionName(expression) : Name.identifier(name); if (referenceName == null || referenceName.toString().isEmpty()) { return Collections.emptyList(); } BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression); JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); if (jetScope == null) { return Collections.emptyList(); } Set<FunctionDescriptor> result = Sets.newHashSet(); Collection<PsiMethod> topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName( referenceName.getName(), project, scope); for (PsiMethod method : topLevelFunctionPrototypes) { FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method); if (functionFQN != null) { JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, new ImportPath(functionFQN, false)); Collection<? extends DeclarationDescriptor> declarationDescriptors = new QualifiedExpressionResolver() .analyseImportReference( importDirective, jetScope, new BindingTraceContext(), resolveSession.getModuleConfiguration()); for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) { if (declarationDescriptor instanceof FunctionDescriptor) { result.add((FunctionDescriptor) declarationDescriptor); } } } } Set<FqName> affectedPackages = Sets.newHashSet(); Collection<JetNamedFunction> jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(referenceName.getName(), project, scope); for (JetNamedFunction jetNamedFunction : jetNamedFunctions) { PsiFile containingFile = jetNamedFunction.getContainingFile(); if (containingFile instanceof JetFile) { JetFile jetFile = (JetFile) containingFile; String packageName = jetFile.getPackageName(); if (packageName != null) { affectedPackages.add(new FqName(packageName)); } } } for (FqName affectedPackage : affectedPackages) { NamespaceDescriptor packageDescriptor = resolveSession.getPackageDescriptorByFqName(affectedPackage); assert packageDescriptor != null : "There's a function in stub index with invalid package: " + affectedPackage; JetScope memberScope = packageDescriptor.getMemberScope(); result.addAll(memberScope.getFunctions(referenceName)); } return result; }
public static JetScope getExpressionMemberScope( @NotNull ResolveSession resolveSession, @NotNull JetExpression expression) { DelegatingBindingTrace trace = new DelegatingBindingTrace( resolveSession.getBindingContext(), "trace to resolve a member scope of expression", expression); if (expression instanceof JetReferenceExpression) { QualifiedExpressionResolver qualifiedExpressionResolver = resolveSession.getInjector().getQualifiedExpressionResolver(); // In some type declaration if (expression.getParent() instanceof JetUserType) { JetUserType qualifier = ((JetUserType) expression.getParent()).getQualifier(); if (qualifier != null) { Collection<? extends DeclarationDescriptor> descriptors = qualifiedExpressionResolver.lookupDescriptorsForUserType( qualifier, getExpressionResolutionScope(resolveSession, expression), trace); for (DeclarationDescriptor descriptor : descriptors) { if (descriptor instanceof LazyPackageDescriptor) { return ((LazyPackageDescriptor) descriptor).getMemberScope(); } } } } // Inside import if (PsiTreeUtil.getParentOfType(expression, JetImportDirective.class, false) != null) { NamespaceDescriptor rootPackage = resolveSession.getPackageDescriptorByFqName(FqName.ROOT); assert rootPackage != null; if (expression.getParent() instanceof JetDotQualifiedExpression) { JetExpression element = ((JetDotQualifiedExpression) expression.getParent()).getReceiverExpression(); String name = ((JetFile) expression.getContainingFile()).getPackageName(); NamespaceDescriptor filePackage = name != null ? resolveSession.getPackageDescriptorByFqName(new FqName(name)) : rootPackage; assert filePackage != null : "File package should be already resolved and be found"; JetScope scope = filePackage.getMemberScope(); Collection<? extends DeclarationDescriptor> descriptors; if (element instanceof JetDotQualifiedExpression) { descriptors = qualifiedExpressionResolver.lookupDescriptorsForQualifiedExpression( (JetDotQualifiedExpression) element, rootPackage.getMemberScope(), scope, trace, false, false); } else { descriptors = qualifiedExpressionResolver.lookupDescriptorsForSimpleNameReference( (JetSimpleNameExpression) element, rootPackage.getMemberScope(), scope, trace, false, false, false); } for (DeclarationDescriptor descriptor : descriptors) { if (descriptor instanceof NamespaceDescriptor) { return ((NamespaceDescriptor) descriptor).getMemberScope(); } } } else { return rootPackage.getMemberScope(); } } // Inside package declaration JetNamespaceHeader namespaceHeader = PsiTreeUtil.getParentOfType(expression, JetNamespaceHeader.class, false); if (namespaceHeader != null) { NamespaceDescriptor packageDescriptor = resolveSession.getPackageDescriptorByFqName( namespaceHeader.getParentFqName((JetReferenceExpression) expression)); if (packageDescriptor != null) { return packageDescriptor.getMemberScope(); } } } return null; }