KT-1229 Packages should be showed in package derictive

This commit is contained in:
Nikolay Krasko
2012-02-16 15:35:54 +04:00
parent 504beac0fa
commit e4cefd000a
13 changed files with 122 additions and 103 deletions
@@ -97,6 +97,16 @@ public final class TipsManager {
return Collections.emptyList(); return Collections.emptyList();
} }
@NotNull
public static Collection<DeclarationDescriptor> 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<DeclarationDescriptor> excludePrivateDescriptors( public static Collection<DeclarationDescriptor> excludePrivateDescriptors(
@NotNull Collection<DeclarationDescriptor> descriptors) { @NotNull Collection<DeclarationDescriptor> descriptors) {
@@ -135,6 +135,8 @@ public class JetParsing extends AbstractJetParsing {
if (at(PACKAGE_KEYWORD)) { if (at(PACKAGE_KEYWORD)) {
advance(); // PACKAGE_KEYWORD advance(); // PACKAGE_KEYWORD
parseNamespaceName(); parseNamespaceName();
if (at(LBRACE)) { if (at(LBRACE)) {
@@ -162,7 +164,14 @@ public class JetParsing extends AbstractJetParsing {
private void parseNamespaceName() { private void parseNamespaceName() {
PsiBuilder.Marker nsName = mark(); PsiBuilder.Marker nsName = mark();
while (true) { 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)) { if (at(DOT)) {
nsName.done(REFERENCE_EXPRESSION); nsName.done(REFERENCE_EXPRESSION);
advance(); // DOT advance(); // DOT
@@ -18,6 +18,9 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement; 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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.JetNodeTypes;
@@ -28,7 +31,7 @@ import java.util.List;
/** /**
* @author abreslav * @author abreslav
*/ */
public class JetNamespaceHeader extends JetElement { public class JetNamespaceHeader extends JetReferenceExpression {
public JetNamespaceHeader(@NotNull ASTNode node) { public JetNamespaceHeader(@NotNull ASTNode node) {
super(node); super(node);
} }
@@ -38,6 +41,19 @@ public class JetNamespaceHeader extends JetElement {
return findChildrenByType(JetNodeTypes.REFERENCE_EXPRESSION); 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 @Nullable
public PsiElement getNameIdentifier() { public PsiElement getNameIdentifier() {
return findChildByType(JetTokens.IDENTIFIER); return findChildByType(JetTokens.IDENTIFIER);
@@ -49,3 +65,4 @@ public class JetNamespaceHeader extends JetElement {
return nameIdentifier == null ? "" : nameIdentifier.getText(); return nameIdentifier == null ? "" : nameIdentifier.getText();
} }
} }
@@ -85,7 +85,7 @@ public class TypeHierarchyResolver {
declaration.accept(new JetVisitorVoid() { declaration.accept(new JetVisitorVoid() {
@Override @Override
public void visitJetFile(JetFile file) { public void visitJetFile(JetFile file) {
NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorPathIfNeeded(file, owner); NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorPathIfNeeded(file, owner, outerScope);
context.getNamespaceDescriptors().put(file, namespaceDescriptor); context.getNamespaceDescriptors().put(file, namespaceDescriptor);
WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), new TraceBasedRedeclarationHandler(context.getTrace())); 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; NamespaceLike currentOwner = owner;
for (JetSimpleNameExpression nameExpression : file.getNamespaceHeader().getParentNamespaceNames()) { 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(REFERENCE_TARGET, nameExpression, currentOwner);
context.getTrace().record(RESOLUTION_SCOPE, nameExpression, outerScope);
outerScope = namespaceDescriptor.getMemberScope();
} }
String name = JetPsiUtil.safeName(file.getNamespaceHeader().getName()); String name = JetPsiUtil.safeName(file.getNamespaceHeader().getName());
context.getTrace().record(RESOLUTION_SCOPE, file.getNamespaceHeader(), outerScope);
return createNamespaceDescriptorIfNeeded(file, currentOwner, name); return createNamespaceDescriptorIfNeeded(file, currentOwner, name);
} }
@NotNull @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); NamespaceDescriptorImpl namespaceDescriptor = owner.getNamespace(name);
if (namespaceDescriptor == null) { if (namespaceDescriptor == null) {
namespaceDescriptor = new NamespaceDescriptorImpl( namespaceDescriptor = new NamespaceDescriptorImpl(
@@ -229,6 +244,7 @@ public class TypeHierarchyResolver {
context.getTrace().record(BindingContext.NAMESPACE, file, namespaceDescriptor); context.getTrace().record(BindingContext.NAMESPACE, file, namespaceDescriptor);
} }
} }
return namespaceDescriptor; return namespaceDescriptor;
} }
+5 -1
View File
@@ -49,6 +49,7 @@
<internalFileTemplate name="Kotlin File"/> <internalFileTemplate name="Kotlin File"/>
<fileTypeFactory implementation="org.jetbrains.jet.plugin.JetFileFactory"/> <fileTypeFactory implementation="org.jetbrains.jet.plugin.JetFileFactory"/>
<lang.syntaxHighlighterFactory key="jet" implementationClass="org.jetbrains.jet.plugin.JetSyntaxHighlighterFactory"/> <lang.syntaxHighlighterFactory key="jet" implementationClass="org.jetbrains.jet.plugin.JetSyntaxHighlighterFactory"/>
<lang.braceMatcher language="jet" implementationClass="org.jetbrains.jet.plugin.JetPairMatcher"/> <lang.braceMatcher language="jet" implementationClass="org.jetbrains.jet.plugin.JetPairMatcher"/>
<lang.parserDefinition language="jet" implementationClass="org.jetbrains.jet.lang.parsing.JetParserDefinition"/> <lang.parserDefinition language="jet" implementationClass="org.jetbrains.jet.lang.parsing.JetParserDefinition"/>
@@ -70,14 +71,17 @@
<completion.contributor language="jet" id="JetKeywordCompletionContributor" order="first" <completion.contributor language="jet" id="JetKeywordCompletionContributor" order="first"
implementationClass="org.jetbrains.jet.plugin.completion.JetKeywordCompletionContributor"/> implementationClass="org.jetbrains.jet.plugin.completion.JetKeywordCompletionContributor"/>
<completion.contributor language="jet" id="JetPackagesContributor" order="after JetKeywordCompletionContributor"
implementationClass="org.jetbrains.jet.plugin.completion.JetPackagesContributor" />
<completion.contributor language="jet" id="JetCompletionContributor" <completion.contributor language="jet" id="JetCompletionContributor"
implementationClass="org.jetbrains.jet.plugin.completion.JetCompletionContributor"/> implementationClass="org.jetbrains.jet.plugin.completion.JetCompletionContributor"/>
<completion.contributor language="jet" implementationClass="org.jetbrains.jet.plugin.completion.GlobalMemberCompletionContributor"/>
<completion.contributor language="jet" implementationClass="org.jetbrains.jet.plugin.liveTemplates.JetLiveTemplateCompletionContributor" id="liveTemplates" order="first"/> <completion.contributor language="jet" implementationClass="org.jetbrains.jet.plugin.liveTemplates.JetLiveTemplateCompletionContributor" id="liveTemplates" order="first"/>
<completion.confidence language="jet" implementationClass="com.intellij.codeInsight.completion.UnfocusedNameIdentifier"/> <completion.confidence language="jet" implementationClass="com.intellij.codeInsight.completion.UnfocusedNameIdentifier"/>
<completion.confidence language="jet" implementationClass="com.intellij.codeInsight.completion.AlwaysFocusLookup" order="last"/> <completion.confidence language="jet" implementationClass="com.intellij.codeInsight.completion.AlwaysFocusLookup" order="last"/>
<completion.skip implementation="org.jetbrains.jet.plugin.liveTemplates.JetLiveTemplateCompletionContributor$Skipper" id="skipLiveTemplate"/> <completion.skip implementation="org.jetbrains.jet.plugin.liveTemplates.JetLiveTemplateCompletionContributor$Skipper" id="skipLiveTemplate"/>
<psi.referenceContributor language="jet" order="after JetCompletionContributor" implementation="org.jetbrains.jet.plugin.references.JetReferenceContributor"/> <psi.referenceContributor language="jet" order="after JetCompletionContributor" implementation="org.jetbrains.jet.plugin.references.JetReferenceContributor"/>
@@ -16,6 +16,7 @@
package org.jetbrains.jet.plugin.completion; package org.jetbrains.jet.plugin.completion;
import com.google.common.collect.Lists;
import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.util.Iconable; 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.plugin.completion.handlers.JetFunctionInsertHandler;
import org.jetbrains.jet.resolve.DescriptorRenderer; import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.List;
/** /**
* @author Nikolay Krasko * @author Nikolay Krasko
*/ */
@@ -107,4 +110,14 @@ public final class DescriptorLookupConverter {
} }
return createLookupElement(descriptor, bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor)); return createLookupElement(descriptor, bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor));
} }
public static LookupElement[] collectLookupElements(BindingContext bindingContext, Iterable<DeclarationDescriptor> descriptors) {
List<LookupElement> result = Lists.newArrayList();
for (final DeclarationDescriptor descriptor : descriptors) {
result.add(createLookupElement(bindingContext, descriptor));
}
return result.toArray(new LookupElement[result.size()]);
}
} }
@@ -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<CompletionParameters>() {
@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;
}
});
}
}
@@ -69,16 +69,16 @@ public class JetCompletionContributor extends CompletionContributor {
final JetSimpleNameReference jetReference = getJetReference(parameters); final JetSimpleNameReference jetReference = getJetReference(parameters);
if (jetReference != null) { if (jetReference != null) {
for (Object variant : jetReference.getVariants()) { for (Object variant : jetReference.getVariants()) {
addReferenceVariant(result, variant, positions, parameters.getPosition().getProject()); addReferenceVariant(result, variant, positions);
} }
}
if (shouldRunTopLevelCompletion(parameters)) { if (shouldRunTopLevelCompletion(parameters)) {
addClasses(parameters, result, positions); addClasses(parameters, result, positions);
addJetTopLevelFunctions(result, position, positions); addJetTopLevelFunctions(result, position, positions);
} }
result.stopHere(); result.stopHere();
}
} }
}); });
} }
@@ -86,8 +86,7 @@ public class JetCompletionContributor extends CompletionContributor {
private static void addReferenceVariant( private static void addReferenceVariant(
@NotNull CompletionResultSet result, @NotNull CompletionResultSet result,
@NotNull Object variant, @NotNull Object variant,
@NotNull final HashSet<LookupPositionObject> positions, @NotNull final HashSet<LookupPositionObject> positions) {
@NotNull final Project project) {
if (variant instanceof LookupElement) { if (variant instanceof LookupElement) {
addCompletionToResult(result, (LookupElement) variant, positions); addCompletionToResult(result, (LookupElement) variant, positions);
@@ -211,9 +210,11 @@ public class JetCompletionContributor extends CompletionContributor {
private static LookupPositionObject getLookupPosition(LookupElement element) { private static LookupPositionObject getLookupPosition(LookupElement element) {
final Object lookupObject = element.getObject(); final Object lookupObject = element.getObject();
if (lookupObject instanceof PsiElement) { if (lookupObject instanceof PsiElement) {
// PsiElement psiElement = (PsiElement) lookupObject;
return new LookupPositionObject((PsiElement) lookupObject); return new LookupPositionObject((PsiElement) lookupObject);
} }
else if (lookupObject instanceof JetLookupObject) { else if (lookupObject instanceof JetLookupObject) {
// JetLookupObject jetLookupObject = (JetLookupObject) lookupObject;
final PsiElement psiElement = ((JetLookupObject) lookupObject).getPsiElement(); final PsiElement psiElement = ((JetLookupObject) lookupObject).getPsiElement();
if (psiElement != null) { if (psiElement != null) {
return new LookupPositionObject(psiElement); return new LookupPositionObject(psiElement);
@@ -20,6 +20,7 @@ import com.intellij.psi.*;
import com.intellij.util.ProcessingContext; import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetArrayAccessExpression; 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.JetSimpleNameExpression;
import org.jetbrains.jet.lang.psi.JetThisReferenceExpression; 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), registrar.registerReferenceProvider(psiElement(JetThisReferenceExpression.class),
new PsiReferenceProvider() { new PsiReferenceProvider() {
@NotNull @NotNull
@@ -16,14 +16,11 @@
package org.jetbrains.jet.plugin.references; 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.openapi.util.TextRange;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException; import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.compiler.TipsManager; 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.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; 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.compiler.WholeProjectAnalyzerFacade;
import org.jetbrains.jet.plugin.completion.DescriptorLookupConverter; import org.jetbrains.jet.plugin.completion.DescriptorLookupConverter;
import java.util.List;
/** /**
* @author yole * @author yole
*/ */
@@ -63,7 +58,8 @@ public class JetSimpleNameReference extends JetPsiReference {
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile( BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(
(JetFile) myExpression.getContainingFile()); (JetFile) myExpression.getContainingFile());
return collectLookupElements(bindingContext, TipsManager.getReferenceVariants(myExpression, bindingContext)); return DescriptorLookupConverter.collectLookupElements(
bindingContext, TipsManager.getReferenceVariants(myExpression, bindingContext));
} }
@Override @Override
@@ -71,14 +67,4 @@ public class JetSimpleNameReference extends JetPsiReference {
PsiElement element = JetPsiFactory.createNameIdentifier(myExpression.getProject(), newElementName); PsiElement element = JetPsiFactory.createNameIdentifier(myExpression.getProject(), newElementName);
return myExpression.getReferencedNameElement().replace(element); return myExpression.getReferencedNameElement().replace(element);
} }
private static Object[] collectLookupElements(BindingContext bindingContext, Iterable<DeclarationDescriptor> descriptors) {
List<LookupElement> result = Lists.newArrayList();
for (final DeclarationDescriptor descriptor : descriptors) {
result.add(DescriptorLookupConverter.createLookupElement(bindingContext, descriptor));
}
return result.toArray();
}
} }
@@ -65,6 +65,14 @@ public class JetBasicCompletionTest extends JetCompletionTestBase {
doTest(); doTest();
} }
public void testInMiddleOfPackage() {
doTest();
}
public void testInPackage() {
doTest();
}
public void testJavaClassNames() { public void testJavaClassNames() {
doTest(); doTest();
} }
@@ -26,27 +26,24 @@ import java.io.File;
*/ */
public class CompletionMultifileHandlerTest extends CompletionTestCase { public class CompletionMultifileHandlerTest extends CompletionTestCase {
public void testTopLevelFunctionImport() { public void testTopLevelFunctionImport() throws Exception {
doTest(); doTest();
} }
public void testTopLevelFunctionInQualifiedExpr() { public void testTopLevelFunctionInQualifiedExpr() throws Exception {
doTest(); doTest();
} }
public void testNoParenthesisInImports() { public void testNoParenthesisInImports() throws Exception {
doTest(); doTest();
} }
public void doTest() { public void doTest() throws Exception {
String fileName = getTestName(false); String fileName = getTestName(false);
try {
configureByFiles(null, fileName + "-1.kt", fileName + "-2.kt"); configureByFiles(null, fileName + "-1.kt", fileName + "-2.kt");
complete(2); complete(2);
checkResultByFile(fileName + ".kt.after"); checkResultByFile(fileName + ".kt.after");
} catch (Exception e) {
throw new AssertionError(e);
}
} }
@Override @Override
@@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.