JS: generate name table entries for non-internal name so that Merger could merge them in a single JsName. It is required for inlining to properly work on non-toplevel declarations between different files.

This commit is contained in:
Alexey Andreev
2017-02-10 20:32:53 +03:00
parent ee1e0fc0b1
commit ce1eabdf6f
@@ -381,9 +381,16 @@ public final class StaticContext {
List<JsName> names = new ArrayList<>(); List<JsName> names = new ArrayList<>();
if (suggested.getStable()) { if (suggested.getStable()) {
String tag = getTag(suggested.getDescriptor());
int index = 0;
for (String namePart : suggested.getNames()) { for (String namePart : suggested.getNames()) {
JsName name = scope.declareName(namePart); JsName name = scope.declareName(namePart);
MetadataProperties.setDescriptor(name, suggested.getDescriptor()); MetadataProperties.setDescriptor(name, suggested.getDescriptor());
if (tag != null && !AnnotationsUtils.isNativeObject(suggested.getDescriptor()) &&
!AnnotationsUtils.isLibraryObject(suggested.getDescriptor())
) {
fragment.getNameBindings().add(new JsNameBinding(index++ + ":" + tag, name));
}
names.add(name); names.add(name);
} }
} }
@@ -395,7 +402,7 @@ public final class StaticContext {
String baseName = NameSuggestion.sanitizeName(suggested.getNames().get(0)); String baseName = NameSuggestion.sanitizeName(suggested.getNames().get(0));
if (suggested.getDescriptor() instanceof LocalVariableDescriptor || if (suggested.getDescriptor() instanceof LocalVariableDescriptor ||
suggested.getDescriptor() instanceof ValueParameterDescriptor suggested.getDescriptor() instanceof ValueParameterDescriptor
) { ) {
name = JsScope.declareTemporaryName(baseName); name = JsScope.declareTemporaryName(baseName);
} }
else { else {
@@ -407,6 +414,10 @@ public final class StaticContext {
} }
nameCache.put(suggested.getDescriptor(), name); nameCache.put(suggested.getDescriptor(), name);
MetadataProperties.setDescriptor(name, suggested.getDescriptor()); MetadataProperties.setDescriptor(name, suggested.getDescriptor());
String tag = getTag(suggested.getDescriptor());
if (tag != null) {
fragment.getNameBindings().add(new JsNameBinding(tag, name));
}
names.add(name); names.add(name);
} }
@@ -454,13 +465,13 @@ public final class StaticContext {
@NotNull @NotNull
public JsName importDeclaration(@NotNull String suggestedName, @NotNull String tag, @NotNull JsExpression declaration) { public JsName importDeclaration(@NotNull String suggestedName, @NotNull String tag, @NotNull JsExpression declaration) {
// Adding prefix is a workaround for a problem with scopes. JsName result = importDeclarationImpl(suggestedName, tag, declaration);
// Consider we declare name `foo` in functions's local scope, then call top-level function `foo` fragment.getNameBindings().add(new JsNameBinding(tag, result));
// from another module. It's imported into global scope under name `foo`. If we could somehow return result;
// declare all names in global scope before running translator, we would have got `foo_1` for local variable, }
// since local scope inherited from global scope.
// TODO: remove prefix when problem with scopes is solved
@NotNull
private JsName importDeclarationImpl(@NotNull String suggestedName, @NotNull String tag, @NotNull JsExpression declaration) {
JsName result = JsScope.declareTemporaryName(suggestedName); JsName result = JsScope.declareTemporaryName(suggestedName);
MetadataProperties.setImported(result, true); MetadataProperties.setImported(result, true);
fragment.getImports().put(tag, declaration); fragment.getImports().put(tag, declaration);
@@ -472,9 +483,17 @@ public final class StaticContext {
ModuleDescriptor module = DescriptorUtilsKt.getModule(descriptor); ModuleDescriptor module = DescriptorUtilsKt.getModule(descriptor);
JsName name; JsName name;
String tag = getTag(descriptor); String tag = getTag(descriptor);
if (module != currentModule || AnnotationsUtils.isNativeObject(descriptor) || AnnotationsUtils.isLibraryObject(descriptor)) { boolean isNative = AnnotationsUtils.isNativeObject(descriptor) || AnnotationsUtils.isLibraryObject(descriptor);
assert tag != null : "Can't import declaration without fqname: " + descriptor; if (module != currentModule || isNative) {
name = importDeclaration(suggestedName, tag, getQualifiedReference(descriptor)); assert tag != null : "Can't import declaration without tag: " + descriptor;
JsNameRef result = getQualifiedReference(descriptor);
if (isNative && result.getQualifier() == null && result.getName() != null) {
name = result.getName();
tag = null;
}
else {
name = importDeclarationImpl(suggestedName, tag, result);
}
} }
else { else {
name = JsScope.declareTemporaryName(suggestedName); name = JsScope.declareTemporaryName(suggestedName);