diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 8625a031ae1..da115c70986 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -13,13 +13,9 @@ - - - - - - + + @@ -147,8 +143,10 @@ - - + + + + @@ -156,8 +154,10 @@ - - + + + + @@ -174,7 +174,7 @@ - + @@ -214,7 +214,7 @@ - + @@ -352,8 +352,8 @@ @@ -1191,7 +1191,7 @@ - + @@ -1238,7 +1238,7 @@ @@ -1329,7 +1329,7 @@ - + @@ -1382,23 +1382,27 @@ - + - - + + + + - + - - + + + + - + diff --git a/translator/src/org/jetbrains/k2js/translate/context/declaration/JsAnnotationsUtils.java b/translator/src/org/jetbrains/k2js/translate/context/declaration/JsAnnotationsUtils.java index edac3595ed6..8e5f8dbf6f4 100644 --- a/translator/src/org/jetbrains/k2js/translate/context/declaration/JsAnnotationsUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/context/declaration/JsAnnotationsUtils.java @@ -1,5 +1,13 @@ package org.jetbrains.k2js.translate.context.declaration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; + /** * @author Pavel Talanov */ @@ -8,5 +16,66 @@ public final class JsAnnotationsUtils { private JsAnnotationsUtils() { } + @NotNull + public static String getNativeName(@NotNull FunctionDescriptor descriptor) { + if (hasNativeFunctionAnnotation(descriptor)) { + return getNativeFunctionName(descriptor); + } + if (declaredInNativeClass(descriptor)) { + return descriptor.getName(); + } + throw new AssertionError("Use isNativeFunction to check"); + } + public static boolean isNativeFunction(@NotNull FunctionDescriptor functionDescriptor) { + return hasNativeFunctionAnnotation(functionDescriptor) || declaredInNativeClass(functionDescriptor); + } + + public static boolean isNativeClass(@NotNull ClassDescriptor classDescriptor) { + return hasNativeClassAnnotation(classDescriptor); + } + + private static boolean declaredInNativeClass(@NotNull DeclarationDescriptor descriptor) { + DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); + if (!(containingDeclaration instanceof ClassDescriptor)) return false; + return hasNativeClassAnnotation((ClassDescriptor) containingDeclaration); + } + + private static boolean hasNativeFunctionAnnotation(@NotNull FunctionDescriptor annotationDescriptor) { + return (getAnnotationByName(annotationDescriptor, "js.annotations.JavascriptNativeFunction") != null); + } + + private static boolean hasNativeClassAnnotation(@NotNull ClassDescriptor descriptor) { + return (getAnnotationByName(descriptor, "JavascriptNativeClass") != null); + } + + @NotNull + private static String getNativeFunctionName(@NotNull DeclarationDescriptor declarationDescriptor) { + AnnotationDescriptor annotationDescriptor = + getAnnotationByName(declarationDescriptor, "js.annotations.JavascriptNativeFunction"); + assert annotationDescriptor != null; + Object value = annotationDescriptor.getValueArguments().iterator().next().getValue(); + assert value instanceof String : "Native function annotation should have one String parameter"; + return (String) value; + } + + @Nullable + private static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor, + @NotNull String FQName) { + for (AnnotationDescriptor annotationDescriptor : descriptor.getAnnotations()) { + String annotationClassFQName = getAnnotationClassFQName(annotationDescriptor); + if (annotationClassFQName.equals(FQName)) { + return annotationDescriptor; + } + } + return null; + } + + @NotNull + private static String getAnnotationClassFQName(@NotNull AnnotationDescriptor annotationDescriptor) { + DeclarationDescriptor annotationDeclaration = + annotationDescriptor.getType().getConstructor().getDeclarationDescriptor(); + assert annotationDeclaration != null : "Annotation supposed to have a declaration"; + return DescriptorUtils.getFQName(annotationDeclaration); + } } diff --git a/translator/src/org/jetbrains/k2js/translate/context/declaration/NativeDeclarationVisitor.java b/translator/src/org/jetbrains/k2js/translate/context/declaration/NativeDeclarationVisitor.java index 451128d2c22..b9d9d003491 100644 --- a/translator/src/org/jetbrains/k2js/translate/context/declaration/NativeDeclarationVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/context/declaration/NativeDeclarationVisitor.java @@ -2,12 +2,10 @@ package org.jetbrains.k2js.translate.context.declaration; import com.google.dart.compiler.backend.js.ast.JsName; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; -import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.k2js.translate.context.NamingScope; /** @@ -32,11 +30,7 @@ public final class NativeDeclarationVisitor extends AbstractDeclarationVisitor { @Override protected JsName doDeclareName(@NotNull DeclarationDescriptor descriptor, @NotNull DeclarationContext context, @NotNull String recommendedName) { - if (!(descriptor instanceof FunctionDescriptor)) { - throw new IllegalStateException(); - } - String nativeName = getNativeName((FunctionDescriptor) descriptor); - assert nativeName != null; + String nativeName = JsAnnotationsUtils.getNativeName((FunctionDescriptor) descriptor); JsName jsName = context.getScope(). declareVariable(descriptor, nativeName, false); jsName.setObfuscatable(false); @@ -47,56 +41,17 @@ public final class NativeDeclarationVisitor extends AbstractDeclarationVisitor { @Override protected boolean accept(@NotNull DeclarationDescriptor descriptor) { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - @Nullable - private String getNativeName(@NotNull FunctionDescriptor descriptor) { - if (isJavascriptNativeFunction(descriptor)) { - return getNativeFunctionName(descriptor); + if (descriptor instanceof NamespaceDescriptor) { + return true; } - if (isJavascriptNativeClass(descriptor.getContainingDeclaration())) { - return descriptor.getName(); + if (descriptor instanceof FunctionDescriptor) { + return JsAnnotationsUtils.isNativeFunction((FunctionDescriptor) descriptor); } - return null; - } - - private boolean isJavascriptNativeFunction(@NotNull DeclarationDescriptor annotationDescriptor) { - return (getAnnotationByName(annotationDescriptor, "js.annotations.JavascriptNativeFunction") != null); - } - - private boolean isJavascriptNativeClass(@NotNull DeclarationDescriptor descriptor) { - assert descriptor instanceof ClassDescriptor; - return (getAnnotationByName(descriptor, "JavascriptNativeClass") != null); - } - - @NotNull - private String getNativeFunctionName(@NotNull DeclarationDescriptor declarationDescriptor) { - AnnotationDescriptor annotationDescriptor = - getAnnotationByName(declarationDescriptor, "js.annotations.JavascriptNativeFunction"); - assert annotationDescriptor != null; - Object value = annotationDescriptor.getValueArguments().iterator().next().getValue(); - assert value instanceof String : "Native function annotation should have one String parameter"; - return (String) value; - } - - @Nullable - private AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor, - @NotNull String FQName) { - for (AnnotationDescriptor annotationDescriptor : descriptor.getAnnotations()) { - String annotationClassFQName = getAnnotationClassFQName(annotationDescriptor); - if (annotationClassFQName.equals(FQName)) { - return annotationDescriptor; - } + if (descriptor instanceof ClassDescriptor) { + return JsAnnotationsUtils.isNativeClass((ClassDescriptor) descriptor); } - return null; + throw new AssertionError(); } - @NotNull - private String getAnnotationClassFQName(@NotNull AnnotationDescriptor annotationDescriptor) { - DeclarationDescriptor annotationDeclaration = - annotationDescriptor.getType().getConstructor().getDeclarationDescriptor(); - assert annotationDeclaration != null : "Annotation supposed to have a declaration"; - return DescriptorUtils.getFQName(annotationDeclaration); - } + }