private static JetScope getExpressionResolutionScope( @NotNull ResolveSession resolveSession, @NotNull JetExpression expression) { ScopeProvider provider = resolveSession.getInjector().getScopeProvider(); JetDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(expression, JetDeclaration.class); if (parentDeclaration == null) { return provider.getFileScopeWithAllImported((JetFile) expression.getContainingFile()); } return provider.getResolutionScopeForDeclaration(parentDeclaration); }
public static @NotNull BindingContext resolveToExpression( @NotNull final ResolveSession resolveSession, @NotNull JetExpression expression) { final DelegatingBindingTrace trace = new DelegatingBindingTrace( resolveSession.getBindingContext(), "trace to resolve expression", expression); JetFile file = (JetFile) expression.getContainingFile(); @SuppressWarnings("unchecked") PsiElement topmostCandidateForAdditionalResolve = JetPsiUtil.getTopmostParentOfTypes( expression, JetNamedFunction.class, JetClassInitializer.class, JetProperty.class, JetDelegationSpecifierList.class); if (topmostCandidateForAdditionalResolve != null) { if (topmostCandidateForAdditionalResolve instanceof JetNamedFunction) { functionAdditionalResolve( resolveSession, (JetNamedFunction) topmostCandidateForAdditionalResolve, trace, file); } else if (topmostCandidateForAdditionalResolve instanceof JetClassInitializer) { initializerAdditionalResolve( resolveSession, (JetClassInitializer) topmostCandidateForAdditionalResolve, trace, file); } else if (topmostCandidateForAdditionalResolve instanceof JetProperty) { propertyAdditionalResolve( resolveSession, (JetProperty) topmostCandidateForAdditionalResolve, trace, file); } else if (topmostCandidateForAdditionalResolve instanceof JetDelegationSpecifierList) { delegationSpecifierAdditionalResolve( resolveSession, (JetDelegationSpecifierList) topmostCandidateForAdditionalResolve, trace, file); } else { assert false : "Invalid type of the topmost parent"; } return trace.getBindingContext(); } // Setup resolution scope explicitly if (trace.getBindingContext().get(BindingContext.RESOLUTION_SCOPE, expression) == null) { JetScope scope = getExpressionMemberScope(resolveSession, expression); if (scope != null) { trace.record(BindingContext.RESOLUTION_SCOPE, expression, scope); } } return trace.getBindingContext(); }
/** * Name suggestion types: 1. According to type: 1a. Primitive types to some short name 1b. Class * types according to class name camel humps: (AbCd => {abCd, cd}) 1c. Arrays => arrayOfInnerType * 2. Reference expressions according to reference name camel humps 3. Method call expression * according to method callee expression * * @param expression to suggest name for variable * @param validator to check scope for such names * @return possible names */ public static String[] suggestNames(JetExpression expression, JetNameValidator validator) { ArrayList<String> result = new ArrayList<String>(); BindingContext bindingContext = AnalyzeSingleFileUtil.getContextForSingleFile((JetFile) expression.getContainingFile()); JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression); if (jetType != null) { addNamesForType(result, jetType, validator); } addNamesForExpression(result, expression, validator); if (result.isEmpty()) addName(result, "value", validator); return ArrayUtil.toStringArray(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; }