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
|
package org.jetbrains.kotlin.js.translate.context
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsExpression
|
import com.google.dart.compiler.backend.js.ast.*
|
||||||
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.metadata.staticRef
|
import com.google.dart.compiler.backend.js.ast.metadata.staticRef
|
||||||
|
|
||||||
class DefinitionPlace(
|
class DefinitionPlace(
|
||||||
@@ -28,9 +24,9 @@ class DefinitionPlace(
|
|||||||
private val fqName: JsExpression,
|
private val fqName: JsExpression,
|
||||||
val properties: MutableList<JsPropertyInitializer>
|
val properties: MutableList<JsPropertyInitializer>
|
||||||
) {
|
) {
|
||||||
fun define(suggestedName: String, expression : JsExpression): JsNameRef {
|
fun define(suggestedName: String, expression : JsExpression) = define(scope.declareFreshName(suggestedName), expression)
|
||||||
val name = scope.declareFreshName(suggestedName)
|
|
||||||
|
|
||||||
|
fun define(name: JsName, expression: JsExpression): JsNameRef {
|
||||||
if (expression is JsFunction) {
|
if (expression is JsFunction) {
|
||||||
/** JsInliner should be able
|
/** JsInliner should be able
|
||||||
* to find function by name */
|
* 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.BindingTrace;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.*;
|
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>() {
|
Rule<JsName> namesForStandardClasses = new Rule<JsName>() {
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -368,6 +394,7 @@ public final class StaticContext {
|
|||||||
};
|
};
|
||||||
|
|
||||||
addRule(namesForDynamic);
|
addRule(namesForDynamic);
|
||||||
|
addRule(localDeclarations);
|
||||||
addRule(namesForStandardClasses);
|
addRule(namesForStandardClasses);
|
||||||
addRule(constructorOrCompanionObjectHasTheSameNameAsTheClass);
|
addRule(constructorOrCompanionObjectHasTheSameNameAsTheClass);
|
||||||
addRule(propertyOrPropertyAccessor);
|
addRule(propertyOrPropertyAccessor);
|
||||||
@@ -554,6 +581,9 @@ public final class StaticContext {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||||
|
if (container != null && !(container instanceof ClassDescriptor)) {
|
||||||
|
container = DescriptorUtils.getContainingClass(container);
|
||||||
|
}
|
||||||
if (container == null) {
|
if (container == null) {
|
||||||
return 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(libraryObjectsHaveKotlinQualifier);
|
||||||
addRule(constructorOrCompanionObjectHasTheSameQualifierAsTheClass);
|
addRule(constructorOrCompanionObjectHasTheSameQualifierAsTheClass);
|
||||||
addRule(standardObjectsHaveKotlinQualifier);
|
addRule(standardObjectsHaveKotlinQualifier);
|
||||||
@@ -581,6 +627,7 @@ public final class StaticContext {
|
|||||||
addRule(nativeObjectsHaveNativePartOfFullQualifier);
|
addRule(nativeObjectsHaveNativePartOfFullQualifier);
|
||||||
addRule(staticMembersHaveContainerQualifier);
|
addRule(staticMembersHaveContainerQualifier);
|
||||||
addRule(nestedClassesHaveContainerQualifier);
|
addRule(nestedClassesHaveContainerQualifier);
|
||||||
|
addRule(localClassesHavePackageQualifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -399,10 +399,15 @@ public class TranslationContext {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsNameRef define(DeclarationDescriptor descriptor, JsExpression expression) {
|
public JsNameRef define(DeclarationDescriptor descriptor, JsExpression expression) {
|
||||||
String suggestedName = TranslationUtils.getSuggestedNameForInnerDeclaration(this, descriptor);
|
String suggestedName = TranslationUtils.getSuggestedNameForInnerDeclaration(staticContext, descriptor);
|
||||||
return getDefinitionPlace().define(suggestedName, expression);
|
return getDefinitionPlace().define(suggestedName, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsNameRef define(JsName name, JsExpression expression) {
|
||||||
|
return getDefinitionPlace().define(name, expression);
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JsNameRef captureIfNeedAndGetCapturedName(DeclarationDescriptor descriptor) {
|
private JsNameRef captureIfNeedAndGetCapturedName(DeclarationDescriptor descriptor) {
|
||||||
if (usageTracker != null) {
|
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.BinaryOperationTranslator;
|
||||||
import org.jetbrains.kotlin.js.translate.operation.UnaryOperationTranslator;
|
import org.jetbrains.kotlin.js.translate.operation.UnaryOperationTranslator;
|
||||||
import org.jetbrains.kotlin.js.translate.reference.*;
|
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.JsAstUtils;
|
||||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
|
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
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);
|
assert descriptor != null : "Missing declaration descriptor: " + PsiUtilsKt.getTextWithLocation(expression);
|
||||||
return descriptor;
|
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.*;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||||
import org.jetbrains.kotlin.js.translate.context.Namer;
|
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.TemporaryConstVariable;
|
||||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.kotlin.js.translate.general.Translation;
|
import org.jetbrains.kotlin.js.translate.general.Translation;
|
||||||
@@ -263,7 +264,7 @@ public final class TranslationUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String getSuggestedNameForInnerDeclaration(TranslationContext context, DeclarationDescriptor descriptor) {
|
public static String getSuggestedNameForInnerDeclaration(StaticContext context, DeclarationDescriptor descriptor) {
|
||||||
String suggestedName = "";
|
String suggestedName = "";
|
||||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
|
|||||||
Reference in New Issue
Block a user