moved lazy generators to static context (2 test fail)
This commit is contained in:
@@ -1,12 +1,23 @@
|
|||||||
package org.jetbrains.k2js.translate.context;
|
package org.jetbrains.k2js.translate.context;
|
||||||
|
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsName;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsProgram;
|
import com.google.dart.compiler.backend.js.ast.JsProgram;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsRootScope;
|
import com.google.dart.compiler.backend.js.ast.JsRootScope;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||||
|
import org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils;
|
||||||
|
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.intrinsic.Intrinsics;
|
||||||
|
|
||||||
|
import static org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils.*;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
|
||||||
|
|
||||||
public class StaticContext {
|
public class StaticContext {
|
||||||
|
|
||||||
public static StaticContext generateStaticContext(@NotNull JetStandardLibrary library,
|
public static StaticContext generateStaticContext(@NotNull JetStandardLibrary library,
|
||||||
@@ -44,6 +55,13 @@ public class StaticContext {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final NamingScope rootScope;
|
private final NamingScope rootScope;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final Generator<JsName> names = nameGenerator();
|
||||||
|
@NotNull
|
||||||
|
private final Generator<NamingScope> scopes = scopeGenerator();
|
||||||
|
@NotNull
|
||||||
|
private final Generator<JsNameRef> qualifiers = qualifierGenerator();
|
||||||
|
|
||||||
|
|
||||||
//TODO: too many parameters in constructor
|
//TODO: too many parameters in constructor
|
||||||
private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
|
private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
|
||||||
@@ -93,4 +111,226 @@ public class StaticContext {
|
|||||||
public StandardClasses getStandardClasses() {
|
public StandardClasses getStandardClasses() {
|
||||||
return standardClasses;
|
return standardClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Generator<JsName> nameGenerator() {
|
||||||
|
|
||||||
|
Rule<JsName> aliasOverridesNames = new Rule<JsName>() {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public JsName apply(@NotNull DeclarationDescriptor data) {
|
||||||
|
if (aliaser.hasAliasForDeclaration(data)) {
|
||||||
|
return aliaser.getAliasForDeclaration(data);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Rule<JsName> namesForStandardClasses = new Rule<JsName>() {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public JsName apply(@NotNull DeclarationDescriptor data) {
|
||||||
|
if (!standardClasses.isStandardObject(data)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return standardClasses.getStandardObjectName(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Rule<JsName> namespacesShouldBeDefinedInRootScope = new Rule<JsName>() {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (!(descriptor instanceof NamespaceDescriptor)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String nameForNamespace = getNameForNamespace((NamespaceDescriptor) descriptor);
|
||||||
|
return getRootScope().declareUnobfuscatableName(nameForNamespace);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Rule<JsName> memberDeclarationsInsideParentsScope = new Rule<JsName>() {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
NamingScope namingScope = getEnclosingScope(descriptor);
|
||||||
|
return namingScope.declareObfuscatableName(descriptor.getName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Rule<JsName> constructorHasTheSameNameAsTheClass = new Rule<JsName>() {
|
||||||
|
@Override
|
||||||
|
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (!(descriptor instanceof ConstructorDescriptor)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||||
|
assert containingClass != null : "Can't have constructor without a class";
|
||||||
|
return getNameForDescriptor(containingClass);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Rule<JsName> accessorsHasNamesWithSpecialPrefixes = new Rule<JsName>() {
|
||||||
|
@Override
|
||||||
|
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (!(descriptor instanceof PropertyAccessorDescriptor)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean isGetter = descriptor instanceof PropertyGetterDescriptor;
|
||||||
|
String propertyName = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty().getName();
|
||||||
|
String accessorName = Namer.getNameForAccessor(propertyName, isGetter);
|
||||||
|
NamingScope enclosingScope = getEnclosingScope(descriptor);
|
||||||
|
return enclosingScope.declareObfuscatableName(accessorName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Rule<JsName> namesAnnotatedAsStandard = new Rule<JsName>() {
|
||||||
|
@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 = (!name.isEmpty()) ? name : descriptor.getName();
|
||||||
|
} else {
|
||||||
|
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||||
|
if (containingClass == null) return null;
|
||||||
|
if (getAnnotationByName(containingClass, LIBRARY_CLASS_ANNOTATION_FQNAME) != null) {
|
||||||
|
name = descriptor.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name != null) {
|
||||||
|
return getEnclosingScope(descriptor).declareUnobfuscatableName(name);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Generator<JsName> nameGenerator = new Generator<JsName>();
|
||||||
|
nameGenerator.addRule(namesForStandardClasses);
|
||||||
|
nameGenerator.addRule(aliasOverridesNames);
|
||||||
|
nameGenerator.addRule(constructorHasTheSameNameAsTheClass);
|
||||||
|
nameGenerator.addRule(namesAnnotatedAsStandard);
|
||||||
|
nameGenerator.addRule(namespacesShouldBeDefinedInRootScope);
|
||||||
|
nameGenerator.addRule(accessorsHasNamesWithSpecialPrefixes);
|
||||||
|
nameGenerator.addRule(memberDeclarationsInsideParentsScope);
|
||||||
|
return nameGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NamingScope getEnclosingScope(DeclarationDescriptor descriptor) {
|
||||||
|
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
|
||||||
|
return getScopeForDescriptor(containingDeclaration.getOriginal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Generator<NamingScope> scopeGenerator() {
|
||||||
|
Generator<NamingScope> scopeGenerator = new Generator<NamingScope>();
|
||||||
|
Rule<NamingScope> generateNewScopesForNamespaceDescriptors = new Rule<NamingScope>() {
|
||||||
|
@Override
|
||||||
|
public NamingScope apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (!(descriptor instanceof NamespaceDescriptor)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getRootScope().innerScope("Namespace " + descriptor.getName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Rule<NamingScope> generateInnerScopesForMembers = new Rule<NamingScope>() {
|
||||||
|
@Override
|
||||||
|
public NamingScope apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
NamingScope enclosingScope = getEnclosingScope(descriptor);
|
||||||
|
return enclosingScope.innerScope("scope for member " + descriptor.getName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
scopeGenerator.addRule(generateNewScopesForNamespaceDescriptors);
|
||||||
|
scopeGenerator.addRule(generateInnerScopesForMembers);
|
||||||
|
|
||||||
|
return scopeGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Generator<JsNameRef> qualifierGenerator() {
|
||||||
|
Generator<JsNameRef> qualifierGenerator = new Generator<JsNameRef>();
|
||||||
|
Rule<JsNameRef> namespacesHaveNoQualifiers = new Rule<JsNameRef>() {
|
||||||
|
@Override
|
||||||
|
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (!standardClasses.isStandardObject(descriptor)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return namer.kotlinObject();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Rule<JsNameRef> namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier = new Rule<JsNameRef>() {
|
||||||
|
@Override
|
||||||
|
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
|
||||||
|
if (!(containingDeclaration instanceof NamespaceDescriptor)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JsName containingDeclarationName = getNameForDescriptor(containingDeclaration);
|
||||||
|
return containingDeclarationName.makeRef();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Rule<JsNameRef> constructorHaveTheSameQualifierAsTheClass = new Rule<JsNameRef>() {
|
||||||
|
@Override
|
||||||
|
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (!(descriptor instanceof ConstructorDescriptor)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||||
|
assert containingClass != null : "Can't have constructor without a class";
|
||||||
|
return getQualifierForDescriptor(containingClass);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Rule<JsNameRef> annonatedObjectsHaveKotlinQualifier = new Rule<JsNameRef>() {
|
||||||
|
|
||||||
|
//TODO: refactor by removing one annotation
|
||||||
|
@Override
|
||||||
|
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (getAnnotationByName(descriptor, AnnotationsUtils.LIBRARY_FUNCTION_ANNOTATION_FQNAME) != null) {
|
||||||
|
return namer.kotlinObject();
|
||||||
|
}
|
||||||
|
if (getAnnotationByName(descriptor, AnnotationsUtils.LIBRARY_CLASS_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_CLASS_ANNOTATION_FQNAME) != null) {
|
||||||
|
return namer.kotlinObject();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
qualifierGenerator.addRule(annonatedObjectsHaveKotlinQualifier);
|
||||||
|
qualifierGenerator.addRule(membersOfAnnotatedClassesHaveKotlinQualifier);
|
||||||
|
qualifierGenerator.addRule(constructorHaveTheSameQualifierAsTheClass);
|
||||||
|
qualifierGenerator.addRule(namespacesHaveNoQualifiers);
|
||||||
|
qualifierGenerator.addRule(namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier);
|
||||||
|
return qualifierGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public NamingScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
NamingScope namingScope = scopes.get(descriptor);
|
||||||
|
assert namingScope != null : "Must have a scope for descriptor";
|
||||||
|
return namingScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JsNameRef getQualifierForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
return qualifiers.get(descriptor.getOriginal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
JsName name = names.get(descriptor.getOriginal());
|
||||||
|
assert name != null : "Must have name for descriptor";
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,22 +3,17 @@ package org.jetbrains.k2js.translate.context;
|
|||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
import org.jetbrains.jet.lang.psi.JetElement;
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||||
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
|
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils;
|
|
||||||
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.intrinsic.Intrinsics;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.context.declaration.AnnotationsUtils.*;
|
|
||||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
@@ -28,12 +23,6 @@ public final class TranslationContext {
|
|||||||
private final DynamicContext dynamicContext;
|
private final DynamicContext dynamicContext;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final StaticContext staticContext;
|
private final StaticContext staticContext;
|
||||||
@NotNull
|
|
||||||
private final Generator<JsName> names = nameGenerator();
|
|
||||||
@NotNull
|
|
||||||
private final Generator<NamingScope> scopes = scopeGenerator();
|
|
||||||
@NotNull
|
|
||||||
private final Generator<JsNameRef> qualifiers = qualifierGenerator();
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static TranslationContext rootContext(@NotNull StaticContext staticContext) {
|
public static TranslationContext rootContext(@NotNull StaticContext staticContext) {
|
||||||
@@ -102,9 +91,7 @@ public final class TranslationContext {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public NamingScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
public NamingScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
NamingScope namingScope = scopes.get(descriptor);
|
return staticContext.getScopeForDescriptor(descriptor);
|
||||||
assert namingScope != null : "Must have a scope for descriptor";
|
|
||||||
return namingScope;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -119,6 +106,16 @@ public final class TranslationContext {
|
|||||||
return getNameForDescriptor(descriptor);
|
return getNameForDescriptor(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
return staticContext.getNameForDescriptor(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JsNameRef getQualifierForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
return staticContext.getQualifierForDescriptor(descriptor.getOriginal());
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
|
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
|
||||||
return dynamicContext.declareTemporary(initExpression);
|
return dynamicContext.declareTemporary(initExpression);
|
||||||
@@ -158,216 +155,4 @@ public final class TranslationContext {
|
|||||||
public JsBlock jsBlock() {
|
public JsBlock jsBlock() {
|
||||||
return dynamicContext.jsBlock();
|
return dynamicContext.jsBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
JsName name = names.get(descriptor.getOriginal());
|
|
||||||
assert name != null : "Must have name for descriptor";
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Generator<JsName> nameGenerator() {
|
|
||||||
|
|
||||||
Rule<JsName> aliasOverridesNames = new Rule<JsName>() {
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public JsName apply(@NotNull DeclarationDescriptor data) {
|
|
||||||
if (aliaser().hasAliasForDeclaration(data)) {
|
|
||||||
return aliaser().getAliasForDeclaration(data);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Rule<JsName> namesForStandardClasses = new Rule<JsName>() {
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public JsName apply(@NotNull DeclarationDescriptor data) {
|
|
||||||
if (!standardClasses().isStandardObject(data)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return standardClasses().getStandardObjectName(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Rule<JsName> namespacesShouldBeDefinedInRootScope = new Rule<JsName>() {
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (!(descriptor instanceof NamespaceDescriptor)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String nameForNamespace = getNameForNamespace((NamespaceDescriptor) descriptor);
|
|
||||||
return staticContext.getRootScope().declareUnobfuscatableName(nameForNamespace);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Rule<JsName> memberDeclarationsInsideParentsScope = new Rule<JsName>() {
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
NamingScope namingScope = getEnclosingScope(descriptor);
|
|
||||||
return namingScope.declareObfuscatableName(descriptor.getName());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Rule<JsName> constructorHasTheSameNameAsTheClass = new Rule<JsName>() {
|
|
||||||
@Override
|
|
||||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (!(descriptor instanceof ConstructorDescriptor)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
|
||||||
assert containingClass != null : "Can't have constructor without a class";
|
|
||||||
return getNameForDescriptor(containingClass);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Rule<JsName> accessorsHasNamesWithSpecialPrefixes = new Rule<JsName>() {
|
|
||||||
@Override
|
|
||||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (!(descriptor instanceof PropertyAccessorDescriptor)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
boolean isGetter = descriptor instanceof PropertyGetterDescriptor;
|
|
||||||
String propertyName = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty().getName();
|
|
||||||
String accessorName = Namer.getNameForAccessor(propertyName, isGetter);
|
|
||||||
NamingScope enclosingScope = getEnclosingScope(descriptor);
|
|
||||||
return enclosingScope.declareObfuscatableName(accessorName);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Rule<JsName> namesAnnotatedAsStandard = new Rule<JsName>() {
|
|
||||||
@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 = (!name.isEmpty()) ? name : descriptor.getName();
|
|
||||||
} else {
|
|
||||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
|
||||||
if (containingClass == null) return null;
|
|
||||||
if (getAnnotationByName(containingClass, LIBRARY_CLASS_ANNOTATION_FQNAME) != null) {
|
|
||||||
name = descriptor.getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (name != null) {
|
|
||||||
return getEnclosingScope(descriptor).declareUnobfuscatableName(name);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Generator<JsName> nameGenerator = new Generator<JsName>();
|
|
||||||
nameGenerator.addRule(namesForStandardClasses);
|
|
||||||
nameGenerator.addRule(aliasOverridesNames);
|
|
||||||
nameGenerator.addRule(constructorHasTheSameNameAsTheClass);
|
|
||||||
nameGenerator.addRule(namesAnnotatedAsStandard);
|
|
||||||
nameGenerator.addRule(namespacesShouldBeDefinedInRootScope);
|
|
||||||
nameGenerator.addRule(accessorsHasNamesWithSpecialPrefixes);
|
|
||||||
nameGenerator.addRule(memberDeclarationsInsideParentsScope);
|
|
||||||
return nameGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
private NamingScope getEnclosingScope(DeclarationDescriptor descriptor) {
|
|
||||||
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
|
|
||||||
return getScopeForDescriptor(containingDeclaration.getOriginal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Generator<NamingScope> scopeGenerator() {
|
|
||||||
Generator<NamingScope> scopeGenerator = new Generator<NamingScope>();
|
|
||||||
Rule<NamingScope> generateNewScopesForNamespaceDescriptors = new Rule<NamingScope>() {
|
|
||||||
@Override
|
|
||||||
public NamingScope apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (!(descriptor instanceof NamespaceDescriptor)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return staticContext.getRootScope().innerScope("Namespace " + descriptor.getName());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Rule<NamingScope> generateInnerScopesForMembers = new Rule<NamingScope>() {
|
|
||||||
@Override
|
|
||||||
public NamingScope apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
NamingScope enclosingScope = getEnclosingScope(descriptor);
|
|
||||||
return enclosingScope.innerScope("scope for member " + descriptor.getName());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scopeGenerator.addRule(generateNewScopesForNamespaceDescriptors);
|
|
||||||
scopeGenerator.addRule(generateInnerScopesForMembers);
|
|
||||||
|
|
||||||
return scopeGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public JsNameRef getQualifierForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
return qualifiers.get(descriptor.getOriginal());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Generator<JsNameRef> qualifierGenerator() {
|
|
||||||
Generator<JsNameRef> qualifierGenerator = new Generator<JsNameRef>();
|
|
||||||
Rule<JsNameRef> namespacesHaveNoQualifiers = new Rule<JsNameRef>() {
|
|
||||||
@Override
|
|
||||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (!standardClasses().isStandardObject(descriptor)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return namer().kotlinObject();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Rule<JsNameRef> namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier = new Rule<JsNameRef>() {
|
|
||||||
@Override
|
|
||||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
|
|
||||||
if (!(containingDeclaration instanceof NamespaceDescriptor)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
JsName containingDeclarationName = getNameForDescriptor(containingDeclaration);
|
|
||||||
return containingDeclarationName.makeRef();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Rule<JsNameRef> constructorHaveTheSameQualifierAsTheClass = new Rule<JsNameRef>() {
|
|
||||||
@Override
|
|
||||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (!(descriptor instanceof ConstructorDescriptor)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
|
||||||
assert containingClass != null : "Can't have constructor without a class";
|
|
||||||
return getQualifierForDescriptor(containingClass);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Rule<JsNameRef> annonatedObjectsHaveKotlinQualifier = new Rule<JsNameRef>() {
|
|
||||||
|
|
||||||
//TODO: refactor by removing one annotation
|
|
||||||
@Override
|
|
||||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (getAnnotationByName(descriptor, AnnotationsUtils.LIBRARY_FUNCTION_ANNOTATION_FQNAME) != null) {
|
|
||||||
return namer().kotlinObject();
|
|
||||||
}
|
|
||||||
if (getAnnotationByName(descriptor, AnnotationsUtils.LIBRARY_CLASS_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_CLASS_ANNOTATION_FQNAME) != null) {
|
|
||||||
return namer().kotlinObject();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
qualifierGenerator.addRule(annonatedObjectsHaveKotlinQualifier);
|
|
||||||
qualifierGenerator.addRule(membersOfAnnotatedClassesHaveKotlinQualifier);
|
|
||||||
qualifierGenerator.addRule(constructorHaveTheSameQualifierAsTheClass);
|
|
||||||
qualifierGenerator.addRule(namespacesHaveNoQualifiers);
|
|
||||||
qualifierGenerator.addRule(namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier);
|
|
||||||
return qualifierGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ public final class Generator<V> {
|
|||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return generate(descriptor);
|
result = generate(descriptor);
|
||||||
|
values.put(descriptor, result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public final class PropertyTranslator extends AbstractTranslator {
|
|||||||
JsFunction result = functionWithScope(context().getScopeForDescriptor(propertySetterDescriptor));
|
JsFunction result = functionWithScope(context().getScopeForDescriptor(propertySetterDescriptor));
|
||||||
JsParameter defaultParameter =
|
JsParameter defaultParameter =
|
||||||
new JsParameter(propertyAccessContext(propertySetterDescriptor).jsScope().declareTemporary());
|
new JsParameter(propertyAccessContext(propertySetterDescriptor).jsScope().declareTemporary());
|
||||||
JsStatement assignment = assignmentToBackingFieldFromParameter(context(), property, defaultParameter);
|
JsStatement assignment = assignmentToBackingField(context(), property, defaultParameter.getName().makeRef());
|
||||||
result.setParameters(Arrays.asList(defaultParameter));
|
result.setParameters(Arrays.asList(defaultParameter));
|
||||||
result.setBody(AstUtil.convertToBlock(assignment));
|
result.setBody(AstUtil.convertToBlock(assignment));
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
+4
-3
@@ -18,6 +18,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField;
|
||||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.functionWithScope;
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.functionWithScope;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,9 +114,9 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
|
|||||||
PropertyDescriptor propertyDescriptor =
|
PropertyDescriptor propertyDescriptor =
|
||||||
getPropertyDescriptorForConstructorParameter(context().bindingContext(), jetParameter);
|
getPropertyDescriptorForConstructorParameter(context().bindingContext(), jetParameter);
|
||||||
if (propertyDescriptor != null) {
|
if (propertyDescriptor != null) {
|
||||||
initializerStatements.add
|
JsStatement assignmentToBackingFieldExpression = assignmentToBackingField
|
||||||
(TranslationUtils.assignmentToBackingFieldFromParameter
|
(context(), propertyDescriptor, jsParameter.getName().makeRef());
|
||||||
(context(), propertyDescriptor, jsParameter));
|
initializerStatements.add(assignmentToBackingFieldExpression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,14 @@ package org.jetbrains.k2js.translate.initializer;
|
|||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
||||||
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -46,8 +47,8 @@ public final class InitializerVisitor extends TranslatorVisitor<List<JsStatement
|
|||||||
JsStatement assignmentToBackingField(@NotNull JetProperty property, @NotNull JsExpression initExpression,
|
JsStatement assignmentToBackingField(@NotNull JetProperty property, @NotNull JsExpression initExpression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
|
|
||||||
return AstUtil.newAssignmentStatement(
|
PropertyDescriptor propertyDescriptor = BindingUtils.getPropertyDescriptor(context.bindingContext(), property);
|
||||||
TranslationUtils.backingFieldReference(context, property), initExpression);
|
return TranslationUtils.assignmentToBackingField(context, propertyDescriptor, initExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -74,6 +74,14 @@ public final class TranslationUtils {
|
|||||||
return AstUtil.qualified(backingFieldName, qualifier);
|
return AstUtil.qualified(backingFieldName, qualifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsStatement assignmentToBackingField(@NotNull TranslationContext context,
|
||||||
|
@NotNull PropertyDescriptor descriptor,
|
||||||
|
@NotNull JsExpression assignTo) {
|
||||||
|
JsNameRef backingFieldReference = backingFieldReference(context, descriptor);
|
||||||
|
return AstUtil.newAssignmentStatement(backingFieldReference, assignTo);
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JsExpression translateInitializerForProperty(@NotNull JetProperty declaration,
|
public static JsExpression translateInitializerForProperty(@NotNull JetProperty declaration,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
@@ -85,14 +93,6 @@ public final class TranslationUtils {
|
|||||||
return jsInitExpression;
|
return jsInitExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static JsStatement assignmentToBackingFieldFromParameter(@NotNull TranslationContext context,
|
|
||||||
@NotNull PropertyDescriptor descriptor,
|
|
||||||
@NotNull JsParameter parameter) {
|
|
||||||
JsNameRef backingFieldReference = backingFieldReference(context, descriptor);
|
|
||||||
return AstUtil.newAssignmentStatement(backingFieldReference, parameter.getName().makeRef());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsNameRef getQualifiedReference(@NotNull TranslationContext context,
|
public static JsNameRef getQualifiedReference(@NotNull TranslationContext context,
|
||||||
@NotNull DeclarationDescriptor descriptor) {
|
@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
|||||||
Reference in New Issue
Block a user