.kotlin.kotlin-compiler.1.3.11.source-code.DestructuringDeclarationTranslator Maven / Gradle / Ivy
/*
* Copyright 2010-2015 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.kotlin.js.translate.expression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
import org.jetbrains.kotlin.js.backend.ast.JsName;
import org.jetbrains.kotlin.js.backend.ast.JsNameRef;
import org.jetbrains.kotlin.js.backend.ast.JsVars;
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.js.translate.reference.CallExpressionTranslator;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration;
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor;
import static org.jetbrains.kotlin.js.translate.utils.InlineUtils.setInlineCallMetadata;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
public class DestructuringDeclarationTranslator extends AbstractTranslator {
// if multiObjectName was init, initializer must be null
@NotNull
public static JsVars translate(
@NotNull KtDestructuringDeclaration multiDeclaration,
@NotNull JsExpression multiObjectExpr,
@NotNull TranslationContext context
) {
return new DestructuringDeclarationTranslator(multiDeclaration, multiObjectExpr, context).translate();
}
@NotNull
private final KtDestructuringDeclaration multiDeclaration;
@NotNull
private final JsExpression multiObjectExpr;
private DestructuringDeclarationTranslator(
@NotNull KtDestructuringDeclaration multiDeclaration,
@NotNull JsExpression multiObjectExpr,
@NotNull TranslationContext context
) {
super(context);
this.multiDeclaration = multiDeclaration;
this.multiObjectExpr = multiObjectExpr;
}
private JsVars translate() {
List jsVars = new ArrayList<>();
for (KtDestructuringDeclarationEntry entry : multiDeclaration.getEntries()) {
VariableDescriptor descriptor = BindingContextUtils.getNotNull(context().bindingContext(), BindingContext.VARIABLE, entry);
// Do not call `componentX` for destructuring entry called _
if (descriptor.getName().isSpecial()) continue;
ResolvedCall entryInitCall = context().bindingContext().get(BindingContext.COMPONENT_RESOLVED_CALL, entry);
assert entryInitCall != null : "Entry init call must be not null";
JsExpression entryInitializer = CallTranslator.translate(context(), entryInitCall, multiObjectExpr);
FunctionDescriptor candidateDescriptor = entryInitCall.getCandidateDescriptor();
if (CallExpressionTranslator.shouldBeInlined(candidateDescriptor, context())) {
setInlineCallMetadata(entryInitializer, entry, entryInitCall, context());
}
entryInitializer = TranslationUtils.coerce(context(), entryInitializer, descriptor.getType());
JsName name = context().getNameForDescriptor(descriptor);
if (isVarCapturedInClosure(context().bindingContext(), descriptor)) {
JsNameRef alias = getCapturedVarAccessor(name.makeRef());
entryInitializer = JsAstUtils.wrapValue(alias, entryInitializer);
}
JsVars.JsVar jsVar = new JsVars.JsVar(name, entryInitializer);
jsVar.setSource(entry);
jsVars.add(jsVar);
}
JsVars result = new JsVars(jsVars, true);
result.setSource(multiDeclaration);
return result;
}
}