Refactor: predefined annotation become represented as enum, all the logic reside in AnnotationUtils.

This commit is contained in:
pTalanov
2012-02-29 20:47:34 +04:00
parent adcffef920
commit 25c30e0472
4 changed files with 75 additions and 57 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.k2js.translate.context.generator.Generator;
import org.jetbrains.k2js.translate.context.generator.Rule;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
import org.jetbrains.k2js.translate.utils.PredefinedAnnotation;
import java.util.Map;
import java.util.Set;
@@ -216,15 +217,18 @@ public final class StaticContext {
}
};
Rule<JsName> namesAnnotatedAsLibraryHasUnobfuscatableNames = new Rule<JsName>() {
Rule<JsName> predefinedObjectsHasUnobfuscatableNames = new Rule<JsName>() {
@Override
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
if (!isLibraryObject(descriptor)) {
return null;
for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) {
if (!hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) {
continue;
}
String name = getNameForAnnotatedObject(descriptor, annotation);
name = (name != null) ? name : descriptor.getName();
return getEnclosingScope(descriptor).declareUnobfuscatableName(name);
}
String name = getNameForAnnotatedObject(descriptor, LIBRARY_ANNOTATION_FQNAME);
name = (name != null) ? name : descriptor.getName();
return getEnclosingScope(descriptor).declareUnobfuscatableName(name);
return null;
}
};
Rule<JsName> propertiesCorrespondToSpeciallyTreatedBackingFieldNames = new Rule<JsName>() {
@@ -254,17 +258,7 @@ public final class StaticContext {
}
};
Rule<JsName> namesForNativeObjectsAreUnobfuscatable = new Rule<JsName>() {
@Override
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
if (!isNativeObject(descriptor)) {
return null;
}
String name = getNameForAnnotatedObject(descriptor, NATIVE_ANNOTATION_FQNAME);
name = (name != null) ? name : descriptor.getName();
return getEnclosingScope(descriptor).declareUnobfuscatableName(name);
}
};
Rule<JsName> overridingDescriptorsReferToOriginalName = new Rule<JsName>() {
@Override
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
@@ -285,8 +279,7 @@ public final class StaticContext {
};
addRule(namesForStandardClasses);
addRule(constructorHasTheSameNameAsTheClass);
addRule(namesAnnotatedAsLibraryHasUnobfuscatableNames);
addRule(namesForNativeObjectsAreUnobfuscatable);
addRule(predefinedObjectsHasUnobfuscatableNames);
addRule(toStringHack);
addRule(propertiesCorrespondToSpeciallyTreatedBackingFieldNames);
addRule(namespacesShouldBeDefinedInRootScope);
@@ -413,27 +406,13 @@ public final class StaticContext {
@Override
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
if (getAnnotationByName(descriptor, AnnotationsUtils.LIBRARY_ANNOTATION_FQNAME) != null) {
return namer.kotlinObject();
}
return null;
}
};
Rule<JsNameRef> membersOfAnnotatedClassesHaveKotlinQualifier = new Rule<JsNameRef>() {
@Override
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
ClassDescriptor containingClass = getContainingClass(descriptor);
if (containingClass == null) {
return null;
}
if (getAnnotationByName(descriptor, LIBRARY_ANNOTATION_FQNAME) != null) {
if (isLibraryObject(descriptor)) {
return namer.kotlinObject();
}
return null;
}
};
addRule(libraryObjectsHaveKotlinQualifier);
addRule(membersOfAnnotatedClassesHaveKotlinQualifier);
addRule(constructorHaveTheSameQualifierAsTheClass);
addRule(namespacesHaveNoQualifiers);
addRule(namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier);
@@ -116,7 +116,7 @@ public final class Translation {
StaticContext staticContext = StaticContext.generateStaticContext(standardLibrary, bindingContext);
JsBlock block = staticContext.getProgram().getFragmentBlock(0);
TranslationContext context = TranslationContext.rootContext(staticContext);
block.getStatements().addAll(Translation.translateFiles(files, context));
block.getStatements().addAll(translateFiles(files, context));
JsNamer namer = new JsPrettyNamer();
namer.exec(context.program());
return context.program();
@@ -31,25 +31,18 @@ import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getContainingCl
*/
public final class AnnotationsUtils {
@NotNull
public static final String NATIVE_ANNOTATION_FQNAME = "js.native";
@NotNull
public static final String LIBRARY_ANNOTATION_FQNAME = "js.library";
private AnnotationsUtils() {
}
//TODO: make public, use when necessary
private static boolean hasAnnotation(@NotNull DeclarationDescriptor descriptor,
@NotNull String annotationFQNAme) {
return getAnnotationByName(descriptor, annotationFQNAme) != null;
@NotNull PredefinedAnnotation annotation) {
return getAnnotationByName(descriptor, annotation) != null;
}
@Nullable
public static String getAnnotationStringParameter(@NotNull DeclarationDescriptor declarationDescriptor,
@NotNull String annotationFQName) {
AnnotationDescriptor annotationDescriptor =
getAnnotationByName(declarationDescriptor, annotationFQName);
@NotNull PredefinedAnnotation annotation) {
AnnotationDescriptor annotationDescriptor = getAnnotationByName(declarationDescriptor, annotation);
assert annotationDescriptor != null;
//TODO: this is a quick fix for unsupported default args problem
if (annotationDescriptor.getValueArguments().isEmpty()) {
@@ -67,19 +60,19 @@ public final class AnnotationsUtils {
@Nullable
public static String getNameForAnnotatedObject(@NotNull DeclarationDescriptor declarationDescriptor,
@NotNull String annotationFQName) {
if (!hasAnnotation(declarationDescriptor, annotationFQName)) {
@NotNull PredefinedAnnotation annotation) {
if (!hasAnnotation(declarationDescriptor, annotation)) {
return null;
}
return getAnnotationStringParameter(declarationDescriptor, annotationFQName);
return getAnnotationStringParameter(declarationDescriptor, annotation);
}
@Nullable
public static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor,
@NotNull String FQName) {
@NotNull PredefinedAnnotation annotation) {
for (AnnotationDescriptor annotationDescriptor : descriptor.getAnnotations()) {
String annotationClassFQName = getAnnotationClassFQName(annotationDescriptor);
if (annotationClassFQName.equals(FQName)) {
if (annotationClassFQName.equals(annotation.getFQName())) {
return annotationDescriptor;
}
}
@@ -95,26 +88,31 @@ public final class AnnotationsUtils {
}
public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) {
return hasAnnotationOrInsideAnnotatedClass(descriptor, NATIVE_ANNOTATION_FQNAME);
return hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.NATIVE);
}
public static boolean isLibraryObject(@NotNull DeclarationDescriptor descriptor) {
return hasAnnotationOrInsideAnnotatedClass(descriptor, LIBRARY_ANNOTATION_FQNAME);
return hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.LIBRARY);
}
public static boolean isPredefinedObject(@NotNull DeclarationDescriptor descriptor) {
return isLibraryObject(descriptor) || isNativeObject(descriptor);
for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) {
if (hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) {
return true;
}
}
return false;
}
public static boolean hasAnnotationOrInsideAnnotatedClass(@NotNull DeclarationDescriptor descriptor,
@NotNull String annotationFQName) {
if (getAnnotationByName(descriptor, annotationFQName) != null) {
@NotNull PredefinedAnnotation annotation) {
if (getAnnotationByName(descriptor, annotation) != null) {
return true;
}
ClassDescriptor containingClass = getContainingClass(descriptor);
if (containingClass == null) {
return false;
}
return (getAnnotationByName(containingClass, annotationFQName) != null);
return (getAnnotationByName(containingClass, annotation) != null);
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2012 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.k2js.translate.utils;
import org.jetbrains.annotations.NotNull;
/**
* @author Pavel Talanov
*/
public enum PredefinedAnnotation {
LIBRARY("js.library"),
NATIVE("js.native");
PredefinedAnnotation(@NotNull String fqName) {
this.fqName = fqName;
}
@NotNull
private String fqName;
@NotNull
public String getFQName() {
return fqName;
}
}