Prevent JS AST nodes of several types to be shared

This commit is contained in:
Alexey Andreev
2017-05-05 17:42:43 +03:00
parent 3077a0f640
commit e9a2c8c0f1
73 changed files with 537 additions and 485 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -63,7 +63,7 @@ object OperatorNameConventions {
// If you add new unary, binary or assignment operators, add it to OperatorConventions as well
@JvmField
internal val UNARY_OPERATION_NAMES = setOf(INC, DEC, UNARY_PLUS, UNARY_MINUS, NOT)
val UNARY_OPERATION_NAMES = setOf(INC, DEC, UNARY_PLUS, UNARY_MINUS, NOT)
@JvmField
internal val SIMPLE_UNARY_OPERATION_NAMES = setOf(UNARY_PLUS, UNARY_MINUS, NOT)
@@ -61,7 +61,7 @@ class JsPrecedenceVisitor extends JsVisitor {
}
@Override
public void visitBoolean(@NotNull JsLiteral.JsBooleanLiteral x) {
public void visitBoolean(@NotNull JsBooleanLiteral x) {
answer = 17; // primary
}
@@ -101,12 +101,12 @@ class JsPrecedenceVisitor extends JsVisitor {
}
@Override
public void visitInt(@NotNull JsNumberLiteral.JsIntLiteral x) {
public void visitInt(@NotNull JsIntLiteral x) {
answer = 17; // primary
}
@Override
public void visitDouble(@NotNull JsNumberLiteral.JsDoubleLiteral x) {
public void visitDouble(@NotNull JsDoubleLiteral x) {
answer = 17; // primary
}
@@ -141,7 +141,7 @@ class JsPrecedenceVisitor extends JsVisitor {
}
@Override
public void visitThis(@NotNull JsLiteral.JsThisRef x) {
public void visitThis(@NotNull JsThisRef x) {
answer = 17; // primary
}
@@ -5,8 +5,8 @@
package org.jetbrains.kotlin.js.backend;
import org.jetbrains.kotlin.js.backend.ast.*;
import org.jetbrains.kotlin.js.backend.ast.JsNumberLiteral.JsDoubleLiteral;
import org.jetbrains.kotlin.js.backend.ast.JsNumberLiteral.JsIntLiteral;
import org.jetbrains.kotlin.js.backend.ast.JsDoubleLiteral;
import org.jetbrains.kotlin.js.backend.ast.JsIntLiteral;
import org.jetbrains.kotlin.js.backend.ast.JsVars.JsVar;
import org.jetbrains.kotlin.js.util.TextOutput;
import gnu.trove.THashSet;
@@ -258,7 +258,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
}
@Override
public void visitBoolean(@NotNull JsLiteral.JsBooleanLiteral x) {
public void visitBoolean(@NotNull JsBooleanLiteral x) {
if (x.getValue()) {
p.print(CHARS_TRUE);
}
@@ -773,7 +773,7 @@ public class JsToStringGenerationVisitor extends JsVisitor {
}
@Override
public void visitThis(@NotNull JsLiteral.JsThisRef x) {
public void visitThis(@NotNull JsThisRef x) {
p.print(CHARS_THIS);
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2017 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.backend.ast;
import org.jetbrains.annotations.NotNull;
public final class JsBooleanLiteral extends JsLiteral.JsValueLiteral {
private final boolean value;
// Should be interned by JsProgram
public JsBooleanLiteral(boolean value) {
this.value = value;
}
public boolean getValue() {
return value;
}
@Override
public void accept(JsVisitor v) {
v.visitBoolean(this);
}
@Override
public void traverse(JsVisitorWithContext v, JsContext ctx) {
v.visit(this, ctx);
v.endVisit(this, ctx);
}
@NotNull
@Override
public JsBooleanLiteral deepCopy() {
return new JsBooleanLiteral(value).withMetadataFrom(this);
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2017 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.backend.ast;
import org.jetbrains.annotations.NotNull;
public final class JsDoubleLiteral extends JsNumberLiteral {
public final double value;
public JsDoubleLiteral(double value) {
this.value = value;
}
@Override
public void accept(JsVisitor v) {
v.visitDouble(this);
}
public String toString() {
return String.valueOf(value);
}
@Override
public void traverse(JsVisitorWithContext v, JsContext ctx) {
v.visit(this, ctx);
v.endVisit(this, ctx);
}
@NotNull
@Override
public JsDoubleLiteral deepCopy() {
return new JsDoubleLiteral(value).withMetadataFrom(this);
}
}
@@ -11,7 +11,7 @@ import java.util.List;
public abstract class JsExpression extends SourceInfoAwareJsNode {
/**
* Determines whether or not this expression is a leaf, such as a
* {@link JsNameRef}, {@link JsLiteral.JsBooleanLiteral}, and so on. Leaf expressions
* {@link JsNameRef}, {@link JsBooleanLiteral}, and so on. Leaf expressions
* never need to be parenthesized.
*/
public boolean isLeaf() {
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2017 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.backend.ast;
import org.jetbrains.annotations.NotNull;
public final class JsIntLiteral extends JsNumberLiteral {
public final int value;
public JsIntLiteral(int value) {
this.value = value;
}
@Override
public void accept(JsVisitor v) {
v.visitInt(this);
}
public String toString() {
return String.valueOf(value);
}
@Override
public void traverse(JsVisitorWithContext v, JsContext ctx) {
v.visit(this, ctx);
v.endVisit(this, ctx);
}
@NotNull
@Override
public JsExpression deepCopy() {
return new JsIntLiteral(value).withMetadataFrom(this);
}
}
@@ -7,59 +7,6 @@ package org.jetbrains.kotlin.js.backend.ast;
import org.jetbrains.annotations.NotNull;
public abstract class JsLiteral extends JsExpression {
public static final JsValueLiteral THIS = new JsThisRef();
public static final JsNameRef UNDEFINED = new JsNameRef("undefined");
public static final JsNullLiteral NULL = new JsNullLiteral();
public static final JsBooleanLiteral TRUE = new JsBooleanLiteral(true);
public static final JsBooleanLiteral FALSE = new JsBooleanLiteral(false);
public static JsBooleanLiteral getBoolean(boolean truth) {
return truth ? TRUE : FALSE;
}
public static final class JsThisRef extends JsValueLiteral {
private JsThisRef() {
super();
}
@Override
public void accept(JsVisitor v) {
v.visitThis(this);
}
@Override
public void traverse(JsVisitorWithContext v, JsContext ctx) {
v.visit(this, ctx);
v.endVisit(this, ctx);
}
}
public static final class JsBooleanLiteral extends JsValueLiteral {
private final boolean value;
// Should be interned by JsProgram
private JsBooleanLiteral(boolean value) {
this.value = value;
}
public boolean getValue() {
return value;
}
@Override
public void accept(JsVisitor v) {
v.visitBoolean(this);
}
@Override
public void traverse(JsVisitorWithContext v, JsContext ctx) {
v.visit(this, ctx);
v.endVisit(this, ctx);
}
}
/**
* A JavaScript string literal expression.
*/
@@ -78,4 +25,12 @@ public abstract class JsLiteral extends JsExpression {
return this;
}
}
public static boolean isTrueBoolean(@NotNull JsExpression expression) {
return expression instanceof JsBooleanLiteral && ((JsBooleanLiteral) expression).getValue();
}
public static boolean isFalseBoolean(@NotNull JsExpression expression) {
return expression instanceof JsBooleanLiteral && !((JsBooleanLiteral) expression).getValue();
}
}
@@ -4,8 +4,10 @@
package org.jetbrains.kotlin.js.backend.ast;
import org.jetbrains.annotations.NotNull;
public final class JsNullLiteral extends JsLiteral.JsValueLiteral {
JsNullLiteral() {
public JsNullLiteral() {
}
@Override
@@ -18,4 +20,10 @@ public final class JsNullLiteral extends JsLiteral.JsValueLiteral {
v.visit(this, ctx);
v.endVisit(this, ctx);
}
@NotNull
@Override
public JsNullLiteral deepCopy() {
return new JsNullLiteral().withMetadataFrom(this);
}
}
@@ -5,51 +5,4 @@
package org.jetbrains.kotlin.js.backend.ast;
public abstract class JsNumberLiteral extends JsLiteral.JsValueLiteral {
public static final JsIntLiteral ZERO = new JsIntLiteral(0);
public static final class JsDoubleLiteral extends JsNumberLiteral {
public final double value;
JsDoubleLiteral(double value) {
this.value = value;
}
@Override
public void accept(JsVisitor v) {
v.visitDouble(this);
}
public String toString() {
return String.valueOf(value);
}
@Override
public void traverse(JsVisitorWithContext v, JsContext ctx) {
v.visit(this, ctx);
v.endVisit(this, ctx);
}
}
public static final class JsIntLiteral extends JsNumberLiteral {
public final int value;
JsIntLiteral(int value) {
this.value = value;
}
@Override
public void accept(JsVisitor v) {
v.visitInt(this);
}
public String toString() {
return String.valueOf(value);
}
@Override
public void traverse(JsVisitorWithContext v, JsContext ctx) {
v.visit(this, ctx);
v.endVisit(this, ctx);
}
}
}
@@ -4,14 +4,7 @@
package org.jetbrains.kotlin.js.backend.ast;
import gnu.trove.TDoubleObjectHashMap;
import gnu.trove.THashMap;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.js.backend.ast.JsNumberLiteral.JsDoubleLiteral;
import org.jetbrains.kotlin.js.backend.ast.JsNumberLiteral.JsIntLiteral;
import java.util.Map;
/**
* A JavaScript program.
@@ -31,14 +24,6 @@ public final class JsProgram extends SourceInfoAwareJsNode {
return globalBlock;
}
public JsNumberLiteral getNumberLiteral(double value) {
return new JsDoubleLiteral(value);
}
public JsNumberLiteral getNumberLiteral(int value) {
return new JsIntLiteral(value);
}
/**
* Gets the quasi-mythical root scope. This is not the same as the top scope;
* all unresolvable identifiers wind up here, because they are considered
@@ -56,14 +41,6 @@ public final class JsProgram extends SourceInfoAwareJsNode {
return topScope;
}
/**
* Creates or retrieves a JsStringLiteral from an interned object pool.
*/
@NotNull
public JsStringLiteral getStringLiteral(String value) {
return new JsStringLiteral(value);
}
@Override
public void accept(JsVisitor v) {
v.visitProgram(this);
@@ -4,24 +4,21 @@
package org.jetbrains.kotlin.js.backend.ast;
public final class JsStringLiteral extends JsLiteral.JsValueLiteral {
public static JsStringLiteral createCharZero() {
return new JsStringLiteral("\0");
}
import org.jetbrains.annotations.NotNull;
public final class JsStringLiteral extends JsLiteral.JsValueLiteral {
private final String value;
// These only get created by JsProgram so that they can be interned.
JsStringLiteral(String value) {
this.value = value;
}
public JsStringLiteral(String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public void accept(JsVisitor v) {
@Override
public void accept(JsVisitor v) {
v.visitString(this);
}
@@ -30,4 +27,10 @@ public final class JsStringLiteral extends JsLiteral.JsValueLiteral {
v.visit(this, ctx);
v.endVisit(this, ctx);
}
@NotNull
@Override
public JsStringLiteral deepCopy() {
return new JsStringLiteral(value).withMetadataFrom(this);
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2017 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.backend.ast;
import org.jetbrains.annotations.NotNull;
public final class JsThisRef extends JsLiteral.JsValueLiteral {
@Override
public void accept(JsVisitor v) {
v.visitThis(this);
}
@Override
public void traverse(JsVisitorWithContext v, JsContext ctx) {
v.visit(this, ctx);
v.endVisit(this, ctx);
}
@NotNull
@Override
public JsThisRef deepCopy() {
return new JsThisRef().withMetadataFrom(this);
}
}
@@ -39,7 +39,7 @@ abstract class JsVisitor {
open fun visitBlock(x: JsBlock): Unit =
visitElement(x)
open fun visitBoolean(x: JsLiteral.JsBooleanLiteral): Unit =
open fun visitBoolean(x: JsBooleanLiteral): Unit =
visitElement(x)
open fun visitBreak(x: JsBreak): Unit =
@@ -99,10 +99,10 @@ abstract class JsVisitor {
open fun visitNull(x: JsNullLiteral): Unit =
visitElement(x)
open fun visitInt(x: JsNumberLiteral.JsIntLiteral): Unit =
open fun visitInt(x: JsIntLiteral): Unit =
visitElement(x)
open fun visitDouble(x: JsNumberLiteral.JsDoubleLiteral): Unit =
open fun visitDouble(x: JsDoubleLiteral): Unit =
visitElement(x)
open fun visitObjectLiteral(x: JsObjectLiteral): Unit =
@@ -135,7 +135,7 @@ abstract class JsVisitor {
open fun visit(x: JsSwitch): Unit =
visitElement(x)
open fun visitThis(x: JsLiteral.JsThisRef): Unit =
open fun visitThis(x: JsThisRef): Unit =
visitElement(x)
open fun visitThrow(x: JsThrow): Unit =
@@ -71,7 +71,7 @@ public abstract class JsVisitorWithContext {
public void endVisit(@NotNull JsBlock x, @NotNull JsContext ctx) {
}
public void endVisit(@NotNull JsLiteral.JsBooleanLiteral x, @NotNull JsContext ctx) {
public void endVisit(@NotNull JsBooleanLiteral x, @NotNull JsContext ctx) {
}
public void endVisit(@NotNull JsBreak x, @NotNull JsContext ctx) {
@@ -167,7 +167,7 @@ public abstract class JsVisitorWithContext {
public void endVisit(@NotNull JsSwitch x, @NotNull JsContext ctx) {
}
public void endVisit(@NotNull JsLiteral.JsThisRef x, @NotNull JsContext ctx) {
public void endVisit(@NotNull JsThisRef x, @NotNull JsContext ctx) {
}
public void endVisit(@NotNull JsThrow x, @NotNull JsContext ctx) {
@@ -201,7 +201,7 @@ public abstract class JsVisitorWithContext {
return true;
}
public boolean visit(@NotNull JsLiteral.JsBooleanLiteral x, @NotNull JsContext ctx) {
public boolean visit(@NotNull JsBooleanLiteral x, @NotNull JsContext ctx) {
return true;
}
@@ -329,7 +329,7 @@ public abstract class JsVisitorWithContext {
return true;
}
public boolean visit(@NotNull JsLiteral.JsThisRef x, @NotNull JsContext ctx) {
public boolean visit(@NotNull JsThisRef x, @NotNull JsContext ctx) {
return true;
}
@@ -63,7 +63,7 @@ class Context {
val index = expression.index
if (index is JsStringLiteral) extractNodeImpl(expression.array)?.member(index.value) else null
}
is JsLiteral.JsThisRef -> {
is JsThisRef -> {
thisNode
}
is JsInvocation -> {
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.js.inline.util.collectBreakContinueTargets
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.utils.DFS
class CoroutineBodyTransformer(private val program: JsProgram, private val context: CoroutineTransformationContext) : RecursiveJsVisitor() {
class CoroutineBodyTransformer(private val context: CoroutineTransformationContext) : RecursiveJsVisitor() {
private val entryBlock = context.entryBlock
private val globalCatchBlock = context.globalCatchBlock
private var currentBlock = entryBlock
@@ -55,7 +55,7 @@ class CoroutineBodyTransformer(private val program: JsProgram, private val conte
currentBlock.statements += JsReturn()
val graph = entryBlock.buildGraph(globalCatchBlock)
val orderedBlocks = DFS.topologicalOrder(listOf(entryBlock)) { graph[it].orEmpty() }
orderedBlocks.replaceCoroutineFlowStatements(context, program)
orderedBlocks.replaceCoroutineFlowStatements(context)
return orderedBlocks
}
@@ -121,7 +121,7 @@ class CoroutineBodyTransformer(private val program: JsProgram, private val conte
currentStatements += stateAndJump(bodyEntryBlock, x)
currentBlock = bodyEntryBlock
if (x.condition != JsLiteral.TRUE) {
if (!JsLiteral.isTrueBoolean(x.condition)) {
currentStatements += JsIf(JsAstUtils.notOptimized(x.condition), JsBlock(stateAndJump(successor, x))).apply { source = x.source }
}
@@ -143,7 +143,7 @@ class CoroutineBodyTransformer(private val program: JsProgram, private val conte
x.body.accept(this)
}
if (x.condition != JsLiteral.TRUE) {
if (!JsLiteral.isTrueBoolean(x.condition)) {
val jsIf = JsIf(JsAstUtils.notOptimized(x.condition), JsBlock(stateAndJump(successor, x))).apply { source = x.source }
currentStatements.add(jsIf)
}
@@ -168,7 +168,7 @@ class CoroutineBodyTransformer(private val program: JsProgram, private val conte
currentStatements += stateAndJump(bodyEntryBlock, x)
currentBlock = bodyEntryBlock
if (x.condition != null && x.condition != JsLiteral.TRUE) {
if (x.condition != null && !JsLiteral.isTrueBoolean(x.condition)) {
currentStatements += JsIf(JsAstUtils.notOptimized(x.condition), JsBlock(stateAndJump(successor, x))).apply { source = x.source }
}
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.js.inline.util.getInnerFunction
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
class CoroutineFunctionTransformer(private val program: JsProgram, private val function: JsFunction, name: String?) {
class CoroutineFunctionTransformer(private val function: JsFunction, name: String?) {
private val innerFunction = function.getInnerFunction()
private val functionWithBody = innerFunction ?: function
private val body = functionWithBody.body
@@ -35,7 +35,7 @@ class CoroutineFunctionTransformer(private val program: JsProgram, private val f
fun transform(): List<JsStatement> {
val context = CoroutineTransformationContext(function.scope, function)
val bodyTransformer = CoroutineBodyTransformer(program, context)
val bodyTransformer = CoroutineBodyTransformer(context)
bodyTransformer.preProcess(body)
body.statements.forEach { it.accept(bodyTransformer) }
val coroutineBlocks = bodyTransformer.postProcess()
@@ -83,11 +83,11 @@ class CoroutineFunctionTransformer(private val program: JsProgram, private val f
constructor.body.statements.run {
val baseClass = context.metadata.baseClassRef.deepCopy()
this += JsInvocation(Namer.getFunctionCallRef(baseClass), JsLiteral.THIS, interceptorRef).source(psiElement).makeStmt()
this += JsInvocation(Namer.getFunctionCallRef(baseClass), JsThisRef(), interceptorRef).source(psiElement).makeStmt()
if (controllerName != null) {
assignToField(context.controllerFieldName, controllerName.makeRef(), psiElement)
}
assignToField(context.metadata.exceptionStateName, program.getNumberLiteral(globalCatchBlockIndex), psiElement)
assignToField(context.metadata.exceptionStateName, JsIntLiteral(globalCatchBlockIndex), psiElement)
if (context.metadata.hasReceiver) {
assignToField(context.receiverFieldName, context.receiverFieldName.makeRef(), psiElement)
}
@@ -117,7 +117,7 @@ class CoroutineFunctionTransformer(private val program: JsProgram, private val f
propertyInitializers +=
JsPropertyInitializer(JsNameRef(Namer.METADATA_CLASS_KIND),
JsNameRef(Namer.CLASS_KIND_CLASS, JsNameRef(Namer.CLASS_KIND_ENUM, Namer.KOTLIN_NAME)))
propertyInitializers += JsPropertyInitializer(JsNameRef(Namer.METADATA_SIMPLE_NAME), JsLiteral.NULL)
propertyInitializers += JsPropertyInitializer(JsNameRef(Namer.METADATA_SIMPLE_NAME), JsNullLiteral())
propertyInitializers += JsPropertyInitializer(JsNameRef(Namer.METADATA_SUPERTYPES), JsArrayLiteral(listOf(baseClassRefRef)))
}
@@ -150,13 +150,13 @@ class CoroutineFunctionTransformer(private val program: JsProgram, private val f
val psiElement = context.metadata.psiElement
val instantiation = JsNew(className.makeRef()).apply { source = psiElement }
if (context.metadata.hasReceiver) {
instantiation.arguments += JsLiteral.THIS
instantiation.arguments += JsThisRef()
}
val parameters = function.parameters + innerFunction?.parameters.orEmpty()
instantiation.arguments += parameters.dropLast(1).map { it.name.makeRef() }
if (function.coroutineMetadata!!.hasController) {
instantiation.arguments += JsLiteral.THIS
instantiation.arguments += JsThisRef()
}
instantiation.arguments += parameters.last().name.makeRef()
@@ -167,7 +167,7 @@ class CoroutineFunctionTransformer(private val program: JsProgram, private val f
val instanceName = JsScope.declareTemporaryName("instance")
functionWithBody.body.statements += JsAstUtils.newVar(instanceName, instantiation)
val invokeResume = JsReturn(JsInvocation(JsNameRef(context.metadata.doResumeName, instanceName.makeRef()), JsLiteral.NULL)
val invokeResume = JsReturn(JsInvocation(JsNameRef(context.metadata.doResumeName, instanceName.makeRef()), JsNullLiteral())
.source(psiElement))
functionWithBody.body.statements += JsIf(
@@ -181,28 +181,28 @@ class CoroutineFunctionTransformer(private val program: JsProgram, private val f
blocks: List<CoroutineBlock>
): List<JsStatement> {
val indexOfGlobalCatch = blocks.indexOf(context.globalCatchBlock)
val stateRef = JsNameRef(context.metadata.stateName, JsLiteral.THIS)
val stateRef = JsNameRef(context.metadata.stateName, JsThisRef())
val isFromGlobalCatch = JsAstUtils.equality(stateRef, program.getNumberLiteral(indexOfGlobalCatch))
val isFromGlobalCatch = JsAstUtils.equality(stateRef, JsIntLiteral(indexOfGlobalCatch))
val catch = JsCatch(functionWithBody.scope, "e")
val continueWithException = JsBlock(
JsAstUtils.assignment(stateRef.deepCopy(), JsNameRef(context.metadata.exceptionStateName, JsLiteral.THIS)).makeStmt(),
JsAstUtils.assignment(JsNameRef(context.metadata.exceptionName, JsLiteral.THIS),
JsAstUtils.assignment(stateRef.deepCopy(), JsNameRef(context.metadata.exceptionStateName, JsThisRef())).makeStmt(),
JsAstUtils.assignment(JsNameRef(context.metadata.exceptionName, JsThisRef()),
catch.parameter.name.makeRef()).makeStmt()
)
catch.body = JsBlock(JsIf(isFromGlobalCatch, JsThrow(catch.parameter.name.makeRef()), continueWithException))
val throwResultRef = JsNameRef(context.metadata.exceptionName, JsLiteral.THIS)
val throwResultRef = JsNameRef(context.metadata.exceptionName, JsThisRef())
context.globalCatchBlock.statements += JsThrow(throwResultRef)
val cases = blocks.withIndex().map { (index, block) ->
JsCase().apply {
caseExpression = program.getNumberLiteral(index)
caseExpression = JsIntLiteral(index)
statements += block.statements
}
}
val switchStatement = JsSwitch(stateRef.deepCopy(), cases)
val loop = JsDoWhile(JsLiteral.TRUE, JsTry(JsBlock(switchStatement), catch, null))
val loop = JsDoWhile(JsBooleanLiteral(true), JsTry(JsBlock(switchStatement), catch, null))
return listOf(loop)
}
@@ -217,7 +217,7 @@ class CoroutineFunctionTransformer(private val program: JsProgram, private val f
}
private fun MutableList<JsStatement>.assignToField(fieldName: JsName, value: JsExpression, psiElement: PsiElement?) {
this += JsAstUtils.assignment(JsNameRef(fieldName, JsLiteral.THIS), value).source(psiElement).makeStmt()
this += JsAstUtils.assignment(JsNameRef(fieldName, JsThisRef()), value).source(psiElement).makeStmt()
}
private fun MutableList<JsStatement>.assignToPrototype(fieldName: JsName, value: JsExpression) {
@@ -113,7 +113,7 @@ fun JsNode.collectNodesToSplit(breakContinueTargets: Map<JsContinue, JsStatement
return nodes
}
fun List<CoroutineBlock>.replaceCoroutineFlowStatements(context: CoroutineTransformationContext, program: JsProgram) {
fun List<CoroutineBlock>.replaceCoroutineFlowStatements(context: CoroutineTransformationContext) {
val blockIndexes = withIndex().associate { (index, block) -> Pair(block, index) }
val blockReplacementVisitor = object : JsVisitorWithContextImpl() {
@@ -121,7 +121,7 @@ fun List<CoroutineBlock>.replaceCoroutineFlowStatements(context: CoroutineTransf
val target = x.targetBlock
if (target != null) {
val lhs = JsNameRef(context.metadata.stateName, JsAstUtils.stateMachineReceiver())
val rhs = program.getNumberLiteral(blockIndexes[target]!!)
val rhs = JsIntLiteral(blockIndexes[target]!!)
ctx.replaceMe(JsExpressionStatement(JsAstUtils.assignment(lhs, rhs).source(x.source)).apply {
targetBlock = true
})
@@ -130,7 +130,7 @@ fun List<CoroutineBlock>.replaceCoroutineFlowStatements(context: CoroutineTransf
val exceptionTarget = x.targetExceptionBlock
if (exceptionTarget != null) {
val lhs = JsNameRef(context.metadata.exceptionStateName, JsAstUtils.stateMachineReceiver())
val rhs = program.getNumberLiteral(blockIndexes[exceptionTarget]!!)
val rhs = JsIntLiteral(blockIndexes[exceptionTarget]!!)
ctx.replaceMe(JsExpressionStatement(JsAstUtils.assignment(lhs, rhs).source(x.source)).apply {
targetExceptionBlock = true
})
@@ -140,7 +140,7 @@ fun List<CoroutineBlock>.replaceCoroutineFlowStatements(context: CoroutineTransf
if (finallyPath != null) {
if (finallyPath.isNotEmpty()) {
val lhs = JsNameRef(context.metadata.finallyPathName, JsAstUtils.stateMachineReceiver())
val rhs = JsArrayLiteral(finallyPath.map { program.getNumberLiteral(blockIndexes[it]!!) })
val rhs = JsArrayLiteral(finallyPath.map { JsIntLiteral(blockIndexes[it]!!) })
ctx.replaceMe(JsExpressionStatement(JsAstUtils.assignment(lhs, rhs).source(x.source)).apply {
this.finallyPath = true
})
@@ -208,8 +208,8 @@ private fun CoroutineBlock.collectFinallyPaths(): List<List<CoroutineBlock>> {
fun JsBlock.replaceSpecialReferences(context: CoroutineTransformationContext) {
val visitor = object : JsVisitorWithContextImpl() {
override fun endVisit(x: JsLiteral.JsThisRef, ctx: JsContext<in JsNode>) {
ctx.replaceMe(JsNameRef(context.receiverFieldName, JsLiteral.THIS))
override fun endVisit(x: JsThisRef, ctx: JsContext<in JsNode>) {
ctx.replaceMe(JsNameRef(context.receiverFieldName, JsThisRef()))
}
override fun visit(x: JsFunction, ctx: JsContext<*>) = false
@@ -217,7 +217,7 @@ fun JsBlock.replaceSpecialReferences(context: CoroutineTransformationContext) {
override fun endVisit(x: JsNameRef, ctx: JsContext<in JsNode>) {
when {
x.coroutineReceiver -> {
ctx.replaceMe(JsLiteral.THIS)
ctx.replaceMe(JsThisRef())
}
x.coroutineController -> {
@@ -254,7 +254,7 @@ fun JsBlock.replaceLocalVariables(context: CoroutineTransformationContext, local
val nameMap = freeVars.associate { it to JsScope.declareTemporaryName(it.ident) }
for (freeVar in freeVars) {
wrapperFunction.parameters += JsParameter(nameMap[freeVar]!!)
wrapperInvocation.arguments += JsNameRef(context.getFieldName(freeVar), JsLiteral.THIS)
wrapperInvocation.arguments += JsNameRef(context.getFieldName(freeVar), JsThisRef())
}
x.body = replaceNames(x.body, nameMap.mapValues { it.value.makeRef() })
ctx.replaceMe(wrapperInvocation)
@@ -264,7 +264,7 @@ fun JsBlock.replaceLocalVariables(context: CoroutineTransformationContext, local
override fun endVisit(x: JsNameRef, ctx: JsContext<in JsNode>) {
if (x.qualifier == null && x.name in localVariables) {
val fieldName = context.getFieldName(x.name!!)
ctx.replaceMe(JsNameRef(fieldName, JsLiteral.THIS).source(x.source))
ctx.replaceMe(JsNameRef(fieldName, JsThisRef()).source(x.source))
}
}
@@ -273,7 +273,7 @@ fun JsBlock.replaceLocalVariables(context: CoroutineTransformationContext, local
val fieldName = context.getFieldName(it.name)
val initExpression = it.initExpression
if (initExpression != null) {
JsAstUtils.assignment(JsNameRef(fieldName, JsLiteral.THIS), it.initExpression)
JsAstUtils.assignment(JsNameRef(fieldName, JsThisRef()), it.initExpression)
}
else {
null
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.js.backend.ast.metadata.coroutineMetadata
import org.jetbrains.kotlin.js.translate.expression.InlineMetadata
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
class CoroutineTransformer(private val program: JsProgram) : JsVisitorWithContextImpl() {
class CoroutineTransformer() : JsVisitorWithContextImpl() {
private val additionalStatementsByNode = mutableMapOf<JsNode, List<JsStatement>>()
override fun endVisit(x: JsExpressionStatement, ctx: JsContext<in JsStatement>) {
@@ -44,13 +44,13 @@ class CoroutineTransformer(private val program: JsProgram) : JsVisitorWithContex
val function = rhs as? JsFunction ?: InlineMetadata.decompose(rhs)?.function
if (function?.coroutineMetadata != null) {
val name = ((lhs as? JsNameRef)?.name ?: function.name)?.ident
additionalStatementsByNode[x] = CoroutineFunctionTransformer(program, function, name).transform()
additionalStatementsByNode[x] = CoroutineFunctionTransformer(function, name).transform()
return false
}
}
else if (expression is JsFunction) {
if (expression.coroutineMetadata != null) {
additionalStatementsByNode[x] = CoroutineFunctionTransformer(program, expression, expression.name?.ident).transform()
additionalStatementsByNode[x] = CoroutineFunctionTransformer(expression, expression.name?.ident).transform()
return false
}
}
@@ -63,7 +63,7 @@ class CoroutineTransformer(private val program: JsProgram) : JsVisitorWithContex
val function = initExpression as? JsFunction ?: InlineMetadata.decompose(initExpression)?.function
if (function?.coroutineMetadata != null) {
val name = x.name.ident
additionalStatementsByNode[x] = CoroutineFunctionTransformer(program, function, name).transform()
additionalStatementsByNode[x] = CoroutineFunctionTransformer(function, name).transform()
return false
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -139,7 +139,7 @@ internal class ExpressionDecomposer private constructor(
}
body = additionalStatements.toStatement()
test = JsLiteral.TRUE
test = JsBooleanLiteral(true)
}
}
@@ -404,8 +404,8 @@ internal open class JsExpressionVisitor() : JsVisitorWithContextImpl() {
override fun visit(x: JsCase, ctx: JsContext<JsNode>): Boolean = false
override fun visit(x: JsDefault, ctx: JsContext<JsNode>): Boolean = false
override fun visit(x: JsEmpty, ctx: JsContext<JsNode>): Boolean = false
override fun visit(x: JsLiteral.JsBooleanLiteral, ctx: JsContext<JsNode>): Boolean = false
override fun visit(x: JsLiteral.JsThisRef, ctx: JsContext<JsNode>): Boolean = false
override fun visit(x: JsBooleanLiteral, ctx: JsContext<JsNode>): Boolean = false
override fun visit(x: JsThisRef, ctx: JsContext<JsNode>): Boolean = false
override fun visit(x: JsNullLiteral, ctx: JsContext<JsNode>): Boolean = false
override fun visit(x: JsNumberLiteral, ctx: JsContext<JsNode>): Boolean = false
override fun visit(x: JsRegExp, ctx: JsContext<JsNode>): Boolean = false
@@ -97,7 +97,7 @@ private constructor(
if (!hasThisReference(block)) return
var thisReplacement = getThisReplacement(call)
if (thisReplacement == null || thisReplacement is JsLiteral.JsThisRef) return
if (thisReplacement == null || thisReplacement is JsThisRef) return
val thisName = JsScope.declareTemporaryName(getThisAlias())
namingContext.newVar(thisName, thisReplacement)
@@ -195,7 +195,7 @@ private constructor(
}
private fun hasThisReference(body: JsBlock): Boolean {
val thisRefs = collectInstances(JsLiteral.JsThisRef::class.java, body)
val thisRefs = collectInstances(JsThisRef::class.java, body)
return !thisRefs.isEmpty()
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -78,7 +78,7 @@ internal class DeadCodeElimination(private val root: JsStatement) {
visitLoop(x.body) {
val condition = x.condition
condition !is JsLiteral.JsBooleanLiteral || !condition.value
condition !is JsBooleanLiteral || !condition.value
}
}
@@ -30,7 +30,7 @@ object LabeledBlockToDoWhileTransformation {
object : JsVisitorWithContextImpl() {
override fun endVisit(x: JsLabel, ctx: JsContext<JsNode>) {
if (x.statement is JsBlock) {
x.statement = JsDoWhile(JsLiteral.FALSE, x.statement)
x.statement = JsDoWhile(JsBooleanLiteral(false), x.statement)
}
super.endVisit(x, ctx)
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic
import org.jetbrains.kotlin.js.inline.util.collectFreeVariables
import org.jetbrains.kotlin.js.inline.util.collectLocalVariables
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.js.translate.utils.splitToRanges
@@ -165,7 +166,7 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
useVariable(name)
if (name !in currentScope) {
// Variable is inconsistent, i.e. it's defined after it's used.
assignVariable(name, JsLiteral.UNDEFINED)
assignVariable(name, Namer.getUndefinedExpression())
}
return
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -66,8 +66,8 @@ class WhileConditionFolding(val body: JsBlock) {
if (condition != null) {
statement.body = remove(statement.body)
val existingCondition = statement.condition
statement.condition = when (existingCondition) {
JsLiteral.TRUE -> condition
statement.condition = when {
JsLiteral.isTrueBoolean(existingCondition) -> condition
else -> combine(existingCondition, condition)
}
changed = true
@@ -105,7 +105,7 @@ class WhileConditionFolding(val body: JsBlock) {
// therefore for single `break` we should return `false`.
is JsBreak -> {
val target = statement.label?.name
if (label == target) JsLiteral.FALSE else null
if (label == target) JsBooleanLiteral(false) else null
}
// Code like this
@@ -138,11 +138,11 @@ class WhileConditionFolding(val body: JsBlock) {
val then = statement.thenStatement
if (statement.elseStatement == null) {
val nextCondition = extractCondition(then, label)
val result: JsExpression? = when (nextCondition) {
val result: JsExpression? = when {
// Just a little optimization. When inner statement is a single `break`, `nextCondition` would be false.
// However, `A || false` can be rewritten as simply `A`
JsLiteral.FALSE -> JsAstUtils.notOptimized(statement.ifExpression)
null -> null
nextCondition == null -> null
JsLiteral.isFalseBoolean(nextCondition) -> JsAstUtils.notOptimized(statement.ifExpression)
else -> JsAstUtils.or(JsAstUtils.notOptimized(statement.ifExpression), nextCondition)
}
result
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.js.inline.util.rewriters
import org.jetbrains.kotlin.js.backend.ast.*
class ThisReplacingVisitor(private val thisReplacement: JsExpression) : JsVisitorWithContextImpl() {
override fun endVisit(x: JsLiteral.JsThisRef, ctx: JsContext<JsNode>) {
override fun endVisit(x: JsThisRef, ctx: JsContext<JsNode>) {
ctx.replaceMe(thisReplacement)
}
@@ -16,7 +16,7 @@
package com.google.gwt.dev.js;
import org.jetbrains.kotlin.js.backend.ast.*;
import org.jetbrains.kotlin.js.backend.ast.JsLiteral.JsBooleanLiteral;
import org.jetbrains.kotlin.js.backend.ast.JsBooleanLiteral;
import org.jetbrains.kotlin.js.backend.ast.metadata.HasMetadata;
import com.google.gwt.dev.js.parserExceptions.JsParserException;
import com.google.gwt.dev.js.rhino.*;
@@ -29,7 +29,6 @@ import java.util.List;
public class JsAstMapper {
private final JsProgram program;
private final ScopeContext scopeContext;
@NotNull
@@ -37,7 +36,6 @@ public class JsAstMapper {
public JsAstMapper(@NotNull JsScope scope, @NotNull String fileName) {
scopeContext = new ScopeContext(scope);
program = scope.getProgram();
this.fileName = fileName;
}
@@ -126,7 +124,7 @@ public class JsAstMapper {
return mapConditional(node);
case TokenStream.STRING:
return program.getStringLiteral(node.getString());
return new JsStringLiteral(node.getString());
case TokenStream.NUMBER_INT:
return mapIntNumber(node);
@@ -348,7 +346,7 @@ public class JsAstMapper {
// Iterate over and map the arguments.
//
List<JsExpression> arguments = new SmartList<JsExpression>();
List<JsExpression> arguments = new SmartList<>();
from = from.getNext();
while (from != null) {
arguments.add(mapExpression(from));
@@ -696,12 +694,12 @@ public class JsAstMapper {
return newExpr;
}
private JsExpression mapIntNumber(Node numberNode) {
return program.getNumberLiteral((int) numberNode.getDouble());
private static JsExpression mapIntNumber(Node numberNode) {
return new JsIntLiteral((int) numberNode.getDouble());
}
private JsExpression mapDoubleNumber(Node numberNode) {
return program.getNumberLiteral(numberNode.getDouble());
private static JsExpression mapDoubleNumber(Node numberNode) {
return new JsDoubleLiteral(numberNode.getDouble());
}
private JsExpression mapObjectLit(Node objLitNode) throws JsParserException {
@@ -762,22 +760,22 @@ public class JsAstMapper {
return new JsPrefixOperation(op, to);
}
private JsExpression mapPrimary(Node node) throws JsParserException {
private static JsExpression mapPrimary(Node node) throws JsParserException {
switch (node.getIntDatum()) {
case TokenStream.THIS:
return JsLiteral.THIS;
return new JsThisRef();
case TokenStream.TRUE:
return JsBooleanLiteral.TRUE;
return new JsBooleanLiteral(true);
case TokenStream.FALSE:
return JsBooleanLiteral.FALSE;
return new JsBooleanLiteral(false);
case TokenStream.NULL:
return JsNullLiteral.NULL;
return new JsNullLiteral();
case TokenStream.UNDEFINED:
return JsLiteral.UNDEFINED;
return new JsNameRef("undefined");
default:
throw createParserException("Unknown primary: " + node.getIntDatum(),
@@ -926,7 +924,7 @@ public class JsAstMapper {
public List<JsStatement> mapStatements(Node nodeStmts)
throws JsParserException {
List<JsStatement> stmts = new ArrayList<JsStatement>();
List<JsStatement> stmts = new ArrayList<>();
mapStatements(stmts, nodeStmts);
return stmts;
}
@@ -19,14 +19,14 @@ package org.jetbrains.kotlin.serialization.js.ast
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.backend.ast.metadata.*
import org.jetbrains.kotlin.protobuf.CodedInputStream
import org.jetbrains.kotlin.resolve.inline.InlineStrategy as KotlinInlineStrategy
import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.*
import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.Expression.ExpressionCase
import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.Statement.StatementCase
import java.io.InputStream
import java.util.*
import org.jetbrains.kotlin.resolve.inline.InlineStrategy as KotlinInlineStrategy
class JsAstDeserializer(private val program: JsProgram) {
class JsAstDeserializer(program: JsProgram) {
private val scope = JsRootScope(program)
private val stringTable = mutableListOf<String>()
private val nameTable = mutableListOf<Name>()
@@ -263,13 +263,13 @@ class JsAstDeserializer(private val program: JsProgram) {
}
private fun deserializeNoMetadata(proto: Expression): JsExpression = when (proto.expressionCase) {
ExpressionCase.THIS_LITERAL -> JsLiteral.THIS
ExpressionCase.NULL_LITERAL -> JsLiteral.NULL
ExpressionCase.TRUE_LITERAL -> JsLiteral.TRUE
ExpressionCase.FALSE_LITERAL -> JsLiteral.FALSE
ExpressionCase.STRING_LITERAL -> program.getStringLiteral(deserializeString(proto.stringLiteral))
ExpressionCase.INT_LITERAL -> program.getNumberLiteral(proto.intLiteral)
ExpressionCase.DOUBLE_LITERAL -> program.getNumberLiteral(proto.doubleLiteral)
ExpressionCase.THIS_LITERAL -> JsThisRef()
ExpressionCase.NULL_LITERAL -> JsNullLiteral()
ExpressionCase.TRUE_LITERAL -> JsBooleanLiteral(true)
ExpressionCase.FALSE_LITERAL -> JsBooleanLiteral(false)
ExpressionCase.STRING_LITERAL -> JsStringLiteral(deserializeString(proto.stringLiteral))
ExpressionCase.INT_LITERAL -> JsIntLiteral(proto.intLiteral)
ExpressionCase.DOUBLE_LITERAL -> JsDoubleLiteral(proto.doubleLiteral)
ExpressionCase.SIMPLE_NAME_REFERENCE -> JsNameRef(deserializeName(proto.simpleNameReference))
ExpressionCase.REG_EXP_LITERAL -> {
@@ -510,9 +510,7 @@ class JsAstDeserializer(private val program: JsProgram) {
}
val node = action()
if (deserializedLocation != null) {
if (node !is JsLiteral.JsBooleanLiteral && node !is JsLiteral.JsThisRef && node !is JsNullLiteral) {
node.source = deserializedLocation
}
node.source = deserializedLocation
}
if (shouldUpdateFile) {
fileStack.pop()
@@ -271,7 +271,7 @@ class JsAstSerializer {
val visitor = object : JsVisitor() {
val builder = Expression.newBuilder()
override fun visitThis(x: JsLiteral.JsThisRef) {
override fun visitThis(x: JsThisRef) {
builder.thisLiteral = ThisLiteral.newBuilder().build()
}
@@ -279,7 +279,7 @@ class JsAstSerializer {
builder.nullLiteral = NullLiteral.newBuilder().build()
}
override fun visitBoolean(x: JsLiteral.JsBooleanLiteral) {
override fun visitBoolean(x: JsBooleanLiteral) {
if (x.value) {
builder.trueLiteral = TrueLiteral.newBuilder().build()
}
@@ -299,11 +299,11 @@ class JsAstSerializer {
builder.regExpLiteral = regExpBuilder.build()
}
override fun visitInt(x: JsNumberLiteral.JsIntLiteral) {
override fun visitInt(x: JsIntLiteral) {
builder.intLiteral = x.value
}
override fun visitDouble(x: JsNumberLiteral.JsDoubleLiteral) {
override fun visitDouble(x: JsDoubleLiteral) {
builder.doubleLiteral = x.value
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -243,7 +243,7 @@ public class DirectiveTestUtils {
if (name.getIdent().equals(nameToSearch)) {
hasReferences = true;
if (!(nameRef.getQualifier() instanceof JsLiteral.JsThisRef)) {
if (!(nameRef.getQualifier() instanceof JsThisRef)) {
allReferencesQualifiedByThis = false;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -127,7 +127,7 @@ public final class K2JSTranslator {
LabeledBlockToDoWhileTransformation.INSTANCE.apply(newFragments);
CoroutineTransformer coroutineTransformer = new CoroutineTransformer(translationResult.getProgram());
CoroutineTransformer coroutineTransformer = new CoroutineTransformer();
for (JsProgramFragment fragment : newFragments) {
coroutineTransformer.accept(fragment.getDeclarationBlock());
coroutineTransformer.accept(fragment.getInitializerBlock());
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -57,7 +57,7 @@ public class JsSourceGenerationVisitor extends JsToStringGenerationVisitor imple
@Override
public void accept(JsNode node) {
if (!(node instanceof JsNameRef) && !(node instanceof JsLiteral.JsThisRef)) {
if (!(node instanceof JsNameRef) && !(node instanceof JsThisRef)) {
mapSource(node);
}
super.accept(node);
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.js.backend.ast.JsBlock
import org.jetbrains.kotlin.js.backend.ast.JsConditional
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsLiteral
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.reference.CallArgumentTranslator
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
@@ -143,11 +140,11 @@ private fun TranslationContext.createCallInfo(
if (resolvedCall.call.isSafeCall()) {
when (resolvedCall.explicitReceiverKind) {
BOTH_RECEIVERS, EXTENSION_RECEIVER -> {
notNullConditional = TranslationUtils.notNullConditional(extensionReceiver!!, JsLiteral.NULL, this)
notNullConditional = TranslationUtils.notNullConditional(extensionReceiver!!, JsNullLiteral(), this)
extensionReceiver = notNullConditional.thenExpression
}
else -> {
notNullConditional = TranslationUtils.notNullConditional(dispatchReceiver!!, JsLiteral.NULL, this)
notNullConditional = TranslationUtils.notNullConditional(dispatchReceiver!!, JsNullLiteral(), this)
dispatchReceiver = notNullConditional.thenExpression
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -16,15 +16,12 @@
package org.jetbrains.kotlin.js.translate.callTranslator
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsInvocation
import org.jetbrains.kotlin.js.backend.ast.JsNameRef
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.js.backend.ast.JsLiteral
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor
import org.jetbrains.kotlin.js.translate.declaration.contextWithPropertyMetadataCreationIntrinsified
@@ -106,7 +103,7 @@ object DefaultVariableAccessCase : VariableAccessCase() {
val delegatedCall = accessorDescriptor?.let { context.bindingContext()[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, it] }
if (delegatedCall != null) {
val delegateContext = context.contextWithPropertyMetadataCreationIntrinsified(
delegatedCall, localVariableDescriptor!!, JsLiteral.NULL)
delegatedCall, localVariableDescriptor!!, JsNullLiteral())
val delegateContextWithArgs = if (!isGetAccess()) {
val valueArg = delegatedCall.valueArgumentsByIndex!![2].arguments[0].getArgumentExpression()
delegateContext.innerContextWithAliasesForExpressions(mapOf(valueArg to value!!))
@@ -176,7 +173,7 @@ object DelegatePropertyAccessIntrinsic : DelegateIntrinsic<VariableAccessInfo> {
object SuperPropertyAccessCase : VariableAccessCase() {
override fun VariableAccessInfo.dispatchReceiver(): JsExpression {
val variableName = context.program().getStringLiteral(this.variableName.ident)
val variableName = JsStringLiteral(this.variableName.ident)
val descriptor = resolvedCall.resultingDescriptor
return if (descriptor is PropertyDescriptor && TranslationUtils.shouldAccessViaFunctions(descriptor)) {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -89,7 +89,7 @@ internal class DeclarationExporter(val context: StaticContext) {
private fun exportObject(declaration: ClassDescriptor, qualifier: JsExpression) {
val name = context.getNameForDescriptor(declaration)
val expression = JsAstUtils.defineGetter(context.program, qualifier, name.ident,
val expression = JsAstUtils.defineGetter(qualifier, name.ident,
context.getNameForObjectInstance(declaration).makeRef())
statements += expression.exportStatement(declaration)
}
@@ -128,7 +128,7 @@ internal class DeclarationExporter(val context: StaticContext) {
propertyLiteral.propertyInitializers += JsPropertyInitializer(JsNameRef("set"), setterBody)
}
statements += JsAstUtils.defineProperty(qualifier, name, propertyLiteral, context.program).exportStatement(declaration)
statements += JsAstUtils.defineProperty(qualifier, name, propertyLiteral).exportStatement(declaration)
}
private fun getLocalPackageReference(packageName: FqName): JsExpression {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -162,7 +162,7 @@ public final class Namer {
@NotNull
public static JsNameRef getDelegateNameRef(String propertyName) {
return new JsNameRef(getDelegateName(propertyName), JsLiteral.THIS);
return new JsNameRef(getDelegateName(propertyName), new JsThisRef());
}
@NotNull
@@ -331,7 +331,7 @@ public final class Namer {
@NotNull
public static JsExpression getUndefinedExpression() {
return new JsPrefixOperation(JsUnaryOperator.VOID, JsNumberLiteral.ZERO);
return new JsPrefixOperation(JsUnaryOperator.VOID, new JsIntLiteral(0));
}
@NotNull
@@ -408,7 +408,7 @@ public class TranslationContext {
if (DescriptorUtils.isObject(descriptor.getContainingDeclaration())) {
if (isConstructorOrDirectScope(descriptor.getContainingDeclaration())) {
return JsLiteral.THIS;
return new JsThisRef();
}
else {
ClassDescriptor objectDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
@@ -416,7 +416,7 @@ public class TranslationContext {
}
}
if (descriptor.getValue() instanceof ExtensionReceiver) return JsLiteral.THIS;
if (descriptor.getValue() instanceof ExtensionReceiver) return new JsThisRef();
ClassifierDescriptor classifier = descriptor.getValue().getType().getConstructor().getDeclarationDescriptor();
@@ -428,7 +428,7 @@ public class TranslationContext {
assert classDescriptor != null : "Can't get ReceiverParameterDescriptor in top level";
JsExpression receiver = getAliasForDescriptor(classDescriptor.getThisAsReceiverParameter());
if (receiver == null) {
receiver = JsLiteral.THIS;
receiver = new JsThisRef();
}
return getDispatchReceiverPath(cls, receiver);
@@ -468,7 +468,7 @@ public class TranslationContext {
if (name != null) {
JsExpression result;
if (shouldCaptureViaThis()) {
result = JsLiteral.THIS;
result = new JsThisRef();
int depth = getOuterLocalClassDepth();
for (int i = 0; i < depth; ++i) {
result = new JsNameRef(Namer.OUTER_FIELD_NAME, result);
@@ -573,7 +573,7 @@ public class TranslationContext {
return getDispatchReceiver((ReceiverParameterDescriptor) descriptor);
}
if (isCoroutineLambda(descriptor)) {
return JsLiteral.THIS;
return new JsThisRef();
}
return getNameForDescriptor(descriptor).makeRef();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -192,7 +192,7 @@ class ClassModelGenerator(val context: StaticContext) {
val sourceName = context.getNameForDescriptor(key).ident
val targetName = context.getNameForDescriptor(value).ident
if (sourceName != targetName) {
val statement = generateDelegateCall(descriptor, key, value, JsLiteral.THIS, translationContext, false)
val statement = generateDelegateCall(descriptor, key, value, JsThisRef(), translationContext, false)
model.postDeclarationBlock.statements += statement
}
}
@@ -228,7 +228,7 @@ class ClassModelGenerator(val context: StaticContext) {
}
val translationContext = TranslationContext.rootContext(context)
model.postDeclarationBlock.statements += generateDelegateCall(descriptor, fromDescriptor, toDescriptor, JsLiteral.THIS,
model.postDeclarationBlock.statements += generateDelegateCall(descriptor, fromDescriptor, toDescriptor, JsThisRef(),
translationContext, false)
}
@@ -258,10 +258,10 @@ class ClassModelGenerator(val context: StaticContext) {
val targetPrototype = prototypeOf(pureFqn(context.getInnerNameForDescriptor(targetDescriptor), null))
val sourcePrototype = prototypeOf(pureFqn(context.getInnerNameForDescriptor(sourceDescriptor), null))
val nameLiteral = context.program.getStringLiteral(name)
val nameLiteral = JsStringLiteral(name)
val getPropertyDescriptor = JsInvocation(JsNameRef("getOwnPropertyDescriptor", "Object"), sourcePrototype, nameLiteral)
val defineProperty = JsAstUtils.defineProperty(targetPrototype, name, getPropertyDescriptor, context.program)
val defineProperty = JsAstUtils.defineProperty(targetPrototype, name, getPropertyDescriptor)
block.statements += defineProperty.makeStmt()
}
@@ -188,7 +188,7 @@ class ClassTranslator private constructor(
val simpleName = descriptor.name
if (!simpleName.isSpecial) {
val simpleNameProp = JsPropertyInitializer(JsNameRef(Namer.METADATA_SIMPLE_NAME), program().getStringLiteral(simpleName.identifier))
val simpleNameProp = JsPropertyInitializer(JsNameRef(Namer.METADATA_SIMPLE_NAME), JsStringLiteral(simpleName.identifier))
metadataLiteral.propertyInitializers += simpleNameProp
}
}
@@ -445,11 +445,11 @@ class ClassTranslator private constructor(
private fun addObjectCache(statements: MutableList<JsStatement>) {
cachedInstanceName = JsScope.declareTemporaryName(StaticContext.getSuggestedName(descriptor) + Namer.OBJECT_INSTANCE_VAR_SUFFIX)
statements += JsAstUtils.assignment(cachedInstanceName.makeRef(), JsObjectLiteral.THIS).source(classDeclaration).makeStmt()
statements += JsAstUtils.assignment(cachedInstanceName.makeRef(), JsThisRef()).source(classDeclaration).makeStmt()
}
private fun addObjectMethods() {
context().addDeclarationStatement(JsAstUtils.newVar(cachedInstanceName, JsLiteral.NULL))
context().addDeclarationStatement(JsAstUtils.newVar(cachedInstanceName, JsNullLiteral()))
val instanceFun = context().createRootScopedFunction("Instance function: " + descriptor)
instanceFun.name = context().getNameForObjectInstance(descriptor)
@@ -458,7 +458,7 @@ class ClassTranslator private constructor(
instanceFun.body.statements += JsInvocation(pureFqn(enumInitializerName, null)).makeStmt()
}
if (descriptor.kind != ClassKind.ENUM_ENTRY) {
val instanceCreatedCondition = JsAstUtils.equality(cachedInstanceName.makeRef(), JsLiteral.NULL)
val instanceCreatedCondition = JsAstUtils.equality(cachedInstanceName.makeRef(), JsNullLiteral())
val instanceCreationBlock = JsBlock()
val instanceCreatedGuard = JsIf(instanceCreatedCondition, instanceCreationBlock)
instanceFun.body.statements += instanceCreatedGuard
@@ -484,11 +484,11 @@ class ClassTranslator private constructor(
.map { DescriptorUtils.getPropertyByName(descriptor.unsubstitutedMemberScope, it) }
.filter { !it.kind.isReal }
for (property in properties) {
val propertyTranslator = DefaultPropertyTranslator(property, context, JsLiteral.NULL)
val propertyTranslator = DefaultPropertyTranslator(property, context, JsNullLiteral())
val literal = JsObjectLiteral(true)
val getterFunction = context.getFunctionObject(property.getter!!)
propertyTranslator.generateDefaultGetterFunction(property.getter!!, getterFunction)
literal.propertyInitializers += JsPropertyInitializer(context.program().getStringLiteral("get"), getterFunction)
literal.propertyInitializers += JsPropertyInitializer(JsStringLiteral("get"), getterFunction)
context.addAccessorsToPrototype(descriptor, property, literal)
}
}
@@ -120,7 +120,7 @@ class DeclarationBodyVisitor(
.innerBlock(caller.body)
val callbackName = JsScope.declareTemporaryName("callback" + Namer.DEFAULT_PARAMETER_IMPLEMENTOR_SUFFIX)
val callee = JsNameRef(bodyName, JsLiteral.THIS)
val callee = JsNameRef(bodyName, JsThisRef())
val defaultInvocation = JsInvocation(callee, listOf<JsExpression>())
val callbackInvocation = JsInvocation(callbackName.makeRef())
@@ -148,9 +148,9 @@ class DeclarationBodyVisitor(
override fun addProperty(descriptor: PropertyDescriptor, getter: JsExpression, setter: JsExpression?) {
if (!JsDescriptorUtils.isSimpleFinalProperty(descriptor)) {
val literal = JsObjectLiteral(true)
literal.propertyInitializers += JsPropertyInitializer(context.program().getStringLiteral("get"), getter)
literal.propertyInitializers += JsPropertyInitializer(JsStringLiteral("get"), getter)
if (setter != null) {
literal.propertyInitializers += JsPropertyInitializer(context.program().getStringLiteral("set"), setter)
literal.propertyInitializers += JsPropertyInitializer(JsStringLiteral("set"), setter)
}
context.addAccessorsToPrototype(containingClass, descriptor, literal)
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -76,7 +76,7 @@ class DelegationTranslator(
val context = context().innerBlock()
val delegateInitExpr = Translation.translateAsExpression(expression, context)
statements += context.dynamicContext().jsBlock().statements
val lhs = JsAstUtils.pureFqn(field.name, JsLiteral.THIS)
val lhs = JsAstUtils.pureFqn(field.name, JsThisRef())
statements += JsAstUtils.assignment(lhs, delegateInitExpr).makeStmt()
}
}
@@ -111,7 +111,7 @@ class DelegationTranslator(
val propertyName: String = descriptor.name.asString()
fun generateDelegateGetterFunction(getterDescriptor: PropertyGetterDescriptor): JsFunction {
val delegateRef = JsNameRef(delegateName, JsLiteral.THIS)
val delegateRef = JsNameRef(delegateName, JsThisRef())
val returnExpression: JsExpression = if (DescriptorUtils.isExtension(descriptor)) {
val getterName = context().getNameForDescriptor(getterDescriptor)
@@ -138,7 +138,7 @@ class DelegationTranslator(
val defaultParameter = JsParameter(JsScope.declareTemporary())
val defaultParameterRef = defaultParameter.name.makeRef()
val delegateRef = JsNameRef(delegateName, JsLiteral.THIS)
val delegateRef = JsNameRef(delegateName, JsThisRef())
// TODO: remove explicit type annotation when Kotlin compiler works this out
val setExpression: JsExpression = if (DescriptorUtils.isExtension(descriptor)) {
@@ -195,7 +195,7 @@ class DelegationTranslator(
overriddenDescriptor: FunctionDescriptor,
delegateName: JsName
) {
val delegateRef = JsNameRef(delegateName, JsLiteral.THIS)
val delegateRef = JsNameRef(delegateName, JsThisRef())
val statement = generateDelegateCall(classDescriptor, descriptor, overriddenDescriptor, delegateRef, context(), true)
context().addDeclarationStatement(statement)
}
@@ -55,15 +55,15 @@ class EnumTranslator(
val clauses = entries.map { entry ->
JsCase().apply {
caseExpression = context().program().getStringLiteral(entry.name.asString())
caseExpression = JsStringLiteral(entry.name.asString())
statements += JsReturn(JsInvocation(JsAstUtils.pureFqn(context().getNameForObjectInstance(entry), null)).source(psi))
source = psi
}
}
val message = JsBinaryOperation(JsBinaryOperator.ADD,
context().program().getStringLiteral("No enum constant ${descriptor.fqNameSafe}."),
nameParam.makeRef())
JsStringLiteral("No enum constant ${descriptor.fqNameSafe}."),
nameParam.makeRef())
val throwStatement = JsExpressionStatement(JsInvocation(Namer.throwIllegalStateExceptionFunRef(), message).source(psi))
if (clauses.isNotEmpty()) {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -50,7 +50,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
assert propertyDescriptor != null : "Property descriptor is expected to be non-null";
JsFunction functionObject = generateJsMethod(function);
JsExpression returnExpression = JsAstUtils.pureFqn(context.getNameForDescriptor(propertyDescriptor), JsLiteral.THIS);
JsExpression returnExpression = JsAstUtils.pureFqn(context.getNameForDescriptor(propertyDescriptor), new JsThisRef());
functionObject.getBody().getStatements().add(new JsReturn(returnExpression));
}
@@ -85,7 +85,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
}
else {
JsExpression defaultCondition = JsAstUtils.equality(new JsNameRef(paramName), Namer.getUndefinedExpression());
argumentValue = new JsConditional(defaultCondition, new JsNameRef(fieldName, JsLiteral.THIS), parameterValue);
argumentValue = new JsConditional(defaultCondition, new JsNameRef(fieldName, new JsThisRef()), parameterValue);
}
constructorArguments.add(argumentValue);
}
@@ -109,13 +109,12 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
assert !classProperties.isEmpty();
JsFunction functionObj = generateJsMethod(function);
JsProgram jsProgram = context.program();
JsExpression result = null;
for (int i = 0; i < classProperties.size(); i++) {
String printName = classProperties.get(i).getName().asString();
JsName name = context.getNameForDescriptor(classProperties.get(i));
JsExpression literal = jsProgram.getStringLiteral((i == 0 ? (getClassDescriptor().getName() + "(") : ", ") + printName + "=");
JsExpression expr = new JsInvocation(context.namer().kotlin("toString"), new JsNameRef(name, JsLiteral.THIS));
JsExpression literal = new JsStringLiteral((i == 0 ? (getClassDescriptor().getName() + "(") : ", ") + printName + "=");
JsExpression expr = new JsInvocation(context.namer().kotlin("toString"), new JsNameRef(name, new JsThisRef()));
JsExpression component = JsAstUtils.sum(literal, expr);
if (result == null) {
result = component;
@@ -125,7 +124,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
}
}
assert result != null;
result = JsAstUtils.sum(result, jsProgram.getStringLiteral(")"));
result = JsAstUtils.sum(result, new JsStringLiteral(")"));
functionObj.getBody().getStatements().add(new JsReturn(result));
}
@@ -133,21 +132,20 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
JsFunction functionObj = generateJsMethod(function);
JsProgram jsProgram = context.program();
List<JsStatement> statements = functionObj.getBody().getStatements();
JsName varName = functionObj.getScope().declareName("result");
statements.add(new JsVars(new JsVars.JsVar(varName, JsNumberLiteral.ZERO)));
statements.add(new JsVars(new JsVars.JsVar(varName, new JsIntLiteral(0))));
for (PropertyDescriptor prop : classProperties) {
// TODO: we should statically check that we can call hashCode method directly.
JsName name = context.getNameForDescriptor(prop);
JsExpression component = new JsInvocation(context.namer().kotlin("hashCode"), new JsNameRef(name, JsLiteral.THIS));
JsExpression newHashValue = JsAstUtils.sum(JsAstUtils.mul(new JsNameRef(varName), jsProgram.getNumberLiteral(31)), component);
JsExpression component = new JsInvocation(context.namer().kotlin("hashCode"), new JsNameRef(name, new JsThisRef()));
JsExpression newHashValue = JsAstUtils.sum(JsAstUtils.mul(new JsNameRef(varName), new JsIntLiteral(31)), component);
JsExpression assignment = JsAstUtils.assignment(new JsNameRef(varName),
new JsBinaryOperation(JsBinaryOperator.BIT_OR, newHashValue,
jsProgram.getNumberLiteral(0)));
new JsIntLiteral(0)));
statements.add(assignment.makeStmt());
}
@@ -163,18 +161,18 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
JsName paramName = funScope.declareName("other");
functionObj.getParameters().add(new JsParameter(paramName));
JsExpression referenceEqual = JsAstUtils.equality(JsLiteral.THIS, new JsNameRef(paramName));
JsExpression isNotNull = JsAstUtils.inequality(new JsNameRef(paramName), JsLiteral.NULL);
JsExpression otherIsObject = JsAstUtils.typeOfIs(paramName.makeRef(), context.program().getStringLiteral("object"));
JsExpression referenceEqual = JsAstUtils.equality(new JsThisRef(), new JsNameRef(paramName));
JsExpression isNotNull = JsAstUtils.inequality(new JsNameRef(paramName), new JsNullLiteral());
JsExpression otherIsObject = JsAstUtils.typeOfIs(paramName.makeRef(), new JsStringLiteral("object"));
JsExpression prototypeEqual =
JsAstUtils.equality(new JsInvocation(new JsNameRef("getPrototypeOf", new JsNameRef("Object")), JsLiteral.THIS),
JsAstUtils.equality(new JsInvocation(new JsNameRef("getPrototypeOf", new JsNameRef("Object")), new JsThisRef()),
new JsInvocation(new JsNameRef("getPrototypeOf", new JsNameRef("Object")), new JsNameRef(paramName)));
JsExpression fieldChain = null;
for (PropertyDescriptor prop : classProperties) {
JsName name = context.getNameForDescriptor(prop);
JsExpression next = new JsInvocation(context.namer().kotlin("equals"),
new JsNameRef(name, JsLiteral.THIS),
new JsNameRef(name, new JsThisRef()),
new JsNameRef(name, new JsNameRef(paramName)));
if (fieldChain == null) {
fieldChain = next;
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -151,7 +151,7 @@ class DefaultPropertyTranslator(
function.addParameter(getReceiverParameterName(), 0).name.makeRef()
}
else {
JsLiteral.THIS
JsThisRef()
}
}
}
@@ -163,7 +163,7 @@ fun TranslationContext.translateDelegateOrInitializerExpression(expression: KtPr
val initializer = Translation.translateAsExpression(expressionPsi, this)
val provideDelegateCall = bindingContext()[BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, propertyDescriptor]
return if (provideDelegateCall != null) {
val innerContext = this.contextWithPropertyMetadataCreationIntrinsified(provideDelegateCall, propertyDescriptor, JsLiteral.THIS)
val innerContext = this.contextWithPropertyMetadataCreationIntrinsified(provideDelegateCall, propertyDescriptor, JsThisRef())
CallTranslator.translate(innerContext, provideDelegateCall, initializer)
}
else {
@@ -176,7 +176,7 @@ fun TranslationContext.contextWithPropertyMetadataCreationIntrinsified(
property: VariableDescriptorWithAccessors,
host: JsExpression
): TranslationContext {
val propertyNameLiteral = program().getStringLiteral(property.name.asString())
val propertyNameLiteral = JsStringLiteral(property.name.asString())
// 0th argument is instance, 1st is KProperty, 2nd (for setter) is value
val hostExpression =
(delegatedCall.valueArgumentsByIndex!![0] as ExpressionValueArgument).valueArgument!!.getArgumentExpression()
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -126,7 +126,7 @@ class CatchTranslator(
translateAsStatementAndMergeInBlockIfNeeded(catchBody, context)
}
else {
JsAstUtils.asSyntheticStatement(JsLiteral.NULL)
JsAstUtils.asSyntheticStatement(JsNullLiteral())
}
return convertToBlock(jsCatchBody)
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -73,7 +73,7 @@ import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFun
public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@Override
protected JsNode emptyResult(@NotNull TranslationContext context) {
return JsLiteral.NULL;
return new JsNullLiteral();
}
@Override
@@ -221,7 +221,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
}
else if (isVarCapturedInClosure(context.bindingContext(), descriptor)) {
JsNameRef alias = getCapturedVarAccessor(name.makeRef());
initializer = JsAstUtils.wrapValue(alias, initializer == null ? JsLiteral.NULL : initializer);
initializer = JsAstUtils.wrapValue(alias, initializer == null ? new JsNullLiteral() : initializer);
}
return newVar(name, initializer).source(expression);
@@ -340,7 +340,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
}
assert value instanceof String : "Compile time constant template should be a String constant.";
String constantString = (String) value;
return context.program().getStringLiteral(constantString);
return new JsStringLiteral(constantString);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -27,8 +27,7 @@ class InlineMetadata(val tag: JsStringLiteral, val function: JsFunction) {
companion object {
@JvmStatic
fun compose(function: JsFunction, descriptor: CallableDescriptor, config: JsConfig): InlineMetadata {
val program = function.scope.program
val tag = program.getStringLiteral(Namer.getFunctionTag(descriptor, config))
val tag = JsStringLiteral(Namer.getFunctionTag(descriptor, config))
return InlineMetadata(tag, function)
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -53,14 +53,14 @@ fun createWhile(doWhile: Boolean, expression: KtWhileExpressionBase, context: Tr
if (!conditionBlock.isEmpty) {
val breakIfConditionIsFalseStatement = JsIf(not(jsCondition), JsBreak())
val bodyBlock = convertToBlock(bodyStatement)
jsCondition = JsLiteral.TRUE
jsCondition = JsBooleanLiteral(true)
if (doWhile) {
// translate to: tmpSecondRun = false;
// do { if(tmpSecondRun) { <expr> if(!tmpExprVar) break; } else tmpSecondRun=true; <body> } while(true)
val secondRun = context.defineTemporary(JsLiteral.FALSE)
val secondRun = context.defineTemporary(JsBooleanLiteral(false))
conditionBlock.statements.add(breakIfConditionIsFalseStatement)
val ifStatement = JsIf(secondRun, conditionBlock, assignment(secondRun, JsLiteral.TRUE).makeStmt())
val ifStatement = JsIf(secondRun, conditionBlock, assignment(secondRun, JsBooleanLiteral(true)).makeStmt())
bodyBlock.statements.add(0, ifStatement)
}
else {
@@ -172,11 +172,11 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont
val rangeExpression = context.defineTemporary(Translation.translateAsExpression(loopRange, context))
val length = ArrayFIF.LENGTH_PROPERTY_INTRINSIC.apply(rangeExpression, listOf<JsExpression>(), context)
val end = context.defineTemporary(length)
val index = context.declareTemporary(context.program().getNumberLiteral(0))
val index = context.declareTemporary(JsIntLiteral(0))
val arrayAccess = JsArrayAccess(rangeExpression, index.reference())
val body = translateBody(arrayAccess)
val initExpression = assignment(index.reference(), context.program().getNumberLiteral(0))
val initExpression = assignment(index.reference(), JsIntLiteral(0))
val conditionExpression = inequality(index.reference(), end)
val incrementExpression = JsPrefixOperation(JsUnaryOperator.INC, index.reference())
@@ -217,7 +217,7 @@ fun translateForExpression(expression: KtForExpression, context: TranslationCont
else {
bodyStatements += hasNextBlock.statements
bodyStatements += JsIf(notOptimized(hasNextInvocation), JsBreak())
JsLiteral.TRUE
JsBooleanLiteral(true)
}
bodyStatements += nextBlock.statements
bodyStatements += translateBody(nextInvoke)?.let(::flattenStatement).orEmpty()
@@ -23,10 +23,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.builtins.ReflectionTypes;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.js.backend.ast.JsConditional;
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
import org.jetbrains.kotlin.js.backend.ast.JsInvocation;
import org.jetbrains.kotlin.js.backend.ast.JsLiteral;
import org.jetbrains.kotlin.js.backend.ast.*;
import org.jetbrains.kotlin.js.patterns.NamePredicate;
import org.jetbrains.kotlin.js.patterns.typePredicates.TypePredicatesKt;
import org.jetbrains.kotlin.js.translate.context.Namer;
@@ -97,7 +94,7 @@ public final class PatternTranslator extends AbstractTranslator {
JsExpression onFail;
if (isSafeCast(expression)) {
onFail = JsLiteral.NULL;
onFail = new JsNullLiteral();
}
else {
JsExpression throwCCEFunRef = Namer.throwClassCastExceptionFunRef();
@@ -127,7 +124,7 @@ public final class PatternTranslator extends AbstractTranslator {
KtTypeReference typeReference = expression.getTypeReference();
assert typeReference != null;
JsExpression result = translateIsCheck(expressionToCheck, typeReference);
if (result == null) return JsLiteral.getBoolean(!expression.isNegated());
if (result == null) return new JsBooleanLiteral(!expression.isNegated());
if (expression.isNegated()) {
return not(result);
@@ -207,7 +204,7 @@ public final class PatternTranslator extends AbstractTranslator {
@Nullable
private JsExpression getIsTypeCheckCallableForBuiltin(@NotNull KotlinType type) {
if (isFunctionTypeOrSubtype(type) && !ReflectionTypes.isNumberedKPropertyOrKMutablePropertyType(type)) {
return namer().isTypeOf(program().getStringLiteral("function"));
return namer().isTypeOf(new JsStringLiteral("function"));
}
if (isArray(type)) {
@@ -232,11 +229,11 @@ public final class PatternTranslator extends AbstractTranslator {
Name typeName = getNameIfStandardType(type);
if (NamePredicate.STRING.test(typeName)) {
return namer().isTypeOf(program().getStringLiteral("string"));
return namer().isTypeOf(new JsStringLiteral("string"));
}
if (NamePredicate.BOOLEAN.test(typeName)) {
return namer().isTypeOf(program().getStringLiteral("boolean"));
return namer().isTypeOf(new JsStringLiteral("boolean"));
}
if (NamePredicate.LONG.test(typeName)) {
@@ -252,7 +249,7 @@ public final class PatternTranslator extends AbstractTranslator {
}
if (NamePredicate.PRIMITIVE_NUMBERS_MAPPED_TO_PRIMITIVE_JS.test(typeName)) {
return namer().isTypeOf(program().getStringLiteral("number"));
return namer().isTypeOf(new JsStringLiteral("number"));
}
if (ArrayFIF.typedArraysEnabled(context().getConfig())) {
@@ -294,7 +291,7 @@ public final class PatternTranslator extends AbstractTranslator {
if (matchEquality == EqualityType.PRIMITIVE && patternEquality == EqualityType.PRIMITIVE) {
return equality(expressionToMatch, expressionToMatchAgainst);
}
else if (expressionToMatchAgainst == JsLiteral.NULL) {
else if (expressionToMatchAgainst instanceof JsNullLiteral) {
return TranslationUtils.nullCheck(expressionToMatch, false);
}
else {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -88,8 +88,8 @@ public final class StringTemplateTranslator extends AbstractTranslator {
if (type != null && KotlinBuiltIns.isCharOrNullableChar(type)) {
if (type.isMarkedNullable()) {
TemporaryVariable tmp = context().declareTemporary(translatedExpression);
append(new JsConditional(JsAstUtils.equality(tmp.assignmentExpression(), JsLiteral.NULL),
JsLiteral.NULL,
append(new JsConditional(JsAstUtils.equality(tmp.assignmentExpression(), new JsNullLiteral()),
new JsNullLiteral(),
JsAstUtils.charToString(tmp.reference())));
}
else {
@@ -97,7 +97,7 @@ public final class StringTemplateTranslator extends AbstractTranslator {
}
}
else if (translatedExpression instanceof JsNumberLiteral) {
append(context().program().getStringLiteral(translatedExpression.toString()));
append(new JsStringLiteral(translatedExpression.toString()));
}
else if (type == null || type.isMarkedNullable()) {
append(TopLevelFIF.TO_STRING.apply((JsExpression) null, new SmartList<>(translatedExpression), context()));
@@ -135,7 +135,7 @@ public final class StringTemplateTranslator extends AbstractTranslator {
}
private void appendText(@NotNull String text) {
append(program().getStringLiteral(text));
append(new JsStringLiteral(text));
}
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -94,7 +94,7 @@ public final class WhenTranslator extends AbstractTranslator {
currentIf.setElseStatement(JsAstUtils.asSyntheticStatement(noWhenMatchedInvocation));
}
return resultIf != null ? resultIf : JsLiteral.NULL;
return resultIf != null ? resultIf : new JsNullLiteral();
}
private boolean isExhaustive() {
@@ -145,7 +145,7 @@ public final class WhenTranslator extends AbstractTranslator {
} else {
assert rightExpression instanceof JsNameRef : "expected JsNameRef, but: " + rightExpression;
JsNameRef result = (JsNameRef) rightExpression;
JsIf ifStatement = JsAstUtils.newJsIf(leftExpression, JsAstUtils.assignment(result, JsLiteral.TRUE).makeStmt(),
JsIf ifStatement = JsAstUtils.newJsIf(leftExpression, JsAstUtils.assignment(result, new JsBooleanLiteral(true)).makeStmt(),
rightContext.getCurrentBlock());
context.addStatementToCurrentBlock(ifStatement);
return result;
@@ -190,7 +190,7 @@ public final class WhenTranslator extends AbstractTranslator {
assert expressionToMatchNonTranslated != null : "expressionToMatch != null => expressionToMatchNonTranslated != null: " +
PsiUtilsKt.getTextWithLocation(conditionIsPattern);
JsExpression result = Translation.patternTranslator(context).translateIsCheck(expressionToMatch, typeReference);
return result != null ? result : JsLiteral.TRUE;
return result != null ? result : new JsBooleanLiteral(true);
}
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -49,16 +49,16 @@ object ModuleWrapperTranslation {
adapter.parameters += JsParameter(rootName)
adapter.parameters += JsParameter(factoryName)
val amdTest = JsAstUtils.and(JsAstUtils.typeOfIs(defineName.makeRef(), program.getStringLiteral("function")),
val amdTest = JsAstUtils.and(JsAstUtils.typeOfIs(defineName.makeRef(), JsStringLiteral("function")),
JsNameRef("amd", defineName.makeRef()))
val commonJsTest = JsAstUtils.typeOfIs(exportsName.makeRef(), program.getStringLiteral("object"))
val commonJsTest = JsAstUtils.typeOfIs(exportsName.makeRef(), JsStringLiteral("object"))
val amdBody = JsBlock(wrapAmd(factoryName.makeRef(), importedModules, program))
val commonJsBody = JsBlock(wrapCommonJs(factoryName.makeRef(), importedModules, program))
val plainInvocation = makePlainInvocation(moduleId, factoryName.makeRef(), importedModules, program)
val lhs: JsExpression = if (Namer.requiresEscaping(moduleId)) {
JsArrayAccess(rootName.makeRef(), program.getStringLiteral(moduleId))
JsArrayAccess(rootName.makeRef(), JsStringLiteral(moduleId))
}
else {
JsNameRef(scope.declareName(moduleId), rootName.makeRef())
@@ -73,7 +73,7 @@ object ModuleWrapperTranslation {
val selector = JsAstUtils.newJsIf(amdTest, amdBody, JsAstUtils.newJsIf(commonJsTest, commonJsBody, plainBlock))
adapterBody.statements += selector
return listOf(JsInvocation(adapter, JsLiteral.THIS, function).makeStmt())
return listOf(JsInvocation(adapter, JsThisRef(), function).makeStmt())
}
private fun wrapAmd(
@@ -83,7 +83,7 @@ object ModuleWrapperTranslation {
val scope = program.scope
val defineName = scope.declareName("define")
val invocationArgs = listOf(
JsArrayLiteral(listOf(program.getStringLiteral("exports")) + importedModules.map { program.getStringLiteral(it.externalName) }),
JsArrayLiteral(listOf(JsStringLiteral("exports")) + importedModules.map { JsStringLiteral(it.externalName) }),
function
)
@@ -100,7 +100,7 @@ object ModuleWrapperTranslation {
val moduleName = scope.declareName("module")
val requireName = scope.declareName("require")
val invocationArgs = importedModules.map { JsInvocation(requireName.makeRef(), program.getStringLiteral(it.externalName)) }
val invocationArgs = importedModules.map { JsInvocation(requireName.makeRef(), JsStringLiteral(it.externalName)) }
val invocation = JsInvocation(function, listOf(JsNameRef("exports", moduleName.makeRef())) + invocationArgs)
return listOf(invocation.makeStmt())
}
@@ -132,8 +132,8 @@ object ModuleWrapperTranslation {
module: JsImportedModule
): JsStatement {
val moduleRef = makePlainModuleRef(module, program)
val moduleExistsCond = JsAstUtils.typeOfIs(moduleRef, program.getStringLiteral("undefined"))
val moduleNotFoundMessage = program.getStringLiteral(
val moduleExistsCond = JsAstUtils.typeOfIs(moduleRef, JsStringLiteral("undefined"))
val moduleNotFoundMessage = JsStringLiteral(
"Error loading module '" + currentModuleId + "'. Its dependency '" + module.externalName + "' was not found. " +
"Please, check whether '" + module.externalName + "' is loaded prior to '" + currentModuleId + "'.")
val moduleNotFoundThrow = JsThrow(JsNew(JsNameRef("Error"), listOf<JsExpression>(moduleNotFoundMessage)))
@@ -148,7 +148,7 @@ object ModuleWrapperTranslation {
): JsInvocation {
val invocationArgs = importedModules.map { makePlainModuleRef(it, program) }
val moduleRef = makePlainModuleRef(moduleId, program)
val testModuleDefined = JsAstUtils.typeOfIs(moduleRef, program.getStringLiteral("undefined"))
val testModuleDefined = JsAstUtils.typeOfIs(moduleRef, JsStringLiteral("undefined"))
val selfArg = JsConditional(testModuleDefined, JsObjectLiteral(false), moduleRef.deepCopy())
return JsInvocation(function, listOf(selfArg) + invocationArgs)
@@ -162,7 +162,7 @@ object ModuleWrapperTranslation {
// TODO: we could use `this.moduleName` syntax. However, this does not work for `kotlin` module in Rhino, since
// we run kotlin.js in a parent scope. Consider better solution
return if (Namer.requiresEscaping(moduleId)) {
JsArrayAccess(JsLiteral.THIS, program.getStringLiteral(moduleId))
JsArrayAccess(JsThisRef(), JsStringLiteral(moduleId))
}
else {
program.scope.declareName(moduleId).makeRef()
@@ -123,14 +123,14 @@ public final class Translation {
KotlinType expectedType = context.bindingContext().getType(expression);
ConstantValue<?> constant = compileTimeValue.toConstantValue(expectedType != null ? expectedType : TypeUtils.NO_EXPECTED_TYPE);
if (constant instanceof NullValue) {
return JsLiteral.NULL;
return new JsNullLiteral();
}
Object value = constant.getValue();
if (value instanceof Integer || value instanceof Short || value instanceof Byte) {
return context.program().getNumberLiteral(((Number) value).intValue());
return new JsIntLiteral(((Number) value).intValue());
}
else if (value instanceof Long) {
return JsAstUtils.newLong((Long) value, context);
return JsAstUtils.newLong((Long) value);
}
else if (value instanceof Float) {
float floatValue = (Float) value;
@@ -141,21 +141,21 @@ public final class Translation {
else {
doubleValue = Double.parseDouble(Float.toString(floatValue));
}
return context.program().getNumberLiteral(doubleValue);
return new JsDoubleLiteral(doubleValue);
}
else if (value instanceof Number) {
return context.program().getNumberLiteral(((Number) value).doubleValue());
return new JsDoubleLiteral(((Number) value).doubleValue());
}
else if (value instanceof Boolean) {
return JsLiteral.getBoolean((Boolean) value);
return new JsBooleanLiteral((Boolean) value);
}
//TODO: test
if (value instanceof String) {
return context.program().getStringLiteral((String) value);
return new JsStringLiteral((String) value);
}
if (value instanceof Character) {
return context.program().getNumberLiteral(((Character) value).charValue());
return new JsIntLiteral(((Character) value).charValue());
}
return null;
@@ -200,7 +200,7 @@ public final class Translation {
}
block.getStatements().add(convertToStatement(jsNode));
return JsLiteral.NULL;
return new JsNullLiteral();
}
@NotNull
@@ -318,7 +318,7 @@ public final class Translation {
List<JsStatement> statements = rootBlock.getStatements();
statements.add(0, program.getStringLiteral("use strict").makeStmt());
statements.add(0, new JsStringLiteral("use strict").makeStmt());
if (!isBuiltinModule(fragments)) {
defineModule(program, statements, config.getModuleId());
}
@@ -380,7 +380,7 @@ public final class Translation {
JsName rootPackageName = program.getScope().findName(Namer.getRootPackageName());
if (rootPackageName != null) {
Namer namer = Namer.newInstance(program.getScope());
statements.add(new JsInvocation(namer.kotlin("defineModule"), program.getStringLiteral(moduleId),
statements.add(new JsInvocation(namer.kotlin("defineModule"), new JsStringLiteral(moduleId),
rootPackageName.makeRef()).makeStmt());
}
}
@@ -411,7 +411,7 @@ public final class Translation {
if (functionDescriptor == null) {
return null;
}
JsArrayLiteral argument = new JsArrayLiteral(toStringLiteralList(arguments, context.program()));
JsArrayLiteral argument = new JsArrayLiteral(toStringLiteralList(arguments));
JsExpression call = CallTranslator.INSTANCE.buildCall(context, functionDescriptor, Collections.singletonList(argument), null);
context.addTopLevelStatement(call.makeStmt());
return staticContext.getFragment();
@@ -142,7 +142,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
initFunction.getParameters().add(0, new JsParameter(outerName));
JsExpression paramRef = pureFqn(outerName, null);
JsExpression assignment = JsAstUtils.assignment(pureFqn(outerName, JsLiteral.THIS), paramRef);
JsExpression assignment = JsAstUtils.assignment(pureFqn(outerName, new JsThisRef()), paramRef);
initFunction.getBody().getStatements().add(new JsExpressionStatement(assignment));
}
@@ -159,8 +159,8 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
resolvedCall = CallUtilKt.getFunctionResolvedCallWithAssert(enumEntry, context.bindingContext());
}
JsExpression nameArg = context.program().getStringLiteral(enumEntry.getName());
JsExpression ordinalArg = context.program().getNumberLiteral(ordinal);
JsExpression nameArg = new JsStringLiteral(enumEntry.getName());
JsExpression ordinalArg = new JsIntLiteral(ordinal);
List<JsExpression> additionalArgs = Arrays.asList(nameArg, ordinalArg);
JsExpression call = CallTranslator.translate(context, resolvedCall);
@@ -191,7 +191,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
}
if (JsDescriptorUtils.isImmediateSubtypeOfError(classDescriptor)) {
emulateSuperCallToNativeError(context, classDescriptor, superCall, JsLiteral.THIS);
emulateSuperCallToNativeError(context, classDescriptor, superCall, new JsThisRef());
return;
}
@@ -199,7 +199,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
JsExpression expression = CallTranslator.translate(context(), superCall, null);
JsExpression fixedInvocation = AstUtilsKt.toInvocationWith(
expression, getAdditionalArgumentsForEnumConstructor(), 0, JsLiteral.THIS);
expression, getAdditionalArgumentsForEnumConstructor(), 0, new JsThisRef());
initFunction.getBody().getStatements().add(fixedInvocation.makeStmt());
}
else {
@@ -272,7 +272,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
statements.add(JsAstUtils.asSyntheticStatement(superInvocation));
JsExpression messageArgument = Namer.getUndefinedExpression();
JsExpression causeArgument = JsLiteral.NULL;
JsExpression causeArgument = new JsNullLiteral();
for (ValueParameterDescriptor param : superCall.getResultingDescriptor().getValueParameters()) {
ResolvedValueArgument argument = superCall.getValueArguments().get(param);
if (!(argument instanceof ExpressionValueArgument)) continue;
@@ -298,13 +298,13 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
PropertyDescriptor messageProperty = DescriptorUtils.getPropertyByName(
classDescriptor.getUnsubstitutedMemberScope(), Name.identifier("message"));
JsExpression messageRef = pureFqn(context.getNameForBackingField(messageProperty), receiver.deepCopy());
JsExpression messageIsUndefined = JsAstUtils.typeOfIs(messageArgument, context.program().getStringLiteral("undefined"));
JsExpression causeIsNull = new JsBinaryOperation(JsBinaryOperator.NEQ, causeArgument, JsLiteral.NULL);
JsExpression messageIsUndefined = JsAstUtils.typeOfIs(messageArgument, new JsStringLiteral("undefined"));
JsExpression causeIsNull = new JsBinaryOperation(JsBinaryOperator.NEQ, causeArgument, new JsNullLiteral());
JsExpression causeToStringCond = JsAstUtils.and(messageIsUndefined, causeIsNull);
JsExpression causeToString = new JsInvocation(pureFqn("toString", Namer.kotlinObject()), causeArgument.deepCopy());
JsExpression correctedMessage;
if (causeArgument == JsLiteral.NULL) {
if (causeArgument instanceof JsNullLiteral) {
correctedMessage = messageArgument.deepCopy();
}
else {
@@ -325,8 +325,8 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
@NotNull
private List<JsExpression> getAdditionalArgumentsForEnumConstructor() {
List<JsExpression> additionalArguments = new ArrayList<>();
additionalArguments.add(program().getStringLiteral(classDescriptor.getName().asString()));
additionalArguments.add(program().getNumberLiteral(ordinal));
additionalArguments.add(new JsStringLiteral(classDescriptor.getName().asString()));
additionalArguments.add(new JsIntLiteral(ordinal));
return additionalArguments;
}
@@ -340,7 +340,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
JsExpression superConstructorRef = context().getInnerReference(superclassDescriptor);
JsInvocation call = new JsInvocation(Namer.getFunctionCallRef(superConstructorRef));
call.setSource(psi);
call.getArguments().add(JsLiteral.THIS);
call.getArguments().add(new JsThisRef());
call.getArguments().addAll(arguments);
initFunction.getBody().getStatements().add(call.makeStmt());
}
@@ -349,7 +349,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
JsExpression reference = context.getInnerReference(descriptor);
JsInvocation call = new JsInvocation(reference);
call.getArguments().addAll(arguments);
call.getArguments().add(JsLiteral.THIS);
call.getArguments().add(new JsThisRef());
initFunction.getBody().getStatements().add(call.makeStmt());
}
@@ -395,12 +395,12 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
JsExpression invocation = new JsInvocation(
pureFqn("captureStack", Namer.kotlinObject()),
ReferenceTranslator.translateAsTypeReference(superClass, context()),
JsLiteral.THIS);
new JsThisRef());
initFunction.getBody().getStatements().add(JsAstUtils.asSyntheticStatement(invocation));
}
JsExpression nameLiteral = context.program().getStringLiteral(context.getInnerNameForDescriptor(classDescriptor).getIdent());
JsExpression nameAssignment = JsAstUtils.assignment(pureFqn("name", JsLiteral.THIS), nameLiteral);
JsExpression nameLiteral = new JsStringLiteral(context.getInnerNameForDescriptor(classDescriptor).getIdent());
JsExpression nameAssignment = JsAstUtils.assignment(pureFqn("name", new JsThisRef()), nameLiteral);
initFunction.getBody().getStatements().add(JsAstUtils.asSyntheticStatement(nameAssignment));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.js.translate.initializer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
import org.jetbrains.kotlin.js.backend.ast.JsLiteral;
import org.jetbrains.kotlin.js.backend.ast.JsNameRef;
import org.jetbrains.kotlin.js.backend.ast.JsStatement;
import org.jetbrains.kotlin.js.backend.ast.*;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.declaration.PropertyTranslatorKt;
import org.jetbrains.kotlin.js.translate.general.TranslatorVisitor;
@@ -62,12 +59,12 @@ public final class InitializerVisitor extends TranslatorVisitor<Void> {
}
else if (Boolean.TRUE.equals(context.bindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
JsNameRef backingFieldReference = TranslationUtils.backingFieldReference(context, descriptor);
JsExpression defaultValue = generateDefaultValue(descriptor, context, backingFieldReference);
JsExpression defaultValue = generateDefaultValue(descriptor, backingFieldReference);
statement = TranslationUtils.assignmentToBackingField(context, descriptor, defaultValue).makeStmt();
}
else if (JsDescriptorUtils.isSimpleFinalProperty(descriptor)) {
JsNameRef propRef = new JsNameRef(context.getNameForDescriptor(descriptor), JsLiteral.THIS);
JsExpression defaultValue = generateDefaultValue(descriptor, context, propRef);
JsNameRef propRef = new JsNameRef(context.getNameForDescriptor(descriptor), new JsThisRef());
JsExpression defaultValue = generateDefaultValue(descriptor, propRef);
statement = JsAstUtils.assignment(propRef, defaultValue).makeStmt();
}
@@ -81,21 +78,21 @@ public final class InitializerVisitor extends TranslatorVisitor<Void> {
@NotNull
private static JsExpression generateDefaultValue(
@NotNull PropertyDescriptor property,
@NotNull TranslationContext context,
@NotNull JsExpression lateInitDefault) {
@NotNull JsExpression lateInitDefault
) {
if (property.isLateInit()) return lateInitDefault.deepCopy();
KotlinType type = property.getType();
if (KotlinBuiltIns.isInt(type) || KotlinBuiltIns.isFloat(type) || KotlinBuiltIns.isDouble(type) ||
KotlinBuiltIns.isByte(type) || KotlinBuiltIns.isShort(type)
) {
return context.program().getNumberLiteral(0);
return new JsIntLiteral(0);
}
else if (KotlinBuiltIns.isBoolean(type)) {
return JsLiteral.FALSE;
return new JsBooleanLiteral(false);
}
else {
return JsLiteral.NULL;
return new JsNullLiteral();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -139,9 +139,9 @@ object ArrayFIF : CompositeFIF() {
}
else {
val initValue = when (type) {
BOOLEAN -> JsLiteral.FALSE
BOOLEAN -> JsBooleanLiteral(false)
LONG -> JsNameRef(Namer.LONG_ZERO, Namer.kotlinLong())
else -> JsNumberLiteral.ZERO
else -> JsIntLiteral(0)
}
JsAstUtils.invokeKotlinFunction("newArray", size, initValue)
}
@@ -155,8 +155,7 @@ object ArrayFIF : CompositeFIF() {
JsAstUtils.invokeKotlinFunction("${type.lowerCaseName}ArrayIterator", receiver!!)
}
else {
JsAstUtils.invokeKotlinFunction("arrayIterator", receiver!!,
context.program().getStringLiteral(type.arrayTypeName.asString()))
JsAstUtils.invokeKotlinFunction("arrayIterator", receiver!!, JsStringLiteral(type.arrayTypeName.asString()))
}
})
}
@@ -164,7 +163,7 @@ object ArrayFIF : CompositeFIF() {
add(pattern(NamePredicate(arrayName), "<init>(Int,Function1)"), createConstructorIntrinsic(null))
add(pattern(NamePredicate(arrayName), "iterator"), KotlinFunctionIntrinsic("arrayIterator"))
add(pattern(Namer.KOTLIN_LOWER_NAME, "arrayOfNulls"), KotlinFunctionIntrinsic("newArray", JsLiteral.NULL))
add(pattern(Namer.KOTLIN_LOWER_NAME, "arrayOfNulls"), KotlinFunctionIntrinsic("newArray", JsNullLiteral()))
val arrayFactoryMethodNames = arrayTypeNames.map { Name.identifier(decapitalize(it.asString() + "Of")) }
val arrayFactoryMethods = pattern(Namer.KOTLIN_LOWER_NAME, NamePredicate(arrayFactoryMethodNames))
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -76,8 +76,8 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
}
private boolean isSafeConstant(@NotNull JsExpression expression) {
if (!(expression instanceof JsNumberLiteral.JsIntLiteral)) return false;
int value = ((JsNumberLiteral.JsIntLiteral) expression).value;
if (!(expression instanceof JsIntLiteral)) return false;
int value = ((JsIntLiteral) expression).value;
return Math.abs(value) < SAFE_THRESHOLD;
}
};
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -132,7 +132,7 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
) {
assert receiver != null;
assert arguments.size() == 0;
return new JsBinaryOperation(JsBinaryOperator.ADD, receiver, context.program().getNumberLiteral(1));
return new JsBinaryOperation(JsBinaryOperator.ADD, receiver, new JsIntLiteral(1));
}
};
@@ -147,7 +147,7 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
) {
assert receiver != null;
assert arguments.size() == 0;
return new JsBinaryOperation(JsBinaryOperator.SUB, receiver, context.program().getNumberLiteral(1));
return new JsBinaryOperation(JsBinaryOperator.SUB, receiver, new JsIntLiteral(1));
}
};
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperation
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsNumberLiteral
import org.jetbrains.kotlin.js.backend.ast.JsIntLiteral
import org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.operation.OperatorTable
@@ -62,7 +62,7 @@ object CompareToBOIF : BinaryOperationIntrinsicFactory {
override fun apply(expression: KtBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
val operator = OperatorTable.getBinaryOperator(getOperationToken(expression))
val compareTo = JsAstUtils.compareTo(left, right)
return JsBinaryOperation(operator, compareTo, JsNumberLiteral.ZERO)
return JsBinaryOperation(operator, compareTo, JsIntLiteral(0))
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.js.translate.intrinsic.operation
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperation
import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperator
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsLiteral
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.general.Translation
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF
@@ -51,8 +48,8 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory {
override fun apply(expression: KtBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
val isNegated = expression.isNegated()
if (right == JsLiteral.NULL || left == JsLiteral.NULL) {
return TranslationUtils.nullCheck(if (right == JsLiteral.NULL) left else right, isNegated)
if (right is JsNullLiteral || left is JsNullLiteral) {
return TranslationUtils.nullCheck(if (right is JsNullLiteral) left else right, isNegated)
}
val ktLeft = checkNotNull(expression.left) { "No left-hand side: " + expression.text }
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperation
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsNumberLiteral
import org.jetbrains.kotlin.js.backend.ast.JsIntLiteral
import org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.context.TranslationContext
@@ -60,7 +60,7 @@ object LongCompareToBOIF : BinaryOperationIntrinsicFactory {
override fun apply(expression: KtBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
val operator = OperatorTable.getBinaryOperator(getOperationToken(expression))
val compareInvocation = compareForObject(toLeft(left), toRight(right))
return JsBinaryOperation(operator, compareInvocation, JsNumberLiteral.ZERO)
return JsBinaryOperation(operator, compareInvocation, JsIntLiteral(0))
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -148,7 +148,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
ifStatement = JsAstUtils.newJsIf(testExpression, rightBlock);
}
else {
result = JsLiteral.NULL;
result = new JsNullLiteral();
JsExpression testExpression = TranslationUtils.isNullCheck(leftExpression);
ifStatement = JsAstUtils.newJsIf(testExpression, rightBlock);
}
@@ -201,7 +201,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
assert operationToken.equals(KtTokens.ANDAND) || operationToken.equals(KtTokens.OROR) : "Unsupported binary operation: " + expression.getText();
boolean isOror = operationToken.equals(KtTokens.OROR);
JsExpression literalResult = isOror ? JsLiteral.TRUE : JsLiteral.FALSE;
JsExpression literalResult = new JsBooleanLiteral(isOror);
leftExpression = isOror ? not(leftExpression) : leftExpression;
JsIf ifStatement;
@@ -219,7 +219,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
}
else {
ifStatement = JsAstUtils.newJsIf(leftExpression, rightBlock);
result = JsLiteral.NULL;
result = new JsNullLiteral();
}
context().addStatementToCurrentBlock(ifStatement);
return result;
@@ -233,7 +233,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
JsExpression left = Translation.translateAsExpression(leftKtExpression, context());
JsExpression right = Translation.translateAsExpression(rightKtExpression, context());
if (left == JsLiteral.NULL || right == JsLiteral.NULL) {
if (left instanceof JsNullLiteral || right instanceof JsNullLiteral) {
JsBinaryOperator operator = operationToken == KtTokens.EXCLEQ ? JsBinaryOperator.NEQ : JsBinaryOperator.EQ;
return new JsBinaryOperation(operator, left, right);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.js.backend.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.js.backend.ast.JsIntLiteral;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.lexer.KtToken;
@@ -70,6 +71,6 @@ public final class CompareToTranslator extends AbstractTranslator {
private JsExpression translate() {
JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(getOperationToken(expression));
JsExpression methodCall = BinaryOperationTranslator.translateAsOverloadedCall(expression, context());
return new JsBinaryOperation(correspondingOperator, methodCall, context().program().getNumberLiteral(0));
return new JsBinaryOperation(correspondingOperator, methodCall, new JsIntLiteral(0));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -69,7 +69,7 @@ public class DynamicIncrementTranslator extends IncrementTranslator {
@NotNull
private JsBinaryOperation unaryAsBinary(@NotNull JsExpression leftExpression) {
JsNumberLiteral oneLiteral = program().getNumberLiteral(1);
JsNumberLiteral oneLiteral = new JsIntLiteral(1);
KtToken token = getOperationToken(expression);
if (token.equals(KtTokens.PLUSPLUS)) {
return new JsBinaryOperation(JsBinaryOperator.ADD, leftExpression, oneLiteral);
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -64,7 +64,7 @@ public final class UnaryOperationTranslator {
assert compileTimeValue != null : message(expression, "Expression is not compile time value: " + expression.getText() + " ");
Object value = getCompileTimeValue(context.bindingContext(), expression, compileTimeValue);
if (value instanceof Long) {
return JsAstUtils.newLong((Long) value, context);
return JsAstUtils.newLong((Long) value);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -150,7 +150,7 @@ class CallArgumentTranslator private constructor(
result.add(0, cachedReceiver.reference())
}
else {
result.add(0, JsLiteral.NULL)
result.add(0, JsNullLiteral())
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -110,7 +110,7 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl
JsNode node;
if (size == 0) {
node = JsLiteral.NULL;
node = new JsNullLiteral();
}
else if (size > 1) {
node = new JsBlock(statements);
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -116,7 +116,7 @@ object CallableReferenceTranslator {
function.body.statements += JsReturn(invocation)
val rawCallableRef = bindIfNecessary(function, receiver)
return wrapFunctionCallableRef(context, expression.callableReference.getReferencedName(), rawCallableRef)
return wrapFunctionCallableRef(expression.callableReference.getReferencedName(), rawCallableRef)
}
private fun translateForProperty(
@@ -138,7 +138,7 @@ object CallableReferenceTranslator {
null
}
return wrapPropertyCallableRef(context, receiver, descriptor, expression.callableReference.getReferencedName(), getter, setter)
return wrapPropertyCallableRef(receiver, descriptor, expression.callableReference.getReferencedName(), getter, setter)
}
private fun isSetterVisible(descriptor: PropertyDescriptor, context: TranslationContext): Boolean {
@@ -176,7 +176,7 @@ object CallableReferenceTranslator {
name.makeRef()
}
else {
JsLiteral.NULL
JsNullLiteral()
}
val accessorResult = translator(accessorContext, call, valueParam, receiverParam)
@@ -186,7 +186,7 @@ object CallableReferenceTranslator {
private fun bindIfNecessary(function: JsFunction, receiver: JsExpression?): JsExpression {
return if (receiver != null) {
JsInvocation(JsNameRef("bind", function), JsLiteral.NULL, receiver)
JsInvocation(JsNameRef("bind", function), JsNullLiteral(), receiver)
}
else {
function
@@ -194,7 +194,6 @@ object CallableReferenceTranslator {
}
private fun wrapPropertyCallableRef(
context: TranslationContext,
receiver: JsExpression?,
descriptor: PropertyDescriptor,
name: String,
@@ -205,8 +204,8 @@ object CallableReferenceTranslator {
if (receiver != null) {
argCount--
}
val nameLiteral = context.program().getStringLiteral(name)
val argCountLiteral = context.program().getNumberLiteral(argCount)
val nameLiteral = JsStringLiteral(name)
val argCountLiteral = JsIntLiteral(argCount)
val invokeFun = JsNameRef(Namer.PROPERTY_CALLABLE_REF, Namer.kotlinObject())
val invocation = JsInvocation(invokeFun, nameLiteral, argCountLiteral, getter)
if (setter != null) {
@@ -216,11 +215,10 @@ object CallableReferenceTranslator {
}
private fun wrapFunctionCallableRef(
context: TranslationContext,
name: String,
function: JsExpression
): JsExpression {
val nameLiteral = context.program().getStringLiteral(name)
val nameLiteral = JsStringLiteral(name)
val invokeName = Namer.FUNCTION_CALLABLE_REF
val invokeFun = JsNameRef(invokeName, Namer.kotlinObject())
invokeFun.sideEffects = SideEffectKind.PURE
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -62,7 +62,7 @@ public final class JSTestGenerator {
JsNew testClass = new JsNew(expression);
JsExpression functionToTestCall =
CallTranslator.INSTANCE.buildCall(context, functionDescriptor, Collections.emptyList(), testClass);
JsStringLiteral testName = context.program().getStringLiteral(classDescriptor.getName() + "." + functionDescriptor.getName());
JsStringLiteral testName = new JsStringLiteral(classDescriptor.getName() + "." + functionDescriptor.getName());
tester.constructTestMethodInvocation(functionToTestCall, testName);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.js.backend.ast.*;
import org.jetbrains.kotlin.js.backend.ast.metadata.MetadataProperties;
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind;
import org.jetbrains.kotlin.js.translate.context.Namer;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import org.jetbrains.kotlin.util.OperatorNameConventions;
@@ -33,16 +32,15 @@ import java.util.List;
public final class JsAstUtils {
private static final JsNameRef DEFINE_PROPERTY = pureFqn("defineProperty", null);
private static final JsNameRef CREATE_OBJECT = pureFqn("create", null);
private static final JsNameRef VALUE = new JsNameRef("value");
private static final JsPropertyInitializer WRITABLE = new JsPropertyInitializer(pureFqn("writable", null), JsLiteral.TRUE);
private static final JsPropertyInitializer ENUMERABLE = new JsPropertyInitializer(pureFqn("enumerable", null), JsLiteral.TRUE);
private static final JsPropertyInitializer WRITABLE = new JsPropertyInitializer(pureFqn("writable", null), new JsBooleanLiteral(true));
private static final JsPropertyInitializer ENUMERABLE = new JsPropertyInitializer(pureFqn("enumerable", null),
new JsBooleanLiteral(false));
static {
JsNameRef globalObjectReference = new JsNameRef("Object");
DEFINE_PROPERTY.setQualifier(globalObjectReference);
CREATE_OBJECT.setQualifier(globalObjectReference);
}
private JsAstUtils() {
@@ -132,7 +130,7 @@ public final class JsAstUtils {
@NotNull
public static JsExpression toInt32(@NotNull JsExpression expression) {
return new JsBinaryOperation(JsBinaryOperator.BIT_OR, expression, JsNumberLiteral.ZERO);
return new JsBinaryOperation(JsBinaryOperator.BIT_OR, expression, new JsIntLiteral(0));
}
@Nullable
@@ -142,8 +140,8 @@ public final class JsAstUtils {
JsBinaryOperation binary = (JsBinaryOperation) expression;
if (binary.getOperator() != JsBinaryOperator.BIT_OR) return null;
if (!(binary.getArg2() instanceof JsNumberLiteral.JsIntLiteral)) return null;
JsNumberLiteral.JsIntLiteral arg2 = (JsNumberLiteral.JsIntLiteral) binary.getArg2();
if (!(binary.getArg2() instanceof JsIntLiteral)) return null;
JsIntLiteral arg2 = (JsIntLiteral) binary.getArg2();
return arg2.value == 0 ? binary.getArg1() : null;
}
@@ -211,13 +209,13 @@ public final class JsAstUtils {
return invokeKotlinFunction(Namer.PRIMITIVE_COMPARE_TO, left, right);
}
public static JsExpression newLong(long value, @NotNull TranslationContext context) {
public static JsExpression newLong(long value) {
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
int low = (int) value;
int high = (int) (value >> 32);
List<JsExpression> args = new SmartList<>();
args.add(context.program().getNumberLiteral(low));
args.add(context.program().getNumberLiteral(high));
args.add(new JsIntLiteral(low));
args.add(new JsIntLiteral(high));
return new JsNew(Namer.kotlinLong(), args);
}
else {
@@ -230,7 +228,7 @@ public final class JsAstUtils {
else if (value == -1) {
return new JsNameRef(Namer.LONG_NEG_ONE, Namer.kotlinLong());
}
return longFromInt(context.program().getNumberLiteral((int) value));
return longFromInt(new JsIntLiteral((int) value));
}
}
@@ -352,7 +350,7 @@ public final class JsAstUtils {
@NotNull
public static JsStatement assignmentToThisField(@NotNull String fieldName, @NotNull JsExpression right) {
return assignment(new JsNameRef(fieldName, JsLiteral.THIS), right).makeStmt();
return assignment(new JsNameRef(fieldName, new JsThisRef()), right).makeStmt();
}
public static JsStatement asSyntheticStatement(@NotNull JsExpression expression) {
@@ -446,14 +444,14 @@ public final class JsAstUtils {
}
@NotNull
public static List<JsExpression> toStringLiteralList(@NotNull List<String> strings, @NotNull JsProgram program) {
public static List<JsExpression> toStringLiteralList(@NotNull List<String> strings) {
if (strings.isEmpty()) {
return Collections.emptyList();
}
List<JsExpression> result = new SmartList<>();
for (String str : strings) {
result.add(program.getStringLiteral(str));
result.add(new JsStringLiteral(str));
}
return result;
}
@@ -462,26 +460,25 @@ public final class JsAstUtils {
public static JsInvocation defineProperty(
@NotNull JsExpression receiver,
@NotNull String name,
@NotNull JsExpression value,
@NotNull JsProgram program
@NotNull JsExpression value
) {
return new JsInvocation(DEFINE_PROPERTY.deepCopy(), receiver, program.getStringLiteral(name), value);
return new JsInvocation(DEFINE_PROPERTY.deepCopy(), receiver, new JsStringLiteral(name), value);
}
@NotNull
public static JsStatement defineSimpleProperty(@NotNull String name, @NotNull JsExpression value) {
return assignment(new JsNameRef(name, JsLiteral.THIS), value).makeStmt();
return assignment(new JsNameRef(name, new JsThisRef()), value).makeStmt();
}
@NotNull
public static JsObjectLiteral createDataDescriptor(@NotNull JsExpression value, boolean writable, boolean enumerable) {
JsObjectLiteral dataDescriptor = new JsObjectLiteral();
dataDescriptor.getPropertyInitializers().add(new JsPropertyInitializer(VALUE, value));
dataDescriptor.getPropertyInitializers().add(new JsPropertyInitializer(VALUE.deepCopy(), value));
if (writable) {
dataDescriptor.getPropertyInitializers().add(WRITABLE);
dataDescriptor.getPropertyInitializers().add(WRITABLE.deepCopy());
}
if (enumerable) {
dataDescriptor.getPropertyInitializers().add(ENUMERABLE);
dataDescriptor.getPropertyInitializers().add(ENUMERABLE.deepCopy());
}
return dataDescriptor;
}
@@ -548,14 +545,13 @@ public final class JsAstUtils {
@NotNull
public static JsExpression defineGetter(
@NotNull JsProgram program,
@NotNull JsExpression receiver,
@NotNull String name,
@NotNull JsExpression body
) {
JsObjectLiteral propertyLiteral = new JsObjectLiteral(true);
propertyLiteral.getPropertyInitializers().add(new JsPropertyInitializer(new JsNameRef("get"), body));
return defineProperty(receiver, name, propertyLiteral, program);
return defineProperty(receiver, name, propertyLiteral);
}
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -73,7 +73,7 @@ public final class TranslationUtils {
return translateExtensionFunctionAsEcma5DataDescriptor(functionExpression, descriptor, context);
}
else {
JsStringLiteral getOrSet = context.program().getStringLiteral(getAccessorFunctionName(descriptor));
JsStringLiteral getOrSet = new JsStringLiteral(getAccessorFunctionName(descriptor));
return new JsPropertyInitializer(getOrSet, functionExpression);
}
}
@@ -136,7 +136,7 @@ public final class TranslationUtils {
@NotNull
public static JsBinaryOperation nullCheck(@NotNull JsExpression expressionToCheck, boolean isNegated) {
JsBinaryOperator operator = isNegated ? JsBinaryOperator.NEQ : JsBinaryOperator.EQ;
return new JsBinaryOperation(operator, expressionToCheck, JsLiteral.NULL);
return new JsBinaryOperation(operator, expressionToCheck, new JsNullLiteral());
}
@NotNull
@@ -151,7 +151,7 @@ fun TranslationContext.addAccessorsToPrototype(
) {
val prototypeRef = JsAstUtils.prototypeOf(getInnerReference(containingClass))
val propertyName = getNameForDescriptor(propertyDescriptor)
val defineProperty = JsAstUtils.defineProperty(prototypeRef, propertyName.ident, literal, program())
val defineProperty = JsAstUtils.defineProperty(prototypeRef, propertyName.ident, literal)
addDeclarationStatement(defineProperty.makeStmt())
}