mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-27 15:51:49 +00:00
Compare commits
195 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6bb03a0b6b | ||
|
|
b736880787 | ||
|
|
ffd1bcf72f | ||
|
|
f9a6da05df | ||
|
|
0518c6f618 | ||
|
|
ad9303b97b | ||
|
|
754b02aa3c | ||
|
|
0a6dbc91ae | ||
|
|
5c83e2ac5b | ||
|
|
36d154babf | ||
|
|
c351293394 | ||
|
|
e8aef7d29e | ||
|
|
3678bda409 | ||
|
|
1d70b58d17 | ||
|
|
11268331a8 | ||
|
|
74c13906ed | ||
|
|
4b3290dd8c | ||
|
|
c97294a066 | ||
|
|
02daeac41b | ||
|
|
aeefdffaab | ||
|
|
2b4f03feef | ||
|
|
00cc9d4150 | ||
|
|
21fd894d75 | ||
|
|
c391882651 | ||
|
|
5b5e7fb9b7 | ||
|
|
9180a99342 | ||
|
|
3af7c7b57a | ||
|
|
004c266433 | ||
|
|
0aef321c73 | ||
|
|
145722b20d | ||
|
|
865fdd7962 | ||
|
|
6ffc407158 | ||
|
|
be590312f7 | ||
|
|
bce9514739 | ||
|
|
fcfb063eca | ||
|
|
da4b1ae0fb | ||
|
|
80916d5ed7 | ||
|
|
911adfd04d | ||
|
|
b71b336a69 | ||
|
|
f9944e28b0 | ||
|
|
d54c3f4fc7 | ||
|
|
91f27ba176 | ||
|
|
ae4ca3b5bb | ||
|
|
bb63bcd520 | ||
|
|
e671d05105 | ||
|
|
e116cc3206 | ||
|
|
85ae0cb78e | ||
|
|
6f0c2a0260 | ||
|
|
9096a443ea | ||
|
|
b38fc7b3c1 | ||
|
|
1c4d4f3e36 | ||
|
|
06e829936e | ||
|
|
4f5f56e4a5 | ||
|
|
d511059cfa | ||
|
|
da53d8cbf4 | ||
|
|
87b6374351 | ||
|
|
39bbd7c795 | ||
|
|
890c961383 | ||
|
|
688a1b6305 | ||
|
|
722a152a74 | ||
|
|
397d2ca312 | ||
|
|
b6edddbe8b | ||
|
|
ec0ec55ab5 | ||
|
|
9773e98d8a | ||
|
|
e2c02f825f | ||
|
|
365ff593f3 | ||
|
|
58caff3411 | ||
|
|
7aaa6422b4 | ||
|
|
8d0a90a838 | ||
|
|
e7dbcfe21f | ||
|
|
555286849e | ||
|
|
48b89a5db7 | ||
|
|
3fd35636ad | ||
|
|
73b961e885 | ||
|
|
0cc09872b6 | ||
|
|
7d6ccc40c2 | ||
|
|
011a9f23b9 | ||
|
|
52c3fb03a2 | ||
|
|
0f3997c6ca | ||
|
|
4c4456c808 | ||
|
|
7179b37d95 | ||
|
|
b93894953d | ||
|
|
d62d7dd84f | ||
|
|
b805ce06c2 | ||
|
|
697228eae0 | ||
|
|
3513a64351 | ||
|
|
0685f06200 | ||
|
|
0ecf04dcc5 | ||
|
|
39c10867a0 | ||
|
|
8dc604ac8b | ||
|
|
64b48f4458 | ||
|
|
002dc92d89 | ||
|
|
dc6a176282 | ||
|
|
fc74759231 | ||
|
|
57b96f38a9 | ||
|
|
b4addd0567 | ||
|
|
e7da56baf4 | ||
|
|
ddcdc11099 | ||
|
|
906d706961 | ||
|
|
7592f31596 | ||
|
|
07a23cab10 | ||
|
|
75f046fa81 | ||
|
|
3d44471659 | ||
|
|
4de26bed93 | ||
|
|
c90d283ff5 | ||
|
|
6978d842fb | ||
|
|
5dcf531048 | ||
|
|
2895e2e86f | ||
|
|
4fba251fba | ||
|
|
03641ffbee | ||
|
|
123b813073 | ||
|
|
ae636a0d32 | ||
|
|
1d3054e7a6 | ||
|
|
1c74bab1cc | ||
|
|
ee9389d089 | ||
|
|
da2806acde | ||
|
|
f870e365fa | ||
|
|
b4db23a7b3 | ||
|
|
2e73559f33 | ||
|
|
aeb6486473 | ||
|
|
80fd9e3cbb | ||
|
|
f9ba35af64 | ||
|
|
de11ed4fc6 | ||
|
|
fc4250b02b | ||
|
|
99a32b93fb | ||
|
|
15746cbf56 | ||
|
|
6b8b39a7bd | ||
|
|
f56dc722d9 | ||
|
|
ebda21c68a | ||
|
|
60521e20ff | ||
|
|
cfacd5da1e | ||
|
|
a7324ebad2 | ||
|
|
12e921ab15 | ||
|
|
7170d488bd | ||
|
|
e67318e049 | ||
|
|
48a0a95e8f | ||
|
|
cd435c4130 | ||
|
|
03606c13aa | ||
|
|
f4c5289cfc | ||
|
|
51cdb981f4 | ||
|
|
f7969621d6 | ||
|
|
696dce68fb | ||
|
|
19372a7210 | ||
|
|
745de229cc | ||
|
|
b3877b5f0b | ||
|
|
70dc5a5c4c | ||
|
|
a8c5e0cc95 | ||
|
|
f20aba63a6 | ||
|
|
6a1ca7b9c9 | ||
|
|
00db7d150b | ||
|
|
f25d80c38b | ||
|
|
259397db9d | ||
|
|
2fba6c361a | ||
|
|
5467671a21 | ||
|
|
1b92fa94bc | ||
|
|
99966c17da | ||
|
|
de6f52030c | ||
|
|
142e85be04 | ||
|
|
ed2ad8e8e3 | ||
|
|
97ce61ac44 | ||
|
|
7449ad2763 | ||
|
|
6d40d94127 | ||
|
|
c10cc30f40 | ||
|
|
6048ebf871 | ||
|
|
2ccd6d54b7 | ||
|
|
a9476dfe37 | ||
|
|
fa8c1f1a37 | ||
|
|
12922c3abd | ||
|
|
c5e43a1327 | ||
|
|
2b6ae3127b | ||
|
|
8139070754 | ||
|
|
5ad0a84039 | ||
|
|
a7e7d53e2b | ||
|
|
45074841a4 | ||
|
|
318f0c89b2 | ||
|
|
afc1e24571 | ||
|
|
01095bc652 | ||
|
|
2c1bf4dbd9 | ||
|
|
aee36c40cd | ||
|
|
b79aa686bb | ||
|
|
697132561f | ||
|
|
8196621be5 | ||
|
|
aff83087a3 | ||
|
|
712d2bdec0 | ||
|
|
94c0ccf2bf | ||
|
|
36210f0a27 | ||
|
|
ef265e23f8 | ||
|
|
b61b4e1c90 | ||
|
|
20379028e8 | ||
|
|
e562b73eff | ||
|
|
5cd23daf4e | ||
|
|
0aa8d89b16 | ||
|
|
0a1f4d6088 | ||
|
|
fbfeb98ecf | ||
|
|
6ba68da811 |
8
.idea/dictionaries/dzharkov.xml
generated
Normal file
8
.idea/dictionaries/dzharkov.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="dzharkov">
|
||||
<words>
|
||||
<w>checkcast</w>
|
||||
<w>insn</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
9
.idea/libraries/kotlin_reflect.xml
generated
Normal file
9
.idea/libraries/kotlin_reflect.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="kotlin-reflect">
|
||||
<CLASSES>
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
3
.idea/libraries/kotlin_runtime.xml
generated
3
.idea/libraries/kotlin_runtime.xml
generated
@@ -2,11 +2,12 @@
|
||||
<library name="kotlin-runtime">
|
||||
<CLASSES>
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-runtime.jar!/" />
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/libraries/stdlib/src" />
|
||||
<root url="file://$PROJECT_DIR$/core/builtins/native" />
|
||||
<root url="file://$PROJECT_DIR$/core/builtins/src" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -9,6 +9,7 @@
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="ant" level="project" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="library" name="kotlin-reflect" level="project" />
|
||||
<orderEntry type="module" module-name="preloader" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -1,7 +0,0 @@
|
||||
<!-- NOTE: this Antlib is deprecated. Use org/jetbrains/kotlin/ant/antlib.xml instead -->
|
||||
<!-- TODO: delete this file -->
|
||||
<antlib>
|
||||
<taskdef name="kotlinc" classname="org.jetbrains.kotlin.ant.Kotlin2JvmTask"/>
|
||||
<taskdef name="kotlin2js" classname="org.jetbrains.kotlin.ant.Kotlin2JsTask"/>
|
||||
<typedef name="withKotlin" classname="org.jetbrains.kotlin.ant.KotlinCompilerAdapter"/>
|
||||
</antlib>
|
||||
@@ -70,7 +70,7 @@ class KotlinCompilerAdapter : Javac13() {
|
||||
// Javac13#execute passes everything in compileList to javac, which doesn't recognize .kt files
|
||||
val compileListForJavac = filterOutKotlinSources(compileList)
|
||||
|
||||
val hasKotlinFilesInSources = compileListForJavac.size() < compileList.size()
|
||||
val hasKotlinFilesInSources = compileListForJavac.size < compileList.size
|
||||
|
||||
if (hasKotlinFilesInSources) {
|
||||
kotlinc.execute()
|
||||
|
||||
@@ -54,7 +54,7 @@ public abstract class KotlinCompilerBaseTask : Task() {
|
||||
}
|
||||
|
||||
public fun setSrcRef(ref: Reference) {
|
||||
createSrc().setRefid(ref)
|
||||
createSrc().refid = ref
|
||||
}
|
||||
|
||||
public fun createCompilerArg(): Commandline.Argument {
|
||||
@@ -75,7 +75,7 @@ public abstract class KotlinCompilerBaseTask : Task() {
|
||||
if (verbose) args.add("-verbose")
|
||||
if (printVersion) args.add("-version")
|
||||
|
||||
args.addAll(additionalArguments.flatMap { it.getParts().toList() })
|
||||
args.addAll(additionalArguments.flatMap { it.parts.toList() })
|
||||
|
||||
fillSpecificArguments()
|
||||
}
|
||||
@@ -85,12 +85,12 @@ public abstract class KotlinCompilerBaseTask : Task() {
|
||||
|
||||
val compilerClass = KotlinAntTaskUtil.getOrCreateClassLoader().loadClass(compilerFqName)
|
||||
val compiler = compilerClass.newInstance()
|
||||
val exec = compilerClass.getMethod("execFullPathsInMessages", javaClass<PrintStream>(), javaClass<Array<String>>())
|
||||
val exec = compilerClass.getMethod("execFullPathsInMessages", PrintStream::class.java, Array<String>::class.java)
|
||||
|
||||
log("Compiling ${src!!.list().toList()} => [${output!!.canonicalPath}]");
|
||||
|
||||
val result = exec(compiler, System.err, args.toTypedArray())
|
||||
exitCode = (result as Enum<*>).ordinal()
|
||||
exitCode = (result as Enum<*>).ordinal
|
||||
|
||||
if (failOnError && exitCode != 0) {
|
||||
throw BuildException("Compile failed; see the compiler error output for details.")
|
||||
|
||||
@@ -969,7 +969,7 @@
|
||||
<target name="pack-kotlin-test">
|
||||
<pack-runtime-jar jar-name="kotlin-test.jar" implementation-title="${manifest.impl.title.kotlin.test}">
|
||||
<jar-content>
|
||||
<fileset dir="${output}/classes/kotlin.test" includes="**/*"/>
|
||||
<fileset dir="${output}/classes/kotlin.test" includes="**/*" excludes="kotlin/internal/OnlyInputTypes*,kotlin/internal"/>
|
||||
</jar-content>
|
||||
</pack-runtime-jar>
|
||||
</target>
|
||||
|
||||
@@ -67,7 +67,7 @@ public object CodegenUtilKt {
|
||||
}
|
||||
else null
|
||||
}
|
||||
assert(actualDelegates.size() <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
|
||||
assert(actualDelegates.size <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
|
||||
|
||||
actualDelegates.firstOrNull()
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Fu
|
||||
result.removeAll(toRemove)
|
||||
|
||||
val concreteRelevantDeclarations = result.filter { !it.isAbstract }
|
||||
if (concreteRelevantDeclarations.size() != 1) {
|
||||
if (concreteRelevantDeclarations.size != 1) {
|
||||
error("Concrete fake override $function should have exactly one concrete super-declaration: $concreteRelevantDeclarations")
|
||||
}
|
||||
|
||||
|
||||
@@ -90,10 +90,9 @@ public fun findImplementationFromInterface(descriptor: CallableMemberDescriptor)
|
||||
val overridden = OverrideResolver.getOverriddenDeclarations(descriptor)
|
||||
val filtered = OverrideResolver.filterOutOverridden(overridden)
|
||||
|
||||
val result = filtered.firstOrNull { it.getModality() != Modality.ABSTRACT } ?: return null
|
||||
val result = filtered.firstOrNull { it.modality != Modality.ABSTRACT } ?: return null
|
||||
|
||||
val container = result.getContainingDeclaration()
|
||||
if (DescriptorUtils.isClass(container) || DescriptorUtils.isEnumClass(container)) return null
|
||||
if (DescriptorUtils.isClassOrEnumClass(result.containingDeclaration)) return null
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ abstract class ArgumentGenerator {
|
||||
* @see kotlin.reflect.jvm.internal.KCallableImpl.callBy
|
||||
*/
|
||||
open fun generate(valueArgumentsByIndex: List<ResolvedValueArgument>, actualArgs: List<ResolvedValueArgument>): DefaultCallMask {
|
||||
assert(valueArgumentsByIndex.size() == actualArgs.size()) {
|
||||
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size()} != ${actualArgs.size()}"
|
||||
assert(valueArgumentsByIndex.size == actualArgs.size) {
|
||||
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size} != ${actualArgs.size}"
|
||||
}
|
||||
|
||||
val arg2Index = valueArgumentsByIndex.mapToIndex()
|
||||
@@ -48,7 +48,7 @@ abstract class ArgumentGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
val masks = DefaultCallMask(valueArgumentsByIndex.size())
|
||||
val masks = DefaultCallMask(valueArgumentsByIndex.size)
|
||||
|
||||
for (argumentWithDeclIndex in actualArgsWithDeclIndex) {
|
||||
val argument = argumentWithDeclIndex.arg
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
|
||||
import org.jetbrains.kotlin.resolve.DeprecationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
@@ -61,11 +62,11 @@ import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_SYNTHETIC_CLASS;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.types.TypeUtils.isNullableType;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
@@ -299,9 +300,6 @@ public class AsmUtil {
|
||||
|
||||
public static int getDeprecatedAccessFlag(@NotNull MemberDescriptor descriptor) {
|
||||
if (descriptor instanceof PropertyAccessorDescriptor) {
|
||||
if (((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty().isConst()) {
|
||||
return ACC_DEPRECATED;
|
||||
}
|
||||
return KotlinBuiltIns.isDeprecated(descriptor)
|
||||
? ACC_DEPRECATED
|
||||
: getDeprecatedAccessFlag(((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty());
|
||||
@@ -542,7 +540,7 @@ public class AsmUtil {
|
||||
if (opToken == KtTokens.EXCLEQ || opToken == KtTokens.EXCLEQEQEQ) {
|
||||
genInvertBoolean(v);
|
||||
}
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -681,28 +679,17 @@ public class AsmUtil {
|
||||
}
|
||||
|
||||
public static boolean isInstancePropertyWithStaticBackingField(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
if (propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DeclarationDescriptor container = propertyDescriptor.getContainingDeclaration();
|
||||
return isNonCompanionObject(container) ||
|
||||
isPropertyWithBackingFieldInOuterClass(propertyDescriptor) ||
|
||||
(isCompanionObject(container) && isInterface(container.getContainingDeclaration()));
|
||||
}
|
||||
|
||||
public static boolean isPropertyWithBackingFieldInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
||||
isCompanionObjectWithBackingFieldsInOuter(propertyDescriptor.getContainingDeclaration());
|
||||
isObject(propertyDescriptor.getContainingDeclaration());
|
||||
}
|
||||
|
||||
public static int getVisibilityForSpecialPropertyBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
|
||||
public static int getVisibilityForBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
|
||||
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
|
||||
if (isDelegate || isExtensionProperty) {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
else {
|
||||
return areBothAccessorDefault(propertyDescriptor)
|
||||
return propertyDescriptor.isLateInit() || isConstOrHasJvmFieldAnnotation(propertyDescriptor)
|
||||
? getVisibilityAccessFlag(descriptorForVisibility(propertyDescriptor))
|
||||
: ACC_PRIVATE;
|
||||
}
|
||||
@@ -718,27 +705,10 @@ public class AsmUtil {
|
||||
}
|
||||
|
||||
public static boolean isPropertyWithBackingFieldCopyInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
|
||||
DeclarationDescriptor propertyContainer = propertyDescriptor.getContainingDeclaration();
|
||||
return !propertyDescriptor.isVar()
|
||||
&& !isExtensionProperty
|
||||
return propertyDescriptor.isConst()
|
||||
&& isCompanionObject(propertyContainer) && isInterface(propertyContainer.getContainingDeclaration())
|
||||
&& areBothAccessorDefault(propertyDescriptor)
|
||||
&& getVisibilityForSpecialPropertyBackingField(propertyDescriptor, false) == ACC_PUBLIC;
|
||||
}
|
||||
|
||||
public static boolean isCompanionObjectWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) {
|
||||
DeclarationDescriptor containingClass = companionObject.getContainingDeclaration();
|
||||
return isCompanionObject(companionObject) && (isClass(containingClass) || isEnumClass(containingClass));
|
||||
}
|
||||
|
||||
private static boolean areBothAccessorDefault(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return isAccessorWithEmptyBody(propertyDescriptor.getGetter())
|
||||
&& (!propertyDescriptor.isVar() || isAccessorWithEmptyBody(propertyDescriptor.getSetter()));
|
||||
}
|
||||
|
||||
private static boolean isAccessorWithEmptyBody(@Nullable PropertyAccessorDescriptor accessorDescriptor) {
|
||||
return accessorDescriptor == null || !accessorDescriptor.hasBody();
|
||||
&& getVisibilityForBackingField(propertyDescriptor, false) == ACC_PUBLIC;
|
||||
}
|
||||
|
||||
public static Type comparisonOperandType(Type left, Type right) {
|
||||
@@ -843,13 +813,6 @@ public class AsmUtil {
|
||||
return asmTypeByFqNameWithoutInnerClasses(fqName).getDescriptor();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String shortNameByAsmType(@NotNull Type type) {
|
||||
String internalName = type.getInternalName();
|
||||
int lastSlash = internalName.lastIndexOf('/');
|
||||
return lastSlash < 0 ? internalName : internalName.substring(lastSlash + 1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type asmTypeByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
|
||||
return Type.getObjectType(internalNameByFqNameWithoutInnerClasses(fqName));
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.DataOutputStream;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -46,7 +46,6 @@ import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.kotlin.utils.FunctionsKt;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
@@ -212,7 +211,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
this.constructor = generateConstructor();
|
||||
|
||||
if (isConst(closure)) {
|
||||
generateConstInstance(asmType, asmType, FunctionsKt.<InstructionAdapter>doNothing());
|
||||
generateConstInstance(asmType, asmType);
|
||||
}
|
||||
|
||||
genClosureFields(closure, v, typeMapper);
|
||||
@@ -259,13 +258,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
|
||||
}
|
||||
|
||||
if (functionReferenceTarget != null) {
|
||||
if (!"true".equalsIgnoreCase(System.getProperty("kotlin.jvm.optimize.callable.references"))) {
|
||||
v.invokestatic(REFLECTION, "function", Type.getMethodDescriptor(K_FUNCTION, FUNCTION_REFERENCE), false);
|
||||
}
|
||||
}
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -214,7 +214,7 @@ class CollectionStubMethodGenerator(
|
||||
private fun Collection<KotlinType>.findMostSpecificTypeForClass(klass: ClassDescriptor): KotlinType {
|
||||
val types = this.filter { it.getConstructor().getDeclarationDescriptor() == klass }
|
||||
if (types.isEmpty()) error("No supertype of $klass in $this")
|
||||
if (types.size() == 1) return types.first()
|
||||
if (types.size == 1) return types.first()
|
||||
// Find the first type in the list such that it's a subtype of every other type in that list
|
||||
return types.first { type ->
|
||||
types.all { other -> KotlinTypeChecker.DEFAULT.isSubtypeOf(type, other) }
|
||||
@@ -227,7 +227,7 @@ class CollectionStubMethodGenerator(
|
||||
child.setModality(Modality.FINAL)
|
||||
child.setVisibility(Visibilities.PUBLIC)
|
||||
val typeParameters = descriptor.getTypeConstructor().getParameters()
|
||||
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size())
|
||||
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size)
|
||||
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitution.EMPTY, child, newTypeParameters)
|
||||
child.setTypeParameterDescriptors(typeParameters)
|
||||
return Pair(child, newTypeParameters)
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.codegen.inline.*;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicPropertyGetter;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics;
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsKt;
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -54,6 +53,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
|
||||
import org.jetbrains.kotlin.jvm.bindingContextSlices.BindingContextSlicesKt;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -92,15 +92,13 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.couldUseDirectAccessToProperty;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isObject;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -480,7 +478,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
markLineNumber(expression, isStatement);
|
||||
v.mark(end);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1294,7 +1292,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1433,7 +1431,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
JvmMethodSignature constructor = typeMapper.mapSignature(SamCodegenUtil.resolveSamAdapter(constructorDescriptor));
|
||||
v.invokespecial(type.getInternalName(), "<init>", constructor.getAsmMethod().getDescriptor(), false);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1551,7 +1549,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
for (Function<StackValue, Void> task : Lists.reverse(leaveTasks)) {
|
||||
task.fun(value);
|
||||
}
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -2118,7 +2116,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
|
||||
FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL;
|
||||
boolean isBackingFieldInClassCompanion = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
boolean isBackingFieldInClassCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
if (isBackingFieldInClassCompanion && forceField) {
|
||||
fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION;
|
||||
}
|
||||
@@ -2142,7 +2140,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
PropertyDescriptor originalPropertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
|
||||
if (fieldAccessorKind != FieldAccessorKind.NORMAL) {
|
||||
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
|
||||
int flags = AsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty);
|
||||
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
|
||||
if (!skipPropertyAccessors) {
|
||||
//noinspection ConstantConditions
|
||||
@@ -2168,7 +2166,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superCallTarget);
|
||||
|
||||
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
|
||||
if (getter != null && !hasJvmFieldAnnotation(propertyDescriptor)) {
|
||||
if (getter != null && !isConstOrHasJvmFieldAnnotation(propertyDescriptor)) {
|
||||
callableGetter = typeMapper.mapToCallableMethod(getter, isSuper);
|
||||
}
|
||||
}
|
||||
@@ -2177,7 +2175,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||
if (setter != null &&
|
||||
!couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context) &&
|
||||
!hasJvmFieldAnnotation(propertyDescriptor)) {
|
||||
!isConstOrHasJvmFieldAnnotation(propertyDescriptor)) {
|
||||
callableSetter = typeMapper.mapToCallableMethod(setter, isSuper);
|
||||
}
|
||||
}
|
||||
@@ -2422,6 +2420,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
|
||||
|
||||
KotlinType returnType = resolvedCall.getResultingDescriptor().getReturnType();
|
||||
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
|
||||
v.aconst(null);
|
||||
v.athrow();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -2734,19 +2738,17 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, expression);
|
||||
if (variableDescriptor != null) {
|
||||
return generatePropertyReference(expression, variableDescriptor, (VariableDescriptor) resolvedCall.getResultingDescriptor(),
|
||||
resolvedCall.getDispatchReceiver());
|
||||
return generatePropertyReference(expression, variableDescriptor, resolvedCall);
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Unsupported callable reference expression: " + expression.getText());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StackValue generatePropertyReference(
|
||||
private StackValue generatePropertyReference(
|
||||
@NotNull KtElement element,
|
||||
@NotNull VariableDescriptor variableDescriptor,
|
||||
@NotNull VariableDescriptor target,
|
||||
@Nullable ReceiverValue dispatchReceiver
|
||||
@NotNull ResolvedCall<?> resolvedCall
|
||||
) {
|
||||
ClassDescriptor classDescriptor = CodegenBinding.anonymousClassForCallable(bindingContext, variableDescriptor);
|
||||
|
||||
@@ -2758,7 +2760,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
PropertyReferenceCodegen codegen = new PropertyReferenceCodegen(
|
||||
state, parentCodegen, context.intoAnonymousClass(classDescriptor, this, OwnerKind.IMPLEMENTATION),
|
||||
element, classBuilder, classDescriptor, target, dispatchReceiver
|
||||
element, classBuilder, resolvedCall
|
||||
);
|
||||
codegen.generate();
|
||||
|
||||
@@ -2783,13 +2785,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
"Non-reified type parameter under ::class should be rejected by type checker: " + typeParameterDescriptor;
|
||||
assert codegen != null :
|
||||
"Reference to member of reified type should be rejected by type checker " + typeParameterDescriptor;
|
||||
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME);
|
||||
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS);
|
||||
}
|
||||
|
||||
putJavaLangClassInstance(v, classAsmType);
|
||||
wrapJavaClassIntoKClass(v);
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3248,7 +3250,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
value.store(StackValue.onStack(storeType), v, true);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3373,7 +3375,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructor, false);
|
||||
invokeMethodWithArguments(method, resolvedCall, StackValue.none());
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3389,7 +3391,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
gen(sizeExpression, Type.INT_TYPE);
|
||||
newArrayInstruction(arrayType);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3397,9 +3399,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public void newArrayInstruction(@NotNull KotlinType arrayType) {
|
||||
if (KotlinBuiltIns.isArray(arrayType)) {
|
||||
KotlinType elementJetType = arrayType.getArguments().get(0).getType();
|
||||
putReifierMarkerIfTypeIsReifiedParameter(
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
elementJetType,
|
||||
ReifiedTypeInliner.NEW_ARRAY_MARKER_METHOD_NAME
|
||||
ReifiedTypeInliner.OperationKind.NEW_ARRAY
|
||||
);
|
||||
v.newarray(boxType(asmType(elementJetType)));
|
||||
}
|
||||
@@ -3628,7 +3630,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
if (finallyBlock != null) {
|
||||
blockStackElements.pop();
|
||||
}
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3676,23 +3678,19 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
StackValue.putUnitInstance(v);
|
||||
}
|
||||
|
||||
if (opToken != KtTokens.AS_SAFE) {
|
||||
if (!TypeUtils.isNullableType(rightType) && !TypeUtils.isReifiedTypeParameter(rightType)) {
|
||||
CodegenUtilKt.generateNullCheckForNonSafeAs(v, rightType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.dup();
|
||||
generateInstanceOfInstruction(rightType);
|
||||
Label ok = new Label();
|
||||
v.ifne(ok);
|
||||
v.pop();
|
||||
v.aconst(null);
|
||||
v.mark(ok);
|
||||
boolean safeAs = opToken == KtTokens.AS_SAFE;
|
||||
Type type = boxType(asmType(rightType));
|
||||
if (TypeUtils.isReifiedTypeParameter(rightType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(rightType,
|
||||
safeAs ? ReifiedTypeInliner.OperationKind.SAFE_AS
|
||||
: ReifiedTypeInliner.OperationKind.AS);
|
||||
v.checkcast(type);
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
generateCheckCastInstruction(rightType, opToken == KtTokens.AS_SAFE);
|
||||
return Unit.INSTANCE$;
|
||||
CodegenUtilKt.generateAsCast(v, rightType, type, safeAs);
|
||||
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3730,11 +3728,11 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
private StackValue generateIsCheck(StackValue expressionToMatch, KtTypeReference typeReference, boolean negated) {
|
||||
KotlinType jetType = bindingContext.get(TYPE, typeReference);
|
||||
markStartLineNumber(typeReference);
|
||||
StackValue value = generateInstanceOf(expressionToMatch, jetType, false);
|
||||
StackValue value = generateIsCheck(expressionToMatch, jetType, false);
|
||||
return negated ? StackValue.not(value) : value;
|
||||
}
|
||||
|
||||
private StackValue generateInstanceOf(final StackValue expressionToGen, final KotlinType kotlinType, final boolean leaveExpressionOnStack) {
|
||||
private StackValue generateIsCheck(final StackValue expressionToGen, final KotlinType kotlinType, final boolean leaveExpressionOnStack) {
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
@@ -3742,46 +3740,35 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
if (leaveExpressionOnStack) {
|
||||
v.dup();
|
||||
}
|
||||
CodegenUtilKt.generateIsCheck(v, kotlinType.isMarkedNullable() && !TypeUtils.isReifiedTypeParameter(kotlinType), new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter adapter) {
|
||||
generateInstanceOfInstruction(kotlinType);
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
|
||||
Type type = boxType(asmType(kotlinType));
|
||||
if (TypeUtils.isReifiedTypeParameter(kotlinType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(kotlinType, ReifiedTypeInliner.OperationKind.IS);
|
||||
v.instanceOf(type);
|
||||
return null;
|
||||
}
|
||||
|
||||
CodegenUtilKt.generateIsCheck(v, kotlinType, type);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void generateInstanceOfInstruction(@NotNull KotlinType jetType) {
|
||||
Type type = boxType(asmType(jetType));
|
||||
putReifierMarkerIfTypeIsReifiedParameter(jetType, ReifiedTypeInliner.INSTANCEOF_MARKER_METHOD_NAME);
|
||||
TypeIntrinsics.instanceOf(v, jetType, type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StackValue generateCheckCastInstruction(@NotNull KotlinType jetType, boolean safeAs) {
|
||||
Type type = boxType(asmType(jetType));
|
||||
putReifierMarkerIfTypeIsReifiedParameter(jetType,
|
||||
safeAs ? ReifiedTypeInliner.SAFE_CHECKCAST_MARKER_METHOD_NAME
|
||||
: ReifiedTypeInliner.CHECKCAST_MARKER_METHOD_NAME);
|
||||
TypeIntrinsics.checkcast(v, jetType, type, safeAs);
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
|
||||
public void putReifierMarkerIfTypeIsReifiedParameter(@NotNull KotlinType type, @NotNull String markerMethodName) {
|
||||
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind
|
||||
) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
|
||||
if (typeParameterDescriptor != null && typeParameterDescriptor.isReified()) {
|
||||
if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) {
|
||||
parentCodegen.getReifiedTypeParametersUsages().
|
||||
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
|
||||
}
|
||||
boolean putNullableFlag = ReifiedTypeInliner.isNullableMarkerInstruction(markerMethodName) && type.isMarkedNullable();
|
||||
v.iconst(operationKind.getId());
|
||||
boolean putNullableFlag = operationKind.isTypeNullabilityAware() && type.isMarkedNullable();
|
||||
v.visitLdcInsn(typeParameterDescriptor.getName().asString() + (putNullableFlag ? "?" : ""));
|
||||
v.invokestatic(
|
||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, markerMethodName,
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
|
||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.REIFIED_OPERATION_MARKER_METHOD_NAME,
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.getType(String.class)), false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3804,11 +3791,12 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
return StackValue.operation(resultType, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
SwitchCodegen switchCodegen =
|
||||
SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(expression, isStatement, ExpressionCodegen.this);
|
||||
SwitchCodegen switchCodegen = SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(
|
||||
expression, isStatement, isExhaustive(expression, isStatement), ExpressionCodegen.this
|
||||
);
|
||||
if (switchCodegen != null) {
|
||||
switchCodegen.generate();
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
int subjectLocal = expr != null ? myFrameMap.enterTemp(subjectType) : -1;
|
||||
@@ -3851,9 +3839,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
}
|
||||
if (!hasElse && nextCondition != null) {
|
||||
v.mark(nextCondition);
|
||||
if (!isStatement) {
|
||||
putUnitInstanceOntoStackForNonExhaustiveWhen(expression);
|
||||
}
|
||||
putUnitInstanceOntoStackForNonExhaustiveWhen(expression, isStatement);
|
||||
}
|
||||
|
||||
markLineNumber(expression, isStatement);
|
||||
@@ -3866,14 +3852,24 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isExhaustive(@NotNull KtWhenExpression whenExpression, boolean isStatement) {
|
||||
if (isStatement) {
|
||||
return Boolean.TRUE.equals(bindingContext.get(BindingContext.IMPLICIT_EXHAUSTIVE_WHEN, whenExpression));
|
||||
}
|
||||
else {
|
||||
return Boolean.TRUE.equals(bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, whenExpression));
|
||||
}
|
||||
}
|
||||
|
||||
public void putUnitInstanceOntoStackForNonExhaustiveWhen(
|
||||
@NotNull KtWhenExpression expression
|
||||
@NotNull KtWhenExpression whenExpression,
|
||||
boolean isStatement
|
||||
) {
|
||||
if (Boolean.TRUE.equals(bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, expression))) {
|
||||
if (isExhaustive(whenExpression, isStatement)) {
|
||||
// when() is supposed to be exhaustive
|
||||
genThrow(v, "kotlin/NoWhenBranchMatchedException", null);
|
||||
}
|
||||
else {
|
||||
else if (!isStatement) {
|
||||
// non-exhaustive when() with no else -> Unit must be expected
|
||||
StackValue.putUnitInstance(v);
|
||||
}
|
||||
|
||||
@@ -33,17 +33,12 @@ public class FieldInfo {
|
||||
|
||||
@NotNull
|
||||
public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper) {
|
||||
return createForSingleton(classDescriptor, typeMapper, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper, boolean oldSingleton) {
|
||||
if (!classDescriptor.getKind().isSingleton() || DescriptorUtils.isEnumEntry(classDescriptor)) {
|
||||
throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor);
|
||||
}
|
||||
|
||||
if (isNonCompanionObject(classDescriptor) || COMPANION_OBJECT_MAPPING.hasMappingToObject(classDescriptor)) {
|
||||
return createSingletonViaInstance(classDescriptor, typeMapper, oldSingleton);
|
||||
return createSingletonViaInstance(classDescriptor, typeMapper);
|
||||
}
|
||||
else {
|
||||
ClassDescriptor ownerDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
|
||||
@@ -56,11 +51,10 @@ public class FieldInfo {
|
||||
@NotNull
|
||||
public static FieldInfo createSingletonViaInstance(
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@NotNull JetTypeMapper typeMapper,
|
||||
boolean oldSingleton
|
||||
@NotNull JetTypeMapper typeMapper
|
||||
) {
|
||||
Type type = typeMapper.mapType(classDescriptor);
|
||||
return new FieldInfo(type, type, oldSingleton ? JvmAbi.DEPRECATED_INSTANCE_FIELD : JvmAbi.INSTANCE_FIELD, true);
|
||||
return new FieldInfo(type, type, JvmAbi.INSTANCE_FIELD, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
|
||||
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
|
||||
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeKt;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
@@ -77,11 +76,12 @@ import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getSuperClassDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -161,7 +161,7 @@ public class FunctionCodegen {
|
||||
int flags = getMethodAsmFlags(functionDescriptor, contextKind);
|
||||
boolean isNative = NativeKt.hasNativeAnnotation(functionDescriptor);
|
||||
|
||||
if (isNative && owner instanceof DelegatingFacadeContext) {
|
||||
if (isNative && owner instanceof MultifileClassFacadeContext) {
|
||||
// Native methods are only defined in facades and do not need package part implementations
|
||||
return;
|
||||
}
|
||||
@@ -172,10 +172,6 @@ public class FunctionCodegen {
|
||||
jvmSignature.getGenericsSignature(),
|
||||
getThrownExceptions(functionDescriptor, typeMapper));
|
||||
|
||||
String implClassName = CodegenContextUtil.getImplementationClassShortName(owner);
|
||||
if (implClassName != null) {
|
||||
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, functionDescriptor, implClassName);
|
||||
}
|
||||
if (CodegenContextUtil.isImplClassOwner(owner)) {
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, functionDescriptor, asmMethod);
|
||||
}
|
||||
@@ -237,22 +233,6 @@ public class FunctionCodegen {
|
||||
else {
|
||||
annotationCodegen.genAnnotations(functionDescriptor, asmMethod.getReturnType());
|
||||
}
|
||||
|
||||
writePackageFacadeMethodAnnotationsIfNeeded(mv);
|
||||
}
|
||||
|
||||
private void writePackageFacadeMethodAnnotationsIfNeeded(MethodVisitor mv) {
|
||||
if (owner instanceof PackageFacadeContext) {
|
||||
PackageFacadeContext packageFacadeContext = (PackageFacadeContext) owner;
|
||||
Type delegateToClassType = packageFacadeContext.getPublicFacadeType();
|
||||
if (delegateToClassType != null) {
|
||||
String className = delegateToClassType.getClassName();
|
||||
AnnotationVisitor
|
||||
av = mv.visitAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_DELEGATED_METHOD), true);
|
||||
av.visit(JvmAnnotationNames.IMPLEMENTATION_CLASS_NAME_FIELD_NAME, className);
|
||||
av.visitEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateParameterAnnotations(
|
||||
@@ -273,9 +253,6 @@ public class FunctionCodegen {
|
||||
|
||||
if (kind == JvmMethodParameterKind.VALUE) {
|
||||
ValueParameterDescriptor parameter = iterator.next();
|
||||
if (parameter.getIndex() != i) {
|
||||
v.getSerializationBindings().put(INDEX_FOR_VALUE_PARAMETER, parameter, i);
|
||||
}
|
||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper);
|
||||
|
||||
if (functionDescriptor instanceof PropertySetterDescriptor) {
|
||||
@@ -364,8 +341,8 @@ public class FunctionCodegen {
|
||||
int functionFakeIndex = -1;
|
||||
int lambdaFakeIndex = -1;
|
||||
|
||||
if (context.getParentContext() instanceof DelegatingFacadeContext) {
|
||||
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (DelegatingFacadeContext) context.getParentContext());
|
||||
if (context.getParentContext() instanceof MultifileClassFacadeContext) {
|
||||
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (MultifileClassFacadeContext) context.getParentContext());
|
||||
methodEnd = new Label();
|
||||
}
|
||||
else {
|
||||
@@ -468,9 +445,9 @@ public class FunctionCodegen {
|
||||
private static void generateFacadeDelegateMethodBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull Method asmMethod,
|
||||
@NotNull DelegatingFacadeContext context
|
||||
@NotNull MultifileClassFacadeContext context
|
||||
) {
|
||||
generateDelegateToMethodBody(true, mv, asmMethod, context.getDelegateToClassType().getInternalName());
|
||||
generateDelegateToMethodBody(true, mv, asmMethod, context.getFilePartType().getInternalName());
|
||||
}
|
||||
|
||||
private static void generateDelegateToMethodBody(
|
||||
@@ -693,9 +670,9 @@ public class FunctionCodegen {
|
||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType());
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
if (this.owner instanceof DelegatingFacadeContext) {
|
||||
if (this.owner instanceof MultifileClassFacadeContext) {
|
||||
mv.visitCode();
|
||||
generateFacadeDelegateMethodBody(mv, defaultMethod, (DelegatingFacadeContext) this.owner);
|
||||
generateFacadeDelegateMethodBody(mv, defaultMethod, (MultifileClassFacadeContext) this.owner);
|
||||
endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
|
||||
}
|
||||
else {
|
||||
@@ -909,13 +886,7 @@ public class FunctionCodegen {
|
||||
iv.ifnonnull(afterBarrier);
|
||||
}
|
||||
else {
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType.isMarkedNullable(), new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter adapter) {
|
||||
TypeIntrinsics.instanceOf(adapter, kotlinType, boxType(delegateParameterType));
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType, boxType(delegateParameterType));
|
||||
iv.ifne(afterBarrier);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
@@ -62,8 +62,8 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
@@ -247,11 +247,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
@Override
|
||||
protected void generateKotlinAnnotation() {
|
||||
if (!isTopLevelOrInnerClass(descriptor)) {
|
||||
AnnotationVisitor av = v.getVisitor().visitAnnotation(
|
||||
asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_LOCAL_CLASS), true
|
||||
);
|
||||
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
|
||||
av.visitEnd();
|
||||
v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_LOCAL_CLASS), true).visitEnd();
|
||||
}
|
||||
|
||||
DescriptorSerializer serializer =
|
||||
@@ -840,22 +836,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateFieldForSingleton() {
|
||||
if (isEnumEntry(descriptor)) return;
|
||||
if (isEnumEntry(descriptor) || isCompanionObject(descriptor)) return;
|
||||
|
||||
boolean isCompanionObject = isCompanionObject(descriptor);
|
||||
if (isNonCompanionObject(descriptor) || isCompanionObject) {
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.Field field = StackValue.singletonViaInstance(descriptor, typeMapper);
|
||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass),
|
||||
ACC_PUBLIC | ACC_STATIC | ACC_FINAL | (isCompanionObject ? ACC_DEPRECATED : 0),
|
||||
ACC_PUBLIC | ACC_STATIC | ACC_FINAL,
|
||||
field.name, field.type.getDescriptor(), null, null);
|
||||
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.Field oldField = StackValue.oldSingleton(descriptor, typeMapper);
|
||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass), ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_DEPRECATED, oldField.name, oldField.type.getDescriptor(), null, null);
|
||||
}
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||
// Invoke the object constructor but ignore the result because INSTANCE$ will be initialized in the first line of <init>
|
||||
// Invoke the object constructor but ignore the result because INSTANCE will be initialized in the first line of <init>
|
||||
InstructionAdapter v = createOrGetClInitCodegen().v;
|
||||
markLineNumberForElement(element, v);
|
||||
v.anew(classAsmType);
|
||||
@@ -874,12 +864,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
|
||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject), ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||
|
||||
if (!isCompanionObjectWithBackingFieldsInOuter(companionObjectDescriptor)) {
|
||||
generateCompanionObjectInitializer(companionObjectDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateCompanionObjectBackingFieldCopies() {
|
||||
@@ -889,7 +873,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
PropertyDescriptor property = info.descriptor;
|
||||
|
||||
Type type = typeMapper.mapType(property);
|
||||
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC | (property.isConst() ? 0 : ACC_DEPRECATED);
|
||||
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC;
|
||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.Synthetic(DescriptorToSourceUtils.descriptorToDeclaration(property), property),
|
||||
modifiers, context.getFieldName(property, false),
|
||||
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property),
|
||||
@@ -931,13 +915,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private void generateCompanionObjectInitializer(@NotNull ClassDescriptor companionObject) {
|
||||
ExpressionCodegen codegen = createOrGetClInitCodegen();
|
||||
//TODO: uncomment when DEPRECATED INSTANCE is removed
|
||||
//FunctionDescriptor constructor = (FunctionDescriptor) context.accessibleDescriptor(
|
||||
// CollectionsKt.single(companionObject.getConstructors()), /* superCallExpression = */ null
|
||||
//);
|
||||
//generateMethodCallTo(constructor, null, codegen.v);
|
||||
//StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
|
||||
StackValue.singleton(companionObject, typeMapper).store(StackValue.singletonViaInstance(companionObject, typeMapper), codegen.v, true);
|
||||
|
||||
FunctionDescriptor constructor = (FunctionDescriptor) context.accessibleDescriptor(
|
||||
CollectionsKt.single(companionObject.getConstructors()), /* superCallExpression = */ null
|
||||
);
|
||||
generateMethodCallTo(constructor, null, codegen.v);
|
||||
StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
|
||||
StackValue.singleton(companionObject, typeMapper).store(instance, codegen.v, true);
|
||||
}
|
||||
|
||||
private void generatePrimaryConstructor(final DelegationFieldsInfo delegationFieldsInfo) {
|
||||
@@ -1007,11 +991,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor,
|
||||
getDelegationConstructorCall(bindingContext, constructorDescriptor));
|
||||
|
||||
if (isObject(descriptor)) {
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.singletonViaInstance(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.oldSingleton(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
|
||||
}
|
||||
}
|
||||
|
||||
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
|
||||
@@ -1035,9 +1016,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
curParam++;
|
||||
}
|
||||
|
||||
if (isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
|
||||
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
|
||||
if (isCompanionObject(descriptor)) {
|
||||
ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
|
||||
parentCodegen.generateCompanionObjectInitializer(descriptor);
|
||||
}
|
||||
|
||||
if (JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
|
||||
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
|
||||
generateInitializers(new Function0<ExpressionCodegen>() {
|
||||
@Override
|
||||
public ExpressionCodegen invoke() {
|
||||
|
||||
@@ -32,9 +32,9 @@ public class InlineCycleReporter(val diagnostics: DiagnosticSink) {
|
||||
if (call != null) {
|
||||
val callElement = call.getCall().getCallElement()
|
||||
if (processingFunctions.contains(callElement)) {
|
||||
val cycle = processingFunctions.asSequence().dropWhile { it.getKey() != callElement }
|
||||
val cycle = processingFunctions.asSequence().dropWhile { it.key != callElement }
|
||||
cycle.forEach {
|
||||
diagnostics.report(Errors.INLINE_CALL_CYCLE.on(it.getKey(), it.getValue()))
|
||||
diagnostics.report(Errors.INLINE_CALL_CYCLE.on(it.key, it.value))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_INTERFACE_DEFAULT_IMPLS
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -124,7 +123,7 @@ public class InterfaceImplBodyCodegen(
|
||||
val myParameters = signature.getValueParameters()
|
||||
val calleeParameters = method.getValueParameters()
|
||||
|
||||
if (myParameters.size() != calleeParameters.size()) {
|
||||
if (myParameters.size != calleeParameters.size) {
|
||||
throw AssertionError(
|
||||
"Method from super interface has a different signature.\n" +
|
||||
"This method:\n%s\n%s\n%s\nSuper method:\n%s\n%s\n%s".format(
|
||||
@@ -151,9 +150,7 @@ public class InterfaceImplBodyCodegen(
|
||||
override fun generateKotlinAnnotation() {
|
||||
(v as InterfaceImplClassBuilder).stopCounting()
|
||||
|
||||
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS), true)
|
||||
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray())
|
||||
av.visitEnd()
|
||||
v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS), true).visitEnd()
|
||||
AsmUtil.writeKotlinSyntheticClassAnnotation(v, state)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.StringsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.text.StringsKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -50,6 +50,7 @@ import java.io.File;
|
||||
|
||||
import static org.jetbrains.kotlin.descriptors.Modality.ABSTRACT;
|
||||
import static org.jetbrains.kotlin.descriptors.Modality.FINAL;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
|
||||
|
||||
public class JvmCodegenUtil {
|
||||
|
||||
@@ -130,6 +131,10 @@ public class JvmCodegenUtil {
|
||||
);
|
||||
}
|
||||
|
||||
public static boolean isConstOrHasJvmFieldAnnotation(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return propertyDescriptor.isConst() || hasJvmFieldAnnotation(propertyDescriptor);
|
||||
}
|
||||
|
||||
public static boolean couldUseDirectAccessToProperty(
|
||||
@NotNull PropertyDescriptor property,
|
||||
boolean forGetter,
|
||||
@@ -219,9 +224,6 @@ public class JvmCodegenUtil {
|
||||
|
||||
public static void writeAbiVersion(@NotNull AnnotationVisitor av) {
|
||||
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
|
||||
|
||||
// TODO: drop after some time
|
||||
av.visit(JvmAnnotationNames.OLD_ABI_VERSION_FIELD_NAME, 32);
|
||||
}
|
||||
|
||||
public static void writeModuleName(@NotNull AnnotationVisitor av, @NotNull GenerationState state) {
|
||||
|
||||
@@ -40,7 +40,7 @@ public class JvmRuntimeTypes {
|
||||
|
||||
public JvmRuntimeTypes() {
|
||||
ModuleDescriptorImpl module = TargetPlatformKt.createModule(
|
||||
JvmPlatform.INSTANCE$,
|
||||
JvmPlatform.INSTANCE,
|
||||
Name.special("<jvm functions impl>"),
|
||||
LockBasedStorageManager.NO_LOCKS
|
||||
);
|
||||
|
||||
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
@@ -46,7 +44,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.storage.NotNullLazyValue;
|
||||
@@ -305,7 +302,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
if (outermost instanceof ClassContext) {
|
||||
return typeMapper.mapType(((ClassContext) outermost).getContextDescriptor());
|
||||
}
|
||||
else if (outermost instanceof DelegatingFacadeContext || outermost instanceof DelegatingToPartContext) {
|
||||
else if (outermost instanceof MultifileClassFacadeContext || outermost instanceof DelegatingToPartContext) {
|
||||
Type implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(outermost);
|
||||
if (implementationOwnerType != null) {
|
||||
return implementationOwnerType;
|
||||
@@ -498,37 +495,23 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
iv.dup();
|
||||
iv.iconst(i);
|
||||
|
||||
StackValue value;
|
||||
// TODO: remove this option and always generate PropertyReferenceNImpl creation
|
||||
if ("true".equalsIgnoreCase(System.getProperty("kotlin.jvm.optimize.delegated.properties"))) {
|
||||
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) +
|
||||
(property.getExtensionReceiverParameter() != null ? 1 : 0);
|
||||
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
|
||||
iv.anew(implType);
|
||||
iv.dup();
|
||||
// TODO: generate the container once and save to a local field instead
|
||||
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
|
||||
iv.aconst(property.getName().asString());
|
||||
iv.aconst(PropertyReferenceCodegen.getPropertyReferenceSignature(property, state));
|
||||
iv.invokespecial(
|
||||
implType.getInternalName(), "<init>",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
|
||||
);
|
||||
value = StackValue.onStack(implType);
|
||||
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
|
||||
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
|
||||
}
|
||||
else {
|
||||
ReceiverParameterDescriptor dispatchReceiver = property.getDispatchReceiverParameter();
|
||||
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) +
|
||||
(property.getExtensionReceiverParameter() != null ? 1 : 0);
|
||||
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
|
||||
iv.anew(implType);
|
||||
iv.dup();
|
||||
// TODO: generate the container once and save to a local field instead (KT-10495)
|
||||
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
|
||||
iv.aconst(property.getName().asString());
|
||||
iv.aconst(PropertyReferenceCodegen.getPropertyReferenceSignature(property, state));
|
||||
iv.invokespecial(
|
||||
implType.getInternalName(), "<init>",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
|
||||
);
|
||||
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
|
||||
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
value = createOrGetClInitCodegen().generatePropertyReference(
|
||||
delegatedProperties.get(i).getDelegate(), property, property,
|
||||
dispatchReceiver != null ? new TransientReceiver(dispatchReceiver.getType()) : null
|
||||
);
|
||||
}
|
||||
|
||||
value.put(K_PROPERTY_TYPE, iv);
|
||||
StackValue.onStack(implType).put(K_PROPERTY_TYPE, iv);
|
||||
|
||||
iv.astore(K_PROPERTY_TYPE);
|
||||
}
|
||||
@@ -567,20 +550,17 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
return sourceMapper;
|
||||
}
|
||||
|
||||
protected void generateConstInstance(
|
||||
@NotNull Type thisAsmType,
|
||||
@NotNull Type fieldAsmType,
|
||||
@NotNull Function1<InstructionAdapter, Unit> initialization
|
||||
) {
|
||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor(),
|
||||
null, null);
|
||||
protected void generateConstInstance(@NotNull Type thisAsmType, @NotNull Type fieldAsmType) {
|
||||
v.newField(
|
||||
JvmDeclarationOriginKt.OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD,
|
||||
fieldAsmType.getDescriptor(), null, null
|
||||
);
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
InstructionAdapter iv = createOrGetClInitCodegen().v;
|
||||
iv.anew(thisAsmType);
|
||||
iv.dup();
|
||||
iv.invokespecial(thisAsmType.getInternalName(), "<init>", "()V", false);
|
||||
initialization.invoke(iv);
|
||||
iv.putstatic(thisAsmType.getInternalName(), JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor());
|
||||
}
|
||||
}
|
||||
@@ -621,7 +601,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
@Override
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
boolean syntheticBackingField = accessor instanceof AccessorForPropertyBackingFieldFromLocal;
|
||||
boolean forceField = (AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
|
||||
boolean forceField = (JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
|
||||
!isCompanionObject(accessor.getContainingDeclaration())) ||
|
||||
syntheticBackingField ||
|
||||
original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY;
|
||||
@@ -672,7 +652,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue generateMethodCallTo(
|
||||
protected StackValue generateMethodCallTo(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@Nullable FunctionDescriptor accessorDescriptor,
|
||||
@NotNull InstructionAdapter iv
|
||||
|
||||
@@ -312,7 +312,7 @@ public class MultifileClassCodegen(
|
||||
fragments.add(fragment)
|
||||
}
|
||||
}
|
||||
if (fragments.size() > 1) {
|
||||
if (fragments.size > 1) {
|
||||
throw IllegalStateException("More than one package fragment, files: $files | fragments: $fragments")
|
||||
}
|
||||
return fragments.firstOrNull()
|
||||
|
||||
@@ -54,10 +54,14 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getDeprecatedAccessFlag;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PROPERTY_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -97,7 +101,7 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
public void generateInPackageFacade(@NotNull DeserializedPropertyDescriptor deserializedProperty) {
|
||||
assert context instanceof DelegatingFacadeContext : "should be called only for generating facade: " + context;
|
||||
assert context instanceof MultifileClassFacadeContext : "should be called only for generating facade: " + context;
|
||||
gen(null, deserializedProperty, null, null);
|
||||
}
|
||||
|
||||
@@ -110,11 +114,6 @@ public class PropertyCodegen {
|
||||
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.DEFAULT_IMPLS
|
||||
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
|
||||
|
||||
String implClassName = CodegenContextUtil.getImplementationClassShortName(context);
|
||||
if (implClassName != null) {
|
||||
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, implClassName);
|
||||
}
|
||||
|
||||
if (CodegenContextUtil.isImplClassOwner(context)) {
|
||||
assert declaration != null : "Declaration is null for different context: " + context;
|
||||
|
||||
@@ -155,7 +154,7 @@ public class PropertyCodegen {
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@Nullable KtPropertyAccessor accessor
|
||||
) {
|
||||
if (hasJvmFieldAnnotation(descriptor)) return false;
|
||||
if (isConstOrHasJvmFieldAnnotation(descriptor)) return false;
|
||||
|
||||
boolean isDefaultAccessor = accessor == null || !accessor.hasBody();
|
||||
|
||||
@@ -265,10 +264,6 @@ public class PropertyCodegen {
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
mv.visitEnd();
|
||||
}
|
||||
else {
|
||||
Type tImplType = typeMapper.mapDefaultImpls((ClassDescriptor) context.getContextDescriptor());
|
||||
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, shortNameByAsmType(tImplType));
|
||||
}
|
||||
|
||||
if (kind != OwnerKind.DEFAULT_IMPLS) {
|
||||
v.getSerializationBindings().put(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor, new Method(name, desc));
|
||||
@@ -307,46 +302,17 @@ public class PropertyCodegen {
|
||||
|
||||
ClassBuilder builder = v;
|
||||
|
||||
boolean hasJvmFieldAnnotation = hasJvmFieldAnnotation(propertyDescriptor);
|
||||
|
||||
FieldOwnerContext backingFieldContext = context;
|
||||
boolean takeVisibilityFromDescriptor = propertyDescriptor.isLateInit() || propertyDescriptor.isConst();
|
||||
if (AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
|
||||
modifiers |= ACC_STATIC;
|
||||
|
||||
if (takeVisibilityFromDescriptor) {
|
||||
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
|
||||
}
|
||||
else if (hasJvmFieldAnnotation && !isDelegate) {
|
||||
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
|
||||
}
|
||||
else {
|
||||
modifiers |= getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate);
|
||||
}
|
||||
|
||||
if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
|
||||
if (JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
|
||||
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
||||
builder = codegen.v;
|
||||
backingFieldContext = codegen.context;
|
||||
v.getSerializationBindings().put(STATIC_FIELD_IN_OUTER_CLASS, propertyDescriptor);
|
||||
}
|
||||
|
||||
if (isObject(propertyDescriptor.getContainingDeclaration()) &&
|
||||
!hasJvmFieldAnnotation &&
|
||||
!propertyDescriptor.isConst() &&
|
||||
(modifiers & ACC_PRIVATE) == 0) {
|
||||
modifiers |= ACC_DEPRECATED;
|
||||
}
|
||||
}
|
||||
else if (takeVisibilityFromDescriptor) {
|
||||
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
|
||||
}
|
||||
else if (!isDelegate && hasJvmFieldAnnotation) {
|
||||
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
|
||||
}
|
||||
else {
|
||||
modifiers |= ACC_PRIVATE;
|
||||
}
|
||||
modifiers |= getVisibilityForBackingField(propertyDescriptor, isDelegate);
|
||||
|
||||
if (AsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) {
|
||||
ImplementationBodyCodegen parentBodyCodegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
||||
|
||||
@@ -28,11 +28,11 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.PropertyImportedFromObject
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -45,14 +45,13 @@ public class PropertyReferenceCodegen(
|
||||
context: ClassContext,
|
||||
expression: KtElement,
|
||||
classBuilder: ClassBuilder,
|
||||
private val classDescriptor: ClassDescriptor,
|
||||
private val target: VariableDescriptor,
|
||||
dispatchReceiver: ReceiverValue?
|
||||
resolvedCall: ResolvedCall<*>
|
||||
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
|
||||
private val classDescriptor = context.contextDescriptor
|
||||
private val asmType = typeMapper.mapClass(classDescriptor)
|
||||
|
||||
private val dispatchReceiverType = dispatchReceiver?.type
|
||||
|
||||
private val target = resolvedCall.resultingDescriptor as VariableDescriptor
|
||||
private val dispatchReceiverType = resolvedCall.dispatchReceiver?.type
|
||||
private val extensionReceiverType = target.extensionReceiverParameter?.type
|
||||
|
||||
private val receiverCount =
|
||||
@@ -80,11 +79,7 @@ public class PropertyReferenceCodegen(
|
||||
|
||||
// TODO: ImplementationBodyCodegen.markLineNumberForSyntheticFunction?
|
||||
override fun generateBody() {
|
||||
generateConstInstance(asmType, wrapperMethod.getReturnType()) { iv ->
|
||||
if (!"true".equals(System.getProperty("kotlin.jvm.optimize.callable.references"), ignoreCase = true)) {
|
||||
iv.invokestatic(REFLECTION, wrapperMethod.getName(), wrapperMethod.getDescriptor(), false)
|
||||
}
|
||||
}
|
||||
generateConstInstance(asmType, wrapperMethod.getReturnType())
|
||||
|
||||
generateMethod("property reference init", 0, method("<init>", Type.VOID_TYPE)) {
|
||||
load(0, OBJECT_TYPE)
|
||||
|
||||
@@ -67,7 +67,7 @@ public abstract class SignatureCollectingClassBuilderFactory(
|
||||
|
||||
override fun done() {
|
||||
for ((signature, elementsAndDescriptors) in signatures.entrySet()) {
|
||||
if (elementsAndDescriptors.size() == 1) continue // no clash
|
||||
if (elementsAndDescriptors.size == 1) continue // no clash
|
||||
handleClashingSignatures(ConflictingJvmDeclarationsData(
|
||||
classInternalName,
|
||||
classCreatedFor,
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import kotlin.ArraysKt;
|
||||
import kotlin.collections.ArraysKt;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty;
|
||||
@@ -45,6 +46,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -597,11 +599,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
public static Field singletonViaInstance(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
|
||||
return field(FieldInfo.createSingletonViaInstance(classDescriptor, typeMapper, false), none());
|
||||
}
|
||||
|
||||
public static Field oldSingleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
|
||||
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper, true), none());
|
||||
return field(FieldInfo.createSingletonViaInstance(classDescriptor, typeMapper), none());
|
||||
}
|
||||
|
||||
public static StackValue operation(Type type, Function1<InstructionAdapter, Unit> lambda) {
|
||||
@@ -1090,6 +1088,12 @@ public abstract class StackValue {
|
||||
else {
|
||||
getter.genInvokeInstruction(v);
|
||||
coerce(getter.getReturnType(), type, v);
|
||||
|
||||
KotlinType returnType = descriptor.getReturnType();
|
||||
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
|
||||
v.aconst(null);
|
||||
v.athrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@ public final class PsiCodegenPredictor {
|
||||
// TODO: Method won't work for declarations inside companion objects
|
||||
// TODO: Method won't give correct class name for traits implementations
|
||||
|
||||
if (declaration instanceof KtPropertyAccessor) {
|
||||
return getPredefinedJvmInternalName(((KtPropertyAccessor) declaration).getProperty(), fileClassesProvider);
|
||||
}
|
||||
KtDeclaration parentDeclaration = KtStubbedPsiUtil.getContainingDeclaration(declaration);
|
||||
|
||||
String parentInternalName;
|
||||
@@ -73,8 +76,8 @@ public final class PsiCodegenPredictor {
|
||||
else {
|
||||
KtFile containingFile = declaration.getContainingKtFile();
|
||||
|
||||
if (declaration instanceof KtNamedFunction) {
|
||||
Name name = ((KtNamedFunction) declaration).getNameAsName();
|
||||
if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty) {
|
||||
Name name = ((KtNamedDeclaration) declaration).getNameAsName();
|
||||
return name == null ? null : FileClasses.getFileClassInternalName(fileClassesProvider, containingFile) + "$" + name.asString();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ private fun List<PackageParts>.addCompiledParts(state: GenerationState): List<Pa
|
||||
mapping.findPackageParts(qualifier)?.run { parts.remove(name) }
|
||||
}
|
||||
|
||||
return (this + mapping.packageFqName2Parts.values())
|
||||
return (this + mapping.packageFqName2Parts.values)
|
||||
.groupBy { it.packageFqName }
|
||||
.map {
|
||||
val (packageFqName, packageParts) = it
|
||||
|
||||
@@ -18,24 +18,28 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
fun generateIsCheck(
|
||||
v: InstructionAdapter,
|
||||
isNullable: Boolean,
|
||||
generateInstanceOfInstruction: (InstructionAdapter) -> Unit
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type
|
||||
) {
|
||||
if (isNullable) {
|
||||
if (TypeUtils.isNullableType(kotlinType)) {
|
||||
val nope = Label()
|
||||
val end = Label()
|
||||
|
||||
@@ -44,7 +48,8 @@ fun generateIsCheck(
|
||||
|
||||
ifnull(nope)
|
||||
|
||||
generateInstanceOfInstruction(this)
|
||||
TypeIntrinsics.instanceOf(this, kotlinType, asmType)
|
||||
|
||||
goTo(end)
|
||||
|
||||
mark(nope)
|
||||
@@ -55,11 +60,37 @@ fun generateIsCheck(
|
||||
}
|
||||
}
|
||||
else {
|
||||
generateInstanceOfInstruction(v)
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateNullCheckForNonSafeAs(
|
||||
fun generateAsCast(
|
||||
v: InstructionAdapter,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type,
|
||||
isSafe: Boolean
|
||||
) {
|
||||
if (!isSafe) {
|
||||
if (!TypeUtils.isNullableType(kotlinType)) {
|
||||
generateNullCheckForNonSafeAs(v, kotlinType)
|
||||
}
|
||||
}
|
||||
else {
|
||||
with(v) {
|
||||
dup()
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
|
||||
val ok = Label()
|
||||
ifne(ok)
|
||||
pop()
|
||||
aconst(null)
|
||||
mark(ok)
|
||||
}
|
||||
}
|
||||
|
||||
TypeIntrinsics.checkcast(v, kotlinType, asmType, isSafe)
|
||||
}
|
||||
|
||||
private fun generateNullCheckForNonSafeAs(
|
||||
v: InstructionAdapter,
|
||||
type: KotlinType
|
||||
) {
|
||||
@@ -82,7 +113,7 @@ fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObject
|
||||
return
|
||||
}
|
||||
|
||||
if (!AsmUtil.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
|
||||
if (!JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
|
||||
return
|
||||
}
|
||||
val properties = companion.declarations.filterIsInstance<KtProperty>()
|
||||
|
||||
@@ -16,24 +16,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.context
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
|
||||
public object CodegenContextUtil {
|
||||
@JvmStatic
|
||||
public fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
|
||||
when (owner) {
|
||||
is DelegatingFacadeContext -> owner.delegateToClassType
|
||||
is MultifileClassFacadeContext -> owner.filePartType
|
||||
is DelegatingToPartContext -> owner.implementationOwnerClassType
|
||||
else -> null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun getImplementationClassShortName(owner: CodegenContext<*>): String? =
|
||||
getImplementationOwnerClassType(owner)?.let { AsmUtil.shortNameByAsmType(it) }
|
||||
|
||||
@JvmStatic
|
||||
public fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
|
||||
owner !is DelegatingFacadeContext
|
||||
}
|
||||
owner !is MultifileClassFacadeContext
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class DefaultImplsClassContext(
|
||||
override fun getAccessors(): Collection<AccessorForCallableDescriptor<*>> {
|
||||
val accessors = super.getAccessors()
|
||||
val alreadyExistKeys = accessors.map ({ Pair(it.calleeDescriptor, it.superCallTarget) })
|
||||
val filtered = interfaceContext.accessors.toMap ({ Pair(it.calleeDescriptor, it.superCallTarget) }, {it}) - alreadyExistKeys
|
||||
val filtered = interfaceContext.accessors.toMapBy({ Pair(it.calleeDescriptor, it.superCallTarget) }, { it }) - alreadyExistKeys
|
||||
return accessors + filtered.values
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.context;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public interface DelegatingFacadeContext {
|
||||
@Nullable
|
||||
Type getDelegateToClassType();
|
||||
}
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.context;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public class MultifileClassFacadeContext extends MultifileClassContextBase implements DelegatingFacadeContext {
|
||||
public class MultifileClassFacadeContext extends MultifileClassContextBase {
|
||||
public MultifileClassFacadeContext(
|
||||
PackageFragmentDescriptor descriptor,
|
||||
CodegenContext parent,
|
||||
@@ -29,10 +28,4 @@ public class MultifileClassFacadeContext extends MultifileClassContextBase imple
|
||||
) {
|
||||
super(descriptor, parent, multifileClassType, filePartType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Type getDelegateToClassType() {
|
||||
return getFilePartType();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor> implements DelegatingToPartContext, FacadePartWithSourceFile {
|
||||
private final Type packagePartType;
|
||||
@Nullable private KtFile sourceFile;
|
||||
private final KtFile sourceFile;
|
||||
|
||||
public PackageContext(
|
||||
@NotNull PackageFragmentDescriptor contextDescriptor,
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.context;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public class PackageFacadeContext extends PackageContext implements DelegatingFacadeContext {
|
||||
private final Type publicFacadeType;
|
||||
|
||||
public PackageFacadeContext(
|
||||
@NotNull PackageFragmentDescriptor contextDescriptor,
|
||||
@NotNull CodegenContext parent,
|
||||
@NotNull Type packagePartType
|
||||
) {
|
||||
this(contextDescriptor, parent, packagePartType, packagePartType);
|
||||
}
|
||||
|
||||
public PackageFacadeContext(
|
||||
@NotNull PackageFragmentDescriptor contextDescriptor,
|
||||
@NotNull CodegenContext parent,
|
||||
@NotNull Type packagePartType,
|
||||
@NotNull Type publicFacadeType
|
||||
) {
|
||||
super(contextDescriptor, parent, packagePartType, null);
|
||||
|
||||
this.publicFacadeType = publicFacadeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Type getDelegateToClassType() {
|
||||
return getPackagePartType();
|
||||
}
|
||||
|
||||
public Type getPublicFacadeType() {
|
||||
return publicFacadeType;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.context;
|
||||
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.FieldInfo;
|
||||
|
||||
@@ -88,6 +88,8 @@ public class AnonymousObjectTransformer {
|
||||
reader.accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) {
|
||||
@Override
|
||||
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
|
||||
InlineCodegenUtil.assertVersionNotGreaterThanJava6(version);
|
||||
|
||||
if (signature != null) {
|
||||
ReifiedTypeInliner.SignatureReificationResult signatureResult = inliningContext.reifedTypeInliner.reifySignature(signature);
|
||||
signature = signatureResult.getNewSignature();
|
||||
@@ -97,7 +99,7 @@ public class AnonymousObjectTransformer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClass(String name, String outerName, String innerName, int access) {
|
||||
public void visitInnerClass(@NotNull String name, String outerName, String innerName, int access) {
|
||||
innerClassNodes.add(new InnerClassNode(name, outerName, innerName, access));
|
||||
}
|
||||
|
||||
@@ -162,7 +164,7 @@ public class AnonymousObjectTransformer {
|
||||
}
|
||||
else {
|
||||
//seems we can't do any clever mapping cause we don't know any about original class name
|
||||
sourceMapper = IdenticalSourceMapper.INSTANCE$;
|
||||
sourceMapper = IdenticalSourceMapper.INSTANCE;
|
||||
}
|
||||
if (sourceInfo != null && !InlineCodegenUtil.GENERATE_SMAP) {
|
||||
classBuilder.visitSource(sourceInfo, debugInfo);
|
||||
@@ -172,7 +174,7 @@ public class AnonymousObjectTransformer {
|
||||
if (sourceInfo != null) {
|
||||
classBuilder.visitSource(sourceInfo, debugInfo);
|
||||
}
|
||||
sourceMapper = IdenticalSourceMapper.INSTANCE$;
|
||||
sourceMapper = IdenticalSourceMapper.INSTANCE;
|
||||
}
|
||||
|
||||
ParametersBuilder allCapturedParamBuilder = ParametersBuilder.newBuilder();
|
||||
@@ -180,7 +182,7 @@ public class AnonymousObjectTransformer {
|
||||
List<CapturedParamInfo> additionalFakeParams =
|
||||
extractParametersMappingAndPatchConstructor(constructor, allCapturedParamBuilder, constructorParamBuilder,
|
||||
anonymousObjectGen, parentRemapper);
|
||||
List<MethodVisitor> deferringMethods = new ArrayList();
|
||||
List<MethodVisitor> deferringMethods = new ArrayList<MethodVisitor>();
|
||||
|
||||
for (MethodNode next : methodsToTransform) {
|
||||
MethodVisitor deferringVisitor = newMethod(classBuilder, next);
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache;
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents;
|
||||
import org.jetbrains.kotlin.modules.TargetId;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
@@ -192,11 +193,15 @@ public class InlineCodegen extends CallGenerator {
|
||||
JetTypeMapper.ContainingClassesInfo containingClasses = typeMapper.getContainingClassesForDeserializedCallable(
|
||||
(DeserializedSimpleFunctionDescriptor) functionDescriptor);
|
||||
|
||||
VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable(containingClasses.getImplClassId(), state);
|
||||
nodeAndSMAP = InlineCodegenUtil.getMethodNode(file.contentsToByteArray(),
|
||||
asmMethod.getName(),
|
||||
asmMethod.getDescriptor(),
|
||||
containingClasses.getFacadeClassId());
|
||||
ClassId containerId = containingClasses.getImplClassId();
|
||||
VirtualFile file = InlineCodegenUtil.findVirtualFile(state, containerId);
|
||||
if (file == null) {
|
||||
throw new IllegalStateException("Couldn't find declaration file for " + containerId);
|
||||
}
|
||||
|
||||
nodeAndSMAP = InlineCodegenUtil.getMethodNode(
|
||||
file.contentsToByteArray(), asmMethod.getName(), asmMethod.getDescriptor(), containingClasses.getFacadeClassId()
|
||||
);
|
||||
|
||||
if (nodeAndSMAP == null) {
|
||||
throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import kotlin.StringsKt;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
@@ -92,6 +91,10 @@ public class InlineCodegenUtil {
|
||||
lines[0] = Integer.MAX_VALUE;
|
||||
lines[1] = Integer.MIN_VALUE;
|
||||
cr.accept(new ClassVisitor(API) {
|
||||
@Override
|
||||
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
|
||||
assertVersionNotGreaterThanJava6(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSource(String source, String debug) {
|
||||
@@ -127,40 +130,44 @@ public class InlineCodegenUtil {
|
||||
return new SMAPAndMethodNode(node[0], smap);
|
||||
}
|
||||
|
||||
public static void initDefaultSourceMappingIfNeeded(@NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state) {
|
||||
if (state.isInlineEnabled()) {
|
||||
CodegenContext<?> parentContext = context.getParentContext();
|
||||
while (parentContext != null) {
|
||||
if (parentContext instanceof MethodContext) {
|
||||
if (((MethodContext) parentContext).isInlineMethodContext()) {
|
||||
//just init default one to one mapping
|
||||
codegen.getOrCreateSourceMapper();
|
||||
break;
|
||||
}
|
||||
}
|
||||
parentContext = parentContext.getParentContext();
|
||||
}
|
||||
public static void assertVersionNotGreaterThanJava6(int version) {
|
||||
// TODO: report a proper diagnostic
|
||||
if (version > Opcodes.V1_6) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot inline bytecode of version " + version + ". " +
|
||||
"This compiler can only inline Java 1.6 bytecode (version " + Opcodes.V1_6 + ")"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static VirtualFile getVirtualFileForCallable(@NotNull ClassId containerClassId, @NotNull GenerationState state) {
|
||||
JvmVirtualFileFinder fileFinder = JvmVirtualFileFinder.SERVICE.getInstance(state.getProject());
|
||||
VirtualFile file = fileFinder.findVirtualFileWithHeader(containerClassId);
|
||||
if (file == null) {
|
||||
throw new IllegalStateException("Couldn't find declaration file for " + containerClassId);
|
||||
public static void initDefaultSourceMappingIfNeeded(
|
||||
@NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state
|
||||
) {
|
||||
if (!state.isInlineEnabled()) return;
|
||||
|
||||
CodegenContext<?> parentContext = context.getParentContext();
|
||||
while (parentContext != null) {
|
||||
if (parentContext.isInlineMethodContext()) {
|
||||
//just init default one to one mapping
|
||||
codegen.getOrCreateSourceMapper();
|
||||
break;
|
||||
}
|
||||
parentContext = parentContext.getParentContext();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile findVirtualFile(@NotNull Project project, @NotNull String internalClassName) {
|
||||
public static VirtualFile findVirtualFile(@NotNull GenerationState state, @NotNull ClassId classId) {
|
||||
return JvmVirtualFileFinder.SERVICE.getInstance(state.getProject()).findVirtualFileWithHeader(classId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile findVirtualFileImprecise(@NotNull GenerationState state, @NotNull String internalClassName) {
|
||||
FqName packageFqName = JvmClassName.byInternalName(internalClassName).getPackageFqName();
|
||||
String classNameWithDollars = StringsKt.substringAfterLast(internalClassName, "/", internalClassName);
|
||||
JvmVirtualFileFinder fileFinder = JvmVirtualFileFinder.SERVICE.getInstance(project);
|
||||
//TODO: we cannot construct proper classId at this point, we need to read InnerClasses info from class file
|
||||
// we construct valid.package.name/RelativeClassNameAsSingleName that should work in compiler, but fails for inner classes in IDE
|
||||
return fileFinder.findVirtualFileWithHeader(new ClassId(packageFqName, Name.identifier(classNameWithDollars)));
|
||||
return findVirtualFile(state, new ClassId(packageFqName, Name.identifier(classNameWithDollars)));
|
||||
}
|
||||
|
||||
public static String getInlineName(
|
||||
@@ -362,8 +369,9 @@ public class InlineCodegenUtil {
|
||||
OutputFile outputFile = state.getFactory().get(internalName + ".class");
|
||||
if (outputFile != null) {
|
||||
return new ClassReader(outputFile.asByteArray());
|
||||
} else {
|
||||
VirtualFile file = findVirtualFile(state.getProject(), internalName);
|
||||
}
|
||||
else {
|
||||
VirtualFile file = findVirtualFileImprecise(state, internalName);
|
||||
if (file == null) {
|
||||
throw new RuntimeException("Couldn't find virtual file for " + internalName);
|
||||
}
|
||||
|
||||
@@ -54,10 +54,10 @@ internal class Parameters(val real: List<ParameterInfo>, val captured: List<Capt
|
||||
}
|
||||
|
||||
private fun get(index: Int): ParameterInfo {
|
||||
if (index < real.size()) {
|
||||
if (index < real.size) {
|
||||
return real.get(index)
|
||||
}
|
||||
return captured.get(index - real.size())
|
||||
return captured.get(index - real.size)
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<ParameterInfo> {
|
||||
|
||||
@@ -35,18 +35,18 @@ internal class ParametersBuilder private constructor(){
|
||||
private var nextCaptured = 0
|
||||
|
||||
fun addThis(type: Type, skipped: Boolean): ParameterInfo {
|
||||
val info = ParameterInfo(type, skipped, nextValueParameterIndex, -1, valueAndHiddenParams.size())
|
||||
val info = ParameterInfo(type, skipped, nextValueParameterIndex, -1, valueAndHiddenParams.size)
|
||||
addParameter(info)
|
||||
return info
|
||||
}
|
||||
|
||||
fun addNextParameter(type: Type, skipped: Boolean, remapValue: StackValue?): ParameterInfo {
|
||||
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue, valueAndHiddenParams.size()))
|
||||
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue, valueAndHiddenParams.size))
|
||||
}
|
||||
|
||||
fun addNextValueParameter(type: Type, skipped: Boolean, remapValue: StackValue?, parameterIndex: Int): ParameterInfo {
|
||||
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue,
|
||||
if (parameterIndex == -1) valueAndHiddenParams.size() else { parameterIndex + valueParamStart }))
|
||||
if (parameterIndex == -1) valueAndHiddenParams.size else { parameterIndex + valueParamStart }))
|
||||
}
|
||||
|
||||
fun addCapturedParam(
|
||||
@@ -102,7 +102,7 @@ internal class ParametersBuilder private constructor(){
|
||||
}
|
||||
|
||||
fun markValueParametesStart(){
|
||||
this.valueParamStart = valueAndHiddenParams.size()
|
||||
this.valueParamStart = valueAndHiddenParams.size
|
||||
}
|
||||
|
||||
fun listCaptured(): List<CapturedParamInfo> {
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext
|
||||
import org.jetbrains.kotlin.codegen.generateAsCast
|
||||
import org.jetbrains.kotlin.codegen.generateIsCheck
|
||||
import org.jetbrains.kotlin.codegen.generateNullCheckForNonSafeAs
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
@@ -36,22 +35,21 @@ private class ParameterNameAndNullability(val name: String, val nullable: Boolea
|
||||
|
||||
public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) {
|
||||
|
||||
enum class OperationKind {
|
||||
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS;
|
||||
|
||||
val id: Int get() = ordinal
|
||||
val isTypeNullabilityAware: Boolean get() = this == AS || this == IS
|
||||
}
|
||||
|
||||
companion object {
|
||||
public val NEW_ARRAY_MARKER_METHOD_NAME: String = "reifyNewArray"
|
||||
public val CHECKCAST_MARKER_METHOD_NAME: String = "reifyCheckcast"
|
||||
public val SAFE_CHECKCAST_MARKER_METHOD_NAME: String = "reifySafeCheckcast"
|
||||
public val INSTANCEOF_MARKER_METHOD_NAME: String = "reifyInstanceof"
|
||||
public val JAVA_CLASS_MARKER_METHOD_NAME: String = "reifyJavaClass"
|
||||
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME: String = "needClassReification"
|
||||
@JvmField
|
||||
public val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
|
||||
@JvmField
|
||||
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
|
||||
|
||||
private val PARAMETRISED_MARKERS = ImmutableSet.of(
|
||||
NEW_ARRAY_MARKER_METHOD_NAME,
|
||||
CHECKCAST_MARKER_METHOD_NAME, SAFE_CHECKCAST_MARKER_METHOD_NAME,
|
||||
INSTANCEOF_MARKER_METHOD_NAME, JAVA_CLASS_MARKER_METHOD_NAME
|
||||
)
|
||||
|
||||
private fun isParametrisedReifiedMarker(insn: AbstractInsnNode) =
|
||||
isReifiedMarker(insn) { PARAMETRISED_MARKERS.contains(it) }
|
||||
private fun isOperationReifiedMarker(insn: AbstractInsnNode) =
|
||||
isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME }
|
||||
|
||||
private fun isReifiedMarker(insn: AbstractInsnNode, namePredicate: (String) -> Boolean): Boolean {
|
||||
if (insn.getOpcode() != Opcodes.INVOKESTATIC || insn !is MethodInsnNode) return false
|
||||
@@ -70,10 +68,6 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE), false
|
||||
);
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun isNullableMarkerInstruction(marker: String) = INSTANCEOF_MARKER_METHOD_NAME == marker ||
|
||||
CHECKCAST_MARKER_METHOD_NAME == marker
|
||||
}
|
||||
|
||||
private var maxStackSize = 0
|
||||
@@ -89,7 +83,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
maxStackSize = 0
|
||||
var result = ReifiedTypeParametersUsages()
|
||||
for (insn in instructions.toArray()) {
|
||||
if (isParametrisedReifiedMarker(insn)) {
|
||||
if (isOperationReifiedMarker(insn)) {
|
||||
val newName: String? = processReifyMarker(insn as MethodInsnNode, instructions)
|
||||
if (newName != null) {
|
||||
result.addUsedReifiedParameter(newName)
|
||||
@@ -142,10 +136,11 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
* or null if it shouldn't
|
||||
*/
|
||||
private fun processReifyMarker(insn: MethodInsnNode, instructions: InsnList): String? {
|
||||
val parameter = getParameter(insn) ?: return null
|
||||
val operationKind = insn.operationKind ?: return null
|
||||
val parameter = insn.parameterNameAndNullability ?: return null
|
||||
val mapping = parametersMapping?.get(parameter.name) ?: return null
|
||||
val kotlinType =
|
||||
if (isNullableMarkerInstruction(insn.name) && parameter.nullable)
|
||||
if (operationKind.isTypeNullabilityAware && parameter.nullable)
|
||||
TypeUtils.makeNullable(mapping.type)
|
||||
else
|
||||
mapping.type
|
||||
@@ -156,21 +151,21 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
// process* methods return false if marker should be reified further
|
||||
// or it's invalid (may be emitted explicitly in code)
|
||||
// they return true if instruction is reified and marker can be deleted
|
||||
if (when (insn.name) {
|
||||
NEW_ARRAY_MARKER_METHOD_NAME -> processNewArray(insn, asmType)
|
||||
CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, kotlinType, asmType, safe = false)
|
||||
SAFE_CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, kotlinType, asmType, safe = true)
|
||||
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, instructions, kotlinType, asmType)
|
||||
JAVA_CLASS_MARKER_METHOD_NAME -> processJavaClass(insn, asmType)
|
||||
else -> false
|
||||
if (when (operationKind) {
|
||||
OperationKind.NEW_ARRAY -> processNewArray(insn, asmType)
|
||||
OperationKind.AS -> processAs(insn, instructions, kotlinType, asmType, safe = false)
|
||||
OperationKind.SAFE_AS -> processAs(insn, instructions, kotlinType, asmType, safe = true)
|
||||
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
|
||||
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
|
||||
}) {
|
||||
instructions.remove(insn.getPrevious()!!)
|
||||
instructions.remove(insn)
|
||||
instructions.remove(insn.previous.previous!!) // PUSH operation ID
|
||||
instructions.remove(insn.previous!!) // PUSH type parameter
|
||||
instructions.remove(insn) // INVOKESTATIC marker method
|
||||
}
|
||||
|
||||
return null
|
||||
} else {
|
||||
val nullableSuffix = if (isNullableMarkerInstruction(insn.name) && kotlinType.isMarkedNullable) "?" else ""
|
||||
val nullableSuffix = if (operationKind.isTypeNullabilityAware && kotlinType.isMarkedNullable) "?" else ""
|
||||
instructions.set(insn.previous!!, LdcInsnNode(mapping.newName + nullableSuffix))
|
||||
return mapping.newName
|
||||
}
|
||||
@@ -179,66 +174,44 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
private fun processNewArray(insn: MethodInsnNode, parameter: Type) =
|
||||
processNextTypeInsn(insn, parameter, Opcodes.ANEWARRAY)
|
||||
|
||||
private fun processCheckcast(insn: MethodInsnNode,
|
||||
instructions: InsnList,
|
||||
jetType: KotlinType,
|
||||
asmType: Type,
|
||||
safe: Boolean) =
|
||||
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { instanceofInsn: AbstractInsnNode ->
|
||||
if (instanceofInsn !is TypeInsnNode) return false
|
||||
private fun processAs(insn: MethodInsnNode,
|
||||
instructions: InsnList,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type,
|
||||
safe: Boolean) =
|
||||
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { stubCheckcast: AbstractInsnNode ->
|
||||
if (stubCheckcast !is TypeInsnNode) return false
|
||||
|
||||
val newMethodNode = MethodNode(InlineCodegenUtil.API)
|
||||
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe)
|
||||
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
instructions.remove(stubCheckcast)
|
||||
|
||||
// TODO: refine max stack calculation (it's not always as big as +4)
|
||||
maxStackSize = Math.max(maxStackSize, 4)
|
||||
|
||||
addNullCheckForAsIfNeeded(insn.previous!!, instructions, jetType, safe)
|
||||
TypeIntrinsics.checkcast(instanceofInsn, instructions, jetType, asmType, safe)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun addNullCheckForAsIfNeeded(insn: AbstractInsnNode, instructions: InsnList, jetType: KotlinType, safe: Boolean) {
|
||||
if (!safe && !TypeUtils.isNullableType(jetType)) {
|
||||
val methodNode = MethodNode(InlineCodegenUtil.API)
|
||||
generateNullCheckForNonSafeAs(InstructionAdapter(methodNode), jetType)
|
||||
private fun processIs(insn: MethodInsnNode,
|
||||
instructions: InsnList,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type) =
|
||||
rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { stubInstanceOf: AbstractInsnNode ->
|
||||
if (stubInstanceOf !is TypeInsnNode) return false
|
||||
|
||||
InlineCodegenUtil.insertNodeBefore(methodNode, instructions, insn)
|
||||
maxStackSize = Math.max(maxStackSize, 4)
|
||||
}
|
||||
}
|
||||
val newMethodNode = MethodNode(InlineCodegenUtil.API)
|
||||
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
|
||||
|
||||
private fun processInstanceof(insn: MethodInsnNode, instructions: InsnList, jetType: KotlinType, asmType: Type) =
|
||||
rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { instanceofInsn: AbstractInsnNode ->
|
||||
if (instanceofInsn !is TypeInsnNode) return false
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
instructions.remove(stubInstanceOf)
|
||||
|
||||
addNullCheckForIsIfNeeded(insn, instructions, jetType)
|
||||
TypeIntrinsics.instanceOf(instanceofInsn, instructions, jetType, asmType)
|
||||
// TODO: refine max stack calculation (it's not always as big as +2)
|
||||
maxStackSize = Math.max(maxStackSize, 2)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun addNullCheckForIsIfNeeded(insn: AbstractInsnNode, instructions: InsnList, type: KotlinType) {
|
||||
if (TypeUtils.isNullableType(type)) {
|
||||
val instanceOf = insn.next
|
||||
insertNullCheckAround(instructions, insn.previous!!, instanceOf)
|
||||
maxStackSize = Math.max(maxStackSize, 2)
|
||||
}
|
||||
}
|
||||
|
||||
private fun insertNullCheckAround(instructions: InsnList, start: AbstractInsnNode, end: AbstractInsnNode) {
|
||||
val methodNode = MethodNode(InlineCodegenUtil.API)
|
||||
var splitIndex: Int = -1
|
||||
generateIsCheck(InstructionAdapter(methodNode), true) {
|
||||
splitIndex = methodNode.instructions.size()
|
||||
}
|
||||
assert(splitIndex >= 0) {
|
||||
"Split index should be non-negative, but $splitIndex"
|
||||
}
|
||||
|
||||
val nullCheckInsns = methodNode.instructions.toArray()
|
||||
nullCheckInsns.take(splitIndex).forEach {
|
||||
instructions.insertBefore(start, it)
|
||||
}
|
||||
|
||||
nullCheckInsns.drop(splitIndex).reversed().forEach {
|
||||
instructions.insert(end, it)
|
||||
}
|
||||
}
|
||||
|
||||
inline private fun rewriteNextTypeInsn(
|
||||
marker: MethodInsnNode,
|
||||
expectedNextOpcode: Int,
|
||||
@@ -262,10 +235,13 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getParameter(insn: MethodInsnNode): ParameterNameAndNullability? {
|
||||
val prev = insn.getPrevious()!!
|
||||
}
|
||||
|
||||
val parameterNameWithFlag = when (prev.getOpcode()) {
|
||||
private val MethodInsnNode.parameterNameAndNullability: ParameterNameAndNullability?
|
||||
get() {
|
||||
val prev = previous!!
|
||||
|
||||
val parameterNameWithFlag = when (prev.opcode) {
|
||||
Opcodes.LDC -> (prev as LdcInsnNode).cst as String
|
||||
else -> return null
|
||||
}
|
||||
@@ -273,7 +249,11 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
val parameterName = if (parameterNameWithFlag.endsWith("?")) parameterNameWithFlag.dropLast(1) else parameterNameWithFlag
|
||||
return ParameterNameAndNullability(parameterName, parameterName !== parameterNameWithFlag)
|
||||
}
|
||||
}
|
||||
|
||||
private val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get() =
|
||||
previous?.previous?.intConstant?.let {
|
||||
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
|
||||
}
|
||||
|
||||
public class ReifiedTypeParameterMappings() {
|
||||
private val mappingsByName = hashMapOf<String, ReifiedTypeParameterMapping>()
|
||||
|
||||
@@ -202,7 +202,7 @@ public open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val p
|
||||
private fun createKey(name: String, path: String) = "$name#$path"
|
||||
|
||||
override val resultMappings: List<FileMapping>
|
||||
get() = fileMappings.values().map { it.toFileMapping() }
|
||||
get() = fileMappings.values.map { it.toFileMapping() }
|
||||
|
||||
override fun visitSource(name: String, path: String) {
|
||||
lastVisited = fileMappings.getOrPut(createKey(name, path), { RawFileMapping(name, path) })
|
||||
|
||||
@@ -44,7 +44,7 @@ object SMAPParser {
|
||||
public fun parse(mappingInfo: String): SMAP {
|
||||
val fileMappings = linkedMapOf<Int, FileMapping>()
|
||||
|
||||
val fileSectionStart = mappingInfo.indexOf(SMAP.FILE_SECTION) + SMAP.FILE_SECTION.length()
|
||||
val fileSectionStart = mappingInfo.indexOf(SMAP.FILE_SECTION) + SMAP.FILE_SECTION.length
|
||||
val lineSectionAnchor = mappingInfo.indexOf(SMAP.LINE_SECTION)
|
||||
val files = mappingInfo.substring(fileSectionStart, lineSectionAnchor)
|
||||
|
||||
@@ -63,7 +63,7 @@ object SMAPParser {
|
||||
}
|
||||
|
||||
|
||||
val lines = mappingInfo.substring(lineSectionAnchor + SMAP.LINE_SECTION.length(), mappingInfo.indexOf(SMAP.END)).trim().split('\n')
|
||||
val lines = mappingInfo.substring(lineSectionAnchor + SMAP.LINE_SECTION.length, mappingInfo.indexOf(SMAP.END)).trim().split('\n')
|
||||
for (lineMapping in lines) {
|
||||
/*only simple mapping now*/
|
||||
val targetSplit = lineMapping.indexOf(':')
|
||||
@@ -79,6 +79,6 @@ object SMAPParser {
|
||||
fileMappings[fileIndex]!!.addRangeMapping(RangeMapping(originalIndex, targetIndex, range))
|
||||
}
|
||||
|
||||
return SMAP(fileMappings.values().toList())
|
||||
return SMAP(fileMappings.values.toList())
|
||||
}
|
||||
}
|
||||
@@ -97,5 +97,5 @@ fun <T : IntervalWithHandler> doClustering(blocks: List<T>): List<TryBlockCluste
|
||||
cluster.blocks.add(block)
|
||||
}
|
||||
|
||||
return clusters.values().toList()
|
||||
return clusters.values.toList()
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
|
||||
|
||||
override fun toCallable(method: CallableMethod): Callable {
|
||||
val returnType = method.returnType
|
||||
assert(method.getValueParameters().size() == 1)
|
||||
assert(method.getValueParameters().size == 1)
|
||||
val operandType = numberFunctionOperandType(returnType)
|
||||
val paramType = if (shift()) Type.INT_TYPE else operandType
|
||||
|
||||
|
||||
@@ -17,20 +17,17 @@
|
||||
package org.jetbrains.kotlin.codegen.intrinsics;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import kotlin.StringsKt;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.CapitalizeDecapitalizeKt;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -38,6 +35,9 @@ import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
public class IntrinsicMethods {
|
||||
public static final String INTRINSICS_CLASS_NAME = "kotlin/jvm/internal/Intrinsics";
|
||||
|
||||
private static final FqName KOTLIN_JVM = new FqName("kotlin.jvm");
|
||||
/* package */ static final FqNameUnsafe RECEIVER_PARAMETER_FQ_NAME = new FqNameUnsafe("T");
|
||||
|
||||
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
|
||||
private static final IntrinsicMethod UNARY_PLUS = new UnaryPlus();
|
||||
private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
|
||||
@@ -57,20 +57,22 @@ public class IntrinsicMethods {
|
||||
private static final ToString TO_STRING = new ToString();
|
||||
private static final Clone CLONE = new Clone();
|
||||
|
||||
private final Map<String, IntrinsicMethod> namedMethods = new HashMap<String, IntrinsicMethod>();
|
||||
private static final IntrinsicMethod ARRAY_ITERATOR = new ArrayIterator();
|
||||
private final IntrinsicsMap intrinsicsMap = new IntrinsicsMap();
|
||||
|
||||
public IntrinsicMethods() {
|
||||
namedMethods.put("kotlin.javaClass.function", new JavaClassFunction());
|
||||
namedMethods.put("kotlin.javaClass.property", new JavaClassProperty());
|
||||
namedMethods.put("kotlin.KClass.java.property", new KClassJavaProperty());
|
||||
namedMethods.put("kotlin.jvm.internal.unsafe.monitorEnter", MonitorInstruction.MONITOR_ENTER);
|
||||
namedMethods.put("kotlin.jvm.internal.unsafe.monitorExit", MonitorInstruction.MONITOR_EXIT);
|
||||
namedMethods.put("kotlin.jvm.isArrayOf", new IsArrayOf());
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "javaClass", 0, new JavaClassFunction());
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, RECEIVER_PARAMETER_FQ_NAME, "javaClass", -1, new JavaClassProperty());
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, KotlinBuiltIns.FQ_NAMES.kClass, "java", -1, new KClassJavaProperty());
|
||||
intrinsicsMap.registerIntrinsic(new FqName("kotlin.jvm.internal.unsafe"), null, "monitorEnter", 1, MonitorInstruction.MONITOR_ENTER);
|
||||
intrinsicsMap.registerIntrinsic(new FqName("kotlin.jvm.internal.unsafe"), null, "monitorExit", 1, MonitorInstruction.MONITOR_EXIT);
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, KotlinBuiltIns.FQ_NAMES.array, "isArrayOf", 0, new IsArrayOf());
|
||||
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "arrayOf", 1, new JavaClassArray());
|
||||
|
||||
// TODO: drop when deprecated kotlin.javaClass property is gone
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, RECEIVER_PARAMETER_FQ_NAME, "javaClass", -1, new JavaClassProperty());
|
||||
|
||||
ImmutableList<Name> primitiveCastMethods = OperatorConventions.NUMBER_CONVERSIONS.asList();
|
||||
for (Name method : primitiveCastMethods) {
|
||||
String methodName = method.asString();
|
||||
@@ -180,16 +182,6 @@ public class IntrinsicMethods {
|
||||
|
||||
@Nullable
|
||||
public IntrinsicMethod getIntrinsic(@NotNull CallableMemberDescriptor descriptor) {
|
||||
IntrinsicMethod intrinsicMethod = intrinsicsMap.getIntrinsic(descriptor);
|
||||
if (intrinsicMethod != null) {
|
||||
return intrinsicMethod;
|
||||
}
|
||||
|
||||
String value = CompileTimeConstantUtils.getIntrinsicAnnotationArgument(descriptor);
|
||||
if (value != null) {
|
||||
return namedMethods.get(value);
|
||||
}
|
||||
|
||||
return null;
|
||||
return intrinsicsMap.getIntrinsic(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.codegen.intrinsics;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
@@ -112,6 +109,10 @@ class IntrinsicsMap {
|
||||
ClassifierDescriptor classifier = receiverParameter.getType().getConstructor().getDeclarationDescriptor();
|
||||
if (classifier == null) return null;
|
||||
|
||||
if (classifier instanceof TypeParameterDescriptor) {
|
||||
return IntrinsicMethods.RECEIVER_PARAMETER_FQ_NAME;
|
||||
}
|
||||
|
||||
return DescriptorUtils.getFqName(classifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class IsArrayOf : IntrinsicMethod() {
|
||||
val method = typeMapper.mapToCallableMethod(fd, false)
|
||||
|
||||
val builtIns = fd.module.builtIns
|
||||
val elementType = typeArguments.values().first()
|
||||
val elementType = typeArguments.values.first()
|
||||
val arrayKtType = builtIns.getArrayType(Variance.INVARIANT, elementType)
|
||||
val arrayType = typeMapper.mapType(arrayKtType)
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
public class JavaClassFunction : IntrinsicMethod() {
|
||||
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
||||
val javaClass = resolvedCall.getResultingDescriptor().getReturnType()!!.getArguments().first().getType()
|
||||
return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), null, null) {
|
||||
return object : IntrinsicCallable(getType(Class::class.java), listOf(), null, null) {
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
codegen.putReifierMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME)
|
||||
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.OperationKind.JAVA_CLASS)
|
||||
putJavaLangClassInstance(v, codegen.getState().typeMapper.mapType(javaClass))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,12 +54,12 @@ public class JavaClassProperty : IntrinsicPropertyGetter() {
|
||||
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
|
||||
}
|
||||
|
||||
return getType(javaClass<Class<Any>>())
|
||||
return getType(Class::class.java)
|
||||
}
|
||||
|
||||
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
||||
val classType = codegen.getState().typeMapper.mapType(resolvedCall.getCall().getDispatchReceiver()!!.getType())
|
||||
return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), classType, null) {
|
||||
return object : IntrinsicCallable(getType(Class::class.java), listOf(), classType, null) {
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
if (isPrimitive(classType)) {
|
||||
v.getstatic(boxType(classType).getInternalName(), "TYPE", "Ljava/lang/Class;")
|
||||
|
||||
@@ -39,7 +39,7 @@ public class KClassJavaProperty : IntrinsicPropertyGetter() {
|
||||
return when {
|
||||
isReifiedTypeParameter(type) -> {
|
||||
StackValue.operation(returnType) { iv ->
|
||||
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME)
|
||||
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS)
|
||||
AsmUtil.putJavaLangClassInstance(iv, asmType)
|
||||
coerceToJavaLangClass(iv, returnType)
|
||||
}
|
||||
|
||||
@@ -23,10 +23,13 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
public class MonitorInstruction private constructor(private val opcode: Int) : IntrinsicMethod() {
|
||||
class MonitorInstruction private constructor(private val opcode: Int) : IntrinsicMethod() {
|
||||
companion object {
|
||||
public val MONITOR_ENTER: MonitorInstruction = MonitorInstruction(Opcodes.MONITORENTER)
|
||||
public val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT)
|
||||
@JvmField
|
||||
val MONITOR_ENTER: MonitorInstruction = MonitorInstruction(Opcodes.MONITORENTER)
|
||||
|
||||
@JvmField
|
||||
val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT)
|
||||
}
|
||||
|
||||
override fun toCallable(method: CallableMethod): Callable {
|
||||
|
||||
@@ -78,26 +78,28 @@ public object TypeIntrinsics {
|
||||
instanceofInsn.desc = asmType.internalName
|
||||
}
|
||||
|
||||
public @JvmStatic fun checkcast(v: InstructionAdapter, jetType: KotlinType, asmType: Type, safe: Boolean) {
|
||||
@JvmStatic
|
||||
public fun checkcast(
|
||||
v: InstructionAdapter,
|
||||
kotlinType: KotlinType, asmType: Type,
|
||||
// This parameter is just for sake of optimization:
|
||||
// when we generate 'as?' we do necessary intrinsic checks
|
||||
// when calling TypeIntrinsics.instanceOf, so here we can just make checkcast
|
||||
safe: Boolean) {
|
||||
if (safe) {
|
||||
v.checkcast(asmType)
|
||||
return
|
||||
}
|
||||
|
||||
val functionTypeArity = getFunctionTypeArity(jetType)
|
||||
val functionTypeArity = getFunctionTypeArity(kotlinType)
|
||||
if (functionTypeArity >= 0) {
|
||||
v.iconst(functionTypeArity)
|
||||
if (safe) {
|
||||
v.typeIntrinsic(BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR)
|
||||
}
|
||||
else {
|
||||
v.typeIntrinsic(BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR)
|
||||
}
|
||||
v.typeIntrinsic(BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR)
|
||||
v.checkcast(asmType)
|
||||
return
|
||||
}
|
||||
|
||||
val asMutableCollectionMethodName = getAsMutableCollectionMethodName(jetType)
|
||||
val asMutableCollectionMethodName = getAsMutableCollectionMethodName(kotlinType)
|
||||
if (asMutableCollectionMethodName != null) {
|
||||
v.typeIntrinsic(asMutableCollectionMethodName, getAsMutableCollectionDescriptor(asmType))
|
||||
return
|
||||
@@ -106,38 +108,6 @@ public object TypeIntrinsics {
|
||||
v.checkcast(asmType)
|
||||
}
|
||||
|
||||
public @JvmStatic fun checkcast(checkcastInsn: TypeInsnNode, instructions: InsnList, jetType: KotlinType, asmType: Type, safe: Boolean) {
|
||||
if (safe) {
|
||||
checkcastInsn.desc = asmType.internalName
|
||||
return
|
||||
}
|
||||
|
||||
val functionTypeArity = getFunctionTypeArity(jetType)
|
||||
if (functionTypeArity >= 0) {
|
||||
instructions.insertBefore(checkcastInsn, iconstNode(functionTypeArity))
|
||||
|
||||
val beforeCheckcast = if (safe)
|
||||
typeIntrinsicNode(BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR)
|
||||
else
|
||||
typeIntrinsicNode(BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR)
|
||||
instructions.insertBefore(checkcastInsn, beforeCheckcast)
|
||||
|
||||
instructions.insertBefore(checkcastInsn, TypeInsnNode(Opcodes.CHECKCAST, asmType.internalName))
|
||||
instructions.remove(checkcastInsn)
|
||||
return
|
||||
}
|
||||
|
||||
val asMutableCollectionMethodName = getAsMutableCollectionMethodName(jetType)
|
||||
if (asMutableCollectionMethodName != null) {
|
||||
instructions.insertBefore(checkcastInsn,
|
||||
typeIntrinsicNode(asMutableCollectionMethodName, getAsMutableCollectionDescriptor(asmType)))
|
||||
instructions.remove(checkcastInsn)
|
||||
return
|
||||
}
|
||||
|
||||
checkcastInsn.desc = asmType.internalName
|
||||
}
|
||||
|
||||
private val INTRINSICS_CLASS = "kotlin/jvm/internal/TypeIntrinsics"
|
||||
|
||||
private val IS_FUNCTON_OF_ARITY_METHOD_NAME = "isFunctionOfArity"
|
||||
@@ -211,9 +181,4 @@ public object TypeIntrinsics {
|
||||
|
||||
private val BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR =
|
||||
Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE, Type.INT_TYPE)
|
||||
|
||||
private val BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY = "beforeSafeCheckcastToFunctionOfArity"
|
||||
|
||||
private val BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR =
|
||||
Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE, Type.INT_TYPE)
|
||||
}
|
||||
@@ -110,10 +110,10 @@ public open class MethodAnalyzer<V : Value>(
|
||||
|
||||
}
|
||||
catch (e: AnalyzerException) {
|
||||
throw AnalyzerException(e.node, "Error at instruction " + insn + ": " + e.getMessage(), e)
|
||||
throw AnalyzerException(e.node, "Error at instruction " + insn + ": " + e.message, e)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
throw AnalyzerException(insnNode, "Error at instruction " + insn + ": " + e.getMessage(), e)
|
||||
throw AnalyzerException(insnNode, "Error at instruction " + insn + ": " + e.message, e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.optimization.common
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.InsnList
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||
|
||||
val AbstractInsnNode.isMeaningful: Boolean get() =
|
||||
@@ -97,3 +96,24 @@ inline fun AbstractInsnNode.findPreviousOrNull(predicate: (AbstractInsnNode) ->
|
||||
|
||||
fun AbstractInsnNode.hasOpcode(): Boolean =
|
||||
getOpcode() >= 0
|
||||
|
||||
// See InstructionAdapter
|
||||
//
|
||||
// public void iconst(final int cst) {
|
||||
// if (cst >= -1 && cst <= 5) {
|
||||
// mv.visitInsn(Opcodes.ICONST_0 + cst);
|
||||
// } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
|
||||
// mv.visitIntInsn(Opcodes.BIPUSH, cst);
|
||||
// } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
|
||||
// mv.visitIntInsn(Opcodes.SIPUSH, cst);
|
||||
// } else {
|
||||
// mv.visitLdcInsn(new Integer(cst));
|
||||
// }
|
||||
// }
|
||||
val AbstractInsnNode.intConstant: Int? get() =
|
||||
when (opcode) {
|
||||
in ICONST_M1..ICONST_5 -> opcode - ICONST_0
|
||||
BIPUSH, SIPUSH -> (this as IntInsnNode).operand
|
||||
LDC -> (this as LdcInsnNode).cst as? Int
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ private fun insertSaveRestoreStackMarkers(
|
||||
val doneTryStartLabels = hashSetOf<LabelNode>()
|
||||
val doneHandlerLabels = hashSetOf<LabelNode>()
|
||||
|
||||
for (decompiledTryDescriptor in decompiledTryDescriptorForStart.values()) {
|
||||
for (decompiledTryDescriptor in decompiledTryDescriptorForStart.values) {
|
||||
with(decompiledTryDescriptor) {
|
||||
if (!doneTryStartLabels.contains(tryStartLabel)) {
|
||||
doneTryStartLabels.add(tryStartLabel)
|
||||
|
||||
@@ -96,7 +96,7 @@ internal class FixStackAnalyzer(
|
||||
}
|
||||
else {
|
||||
extraStack.add(value)
|
||||
maxExtraStackSize = Math.max(maxExtraStackSize, extraStack.size())
|
||||
maxExtraStackSize = Math.max(maxExtraStackSize, extraStack.size)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ internal class FixStackContext(val methodNode: MethodNode) {
|
||||
if (saveNodes.isEmpty()) {
|
||||
throw AssertionError("${indexOf(insnNode)}: in handler ${indexOf(restoreLabel)} restore is not matched with save")
|
||||
}
|
||||
else if (saveNodes.size() > 1) {
|
||||
else if (saveNodes.size > 1) {
|
||||
throw AssertionError("${indexOf(insnNode)}: in handler ${indexOf(restoreLabel)} restore is matched with several saves")
|
||||
}
|
||||
val saveNode = saveNodes.first()
|
||||
|
||||
@@ -39,7 +39,7 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
|
||||
}
|
||||
|
||||
fun allocateVariablesForSaveStackMarker(saveStackMarker: AbstractInsnNode, savedStackValues: List<BasicValue>): SavedStackDescriptor {
|
||||
val numRestoreStackMarkers = context.restoreStackMarkersForSaveMarker[saveStackMarker]!!.size()
|
||||
val numRestoreStackMarkers = context.restoreStackMarkersForSaveMarker[saveStackMarker]!!.size
|
||||
return allocateNewHandle(numRestoreStackMarkers, saveStackMarker, savedStackValues)
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
|
||||
}
|
||||
|
||||
private fun getFirstUnusedLocalVariableIndex(): Int =
|
||||
allocatedHandles.values().fold(initialMaxLocals) {
|
||||
allocatedHandles.values.fold(initialMaxLocals) {
|
||||
index, handle -> Math.max(index, handle.savedStackDescriptor.firstUnusedLocalVarIndex)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,8 @@ package org.jetbrains.kotlin.codegen.serialization;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice;
|
||||
import org.jetbrains.kotlin.util.slicedMap.MutableSlicedMap;
|
||||
import org.jetbrains.kotlin.util.slicedMap.SlicedMapImpl;
|
||||
@@ -37,12 +35,6 @@ public final class JvmSerializationBindings {
|
||||
SerializationMappingSlice.create();
|
||||
public static final SerializationMappingSlice<PropertyDescriptor, Method> SYNTHETIC_METHOD_FOR_PROPERTY =
|
||||
SerializationMappingSlice.create();
|
||||
public static final SerializationMappingSlice<CallableMemberDescriptor, String> IMPL_CLASS_NAME_FOR_CALLABLE =
|
||||
SerializationMappingSlice.create();
|
||||
public static final SerializationMappingSetSlice<PropertyDescriptor> STATIC_FIELD_IN_OUTER_CLASS =
|
||||
SerializationMappingSetSlice.create();
|
||||
public static final SerializationMappingSlice<ValueParameterDescriptor, Integer> INDEX_FOR_VALUE_PARAMETER =
|
||||
SerializationMappingSlice.create();
|
||||
|
||||
private static final class SerializationMappingSlice<K, V> extends BasicWritableSlice<K, V> {
|
||||
public SerializationMappingSlice() {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.serialization;
|
||||
|
||||
import com.google.protobuf.MessageLite;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -61,14 +60,6 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
return useTypeTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeValueParameter(@NotNull ValueParameterDescriptor descriptor, @NotNull ProtoBuf.ValueParameter.Builder proto) {
|
||||
Integer index = bindings.get(INDEX_FOR_VALUE_PARAMETER, descriptor);
|
||||
if (index != null) {
|
||||
proto.setExtension(JvmProtoBuf.index, index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeType(@NotNull KotlinType type, @NotNull ProtoBuf.Type.Builder proto) {
|
||||
// TODO: don't store type annotations in our binary metadata on Java 8, use *TypeAnnotations attributes instead
|
||||
@@ -99,8 +90,6 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
proto.setExtension(JvmProtoBuf.constructorSignature, signature);
|
||||
}
|
||||
}
|
||||
|
||||
saveImplClassName(descriptor, proto);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,8 +101,6 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
proto.setExtension(JvmProtoBuf.methodSignature, signature);
|
||||
}
|
||||
}
|
||||
|
||||
saveImplClassName(descriptor, proto);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,45 +113,18 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
Method setterMethod = setter == null ? null : bindings.get(METHOD_FOR_FUNCTION, setter);
|
||||
|
||||
Pair<Type, String> field = bindings.get(FIELD_FOR_PROPERTY, descriptor);
|
||||
String fieldName;
|
||||
String fieldDesc;
|
||||
boolean isStaticInOuter;
|
||||
if (field != null) {
|
||||
fieldName = field.second;
|
||||
fieldDesc = field.first.getDescriptor();
|
||||
isStaticInOuter = bindings.get(STATIC_FIELD_IN_OUTER_CLASS, descriptor);
|
||||
}
|
||||
else {
|
||||
fieldName = null;
|
||||
fieldDesc = null;
|
||||
isStaticInOuter = false;
|
||||
}
|
||||
|
||||
Method syntheticMethod = bindings.get(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor);
|
||||
|
||||
JvmProtoBuf.JvmPropertySignature signature = signatureSerializer.propertySignature(
|
||||
descriptor, fieldName, fieldDesc, isStaticInOuter,
|
||||
descriptor,
|
||||
field != null ? field.second : null,
|
||||
field != null ? field.first.getDescriptor() : null,
|
||||
syntheticMethod != null ? signatureSerializer.methodSignature(null, syntheticMethod) : null,
|
||||
getterMethod != null ? signatureSerializer.methodSignature(null, getterMethod) : null,
|
||||
setterMethod != null ? signatureSerializer.methodSignature(null, setterMethod) : null
|
||||
);
|
||||
|
||||
proto.setExtension(JvmProtoBuf.propertySignature, signature);
|
||||
|
||||
saveImplClassName(descriptor, proto);
|
||||
}
|
||||
|
||||
private void saveImplClassName(@NotNull CallableMemberDescriptor callable, @NotNull MessageLite.Builder proto) {
|
||||
String name = bindings.get(IMPL_CLASS_NAME_FOR_CALLABLE, callable);
|
||||
if (name == null) return;
|
||||
|
||||
int index = stringTable.getStringIndex(name);
|
||||
if (proto instanceof ProtoBuf.Function.Builder) {
|
||||
((ProtoBuf.Function.Builder) proto).setExtension(JvmProtoBuf.methodImplClassName, index);
|
||||
}
|
||||
else if (proto instanceof ProtoBuf.Property.Builder) {
|
||||
((ProtoBuf.Property.Builder) proto).setExtension(JvmProtoBuf.propertyImplClassName, index);
|
||||
}
|
||||
}
|
||||
|
||||
private class SignatureSerializer {
|
||||
@@ -240,7 +200,6 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@Nullable String fieldName,
|
||||
@Nullable String fieldDesc,
|
||||
boolean isStaticInOuter,
|
||||
@Nullable JvmProtoBuf.JvmMethodSignature syntheticMethod,
|
||||
@Nullable JvmProtoBuf.JvmMethodSignature getter,
|
||||
@Nullable JvmProtoBuf.JvmMethodSignature setter
|
||||
@@ -249,7 +208,7 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
|
||||
if (fieldDesc != null) {
|
||||
assert fieldName != null : "Field name shouldn't be null when there's a field type: " + fieldDesc;
|
||||
signature.setField(fieldSignature(descriptor, fieldName, fieldDesc, isStaticInOuter));
|
||||
signature.setField(fieldSignature(descriptor, fieldName, fieldDesc));
|
||||
}
|
||||
|
||||
if (syntheticMethod != null) {
|
||||
@@ -270,8 +229,7 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
public JvmProtoBuf.JvmFieldSignature fieldSignature(
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@NotNull String name,
|
||||
@NotNull String desc,
|
||||
boolean isStaticInOuter
|
||||
@NotNull String desc
|
||||
) {
|
||||
JvmProtoBuf.JvmFieldSignature.Builder builder = JvmProtoBuf.JvmFieldSignature.newBuilder();
|
||||
if (!descriptor.getName().asString().equals(name)) {
|
||||
@@ -280,9 +238,6 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
if (requiresSignature(descriptor, desc)) {
|
||||
builder.setDesc(stringTable.getStringIndex(desc));
|
||||
}
|
||||
if (isStaticInOuter) {
|
||||
builder.setIsStaticInOuter(true);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class JvmStringTable(private val typeMapper: JetTypeMapper) : StringTable {
|
||||
|
||||
override fun getStringIndex(string: String): Int =
|
||||
map.getOrPut(string) {
|
||||
strings.size().apply {
|
||||
strings.size.apply {
|
||||
strings.add(string)
|
||||
|
||||
val lastRecord = records.lastOrNull()
|
||||
@@ -78,7 +78,7 @@ class JvmStringTable(private val typeMapper: JetTypeMapper) : StringTable {
|
||||
}
|
||||
}
|
||||
|
||||
val index = strings.size()
|
||||
val index = strings.size
|
||||
if (classId.isLocal) {
|
||||
localNames.add(index)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ public class GenerationState @JvmOverloads constructor(
|
||||
public abstract fun shouldGenerateScript(script: KtScript): Boolean
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
public val GENERATE_ALL: GenerateClassFilter = object : GenerateClassFilter() {
|
||||
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean = true
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.codegen.state;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -404,10 +404,11 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
TypeConstructor constructor = jetType.getConstructor();
|
||||
DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
|
||||
if (constructor instanceof IntersectionTypeConstructor) {
|
||||
jetType = CommonSupertypes.commonSupertype(new ArrayList<KotlinType>(constructor.getSupertypes()));
|
||||
constructor = jetType.getConstructor();
|
||||
}
|
||||
DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
|
||||
|
||||
if (descriptor == null) {
|
||||
throw new UnsupportedOperationException("no descriptor for type constructor of " + jetType);
|
||||
|
||||
@@ -76,7 +76,7 @@ val CallableDescriptor?.isMethodWithDeclarationSiteWildcards: Boolean
|
||||
get() {
|
||||
if (this !is CallableMemberDescriptor) return false
|
||||
return firstOverridden {
|
||||
METHODS_WITH_DECLARATION_SITE_WILDCARDS.containsRaw(it.propertyIfAccessor.fqNameOrNull())
|
||||
METHODS_WITH_DECLARATION_SITE_WILDCARDS.contains(it.propertyIfAccessor.fqNameOrNull())
|
||||
} != null
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,11 @@ public class EnumSwitchCodegen extends SwitchCodegen {
|
||||
public EnumSwitchCodegen(
|
||||
@NotNull KtWhenExpression expression,
|
||||
boolean isStatement,
|
||||
boolean isExhaustive,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull WhenByEnumsMapping mapping
|
||||
) {
|
||||
super(expression, isStatement, codegen);
|
||||
super(expression, isStatement, isExhaustive, codegen);
|
||||
this.mapping = mapping;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,10 @@ public class IntegralConstantsSwitchCodegen extends SwitchCodegen {
|
||||
public IntegralConstantsSwitchCodegen(
|
||||
@NotNull KtWhenExpression expression,
|
||||
boolean isStatement,
|
||||
boolean isExhaustive,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
super(expression, isStatement, codegen);
|
||||
super(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,9 +40,10 @@ public class StringSwitchCodegen extends SwitchCodegen {
|
||||
public StringSwitchCodegen(
|
||||
@NotNull KtWhenExpression expression,
|
||||
boolean isStatement,
|
||||
boolean isExhaustive,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
super(expression, isStatement, codegen);
|
||||
super(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.util.*;
|
||||
abstract public class SwitchCodegen {
|
||||
protected final KtWhenExpression expression;
|
||||
protected final boolean isStatement;
|
||||
protected final boolean isExhaustive;
|
||||
protected final ExpressionCodegen codegen;
|
||||
protected final BindingContext bindingContext;
|
||||
protected final Type subjectType;
|
||||
@@ -49,10 +50,11 @@ abstract public class SwitchCodegen {
|
||||
|
||||
public SwitchCodegen(
|
||||
@NotNull KtWhenExpression expression, boolean isStatement,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
boolean isExhaustive, @NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
this.expression = expression;
|
||||
this.isStatement = isStatement;
|
||||
this.isExhaustive = isExhaustive;
|
||||
this.codegen = codegen;
|
||||
this.bindingContext = codegen.getBindingContext();
|
||||
|
||||
@@ -70,7 +72,7 @@ abstract public class SwitchCodegen {
|
||||
boolean hasElse = expression.getElseExpression() != null;
|
||||
|
||||
// if there is no else-entry and it's statement then default --- endLabel
|
||||
defaultLabel = (hasElse || !isStatement) ? elseLabel : endLabel;
|
||||
defaultLabel = (hasElse || !isStatement || isExhaustive) ? elseLabel : endLabel;
|
||||
|
||||
generateSubject();
|
||||
|
||||
@@ -79,9 +81,9 @@ abstract public class SwitchCodegen {
|
||||
generateEntries();
|
||||
|
||||
// there is no else-entry but this is not statement, so we should return Unit
|
||||
if (!hasElse && !isStatement) {
|
||||
if (!hasElse && (!isStatement || isExhaustive)) {
|
||||
v.visitLabel(elseLabel);
|
||||
codegen.putUnitInstanceOntoStackForNonExhaustiveWhen(expression);
|
||||
codegen.putUnitInstanceOntoStackForNonExhaustiveWhen(expression, isStatement);
|
||||
}
|
||||
|
||||
codegen.markLineNumber(expression, isStatement);
|
||||
|
||||
@@ -102,6 +102,7 @@ public class SwitchCodegenUtil {
|
||||
public static SwitchCodegen buildAppropriateSwitchCodegenIfPossible(
|
||||
@NotNull KtWhenExpression expression,
|
||||
boolean isStatement,
|
||||
boolean isExhaustive,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
BindingContext bindingContext = codegen.getBindingContext();
|
||||
@@ -114,15 +115,15 @@ public class SwitchCodegenUtil {
|
||||
WhenByEnumsMapping mapping = codegen.getBindingContext().get(CodegenBinding.MAPPING_FOR_WHEN_BY_ENUM, expression);
|
||||
|
||||
if (mapping != null) {
|
||||
return new EnumSwitchCodegen(expression, isStatement, codegen, mapping);
|
||||
return new EnumSwitchCodegen(expression, isStatement, isExhaustive, codegen, mapping);
|
||||
}
|
||||
|
||||
if (isIntegralConstantsSwitch(expression, subjectType, bindingContext)) {
|
||||
return new IntegralConstantsSwitchCodegen(expression, isStatement, codegen);
|
||||
return new IntegralConstantsSwitchCodegen(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
if (isStringConstantsSwitch(expression, subjectType, bindingContext)) {
|
||||
return new StringSwitchCodegen(expression, isStatement, codegen);
|
||||
return new StringSwitchCodegen(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.ModuleContent
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.builtins.BuiltInsSerializedResourcePaths
|
||||
import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
@@ -33,19 +34,18 @@ import org.jetbrains.kotlin.config.addKotlinSourceRoots
|
||||
import org.jetbrains.kotlin.context.ProjectContext
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.utils.recursePostOrder
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.io.File
|
||||
|
||||
public class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) {
|
||||
@@ -98,9 +98,7 @@ public class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) {
|
||||
|
||||
val moduleDescriptor = resolver.descriptorForModule(builtInModule)
|
||||
|
||||
// We don't use FileUtil because it spawns JNA initialization, which fails because we don't have (and don't want to have) its
|
||||
// native libraries in the compiler jar (libjnidispatch.so / jnidispatch.dll / ...)
|
||||
destDir.recursePostOrder { it.delete() }
|
||||
destDir.deleteRecursively()
|
||||
|
||||
if (!destDir.mkdirs()) {
|
||||
System.err.println("Could not make directories: " + destDir)
|
||||
@@ -108,68 +106,82 @@ public class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) {
|
||||
|
||||
files.map { it.packageFqName }.toSet().forEach {
|
||||
fqName ->
|
||||
serializePackage(moduleDescriptor, fqName, destDir)
|
||||
PackageSerializer(moduleDescriptor.getPackage(fqName), destDir, { bytesWritten ->
|
||||
totalSize += bytesWritten
|
||||
totalFiles++
|
||||
}).run()
|
||||
}
|
||||
}
|
||||
|
||||
private fun serializePackage(module: ModuleDescriptor, fqName: FqName, destDir: File) {
|
||||
val packageView = module.getPackage(fqName)
|
||||
private class PackageSerializer(
|
||||
private val packageView: PackageViewDescriptor,
|
||||
private val destDir: File,
|
||||
private val onFileWrite: (bytesWritten: Int) -> Unit
|
||||
) {
|
||||
private val fqName = packageView.fqName
|
||||
private val builtinsMessage = BuiltInsProtoBuf.BuiltIns.newBuilder()
|
||||
private val extension = BuiltInsSerializerExtension()
|
||||
|
||||
// TODO: perform some kind of validation? At the moment not possible because DescriptorValidator is in compiler-tests
|
||||
// DescriptorValidator.validate(packageView)
|
||||
fun run() {
|
||||
serializeClasses(packageView.memberScope)
|
||||
serializePackageFragments(packageView.fragments)
|
||||
serializeStringTable()
|
||||
serializeBuiltInsFile()
|
||||
}
|
||||
|
||||
val classifierDescriptors = DescriptorSerializer.sort(packageView.memberScope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS))
|
||||
private fun serializeClass(classDescriptor: ClassDescriptor) {
|
||||
val classProto = DescriptorSerializer.createTopLevel(extension).classProto(classDescriptor).build()
|
||||
|
||||
val extension = BuiltInsSerializerExtension()
|
||||
serializeClasses(classifierDescriptors, extension) {
|
||||
classDescriptor, classProto ->
|
||||
val stream = ByteArrayOutputStream()
|
||||
classProto.writeTo(stream)
|
||||
write(destDir, getFileName(classDescriptor), stream)
|
||||
write(BuiltInsSerializedResourcePaths.getClassMetadataPath(classDescriptor.classId), stream)
|
||||
builtinsMessage.addClass(classProto)
|
||||
|
||||
serializeClasses(classDescriptor.unsubstitutedInnerClassesScope)
|
||||
}
|
||||
|
||||
val packageStream = ByteArrayOutputStream()
|
||||
val fragments = packageView.fragments
|
||||
val packageProto = DescriptorSerializer.createTopLevel(extension).packageProto(fragments).build()
|
||||
packageProto.writeTo(packageStream)
|
||||
write(destDir, BuiltInsSerializedResourcePaths.getPackageFilePath(fqName), packageStream)
|
||||
|
||||
val nameStream = ByteArrayOutputStream()
|
||||
extension.stringTable.serializeTo(nameStream)
|
||||
write(destDir, BuiltInsSerializedResourcePaths.getStringTableFilePath(fqName), nameStream)
|
||||
}
|
||||
|
||||
private fun write(destDir: File, fileName: String, stream: ByteArrayOutputStream) {
|
||||
totalSize += stream.size()
|
||||
totalFiles++
|
||||
File(destDir, fileName).parentFile.mkdirs()
|
||||
File(destDir, fileName).writeBytes(stream.toByteArray())
|
||||
}
|
||||
|
||||
private fun serializeClass(
|
||||
classDescriptor: ClassDescriptor,
|
||||
serializer: BuiltInsSerializerExtension,
|
||||
writeClass: (ClassDescriptor, ProtoBuf.Class) -> Unit
|
||||
) {
|
||||
val classProto = DescriptorSerializer.createTopLevel(serializer).classProto(classDescriptor).build()
|
||||
writeClass(classDescriptor, classProto)
|
||||
|
||||
serializeClasses(classDescriptor.unsubstitutedInnerClassesScope.getContributedDescriptors(), serializer, writeClass)
|
||||
}
|
||||
|
||||
private fun serializeClasses(
|
||||
descriptors: Collection<DeclarationDescriptor>,
|
||||
serializer: BuiltInsSerializerExtension,
|
||||
writeClass: (ClassDescriptor, ProtoBuf.Class) -> Unit
|
||||
) {
|
||||
for (descriptor in descriptors) {
|
||||
if (descriptor is ClassDescriptor && descriptor.kind != ClassKind.ENUM_ENTRY) {
|
||||
serializeClass(descriptor, serializer, writeClass)
|
||||
private fun serializeClasses(scope: MemberScope) {
|
||||
for (descriptor in DescriptorSerializer.sort(scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS))) {
|
||||
if (descriptor is ClassDescriptor && descriptor.kind != ClassKind.ENUM_ENTRY) {
|
||||
serializeClass(descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFileName(classDescriptor: ClassDescriptor): String {
|
||||
return BuiltInsSerializedResourcePaths.getClassMetadataPath(classDescriptor.classId)
|
||||
private fun serializePackageFragments(fragments: List<PackageFragmentDescriptor>) {
|
||||
val stream = ByteArrayOutputStream()
|
||||
val packageProto = DescriptorSerializer.createTopLevel(extension).packageProto(fragments).build()
|
||||
packageProto.writeTo(stream)
|
||||
write(BuiltInsSerializedResourcePaths.getPackageFilePath(fqName), stream)
|
||||
builtinsMessage.setPackage(packageProto)
|
||||
}
|
||||
|
||||
private fun serializeStringTable() {
|
||||
val stream = ByteArrayOutputStream()
|
||||
val (strings, qualifiedNames) = extension.stringTable.buildProto()
|
||||
strings.writeDelimitedTo(stream)
|
||||
qualifiedNames.writeDelimitedTo(stream)
|
||||
write(BuiltInsSerializedResourcePaths.getStringTableFilePath(fqName), stream)
|
||||
builtinsMessage.setStrings(strings)
|
||||
builtinsMessage.setQualifiedNames(qualifiedNames)
|
||||
}
|
||||
|
||||
private fun serializeBuiltInsFile() {
|
||||
val stream = ByteArrayOutputStream()
|
||||
with(DataOutputStream(stream)) {
|
||||
val version = BuiltinsPackageFragment.VERSION.toArray()
|
||||
writeInt(version.size)
|
||||
version.forEach { writeInt(it) }
|
||||
}
|
||||
builtinsMessage.build().writeTo(stream)
|
||||
write(BuiltInsSerializedResourcePaths.getBuiltInsFilePath(fqName), stream)
|
||||
}
|
||||
|
||||
private fun write(fileName: String, stream: ByteArrayOutputStream) {
|
||||
onFileWrite(stream.size())
|
||||
val file = File(destDir, fileName)
|
||||
file.parentFile.mkdirs()
|
||||
file.writeBytes(stream.toByteArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,15 +21,15 @@ import java.io.File
|
||||
fun main(args: Array<String>) {
|
||||
System.setProperty("java.awt.headless", "true")
|
||||
|
||||
if (args.size() < 2) {
|
||||
if (args.size < 2) {
|
||||
println(
|
||||
"""Kotlin built-ins serializer
|
||||
|
||||
Usage: ... <destination dir> (<source dir>)+
|
||||
|
||||
Analyzes Kotlin sources found in the given source directories and serializes
|
||||
found top-level declarations to <destination dir> (files such as
|
||||
*.kotlin_string_table, *.kotlin_package, *.kotlin_class)"""
|
||||
found top-level declarations to <destination dir> (files such as *.kotlin_builtins,
|
||||
as well as old files *.kotlin_string_table, *.kotlin_package, *.kotlin_class)"""
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -7,10 +7,9 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="intellij-core" level="project" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="library" exported="" name="cli-parser" level="project" />
|
||||
<orderEntry type="library" name="jps" level="project" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -41,7 +41,7 @@ public object Main {
|
||||
classpath.add(".")
|
||||
|
||||
var i = 0
|
||||
while (i < args.size()) {
|
||||
while (i < args.size) {
|
||||
val arg = args[i]
|
||||
if (collectingArguments) {
|
||||
arguments.add(arg)
|
||||
@@ -50,7 +50,7 @@ public object Main {
|
||||
}
|
||||
|
||||
fun next(): String {
|
||||
if (++i == args.size()) {
|
||||
if (++i == args.size) {
|
||||
throw RunnerException("argument expected to $arg")
|
||||
}
|
||||
return args[i]
|
||||
@@ -105,7 +105,7 @@ public object Main {
|
||||
run(args)
|
||||
}
|
||||
catch (e: RunnerException) {
|
||||
System.err.println("error: " + e.getMessage())
|
||||
System.err.println("error: " + e.message)
|
||||
System.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ class JarRunner(private val path: String) : AbstractRunner() {
|
||||
}
|
||||
}
|
||||
catch (e: IOException) {
|
||||
throw RunnerException("could not read manifest from " + path + ": " + e.getMessage())
|
||||
throw RunnerException("could not read manifest from " + path + ": " + e.message)
|
||||
}
|
||||
?: throw RunnerException("no Main-Class entry found in manifest in $path")
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.cli.common.messages;
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.util.LineSeparator;
|
||||
import kotlin.StringsKt;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.fusesource.jansi.Ansi;
|
||||
import org.fusesource.jansi.internal.CLibrary;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -135,7 +135,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
@Override
|
||||
public Unit invoke(String message) {
|
||||
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
})) {
|
||||
return COMPILATION_ERROR;
|
||||
|
||||
@@ -61,11 +61,11 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageSeverityCollector)
|
||||
|
||||
if (IncrementalCompilation.isEnabled()) {
|
||||
val incrementalCompilationComponents = services.get(javaClass<IncrementalCompilationComponents>())
|
||||
val incrementalCompilationComponents = services.get(IncrementalCompilationComponents::class.java)
|
||||
configuration.put(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS, incrementalCompilationComponents)
|
||||
}
|
||||
|
||||
val locator = services.get(javaClass<CompilerJarLocator>())
|
||||
val locator = services.get(CompilerJarLocator::class.java)
|
||||
configuration.put(JVMConfigurationKeys.COMPILER_JAR_LOCATOR, locator)
|
||||
|
||||
try {
|
||||
@@ -83,12 +83,12 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
PluginCliParser.loadPlugins(arguments, configuration)
|
||||
}
|
||||
catch (e: PluginCliOptionProcessingException) {
|
||||
val message = e.getMessage() + "\n\n" + cliPluginUsageString(e.pluginId, e.options)
|
||||
val message = e.message + "\n\n" + cliPluginUsageString(e.pluginId, e.options)
|
||||
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION)
|
||||
return INTERNAL_ERROR
|
||||
}
|
||||
catch (e: CliOptionProcessingException) {
|
||||
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, e.getMessage()!!, CompilerMessageLocation.NO_LOCATION)
|
||||
messageSeverityCollector.report(CompilerMessageSeverity.ERROR, e.message!!, CompilerMessageLocation.NO_LOCATION)
|
||||
return INTERNAL_ERROR
|
||||
}
|
||||
catch (t: Throwable) {
|
||||
@@ -169,7 +169,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
KotlinToJVMBytecodeCompiler.compileModules(environment, configuration, moduleScript.getModules(), directory, jar, friendPaths, arguments.includeRuntime)
|
||||
}
|
||||
else if (arguments.script) {
|
||||
val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size())
|
||||
val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size)
|
||||
environment = createCoreEnvironment(rootDisposable, configuration)
|
||||
|
||||
if (messageSeverityCollector.anyReported(CompilerMessageSeverity.ERROR)) return COMPILATION_ERROR
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.compiler.plugin.*
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.utils.valuesToMap
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
import java.net.URLClassLoader
|
||||
@@ -39,7 +38,7 @@ public object PluginCliParser {
|
||||
javaClass.getClassLoader()
|
||||
)
|
||||
|
||||
val componentRegistrars = ServiceLoader.load(javaClass<ComponentRegistrar>(), classLoader).toArrayList()
|
||||
val componentRegistrars = ServiceLoader.load(ComponentRegistrar::class.java, classLoader).toArrayList()
|
||||
componentRegistrars.addAll(BundledCompilerPlugins.componentRegistrars)
|
||||
configuration.addAll(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, componentRegistrars)
|
||||
|
||||
@@ -56,11 +55,11 @@ public object PluginCliParser {
|
||||
it.pluginId
|
||||
} ?: mapOf()
|
||||
|
||||
val commandLineProcessors = ServiceLoader.load(javaClass<CommandLineProcessor>(), classLoader).toArrayList()
|
||||
val commandLineProcessors = ServiceLoader.load(CommandLineProcessor::class.java, classLoader).toArrayList()
|
||||
commandLineProcessors.addAll(BundledCompilerPlugins.commandLineProcessors)
|
||||
|
||||
for (processor in commandLineProcessors) {
|
||||
val declaredOptions = processor.pluginOptions.valuesToMap { it.name }
|
||||
val declaredOptions = processor.pluginOptions.toMapBy { it.name }
|
||||
val optionsToValues = MultiMap<CliOption, CliOptionValue>()
|
||||
|
||||
for (optionValue in optionValuesByPlugin[processor.pluginId].orEmpty()) {
|
||||
@@ -79,7 +78,7 @@ public object PluginCliParser {
|
||||
processor.pluginOptions,
|
||||
"Required plugin option not present: ${processor.pluginId}:${option.name}")
|
||||
}
|
||||
if (!option.allowMultipleOccurrences && values.size() > 1) {
|
||||
if (!option.allowMultipleOccurrences && values.size > 1) {
|
||||
throw PluginCliOptionProcessingException(
|
||||
processor.pluginId,
|
||||
processor.pluginOptions,
|
||||
|
||||
@@ -175,7 +175,7 @@ public class CompileEnvironmentUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -119,14 +119,14 @@ public class KotlinCoreEnvironment private constructor(
|
||||
|
||||
init {
|
||||
val project = projectEnvironment.getProject()
|
||||
project.registerService(javaClass<DeclarationProviderFactoryService>(), CliDeclarationProviderFactoryService(sourceFiles))
|
||||
project.registerService(DeclarationProviderFactoryService::class.java, CliDeclarationProviderFactoryService(sourceFiles))
|
||||
project.registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl())
|
||||
|
||||
registerProjectServicesForCLI(projectEnvironment)
|
||||
registerProjectServices(projectEnvironment)
|
||||
|
||||
fillClasspath(configuration)
|
||||
val fileManager = ServiceManager.getService(project, javaClass<CoreJavaFileManager>())
|
||||
val fileManager = ServiceManager.getService(project, CoreJavaFileManager::class.java)
|
||||
val index = JvmDependenciesIndex(javaRoots)
|
||||
(fileManager as KotlinCliJavaFileManagerImpl).initIndex(index)
|
||||
|
||||
@@ -142,7 +142,7 @@ public class KotlinCoreEnvironment private constructor(
|
||||
|
||||
KotlinScriptDefinitionProvider.getInstance(project).setScriptDefinitions(configuration.getList(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY))
|
||||
|
||||
project.registerService(javaClass<JvmVirtualFileFinderFactory>(), JvmCliVirtualFileFinderFactory(index))
|
||||
project.registerService(JvmVirtualFileFinderFactory::class.java, JvmCliVirtualFileFinderFactory(index))
|
||||
|
||||
ExternalDeclarationsProvider.registerExtensionPoint(project)
|
||||
ExpressionCodegenExtension.registerExtensionPoint(project)
|
||||
@@ -342,16 +342,16 @@ public class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
|
||||
private fun registerAppExtensionPoints() {
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), BinaryFileStubBuilders.EP_NAME, javaClass<FileTypeExtensionPoint<Any>>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), FileContextProvider.EP_NAME, javaClass<FileContextProvider>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), FileContextProvider.EP_NAME, FileContextProvider::class.java)
|
||||
//
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaDataContributor.EP_NAME, javaClass<MetaDataContributor>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), PsiAugmentProvider.EP_NAME, javaClass<PsiAugmentProvider>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaMainMethodProvider.EP_NAME, javaClass<JavaMainMethodProvider>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaDataContributor.EP_NAME, MetaDataContributor::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), PsiAugmentProvider.EP_NAME, PsiAugmentProvider::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider::class.java)
|
||||
//
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ContainerProvider.EP_NAME, javaClass<ContainerProvider>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClsCustomNavigationPolicy.EP_NAME, javaClass<ClsCustomNavigationPolicy>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClassFileDecompilers.EP_NAME, javaClass<ClassFileDecompilers.Decompiler>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ContainerProvider.EP_NAME, ContainerProvider::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClsCustomNavigationPolicy.EP_NAME, ClsCustomNavigationPolicy::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler::class.java)
|
||||
}
|
||||
|
||||
private fun registerApplicationExtensionPointsAndExtensionsFrom(configuration: CompilerConfiguration, configFilePath: String) {
|
||||
@@ -384,40 +384,40 @@ public class KotlinCoreEnvironment private constructor(
|
||||
registerFileType(KotlinFileType.INSTANCE, "kt")
|
||||
registerFileType(KotlinFileType.INSTANCE, KotlinParserDefinition.STD_SCRIPT_SUFFIX)
|
||||
registerParserDefinition(KotlinParserDefinition())
|
||||
getApplication().registerService(javaClass<KotlinBinaryClassCache>(), KotlinBinaryClassCache())
|
||||
getApplication().registerService(javaClass<JavaClassSupers>(), javaClass<JavaClassSupersImpl>())
|
||||
getApplication().registerService(KotlinBinaryClassCache::class.java, KotlinBinaryClassCache())
|
||||
getApplication().registerService(JavaClassSupers::class.java, JavaClassSupersImpl::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerProjectExtensionPoints(area: ExtensionsArea) {
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiTreeChangePreprocessor.EP_NAME, javaClass<PsiTreeChangePreprocessor>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, javaClass<PsiElementFinder>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, PsiElementFinder::class.java)
|
||||
}
|
||||
|
||||
// made public for Upsource
|
||||
@JvmStatic
|
||||
public fun registerProjectServices(projectEnvironment: JavaCoreProjectEnvironment) {
|
||||
with (projectEnvironment.getProject()) {
|
||||
registerService(javaClass<KotlinScriptDefinitionProvider>(), KotlinScriptDefinitionProvider())
|
||||
registerService(javaClass<KotlinJavaPsiFacade>(), KotlinJavaPsiFacade(this))
|
||||
registerService(javaClass<KtLightClassForFacade.FacadeStubCache>(), KtLightClassForFacade.FacadeStubCache(this))
|
||||
registerService(KotlinScriptDefinitionProvider::class.java, KotlinScriptDefinitionProvider())
|
||||
registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this))
|
||||
registerService(KtLightClassForFacade.FacadeStubCache::class.java, KtLightClassForFacade.FacadeStubCache(this))
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerProjectServicesForCLI(projectEnvironment: JavaCoreProjectEnvironment) {
|
||||
with (projectEnvironment.getProject()) {
|
||||
registerService(javaClass<CoreJavaFileManager>(), ServiceManager.getService(this, javaClass<JavaFileManager>()) as CoreJavaFileManager)
|
||||
registerService(CoreJavaFileManager::class.java, ServiceManager.getService(this, JavaFileManager::class.java) as CoreJavaFileManager)
|
||||
|
||||
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(this)
|
||||
registerService(javaClass<LightClassGenerationSupport>(), cliLightClassGenerationSupport)
|
||||
registerService(javaClass<CliLightClassGenerationSupport>(), cliLightClassGenerationSupport)
|
||||
registerService(javaClass<CodeAnalyzerInitializer>(), cliLightClassGenerationSupport)
|
||||
registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
|
||||
registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
|
||||
registerService(CodeAnalyzerInitializer::class.java, cliLightClassGenerationSupport)
|
||||
|
||||
val area = Extensions.getArea(this)
|
||||
|
||||
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(JavaElementFinder(this, cliLightClassGenerationSupport))
|
||||
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(
|
||||
PsiElementFinderImpl(this, ServiceManager.getService(this, javaClass<JavaFileManager>())))
|
||||
PsiElementFinderImpl(this, ServiceManager.getService(this, JavaFileManager::class.java)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class ReplSystemInWrapper(
|
||||
private var inputByteArray = byteArrayOf()
|
||||
|
||||
private val isAtBufferEnd: Boolean
|
||||
get() = curBytePos == inputByteArray.size()
|
||||
get() = curBytePos == inputByteArray.size
|
||||
|
||||
@Volatile var isReplScriptExecuting = false
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="library" name="intellij-core" level="project" />
|
||||
<orderEntry type="module" module-name="cli" />
|
||||
<orderEntry type="module" module-name="frontend" />
|
||||
|
||||
@@ -25,7 +25,7 @@ data class Modification(val range: TextRange, val apply: (String) -> String)
|
||||
class CollectModificationsVisitor(evaluators: List<Evaluator>) : KtTreeVisitorVoid() {
|
||||
|
||||
val elementModifications: Map<Evaluator, MutableList<Modification>> =
|
||||
evaluators.toMap(selector = { it }, transform = { arrayListOf<Modification>() })
|
||||
evaluators.toMapBy(selector = { it }, transform = { arrayListOf<Modification>() })
|
||||
|
||||
override fun visitDeclaration(declaration: KtDeclaration) {
|
||||
super.visitDeclaration(declaration)
|
||||
@@ -40,10 +40,10 @@ class CollectModificationsVisitor(evaluators: List<Evaluator>) : KtTreeVisitorVo
|
||||
|
||||
if (!conditionalResult)
|
||||
modifications.add(Modification(declaration.textRange) { rangeText ->
|
||||
StringBuilder {
|
||||
buildString {
|
||||
append("/* Not available on $evaluator */")
|
||||
repeat(StringUtil.getLineBreakCount(rangeText)) { append("\n") }
|
||||
}.toString()
|
||||
}
|
||||
})
|
||||
else {
|
||||
val targetName = annotations.filterIsInstance<Conditional.TargetName>().singleOrNull()
|
||||
@@ -60,13 +60,13 @@ class CollectModificationsVisitor(evaluators: List<Evaluator>) : KtTreeVisitorVo
|
||||
}
|
||||
|
||||
fun List<Modification>.applyTo(sourceText: String): String {
|
||||
return StringBuilder {
|
||||
return buildString {
|
||||
var prevIndex = 0
|
||||
for ((range, transform) in this@applyTo) {
|
||||
append(sourceText, prevIndex, range.startOffset)
|
||||
append(transform(range.substring(sourceText)))
|
||||
prevIndex = range.endOffset
|
||||
}
|
||||
append(sourceText, prevIndex, sourceText.length())
|
||||
}.toString()
|
||||
append(sourceText, prevIndex, sourceText.length)
|
||||
}
|
||||
}
|
||||
@@ -36,10 +36,10 @@ public fun createJvmProfile(targetRoot: File, version: Int): Profile = Profile("
|
||||
public fun createJsProfile(targetRoot: File): Profile = Profile("JS", JsPlatformEvaluator(), File(targetRoot, "js"))
|
||||
|
||||
public val profileEvaluators: Map<String, () -> Evaluator> =
|
||||
listOf(6, 7, 8).toMap({ version -> "JVM$version" }, { version -> { JvmPlatformEvaluator(version) } }) + ("JS" to { JsPlatformEvaluator() })
|
||||
listOf(6, 7, 8).toMapBy({ version -> "JVM$version" }, { version -> { JvmPlatformEvaluator(version) } }) + ("JS" to { JsPlatformEvaluator() })
|
||||
|
||||
public fun createProfile(name: String, targetRoot: File): Profile {
|
||||
val (profileName, evaluator) = profileEvaluators.entrySet().firstOrNull { it.key.equals(name, ignoreCase = true) } ?: throw IllegalArgumentException("Profile with name '$name' is not supported")
|
||||
val (profileName, evaluator) = profileEvaluators.entries.firstOrNull { it.key.equals(name, ignoreCase = true) } ?: throw IllegalArgumentException("Profile with name '$name' is not supported")
|
||||
return Profile(profileName, evaluator(), targetRoot)
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public class Preprocessor(val logger: Logger = SystemOutLogger) {
|
||||
class Modify(val sourceText: String, val modifications: List<Modification>) : FileProcessingResult() {
|
||||
fun getModifiedText(): String = modifications.applyTo(sourceText)
|
||||
|
||||
override fun toString(): String = "Modify(${modifications.size()})"
|
||||
override fun toString(): String = "Modify(${modifications.size})"
|
||||
}
|
||||
|
||||
override fun toString() = this.javaClass.simpleName
|
||||
@@ -89,7 +89,7 @@ public class Preprocessor(val logger: Logger = SystemOutLogger) {
|
||||
val visitor = CollectModificationsVisitor(listOf(evaluator))
|
||||
psiFile.accept(visitor)
|
||||
|
||||
val list = visitor.elementModifications.values().single()
|
||||
val list = visitor.elementModifications.values.single()
|
||||
return if (list.isNotEmpty())
|
||||
FileProcessingResult.Modify(sourceText, list)
|
||||
else
|
||||
@@ -150,7 +150,7 @@ fun String.convertLineSeparators(): String = StringUtil.convertLineSeparators(th
|
||||
|
||||
fun File.isTextEqualTo(content: String): Boolean = readText().lines() == content.lines()
|
||||
|
||||
fun File.makeRelativeTo(from: File, to: File) = File(to, relativeTo(from))
|
||||
fun File.makeRelativeTo(from: File, to: File) = File(to, toRelativeString(from))
|
||||
|
||||
fun File.mkdirsOrFail() {
|
||||
if (!mkdirs() && !exists()) {
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
if (args.size() != 3) {
|
||||
if (args.size != 3) {
|
||||
println("Usage: <path to sources> <output path> <profile>")
|
||||
System.exit(1)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public object SystemOutLogger : Logger {
|
||||
public fun Logger.withPrefix(prefix: String): Logger = PrefixedLogger(prefix, this)
|
||||
|
||||
public class PrefixedLogger(val prefix: String, val logger: Logger) : Logger {
|
||||
private fun prefix(msg: CharSequence): CharSequence = StringBuilder {
|
||||
private fun prefix(msg: CharSequence): CharSequence = StringBuilder().apply {
|
||||
append(prefix)
|
||||
append(": ")
|
||||
append(msg)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="library" name="kotlin-reflect" level="project" />
|
||||
<orderEntry type="library" name="intellij-core" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="junit-4.12" level="project" />
|
||||
<orderEntry type="library" exported="" name="javax.inject" level="project" />
|
||||
|
||||
@@ -63,7 +63,7 @@ private fun getSetterInfos(c: Class<*>): List<SetterInfo> {
|
||||
val setterInfos = ArrayList<SetterInfo>()
|
||||
for (method in c.getMethods()) {
|
||||
for (annotation in method.getDeclaredAnnotations()) {
|
||||
if (annotation.annotationType().getName().endsWith(".Inject")) {
|
||||
if (annotation.annotationClass.java.getName().endsWith(".Inject")) {
|
||||
setterInfos.add(SetterInfo(method, method.getGenericParameterTypes().toList()))
|
||||
}
|
||||
}
|
||||
@@ -114,6 +114,6 @@ private fun getRegistrations(klass: Class<*>): List<Type> {
|
||||
val interfaces = LinkedHashSet<Type>()
|
||||
superClasses.forEach { collectInterfacesRecursive(it, interfaces) }
|
||||
registrations.addAll(interfaces)
|
||||
registrations.remove(javaClass<Any>())
|
||||
registrations.remove(Any::class.java)
|
||||
return registrations
|
||||
}
|
||||
@@ -70,14 +70,14 @@ public class StorageComponentContainer(id: String) : ComponentContainer, Compone
|
||||
private fun resolveIterable(request: Type, context: ValueResolveContext): ValueDescriptor? {
|
||||
if (request !is ParameterizedType) return null
|
||||
val rawType = request.getRawType()
|
||||
if (rawType != javaClass<Iterable<*>>()) return null
|
||||
if (rawType != Iterable::class.java) return null
|
||||
val typeArguments = request.getActualTypeArguments()
|
||||
if (typeArguments.size() != 1) return null
|
||||
if (typeArguments.size != 1) return null
|
||||
val iterableTypeArgument = typeArguments[0]
|
||||
val iterableType = when (iterableTypeArgument) {
|
||||
is WildcardType -> {
|
||||
val upperBounds = iterableTypeArgument.getUpperBounds()
|
||||
if (upperBounds.size() != 1) return null
|
||||
if (upperBounds.size != 1) return null
|
||||
upperBounds[0]
|
||||
}
|
||||
is Class<*> -> iterableTypeArgument
|
||||
@@ -112,9 +112,9 @@ public fun StorageComponentContainer.registerInstance(instance: Any): StorageCom
|
||||
}
|
||||
|
||||
public inline fun <reified T : Any> StorageComponentContainer.resolve(context: ValueResolveContext = unknownContext): ValueDescriptor? {
|
||||
return resolve(javaClass<T>(), context)
|
||||
return resolve(T::class.java, context)
|
||||
}
|
||||
|
||||
public inline fun <reified T : Any> StorageComponentContainer.resolveMultiple(context: ValueResolveContext = unknownContext): Iterable<ValueDescriptor> {
|
||||
return resolveMultiple(javaClass<T>(), context)
|
||||
return resolveMultiple(T::class.java, context)
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ fun Method.bindToMethod(context: ValueResolveContext): MethodBinding {
|
||||
}
|
||||
|
||||
private fun Member.bindArguments(parameters: List<Type>, context: ValueResolveContext): List<ValueDescriptor> {
|
||||
val bound = ArrayList<ValueDescriptor>(parameters.size())
|
||||
val bound = ArrayList<ValueDescriptor>(parameters.size)
|
||||
var unsatisfied: MutableList<Type>? = null
|
||||
|
||||
for (parameter in parameters) {
|
||||
|
||||
@@ -49,7 +49,7 @@ public class ComponentStorage(val myId: String) : ValueResolver {
|
||||
if (entry.isNotEmpty()) {
|
||||
registerDependency(request, context)
|
||||
|
||||
if (entry.size() > 1)
|
||||
if (entry.size > 1)
|
||||
throw InvalidCardinalityException("Request $request cannot be satisfied because there is more than one type registered", entry)
|
||||
return entry.singleOrNull()
|
||||
}
|
||||
@@ -68,7 +68,7 @@ public class ComponentStorage(val myId: String) : ValueResolver {
|
||||
public fun dump(printer: PrintStream): Unit = with (printer) {
|
||||
val heading = "Container: $myId"
|
||||
println(heading)
|
||||
println("=".repeat(heading.length()))
|
||||
println("=".repeat(heading.length))
|
||||
println()
|
||||
getDescriptorsInDisposeOrder().forEach { descriptor ->
|
||||
println(descriptor)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="module" module-name="daemon-common" />
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.daemon.client
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import org.jetbrains.kotlin.daemon.common.CompilerCallbackServicesFacade
|
||||
import org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface
|
||||
import org.jetbrains.kotlin.daemon.common.RmiFriendlyCompilationCancelledException
|
||||
import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT
|
||||
import org.jetbrains.kotlin.incremental.components.LookupInfo
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
@@ -51,7 +53,7 @@ class CompilerCallbackServicesFacadeServer(
|
||||
|
||||
override fun incrementalCache_getMultifileFacade(target: TargetId, partInternalName: String): String? = incrementalCompilationComponents!!.getIncrementalCache(target).getMultifileFacade(partInternalName)
|
||||
|
||||
override fun incrementalCache_getPackagePartData(target: TargetId, fqName: String): JvmPackagePartProto? = incrementalCompilationComponents!!.getIncrementalCache(target).getPackagePartData(fqName)
|
||||
override fun incrementalCache_getPackagePartData(target: TargetId, partInternalName: String): JvmPackagePartProto? = incrementalCompilationComponents!!.getIncrementalCache(target).getPackagePartData(partInternalName)
|
||||
|
||||
override fun incrementalCache_getModuleMappingData(target: TargetId): ByteArray? = incrementalCompilationComponents!!.getIncrementalCache(target).getModuleMappingData()
|
||||
|
||||
@@ -80,6 +82,13 @@ class CompilerCallbackServicesFacadeServer(
|
||||
override fun lookupTracker_isDoNothing(): Boolean = lookupTracker_isDoNothing
|
||||
|
||||
override fun compilationCanceledStatus_checkCanceled() {
|
||||
compilationCancelledStatus!!.checkCanceled()
|
||||
try {
|
||||
compilationCancelledStatus!!.checkCanceled()
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
// avoid passing exceptions that may have different serialVersionUID on across rmi border
|
||||
// TODO: doublecheck whether we need to distinguish different cancellation exceptions
|
||||
throw RmiFriendlyCompilationCancelledException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user