KT-11030 Implements local classes that don't have closure
This commit is contained in:
@@ -16,11 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.context
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression
|
||||
import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef
|
||||
import com.google.dart.compiler.backend.js.ast.JsObjectScope
|
||||
import com.google.dart.compiler.backend.js.ast.JsFunction
|
||||
import com.google.dart.compiler.backend.js.ast.*
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.staticRef
|
||||
|
||||
class DefinitionPlace(
|
||||
@@ -28,9 +24,9 @@ class DefinitionPlace(
|
||||
private val fqName: JsExpression,
|
||||
val properties: MutableList<JsPropertyInitializer>
|
||||
) {
|
||||
fun define(suggestedName: String, expression : JsExpression): JsNameRef {
|
||||
val name = scope.declareFreshName(suggestedName)
|
||||
fun define(suggestedName: String, expression : JsExpression) = define(scope.declareFreshName(suggestedName), expression)
|
||||
|
||||
fun define(name: JsName, expression: JsExpression): JsNameRef {
|
||||
if (expression is JsFunction) {
|
||||
/** JsInliner should be able
|
||||
* to find function by name */
|
||||
|
||||
@@ -38,6 +38,9 @@ import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.*;
|
||||
@@ -255,6 +258,29 @@ public final class StaticContext {
|
||||
}
|
||||
};
|
||||
|
||||
Rule<JsName> localDeclarations = new Rule<JsName>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (!DescriptorUtils.isLocal(descriptor) || !DescriptorUtils.isClass(descriptor)) return null;
|
||||
|
||||
List<String> parts = new ArrayList<String>();
|
||||
do {
|
||||
parts.add(descriptor.getName().asString());
|
||||
descriptor = descriptor.getContainingDeclaration();
|
||||
} while (!(descriptor instanceof ClassOrPackageFragmentDescriptor));
|
||||
|
||||
Collections.reverse(parts);
|
||||
StringBuilder suggestedName = new StringBuilder(parts.get(0));
|
||||
for (int i = 1; i < parts.size(); ++i) {
|
||||
suggestedName.append('$').append(parts.get(i));
|
||||
}
|
||||
|
||||
JsScope scope = getScopeForDescriptor(descriptor);
|
||||
return scope.declareFreshName(suggestedName.toString());
|
||||
}
|
||||
};
|
||||
|
||||
Rule<JsName> namesForStandardClasses = new Rule<JsName>() {
|
||||
@Override
|
||||
@Nullable
|
||||
@@ -368,6 +394,7 @@ public final class StaticContext {
|
||||
};
|
||||
|
||||
addRule(namesForDynamic);
|
||||
addRule(localDeclarations);
|
||||
addRule(namesForStandardClasses);
|
||||
addRule(constructorOrCompanionObjectHasTheSameNameAsTheClass);
|
||||
addRule(propertyOrPropertyAccessor);
|
||||
@@ -554,6 +581,9 @@ public final class StaticContext {
|
||||
return null;
|
||||
}
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
if (container != null && !(container instanceof ClassDescriptor)) {
|
||||
container = DescriptorUtils.getContainingClass(container);
|
||||
}
|
||||
if (container == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -574,6 +604,22 @@ public final class StaticContext {
|
||||
}
|
||||
};
|
||||
|
||||
Rule<JsExpression> localClassesHavePackageQualifier = new Rule<JsExpression>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public JsExpression apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (!DescriptorUtils.isLocal(descriptor) || !(descriptor instanceof ClassDescriptor)) return null;
|
||||
|
||||
descriptor = descriptor.getContainingDeclaration();
|
||||
while (descriptor != null && !(descriptor instanceof ClassOrPackageFragmentDescriptor)) {
|
||||
descriptor = descriptor.getContainingDeclaration();
|
||||
}
|
||||
if (!(descriptor instanceof PackageFragmentDescriptor)) return null;
|
||||
|
||||
return getQualifiedReference(descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
addRule(libraryObjectsHaveKotlinQualifier);
|
||||
addRule(constructorOrCompanionObjectHasTheSameQualifierAsTheClass);
|
||||
addRule(standardObjectsHaveKotlinQualifier);
|
||||
@@ -581,6 +627,7 @@ public final class StaticContext {
|
||||
addRule(nativeObjectsHaveNativePartOfFullQualifier);
|
||||
addRule(staticMembersHaveContainerQualifier);
|
||||
addRule(nestedClassesHaveContainerQualifier);
|
||||
addRule(localClassesHavePackageQualifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -399,10 +399,15 @@ public class TranslationContext {
|
||||
|
||||
@NotNull
|
||||
public JsNameRef define(DeclarationDescriptor descriptor, JsExpression expression) {
|
||||
String suggestedName = TranslationUtils.getSuggestedNameForInnerDeclaration(this, descriptor);
|
||||
String suggestedName = TranslationUtils.getSuggestedNameForInnerDeclaration(staticContext, descriptor);
|
||||
return getDefinitionPlace().define(suggestedName, expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsNameRef define(JsName name, JsExpression expression) {
|
||||
return getDefinitionPlace().define(name, expression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JsNameRef captureIfNeedAndGetCapturedName(DeclarationDescriptor descriptor) {
|
||||
if (usageTracker != null) {
|
||||
|
||||
+9
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.js.translate.general.TranslatorVisitor;
|
||||
import org.jetbrains.kotlin.js.translate.operation.BinaryOperationTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.operation.UnaryOperationTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.reference.*;
|
||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
@@ -565,4 +566,12 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
assert descriptor != null : "Missing declaration descriptor: " + PsiUtilsKt.getTextWithLocation(expression);
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsNode visitClass(@NotNull KtClass klass, TranslationContext context) {
|
||||
JsInvocation jsClass = ClassTranslator.generateClassCreation(klass, context);
|
||||
DeclarationDescriptor descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), klass);
|
||||
JsName name = context.getNameForDescriptor(descriptor);
|
||||
return context.define(name, jsClass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer;
|
||||
import org.jetbrains.kotlin.js.translate.context.StaticContext;
|
||||
import org.jetbrains.kotlin.js.translate.context.TemporaryConstVariable;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.general.Translation;
|
||||
@@ -263,7 +264,7 @@ public final class TranslationUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getSuggestedNameForInnerDeclaration(TranslationContext context, DeclarationDescriptor descriptor) {
|
||||
public static String getSuggestedNameForInnerDeclaration(StaticContext context, DeclarationDescriptor descriptor) {
|
||||
String suggestedName = "";
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
//noinspection ConstantConditions
|
||||
|
||||
Reference in New Issue
Block a user