Add JetPackageClass annotation
This commit is contained in:
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
@@ -84,6 +85,10 @@ public class NamespaceCodegen extends MemberCodegen {
|
||||
public void generate(CompilationErrorHandler errorHandler) {
|
||||
boolean multiFile = CodegenBinding.isMultiFileNamespace(state.getBindingContext(), name);
|
||||
|
||||
if (shouldGenerateNSClass(files)) {
|
||||
v.getClassBuilder().newAnnotation(JvmStdlibNames.JET_PACKAGE_CLASS.getDescriptor(), true);
|
||||
}
|
||||
|
||||
for (JetFile file : files) {
|
||||
VirtualFile vFile = file.getVirtualFile();
|
||||
try {
|
||||
|
||||
+2
-1
@@ -46,7 +46,8 @@ public final class DescriptorResolverUtils {
|
||||
}
|
||||
|
||||
public static boolean isKotlinClass(@NotNull PsiClass psiClass) {
|
||||
return new PsiClassWrapper(psiClass).getJetClass().isDefined() || PackageClassUtils.isPackageClass(psiClass);
|
||||
PsiClassWrapper wrapper = new PsiClassWrapper(psiClass);
|
||||
return wrapper.getJetClass().isDefined() || wrapper.getJetPackageClass().isDefined();
|
||||
}
|
||||
|
||||
public static boolean isInnerEnum(@NotNull PsiClass innerClass, @Nullable DeclarationDescriptor owner) {
|
||||
|
||||
@@ -68,7 +68,9 @@ public class JvmStdlibNames {
|
||||
|
||||
|
||||
public static final JvmClassName JET_CLASS = JvmClassName.byFqNameWithoutInnerClasses("jet.runtime.typeinfo.JetClass");
|
||||
|
||||
|
||||
public static final JvmClassName JET_PACKAGE_CLASS = JvmClassName.byFqNameWithoutInnerClasses("jet.runtime.typeinfo.JetPackageClass");
|
||||
|
||||
public static final String JET_CLASS_SIGNATURE = "signature";
|
||||
|
||||
|
||||
|
||||
+2
-15
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetPackageClassAnnotation;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
@@ -38,21 +39,7 @@ public class PackageClassUtils {
|
||||
return packageFQN.child(Name.identifier(getPackageClassName(packageFQN)));
|
||||
}
|
||||
|
||||
public static boolean isPackageClass(@NotNull FqName fqName) {
|
||||
if (fqName.isRoot()) {
|
||||
return true;
|
||||
}
|
||||
return getPackageClassName(fqName.parent()).equals(fqName.shortName().getName());
|
||||
}
|
||||
|
||||
public static boolean isPackageClass(@NotNull PsiClass psiClass) {
|
||||
String qualifiedName = psiClass.getQualifiedName();
|
||||
if (qualifiedName == null) {
|
||||
return false;
|
||||
}
|
||||
if (DEFAULT_PACKAGE.equals(qualifiedName)) {
|
||||
return true;
|
||||
}
|
||||
return getPackageClassName(new FqName(qualifiedName).parent()).equals(psiClass.getName());
|
||||
return JetPackageClassAnnotation.get(psiClass).isDefined();
|
||||
}
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.lang.resolve.java.kt;
|
||||
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver;
|
||||
|
||||
public class JetPackageClassAnnotation extends PsiAnnotationWithFlags {
|
||||
private static final JetPackageClassAnnotation NULL_ANNOTATION = new JetPackageClassAnnotation(null);
|
||||
static {
|
||||
NULL_ANNOTATION.checkInitialized();
|
||||
}
|
||||
|
||||
private JetPackageClassAnnotation(@Nullable PsiAnnotation psiAnnotation) {
|
||||
super(psiAnnotation);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetPackageClassAnnotation get(PsiClass psiClass) {
|
||||
final PsiAnnotation annotation = JavaAnnotationResolver.findOwnAnnotation(psiClass,
|
||||
JvmStdlibNames.JET_PACKAGE_CLASS.getFqName().getFqName());
|
||||
return annotation != null ? new JetPackageClassAnnotation(annotation) : NULL_ANNOTATION;
|
||||
}
|
||||
}
|
||||
+11
-5
@@ -17,13 +17,9 @@
|
||||
package org.jetbrains.jet.lang.resolve.java.wrapper;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetPackageClassAnnotation;
|
||||
|
||||
public class PsiClassWrapper {
|
||||
|
||||
@@ -44,6 +40,8 @@ public class PsiClassWrapper {
|
||||
}
|
||||
|
||||
private JetClassAnnotation jetClass;
|
||||
private JetPackageClassAnnotation jetPackageClass;
|
||||
|
||||
@NotNull
|
||||
public JetClassAnnotation getJetClass() {
|
||||
if (jetClass == null) {
|
||||
@@ -51,4 +49,12 @@ public class PsiClassWrapper {
|
||||
}
|
||||
return jetClass;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetPackageClassAnnotation getJetPackageClass() {
|
||||
if (jetPackageClass == null) {
|
||||
jetPackageClass = JetPackageClassAnnotation.get(psiClass);
|
||||
}
|
||||
return jetPackageClass;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,36 +57,6 @@ public class PackageClassNameTest {
|
||||
doTest(FqName.ROOT.child(Name.identifier("kotlin")), "KotlinPackage", "_DefaultPackage");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPackageClass1() {
|
||||
doTestIsPackageClass("", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPackageClass2() {
|
||||
doTestIsPackageClass("kotlin", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPackageClass3() {
|
||||
doTestIsPackageClass("kotlin.KotlinPackage", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPackageClass4() {
|
||||
doTestIsPackageClass("kotlin.test.SomeClass", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPackageClass5() {
|
||||
doTestIsPackageClass("kotlin.io.IoPackage", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInnerIsPackage() {
|
||||
doTestIsPackageClass("kotlin.io.IoPackage$Foo", false);
|
||||
}
|
||||
|
||||
private void doTest(@NotNull String name, @NotNull String expectedForChild, @Nullable String expectedForParent) {
|
||||
doTest(new FqName(name), expectedForChild, expectedForParent);
|
||||
}
|
||||
@@ -97,8 +67,4 @@ public class PackageClassNameTest {
|
||||
assertEquals("Wrong result for parent [" + name + "].", expectedForParent, getPackageClassName(name.parent()));
|
||||
}
|
||||
}
|
||||
|
||||
private void doTestIsPackageClass(String testedName, boolean expected) {
|
||||
assertEquals("Wrong result for [" + testedName + "].", expected, isPackageClass(new FqName(testedName)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaMethodNameIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiShortNamesCache;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import jet.runtime.typeinfo.JetClass;
|
||||
import jet.runtime.typeinfo.JetPackageClass;
|
||||
import jet.runtime.typeinfo.JetValueParameter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -53,12 +53,12 @@ class JetFromJavaDescriptorHelper {
|
||||
/**
|
||||
* Get java equivalents for jet top level classes.
|
||||
*/
|
||||
static PsiClass[] getClassesForJetNamespaces(Project project, GlobalSearchScope scope) {
|
||||
static Collection<PsiClass> getClassesForJetNamespaces(Project project, GlobalSearchScope scope) {
|
||||
/* Will iterate through short name caches
|
||||
Kotlin namespaces from jar a class files will be collected from java cache
|
||||
Kotlin namespaces classes from sources will be collected with JetShortNamesCache.getClassesByName */
|
||||
// TODO Collect all package classes
|
||||
return PsiShortNamesCache.getInstance(project).getClassesByName("namespace", scope);
|
||||
|
||||
return getClassesByAnnotation(JetPackageClass.class.getSimpleName(), project, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,16 +81,11 @@ class JetFromJavaDescriptorHelper {
|
||||
static Collection<PsiClass> getCompiledClassesForTopLevelObjects(Project project, GlobalSearchScope scope) {
|
||||
Set<PsiClass> jetObjectClasses = Sets.newHashSet();
|
||||
|
||||
Collection<PsiAnnotation> annotations = JavaAnnotationIndex.getInstance().get(JetClass.class.getSimpleName(), project, scope);
|
||||
for (PsiAnnotation annotation : annotations) {
|
||||
PsiModifierList modifierList = (PsiModifierList) annotation.getParent();
|
||||
final PsiElement owner = modifierList.getParent();
|
||||
if (owner instanceof PsiClass) {
|
||||
PsiClass psiClass = (PsiClass) owner;
|
||||
JetClassAnnotation jetAnnotation = JetClassAnnotation.get(psiClass);
|
||||
if (psiClass.getContainingClass() == null && jetAnnotation.kind() == JvmStdlibNames.FLAG_CLASS_KIND_OBJECT) {
|
||||
jetObjectClasses.add(psiClass);
|
||||
}
|
||||
Collection<PsiClass> classesByAnnotation = getClassesByAnnotation(JetClass.class.getSimpleName(), project, scope);
|
||||
for (PsiClass psiClass : classesByAnnotation) {
|
||||
JetClassAnnotation jetAnnotation = JetClassAnnotation.get(psiClass);
|
||||
if (psiClass.getContainingClass() == null && jetAnnotation.kind() == JvmStdlibNames.FLAG_CLASS_KIND_OBJECT) {
|
||||
jetObjectClasses.add(psiClass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +156,7 @@ class JetFromJavaDescriptorHelper {
|
||||
|
||||
FqName classFQN = new FqName(qualifiedName);
|
||||
|
||||
if (PackageClassUtils.isPackageClass(classFQN)) {
|
||||
if (PackageClassUtils.isPackageClass(containingClass)) {
|
||||
FqName classParentFQN = QualifiedNamesUtil.withoutLastSegment(classFQN);
|
||||
return QualifiedNamesUtil.combine(classParentFQN, Name.identifier(method.getName()));
|
||||
}
|
||||
@@ -196,4 +191,19 @@ class JetFromJavaDescriptorHelper {
|
||||
|
||||
return selectedMethods;
|
||||
}
|
||||
|
||||
private static Collection<PsiClass> getClassesByAnnotation(
|
||||
String annotationName, Project project, GlobalSearchScope scope
|
||||
) {
|
||||
Collection<PsiClass> classes = Sets.newHashSet();
|
||||
Collection<PsiAnnotation> annotations = JavaAnnotationIndex.getInstance().get(annotationName, project, scope);
|
||||
for (PsiAnnotation annotation : annotations) {
|
||||
PsiModifierList modifierList = (PsiModifierList) annotation.getParent();
|
||||
final PsiElement owner = modifierList.getParent();
|
||||
if (owner instanceof PsiClass) {
|
||||
classes.add((PsiClass) owner);
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +230,7 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
return null;
|
||||
}
|
||||
|
||||
return combineClassFqNameWithMemberName(classFQN, field.getName());
|
||||
return combineClassFqNameWithMemberName(field.getContainingClass(), classFQN, field.getName());
|
||||
}
|
||||
|
||||
// TODO: Still problem with kotlin global properties imported from class files
|
||||
@@ -245,7 +245,7 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
return classFQN;
|
||||
}
|
||||
|
||||
return combineClassFqNameWithMemberName(classFQN, method.getName());
|
||||
return combineClassFqNameWithMemberName(method.getContainingClass(), classFQN, method.getName());
|
||||
}
|
||||
|
||||
if (element instanceof PsiPackage) {
|
||||
@@ -256,11 +256,11 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static FqName combineClassFqNameWithMemberName(FqName classFQN, String memberName) {
|
||||
private static FqName combineClassFqNameWithMemberName(PsiClass containingClass, FqName classFQN, String memberName) {
|
||||
if (memberName == null) {
|
||||
return null;
|
||||
}
|
||||
if (PackageClassUtils.isPackageClass(classFQN)) {
|
||||
if (PackageClassUtils.isPackageClass(containingClass)) {
|
||||
return QualifiedNamesUtil.combine(classFQN.parent(), Name.identifier(memberName));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.psi.impl.compiled.ClsFileImpl;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import jet.runtime.typeinfo.JetClass;
|
||||
import jet.runtime.typeinfo.JetMethod;
|
||||
import jet.runtime.typeinfo.JetPackageClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -43,6 +44,7 @@ import java.util.*;
|
||||
|
||||
public class DecompiledDataFactory {
|
||||
private static final String JET_CLASS = JetClass.class.getName();
|
||||
private static final String JET_PACKAGE_CLASS = JetPackageClass.class.getName();
|
||||
private static final String JET_METHOD = JetMethod.class.getName();
|
||||
private static final String DECOMPILED_COMMENT = "/* compiled code */";
|
||||
private static final DescriptorRenderer DESCRIPTOR_RENDERER =
|
||||
@@ -233,14 +235,7 @@ public class DecompiledDataFactory {
|
||||
}
|
||||
|
||||
public static boolean isKotlinNamespaceClass(@NotNull PsiClass psiClass) {
|
||||
if (PackageClassUtils.isPackageClass(psiClass) && !isKotlinClass(psiClass)) {
|
||||
for (PsiMethod method : psiClass.getMethods()) {
|
||||
if (hasAnnotation(method, JET_METHOD)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return hasAnnotation(psiClass, JET_PACKAGE_CLASS);
|
||||
}
|
||||
|
||||
public static boolean isCompiledFromKotlin(@NotNull PsiClass psiClass) {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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 jet.runtime.typeinfo;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* @url http://confluence.jetbrains.net/display/JET/Jet+Signatures
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface JetPackageClass {
|
||||
}
|
||||
Reference in New Issue
Block a user