Compare commits

...

57 Commits

Author SHA1 Message Date
Stanislav Erokhin
0fbd76755a KT-9461: Inference failed: type parameter fixed early
#KT-9461 Fixed
(cherry picked from commit 77ce125)
2015-10-05 17:37:07 +03:00
Nikolay Krasko
1aba7c28dd Enable version auto-increment and bootstrap against M13 2015-09-25 18:45:11 +03:00
Nikolay Krasko
c2ed3ed2f6 Do not substitute version in bootstrap build 2015-09-25 18:41:52 +03:00
Nikolay Krasko
0e695dd185 Enable override version filter only for specific branch - allow auto-merge to other branches 2015-09-25 18:41:51 +03:00
Nikolay Krasko
dfa3acf0ec Auto-increment version from script
This allows to have own version system on particular branch. It's planned to be enabled in release branches.
2015-09-25 18:41:50 +03:00
Dmitry Jemerov
3f792854b6 to avoid deadlock, don't refresh VFS during service initialization, instead refresh asynchronously during plugin initialization
(cherry picked from commit c5309d7)
2015-09-22 15:28:06 +02:00
Dmitry Jemerov
e754035a13 do not cache binary contents when trying to check if a .class file is compiled with Kotlin
(cherry picked from commit 51ee1b3)
2015-09-22 15:28:06 +02:00
Alexander Udalov
7f60605d8e Update .idea/encodings.xml due to latest changes in IDEA EAP 2015-09-17 21:16:00 +03:00
Alexander Udalov
7306b7abfd Disallow arrays as upper bounds of type parameters
#KT-9189 Fixed
2015-09-17 21:15:58 +03:00
Ilya Gorbunov
e0fde36246 Revert unification of operations on Array<T> and Array<out T> (copyOf, copyOfRange) which return the same type as the receiver.
Leave sortedArray, reversedArray and sliceArray only for covariant projection of array as the receiver.
2015-09-17 21:15:53 +03:00
Alexey Tsvetkov
75f52ce5d4 Relax test assert: format-version.txt is ok
This change is due to d1bc711053
In the former commit kotlin cache dir is always created,
so changed assertion is always false. Not so on master.
2015-09-16 18:53:26 +03:00
Alexey Tsvetkov
bf567ca37e Create Kotlin incremental caches only on write 2015-09-16 18:53:26 +03:00
Alexey Tsvetkov
deb71945d4 Revert removing testDoNotCreateUselessKotlinIncrementalCaches
Removed by mistake in b25dfabbcc
2015-09-16 18:53:26 +03:00
Alexander Udalov
475519cbbc Do not decompile old incompatible package parts
Fix the test by reverting 282727b
2015-09-16 03:33:45 +03:00
Alexander Udalov
e3ec6be284 Revert incomplete hierarchy error reporting because of a flaky test
This reverts commit 0d2c6be91a.
2015-09-16 03:33:17 +03:00
Alexander Udalov
188a702599 Improve ABI version error reporting in the compiler
- only report ABI errors if there's at least one other error
- append additional helpful information to the "unresolved reference" error
2015-09-16 01:55:53 +03:00
Alexander Udalov
9e90116e03 Fix ABI version diagnostic for old package facades
Restore the test data that was erroneously replaced in 84649e4
2015-09-16 01:55:47 +03:00
Alexander Udalov
ce9521a8c5 Minor refactoring in LazyJavaPackageScope 2015-09-16 01:55:40 +03:00
Alexander Udalov
0d2c6be91a Report incomplete hierarchy error for deserialized types
#KT-5129 Fixed

Delete a JPS test that was specifically testing that we would not fail in this
situation; now there's a compilation error
2015-09-16 01:55:07 +03:00
Alexander Udalov
6cc26dfb8d Minor, improve exception message for reflection on built-ins 2015-09-16 01:54:27 +03:00
Alexander Udalov
c8bddb7fd8 Improve inline diagnostics, report "nothing to inline" on the modifier 2015-09-16 01:54:21 +03:00
Alexander Udalov
ecf1a1b52f Fix exception from data class codegen for light classes
EA-66827
2015-09-16 01:54:10 +03:00
Valentin Kipyatkov
24dbd7734d KT-9128 ReplaceWith incorrectly converts javaClass<X>() to X::class.java for type with arguments
#KT-9128 Fixed
(cherry picked from commit 695feac)
2015-09-15 20:21:14 +03:00
Dmitry Jemerov
691e68c015 verify.groovy: ignore PERF output 2015-09-15 17:20:21 +02:00
Dmitry Jemerov
f03967dbd7 don't initialize Kotlin caches if there is no Kotlin code to compile 2015-09-15 14:07:10 +02:00
Dmitry Jemerov
d1bc711053 ensure that directory for incremental cache storage is created 2015-09-15 10:22:00 +02:00
Dmitry Petrov
8be86d3b04 Generate light classes for single-file facades using PackageCodegen.
(cherry picked from commit 47b8853)
2015-09-15 10:58:06 +03:00
Dmitry Jemerov
9c1a45d11e fix JetSafeDeleteTest
(cherry picked from commit d499103)
2015-09-14 21:50:59 +02:00
Dmitry Petrov
75b59d1b9f Do not generate facade for single-file light classes
(cherry picked from commit ef6da03)
2015-09-14 22:05:19 +03:00
Dmitry Petrov
e03e78f520 Advance ABI version (due to stdlib binary layout changes)
(cherry picked from commit b63eed4)
2015-09-14 22:03:28 +03:00
Dmitry Jemerov
960c50b696 Merge branch 'm13-facades' into M13 2015-09-14 19:42:24 +02:00
Dmitry Jemerov
93f3cdf5fb fix expected output that changed due to perf removal 2015-09-14 19:28:04 +02:00
Valentin Kipyatkov
fe2ff6d0d3 Made methods generated from declarations marked with @HiddenDeclaration synthetic in JVM
(cherry picked from commit 08e7a9d)
2015-09-14 20:11:32 +03:00
Valentin Kipyatkov
b3cec87b4c Fixed assertion in j2k on updating external usages
(cherry picked from commit aec661a)
2015-09-14 20:11:31 +03:00
Yan Zhulanow
2b0af6c34a Fix .java files compilation in android-compiler-plugin 2015-09-14 19:55:52 +03:00
Alexey Sedunov
062fea3180 Change Signature: Fix processing of top-level declarations usages in Java (old/new package facades are supported) 2015-09-14 18:52:31 +02:00
Dmitry Jemerov
a424020332 code review 2015-09-14 18:52:31 +02:00
Dmitry Jemerov
7df0636206 move supports new facades 2015-09-14 18:52:30 +02:00
Dmitry Jemerov
6c3adeedd9 safe delete supports new facades 2015-09-14 18:52:29 +02:00
Dmitry Jemerov
4f0e6fce52 call hierarchy supports new facades 2015-09-14 18:52:29 +02:00
Dmitry Jemerov
1da391b306 update Java references to file class when a file is renamed 2015-09-14 18:52:29 +02:00
Dmitry Jemerov
77d25b20a7 allow returning multiple PsiMethod wrappers for a JetFunction or JetPropertyAccessor; use that for handling Java usages through old-style and new-style facades
#KT-9102 Fixed
2015-09-14 18:52:29 +02:00
Dmitry Jemerov
3dda274ab6 LightClassUtil: J2K 2015-09-14 18:52:28 +02:00
Dmitry Jemerov
244cfa3e5d LightClassUtil: rename to .kt 2015-09-14 18:52:28 +02:00
Pavel V. Talanov
87aa52995c Do not generate parts of multifile facade when building light classes
Building facade class is enough for this purpose
2015-09-14 19:47:36 +03:00
Pavel V. Talanov
ea743f5748 Introduce ClsJavaStubByVirtualFileCache
Avoid caching in user data of virtual file because it leads to project leaking
2015-09-14 19:47:35 +03:00
Dmitry Petrov
1f3d1595e2 Fix navigation to decompiled multifile class members.
(cherry picked from commit f4e9d9a)
2015-09-14 19:00:20 +03:00
Dmitry Petrov
32960aa445 Multifile facade should contain reflection data,
otherwise callable references to stdlib functions will not work in the migration scheme.
(cherry picked from commit 50ff2a3)
2015-09-14 19:00:17 +03:00
Dmitry Petrov
372e1026c8 Fix incremental compilation tests
(cherry picked from commit 5d0243d)
2015-09-14 19:00:11 +03:00
Dmitry Petrov
688a7b58d2 Make stdlib work with -Xmultifile-package-facades.
Fixed wrong owner mapping in presence of -Xmultifile-package-facades.
Fixed backing field mapping issue.
Added more tests.
(cherry picked from commit 1586a2d)
2015-09-14 19:00:07 +03:00
Dmitry Petrov
120dde0645 - call multifile class members (compiling against binaries)
- inline multifile class members
HACK? scope-based part/facade resolution
(cherry picked from commit 838433b)
2015-09-14 19:00:03 +03:00
Dmitry Petrov
a408401149 - call multifile class members (compiling against binaries)
- inline multifile class members
(cherry picked from commit 50f83da)
2015-09-14 18:59:59 +03:00
Dmitry Petrov
22bc3b8e34 - bytecodeTextMultifile - framework for bytecode text tests
with multiple Kotlin source files
- bytecodeTextMultifile/partMembersCall, initial import
(cherry picked from commit 5f9a59d)
2015-09-14 18:59:55 +03:00
Dmitry Petrov
71f84f7982 - InnerClasses & EnclosingMethod attributes for local classes
in multifile part members
- invocation of multifile part/facade members
(TODO: deserialized descriptor case)
- inlining of multifile part/facade members
(TODO: inline against binaries case)
(cherry picked from commit 2931e47)
2015-09-14 18:59:51 +03:00
Dmitry Jemerov
2910bf69da disable perf output by default (M13 only) 2015-09-14 15:16:02 +02:00
Alexander Udalov
5edc043d05 Fix NPE from REPL initialization 2015-09-14 13:24:37 +03:00
Mikhail Glukhikh
585aa59e4c AnnotationTarget.CLASSIFIER and KotlinTarget.CLASSIFIER both dropped (second step) 2015-09-14 11:16:17 +03:00
253 changed files with 3051 additions and 1271 deletions

7
.idea/encodings.xml generated
View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

View File

@@ -586,8 +586,9 @@
<target name="android-compiler-plugin">
<cleandir dir="${output}/classes/android-compiler-plugin"/>
<kotlinc output="${output}/classes/android-compiler-plugin" modulename="kotlin-android-compiler-plugin">
<javac2 destdir="${output}/classes/android-compiler-plugin" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
<withKotlin modulename="kotlin-android-compiler-plugin"/>
<skip pattern="kotlin/jvm/internal/.*"/>
<src>
<pathelement path="plugins/android-compiler-plugin/src"/>
</src>
@@ -597,7 +598,7 @@
<pathelement path="${bootstrap.runtime}"/>
<pathelement path="${bootstrap.reflect}"/>
</classpath>
</kotlinc>
</javac2>
<jar destfile="${kotlin-home}/lib/android-compiler-plugin.jar">
<fileset dir="${output}/classes/android-compiler-plugin"/>
@@ -702,6 +703,7 @@
<arg value="-d"/>
<arg value="@{output}"/>
<arg value="-no-stdlib"/>
<arg value="-Xmultifile-package-facades"/>
<arg value="-classpath"/>
<arg value="${toString:classpath.path}"/>
<arg value="-module-name"/>

View File

