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 7abcb968dac..bab37c421fb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -17,12 +17,14 @@ package org.jetbrains.jet.lang.psi; import com.google.common.base.Function; +import com.google.common.collect.Lists; import com.intellij.lang.ASTNode; 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 com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; @@ -207,6 +209,23 @@ public class JetPsiUtil { return firstPart.child(name); } + /** @return null iff the tye has syntactic errors */ + @Nullable + public static FqName toQualifiedName(@NotNull JetUserType userType) { + List reversedNames = Lists.newArrayList(); + + JetUserType current = userType; + while (current != null) { + String name = current.getReferencedName(); + if (name == null) return null; + + reversedNames.add(name); + current = current.getQualifier(); + } + + return FqName.fromSegments(ContainerUtil.reverse(reversedNames)); + } + @Nullable public static Name getShortName(JetAnnotationEntry annotation) { JetTypeReference typeReference = annotation.getTypeReference(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/FqName.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/FqName.java index 4fc5b1bae9c..135708bea66 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/FqName.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/FqName.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve.name; import com.google.common.collect.Lists; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,6 +25,12 @@ import java.util.List; public class FqName extends FqNameBase { + @NotNull + public static FqName fromSegments(@NotNull List names) { + String fqName = StringUtil.join(names, "."); + return new FqName(fqName); + } + public static final FqName ROOT = new FqName(""); @NotNull @@ -32,7 +39,6 @@ public class FqName extends FqNameBase { // cache private transient FqName parent; - public FqName(@NotNull String fqName) { this.fqName = new FqNameUnsafe(fqName, this); diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java index e4377bb59cf..0c5a71f1086 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java @@ -345,15 +345,13 @@ public class KotlinLightClassForExplicitDeclaration extends AbstractLightClass i if (typeReference == null) continue; JetTypeElement typeElement = typeReference.getTypeElement(); - if (typeElement == null) continue; + if (!(typeElement instanceof JetUserType)) continue; // If it's not a user type, it's definitely not a ref to deprecated - // typeElement.getText() is either - // simple name => we just compare it to "deprecated" - // qualified name => we compare to FqName, there may be spaces, comments etc, we do not support these cases - // function type, etc => comparisons below fail - String text = typeElement.getText(); - if (deprecatedFqName.getFqName().equals(text)) return true; - if (deprecatedName.equals(text)) return true; + FqName fqName = JetPsiUtil.toQualifiedName((JetUserType) typeElement); + if (fqName == null) continue; + + if (deprecatedFqName.equals(fqName.toUnsafe())) return true; + if (deprecatedName.equals(fqName.getFqName())) return true; } return false; } diff --git a/compiler/testData/asJava/lightClasses/Declared.kt b/compiler/testData/asJava/lightClasses/Declared.kt index d7466bd7477..4b244304c5d 100644 --- a/compiler/testData/asJava/lightClasses/Declared.kt +++ b/compiler/testData/asJava/lightClasses/Declared.kt @@ -28,8 +28,11 @@ trait Trait // Deprecation deprecated("") class Deprecated jet.deprecated("") class DeprecatedFQN +jet. deprecated /**/ ("") class DeprecatedFQNSpaces [deprecated("")] class DeprecatedWithBrackets [jet.deprecated("")] class DeprecatedWithBracketsFQN +[jet +./**/deprecated ("")] class DeprecatedWithBracketsFQNSpaces // Generic class Generic1 diff --git a/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassCoherenceTest.java b/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassCoherenceTest.java index 6ecad1f476c..7124b97c987 100644 --- a/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassCoherenceTest.java +++ b/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassCoherenceTest.java @@ -184,7 +184,23 @@ public class KotlinLightClassCoherenceTest extends KotlinAsJavaTestBase { doTest(); } + public void testDeprecatedFQN() throws Exception { + doTest(); + } + + public void testDeprecatedFQNSpaces() throws Exception { + doTest(); + } + public void testDeprecatedWithBrackets() throws Exception { doTest(); } + + public void testDeprecatedWithBracketsFQN() throws Exception { + doTest(); + } + + public void testDeprecatedWithBracketsFQNSpaces() throws Exception { + doTest(); + } } diff --git a/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassTest.java b/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassTest.java index cf87fc02005..3bda2cf09a1 100644 --- a/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassTest.java +++ b/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassTest.java @@ -88,8 +88,10 @@ public abstract class KotlinLightClassTest extends KotlinAsJavaTestBase { public void testDeprecation() { checkModifiers("test.Deprecated", PUBLIC, FINAL, DEPRECATED); checkModifiers("test.DeprecatedFQN", PUBLIC, FINAL, DEPRECATED); + checkModifiers("test.DeprecatedFQNSpaces", PUBLIC, FINAL, DEPRECATED); checkModifiers("test.DeprecatedWithBrackets", PUBLIC, FINAL, DEPRECATED); checkModifiers("test.DeprecatedWithBracketsFQN", PUBLIC, FINAL, DEPRECATED); + checkModifiers("test.DeprecatedWithBracketsFQNSpaces", PUBLIC, FINAL, DEPRECATED); } public void testGenericity() {