@Nullable private NamespaceType lookupNamespaceType( @NotNull JetSimpleNameExpression expression, @NotNull ResolutionContext context) { Name name = expression.getReferencedNameAsName(); NamespaceDescriptor namespace = context.scope.getNamespace(name); if (namespace == null) { return null; } context.trace.record(REFERENCE_TARGET, expression, namespace); // Construct a NamespaceType with everything from the namespace and with nested classes of the // corresponding class (if any) JetScope scope; ClassifierDescriptor classifier = context.scope.getClassifier(name); if (classifier instanceof ClassDescriptor) { scope = new ChainedScope( namespace, namespace.getMemberScope(), getStaticNestedClassesScope((ClassDescriptor) classifier)); } else { scope = namespace.getMemberScope(); } return new NamespaceType(name, scope); }
@Nullable private JetType getExtendedClassObjectType( @NotNull JetType classObjectType, @NotNull Name referencedName, @NotNull ClassifierDescriptor classifier, @NotNull ResolutionContext context) { if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT && classifier instanceof ClassDescriptor) { List<JetScope> scopes = new ArrayList<JetScope>(3); scopes.add(classObjectType.getMemberScope()); scopes.add(getStaticNestedClassesScope((ClassDescriptor) classifier)); NamespaceDescriptor namespace = context.scope.getNamespace(referencedName); if (namespace != null) { scopes.add(namespace.getMemberScope()); } JetScope scope = new ChainedScope(classifier, scopes.toArray(new JetScope[scopes.size()])); return new NamespaceType(referencedName, scope); } else if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT || classifier.isClassObjectAValue()) { return classObjectType; } else { return null; } }
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; }
@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; }