@@ -19,11 +19,9 @@ package org.jetbrains.kotlin.backend.common;
import com.intellij.openapi.editor.Document;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.bridges.BridgesPackage;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.name.Name;
@@ -41,19 +39,11 @@ import java.util.*;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
/**
* Backend-independent utility class.
*/
public class CodegenUtil {
private CodegenUtil() {
}
// TODO: consider putting predefined method signatures here too.
public static final String EQUALS_METHOD_NAME = "equals";
public static final String TO_STRING_METHOD_NAME = "toString";
public static final String HASH_CODE_METHOD_NAME = "hashCode";
@Nullable
public static FunctionDescriptor getDeclaredFunctionByRawSignature(
@NotNull ClassDescriptor owner,
@@ -73,29 +63,6 @@ public class CodegenUtil {
return null;
}
public static FunctionDescriptor getAnyEqualsMethod(@NotNull KotlinBuiltIns builtIns) {
ClassDescriptor anyClass = builtIns.getAny();
FunctionDescriptor function = getDeclaredFunctionByRawSignature(
anyClass, Name.identifier(EQUALS_METHOD_NAME), builtIns.getBoolean(), anyClass
);
assert function != null;
return function;
}
public static FunctionDescriptor getAnyToStringMethod(@NotNull KotlinBuiltIns builtIns) {
ClassDescriptor anyClass = builtIns.getAny();
FunctionDescriptor function = getDeclaredFunctionByRawSignature(anyClass, Name.identifier(TO_STRING_METHOD_NAME), builtIns.getString());
assert function != null;
return function;
}
public static FunctionDescriptor getAnyHashCodeMethod(@NotNull KotlinBuiltIns builtIns) {
ClassDescriptor anyClass = builtIns.getAny();
FunctionDescriptor function = getDeclaredFunctionByRawSignature(anyClass, Name.identifier(HASH_CODE_METHOD_NAME), builtIns.getInt());
assert function != null;
return function;
}
@Nullable
public static PropertyDescriptor getDelegatePropertyIfAny(JetExpression expression, ClassDescriptor classDescriptor, BindingContext bindingContext) {
PropertyDescriptor propertyDescriptor = null;

View File

@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.backend.common;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.JetClass;
@@ -41,11 +43,13 @@ public abstract class DataClassMethodGenerator {
private final JetClassOrObject declaration;
private final BindingContext bindingContext;
private final ClassDescriptor classDescriptor;
private final KotlinBuiltIns builtIns;
public DataClassMethodGenerator(JetClassOrObject declaration, BindingContext bindingContext) {
this.declaration = declaration;
this.bindingContext = bindingContext;
this.classDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration);
this.builtIns = getBuiltIns(classDescriptor);
}
public void generate() {
@@ -61,20 +65,17 @@ public abstract class DataClassMethodGenerator {
}
}
// Backend-specific implementations.
protected abstract void generateComponentFunction(
@NotNull FunctionDescriptor function,
@NotNull ValueParameterDescriptor parameter
);
protected abstract void generateComponentFunction(@NotNull FunctionDescriptor function, @NotNull ValueParameterDescriptor parameter);
protected abstract void generateCopyFunction(@NotNull FunctionDescriptor function, @NotNull List<JetParameter> constructorParameters);
protected abstract void generateToStringMethod(@NotNull List<PropertyDescriptor> properties);
protected abstract void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
protected abstract void generateHashCodeMethod(@NotNull List<PropertyDescriptor> properties);
protected abstract void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
protected abstract void generateEqualsMethod(@NotNull List<PropertyDescriptor> properties);
protected abstract void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
@NotNull
protected ClassDescriptor getClassDescriptor() {
return classDescriptor;
}
@@ -101,24 +102,23 @@ public abstract class DataClassMethodGenerator {
}
private void generateDataClassToStringIfNeeded(@NotNull List<PropertyDescriptor> properties) {
ClassDescriptor stringClass = getBuiltIns(classDescriptor).getString();
if (!hasDeclaredNonTrivialMember(CodegenUtil.TO_STRING_METHOD_NAME, stringClass)) {
generateToStringMethod(properties);
FunctionDescriptor function = getDeclaredMember("toString", builtIns.getString());
if (function != null && isTrivial(function)) {
generateToStringMethod(function, properties);
}
}
private void generateDataClassHashCodeIfNeeded(@NotNull List<PropertyDescriptor> properties) {
ClassDescriptor intClass = getBuiltIns(classDescriptor).getInt();
if (!hasDeclaredNonTrivialMember(CodegenUtil.HASH_CODE_METHOD_NAME, intClass)) {
generateHashCodeMethod(properties);
FunctionDescriptor function = getDeclaredMember("hashCode", builtIns.getInt());
if (function != null && isTrivial(function)) {
generateHashCodeMethod(function, properties);
}
}
private void generateDataClassEqualsIfNeeded(@NotNull List<PropertyDescriptor> properties) {
ClassDescriptor booleanClass = getBuiltIns(classDescriptor).getBoolean();
ClassDescriptor anyClass = getBuiltIns(classDescriptor).getAny();
if (!hasDeclaredNonTrivialMember(CodegenUtil.EQUALS_METHOD_NAME, booleanClass, anyClass)) {
generateEqualsMethod(properties);
FunctionDescriptor function = getDeclaredMember("equals", builtIns.getBoolean(), builtIns.getAny());
if (function != null && isTrivial(function)) {
generateEqualsMethod(function, properties);
}
}
@@ -132,42 +132,41 @@ public abstract class DataClassMethodGenerator {
return result;
}
private
@NotNull
List<JetParameter> getPrimaryConstructorParameters() {
private List<JetParameter> getPrimaryConstructorParameters() {
if (declaration instanceof JetClass) {
return ((JetClass) declaration).getPrimaryConstructorParameters();
return declaration.getPrimaryConstructorParameters();
}
return Collections.emptyList();
}
/**
* @return true if the class has a declared member with the given name anywhere in its hierarchy besides Any
*/
private boolean hasDeclaredNonTrivialMember(
@Nullable
private FunctionDescriptor getDeclaredMember(
@NotNull String name,
@NotNull ClassDescriptor returnedClassifier,
@NotNull ClassDescriptor... valueParameterClassifiers
) {
FunctionDescriptor function =
CodegenUtil.getDeclaredFunctionByRawSignature(classDescriptor, Name.identifier(name), returnedClassifier,
valueParameterClassifiers);
if (function == null) {
return false;
}
return CodegenUtil.getDeclaredFunctionByRawSignature(
classDescriptor, Name.identifier(name), returnedClassifier, valueParameterClassifiers
);
}
/**
* @return true if the member is an inherited implementation of a method from Any
*/
private boolean isTrivial(@NotNull FunctionDescriptor function) {
if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
return true;
return false;
}
for (CallableDescriptor overridden : OverrideResolver.getOverriddenDeclarations(function)) {
if (overridden instanceof CallableMemberDescriptor
&& ((CallableMemberDescriptor) overridden).getKind() == CallableMemberDescriptor.Kind.DECLARATION
&& !overridden.getContainingDeclaration().equals(getBuiltIns(classDescriptor).getAny())) {
return true;
&& !overridden.getContainingDeclaration().equals(builtIns.getAny())) {
return false;
}
}
return false;
return true;
}
}

View File

@@ -188,7 +188,6 @@ public abstract class AnnotationCodegen {
new EnumMap<KotlinTarget, ElementType>(KotlinTarget.class);
static {
annotationTargetMap.put(KotlinTarget.CLASSIFIER, ElementType.TYPE);
annotationTargetMap.put(KotlinTarget.CLASS, ElementType.TYPE);
annotationTargetMap.put(KotlinTarget.ANNOTATION_CLASS, ElementType.ANNOTATION_TYPE);
annotationTargetMap.put(KotlinTarget.CONSTRUCTOR, ElementType.CONSTRUCTOR);

View File

@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.kotlin.resolve.jvm.JvmPackage;
@@ -218,6 +219,11 @@ public class AsmUtil {
int flags = getVisibilityAccessFlag(functionDescriptor);
flags |= getVarargsFlag(functionDescriptor);
flags |= getDeprecatedAccessFlag(functionDescriptor);
if (DescriptorUtilPackage.isAnnotatedAsHidden(functionDescriptor)
|| functionDescriptor instanceof PropertyAccessorDescriptor
&& DescriptorUtilPackage.isAnnotatedAsHidden(((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty())) {
flags |= ACC_SYNTHETIC;
}
return flags;
}

View File

@@ -88,25 +88,29 @@ public class ClassFileFactory implements OutputFileCollection {
for (PackageCodegen codegen : packageCodegens) {
codegen.done();
}
for (MultifileClassCodegen codegen : multifileClass2codegen.values()) {
Collection<MultifileClassCodegen> multifileClassCodegens = multifileClass2codegen.values();
for (MultifileClassCodegen codegen : multifileClassCodegens) {
codegen.done();
}
// TODO module mappings for multifile classes
writeModuleMappings(packageCodegens);
writeModuleMappings(packageCodegens, multifileClassCodegens);
}
}
private void writeModuleMappings(Collection<PackageCodegen> values) {
private void writeModuleMappings(
@NotNull Collection<PackageCodegen> packageCodegens,
@NotNull Collection<MultifileClassCodegen> multifileClassCodegens
) {
final JvmPackageTable.PackageTable.Builder builder = JvmPackageTable.PackageTable.newBuilder();
String outputFilePath = getMappingFileName(state.getModuleName());
List<PackageParts> parts = ContainerUtil.newArrayList();
List<PackageParts> parts = collectGeneratedPackageParts(packageCodegens, multifileClassCodegens);
Set<File> sourceFiles = new HashSet<File>();
for (PackageCodegen codegen : values) {
parts.add(codegen.getPackageParts());
// TODO extract common logic
// TODO extract common logic
for (PackageCodegen codegen : packageCodegens) {
sourceFiles.addAll(toIoFilesIgnoringNonPhysical(PackagePartClassUtils.getFilesWithCallables(codegen.getFiles())));
}
for (MultifileClassCodegen codegen : multifileClassCodegens) {
sourceFiles.addAll(toIoFilesIgnoringNonPhysical(PackagePartClassUtils.getFilesWithCallables(codegen.getFiles())));
}
@@ -152,6 +156,34 @@ public class ClassFileFactory implements OutputFileCollection {
}
}
private static List<PackageParts> collectGeneratedPackageParts(
@NotNull Collection<PackageCodegen> packageCodegens,
@NotNull Collection<MultifileClassCodegen> multifileClassCodegens
) {
Map<String, PackageParts> mergedPartsByPackageName = new LinkedHashMap<String, PackageParts>();
for (PackageCodegen packageCodegen : packageCodegens) {
PackageParts generatedParts = packageCodegen.getPackageParts();
PackageParts premergedParts = new PackageParts(generatedParts.getPackageFqName());
mergedPartsByPackageName.put(generatedParts.getPackageFqName(), premergedParts);
premergedParts.getParts().addAll(generatedParts.getParts());
}
for (MultifileClassCodegen multifileClassCodegen : multifileClassCodegens) {
PackageParts multifileClassParts = multifileClassCodegen.getPackageParts();
PackageParts premergedParts = mergedPartsByPackageName.get(multifileClassParts.getPackageFqName());
if (premergedParts == null) {
premergedParts = new PackageParts(multifileClassParts.getPackageFqName());
mergedPartsByPackageName.put(multifileClassParts.getPackageFqName(), premergedParts);
}
premergedParts.getParts().addAll(multifileClassParts.getParts());
}
List<PackageParts> result = new ArrayList<PackageParts>();
result.addAll(mergedPartsByPackageName.values());
return result;
}
@NotNull
@Override
public List<OutputFile> asList() {
@@ -183,6 +215,16 @@ public class ClassFileFactory implements OutputFileCollection {
return answer.toString();
}
@NotNull
@TestOnly
public Map<String, String> createTextForEachFile() {
Map<String, String> answer = new LinkedHashMap<String, String>();
for (OutputFile file : asList()) {
answer.put(file.getRelativePath(), file.asText());
}
return answer;
}
@NotNull
public PackageCodegen forPackage(@NotNull FqName fqName, @NotNull Collection<JetFile> files) {
assert !isDone : "Already done!";

View File

@@ -19,17 +19,16 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.resolve.BindingContext
import java.util.*
public class CodegenFileClassesProvider() : JvmFileClassesProvider {
private val fileParts = hashMapOf<JetFile, JvmFileClassInfo>()
override fun getFileClassFqName(file: JetFile): FqName =
getFileClassInfo(file).fileClassFqName
public fun getFileClassInfo(file: JetFile): JvmFileClassInfo =
fileParts.getOrPut(file) { JvmFileClassUtil.getFileClassInfoNoResolve(file) }
public class CodegenFileClassesProvider(private val packageFacadesAsMultifileClasses: Boolean) : JvmFileClassesProvider {
override public fun getFileClassInfo(file: JetFile): JvmFileClassInfo {
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file)
if (packageFacadesAsMultifileClasses && !fileClassInfo.isMultifileClass) {
return JvmFileClassUtil.getMultifilePackageFacadePartInfo(file)
}
else {
return fileClassInfo
}
}
}

View File

@@ -148,9 +148,8 @@ public class FunctionCodegen {
int flags = getMethodAsmFlags(functionDescriptor, contextKind);
boolean isNative = NativeDeclarationsPackage.hasNativeAnnotation(functionDescriptor);
//TODO: generate native method only in new mini facades (now it equals to package part)
if (isNative && owner instanceof PackageFacadeContext) {
// Native methods are only defined in package facades and do not need package part implementations
if (isNative && owner instanceof DelegatingFacadeContext) {
// Native methods are only defined in facades and do not need package part implementations
return;
}
MethodVisitor mv = v.newMethod(origin,
@@ -160,7 +159,7 @@ public class FunctionCodegen {
jvmSignature.getGenericsSignature(),
getThrownExceptions(functionDescriptor, typeMapper));
String implClassName = CodegenContextUtil.getImplClassNameByOwnerIfRequired(owner);
String implClassName = CodegenContextUtil.getImplementationClassShortName(owner);
if (implClassName != null) {
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, functionDescriptor, implClassName);
}
@@ -329,8 +328,8 @@ public class FunctionCodegen {
JetTypeMapper typeMapper = parentCodegen.typeMapper;
Label methodEnd;
if (context.getParentContext() instanceof PackageFacadeContext) {
generatePackageDelegateMethodBody(mv, signature.getAsmMethod(), (PackageFacadeContext) context.getParentContext());
if (context.getParentContext() instanceof DelegatingFacadeContext) {
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (DelegatingFacadeContext) context.getParentContext());
methodEnd = new Label();
}
else {
@@ -402,10 +401,10 @@ public class FunctionCodegen {
}
}
private static void generatePackageDelegateMethodBody(
private static void generateFacadeDelegateMethodBody(
@NotNull MethodVisitor mv,
@NotNull Method asmMethod,
@NotNull PackageFacadeContext context
@NotNull DelegatingFacadeContext context
) {
generateDelegateToMethodBody(true, mv, asmMethod, context.getDelegateToClassType().getInternalName());
}
@@ -596,9 +595,9 @@ public class FunctionCodegen {
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType());
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
if (this.owner instanceof PackageFacadeContext) {
if (this.owner instanceof DelegatingFacadeContext) {
mv.visitCode();
generatePackageDelegateMethodBody(mv, defaultMethod, (PackageFacadeContext) this.owner);
generateFacadeDelegateMethodBody(mv, defaultMethod, (DelegatingFacadeContext) this.owner);
endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
}
else {

View File

@@ -484,17 +484,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
public void generateEqualsMethod(@NotNull List<PropertyDescriptor> properties) {
KotlinBuiltIns builtins = getBuiltIns(descriptor);
FunctionDescriptor equalsFunction = CodegenUtil.getDeclaredFunctionByRawSignature(
descriptor, Name.identifier(CodegenUtil.EQUALS_METHOD_NAME), builtins.getBoolean(), builtins.getAny()
);
assert equalsFunction != null : String.format("Should be called only for classes with non-trivial '%s'. In %s, %s",
CodegenUtil.EQUALS_METHOD_NAME, descriptor.getName(), descriptor);
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(equalsFunction);
MethodVisitor mv = v.newMethod(OtherOrigin(equalsFunction), ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
MethodVisitor mv = v.newMethod(OtherOrigin(function), ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
InstructionAdapter iv = new InstructionAdapter(mv);
mv.visitCode();
@@ -560,16 +552,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
public void generateHashCodeMethod(@NotNull List<PropertyDescriptor> properties) {
FunctionDescriptor hashCodeFunction = CodegenUtil.getDeclaredFunctionByRawSignature(
descriptor, Name.identifier(CodegenUtil.HASH_CODE_METHOD_NAME), getBuiltIns(descriptor).getInt()
);
assert hashCodeFunction != null : String.format("Should be called only for classes with non-trivial '%s'. In %s, %s",
CodegenUtil.HASH_CODE_METHOD_NAME, descriptor.getName(), descriptor);
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(hashCodeFunction);
MethodVisitor mv = v.newMethod(OtherOrigin(hashCodeFunction), ACC_PUBLIC, "hashCode", "()I", null, null);
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
MethodVisitor mv = v.newMethod(OtherOrigin(function), ACC_PUBLIC, "hashCode", "()I", null, null);
InstructionAdapter iv = new InstructionAdapter(mv);
mv.visitCode();
@@ -616,16 +601,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
public void generateToStringMethod(@NotNull List<PropertyDescriptor> properties) {
FunctionDescriptor toString = CodegenUtil.getDeclaredFunctionByRawSignature(
descriptor, Name.identifier(CodegenUtil.TO_STRING_METHOD_NAME), getBuiltIns(descriptor).getString()
);
assert toString != null : String.format("Should be called only for classes with non-trivial '%s'. In %s, %s",
CodegenUtil.TO_STRING_METHOD_NAME, descriptor.getName(), descriptor);
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(toString);
MethodVisitor mv = v.newMethod(OtherOrigin(toString), ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
MethodVisitor mv = v.newMethod(OtherOrigin(function), ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
InstructionAdapter iv = new InstructionAdapter(mv);
mv.visitCode();

View File

@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment;
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass;
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement;
import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass;
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider;
@@ -143,12 +144,15 @@ public class JvmCodegenUtil {
return false;
}
KotlinJvmBinaryClass binaryClass = ((LazyJavaPackageFragment) packageFragment).getScope().getKotlinBinaryClass();
if (binaryClass instanceof VirtualFileKotlinClass) {
VirtualFile file = ((VirtualFileKotlinClass) binaryClass).getFile();
if (file.getFileSystem().getProtocol() == StandardFileSystems.FILE_PROTOCOL) {
File ioFile = VfsUtilCore.virtualToIoFile(file);
return ioFile.getAbsolutePath().startsWith(outDirectory.getAbsolutePath() + File.separator);
SourceElement source = ((LazyJavaPackageFragment) packageFragment).getSource();
if (source instanceof KotlinJvmBinarySourceElement) {
KotlinJvmBinaryClass binaryClass = ((KotlinJvmBinarySourceElement) source).getBinaryClass();
if (binaryClass instanceof VirtualFileKotlinClass) {
VirtualFile file = ((VirtualFileKotlinClass) binaryClass).getFile();
if (file.getFileSystem().getProtocol() == StandardFileSystems.FILE_PROTOCOL) {
File ioFile = VfsUtilCore.virtualToIoFile(file);
return ioFile.getAbsolutePath().startsWith(outDirectory.getAbsolutePath() + File.separator);
}
}
}

View File

@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.name.Name;
@@ -289,9 +290,16 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
if (outermost instanceof ClassContext) {
return typeMapper.mapType(((ClassContext) outermost).getContextDescriptor());
}
else if (outermost instanceof PackageContext && !(outermost instanceof PackageFacadeContext)) {
return fileClassesProvider.getFileClassType(element.getContainingJetFile());
}/*disabled cause of KT-7775
else if (outermost instanceof DelegatingFacadeContext || outermost instanceof DelegatingToPartContext) {
Type implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(outermost);
if (implementationOwnerType != null) {
return implementationOwnerType;
}
else {
return FileClassesPackage.getFileClassType(fileClassesProvider, element.getContainingJetFile());
}
}
/*disabled cause of KT-7775
else if (outermost instanceof ScriptContext) {
return asmTypeForScriptDescriptor(bindingContext, ((ScriptContext) outermost).getScriptDescriptor());
}*/

View File

@@ -26,22 +26,29 @@ import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.fileClasses.getFileClassType
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.PackageParts
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.MemberComparator
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClassPart
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import java.util.*
public class MultifileClassCodegen(
private val state: GenerationState,
private val files: Collection<JetFile>,
public val files: Collection<JetFile>,
private val facadeFqName: FqName
) {
private val facadeClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(facadeFqName)
@@ -50,6 +57,8 @@ public class MultifileClassCodegen(
private val compiledPackageFragment = getCompiledPackageFragment(facadeFqName.parent(), state)
public val packageParts = PackageParts(facadeFqName.parent().asString())
// TODO incremental compilation support
// TODO previouslyCompiledCallables
// We can do this (probably without 'compiledPackageFragment') after modifications to part codegen.
@@ -107,6 +116,7 @@ public class MultifileClassCodegen(
tasks: Map<CallableMemberDescriptor, () -> Unit>,
partFqNames: List<FqName>
) {
generateKotlinPackageReflectionField()
MemberCodegen.generateModuleNameField(state, classBuilder)
for (member in tasks.keySet().sortedWith(MemberComparator.INSTANCE)) {
@@ -146,7 +156,6 @@ public class MultifileClassCodegen(
}
}
else if (declaration is JetScript) {
// SCRIPT: generate script code, should be separate execution branch
if (state.generateDeclaredClassFilter.shouldGenerateScript(declaration)) {
ScriptCodegen.createScriptCodegen(declaration, state, partContext).generate()
@@ -159,8 +168,8 @@ public class MultifileClassCodegen(
partFqNames.add(partClassInfo.fileClassFqName)
// val name = partType.internalName
// packageParts.parts.add(name.substring(name.lastIndexOf('/') + 1))
val name = partType.internalName
packageParts.parts.add(name.substring(name.lastIndexOf('/') + 1))
val builder = state.factory.newVisitor(MultifileClassPart(file, packageFragment, facadeFqName), partType, file)
@@ -178,6 +187,16 @@ public class MultifileClassCodegen(
}
}
private fun generateKotlinPackageReflectionField() {
val mv = classBuilder.newMethod(JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_STATIC, "<clinit>", "()V", null, null)
val method = AsmUtil.method("createKotlinPackage",
AsmTypes.K_PACKAGE_TYPE, AsmTypes.getType(Class::class.java), AsmTypes.getType(String::class.java))
val iv = InstructionAdapter(mv)
MemberCodegen.generateReflectionObjectField(state, facadeClassType, classBuilder, method, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, iv)
iv.areturn(Type.VOID_TYPE)
FunctionCodegen.endVisit(mv, "package facade static initializer", null)
}
private fun writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames: List<FqName>) {
if (state.classBuilderMode != ClassBuilderMode.FULL) return
if (files.any { it.isScript }) return

View File

@@ -43,6 +43,11 @@ public class MultifileClassPartCodegen(
partContext: FieldOwnerContext<*>,
state: GenerationState
) : MemberCodegen<JetFile>(state, null, partContext, file, v) {
override fun generate() {
if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) return
super.generate()
}
override fun generateDeclaration() {
v.defineClass(element, Opcodes.V1_6,
Opcodes.ACC_FINAL or Opcodes.ACC_SYNTHETIC,

View File

@@ -39,7 +39,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
@@ -313,7 +313,7 @@ public class PackageCodegen {
@Nullable
private ClassBuilder generate(@NotNull JetFile file, @NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks) {
boolean generatePackagePart = false;
Type packagePartType = state.getFileClassesProvider().getFileClassType(file);
Type packagePartType = FileClassesPackage.getFileClassType(state.getFileClassesProvider(), file);
PackageContext packagePartContext = state.getRootContext().intoPackagePart(packageFragment, packagePartType);
for (JetDeclaration declaration : file.getDeclarations()) {
@@ -414,7 +414,7 @@ public class PackageCodegen {
public void generateClassOrObject(@NotNull JetClassOrObject classOrObject) {
JetFile file = classOrObject.getContainingJetFile();
Type packagePartType = state.getFileClassesProvider().getFileClassType(file);
Type packagePartType = FileClassesPackage.getFileClassType(state.getFileClassesProvider(), file);
CodegenContext context = state.getRootContext().intoPackagePart(packageFragment, packagePartType);
MemberCodegen.genClassOrObject(context, classOrObject, state, null);
}

View File

@@ -110,9 +110,9 @@ public class PropertyCodegen {
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
Type implClassType = CodegenContextUtil.getImplClassTypeByOwnerIfRequired(context);
if (implClassType != null) {
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, shortNameByAsmType(implClassType));
String implClassName = CodegenContextUtil.getImplementationClassShortName(context);
if (implClassName != null) {
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, implClassName);
}
if (CodegenContextUtil.isImplClassOwner(context)) {
@@ -493,6 +493,9 @@ public class PropertyCodegen {
else if (ownerContext instanceof PackageContext) {
owner = ((PackageContext) ownerContext).getPackagePartType();
}
else if (ownerContext instanceof MultifileClassContextBase) {
owner = ((MultifileClassContextBase) ownerContext).getFilePartType();
}
else {
throw new UnsupportedOperationException("Unknown context: " + ownerContext);
}

View File

@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl;
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
import org.jetbrains.kotlin.name.Name;
@@ -394,7 +395,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
else if (containingDeclaration instanceof PackageFragmentDescriptor) {
JetFile containingFile = DescriptorToSourceUtils.getContainingFile(descriptor);
assert containingFile != null : "File not found for " + descriptor;
return fileClassesProvider.getFileClassInternalName(containingFile) + '$' + name;
return FileClassesPackage.getFileClassInternalName(fileClassesProvider, containingFile) + '$' + name;
}
return null;
@@ -575,7 +576,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
}
}
return fileClassesProvider.getFileClassInternalName(file);
return FileClassesPackage.getFacadeClassInternalName(fileClassesProvider, file);
}
private static <T> T peekFromStack(@NotNull Stack<T> stack) {

View File

@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.AsmUtil;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
@@ -55,7 +56,7 @@ public final class PsiCodegenPredictor {
@Nullable
public static String getPredefinedJvmInternalName(
@NotNull JetDeclaration declaration,
@NotNull JvmFileClassesProvider fileClassesManager
@NotNull JvmFileClassesProvider fileClassesProvider
) {
// TODO: Method won't work for declarations inside companion objects
// TODO: Method won't give correct class name for traits implementations
@@ -64,7 +65,7 @@ public final class PsiCodegenPredictor {
String parentInternalName;
if (parentDeclaration != null) {
parentInternalName = getPredefinedJvmInternalName(parentDeclaration, fileClassesManager);
parentInternalName = getPredefinedJvmInternalName(parentDeclaration, fileClassesProvider);
if (parentInternalName == null) {
return null;
}
@@ -74,7 +75,7 @@ public final class PsiCodegenPredictor {
if (declaration instanceof JetNamedFunction) {
Name name = ((JetNamedFunction) declaration).getNameAsName();
return name == null ? null : fileClassesManager.getFileClassInternalName(containingFile) + "$" + name.asString();
return name == null ? null : FileClassesPackage.getFileClassInternalName(fileClassesProvider, containingFile) + "$" + name.asString();
}
parentInternalName = AsmUtil.internalNameByFqNameWithoutInnerClasses(containingFile.getPackageFqName());

View File

@@ -204,7 +204,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull Type multifileClassType,
@NotNull Type filePartType
) {
return new MultifileClassContext(descriptor, this, multifileClassType, filePartType);
return new MultifileClassFacadeContext(descriptor, this, multifileClassType, filePartType);
}
@NotNull

View File

@@ -21,21 +21,16 @@ import org.jetbrains.org.objectweb.asm.Type
public object CodegenContextUtil {
public @JvmStatic fun getImplClassTypeByOwnerIfRequired(owner: CodegenContext<*>): Type? =
public @JvmStatic fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
when (owner) {
is PackageFacadeContext ->
owner.delegateToClassType
is PackageContext ->
owner.packagePartType
is MultifileClassOrPartContext ->
owner.filePartType
else ->
null
is DelegatingFacadeContext -> owner.delegateToClassType
is DelegatingToPartContext -> owner.implementationOwnerClassType
else -> null
}
public @JvmStatic fun getImplClassNameByOwnerIfRequired(owner: CodegenContext<*>): String? =
getImplClassTypeByOwnerIfRequired(owner)?.let{ AsmUtil.shortNameByAsmType(it) }
public @JvmStatic fun getImplementationClassShortName(owner: CodegenContext<*>): String? =
getImplementationOwnerClassType(owner)?.let { AsmUtil.shortNameByAsmType(it) }
public @JvmStatic fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
!(owner is PackageFacadeContext || owner is MultifileClassContext)
owner !is DelegatingFacadeContext
}

View File

@@ -0,0 +1,25 @@
/*
* 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();
}

View File

@@ -0,0 +1,25 @@
/*
* 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 DelegatingToPartContext {
@Nullable
Type getImplementationOwnerClassType();
}

View File

@@ -20,11 +20,11 @@ import org.jetbrains.kotlin.codegen.OwnerKind;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.org.objectweb.asm.Type;
public class MultifileClassOrPartContext extends FieldOwnerContext<PackageFragmentDescriptor> {
public class MultifileClassContextBase extends FieldOwnerContext<PackageFragmentDescriptor> {
private final Type multifileClassType;
private final Type filePartType;
public MultifileClassOrPartContext(
public MultifileClassContextBase(
PackageFragmentDescriptor descriptor,
CodegenContext parent,
Type multifileClassType,

View File

@@ -16,13 +16,12 @@
package org.jetbrains.kotlin.codegen.context;
import org.jetbrains.kotlin.codegen.OwnerKind;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.org.objectweb.asm.Type;
public class MultifileClassContext extends MultifileClassOrPartContext {
public MultifileClassContext(
public class MultifileClassFacadeContext extends MultifileClassContextBase implements DelegatingFacadeContext {
public MultifileClassFacadeContext(
PackageFragmentDescriptor descriptor,
CodegenContext parent,
Type multifileClassType,
@@ -31,4 +30,9 @@ public class MultifileClassContext extends MultifileClassOrPartContext {
super(descriptor, parent, multifileClassType, filePartType);
}
@Nullable
@Override
public Type getDelegateToClassType() {
return getFilePartType();
}
}

View File

@@ -16,12 +16,11 @@
package org.jetbrains.kotlin.codegen.context;
import org.jetbrains.kotlin.codegen.OwnerKind;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.org.objectweb.asm.Type;
public class MultifileClassPartContext extends MultifileClassOrPartContext {
public class MultifileClassPartContext extends MultifileClassContextBase implements DelegatingToPartContext {
public MultifileClassPartContext(
PackageFragmentDescriptor descriptor,
CodegenContext parent,
@@ -31,4 +30,9 @@ public class MultifileClassPartContext extends MultifileClassOrPartContext {
super(descriptor, parent, multifileClassType, filePartType);
}
@Nullable
@Override
public Type getImplementationOwnerClassType() {
return getFilePartType();
}
}

View File

@@ -17,14 +17,19 @@
package org.jetbrains.kotlin.codegen.context;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.OwnerKind;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.org.objectweb.asm.Type;
public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor> {
public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor> implements DelegatingToPartContext {
private final Type packagePartType;
public PackageContext(@NotNull PackageFragmentDescriptor contextDescriptor, @NotNull CodegenContext parent, Type packagePartType) {
public PackageContext(
@NotNull PackageFragmentDescriptor contextDescriptor,
@NotNull CodegenContext parent,
@Nullable Type packagePartType
) {
super(contextDescriptor, OwnerKind.PACKAGE, parent, null, null, null);
this.packagePartType = packagePartType;
}
@@ -34,7 +39,14 @@ public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor>
return "Package: " + getContextDescriptor().getName();
}
@Nullable
public Type getPackagePartType() {
return packagePartType;
}
@Nullable
@Override
public Type getImplementationOwnerClassType() {
return packagePartType;
}
}

View File

@@ -17,20 +17,22 @@
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 {
public class PackageFacadeContext extends PackageContext implements DelegatingFacadeContext {
public PackageFacadeContext(
@NotNull PackageFragmentDescriptor contextDescriptor,
@NotNull CodegenContext parent,
@NotNull Type delegateTo
@NotNull Type packagePartType
) {
super(contextDescriptor, parent, delegateTo);
super(contextDescriptor, parent, packagePartType);
}
@NotNull
@Override
@Nullable
public Type getDelegateToClassType() {
return getPackagePartType();
}

View File

@@ -26,12 +26,11 @@ import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.codegen.MemberCodegen;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.context.PackageContext;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinder;
@@ -216,27 +215,27 @@ public class InlineCodegenUtil {
@NotNull CodegenContext codegenContext,
@NotNull DeclarationDescriptor currentDescriptor,
@NotNull JetTypeMapper typeMapper,
@NotNull JvmFileClassesProvider fileClassesManager
@NotNull JvmFileClassesProvider fileClassesProvider
) {
if (currentDescriptor instanceof PackageFragmentDescriptor) {
PsiFile file = getContainingFile(codegenContext);
Type packagePartType;
Type implementationOwnerType;
if (file == null) {
//in case package fragment clinit
assert codegenContext instanceof PackageContext : "Expected package context but " + codegenContext;
packagePartType = ((PackageContext) codegenContext).getPackagePartType();
implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(codegenContext);
} else {
packagePartType = fileClassesManager.getFileClassType((JetFile) file);
implementationOwnerType = FileClassesPackage.getFileClassType(fileClassesProvider, (JetFile) file);
}
if (packagePartType == null) {
if (implementationOwnerType == null) {
DeclarationDescriptor contextDescriptor = codegenContext.getContextDescriptor();
//noinspection ConstantConditions
throw new RuntimeException("Couldn't find declaration for " + contextDescriptor.getContainingDeclaration().getName() + "." + contextDescriptor.getName() );
throw new RuntimeException("Couldn't find declaration for " +
contextDescriptor.getContainingDeclaration().getName() + "." + contextDescriptor.getName() +
"; context: " + codegenContext);
}
return packagePartType.getInternalName();
return implementationOwnerType.getInternalName();
}
else if (currentDescriptor instanceof ClassifierDescriptor) {
Type type = typeMapper.mapType((ClassifierDescriptor) currentDescriptor);
@@ -254,7 +253,7 @@ public class InlineCodegenUtil {
String suffix = currentDescriptor.getName().isSpecial() ? "" : currentDescriptor.getName().asString();
//noinspection ConstantConditions
return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper, fileClassesManager) + "$" + suffix;
return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper, fileClassesProvider) + "$" + suffix;
}
public static boolean isInvokeOnLambda(@NotNull String owner, @NotNull String name) {

View File

@@ -82,7 +82,7 @@ public class GenerationState jvmOverloads constructor(
}
}
public val fileClassesProvider: CodegenFileClassesProvider = CodegenFileClassesProvider()
public val fileClassesProvider: CodegenFileClassesProvider = CodegenFileClassesProvider(packageFacadesAsMultifileClasses)
public val classBuilderMode: ClassBuilderMode = builderFactory.getClassBuilderMode()
public val bindingTrace: BindingTrace = DelegatingBindingTrace(bindingContext, "trace in GenerationState")

View File

@@ -20,6 +20,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
@@ -30,16 +31,15 @@ import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeDeclarationsPackage;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
import org.jetbrains.kotlin.name.*;
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
import org.jetbrains.kotlin.psi.JetExpression;
import org.jetbrains.kotlin.psi.JetFile;
@@ -58,8 +58,12 @@ import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
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.AbstractScopeAdapter;
import org.jetbrains.kotlin.resolve.scopes.ChainedScope;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.serialization.deserialization.DeserializedType;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope;
import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import org.jetbrains.org.objectweb.asm.Type;
@@ -142,12 +146,7 @@ public class JetTypeMapper {
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container instanceof PackageFragmentDescriptor) {
boolean effectiveInsideModule = isInsideModule && !NativeDeclarationsPackage.hasNativeAnnotation(descriptor);
return Type.getObjectType(internalNameForPackage(
(PackageFragmentDescriptor) container,
(CallableMemberDescriptor) descriptor,
effectiveInsideModule
));
return Type.getObjectType(internalNameForPackage((CallableMemberDescriptor) descriptor));
}
else if (container instanceof ClassDescriptor) {
return mapClass((ClassDescriptor) container);
@@ -161,30 +160,80 @@ public class JetTypeMapper {
}
@NotNull
private String internalNameForPackage(
@NotNull PackageFragmentDescriptor packageFragment,
@NotNull CallableMemberDescriptor descriptor,
boolean insideModule
) {
///if (insideModule) {
JetFile file = DescriptorToSourceUtils.getContainingFile(descriptor);
if (file != null) {
return fileClassesProvider.getFileClassInternalName(file);
private String internalNameForPackage(@NotNull CallableMemberDescriptor descriptor) {
JetFile file = DescriptorToSourceUtils.getContainingFile(descriptor);
if (file != null) {
Visibility visibility = descriptor.getVisibility();
if (descriptor instanceof PropertyDescriptor || Visibilities.isPrivate(visibility)) {
return FileClassesPackage.getFileClassInternalName(fileClassesProvider, file);
}
CallableMemberDescriptor directMember = getDirectMember(descriptor);
if (directMember instanceof DeserializedCallableMemberDescriptor) {
FqName packagePartFqName = PackagePartClassUtils.getPackagePartFqName((DeserializedCallableMemberDescriptor) directMember);
return internalNameByFqNameWithoutInnerClasses(packagePartFqName);
else {
return FileClassesPackage.getFacadeClassInternalName(fileClassesProvider, file);
}
}
//}
CallableMemberDescriptor directMember = getDirectMember(descriptor);
if (directMember instanceof DeserializedCallableMemberDescriptor) {
String facadeFqName = getPackageMemberOwnerInternalName((DeserializedCallableMemberDescriptor) directMember);
if (facadeFqName != null) return facadeFqName;
}
throw new RuntimeException("Unreachable state");
//return PackageClassUtils.getPackageClassInternalName(packageFragment.getFqName());
}
@Nullable
private static String getPackageMemberOwnerInternalName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
// XXX This method (and getPackageMemberOwnerShortName) is a dirty hack
// introduced to make stdlib work with package facades built as multifile facades for M13.
// We need some safe, concise way to identify multifile facade and multifile part
// from a deserialized package member descriptor.
// Possible approaches:
// - create a special instance of DeserializedPackageFragmentDescriptor for each facade class (multifile or single-file),
// keep related mapping information there;
// - provide a proper SourceElement for such descriptors (similar to KotlinJvmBinarySourceElement).
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
assert containingDeclaration instanceof PackageFragmentDescriptor : "Not a top-level member: " + descriptor;
PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
String facadeShortName = getPackageMemberOwnerShortName(descriptor);
if (facadeShortName == null) {
return null;
}
FqName facadeFqName = packageFragmentDescriptor.getFqName().child(Name.identifier(facadeShortName));
return internalNameByFqNameWithoutInnerClasses(facadeFqName);
}
@Nullable
private static String getPackageMemberOwnerShortName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
// XXX Dirty hack; see getPackageMemberOwnerInternalName above for more details.
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration instanceof PackageFragmentDescriptor) {
PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
JetScope scope = packageFragmentDescriptor.getMemberScope();
if (scope instanceof AbstractScopeAdapter) {
scope = ((AbstractScopeAdapter) scope).getActualScope();
}
if (scope instanceof LazyJavaPackageScope) {
Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
return ((LazyJavaPackageScope) scope).getFacadeSimpleNameForPartSimpleName(implClassName.asString());
}
else if (packageFragmentDescriptor instanceof BuiltinsPackageFragment) {
return PackageClassUtils.getPackageClassFqName(packageFragmentDescriptor.getFqName()).shortName().asString();
}
else {
// Incremental compilation ends up here. We do not have multifile classes support in incremental so far,
// so "use implementation class name" looks like a safe assumption for this case.
// However, this should be fixed; see getPackageMemberOwnerInternalName above for more details.
Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
return implClassName.asString();
}
}
return null;
}
@NotNull
public Type mapReturnType(@NotNull CallableDescriptor descriptor) {
return mapReturnType(descriptor, null);

View File

@@ -26,6 +26,8 @@ public class CLIConfigurationKeys {
CompilerConfigurationKey.create("message collector");
public static final CompilerConfigurationKey<List<CompilerPlugin>> COMPILER_PLUGINS =
CompilerConfigurationKey.create("compiler plugins");
public static final CompilerConfigurationKey<Boolean> REPORT_PERF =
CompilerConfigurationKey.create("enable perf");
private CLIConfigurationKeys() {
}

View File

@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
import org.jetbrains.kotlin.load.java.JavaBindingContext;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.components.TraceBasedErrorReporter;
import org.jetbrains.kotlin.load.java.components.TraceBasedErrorReporter.AbiVersionErrorData;
import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.kotlin.resolve.AnalyzingUtils;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -42,6 +43,7 @@ import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.kotlin.utils.UtilsPackage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -72,7 +74,11 @@ public final class AnalyzerWithCompilerReport {
messageCollector = new MessageSeverityCollector(collector);
}
private static boolean reportDiagnostic(@NotNull Diagnostic diagnostic, @NotNull MessageCollector messageCollector) {
private static boolean reportDiagnostic(
@NotNull Diagnostic diagnostic,
@NotNull MessageCollector messageCollector,
boolean incompatibleFilesFound
) {
if (!diagnostic.isValid()) return false;
String render;
@@ -83,6 +89,12 @@ public final class AnalyzerWithCompilerReport {
render = DefaultErrorMessages.render(diagnostic);
}
if (incompatibleFilesFound && Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) {
render += "\n(note: this may be caused by the fact that some classes compiled with an incompatible version of Kotlin " +
"were found in the classpath. Such classes cannot be loaded properly by this version of Kotlin compiler. " +
"See below for more information)";
}
PsiFile file = diagnostic.getPsiFile();
messageCollector.report(
convertSeverity(diagnostic.getSeverity()),
@@ -137,15 +149,23 @@ public final class AnalyzerWithCompilerReport {
}
}
private void reportAbiVersionErrors() {
@NotNull
private List<AbiVersionErrorData> getAbiVersionErrors() {
assert analysisResult != null;
BindingContext bindingContext = analysisResult.getBindingContext();
Collection<String> errorClasses = bindingContext.getKeys(TraceBasedErrorReporter.ABI_VERSION_ERRORS);
List<AbiVersionErrorData> result = new ArrayList<AbiVersionErrorData>(errorClasses.size());
for (String kotlinClass : errorClasses) {
TraceBasedErrorReporter.AbiVersionErrorData data = bindingContext.get(TraceBasedErrorReporter.ABI_VERSION_ERRORS, kotlinClass);
assert data != null;
String path = toSystemDependentName(kotlinClass);
result.add(bindingContext.get(TraceBasedErrorReporter.ABI_VERSION_ERRORS, kotlinClass));
}
return result;
}
private void reportAbiVersionErrors(@NotNull List<AbiVersionErrorData> errors) {
for (AbiVersionErrorData data : errors) {
String path = toSystemDependentName(data.getFilePath());
messageCollector.report(
CompilerMessageSeverity.ERROR,
"Class '" + JvmClassName.byClassId(data.getClassId()) + "' was compiled with an incompatible version of Kotlin. " +
@@ -155,14 +175,22 @@ public final class AnalyzerWithCompilerReport {
}
}
public static boolean reportDiagnostics(@NotNull Diagnostics diagnostics, @NotNull MessageCollector messageCollector) {
private static boolean reportDiagnostics(
@NotNull Diagnostics diagnostics,
@NotNull MessageCollector messageCollector,
boolean incompatibleFilesFound
) {
boolean hasErrors = false;
for (Diagnostic diagnostic : sortedDiagnostics(diagnostics.all())) {
hasErrors |= reportDiagnostic(diagnostic, messageCollector);
hasErrors |= reportDiagnostic(diagnostic, messageCollector, incompatibleFilesFound);
}
return hasErrors;
}
public static boolean reportDiagnostics(@NotNull Diagnostics diagnostics, @NotNull MessageCollector collector) {
return reportDiagnostics(diagnostics, collector, false);
}
private void reportSyntaxErrors(@NotNull Collection<JetFile> files) {
for (JetFile file : files) {
reportSyntaxErrors(file, messageCollector);
@@ -194,7 +222,7 @@ public final class AnalyzerWithCompilerReport {
private <E extends PsiElement> void reportDiagnostic(E element, DiagnosticFactory0<E> factory, String message) {
MyDiagnostic<?> diagnostic = new MyDiagnostic<E>(element, factory, message);
AnalyzerWithCompilerReport.reportDiagnostic(diagnostic, messageCollector);
AnalyzerWithCompilerReport.reportDiagnostic(diagnostic, messageCollector, false);
if (element.getTextRange().getStartOffset() != file.getTextRange().getEndOffset()) {
allErrorsAtEof = false;
}
@@ -225,10 +253,12 @@ public final class AnalyzerWithCompilerReport {
public void analyzeAndReport(@NotNull Collection<JetFile> files, @NotNull Function0<AnalysisResult> analyzer) {
analysisResult = analyzer.invoke();
reportAbiVersionErrors();
reportSyntaxErrors(files);
//noinspection ConstantConditions
reportDiagnostics(analysisResult.getBindingContext().getDiagnostics(), messageCollector);
List<AbiVersionErrorData> abiVersionErrors = getAbiVersionErrors();
reportDiagnostics(analysisResult.getBindingContext().getDiagnostics(), messageCollector, !abiVersionErrors.isEmpty());
if (hasErrors()) {
reportAbiVersionErrors(abiVersionErrors);
}
reportIncompleteHierarchies();
reportAlternativeSignatureErrors();
}

View File

@@ -66,6 +66,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
val configuration = CompilerConfiguration()
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageSeverityCollector)
configuration.put(CLIConfigurationKeys.REPORT_PERF, arguments.reportPerf)
if (IncrementalCompilation.ENABLED) {
val incrementalCompilationComponents = services.get(javaClass<IncrementalCompilationComponents>())
@@ -125,6 +126,8 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
configuration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, getAnnotationsPath(paths, arguments))
configuration.put(JVMConfigurationKeys.MODULE_NAME, arguments.moduleName ?: JvmAbi.DEFAULT_MODULE_NAME)
if (arguments.module == null && arguments.freeArgs.isEmpty() && !arguments.version) {
ReplFromTerminal.run(rootDisposable, configuration)
return ExitCode.OK
@@ -135,8 +138,6 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
else
emptyList<AnalyzerScriptParameter>())
configuration.put(JVMConfigurationKeys.MODULE_NAME, arguments.moduleName ?: JvmAbi.DEFAULT_MODULE_NAME)
putAdvancedOptions(configuration, arguments)
messageSeverityCollector.report(CompilerMessageSeverity.LOGGING, "Configuring the compilation environment", CompilerMessageLocation.NO_LOCATION)
@@ -246,8 +247,10 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
}
public fun reportPerf(configuration: CompilerConfiguration, message: String) {
val collector = configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY]!!
collector.report(CompilerMessageSeverity.INFO, "PERF: " + message, CompilerMessageLocation.NO_LOCATION)
if (configuration[CLIConfigurationKeys.REPORT_PERF] == true) {
val collector = configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY]!!
collector.report(CompilerMessageSeverity.INFO, "PERF: " + message, CompilerMessageLocation.NO_LOCATION)
}
}
fun reportGCTime(configuration: CompilerConfiguration) {

View File

@@ -16,12 +16,17 @@
package org.jetbrains.kotlin.fileClasses
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
public object JvmFileClassUtil {
public val JVM_NAME: FqName = FqName("kotlin.jvm.JvmName")
@@ -49,19 +54,29 @@ public object JvmFileClassUtil {
public @JvmStatic fun getFacadeFqName(file: JetFile, jvmFileClassAnnotations: ParsedJmvFileClassAnnotations): FqName =
file.packageFqName.child(Name.identifier(jvmFileClassAnnotations.name))
public @JvmStatic fun getPartFqNameForDeserializedCallable(callable: DeserializedCallableMemberDescriptor): FqName {
val implClassName = getImplClassName(callable)
val packageFqName = (callable.containingDeclaration as PackageFragmentDescriptor).fqName
return packageFqName.child(implClassName)
}
public @JvmStatic fun getImplClassName(callable: DeserializedCallableMemberDescriptor): Name =
callable.nameResolver.getName(callable.proto.getExtension(JvmProtoBuf.implClassName))
public @JvmStatic fun getHiddenPartFqName(file: JetFile, jvmFileClassAnnotations: ParsedJmvFileClassAnnotations): FqName =
file.packageFqName.child(Name.identifier(manglePartName(jvmFileClassAnnotations.name, file.name)))
public @JvmStatic fun getMultifilePackageFacadePartInfo(file: JetFile): JvmFileClassInfo {
val packageFqName = file.packageFqName
val packageFacadeFqName = PackageClassUtils.getPackageClassFqName(packageFqName)
val filePartName = manglePartName(packageFacadeFqName.shortName().asString(), file.name)
val filePartFqName = packageFqName.child(Name.identifier(filePartName))
return JvmMultifileClassPartInfo(filePartFqName, packageFacadeFqName)
}
public @JvmStatic fun manglePartName(facadeName: String, fileName: String): String =
"${facadeName}__${PackagePartClassUtils.getFilePartShortName(fileName)}"
public @JvmStatic fun parseJvmFileClass(jvmName: AnnotationDescriptor, jvmMultifileClass: AnnotationDescriptor?): ParsedJmvFileClassAnnotations? {
val jvmNameArgument = jvmName.allValueArguments.values().singleOrNull() ?: return null
val name = (jvmNameArgument as? StringValue)?.value ?: return null
val isMultifileClassPart = jvmMultifileClass != null
return ParsedJmvFileClassAnnotations(name, isMultifileClassPart)
}
public @JvmStatic fun getFileClassInfoNoResolve(file: JetFile): JvmFileClassInfo =
getFileClassInfo(file, parseJvmNameOnFileNoResolve(file))
@@ -90,3 +105,13 @@ public object JvmFileClassUtil {
}
public class ParsedJmvFileClassAnnotations(public val name: String, public val multipleFiles: Boolean)
public val JetFile.javaFileFacadeFqName: FqName
get() {
return CachedValuesManager.getCachedValue(this) {
val facadeFqName =
if (isCompiled) packageFqName.child(Name.identifier(virtualFile.nameWithoutExtension))
else JvmFileClassUtil.getFileClassInfoNoResolve(this).facadeClassFqName
CachedValueProvider.Result(facadeFqName, this)
}
}

View File

@@ -22,12 +22,29 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.org.objectweb.asm.Type
public interface JvmFileClassesProvider {
public fun getFileClassFqName(file: JetFile): FqName
public fun getFileClassInternalName(file: JetFile): String =
JvmClassName.byFqNameWithoutInnerClasses(getFileClassFqName(file)).internalName
public fun getFileClassType(file: JetFile): Type =
Type.getObjectType(getFileClassInternalName(file))
public fun getFileClassInfo(file: JetFile): JvmFileClassInfo
}
public fun FqName.getInternalName(): String =
JvmClassName.byFqNameWithoutInnerClasses(this).internalName
public fun FqName.getClassType(): Type =
Type.getObjectType(getInternalName())
public fun JvmFileClassesProvider.getFileClassFqName(file: JetFile): FqName =
getFileClassInfo(file).fileClassFqName
public fun JvmFileClassesProvider.getFileClassInternalName(file: JetFile): String =
getFileClassFqName(file).getInternalName()
public fun JvmFileClassesProvider.getFileClassType(file: JetFile): Type =
getFileClassFqName(file).getClassType()
public fun JvmFileClassesProvider.getFacadeClassFqName(file: JetFile): FqName =
getFileClassInfo(file).facadeClassFqName
public fun JvmFileClassesProvider.getFacadeClassInternalName(file: JetFile): String =
getFacadeClassFqName(file).getInternalName()
public fun JvmFileClassesProvider.getFacadeClassType(file: JetFile): Type =
getFacadeClassFqName(file).getClassType()

View File

@@ -21,6 +21,6 @@ import org.jetbrains.kotlin.psi.JetFile
public object NoResolveFileClassesProvider : JvmFileClassesProvider {
override fun getFileClassFqName(file: JetFile): FqName =
JvmFileClassUtil.getFileClassInfo(file, JvmFileClassUtil.parseJvmNameOnFileNoResolve(file)).fileClassFqName
override fun getFileClassInfo(file: JetFile): JvmFileClassInfo =
JvmFileClassUtil.getFileClassInfo(file, JvmFileClassUtil.parseJvmNameOnFileNoResolve(file))
}

View File

@@ -39,11 +39,12 @@ public class TraceBasedErrorReporter(private val trace: BindingTrace) : ErrorRep
public data class AbiVersionErrorData(
public val actualVersion: BinaryVersion,
public val filePath: String,
public val classId: ClassId
)
override fun reportIncompatibleAbiVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
trace.record(ABI_VERSION_ERRORS, filePath, AbiVersionErrorData(actualVersion, classId))
trace.record(ABI_VERSION_ERRORS, filePath, AbiVersionErrorData(actualVersion, filePath, classId))
}
override fun reportIncompleteHierarchy(descriptor: ClassDescriptor, unresolvedSuperClasses: List<String>) {

View File

@@ -36,7 +36,7 @@ public object PackagePartClassUtils {
private val PART_CLASS_NAME_SUFFIX = "Kt"
private @JvmStatic fun getPartClassName(str: String): String =
public @JvmStatic fun getPartClassName(str: String): String =
if (str.isEmpty())
"_$PART_CLASS_NAME_SUFFIX"
else
@@ -82,9 +82,6 @@ public object PackagePartClassUtils {
public @JvmStatic fun fileHasTopLevelCallables(file: JetFile): Boolean =
file.declarations.any { it is JetProperty || it is JetNamedFunction }
public @JvmStatic fun getFilesForPart(partFqName: FqName, files: Collection<JetFile>): List<JetFile> =
getFilesWithCallables(files).filter { getPackagePartFqName(it) == partFqName }
public @JvmStatic fun getFilePartShortName(fileName: String): String =
getPartClassName(FileUtil.getNameWithoutExtension(fileName))

View File

@@ -59,7 +59,7 @@ public class VirtualFileKotlinClass private constructor(
assert(file.getFileType() == JavaClassFileType.INSTANCE) { "Trying to read binary data from a non-class file $file" }
try {
val byteContent = file.contentsToByteArray()
val byteContent = file.contentsToByteArray(false)
if (!byteContent.isEmpty()) {
return@time FileBasedKotlinClass.create(byteContent) {
name, header, innerClasses ->

View File

@@ -24,8 +24,6 @@ import org.jetbrains.kotlin.diagnostics.rendering.Renderers;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.renderer.Renderer;
import static org.jetbrains.kotlin.diagnostics.rendering.Renderers.STRING;
public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
private static final Renderer<ConflictingJvmDeclarationsData> CONFLICTING_JVM_DECLARATIONS_DATA = new Renderer<ConflictingJvmDeclarationsData>() {
@@ -86,6 +84,8 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
"Java type mismatch expected {1} but found {0}. Use explicit cast", Renderers.RENDER_TYPE, Renderers.RENDER_TYPE);
MAP.put(ErrorsJvm.DUPLICATE_CLASS_NAMES, "Duplicate JVM class name ''{0}'' generated from: {1}", Renderers.TO_STRING, Renderers.TO_STRING);
MAP.put(ErrorsJvm.UPPER_BOUND_CANNOT_BE_ARRAY, "Upper bound of a type parameter cannot be an array");
}
@NotNull

View File

@@ -71,6 +71,8 @@ public interface ErrorsJvm {
DiagnosticFactory2<PsiElement, String, String> DUPLICATE_CLASS_NAMES = DiagnosticFactory2.create(ERROR);
DiagnosticFactory0<PsiElement> UPPER_BOUND_CANNOT_BE_ARRAY = DiagnosticFactory0.create(ERROR);
enum NullabilityInformationSource {
KOTLIN {
@NotNull

View File

@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.resolve.jvm.platform
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isArray
import org.jetbrains.kotlin.cfg.WhenChecker
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useImpl
@@ -70,7 +72,8 @@ public object JvmPlatformConfigurator : PlatformConfigurator(
ReifiedTypeParameterAnnotationChecker(),
NativeFunChecker(),
OverloadsAnnotationChecker(),
PublicFieldAnnotationChecker()
PublicFieldAnnotationChecker(),
TypeParameterBoundIsNotArrayChecker()
),
additionalCallCheckers = listOf(
@@ -268,6 +271,26 @@ public class PublicFieldAnnotationChecker: DeclarationChecker {
}
}
public class TypeParameterBoundIsNotArrayChecker : DeclarationChecker {
override fun check(
declaration: JetDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
val typeParameters = (descriptor as? CallableDescriptor)?.typeParameters
?: (descriptor as? ClassDescriptor)?.typeConstructor?.parameters
?: return
for (typeParameter in typeParameters) {
if (typeParameter.upperBounds.any { KotlinBuiltIns.isArray(it) || KotlinBuiltIns.isPrimitiveArray(it) }) {
val element = DescriptorToSourceUtils.descriptorToDeclaration(typeParameter) ?: declaration
diagnosticHolder.report(ErrorsJvm.UPPER_BOUND_CANNOT_BE_ARRAY.on(element))
}
}
}
}
public class ReifiedTypeParameterAnnotationChecker : DeclarationChecker {
override fun check(

View File

@@ -672,7 +672,7 @@ public interface Errors {
DiagnosticFactory2<JetElement, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
DiagnosticFactory3<JetElement, JetElement, DeclarationDescriptor, DeclarationDescriptor> NON_LOCAL_RETURN_NOT_ALLOWED = DiagnosticFactory3.create(ERROR, CALL_ELEMENT);
DiagnosticFactory2<JetElement, JetNamedDeclaration, DeclarationDescriptor> NOT_YET_SUPPORTED_IN_INLINE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory1<JetFunction, DeclarationDescriptor> NOTHING_TO_INLINE = DiagnosticFactory1.create(WARNING, DECLARATION_SIGNATURE);
DiagnosticFactory1<PsiElement, DeclarationDescriptor> NOTHING_TO_INLINE = DiagnosticFactory1.create(WARNING);
DiagnosticFactory2<JetElement, JetExpression, DeclarationDescriptor> USAGE_IS_NOT_INLINABLE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<JetElement, JetElement, DeclarationDescriptor> NULLABLE_INLINE_PARAMETER = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<JetElement, JetElement, DeclarationDescriptor> RECURSION_IN_INLINE = DiagnosticFactory2.create(ERROR);

View File

@@ -622,14 +622,14 @@ public class DefaultErrorMessages {
MAP.put(ARRAY_CLASS_LITERAL_REQUIRES_ARGUMENT, "kotlin.Array class literal requires a type argument, please specify one in angle brackets");
//Inline
MAP.put(INVISIBLE_MEMBER_FROM_INLINE, "Cannot access effectively non-public-api ''{0}'' member from effectively public-api ''{1}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(NOT_YET_SUPPORTED_IN_INLINE, "''{0}'' construction not yet supported in inline functions", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(DECLARATION_CANT_BE_INLINED, "Inline annotation could be present only on nonvirtual members (private or final)");
MAP.put(INVISIBLE_MEMBER_FROM_INLINE, "Cannot access effectively non-public-API ''{0}'' member from effectively public-API ''{1}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(NOT_YET_SUPPORTED_IN_INLINE, "''{0}'' construction is not yet supported in inline functions", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(DECLARATION_CANT_BE_INLINED, "''inline'' modifier is not allowed on virtual members. Only private or final members can be inlined");
MAP.put(NOTHING_TO_INLINE, "Expected performance impact of inlining ''{0}'' can be insignificant. Inlining works best for functions with lambda parameters", SHORT_NAMES_IN_TYPES);
MAP.put(USAGE_IS_NOT_INLINABLE, "Illegal usage of inline-parameter ''{0}'' in ''{1}''. Annotate the parameter with [noinline]", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(NULLABLE_INLINE_PARAMETER, "Inline-parameter ''{0}'' of ''{1}'' must not be nullable. Annotate the parameter with [noinline] or make not nullable", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(RECURSION_IN_INLINE, "Inline-function ''{1}'' can't be recursive", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
//Inline non Locals
MAP.put(USAGE_IS_NOT_INLINABLE, "Illegal usage of inline-parameter ''{0}'' in ''{1}''. Add ''noinline'' modifier to the parameter declaration", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(NULLABLE_INLINE_PARAMETER, "Inline-parameter ''{0}'' of ''{1}'' must not be nullable. Add ''noinline'' modifier to the parameter declaration or make its type not nullable", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
MAP.put(RECURSION_IN_INLINE, "Inline function ''{1}'' can't be recursive", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
//Inline non locals
MAP.put(NON_LOCAL_RETURN_NOT_ALLOWED, "Can''t inline ''{0}'' here: it may contain non-local returns. Add ''crossinline'' modifier to parameter declaration ''{0}''", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
MAP.put(INLINE_CALL_CYCLE, "The ''{0}'' invocation is a part of inline cycle", NAME);
MAP.put(NON_LOCAL_RETURN_IN_DISABLED_INLINE, "Non-local returns are not allowed with inlining disabled");

View File

@@ -25,18 +25,16 @@ import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream;
import com.intellij.psi.stubs.StubOutputStream;
import com.intellij.psi.tree.IStubFileElementType;
import com.intellij.util.io.StringRef;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.JetLanguage;
import org.jetbrains.kotlin.parsing.JetParser;
import org.jetbrains.kotlin.psi.stubs.KotlinFileStub;
import org.jetbrains.kotlin.psi.stubs.impl.KotlinFileStubImpl;
import java.io.IOException;
public class JetFileElementType extends IStubFileElementType<KotlinFileStub> {
public static final int STUB_VERSION = 56;
public static final int STUB_VERSION = 57;
private static final String NAME = "kotlin.FILE";

View File

@@ -203,7 +203,7 @@ public class AnnotationChecker(private val additionalCheckers: Iterable<Addition
}
private object TargetLists {
val T_CLASSIFIER = targetList(CLASS, CLASSIFIER)
val T_CLASSIFIER = targetList(CLASS)
val T_LOCAL_VARIABLE = targetList(LOCAL_VARIABLE) {
onlyWithUseSiteTarget(PROPERTY, FIELD, PROPERTY_GETTER, PROPERTY_SETTER, VALUE_PARAMETER)

View File

@@ -45,20 +45,20 @@ public object ModifierCheckerCore {
SEALED_KEYWORD to EnumSet.of(CLASS_ONLY, LOCAL_CLASS, INNER_CLASS),
INNER_KEYWORD to EnumSet.of(INNER_CLASS),
OVERRIDE_KEYWORD to EnumSet.of(MEMBER_PROPERTY, MEMBER_FUNCTION),
PRIVATE_KEYWORD to EnumSet.of(CLASS, CLASSIFIER, MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER,
PRIVATE_KEYWORD to EnumSet.of(CLASS, MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER,
MEMBER_PROPERTY, TOP_LEVEL_PROPERTY, CONSTRUCTOR),
PUBLIC_KEYWORD to EnumSet.of(CLASS, CLASSIFIER, MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER,
PUBLIC_KEYWORD to EnumSet.of(CLASS, MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER,
MEMBER_PROPERTY, TOP_LEVEL_PROPERTY, CONSTRUCTOR),
INTERNAL_KEYWORD to EnumSet.of(CLASS, CLASSIFIER, MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER,
INTERNAL_KEYWORD to EnumSet.of(CLASS, MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER,
MEMBER_PROPERTY, TOP_LEVEL_PROPERTY, CONSTRUCTOR),
PROTECTED_KEYWORD to EnumSet.of(CLASS, CLASSIFIER, MEMBER_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, MEMBER_PROPERTY, CONSTRUCTOR),
PROTECTED_KEYWORD to EnumSet.of(CLASS, MEMBER_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, MEMBER_PROPERTY, CONSTRUCTOR),
IN_KEYWORD to EnumSet.of(TYPE_PARAMETER, TYPE_PROJECTION),
OUT_KEYWORD to EnumSet.of(TYPE_PARAMETER, TYPE_PROJECTION),
REIFIED_KEYWORD to EnumSet.of(TYPE_PARAMETER),
VARARG_KEYWORD to EnumSet.of(VALUE_PARAMETER, PROPERTY_PARAMETER),
COMPANION_KEYWORD to EnumSet.of(OBJECT),
LATE_INIT_KEYWORD to EnumSet.of(MEMBER_PROPERTY),
DATA_KEYWORD to EnumSet.of(CLASS, CLASSIFIER),
DATA_KEYWORD to EnumSet.of(CLASS),
INLINE_KEYWORD to EnumSet.of(FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, PROPERTY),
NOINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER),
TAILREC_KEYWORD to EnumSet.of(FUNCTION),
@@ -76,8 +76,8 @@ public object ModifierCheckerCore {
private val possibleParentTargetMap = mapOf<JetModifierKeywordToken, Set<KotlinTarget>>(
INNER_KEYWORD to EnumSet.of(CLASS_ONLY, INNER_CLASS, LOCAL_CLASS, ENUM_CLASS, ENUM_ENTRY),
OVERRIDE_KEYWORD to EnumSet.of(CLASS, CLASSIFIER, ENUM_ENTRY),
PROTECTED_KEYWORD to EnumSet.of(CLASS, CLASSIFIER, ENUM_ENTRY),
OVERRIDE_KEYWORD to EnumSet.of(CLASS, ENUM_ENTRY),
PROTECTED_KEYWORD to EnumSet.of(CLASS, ENUM_ENTRY),
COMPANION_KEYWORD to EnumSet.of(CLASS_ONLY, ENUM_CLASS, INTERFACE)
)

View File

@@ -261,7 +261,7 @@ class GenericCandidateResolver(
return
}
}
val expectedTypeWithoutReturnType = if (hasExpectedReturnType) replaceReturnTypeByUnknown(expectedType) else expectedType
val expectedTypeWithoutReturnType = replaceReturnTypeByUnknown(expectedType)
val newContext = context.replaceExpectedType(expectedTypeWithoutReturnType).replaceDataFlowInfo(dataFlowInfoForArgument)
.replaceContextDependency(INDEPENDENT)
val type = argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS).type

View File

@@ -16,10 +16,12 @@
package org.jetbrains.kotlin.resolve.inline;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
@@ -125,7 +127,10 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz
hasInlinable |= DescriptorUtils.containsReifiedTypeParameters(functionDescriptor);
if (!hasInlinable) {
trace.report(Errors.NOTHING_TO_INLINE.on(function, functionDescriptor));
JetModifierList modifierList = function.getModifierList();
PsiElement inlineModifier = modifierList == null ? null : modifierList.getModifier(JetTokens.INLINE_KEYWORD);
PsiElement reportOn = inlineModifier == null ? function : inlineModifier;
trace.report(Errors.NOTHING_TO_INLINE.on(reportOn, functionDescriptor));
}
}

View File

@@ -32,7 +32,6 @@ import com.intellij.util.containers.SLRUCache;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.NamePackage;
import org.jetbrains.kotlin.psi.JetClassOrObject;
@@ -134,7 +133,7 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
for (JetClassOrObject declaration : classOrObjectDeclarations) {
if (!(declaration instanceof JetEnumEntry)) {
PsiClass lightClass = LightClassUtil.getPsiClass(declaration);
PsiClass lightClass = LightClassUtil.INSTANCE$.getPsiClass(declaration);
if (lightClass != null) {
answer.add(lightClass);
}
@@ -208,7 +207,7 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
Collection<JetClassOrObject> declarations = lightClassGenerationSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope);
for (JetClassOrObject declaration : declarations) {
PsiClass aClass = LightClassUtil.getPsiClass(declaration);
PsiClass aClass = LightClassUtil.INSTANCE$.getPsiClass(declaration);
if (aClass != null) {
answer.add(aClass);
}

View File

@@ -47,6 +47,8 @@ import org.jetbrains.kotlin.codegen.PackageCodegen;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.JetClassOrObject;
import org.jetbrains.kotlin.psi.JetFile;
@@ -215,6 +217,17 @@ public class KotlinJavaFileStubProvider<T extends WithFileStubAndExtraDiagnostic
@Override
public void generate(@NotNull GenerationState state, @NotNull Collection<JetFile> files) {
if (!files.isEmpty()) {
JetFile representativeFile = files.iterator().next();
JvmFileClassInfo fileClassInfo = NoResolveFileClassesProvider.INSTANCE$.getFileClassInfo(representativeFile);
if (!fileClassInfo.getIsMultifileClass()) {
PackageCodegen codegen = state.getFactory().forPackage(representativeFile.getPackageFqName(), files);
codegen.generate(CompilationErrorHandler.THROW_EXCEPTION);
state.getFactory().asList();
return;
}
}
MultifileClassCodegen codegen = state.getFactory().forMultifileClass(facadeFqName, files);
codegen.generate(CompilationErrorHandler.THROW_EXCEPTION);
state.getFactory().asList();
@@ -499,7 +512,7 @@ public class KotlinJavaFileStubProvider<T extends WithFileStubAndExtraDiagnostic
private static void checkForBuiltIns(@NotNull FqName fqName, @NotNull Collection<JetFile> files) {
for (JetFile file : files) {
if (LightClassUtil.belongsToKotlinBuiltIns(file)) {
if (LightClassUtil.INSTANCE$.belongsToKotlinBuiltIns(file)) {
// We may not fail later due to some luck, but generating JetLightClasses for built-ins is a bad idea anyways
// If it fails later, there will be an exception logged
logErrorWithOSInfo(null, fqName, file.getVirtualFile());
@@ -511,7 +524,7 @@ public class KotlinJavaFileStubProvider<T extends WithFileStubAndExtraDiagnostic
String path = virtualFile == null ? "<null>" : virtualFile.getPath();
LOG.error(
"Could not generate LightClass for " + fqName + " declared in " + path + "\n" +
"built-ins dir URL is " + LightClassUtil.getBuiltInsDirUrl() + "\n" +
"built-ins dir URL is " + LightClassUtil.INSTANCE$.getBuiltInsDirUrl() + "\n" +
"System: " + SystemInfo.OS_NAME + " " + SystemInfo.OS_VERSION + " Java Runtime: " + SystemInfo.JAVA_RUNTIME_VERSION,
cause);
}

View File

@@ -180,6 +180,8 @@ public class KotlinLightClassForFacade private constructor(
override fun getName() = facadeClassFqName.shortName().asString()
override fun setName(name: String): PsiElement? = this
override fun getQualifiedName() = facadeClassFqName.asString()
override fun isValid() = files.all { it.isValid() }

View File

@@ -1,424 +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.asJava;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.java.stubs.PsiClassStub;
import com.intellij.psi.impl.light.LightTypeParameterListBuilder;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.stubs.PsiFileStub;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.SmartList;
import kotlin.KotlinPackage;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.utils.KotlinVfsUtil;
import org.jetbrains.kotlin.utils.UtilsPackage;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
public class LightClassUtil {
private static final Logger LOG = Logger.getInstance(LightClassUtil.class);
public static final File BUILT_INS_SRC_DIR = new File("core/builtins/native", KotlinBuiltIns.BUILT_INS_PACKAGE_NAME.asString());
private static final class BuiltinsDirUrlHolder {
private static final URL BUILT_INS_DIR_URL = computeBuiltInsDir();
}
/**
* Checks whether the given file is loaded from the location where Kotlin's built-in classes are defined.
* As of today, this is core/builtins/native/kotlin directory and files such as Any.kt, Nothing.kt etc.
*
* Used to skip JetLightClass creation for built-ins, because built-in classes have no Java counterparts
*/
public static boolean belongsToKotlinBuiltIns(@NotNull JetFile file) {
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile != null) {
VirtualFile parent = virtualFile.getParent();
if (parent != null) {
try {
String jetVfsPathUrl = KotlinVfsUtil.convertFromUrl(getBuiltInsDirUrl());
String fileDirVfsUrl = parent.getUrl();
if (jetVfsPathUrl.equals(fileDirVfsUrl)) {
return true;
}
}
catch (MalformedURLException e) {
LOG.error(e);
}
}
}
// We deliberately return false on error: who knows what weird URLs we might come across out there
// it would be a pity if no light classes would be created in such cases
return false;
}
@NotNull
public static URL getBuiltInsDirUrl() {
return BuiltinsDirUrlHolder.BUILT_INS_DIR_URL;
}
@NotNull
private static URL computeBuiltInsDir() {
String builtInFilePath = "/" + KotlinBuiltIns.BUILT_INS_PACKAGE_NAME + "/Library.kt";
URL url = KotlinBuiltIns.class.getResource(builtInFilePath);
if (url == null) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
// HACK: Temp code. Get built-in files from the sources when running from test.
try {
return new URL(StandardFileSystems.FILE_PROTOCOL, "",
FileUtil.toSystemIndependentName(BUILT_INS_SRC_DIR.getAbsolutePath()));
}
catch (MalformedURLException e) {
throw UtilsPackage.rethrow(e);
}
}
throw new IllegalStateException("Built-ins file wasn't found at url: " + builtInFilePath);
}
try {
return new URL(url.getProtocol(), url.getHost(), PathUtil.getParentPath(url.getFile()));
}
catch (MalformedURLException e) {
throw new AssertionError(e);
}
}
@Nullable
/*package*/ static PsiClass findClass(@NotNull FqName fqn, @NotNull StubElement<?> stub) {
if (stub instanceof PsiClassStub && Comparing.equal(fqn.asString(), ((PsiClassStub) stub).getQualifiedName())) {
return (PsiClass) stub.getPsi();
}
if (stub instanceof PsiClassStub || stub instanceof PsiFileStub) {
for (StubElement child : stub.getChildrenStubs()) {
PsiClass answer = findClass(fqn, child);
if (answer != null) return answer;
}
}
return null;
}
@Nullable
public static PsiClass getPsiClass(@Nullable JetClassOrObject classOrObject) {
if (classOrObject == null) return null;
return LightClassGenerationSupport.getInstance(classOrObject.getProject()).getPsiClass(classOrObject);
}
@Nullable
public static PsiMethod getLightClassAccessorMethod(@NotNull JetPropertyAccessor accessor) {
JetProperty property = PsiTreeUtil.getParentOfType(accessor, JetProperty.class);
if (property == null) {
return null;
}
List<PsiMethod> wrappers = getPsiMethodWrappers(property, true);
for (PsiMethod wrapper : wrappers) {
if ((accessor.isGetter() && !wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX)) ||
(accessor.isSetter() && wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX))) {
return wrapper;
}
}
return null;
}
@Nullable
public static PsiField getLightFieldForCompanionObject(@NotNull JetClassOrObject companionObject) {
PsiClass outerPsiClass = getWrappingClass(companionObject);
if (outerPsiClass != null) {
for (PsiField fieldOfParent : outerPsiClass.getFields()) {
if ((fieldOfParent instanceof KotlinLightElement) &&
((KotlinLightElement<?, ?>) fieldOfParent).getOrigin() == companionObject) {
return fieldOfParent;
}
}
}
return null;
}
@NotNull
public static PropertyAccessorsPsiMethods getLightClassPropertyMethods(@NotNull JetProperty property) {
JetPropertyAccessor getter = property.getGetter();
JetPropertyAccessor setter = property.getSetter();
PsiMethod getterWrapper = getter != null ? getLightClassAccessorMethod(getter) : null;
PsiMethod setterWrapper = setter != null ? getLightClassAccessorMethod(setter) : null;
return extractPropertyAccessors(property, getterWrapper, setterWrapper);
}
@Nullable
private static PsiField getLightClassBackingField(JetDeclaration declaration) {
PsiClass psiClass = getWrappingClass(declaration);
if (psiClass == null) {
return null;
}
if (psiClass instanceof KotlinLightClass) {
JetClassOrObject origin = ((KotlinLightClass) psiClass).getOrigin();
if (origin instanceof JetObjectDeclaration && ((JetObjectDeclaration) origin).isCompanion()) {
JetClass containingClass = PsiTreeUtil.getParentOfType(origin, JetClass.class);
if (containingClass != null) {
PsiClass containingLightClass = getPsiClass(containingClass);
if (containingLightClass != null) {
psiClass = containingLightClass;
}
}
}
}
for (PsiField field : psiClass.getFields()) {
if (field instanceof KotlinLightField && ((KotlinLightField) field).getOrigin() == declaration) {
return field;
}
}
return null;
}
@NotNull
public static PropertyAccessorsPsiMethods getLightClassPropertyMethods(@NotNull JetParameter parameter) {
return extractPropertyAccessors(parameter, null, null);
}
@Nullable
public static PsiMethod getLightClassMethod(@NotNull JetFunction function) {
return getPsiMethodWrapper(function);
}
@Nullable
private static PsiMethod getPsiMethodWrapper(@NotNull JetDeclaration declaration) {
List<PsiMethod> wrappers = getPsiMethodWrappers(declaration, false);
return !wrappers.isEmpty() ? wrappers.get(0) : null;
}
@NotNull
private static List<PsiMethod> getPsiMethodWrappers(@NotNull JetDeclaration declaration, boolean collectAll) {
PsiClass psiClass = getWrappingClass(declaration);
if (psiClass == null) {
return Collections.emptyList();
}
List<PsiMethod> methods = new SmartList<PsiMethod>();
for (PsiMethod method : psiClass.getMethods()) {
try {
if (method instanceof KotlinLightMethod && ((KotlinLightMethod) method).getOrigin() == declaration) {
methods.add(method);
if (!collectAll) {
return methods;
}
}
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Throwable e) {
throw new IllegalStateException(
"Error while wrapping declaration " + declaration.getName() +
"Context\n:" +
String.format("=== In file ===\n" +
"%s\n" +
"=== On element ===\n" +
"%s\n" +
"=== WrappedElement ===\n" +
"%s\n",
declaration.getContainingFile().getText(),
declaration.getText(),
method.toString()),
e
);
}
}
return methods;
}
@Nullable
private static PsiClass getWrappingClass(@NotNull JetDeclaration declaration) {
if (declaration instanceof JetParameter) {
JetClassOrObject constructorClass = JetPsiUtil.getClassIfParameterIsProperty((JetParameter) declaration);
if (constructorClass != null) {
return getPsiClass(constructorClass);
}
}
if (declaration instanceof JetPropertyAccessor) {
PsiElement propertyParent = declaration.getParent();
assert propertyParent instanceof JetProperty : "JetProperty is expected to be parent of accessor";
declaration = (JetProperty) propertyParent;
}
if (declaration instanceof JetConstructor) {
return getPsiClass(((JetConstructor) declaration).getContainingClassOrObject());
}
if (!canGenerateLightClass(declaration)) {
// Can't get wrappers for internal declarations. Their classes are not generated during calcStub
// with ClassBuilderMode.LIGHT_CLASSES mode, and this produces "Class not found exception" in getDelegate()
return null;
}
PsiElement parent = declaration.getParent();
if (parent instanceof JetFile) {
// top-level declaration
FqName fqName = PackageClassUtils.getPackageClassFqName(((JetFile) parent).getPackageFqName());
Project project = declaration.getProject();
return JavaElementFinder.getInstance(project).findClass(fqName.asString(), GlobalSearchScope.allScope(project));
}
else if (parent instanceof JetClassBody) {
assert parent.getParent() instanceof JetClassOrObject;
return getPsiClass((JetClassOrObject) parent.getParent());
}
return null;
}
public static boolean canGenerateLightClass(JetDeclaration declaration) {
//noinspection unchecked
return PsiTreeUtil.getParentOfType(declaration, JetFunction.class, JetProperty.class) == null;
}
@NotNull
private static PropertyAccessorsPsiMethods extractPropertyAccessors(
@NotNull JetDeclaration jetDeclaration,
@Nullable PsiMethod specialGetter, @Nullable PsiMethod specialSetter
) {
PsiMethod getterWrapper = specialGetter;
PsiMethod setterWrapper = specialSetter;
if (getterWrapper == null || setterWrapper == null) {
// If some getter or setter isn't found yet try to get it from wrappers for general declaration
List<PsiMethod> wrappers = KotlinPackage.filter(
getPsiMethodWrappers(jetDeclaration, true),
new Function1<PsiMethod, Boolean>() {
@Override
public Boolean invoke(PsiMethod method) {
String name = method.getName();
return name.startsWith(JvmAbi.GETTER_PREFIX) || name.startsWith(JvmAbi.SETTER_PREFIX);
}
}
);
assert wrappers.size() <= 2 : "Maximum two wrappers are expected to be generated for declaration: " + jetDeclaration.getText();
for (PsiMethod wrapper : wrappers) {
if (wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX)) {
assert setterWrapper == null || setterWrapper == specialSetter: String.format(
"Setter accessor isn't expected to be reassigned (old: %s, new: %s)", setterWrapper, wrapper);
setterWrapper = wrapper;
}
else {
assert getterWrapper == null || getterWrapper == specialGetter: String.format(
"Getter accessor isn't expected to be reassigned (old: %s, new: %s)", getterWrapper, wrapper);
getterWrapper = wrapper;
}
}
}
PsiField backingField = getLightClassBackingField(jetDeclaration);
return new PropertyAccessorsPsiMethods(getterWrapper, setterWrapper, backingField);
}
@NotNull
public static PsiTypeParameterList buildLightTypeParameterList(PsiTypeParameterListOwner owner, JetDeclaration declaration) {
LightTypeParameterListBuilder builder = new KotlinLightTypeParameterListBuilder(owner.getManager());
if (declaration instanceof JetTypeParameterListOwner) {
JetTypeParameterListOwner typeParameterListOwner = (JetTypeParameterListOwner) declaration;
List<JetTypeParameter> parameters = typeParameterListOwner.getTypeParameters();
for (int i = 0; i < parameters.size(); i++) {
JetTypeParameter jetTypeParameter = parameters.get(i);
String name = jetTypeParameter.getName();
String safeName = name == null ? "__no_name__" : name;
builder.addParameter(new KotlinLightTypeParameter(owner, i, safeName));
}
}
return builder;
}
public static class PropertyAccessorsPsiMethods implements Iterable<PsiMethod> {
private final PsiMethod getter;
private final PsiMethod setter;
private final PsiField backingField;
private final Collection<PsiMethod> accessors = new ArrayList<PsiMethod>(2);
PropertyAccessorsPsiMethods(@Nullable PsiMethod getter, @Nullable PsiMethod setter, @Nullable PsiField backingField) {
this.getter = getter;
if (getter != null) {
accessors.add(getter);
}
this.setter = setter;
if (setter != null) {
accessors.add(setter);
}
this.backingField = backingField;
}
@Nullable
public PsiMethod getGetter() {
return getter;
}
@Nullable
public PsiMethod getSetter() {
return setter;
}
@Nullable
public PsiField getBackingField() {
return backingField;
}
@NotNull
@Override
public Iterator<PsiMethod> iterator() {
return accessors.iterator();
}
}
private LightClassUtil() {
}
}

View File

@@ -0,0 +1,357 @@
/*
* 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.asJava
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.util.Comparing
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.psi.*
import com.intellij.psi.impl.java.stubs.PsiClassStub
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.PsiFileStub
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.PathUtil
import com.intellij.util.SmartList
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.utils.KotlinVfsUtil
import org.jetbrains.kotlin.utils.rethrow
import java.io.File
import java.net.MalformedURLException
import java.net.URL
public object LightClassUtil {
private val LOG = Logger.getInstance(LightClassUtil::class.java)
public val BUILT_INS_SRC_DIR: File = File("core/builtins/native", KotlinBuiltIns.BUILT_INS_PACKAGE_NAME.asString())
public val builtInsDirUrl: URL by lazy { computeBuiltInsDir() }
/**
* Checks whether the given file is loaded from the location where Kotlin's built-in classes are defined.
* As of today, this is core/builtins/native/kotlin directory and files such as Any.kt, Nothing.kt etc.
* Used to skip JetLightClass creation for built-ins, because built-in classes have no Java counterparts
*/
public fun belongsToKotlinBuiltIns(file: JetFile): Boolean {
val virtualFile = file.virtualFile
if (virtualFile != null) {
val parent = virtualFile.parent
if (parent != null) {
try {
val jetVfsPathUrl = KotlinVfsUtil.convertFromUrl(builtInsDirUrl)
val fileDirVfsUrl = parent.url
if (jetVfsPathUrl == fileDirVfsUrl) {
return true
}
}
catch (e: MalformedURLException) {
LOG.error(e)
}
}
}
// We deliberately return false on error: who knows what weird URLs we might come across out there
// it would be a pity if no light classes would be created in such cases
return false
}
private fun computeBuiltInsDir(): URL {
val builtInFilePath = "/" + KotlinBuiltIns.BUILT_INS_PACKAGE_NAME + "/Library.kt"
val url = KotlinBuiltIns::class.java.getResource(builtInFilePath)
if (url == null) {
if (ApplicationManager.getApplication().isUnitTestMode) {
// HACK: Temp code. Get built-in files from the sources when running from test.
try {
return URL(StandardFileSystems.FILE_PROTOCOL, "",
FileUtil.toSystemIndependentName(BUILT_INS_SRC_DIR.absolutePath))
}
catch (e: MalformedURLException) {
throw rethrow(e)
}
}
throw IllegalStateException("Built-ins file wasn't found at url: " + builtInFilePath)
}
try {
return URL(url.protocol, url.host, PathUtil.getParentPath(url.file))
}
catch (e: MalformedURLException) {
throw AssertionError(e)
}
}
fun findClass(fqn: FqName, stub: StubElement<*>): PsiClass? {
if (stub is PsiClassStub<*> && Comparing.equal(fqn.asString(), stub.qualifiedName)) {
return stub.getPsi()
}
if (stub is PsiClassStub<*> || stub is PsiFileStub<*>) {
for (child in stub.childrenStubs) {
val answer = findClass(fqn, child)
if (answer != null) return answer
}
}
return null
}/*package*/
public fun getPsiClass(classOrObject: JetClassOrObject?): PsiClass? {
if (classOrObject == null) return null
return LightClassGenerationSupport.getInstance(classOrObject.project).getPsiClass(classOrObject)
}
public fun getLightClassAccessorMethod(accessor: JetPropertyAccessor): PsiMethod? =
getLightClassAccessorMethods(accessor).firstOrNull()
public fun getLightClassAccessorMethods(accessor: JetPropertyAccessor): List<PsiMethod> {
val property = accessor.getNonStrictParentOfType<JetProperty>() ?: return emptyList()
val wrappers = getPsiMethodWrappers(property, true)
return wrappers.filter { wrapper -> (accessor.isGetter && !wrapper.name.startsWith(JvmAbi.SETTER_PREFIX)) ||
(accessor.isSetter && wrapper.name.startsWith(JvmAbi.SETTER_PREFIX)) }
}
public fun getLightFieldForCompanionObject(companionObject: JetClassOrObject): PsiField? {
val outerPsiClass = getWrappingClass(companionObject, true)
if (outerPsiClass != null) {
for (fieldOfParent in outerPsiClass.fields) {
if ((fieldOfParent is KotlinLightElement<*, *>) && fieldOfParent.getOrigin() === companionObject) {
return fieldOfParent
}
}
}
return null
}
public fun getLightClassPropertyMethods(property: JetProperty): PropertyAccessorsPsiMethods {
val getter = property.getter
val setter = property.setter
val getterWrapper = if (getter != null) getLightClassAccessorMethod(getter) else null
val setterWrapper = if (setter != null) getLightClassAccessorMethod(setter) else null
return extractPropertyAccessors(property, getterWrapper, setterWrapper)
}
private fun getLightClassBackingField(declaration: JetDeclaration): PsiField? {
var psiClass: PsiClass = getWrappingClass(declaration, true) ?: return null
if (psiClass is KotlinLightClass) {
val origin = psiClass.getOrigin()
if (origin is JetObjectDeclaration && origin.isCompanion()) {
val containingClass = PsiTreeUtil.getParentOfType(origin, JetClass::class.java)
if (containingClass != null) {
val containingLightClass = getPsiClass(containingClass)
if (containingLightClass != null) {
psiClass = containingLightClass
}
}
}
}
for (field in psiClass.fields) {
if (field is KotlinLightField<*, *> && field.getOrigin() === declaration) {
return field
}
}
return null
}
public fun getLightClassPropertyMethods(parameter: JetParameter): PropertyAccessorsPsiMethods {
return extractPropertyAccessors(parameter, null, null)
}
public fun getLightClassMethod(function: JetFunction): PsiMethod? {
return getPsiMethodWrapper(function)
}
public fun getLightClassMethods(function: JetFunction): List<PsiMethod> {
return getPsiMethodWrappers(function, true)
}
private fun getPsiMethodWrapper(declaration: JetDeclaration): PsiMethod? {
return getPsiMethodWrappers(declaration, false).firstOrNull()
}
private fun getPsiMethodWrappers(declaration: JetDeclaration, collectAll: Boolean): List<PsiMethod> {
val psiClasses = getWrappingClasses(declaration, collectAll)
val methods = SmartList<PsiMethod>()
for (method in psiClasses.flatMap { it.methods.asList() }) {
try {
if (method is KotlinLightMethod && method.getOrigin() === declaration) {
methods.add(method)
if (!collectAll) {
return methods
}
}
}
catch (e: ProcessCanceledException) {
throw e
}
catch (e: Throwable) {
throw IllegalStateException(
"Error while wrapping declaration " + declaration.name + "Context\n:" + method, e)
}
}
return methods
}
private fun getWrappingClasses(declaration: JetDeclaration, collectAll: Boolean): Collection<PsiClass> {
val wrappingClass = getWrappingClass(declaration, true)
val oldPackagePartWrappingClass = if (declaration.parent is JetFile && collectAll)
getWrappingClass(declaration, false)
else
null
return setOf(wrappingClass, oldPackagePartWrappingClass).filterNotNull()
}
private fun getWrappingClass(declaration: JetDeclaration, useNewPackageParts: Boolean): PsiClass? {
var declaration = declaration
if (declaration is JetParameter) {
val constructorClass = JetPsiUtil.getClassIfParameterIsProperty(declaration)
if (constructorClass != null) {
return getPsiClass(constructorClass)
}
}
if (declaration is JetPropertyAccessor) {
val propertyParent = declaration.parent
assert(propertyParent is JetProperty, "JetProperty is expected to be parent of accessor")
declaration = propertyParent as JetProperty
}
if (declaration is JetConstructor<*>) {
return getPsiClass(declaration.getContainingClassOrObject())
}
if (!canGenerateLightClass(declaration)) {
// Can't get wrappers for internal declarations. Their classes are not generated during calcStub
// with ClassBuilderMode.LIGHT_CLASSES mode, and this produces "Class not found exception" in getDelegate()
return null
}
val parent = declaration.parent
if (parent is JetFile) {
// top-level declaration
val fqName = if (useNewPackageParts)
parent.javaFileFacadeFqName
else
PackageClassUtils.getPackageClassFqName(parent.packageFqName)
val project = declaration.project
return JavaElementFinder.getInstance(project).findClass(fqName.asString(), GlobalSearchScope.allScope(project))
}
else if (parent is JetClassBody) {
assert(parent.parent is JetClassOrObject)
return getPsiClass(parent.parent as JetClassOrObject)
}
return null
}
public fun canGenerateLightClass(declaration: JetDeclaration): Boolean {
//noinspection unchecked
return PsiTreeUtil.getParentOfType(declaration, JetFunction::class.java, JetProperty::class.java) == null
}
private fun extractPropertyAccessors(
jetDeclaration: JetDeclaration,
specialGetter: PsiMethod?, specialSetter: PsiMethod?): PropertyAccessorsPsiMethods {
var getterWrapper = specialGetter
var setterWrapper = specialSetter
val additionalAccessors = arrayListOf<PsiMethod>()
val wrappers = getPsiMethodWrappers(jetDeclaration, true).filter {
it.name.startsWith(JvmAbi.GETTER_PREFIX) || it.name.startsWith(JvmAbi.SETTER_PREFIX)
}
for (wrapper in wrappers) {
if (wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX)) {
if (setterWrapper == null || setterWrapper === specialSetter) {
setterWrapper = wrapper
}
else {
additionalAccessors.add(wrapper)
}
}
else {
if (getterWrapper == null || getterWrapper == specialGetter) {
getterWrapper = wrapper
}
else {
additionalAccessors.add(wrapper)
}
}
}
val backingField = getLightClassBackingField(jetDeclaration)
return PropertyAccessorsPsiMethods(getterWrapper, setterWrapper, backingField, additionalAccessors)
}
public fun buildLightTypeParameterList(
owner: PsiTypeParameterListOwner,
declaration: JetDeclaration): PsiTypeParameterList {
val builder = KotlinLightTypeParameterListBuilder(owner.manager)
if (declaration is JetTypeParameterListOwner) {
val parameters = declaration.typeParameters
for (i in parameters.indices) {
val jetTypeParameter = parameters.get(i)
val name = jetTypeParameter.name
val safeName = name ?: "__no_name__"
builder.addParameter(KotlinLightTypeParameter(owner, i, safeName))
}
}
return builder
}
public class PropertyAccessorsPsiMethods(public val getter: PsiMethod?,
public val setter: PsiMethod?,
public val backingField: PsiField?,
additionalAccessors: List<PsiMethod>) : Iterable<PsiMethod> {
private val allMethods = arrayListOf<PsiMethod>()
val allDeclarations = arrayListOf<PsiNamedElement>()
init {
listOf(getter, setter).filterNotNullTo(allMethods)
listOf<PsiNamedElement?>(getter, setter, backingField).filterNotNullTo(allDeclarations)
allDeclarations.addAll(additionalAccessors)
additionalAccessors.filterIsInstanceTo<PsiMethod, MutableList<PsiMethod>>(allMethods)
}
override fun iterator(): Iterator<PsiMethod> = allMethods.iterator()
}
}

View File

@@ -17,14 +17,12 @@
package org.jetbrains.kotlin.asJava
import com.intellij.psi.*
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.psi.*
import java.util.Collections
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import java.util.ArrayList
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
import java.util.*
public fun JetClassOrObject.toLightClass(): KotlinLightClass? = LightClassUtil.getPsiClass(this) as KotlinLightClass?
@@ -32,11 +30,11 @@ public fun JetDeclaration.toLightElements(): List<PsiNamedElement> =
when (this) {
is JetClassOrObject -> LightClassUtil.getPsiClass(this).singletonOrEmptyList()
is JetNamedFunction,
is JetSecondaryConstructor -> LightClassUtil.getLightClassMethod(this as JetFunction).singletonOrEmptyList()
is JetSecondaryConstructor -> LightClassUtil.getLightClassMethods(this as JetFunction)
is JetProperty -> LightClassUtil.getLightClassPropertyMethods(this).toList()
is JetPropertyAccessor -> LightClassUtil.getLightClassAccessorMethod(this).singletonOrEmptyList()
is JetParameter -> ArrayList<PsiNamedElement>().let { elements ->
toPsiParameter()?.let { psiParameter -> elements.add(psiParameter) }
toPsiParameters().toCollection(elements)
LightClassUtil.getLightClassPropertyMethods(this).toCollection(elements)
elements
@@ -47,10 +45,10 @@ public fun JetDeclaration.toLightElements(): List<PsiNamedElement> =
public fun PsiElement.toLightMethods(): List<PsiMethod> =
when (this) {
is JetFunction -> LightClassUtil.getLightClassMethod(this).singletonOrEmptyList()
is JetFunction -> LightClassUtil.getLightClassMethods(this)
is JetProperty -> LightClassUtil.getLightClassPropertyMethods(this).toList()
is JetParameter -> LightClassUtil.getLightClassPropertyMethods(this).toList()
is JetPropertyAccessor -> LightClassUtil.getLightClassAccessorMethod(this).singletonOrEmptyList()
is JetPropertyAccessor -> LightClassUtil.getLightClassAccessorMethods(this)
is JetClass -> LightClassUtil.getPsiClass(this)?.getConstructors()?.first().singletonOrEmptyList()
is PsiMethod -> this.singletonList()
else -> listOf()
@@ -59,28 +57,28 @@ public fun PsiElement.toLightMethods(): List<PsiMethod> =
public fun PsiElement.getRepresentativeLightMethod(): PsiMethod? =
when (this) {
is JetFunction -> LightClassUtil.getLightClassMethod(this)
is JetProperty -> LightClassUtil.getLightClassPropertyMethods(this).getGetter()
is JetParameter -> LightClassUtil.getLightClassPropertyMethods(this).getGetter()
is JetProperty -> LightClassUtil.getLightClassPropertyMethods(this).getter
is JetParameter -> LightClassUtil.getLightClassPropertyMethods(this).getter
is JetPropertyAccessor -> LightClassUtil.getLightClassAccessorMethod(this)
is PsiMethod -> this
else -> null
}
public fun JetParameter.toPsiParameter(): PsiParameter? {
val paramList = getNonStrictParentOfType<JetParameterList>() ?: return null
public fun JetParameter.toPsiParameters(): Collection<PsiParameter> {
val paramList = getNonStrictParentOfType<JetParameterList>() ?: return emptyList()
val paramIndex = paramList.getParameters().indexOf(this)
val owner = paramList.getParent()
val lightParamIndex = if (owner is JetDeclaration && owner.isExtensionDeclaration()) paramIndex + 1 else paramIndex
val method: PsiMethod =
val methods: Collection<PsiMethod> =
when (owner) {
is JetFunction -> LightClassUtil.getLightClassMethod(owner)
is JetPropertyAccessor -> LightClassUtil.getLightClassAccessorMethod(owner)
is JetFunction -> LightClassUtil.getLightClassMethods(owner)
is JetPropertyAccessor -> LightClassUtil.getLightClassAccessorMethods(owner)
else -> null
} ?: return null
} ?: return emptyList()
return method.getParameterList().getParameters()[lightParamIndex]
return methods.map { it.getParameterList().getParameters()[lightParamIndex] }
}
public fun JetTypeParameter.toPsiTypeParameters(): List<PsiTypeParameter> {

View File

@@ -283,7 +283,7 @@ public interface Comparable</*0*/ in T> {
public abstract fun compareTo(/*0*/ other: T): kotlin.Int
}
kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASSIFIER, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.VALUE_PARAMETER}) kotlin.annotation.MustBeDocumented() kotlin.annotation.annotation() public final class Deprecated : kotlin.Annotation {
kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.VALUE_PARAMETER}) kotlin.annotation.MustBeDocumented() kotlin.annotation.annotation() public final class Deprecated : kotlin.Annotation {
/*primary*/ public constructor Deprecated(/*0*/ value: kotlin.String, /*1*/ replaceWith: kotlin.ReplaceWith = ...)
public final val replaceWith: kotlin.ReplaceWith
public final fun <get-replaceWith>(): kotlin.ReplaceWith
@@ -1235,7 +1235,7 @@ public final class String : kotlin.Comparable<kotlin.String>, kotlin.CharSequenc
}
}
kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASSIFIER, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.TYPE, AnnotationTarget.EXPRESSION, AnnotationTarget.FILE}) kotlin.annotation.Retention(value = AnnotationRetention.SOURCE) kotlin.annotation.annotation() public final class Suppress : kotlin.Annotation {
kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.TYPE, AnnotationTarget.EXPRESSION, AnnotationTarget.FILE}) kotlin.annotation.Retention(value = AnnotationRetention.SOURCE) kotlin.annotation.annotation() public final class Suppress : kotlin.Annotation {
/*primary*/ public constructor Suppress(/*0*/ vararg names: kotlin.String /*kotlin.Array<out kotlin.String>*/)
public final val names: kotlin.Array<out kotlin.String>
public final fun <get-names>(): kotlin.Array<out kotlin.String>
@@ -1256,7 +1256,7 @@ kotlin.annotation.Target(allowedTargets = {AnnotationTarget.VALUE_PARAMETER}) ko
/*primary*/ public constructor crossinline()
}
kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASSIFIER}) kotlin.annotation.MustBeDocumented() kotlin.annotation.annotation() public final class data : kotlin.Annotation {
kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS}) kotlin.annotation.MustBeDocumented() kotlin.annotation.annotation() public final class data : kotlin.Annotation {
/*primary*/ public constructor data()
}

View File

@@ -1,5 +1,7 @@
import wrong.*
fun foo(x: ClassWithWrongAbiVersion) {
bar()
}
bar()
1.set(2, 3)
}

View File

@@ -1,6 +1,12 @@
compiler/testData/cli/jvm/wrongAbiVersion.kt:4:5: error: unresolved reference: bar
(note: this may be caused by the fact that some classes compiled with an incompatible version of Kotlin were found in the classpath. Such classes cannot be loaded properly by this version of Kotlin compiler. See below for more information)
bar()
^
compiler/testData/cli/jvm/wrongAbiVersion.kt:6:7: error: unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public fun <K, V> kotlin.MutableMap<kotlin.Int, kotlin.Int>.set(key: kotlin.Int, value: kotlin.Int): kotlin.Int? defined in kotlin
(note: this may be caused by the fact that some classes compiled with an incompatible version of Kotlin were found in the classpath. Such classes cannot be loaded properly by this version of Kotlin compiler. See below for more information)
1.set(2, 3)
^
compiler/testData/cli/jvm/wrongAbiVersionLib/bin/ClassWithWrongAbiVersion.class: error: class 'ClassWithWrongAbiVersion' was compiled with an incompatible version of Kotlin. Its ABI version is unknown, expected ABI version is $ABI_VERSION$
compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/Wrong_packageKt.class: error: class 'wrong/Wrong_packageKt' was compiled with an incompatible version of Kotlin. Its ABI version is unknown, expected ABI version is $ABI_VERSION$
compiler/testData/cli/jvm/wrongAbiVersion.kt:4:3: error: unresolved reference: bar
bar()
^
compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/WrongPackage.class: error: class 'wrong/WrongPackage' was compiled with an incompatible version of Kotlin. Its ABI version is unknown, expected ABI version is $ABI_VERSION$
COMPILATION_ERROR

View File

@@ -0,0 +1,5 @@
$TESTDATA_DIR$/wrongAbiVersionNoErrors.kt
-classpath
$TESTDATA_DIR$/wrongAbiVersionLib/bin
-d
$TEMP_DIR$

View File

@@ -0,0 +1,7 @@
// This should compile despite the fact that there are usages of symbols with the wrong ABI version!
import wrong.ClassWithInnerLambda
fun happy(): Int {
return 2 + 2
}

View File

@@ -0,0 +1 @@
OK

View File

@@ -0,0 +1,3 @@
import a.foo
fun box(): String = foo { "OK" }

View File

@@ -0,0 +1,6 @@
@file:[JvmName("MultifileClass") JvmMultifileClass]
package a
inline fun foo(body: () -> String): String = bar(body())
public fun bar(x: String): String = x

View File

@@ -0,0 +1,5 @@
package test
import b.bar
fun box(): String = bar()

View File

@@ -0,0 +1,5 @@
package b
import a.foo
fun bar(): String = foo()

View File

@@ -0,0 +1,4 @@
@file:[JvmName("MultifileClass") JvmMultifileClass]
package a
fun foo(): String = "OK"

View File

@@ -0,0 +1,5 @@
package test
import a.foo
fun box(): String = foo { "OK" }

View File

@@ -0,0 +1,4 @@
@file:[JvmName("APackage") JvmMultifileClass]
package a
inline fun foo(body: () -> String): String = zee(body())

View File

@@ -0,0 +1,4 @@
@file:[JvmName("APackage") JvmMultifileClass]
package a
public fun zee(x: String): String = x

View File

@@ -0,0 +1,3 @@
import a.*
fun box(): String = OK

View File

@@ -0,0 +1,4 @@
@file:[JvmName("MultifileClass") JvmMultifileClass]
package a
val O: String = "O"

View File

@@ -0,0 +1,4 @@
@file:[JvmName("MultifileClass") JvmMultifileClass]
package a
val K: String = "K"

View File

@@ -0,0 +1,4 @@
@file:[JvmName("MultifileClass") JvmMultifileClass]
package a
val OK: String = O + K

View File

@@ -0,0 +1,3 @@
import a.foo
fun box(): String = foo()

View File

@@ -0,0 +1,4 @@
@file:[JvmName("MultifileClass") JvmMultifileClass]
package a
fun foo(): String = "OK"

View File

@@ -0,0 +1,3 @@
import a.OK
fun box(): String = OK

View File

@@ -0,0 +1,4 @@
@file:[JvmName("MultifileClass") JvmMultifileClass]
package a
val OK: String = "OK"

View File

@@ -0,0 +1,6 @@
import a.OK
fun box(): String {
OK = "OK"
return OK
}

View File

@@ -0,0 +1,4 @@
@file:[JvmName("MultifileClass") JvmMultifileClass]
package a
var OK: String = "Hmmm?"

View File

@@ -2,4 +2,4 @@
@file:JvmMultifileClass
public fun bar(): String = barx()
private fun foox(): String = "O"
public fun foox(): String = "O"

View File

@@ -2,4 +2,4 @@
@file:JvmMultifileClass
public fun foo(): String = foox()
private fun barx(): String = "K"
public fun barx(): String = "K"

View File

@@ -0,0 +1,2 @@
fun box(): String =
listOf("a").map { "OK" }.get(0)

View File

@@ -0,0 +1,11 @@
@file:JvmName("TestPackage")
@file:JvmMultifileClass
package test
fun foo(): String = bar()
fun bar(): String {
class Local(val x: String)
return Local("OK").x
}
fun box(): String = foo()

View File

@@ -0,0 +1,5 @@
fun doStuff(fn: String.() -> String) = "ok".fn()
fun box(): String {
return doStuff(String::toUpperCase)
}

View File

@@ -2,6 +2,5 @@ fun foo() {
assert(1 == 1) { "Hahaha" }
}
// assert function will be inlined, and we assure that there are no calls via package part, but is call via package facade in inlined code
// 0 INVOKESTATIC kotlin\/KotlinPackage.+\.getASSERTIONS_ENABLED \(\)Z
// 1 INVOKESTATIC kotlin\/AssertionsJVMKt\.getASSERTIONS_ENABLED \(\)Z
// 1 INVOKESTATIC kotlin\/KotlinPackage\.getASSERTIONS_ENABLED
// 0 INVOKESTATIC kotlin\/AssertionsJVMKt\.getASSERTIONS_ENABLED

View File

@@ -0,0 +1,5 @@
@file:[JvmName("Util") JvmMultifileClass]
package test
internal fun internalInOtherFile() {}
public fun publicInOtherFile() {}

View File

@@ -0,0 +1,23 @@
@file:[JvmName("Util") JvmMultifileClass]
package test
fun foo() {
privateInThisFile()
internalInThisFile()
publicInThisFile()
internalInOtherFile()
publicInOtherFile()
}
private fun privateInThisFile() {}
internal fun internalInThisFile() {}
public fun publicInThisFile() {}
// @test/Util__ThisFileKt.class:
// 1 INVOKESTATIC test/Util__ThisFileKt.privateInThisFile
// 1 INVOKESTATIC test/Util.internalInThisFile
// 1 INVOKESTATIC test/Util.publicInThisFile
// 1 INVOKESTATIC test/Util.internalInOtherFile
// 1 INVOKESTATIC test/Util.publicInOtherFile

View File

@@ -0,0 +1,4 @@
@file:[JvmName("Util") JvmMultifileClass]
package test
public fun publicInOtherFile() {}

View File

@@ -0,0 +1,18 @@
@file:[JvmName("Util") JvmMultifileClass]
package test
inline fun foo(body: () -> Unit) {
publicInThisFile()
publicInOtherFile()
body()
}
public fun publicInThisFile() {}
fun bar() {
foo {}
}
// @test/Util__ThisFileKt.class:
// 2 INVOKESTATIC test/Util.publicInThisFile
// 2 INVOKESTATIC test/Util.publicInOtherFile

Some files were not shown because too many files have changed in this diff Show More