Added hacky checks for accessing compiled functions from our module via package part instead of facade.
#KT-4590 fixed
This commit is contained in:
@@ -33,6 +33,7 @@ import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalPackageFragmentProvider;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
@@ -152,20 +153,19 @@ public class JvmCodegenUtil {
|
||||
}
|
||||
|
||||
private static boolean isSamePackageInSameModule(
|
||||
@NotNull DeclarationDescriptor owner1,
|
||||
@NotNull DeclarationDescriptor owner2
|
||||
@NotNull DeclarationDescriptor callerOwner,
|
||||
@NotNull DeclarationDescriptor calleeOwner
|
||||
) {
|
||||
if (owner1 instanceof PackageFragmentDescriptor && owner2 instanceof PackageFragmentDescriptor) {
|
||||
PackageFragmentDescriptor fragment1 = (PackageFragmentDescriptor) owner1;
|
||||
PackageFragmentDescriptor fragment2 = (PackageFragmentDescriptor) owner2;
|
||||
|
||||
if (!IncrementalCompilation.ENABLED) {
|
||||
return fragment1 == fragment2;
|
||||
}
|
||||
if (callerOwner instanceof PackageFragmentDescriptor && calleeOwner instanceof PackageFragmentDescriptor) {
|
||||
PackageFragmentDescriptor callerFragment = (PackageFragmentDescriptor) callerOwner;
|
||||
PackageFragmentDescriptor calleeFragment = (PackageFragmentDescriptor) calleeOwner;
|
||||
|
||||
// backing field should be used directly within same module of same package
|
||||
// TODO calls from other modules/libraries should use facade: KT-4590
|
||||
return fragment1.getFqName().equals(fragment2.getFqName()) && DescriptorUtils.areInSameModule(fragment1, fragment2);
|
||||
if (callerFragment == calleeFragment) {
|
||||
return true;
|
||||
}
|
||||
return callerFragment.getFqName().equals(calleeFragment.getFqName())
|
||||
&& calleeFragment instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -112,7 +113,7 @@ public class GenerationState {
|
||||
@NotNull List<JetFile> files
|
||||
) {
|
||||
this(project, builderFactory, Progress.DEAF, module, bindingContext, files, true, false, GenerateClassFilter.GENERATE_ALL,
|
||||
InlineCodegenUtil.DEFAULT_INLINE_FLAG, null, null, DiagnosticHolder.DO_NOTHING);
|
||||
InlineCodegenUtil.DEFAULT_INLINE_FLAG, null, null, DiagnosticHolder.DO_NOTHING, null);
|
||||
}
|
||||
|
||||
public GenerationState(
|
||||
@@ -128,7 +129,8 @@ public class GenerationState {
|
||||
boolean inlineEnabled,
|
||||
@Nullable Collection<FqName> packagesWithRemovedFiles,
|
||||
@Nullable String moduleId,
|
||||
@NotNull DiagnosticHolder diagnostics
|
||||
@NotNull DiagnosticHolder diagnostics,
|
||||
@Nullable File outDirectory
|
||||
) {
|
||||
this.project = project;
|
||||
this.progress = progress;
|
||||
@@ -142,7 +144,7 @@ public class GenerationState {
|
||||
this.bindingTrace = new DelegatingBindingTrace(bindingContext, "trace in GenerationState");
|
||||
this.bindingContext = bindingTrace.getBindingContext();
|
||||
|
||||
this.typeMapper = new JetTypeMapper(this.bindingContext, classBuilderMode);
|
||||
this.typeMapper = new JetTypeMapperWithOutDirectory(this.bindingContext, classBuilderMode, outDirectory);
|
||||
|
||||
this.intrinsics = new IntrinsicMethods();
|
||||
this.classFileFactory = new ClassFileFactory(this, new BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterSignat
|
||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalPackageFragmentProvider;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
@@ -123,6 +124,10 @@ public class JetTypeMapper {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isContainedByCompiledPartOfOurModule(@NotNull DeclarationDescriptor descriptor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String internalNameForPackage(
|
||||
@NotNull PackageFragmentDescriptor packageFragment,
|
||||
@@ -135,11 +140,17 @@ public class JetTypeMapper {
|
||||
return PackagePartClassUtils.getPackagePartInternalName(file);
|
||||
}
|
||||
|
||||
if (descriptor instanceof DeserializedCallableMemberDescriptor && IncrementalCompilation.ENABLED) {
|
||||
//
|
||||
// TODO calls from other modules/libraries should use facade: KT-4590
|
||||
FqName packagePartFqName = PackagePartClassUtils.getPackagePartFqName((DeserializedCallableMemberDescriptor) descriptor);
|
||||
return AsmUtil.internalNameByFqNameWithoutInnerClasses(packagePartFqName);
|
||||
DeclarationDescriptor descriptorToCheck = descriptor instanceof PropertyAccessorDescriptor
|
||||
? ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty()
|
||||
: descriptor;
|
||||
|
||||
if (descriptorToCheck instanceof DeserializedCallableMemberDescriptor) {
|
||||
// TODO Temporary hack until modules infrastructure is implemented. See JetTypeMapperWithOutDirectory for details
|
||||
if (descriptor.getContainingDeclaration() instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment ||
|
||||
isContainedByCompiledPartOfOurModule(descriptor)) {
|
||||
FqName packagePartFqName = PackagePartClassUtils.getPackagePartFqName((DeserializedCallableMemberDescriptor) descriptorToCheck);
|
||||
return AsmUtil.internalNameByFqNameWithoutInnerClasses(packagePartFqName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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.jet.codegen.state;
|
||||
|
||||
import com.intellij.openapi.vfs.StandardFileSystems;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderMode;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyPackageFragmentScopeForJavaPackage;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
// TODO Temporary hack until modules infrastructure is implemented.
|
||||
// This class is necessary for detecting if compiled class is from the same module as callee.
|
||||
// Module chunks are treated as single module.
|
||||
public class JetTypeMapperWithOutDirectory extends JetTypeMapper {
|
||||
private final File outDirectory;
|
||||
|
||||
public JetTypeMapperWithOutDirectory(
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull ClassBuilderMode classBuilderMode,
|
||||
@Nullable File outDirectory
|
||||
) {
|
||||
super(bindingContext, classBuilderMode);
|
||||
this.outDirectory = outDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isContainedByCompiledPartOfOurModule(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (outDirectory == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(descriptor.getContainingDeclaration() instanceof JavaPackageFragmentDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
JavaPackageFragmentDescriptor packageFragment = (JavaPackageFragmentDescriptor) descriptor.getContainingDeclaration();
|
||||
JetScope packageScope = packageFragment.getMemberScope();
|
||||
if (!(packageScope instanceof LazyPackageFragmentScopeForJavaPackage)) {
|
||||
return false;
|
||||
}
|
||||
KotlinJvmBinaryClass binaryClass = ((LazyPackageFragmentScopeForJavaPackage) packageScope).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);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+7
-5
@@ -135,7 +135,8 @@ public class KotlinToJVMBytecodeCompiler {
|
||||
}
|
||||
}
|
||||
);
|
||||
GenerationState generationState = generate(environment, exhaust, jetFiles, module.getModuleName());
|
||||
GenerationState generationState =
|
||||
generate(environment, exhaust, jetFiles, module.getModuleName(), new File(module.getOutputDirectory()));
|
||||
outputFiles.put(module, generationState.getFactory());
|
||||
}
|
||||
}
|
||||
@@ -274,7 +275,7 @@ public class KotlinToJVMBytecodeCompiler {
|
||||
|
||||
exhaust.throwIfError();
|
||||
|
||||
return generate(environment, exhaust, environment.getSourceFiles(), null);
|
||||
return generate(environment, exhaust, environment.getSourceFiles(), null, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -319,7 +320,8 @@ public class KotlinToJVMBytecodeCompiler {
|
||||
@NotNull JetCoreEnvironment environment,
|
||||
@NotNull AnalyzeExhaust exhaust,
|
||||
@NotNull List<JetFile> sourceFiles,
|
||||
@Nullable String moduleId
|
||||
@Nullable String moduleId,
|
||||
File outputDirectory
|
||||
) {
|
||||
CompilerConfiguration configuration = environment.getConfiguration();
|
||||
File incrementalCacheDir = configuration.get(JVMConfigurationKeys.INCREMENTAL_CACHE_BASE_DIR);
|
||||
@@ -344,8 +346,8 @@ public class KotlinToJVMBytecodeCompiler {
|
||||
configuration.get(JVMConfigurationKeys.ENABLE_INLINE, InlineCodegenUtil.DEFAULT_INLINE_FLAG),
|
||||
packagesWithRemovedFiles,
|
||||
moduleId,
|
||||
diagnosticHolder
|
||||
);
|
||||
diagnosticHolder,
|
||||
outputDirectory);
|
||||
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION);
|
||||
AnalyzerWithCompilerReport.reportDiagnostics(
|
||||
new FilteredJvmDiagnostics(
|
||||
|
||||
+2
-2
@@ -300,8 +300,8 @@ public class KotlinJavaFileStubProvider<T extends WithFileStubAndExtraDiagnostic
|
||||
/*to generate inline flag on methods*/true,
|
||||
null,
|
||||
null,
|
||||
forExtraDiagnostics
|
||||
);
|
||||
forExtraDiagnostics,
|
||||
null);
|
||||
KotlinCodegenFacade.prepareForCompilation(state);
|
||||
|
||||
bindingContext = state.getBindingContext();
|
||||
|
||||
@@ -70,8 +70,8 @@ public class CodegenTestUtil {
|
||||
configuration.get(JVMConfigurationKeys.ENABLE_INLINE, InlineCodegenUtil.DEFAULT_INLINE_FLAG),
|
||||
null,
|
||||
null,
|
||||
forExtraDiagnostics
|
||||
);
|
||||
forExtraDiagnostics,
|
||||
null);
|
||||
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION);
|
||||
|
||||
// For JVM-specific errors
|
||||
|
||||
+7
-2
@@ -38,6 +38,7 @@ import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaMemberScope.MethodSignatureData
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.name.SpecialNames
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass
|
||||
|
||||
public abstract class LazyJavaPackageFragmentScope(
|
||||
c: LazyJavaResolverContext,
|
||||
@@ -91,9 +92,13 @@ public class LazyPackageFragmentScopeForJavaPackage(
|
||||
packageFragment: LazyPackageFragmentForJavaPackage
|
||||
) : LazyJavaPackageFragmentScope(c, packageFragment) {
|
||||
|
||||
// TODO: Storing references is a temporary hack until modules infrastructure is implemented.
|
||||
// See JetTypeMapperWithOutDirectories for details
|
||||
public val kotlinBinaryClass: KotlinJvmBinaryClass?
|
||||
= c.kotlinClassFinder.findKotlinClass(PackageClassUtils.getPackageClassFqName(fqName))
|
||||
|
||||
private val deserializedPackageScope = c.storageManager.createLazyValue {
|
||||
val packageClassFqName = PackageClassUtils.getPackageClassFqName(fqName)
|
||||
val kotlinBinaryClass = c.kotlinClassFinder.findKotlinClass(packageClassFqName)
|
||||
val kotlinBinaryClass = kotlinBinaryClass
|
||||
if (kotlinBinaryClass == null)
|
||||
JetScope.EMPTY
|
||||
else
|
||||
|
||||
@@ -116,7 +116,7 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
|
||||
Collections.singletonList(jetFile), true, true,
|
||||
GenerationState.GenerateClassFilter.GENERATE_ALL,
|
||||
enableInline.isSelected(), null, null,
|
||||
DiagnosticHolder.DO_NOTHING);
|
||||
DiagnosticHolder.DO_NOTHING, null);
|
||||
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
|
||||
@@ -32,6 +32,16 @@ import org.jetbrains.jet.jps.build.AbstractIncrementalJpsTest;
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental")
|
||||
public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
||||
@TestMetadata("accessingFunctionsViaPackagePart")
|
||||
public void testAccessingFunctionsViaPackagePart() throws Exception {
|
||||
doTest("jps-plugin/testData/incremental/accessingFunctionsViaPackagePart/");
|
||||
}
|
||||
|
||||
@TestMetadata("accessingPropertiesViaField")
|
||||
public void testAccessingPropertiesViaField() throws Exception {
|
||||
doTest("jps-plugin/testData/incremental/accessingPropertiesViaField/");
|
||||
}
|
||||
|
||||
@TestMetadata("allConstants")
|
||||
public void testAllConstants() throws Exception {
|
||||
doTest("jps-plugin/testData/incremental/allConstants/");
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
fun a() = "a"
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
fun b() = "b"
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
fun b() = "b"
|
||||
@@ -0,0 +1,9 @@
|
||||
Cleaning output files:
|
||||
out/production/module/test/TestPackage-b-*.class
|
||||
out/production/module/test/TestPackage-usage-*.class
|
||||
out/production/module/test/TestPackage.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/b.kt
|
||||
src/usage.kt
|
||||
End of files
|
||||
@@ -0,0 +1,3 @@
|
||||
package other
|
||||
|
||||
fun other() = "other"
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println(a() + b() + other.other())
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println(a() + b() + other.other())
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
var a = "a"
|
||||
@@ -0,0 +1,4 @@
|
||||
// TODO add var
|
||||
package test
|
||||
|
||||
var b = "b"
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
var b = "b"
|
||||
@@ -0,0 +1,9 @@
|
||||
Cleaning output files:
|
||||
out/production/module/test/TestPackage-b-*.class
|
||||
out/production/module/test/TestPackage-usage-*.class
|
||||
out/production/module/test/TestPackage.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/b.kt
|
||||
src/usage.kt
|
||||
End of files
|
||||
@@ -0,0 +1,3 @@
|
||||
package other
|
||||
|
||||
var other = "other"
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val x = a + b + other.other
|
||||
a = "aa"
|
||||
b = "bb"
|
||||
other.other = "other.other"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val x = a + b + other.other
|
||||
a = "aa"
|
||||
b = "bb"
|
||||
other.other = "other.other"
|
||||
}
|
||||
Reference in New Issue
Block a user