review fixes + DCE data update + test (un)muting
This commit is contained in:
committed by
Ilya Gorbunov
parent
2663d9751a
commit
a83baee67b
+1
-1
@@ -1235,4 +1235,4 @@ fun CompileTimeConstant<*>.isStandaloneOnlyConstant(): Boolean {
|
|||||||
is TypedCompileTimeConstant -> this.constantValue.isStandaloneOnlyConstant()
|
is TypedCompileTimeConstant -> this.constantValue.isStandaloneOnlyConstant()
|
||||||
else -> return false
|
else -> return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// WITH_UNSIGNED
|
// WITH_UNSIGNED
|
||||||
// IGNORE_BACKEND: JVM_IR, JS_IR, JS
|
// IGNORE_BACKEND: JVM_IR, JS_IR
|
||||||
|
|
||||||
val xs = Array(2) { 42u }
|
val xs = Array(2) { 42u }
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
// WITH_UNSIGNED
|
// WITH_UNSIGNED
|
||||||
// IGNORE_BACKEND: JVM_IR, JS_IR, JS
|
// IGNORE_BACKEND: JVM_IR, JS_IR
|
||||||
|
|
||||||
inline class Data(val data: Array<UInt>)
|
inline class Data(val data: Array<UInt>)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
// IGNORE_BACKEND: JVM_IR, JS_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
|
||||||
inline class Foo(val x: Int)
|
inline class Foo(val x: Int)
|
||||||
inline class FooRef(val y: String)
|
inline class FooRef(val y: String)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// IGNORE_BACKEND: JS_IR
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|||||||
+11
-3
@@ -6,13 +6,14 @@ const val HUNDRED: UByte = 100u
|
|||||||
|
|
||||||
const val MAX_LONG: ULong = ULong.MAX_VALUE
|
const val MAX_LONG: ULong = ULong.MAX_VALUE
|
||||||
|
|
||||||
|
const val MAX_BYTE_STRING = "$MAX_BYTE"
|
||||||
|
|
||||||
|
const val MAX_LONG_STRING = "$MAX_LONG"
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val maxByteStringSingle = "$MAX_BYTE"
|
val maxByteStringSingle = "$MAX_BYTE"
|
||||||
if (maxByteStringSingle != MAX_BYTE.toString() || maxByteStringSingle != "255") return "Fail 1: $maxByteStringSingle"
|
if (maxByteStringSingle != MAX_BYTE.toString() || maxByteStringSingle != "255") return "Fail 1: $maxByteStringSingle"
|
||||||
|
|
||||||
val maxLongStringSingle = "$MAX_LONG"
|
|
||||||
if (maxLongStringSingle != MAX_LONG.toString() || maxLongStringSingle != "18446744073709551615") return "Fail 1.5: $maxLongStringSingle"
|
|
||||||
|
|
||||||
val twoHundredUByte = "${(HUNDRED * 2u).toUByte()}"
|
val twoHundredUByte = "${(HUNDRED * 2u).toUByte()}"
|
||||||
if (twoHundredUByte != "200") return "Fail 2: $twoHundredUByte"
|
if (twoHundredUByte != "200") return "Fail 2: $twoHundredUByte"
|
||||||
|
|
||||||
@@ -23,5 +24,12 @@ fun box(): String {
|
|||||||
val complex = "Max UByte: $MAX_BYTE, next: $nonConst"
|
val complex = "Max UByte: $MAX_BYTE, next: $nonConst"
|
||||||
if (complex != "Max UByte: 255, next: 256") return "Fail 4: $complex"
|
if (complex != "Max UByte: 255, next: 256") return "Fail 4: $complex"
|
||||||
|
|
||||||
|
val maxLongStringSingle = "$MAX_LONG"
|
||||||
|
if (maxLongStringSingle != MAX_LONG.toString() || maxLongStringSingle != "18446744073709551615") return "Fail 5: $maxLongStringSingle"
|
||||||
|
|
||||||
|
if (MAX_BYTE_STRING != "255") return "Fail 6: $MAX_BYTE_STRING"
|
||||||
|
|
||||||
|
if (MAX_LONG_STRING != "18446744073709551615") return "Fail 7: $MAX_LONG_STRING"
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,10 @@ fun box(): String {
|
|||||||
val complexInlinedUInts = inlinedUInt(*inlinedUInts, 3u, *inlinedUInts)
|
val complexInlinedUInts = inlinedUInt(*inlinedUInts, 3u, *inlinedUInts)
|
||||||
if (sum(*complexInlinedUInts) != 11u) return "Fail 5"
|
if (sum(*complexInlinedUInts) != 11u) return "Fail 5"
|
||||||
|
|
||||||
|
if (nullableUInts !is UIntArray) return "Fail 6"
|
||||||
|
|
||||||
|
if (inlinedUInts !is UIntArray) return "Fail 7"
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -126,9 +126,11 @@ class ClassTranslator private constructor(
|
|||||||
addSuperclassReferences()
|
addSuperclassReferences()
|
||||||
classDeclaration.secondaryConstructors.forEach { generateSecondaryConstructor(context, it) }
|
classDeclaration.secondaryConstructors.forEach { generateSecondaryConstructor(context, it) }
|
||||||
|
|
||||||
if ((descriptor.isData || descriptor.isInline) && classDeclaration is KtClassOrObject) {
|
if (classDeclaration is KtClassOrObject) {
|
||||||
// TODO is `inline data class` a bug or a feature?
|
when {
|
||||||
JsDataClassGenerator(classDeclaration, context, !descriptor.isData).generate()
|
descriptor.isData -> JsDataClassGenerator(classDeclaration, context).generate()
|
||||||
|
descriptor.isInline -> JsInlineClassGenerator(classDeclaration, context).generate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emitConstructors(nonConstructorContext, nonConstructorContext.endDeclaration())
|
emitConstructors(nonConstructorContext, nonConstructorContext.endDeclaration())
|
||||||
|
|||||||
+3
-147
@@ -16,20 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.translate.declaration;
|
package org.jetbrains.kotlin.js.translate.declaration;
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
|
||||||
import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator;
|
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*;
|
import org.jetbrains.kotlin.js.backend.ast.*;
|
||||||
import org.jetbrains.kotlin.js.translate.context.Namer;
|
import org.jetbrains.kotlin.js.translate.context.Namer;
|
||||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||||
import org.jetbrains.kotlin.js.translate.utils.UtilsKt;
|
|
||||||
import org.jetbrains.kotlin.name.Name;
|
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||||
import org.jetbrains.kotlin.psi.KtParameter;
|
import org.jetbrains.kotlin.psi.KtParameter;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -40,33 +32,14 @@ import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.and;
|
class JsDataClassGenerator extends JsEqualsHashcodeToStringGenerator {
|
||||||
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.or;
|
|
||||||
|
|
||||||
class JsDataClassGenerator extends DataClassMethodGenerator {
|
JsDataClassGenerator(KtClassOrObject klass, TranslationContext context) {
|
||||||
private final TranslationContext context;
|
super(klass, context);
|
||||||
|
|
||||||
private final boolean isInline;
|
|
||||||
|
|
||||||
JsDataClassGenerator(KtClassOrObject klass, TranslationContext context, boolean isInline) {
|
|
||||||
super(klass, context.bindingContext());
|
|
||||||
this.context = context;
|
|
||||||
this.isInline = isInline;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generate() {
|
|
||||||
if (isInline) {
|
|
||||||
generateUnboxFunction();
|
|
||||||
}
|
|
||||||
|
|
||||||
super.generate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateComponentFunction(@NotNull FunctionDescriptor function, @NotNull ValueParameterDescriptor parameter) {
|
public void generateComponentFunction(@NotNull FunctionDescriptor function, @NotNull ValueParameterDescriptor parameter) {
|
||||||
if (isInline) return;
|
|
||||||
|
|
||||||
PropertyDescriptor propertyDescriptor = context.bindingContext().get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
|
PropertyDescriptor propertyDescriptor = context.bindingContext().get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
|
||||||
assert propertyDescriptor != null : "Property descriptor is expected to be non-null";
|
assert propertyDescriptor != null : "Property descriptor is expected to be non-null";
|
||||||
|
|
||||||
@@ -79,8 +52,6 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateCopyFunction(@NotNull FunctionDescriptor function, @NotNull List<? extends KtParameter> constructorParameters) {
|
public void generateCopyFunction(@NotNull FunctionDescriptor function, @NotNull List<? extends KtParameter> constructorParameters) {
|
||||||
if (isInline) return;
|
|
||||||
|
|
||||||
JsFunction functionObj = generateJsMethod(function);
|
JsFunction functionObj = generateJsMethod(function);
|
||||||
|
|
||||||
assert function.getValueParameters().size() == constructorParameters.size();
|
assert function.getValueParameters().size() == constructorParameters.size();
|
||||||
@@ -131,119 +102,4 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
|
|||||||
returnStatement.setSource(getDeclaration());
|
returnStatement.setSource(getDeclaration());
|
||||||
functionObj.getBody().getStatements().add(returnStatement);
|
functionObj.getBody().getStatements().add(returnStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
|
|
||||||
// TODO: relax this limitation, with the data generation logic fixed.
|
|
||||||
assert !classProperties.isEmpty();
|
|
||||||
JsFunction functionObj = generateJsMethod(function);
|
|
||||||
|
|
||||||
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 = new JsStringLiteral((i == 0 ? (getClassDescriptor().getName() + "(") : ", ") + printName + "=");
|
|
||||||
JsExpression expr = new JsInvocation(context.namer().kotlin("toString"), new JsNameRef(name, new JsThisRef()));
|
|
||||||
PsiElement source = KotlinSourceElementKt.getPsi(classProperties.get(i).getSource());
|
|
||||||
JsExpression component = JsAstUtils.sum(literal, expr).source(source);
|
|
||||||
if (result == null) {
|
|
||||||
result = component;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = JsAstUtils.sum(result, component);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert result != null;
|
|
||||||
result = JsAstUtils.sum(result, new JsStringLiteral(")"));
|
|
||||||
|
|
||||||
JsReturn returnStatement = new JsReturn(result);
|
|
||||||
returnStatement.setSource(getDeclaration());
|
|
||||||
functionObj.getBody().getStatements().add(returnStatement);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
|
|
||||||
JsFunction functionObj = generateJsMethod(function);
|
|
||||||
|
|
||||||
List<JsStatement> statements = functionObj.getBody().getStatements();
|
|
||||||
|
|
||||||
JsName varName = functionObj.getScope().declareName("result");
|
|
||||||
|
|
||||||
JsVars resultVar = new JsVars(new JsVars.JsVar(varName, new JsIntLiteral(0)));
|
|
||||||
resultVar.setSource(getDeclaration());
|
|
||||||
statements.add(resultVar);
|
|
||||||
|
|
||||||
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, 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,
|
|
||||||
new JsIntLiteral(0)));
|
|
||||||
statements.add(assignment.source(KotlinSourceElementKt.getPsi(prop.getSource())).makeStmt());
|
|
||||||
}
|
|
||||||
|
|
||||||
JsReturn returnStatement = new JsReturn(new JsNameRef(varName));
|
|
||||||
returnStatement.setSource(getDeclaration());
|
|
||||||
statements.add(returnStatement);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
|
|
||||||
assert !classProperties.isEmpty();
|
|
||||||
JsFunction functionObj = generateJsMethod(function);
|
|
||||||
JsFunctionScope funScope = functionObj.getScope();
|
|
||||||
|
|
||||||
JsName paramName = funScope.declareName("other");
|
|
||||||
functionObj.getParameters().add(new JsParameter(paramName));
|
|
||||||
|
|
||||||
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")), 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);
|
|
||||||
PsiElement source = KotlinSourceElementKt.getPsi(prop.getSource());
|
|
||||||
JsExpression next = new JsInvocation(context.namer().kotlin("equals"),
|
|
||||||
new JsNameRef(name, new JsThisRef()),
|
|
||||||
new JsNameRef(name, new JsNameRef(paramName))).source(source);
|
|
||||||
if (fieldChain == null) {
|
|
||||||
fieldChain = next;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fieldChain = and(fieldChain, next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert fieldChain != null;
|
|
||||||
|
|
||||||
JsExpression returnExpression = or(referenceEqual, and(isNotNull, and(otherIsObject, and(prototypeEqual, fieldChain))));
|
|
||||||
JsReturn returnStatement = new JsReturn(returnExpression);
|
|
||||||
returnStatement.setSource(getDeclaration());
|
|
||||||
functionObj.getBody().getStatements().add(returnStatement);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateUnboxFunction() {
|
|
||||||
PropertyDescriptor boxee = getPrimaryConstructorProperties().get(0);
|
|
||||||
|
|
||||||
JsFunction unboxFunction = context.createRootScopedFunction("unbox");
|
|
||||||
JsExpression prototypeRef = JsAstUtils.prototypeOf(context.getInnerReference(getClassDescriptor()));
|
|
||||||
JsExpression functionRef = new JsNameRef("unbox", prototypeRef);
|
|
||||||
|
|
||||||
unboxFunction.getBody().getStatements().add(new JsReturn(JsAstUtils.pureFqn(context.getNameForDescriptor(boxee), new JsThisRef())));
|
|
||||||
|
|
||||||
context.addDeclarationStatement(JsAstUtils.assignment(functionRef, unboxFunction).makeStmt());
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsFunction generateJsMethod(@NotNull FunctionDescriptor functionDescriptor) {
|
|
||||||
JsFunction functionObject = context.createRootScopedFunction(functionDescriptor);
|
|
||||||
functionObject.setSource(getDeclaration());
|
|
||||||
ClassDescriptor containingClass = (ClassDescriptor) functionDescriptor.getContainingDeclaration();
|
|
||||||
context.addDeclarationStatement(UtilsKt.addFunctionToPrototype(context, containingClass, functionDescriptor, functionObject));
|
|
||||||
return functionObject;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+149
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.js.translate.declaration;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator;
|
||||||
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.*;
|
||||||
|
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.UtilsKt;
|
||||||
|
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||||
|
import org.jetbrains.kotlin.psi.KtParameter;
|
||||||
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.and;
|
||||||
|
import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.or;
|
||||||
|
|
||||||
|
abstract class JsEqualsHashcodeToStringGenerator extends DataClassMethodGenerator {
|
||||||
|
protected final TranslationContext context;
|
||||||
|
|
||||||
|
protected JsEqualsHashcodeToStringGenerator(KtClassOrObject klass, TranslationContext context) {
|
||||||
|
super(klass, context.bindingContext());
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
|
||||||
|
// TODO: relax this limitation, with the data generation logic fixed.
|
||||||
|
assert !classProperties.isEmpty();
|
||||||
|
JsFunction functionObj = generateJsMethod(function);
|
||||||
|
|
||||||
|
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 = new JsStringLiteral((i == 0 ? (getClassDescriptor().getName() + "(") : ", ") + printName + "=");
|
||||||
|
JsExpression expr = new JsInvocation(context.namer().kotlin("toString"), new JsNameRef(name, new JsThisRef()));
|
||||||
|
PsiElement source = KotlinSourceElementKt.getPsi(classProperties.get(i).getSource());
|
||||||
|
JsExpression component = JsAstUtils.sum(literal, expr).source(source);
|
||||||
|
if (result == null) {
|
||||||
|
result = component;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = JsAstUtils.sum(result, component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert result != null;
|
||||||
|
result = JsAstUtils.sum(result, new JsStringLiteral(")"));
|
||||||
|
|
||||||
|
JsReturn returnStatement = new JsReturn(result);
|
||||||
|
returnStatement.setSource(getDeclaration());
|
||||||
|
functionObj.getBody().getStatements().add(returnStatement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
|
||||||
|
JsFunction functionObj = generateJsMethod(function);
|
||||||
|
|
||||||
|
List<JsStatement> statements = functionObj.getBody().getStatements();
|
||||||
|
|
||||||
|
JsName varName = functionObj.getScope().declareName("result");
|
||||||
|
|
||||||
|
JsVars resultVar = new JsVars(new JsVars.JsVar(varName, new JsIntLiteral(0)));
|
||||||
|
resultVar.setSource(getDeclaration());
|
||||||
|
statements.add(resultVar);
|
||||||
|
|
||||||
|
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, 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,
|
||||||
|
new JsIntLiteral(0)));
|
||||||
|
statements.add(assignment.source(KotlinSourceElementKt.getPsi(prop.getSource())).makeStmt());
|
||||||
|
}
|
||||||
|
|
||||||
|
JsReturn returnStatement = new JsReturn(new JsNameRef(varName));
|
||||||
|
returnStatement.setSource(getDeclaration());
|
||||||
|
statements.add(returnStatement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
|
||||||
|
assert !classProperties.isEmpty();
|
||||||
|
JsFunction functionObj = generateJsMethod(function);
|
||||||
|
JsFunctionScope funScope = functionObj.getScope();
|
||||||
|
|
||||||
|
JsName paramName = funScope.declareName("other");
|
||||||
|
functionObj.getParameters().add(new JsParameter(paramName));
|
||||||
|
|
||||||
|
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")), 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);
|
||||||
|
PsiElement source = KotlinSourceElementKt.getPsi(prop.getSource());
|
||||||
|
JsExpression next = new JsInvocation(context.namer().kotlin("equals"),
|
||||||
|
new JsNameRef(name, new JsThisRef()),
|
||||||
|
new JsNameRef(name, new JsNameRef(paramName))).source(source);
|
||||||
|
if (fieldChain == null) {
|
||||||
|
fieldChain = next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fieldChain = and(fieldChain, next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert fieldChain != null;
|
||||||
|
|
||||||
|
JsExpression returnExpression = or(referenceEqual, and(isNotNull, and(otherIsObject, and(prototypeEqual, fieldChain))));
|
||||||
|
JsReturn returnStatement = new JsReturn(returnExpression);
|
||||||
|
returnStatement.setSource(getDeclaration());
|
||||||
|
functionObj.getBody().getStatements().add(returnStatement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void generateComponentFunction(
|
||||||
|
@NotNull FunctionDescriptor function, @NotNull ValueParameterDescriptor parameter
|
||||||
|
) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void generateCopyFunction(
|
||||||
|
@NotNull FunctionDescriptor function, @NotNull List<? extends KtParameter> constructorParameters
|
||||||
|
) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JsFunction generateJsMethod(@NotNull FunctionDescriptor functionDescriptor) {
|
||||||
|
JsFunction functionObject = context.createRootScopedFunction(functionDescriptor);
|
||||||
|
functionObject.setSource(getDeclaration());
|
||||||
|
ClassDescriptor containingClass = (ClassDescriptor) functionDescriptor.getContainingDeclaration();
|
||||||
|
context.addDeclarationStatement(UtilsKt.addFunctionToPrototype(context, containingClass, functionDescriptor, functionObject));
|
||||||
|
return functionObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.js.translate.declaration;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||||
|
import org.jetbrains.kotlin.js.backend.ast.*;
|
||||||
|
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||||
|
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||||
|
import org.jetbrains.kotlin.psi.KtParameter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class JsInlineClassGenerator extends JsEqualsHashcodeToStringGenerator {
|
||||||
|
|
||||||
|
protected JsInlineClassGenerator(KtClassOrObject klass, TranslationContext context) {
|
||||||
|
super(klass, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate() {
|
||||||
|
generateUnboxFunction();
|
||||||
|
|
||||||
|
super.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateUnboxFunction() {
|
||||||
|
PropertyDescriptor boxee = getPrimaryConstructorProperties().get(0);
|
||||||
|
|
||||||
|
JsFunction unboxFunction = context.createRootScopedFunction("unbox");
|
||||||
|
JsExpression prototypeRef = JsAstUtils.prototypeOf(context.getInnerReference(getClassDescriptor()));
|
||||||
|
JsExpression functionRef = new JsNameRef("unbox", prototypeRef);
|
||||||
|
|
||||||
|
unboxFunction.getBody().getStatements().add(new JsReturn(JsAstUtils.pureFqn(context.getNameForDescriptor(boxee), new JsThisRef())));
|
||||||
|
|
||||||
|
context.addDeclarationStatement(JsAstUtils.assignment(functionRef, unboxFunction).makeStmt());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -526,10 +526,10 @@ public final class TranslationUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ArrayFIF.INSTANCE.unsignedPrimitiveToSigned(to) != null) {
|
PrimitiveType signedPrimitiveFromUnsigned = ArrayFIF.INSTANCE.unsignedPrimitiveToSigned(to);
|
||||||
PrimitiveType fromPrimitive = Objects.requireNonNull(ArrayFIF.INSTANCE.unsignedPrimitiveToSigned(to));
|
if (signedPrimitiveFromUnsigned != null) {
|
||||||
if (KotlinBuiltIns.isInt(from)) {
|
if (KotlinBuiltIns.isInt(from)) {
|
||||||
switch (fromPrimitive) {
|
switch (signedPrimitiveFromUnsigned) {
|
||||||
case BYTE:
|
case BYTE:
|
||||||
value = AstUtilsKt.toByte(context, value);
|
value = AstUtilsKt.toByte(context, value);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1109
|
// EXPECTED_REACHABLE_NODES: 1221
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
import kotlin.reflect.KFunction
|
import kotlin.reflect.KFunction
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1126
|
// EXPECTED_REACHABLE_NODES: 1240
|
||||||
// This test was adapted from compiler/testData/codegen/box/callableReference/property/.
|
// This test was adapted from compiler/testData/codegen/box/callableReference/property/.
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -20,4 +20,4 @@ fun box(): String {
|
|||||||
|
|
||||||
fun bar(x: Char) = x.equals('Q')
|
fun bar(x: Char) = x.equals('Q')
|
||||||
|
|
||||||
fun baz(x: Any) = x.equals('Q')
|
fun baz(x: Any) = x.equals('Q')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1121
|
// EXPECTED_REACHABLE_NODES: 1234
|
||||||
// MODULE: lib
|
// MODULE: lib
|
||||||
// FILE: lib.kt
|
// FILE: lib.kt
|
||||||
package lib
|
package lib
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1147
|
// EXPECTED_REACHABLE_NODES: 1270
|
||||||
// FILE: classes.kt
|
// FILE: classes.kt
|
||||||
class C : J
|
class C : J
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1119
|
// EXPECTED_REACHABLE_NODES: 1237
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1117
|
// EXPECTED_REACHABLE_NODES: 1231
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1094
|
// EXPECTED_REACHABLE_NODES: 1217
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
import kotlin.reflect.*
|
import kotlin.reflect.*
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1113
|
// EXPECTED_REACHABLE_NODES: 1226
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1124
|
// EXPECTED_REACHABLE_NODES: 1237
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
var c: String = "fail3"
|
var c: String = "fail3"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1113
|
// EXPECTED_REACHABLE_NODES: 1231
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
val a1 = arrayOfNulls<Int>(10)
|
val a1 = arrayOfNulls<Int>(10)
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1115
|
// EXPECTED_REACHABLE_NODES: 1230
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
var global: String = ""
|
var global: String = ""
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1113
|
// EXPECTED_REACHABLE_NODES: 1226
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
class Ex1(val s: String) : Exception()
|
class Ex1(val s: String) : Exception()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1232
|
// EXPECTED_REACHABLE_NODES: 1356
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1096
|
// EXPECTED_REACHABLE_NODES: 1211
|
||||||
|
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1106
|
// EXPECTED_REACHABLE_NODES: 1219
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
class SimpleEnumerator {
|
class SimpleEnumerator {
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1110
|
// EXPECTED_REACHABLE_NODES: 1230
|
||||||
// GENERATE_SOURCE_MAPS
|
// GENERATE_SOURCE_MAPS
|
||||||
// FILE: Enum.kt
|
// FILE: Enum.kt
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1120
|
// EXPECTED_REACHABLE_NODES: 1235
|
||||||
interface I {
|
interface I {
|
||||||
fun foo() = "OK"
|
fun foo() = "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1117
|
// EXPECTED_REACHABLE_NODES: 1232
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
class C: B()
|
class C: B()
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1112
|
// EXPECTED_REACHABLE_NODES: 1224
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
fun f() {}
|
fun f() {}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1634
|
// EXPECTED_REACHABLE_NODES: 1806
|
||||||
// See KT-11711
|
// See KT-11711
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -288,4 +288,4 @@ fun htmlNoInline(init: HTML.() -> Unit): HTML {
|
|||||||
val html = HTML()
|
val html = HTML()
|
||||||
html.init()
|
html.init()
|
||||||
return html
|
return html
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1520
|
// EXPECTED_REACHABLE_NODES: 1681
|
||||||
/*
|
/*
|
||||||
* Copy of JVM-backend test
|
* Copy of JVM-backend test
|
||||||
* Found at: compiler/testData/codegen/boxInline/builders/buildersAndLambdaCapturing.1.kt
|
* Found at: compiler/testData/codegen/boxInline/builders/buildersAndLambdaCapturing.1.kt
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1132
|
// EXPECTED_REACHABLE_NODES: 1249
|
||||||
// LANGUAGE_VERSION: 1.2
|
// LANGUAGE_VERSION: 1.2
|
||||||
// MODULE: lib
|
// MODULE: lib
|
||||||
// FILE: lib.kt
|
// FILE: lib.kt
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ fun box(): String {
|
|||||||
assertEquals(listOf(1, -2, 3, -4), test(listOf(-2, 1, -4, 3)))
|
assertEquals(listOf(1, -2, 3, -4), test(listOf(-2, 1, -4, 3)))
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1178
|
// EXPECTED_REACHABLE_NODES: 1297
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.BeforeTest
|
import kotlin.test.BeforeTest
|
||||||
import kotlin.test.AfterTest
|
import kotlin.test.AfterTest
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1653
|
// EXPECTED_REACHABLE_NODES: 1819
|
||||||
// MODULE: lib1
|
// MODULE: lib1
|
||||||
// FILE: lib1.kt
|
// FILE: lib1.kt
|
||||||
package lib1
|
package lib1
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1638
|
// EXPECTED_REACHABLE_NODES: 1805
|
||||||
// MODULE: lib
|
// MODULE: lib
|
||||||
// FILE: lib.kt
|
// FILE: lib.kt
|
||||||
package lib
|
package lib
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1098
|
// EXPECTED_REACHABLE_NODES: 1211
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1123
|
// EXPECTED_REACHABLE_NODES: 1236
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
class C(val i: Int) : Comparable<C>, A() {
|
class C(val i: Int) : Comparable<C>, A() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1114
|
// EXPECTED_REACHABLE_NODES: 1227
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// EXPECTED_REACHABLE_NODES: 1114
|
// EXPECTED_REACHABLE_NODES: 1230
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
fun fact(n: Int): Long = if (n == 1) 1L else n * fact(n - 1)
|
fun fact(n: Int): Long = if (n == 1) 1L else n * fact(n - 1)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1112
|
// EXPECTED_REACHABLE_NODES: 1228
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1114
|
// EXPECTED_REACHABLE_NODES: 1226
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1112
|
// EXPECTED_REACHABLE_NODES: 1225
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1099
|
// EXPECTED_REACHABLE_NODES: 1221
|
||||||
external class A
|
external class A
|
||||||
|
|
||||||
external object O
|
external object O
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1114
|
// EXPECTED_REACHABLE_NODES: 1228
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
open class Base(val bb: String) {
|
open class Base(val bb: String) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1114
|
// EXPECTED_REACHABLE_NODES: 1230
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
open class Base {
|
open class Base {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1114
|
// EXPECTED_REACHABLE_NODES: 1230
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
open class Base(val bs: String) {
|
open class Base(val bs: String) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1114
|
// EXPECTED_REACHABLE_NODES: 1231
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
open class Base {
|
open class Base {
|
||||||
|
|||||||
Reference in New Issue
Block a user