From d4564a41e3c4014204173024ba2c5630cf45bb8a Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 4 Sep 2012 22:56:12 +0400 Subject: [PATCH] EA-38865 Fail for convention functions names --- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 21 +++++++++++++++++++ .../jetbrains/jet/lang/resolve/name/Name.java | 2 +- .../jet/plugin/caches/JetShortNamesCache.java | 15 ++++++++----- .../checker/NotFinishedGenericDeclaration.jet | 5 +++++ .../checkers/JetPsiCheckerTestGenerated.java | 13 +++++++----- 5 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 idea/testData/checker/NotFinishedGenericDeclaration.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 235b25501af..448ff6334c1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -21,13 +21,16 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.impl.CheckUtil; import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; +import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetTokens; import java.util.Collection; @@ -353,6 +356,24 @@ public class JetPsiUtil { return !(multiDeclarationEntry.getParent().getParent() instanceof JetForExpression); } + @Nullable + public static Name getConventionName(@NotNull JetSimpleNameExpression simpleNameExpression) { + if (simpleNameExpression.getIdentifier() != null) { + return simpleNameExpression.getReferencedNameAsName(); + } + + PsiElement firstChild = simpleNameExpression.getFirstChild(); + if (firstChild != null) { + IElementType elementType = firstChild.getNode().getElementType(); + if (elementType instanceof JetToken) { + JetToken jetToken = (JetToken) elementType; + return OperatorConventions.getNameForOperationSymbol(jetToken); + } + } + + return null; + } + public static PsiElement getTopmostParentOfTypes(@Nullable PsiElement element, @NotNull Class... parentTypes) { if (element == null) { return null; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/Name.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/Name.java index 795ce1bbe0e..2bc2bd77b69 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/Name.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/Name.java @@ -26,7 +26,7 @@ public class Name implements Comparable { private final String name; private final boolean special; - private Name(String name, boolean special) { + private Name(@NotNull String name, boolean special) { this.name = name; this.special = special; } diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 62c4d9d48d6..16c7211c65c 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -156,16 +156,23 @@ public class JetShortNamesCache extends PsiShortNamesCache { @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 || name.isEmpty()) { + if (jetScope == null) { return Collections.emptyList(); } Set result = Sets.newHashSet(); - Collection topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName(name, project, scope); + Collection topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName( + referenceName.getName(), project, scope); for (PsiMethod method : topLevelFunctionPrototypes) { FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method); if (functionFQN != null) { @@ -181,7 +188,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { } Set affectedPackages = Sets.newHashSet(); - Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope); + Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(referenceName.getName(), project, scope); for (JetNamedFunction jetNamedFunction : jetNamedFunctions) { PsiFile containingFile = jetNamedFunction.getContainingFile(); if (containingFile instanceof JetFile) { @@ -193,8 +200,6 @@ public class JetShortNamesCache extends PsiShortNamesCache { } } - Name referenceName = Name.identifier(name); - for (FqName affectedPackage : affectedPackages) { NamespaceDescriptor packageDescriptor = resolveSession.getPackageDescriptorByFqName(affectedPackage); assert packageDescriptor != null : "There's a function in stub index with invalid package"; diff --git a/idea/testData/checker/NotFinishedGenericDeclaration.jet b/idea/testData/checker/NotFinishedGenericDeclaration.jet new file mode 100644 index 00000000000..f07b7e2e624 --- /dev/null +++ b/idea/testData/checker/NotFinishedGenericDeclaration.jet @@ -0,0 +1,5 @@ +class Test + +val localTest1 = Test() - 12 +val localTest2 = Test() > 12 +val localTest3 = Test() < 12 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java b/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java index 0eb93dd4112..e21e498fc3f 100644 --- a/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java @@ -15,15 +15,12 @@ */ package org.jetbrains.jet.checkers; -import junit.framework.Assert; import junit.framework.Test; import junit.framework.TestSuite; - -import java.io.File; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.test.TestMetadata; -import org.jetbrains.jet.checkers.AbstractJetPsiCheckerTest; +import java.io.File; /** This class is generated by {@link org.jetbrains.jet.checkers.AbstractJetPsiCheckerTest}. DO NOT MODIFY MANUALLY */ public class JetPsiCheckerTestGenerated extends AbstractJetPsiCheckerTest { @@ -35,7 +32,8 @@ public class JetPsiCheckerTestGenerated extends AbstractJetPsiCheckerTest { } public void testAllFilesPresentInChecker() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.checkers.AbstractJetPsiCheckerTest", new File("idea/testData/checker"), "jet", false); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.checkers.AbstractJetPsiCheckerTest", + new File("idea/testData/checker"), "jet", false); } @TestMetadata("AnonymousInitializers.jet") @@ -153,6 +151,11 @@ public class JetPsiCheckerTestGenerated extends AbstractJetPsiCheckerTest { doTest("idea/testData/checker/NestedObjects.jet"); } + @TestMetadata("NotFinishedGenericDeclaration.jet") + public void testNotFinishedGenericDeclaration() throws Exception { + doTest("idea/testData/checker/NotFinishedGenericDeclaration.jet"); + } + @TestMetadata("Nullability.jet") public void testNullability() throws Exception { doTest("idea/testData/checker/Nullability.jet");