From e4cefd000ab8db59226de61b693f2150e51e08a4 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 16 Feb 2012 15:35:54 +0400 Subject: [PATCH] KT-1229 Packages should be showed in package derictive --- .../jetbrains/jet/compiler/TipsManager.java | 10 ++++ .../jet/lang/parsing/JetParsing.java | 11 +++- .../jet/lang/psi/JetNamespaceHeader.java | 19 ++++++- .../lang/resolve/TypeHierarchyResolver.java | 30 ++++++++--- idea/src/META-INF/plugin.xml | 6 ++- .../completion/DescriptorLookupConverter.java | 15 +++++- .../GlobalMemberCompletionContributor.java | 52 ------------------- .../completion/JetCompletionContributor.java | 25 ++++----- .../references/JetReferenceContributor.java | 10 ++++ .../references/JetSimpleNameReference.java | 18 +------ .../completion/JetBasicCompletionTest.java | 8 +++ .../CompletionMultifileHandlerTest.java | 19 +++---- ...thJdkAndRuntimeLightProjectDescriptor.java | 2 +- 13 files changed, 122 insertions(+), 103 deletions(-) delete mode 100644 idea/src/org/jetbrains/jet/plugin/completion/GlobalMemberCompletionContributor.java diff --git a/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java b/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java index 5b1281de6cb..0857ebfa235 100644 --- a/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java +++ b/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java @@ -97,6 +97,16 @@ public final class TipsManager { return Collections.emptyList(); } + @NotNull + public static Collection getReferenceVariants(JetNamespaceHeader expression, BindingContext context) { + JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); + if (resolutionScope != null) { + return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors()); + } + + return Collections.emptyList(); + } + public static Collection excludePrivateDescriptors( @NotNull Collection descriptors) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 2bdd9398639..b8aebb0e19f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -135,6 +135,8 @@ public class JetParsing extends AbstractJetParsing { if (at(PACKAGE_KEYWORD)) { advance(); // PACKAGE_KEYWORD + + parseNamespaceName(); if (at(LBRACE)) { @@ -162,7 +164,14 @@ public class JetParsing extends AbstractJetParsing { private void parseNamespaceName() { PsiBuilder.Marker nsName = mark(); while (true) { - expect(IDENTIFIER, "Namespace name must be a '.'-separated identifier list", NAMESPACE_NAME_RECOVERY_SET); + if (myBuilder.newlineBeforeCurrentToken()) { + errorWithRecovery("Package name must be a '.'-separated identifier list placed on a single line", NAMESPACE_NAME_RECOVERY_SET); + nsName.drop(); + break; + } + + expect(IDENTIFIER, "Package name must be a '.'-separated identifier list", NAMESPACE_NAME_RECOVERY_SET); + if (at(DOT)) { nsName.done(REFERENCE_EXPRESSION); advance(); // DOT diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceHeader.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceHeader.java index 27d2c1416fe..97dc2a7e749 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceHeader.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceHeader.java @@ -18,6 +18,9 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceService; +import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; @@ -28,7 +31,7 @@ import java.util.List; /** * @author abreslav */ -public class JetNamespaceHeader extends JetElement { +public class JetNamespaceHeader extends JetReferenceExpression { public JetNamespaceHeader(@NotNull ASTNode node) { super(node); } @@ -38,6 +41,19 @@ public class JetNamespaceHeader extends JetElement { return findChildrenByType(JetNodeTypes.REFERENCE_EXPRESSION); } + @NotNull + @Override + public PsiReference[] getReferences() { + return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS); + } + + @Nullable + @Override + public PsiReference getReference() { + PsiReference[] references = getReferences(); + return references.length == 1 ? references[0] : null; + } + @Nullable public PsiElement getNameIdentifier() { return findChildByType(JetTokens.IDENTIFIER); @@ -49,3 +65,4 @@ public class JetNamespaceHeader extends JetElement { return nameIdentifier == null ? "" : nameIdentifier.getText(); } } + diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index cb1ef490ab1..8fe8c8e8eba 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -85,7 +85,7 @@ public class TypeHierarchyResolver { declaration.accept(new JetVisitorVoid() { @Override public void visitJetFile(JetFile file) { - NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorPathIfNeeded(file, owner); + NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorPathIfNeeded(file, owner, outerScope); context.getNamespaceDescriptors().put(file, namespaceDescriptor); WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), new TraceBasedRedeclarationHandler(context.getTrace())); @@ -199,19 +199,34 @@ public class TypeHierarchyResolver { } } - private NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(JetFile file, NamespaceLike owner) { + private NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(JetFile file, NamespaceLike owner, JetScope outerScope) { + NamespaceLike currentOwner = owner; + for (JetSimpleNameExpression nameExpression : file.getNamespaceHeader().getParentNamespaceNames()) { - currentOwner = createNamespaceDescriptorIfNeeded(null, currentOwner, JetPsiUtil.safeName(nameExpression.getReferencedName())); + String namespaceName = JetPsiUtil.safeName(nameExpression.getReferencedName()); + + NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorIfNeeded(null, currentOwner, namespaceName); + + currentOwner = namespaceDescriptor; + context.getTrace().record(REFERENCE_TARGET, nameExpression, currentOwner); + context.getTrace().record(RESOLUTION_SCOPE, nameExpression, outerScope); + + outerScope = namespaceDescriptor.getMemberScope(); } String name = JetPsiUtil.safeName(file.getNamespaceHeader().getName()); + context.getTrace().record(RESOLUTION_SCOPE, file.getNamespaceHeader(), outerScope); + return createNamespaceDescriptorIfNeeded(file, currentOwner, name); + + } @NotNull - private NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file, @NotNull NamespaceLike owner, @NotNull String name) { + private NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file, @NotNull NamespaceLike owner, String name) { + NamespaceDescriptorImpl namespaceDescriptor = owner.getNamespace(name); if (namespaceDescriptor == null) { namespaceDescriptor = new NamespaceDescriptorImpl( @@ -229,6 +244,7 @@ public class TypeHierarchyResolver { context.getTrace().record(BindingContext.NAMESPACE, file, namespaceDescriptor); } } + return namespaceDescriptor; } @@ -406,7 +422,7 @@ public class TypeHierarchyResolver { Filter.REMOVE_IF_SUBTYPE_IN_THE_SET.proceed(conflictingTypes); break; } - + if (conflictingTypes.size() > 1) { DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration(); assert containingDeclaration instanceof ClassDescriptor : containingDeclaration; @@ -436,7 +452,7 @@ public class TypeHierarchyResolver { return JetTypeChecker.INSTANCE.isSubtypeOf(subject, other); } }; - + private void proceed(Set conflictingTypes) { for (Iterator iterator = conflictingTypes.iterator(); iterator.hasNext(); ) { JetType type = iterator.next(); @@ -452,7 +468,7 @@ public class TypeHierarchyResolver { public abstract boolean removeNeeded(JetType subject, JetType other); } - + private void checkTypesInClassHeaders() { for (Map.Entry entry : context.getClasses().entrySet()) { JetClass jetClass = entry.getKey(); diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index acbebe0abdd..3421b9817a4 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -49,6 +49,7 @@ + @@ -70,14 +71,17 @@ + + - + diff --git a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java index 9f2a9f17172..21926bbed22 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.plugin.completion; +import com.google.common.collect.Lists; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.util.Iconable; @@ -31,6 +32,8 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler; import org.jetbrains.jet.resolve.DescriptorRenderer; +import java.util.List; + /** * @author Nikolay Krasko */ @@ -95,7 +98,7 @@ public final class DescriptorLookupConverter { return element; } - @NotNull + @NotNull public static LookupElement createLookupElement(@NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor descriptor) { if (descriptor instanceof CallableMemberDescriptor) { CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) descriptor; @@ -107,4 +110,14 @@ public final class DescriptorLookupConverter { } return createLookupElement(descriptor, bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor)); } + + public static LookupElement[] collectLookupElements(BindingContext bindingContext, Iterable descriptors) { + List result = Lists.newArrayList(); + + for (final DeclarationDescriptor descriptor : descriptors) { + result.add(createLookupElement(bindingContext, descriptor)); + } + + return result.toArray(new LookupElement[result.size()]); + } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/GlobalMemberCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/GlobalMemberCompletionContributor.java deleted file mode 100644 index ab50e19c1b7..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/completion/GlobalMemberCompletionContributor.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2010-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.completion; - -import com.intellij.codeInsight.completion.*; -import com.intellij.patterns.PlatformPatterns; -import com.intellij.psi.PsiElement; -import com.intellij.util.ProcessingContext; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetFile; - -/** - * @author Nikolay Krasko - */ -public class GlobalMemberCompletionContributor extends CompletionContributor { - public GlobalMemberCompletionContributor() { - extend(CompletionType.CLASS_NAME, PlatformPatterns.psiElement(), - new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, - @NotNull CompletionResultSet result) { - if (result.getPrefixMatcher().getPrefix().isEmpty()) { - return; - } - - final PsiElement position = parameters.getPosition(); - if (!(position.getContainingFile() instanceof JetFile)) { - return; - } - -// final PsiElement parent = position.getParent(); -// if (parent.getReference() instanceof JetSimpleName) - - return; - } - }); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index 9eab90e3007..7b18dbc0bc4 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -69,25 +69,24 @@ public class JetCompletionContributor extends CompletionContributor { final JetSimpleNameReference jetReference = getJetReference(parameters); if (jetReference != null) { for (Object variant : jetReference.getVariants()) { - addReferenceVariant(result, variant, positions, parameters.getPosition().getProject()); + addReferenceVariant(result, variant, positions); } - } - if (shouldRunTopLevelCompletion(parameters)) { - addClasses(parameters, result, positions); - addJetTopLevelFunctions(result, position, positions); - } + if (shouldRunTopLevelCompletion(parameters)) { + addClasses(parameters, result, positions); + addJetTopLevelFunctions(result, position, positions); + } - result.stopHere(); + result.stopHere(); + } } }); } private static void addReferenceVariant( - @NotNull CompletionResultSet result, + @NotNull CompletionResultSet result, @NotNull Object variant, - @NotNull final HashSet positions, - @NotNull final Project project) { + @NotNull final HashSet positions) { if (variant instanceof LookupElement) { addCompletionToResult(result, (LookupElement) variant, positions); @@ -99,7 +98,7 @@ public class JetCompletionContributor extends CompletionContributor { private static void addJetTopLevelFunctions(@NotNull CompletionResultSet result, @NotNull PsiElement position, @NotNull final HashSet positions) { - + String actualPrefix = result.getPrefixMatcher().getPrefix(); final Project project = position.getProject(); @@ -153,7 +152,7 @@ public class JetCompletionContributor extends CompletionContributor { if (parameters.getInvocationCount() > 1) { return true; } - + if (element.getNode().getElementType() == JetTokens.IDENTIFIER) { if (element.getParent() instanceof JetSimpleNameExpression) { JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) element.getParent(); @@ -211,9 +210,11 @@ public class JetCompletionContributor extends CompletionContributor { private static LookupPositionObject getLookupPosition(LookupElement element) { final Object lookupObject = element.getObject(); if (lookupObject instanceof PsiElement) { +// PsiElement psiElement = (PsiElement) lookupObject; return new LookupPositionObject((PsiElement) lookupObject); } else if (lookupObject instanceof JetLookupObject) { +// JetLookupObject jetLookupObject = (JetLookupObject) lookupObject; final PsiElement psiElement = ((JetLookupObject) lookupObject).getPsiElement(); if (psiElement != null) { return new LookupPositionObject(psiElement); diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetReferenceContributor.java b/idea/src/org/jetbrains/jet/plugin/references/JetReferenceContributor.java index 11532be83dd..9a73cfcac8b 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/JetReferenceContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/references/JetReferenceContributor.java @@ -20,6 +20,7 @@ import com.intellij.psi.*; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetArrayAccessExpression; +import org.jetbrains.jet.lang.psi.JetNamespaceHeader; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.psi.JetThisReferenceExpression; @@ -40,6 +41,15 @@ public class JetReferenceContributor extends PsiReferenceContributor { } }); + registrar.registerReferenceProvider(psiElement(JetNamespaceHeader.class), + new PsiReferenceProvider() { + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + return new PsiReference[] { new JetPackageReference((JetNamespaceHeader) element) }; + } + }); + registrar.registerReferenceProvider(psiElement(JetThisReferenceExpression.class), new PsiReferenceProvider() { @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java index af8cc61672b..96027693cf6 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java +++ b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java @@ -16,14 +16,11 @@ package org.jetbrains.jet.plugin.references; -import com.google.common.collect.Lists; -import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.compiler.TipsManager; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; @@ -31,8 +28,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.completion.DescriptorLookupConverter; -import java.util.List; - /** * @author yole */ @@ -63,7 +58,8 @@ public class JetSimpleNameReference extends JetPsiReference { BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile( (JetFile) myExpression.getContainingFile()); - return collectLookupElements(bindingContext, TipsManager.getReferenceVariants(myExpression, bindingContext)); + return DescriptorLookupConverter.collectLookupElements( + bindingContext, TipsManager.getReferenceVariants(myExpression, bindingContext)); } @Override @@ -71,14 +67,4 @@ public class JetSimpleNameReference extends JetPsiReference { PsiElement element = JetPsiFactory.createNameIdentifier(myExpression.getProject(), newElementName); return myExpression.getReferencedNameElement().replace(element); } - - private static Object[] collectLookupElements(BindingContext bindingContext, Iterable descriptors) { - List result = Lists.newArrayList(); - - for (final DeclarationDescriptor descriptor : descriptors) { - result.add(DescriptorLookupConverter.createLookupElement(bindingContext, descriptor)); - } - - return result.toArray(); - } } diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java index 50d6df6930f..660e9d1f92f 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java @@ -65,6 +65,14 @@ public class JetBasicCompletionTest extends JetCompletionTestBase { doTest(); } + public void testInMiddleOfPackage() { + doTest(); + } + + public void testInPackage() { + doTest(); + } + public void testJavaClassNames() { doTest(); } diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java b/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java index 678cc044027..68e78e1c80e 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java +++ b/idea/tests/org/jetbrains/jet/completion/handlers/CompletionMultifileHandlerTest.java @@ -26,27 +26,24 @@ import java.io.File; */ public class CompletionMultifileHandlerTest extends CompletionTestCase { - public void testTopLevelFunctionImport() { + public void testTopLevelFunctionImport() throws Exception { doTest(); } - public void testTopLevelFunctionInQualifiedExpr() { + public void testTopLevelFunctionInQualifiedExpr() throws Exception { doTest(); } - public void testNoParenthesisInImports() { + public void testNoParenthesisInImports() throws Exception { doTest(); } - public void doTest() { + public void doTest() throws Exception { String fileName = getTestName(false); - try { - configureByFiles(null, fileName + "-1.kt", fileName + "-2.kt"); - complete(2); - checkResultByFile(fileName + ".kt.after"); - } catch (Exception e) { - throw new AssertionError(e); - } + + configureByFiles(null, fileName + "-1.kt", fileName + "-2.kt"); + complete(2); + checkResultByFile(fileName + ".kt.after"); } @Override diff --git a/idea/tests/org/jetbrains/jet/plugin/JetWithJdkAndRuntimeLightProjectDescriptor.java b/idea/tests/org/jetbrains/jet/plugin/JetWithJdkAndRuntimeLightProjectDescriptor.java index 754f5de4cc8..a698d4fea2b 100644 --- a/idea/tests/org/jetbrains/jet/plugin/JetWithJdkAndRuntimeLightProjectDescriptor.java +++ b/idea/tests/org/jetbrains/jet/plugin/JetWithJdkAndRuntimeLightProjectDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2012 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.