diff --git a/translator/src/org/jetbrains/k2js/translate/context/StaticContext.java b/translator/src/org/jetbrains/k2js/translate/context/StaticContext.java index 7d2d8fea65f..ac11e010cf2 100644 --- a/translator/src/org/jetbrains/k2js/translate/context/StaticContext.java +++ b/translator/src/org/jetbrains/k2js/translate/context/StaticContext.java @@ -180,14 +180,14 @@ public class StaticContext { } }; - Rule namesAnnotatedAsStandard = new Rule() { + Rule namesAnnotatedAsLibraryHasUnobfuscatableNames = new Rule() { @Override public JsName apply(@NotNull DeclarationDescriptor descriptor) { //TODO: refactor String name = null; AnnotationDescriptor annotation = getAnnotationByName(descriptor, LIBRARY_FUNCTION_ANNOTATION_FQNAME); if (annotation != null) { - name = AnnotationsUtils.annotationStringParameter(descriptor, LIBRARY_FUNCTION_ANNOTATION_FQNAME); + name = AnnotationsUtils.getAnnotationStringParameter(descriptor, LIBRARY_FUNCTION_ANNOTATION_FQNAME); name = (!name.isEmpty()) ? name : descriptor.getName(); } else { ClassDescriptor containingClass = getContainingClass(descriptor); @@ -229,20 +229,43 @@ public class StaticContext { } }; + Rule namesForNativeObjectsAreUnobfuscatable = new Rule() { + @Override + public JsName apply(@NotNull DeclarationDescriptor descriptor) { + String name = null; + AnnotationDescriptor annotation = getAnnotationByName(descriptor, NATIVE_ANNOTATION_FQNAME); + if (annotation != null) { + name = AnnotationsUtils.getAnnotationStringParameter(descriptor, NATIVE_ANNOTATION_FQNAME); + name = (!name.isEmpty()) ? name : descriptor.getName(); + } else { + ClassDescriptor containingClass = getContainingClass(descriptor); + if (containingClass == null) return null; + if (getAnnotationByName(containingClass, NATIVE_ANNOTATION_FQNAME) != null) { + name = descriptor.getName(); + } + } + if (name != null) { + return getEnclosingScope(descriptor).declareUnobfuscatableName(name); + } + return null; + + } + }; Generator nameGenerator = new Generator(); nameGenerator.addRule(namesForStandardClasses); nameGenerator.addRule(aliasOverridesNames); + nameGenerator.addRule(constructorHasTheSameNameAsTheClass); + nameGenerator.addRule(namesAnnotatedAsLibraryHasUnobfuscatableNames); + nameGenerator.addRule(namesForNativeObjectsAreUnobfuscatable); nameGenerator.addRule(toStringHack); nameGenerator.addRule(propertiesCorrespondToSpeciallyTreatedBackingFieldNames); - nameGenerator.addRule(constructorHasTheSameNameAsTheClass); - nameGenerator.addRule(namesAnnotatedAsStandard); nameGenerator.addRule(namespacesShouldBeDefinedInRootScope); nameGenerator.addRule(accessorsHasNamesWithSpecialPrefixes); nameGenerator.addRule(memberDeclarationsInsideParentsScope); return nameGenerator; } - private NamingScope getEnclosingScope(DeclarationDescriptor descriptor) { + private NamingScope getEnclosingScope(@NotNull DeclarationDescriptor descriptor) { DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor); return getScopeForDescriptor(containingDeclaration.getOriginal()); } @@ -275,7 +298,6 @@ public class StaticContext { @NotNull private Generator qualifierGenerator() { - Generator qualifierGenerator = new Generator(); Rule namespacesHaveNoQualifiers = new Rule() { @Override public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) { @@ -307,7 +329,7 @@ public class StaticContext { return getQualifierForDescriptor(containingClass); } }; - Rule annotatedObjectsHaveKotlinQualifier = new Rule() { + Rule libraryObjectsHaveKotlinQualifier = new Rule() { //TODO: refactor by removing one annotation @Override @@ -334,7 +356,8 @@ public class StaticContext { return null; } }; - qualifierGenerator.addRule(annotatedObjectsHaveKotlinQualifier); + Generator qualifierGenerator = new Generator(); + qualifierGenerator.addRule(libraryObjectsHaveKotlinQualifier); qualifierGenerator.addRule(membersOfAnnotatedClassesHaveKotlinQualifier); qualifierGenerator.addRule(constructorHaveTheSameQualifierAsTheClass); qualifierGenerator.addRule(namespacesHaveNoQualifiers); @@ -352,6 +375,11 @@ public class StaticContext { @Nullable public JsNameRef getQualifierForDescriptor(@NotNull DeclarationDescriptor descriptor) { + //TODO: hack! + if (AnnotationsUtils.isNativeObject(descriptor)) { + return null; + } + return qualifiers.get(descriptor.getOriginal()); } diff --git a/translator/src/org/jetbrains/k2js/translate/context/declaration/AnnotationsUtils.java b/translator/src/org/jetbrains/k2js/translate/context/declaration/AnnotationsUtils.java index 38dddb854f9..8f96026c1ba 100644 --- a/translator/src/org/jetbrains/k2js/translate/context/declaration/AnnotationsUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/context/declaration/AnnotationsUtils.java @@ -2,11 +2,14 @@ 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.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; +import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getContainingClass; + /** * @author Pavel Talanov */ @@ -28,8 +31,8 @@ public final class AnnotationsUtils { } @NotNull - public static String annotationStringParameter(@NotNull DeclarationDescriptor declarationDescriptor, - @NotNull String annotationFQName) { + public static String getAnnotationStringParameter(@NotNull DeclarationDescriptor declarationDescriptor, + @NotNull String annotationFQName) { AnnotationDescriptor annotationDescriptor = getAnnotationByName(declarationDescriptor, annotationFQName); assert annotationDescriptor != null; @@ -66,4 +69,15 @@ public final class AnnotationsUtils { assert annotationDeclaration != null : "Annotation supposed to have a declaration"; return DescriptorUtils.getFQName(annotationDeclaration); } + + public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) { + if (getAnnotationByName(descriptor, NATIVE_ANNOTATION_FQNAME) != null) { + return true; + } + ClassDescriptor containingClass = getContainingClass(descriptor); + if (containingClass == null) { + return false; + } + return (getAnnotationByName(containingClass, NATIVE_ANNOTATION_FQNAME) != null); + } } diff --git a/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java index cc9503b0651..04ec7932c06 100644 --- a/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java @@ -10,9 +10,8 @@ import org.jetbrains.jet.lang.psi.JetQualifiedExpression; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.k2js.translate.context.TranslationContext; -import org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils; -import static org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils.getAnnotationByName; +import static org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils.isNativeObject; import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall; import static org.jetbrains.k2js.translate.utils.PsiUtils.getSelectorAsSimpleName; @@ -27,7 +26,7 @@ public abstract class PropertyAccessTranslator extends AccessTranslator { public static PropertyAccessTranslator newInstance(@NotNull PropertyDescriptor descriptor, @NotNull ResolvedCall resolvedCall, @NotNull TranslationContext context) { - if (isNativeProperty(descriptor, context)) { + if (isNativeObject(descriptor)) { return new NativePropertyAccessTranslator(descriptor, /*qualifier = */ null, context); } else { return new KotlinPropertyAccessTranslator(descriptor, /*qualifier = */ null, /*backingFieldAccess = */ false, @@ -40,7 +39,7 @@ public abstract class PropertyAccessTranslator extends AccessTranslator { @Nullable JsExpression qualifier, @NotNull TranslationContext context) { PropertyDescriptor propertyDescriptor = getPropertyDescriptor(expression, context); - if (isNativeProperty(propertyDescriptor, context)) { + if (isNativeObject(propertyDescriptor)) { return new NativePropertyAccessTranslator(propertyDescriptor, qualifier, context); } ResolvedCall resolvedCall = getResolvedCall(context.bindingContext(), expression); @@ -109,11 +108,6 @@ public abstract class PropertyAccessTranslator extends AccessTranslator { return canBePropertyGetterCall(expression, context); } - private static boolean isNativeProperty(@NotNull PropertyDescriptor propertyDescriptor, - @NotNull TranslationContext context) { - return getAnnotationByName(propertyDescriptor, AnnotationsUtils.NATIVE_ANNOTATION_FQNAME) != null; - } - protected PropertyAccessTranslator(@NotNull TranslationContext context) { super(context); }