diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java index f459c4b3930..5e52ca69f12 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java @@ -88,6 +88,8 @@ public class AnonymousObjectTransformer { reader.accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) { @Override public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) { + InlineCodegenUtil.assertVersionNotGreaterThanJava6(version); + if (signature != null) { ReifiedTypeInliner.SignatureReificationResult signatureResult = inliningContext.reifedTypeInliner.reifySignature(signature); signature = signatureResult.getNewSignature(); @@ -97,7 +99,7 @@ public class AnonymousObjectTransformer { } @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { + public void visitInnerClass(@NotNull String name, String outerName, String innerName, int access) { innerClassNodes.add(new InnerClassNode(name, outerName, innerName, access)); } @@ -162,7 +164,7 @@ public class AnonymousObjectTransformer { } else { //seems we can't do any clever mapping cause we don't know any about original class name - sourceMapper = IdenticalSourceMapper.INSTANCE$; + sourceMapper = IdenticalSourceMapper.INSTANCE; } if (sourceInfo != null && !InlineCodegenUtil.GENERATE_SMAP) { classBuilder.visitSource(sourceInfo, debugInfo); @@ -172,7 +174,7 @@ public class AnonymousObjectTransformer { if (sourceInfo != null) { classBuilder.visitSource(sourceInfo, debugInfo); } - sourceMapper = IdenticalSourceMapper.INSTANCE$; + sourceMapper = IdenticalSourceMapper.INSTANCE; } ParametersBuilder allCapturedParamBuilder = ParametersBuilder.newBuilder(); @@ -180,7 +182,7 @@ public class AnonymousObjectTransformer { List additionalFakeParams = extractParametersMappingAndPatchConstructor(constructor, allCapturedParamBuilder, constructorParamBuilder, anonymousObjectGen, parentRemapper); - List deferringMethods = new ArrayList(); + List deferringMethods = new ArrayList(); for (MethodNode next : methodsToTransform) { MethodVisitor deferringVisitor = newMethod(classBuilder, next); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java index 36f52adecba..77de62194bb 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache; import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents; import org.jetbrains.kotlin.modules.TargetId; +import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.renderer.DescriptorRenderer; @@ -192,11 +193,15 @@ public class InlineCodegen extends CallGenerator { JetTypeMapper.ContainingClassesInfo containingClasses = typeMapper.getContainingClassesForDeserializedCallable( (DeserializedSimpleFunctionDescriptor) functionDescriptor); - VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable(containingClasses.getImplClassId(), state); - nodeAndSMAP = InlineCodegenUtil.getMethodNode(file.contentsToByteArray(), - asmMethod.getName(), - asmMethod.getDescriptor(), - containingClasses.getFacadeClassId()); + ClassId containerId = containingClasses.getImplClassId(); + VirtualFile file = InlineCodegenUtil.findVirtualFile(state, containerId); + if (file == null) { + throw new IllegalStateException("Couldn't find declaration file for " + containerId); + } + + nodeAndSMAP = InlineCodegenUtil.getMethodNode( + file.contentsToByteArray(), asmMethod.getName(), asmMethod.getDescriptor(), containingClasses.getFacadeClassId() + ); if (nodeAndSMAP == null) { throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor)); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java index 30bc4c6a57a..e1131b943f7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java @@ -16,11 +16,10 @@ package org.jetbrains.kotlin.codegen.inline; -import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import kotlin.StringsKt; +import kotlin.text.StringsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; @@ -92,6 +91,10 @@ public class InlineCodegenUtil { lines[0] = Integer.MAX_VALUE; lines[1] = Integer.MIN_VALUE; cr.accept(new ClassVisitor(API) { + @Override + public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) { + assertVersionNotGreaterThanJava6(version); + } @Override public void visitSource(String source, String debug) { @@ -127,40 +130,44 @@ public class InlineCodegenUtil { return new SMAPAndMethodNode(node[0], smap); } - public static void initDefaultSourceMappingIfNeeded(@NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state) { - if (state.isInlineEnabled()) { - CodegenContext parentContext = context.getParentContext(); - while (parentContext != null) { - if (parentContext instanceof MethodContext) { - if (((MethodContext) parentContext).isInlineMethodContext()) { - //just init default one to one mapping - codegen.getOrCreateSourceMapper(); - break; - } - } - parentContext = parentContext.getParentContext(); - } + public static void assertVersionNotGreaterThanJava6(int version) { + // TODO: report a proper diagnostic + if (version > Opcodes.V1_6) { + throw new UnsupportedOperationException( + "Cannot inline bytecode of version " + version + ". " + + "This compiler can only inline Java 1.6 bytecode (version " + Opcodes.V1_6 + ")" + ); } } - @NotNull - public static VirtualFile getVirtualFileForCallable(@NotNull ClassId containerClassId, @NotNull GenerationState state) { - JvmVirtualFileFinder fileFinder = JvmVirtualFileFinder.SERVICE.getInstance(state.getProject()); - VirtualFile file = fileFinder.findVirtualFileWithHeader(containerClassId); - if (file == null) { - throw new IllegalStateException("Couldn't find declaration file for " + containerClassId); + public static void initDefaultSourceMappingIfNeeded( + @NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state + ) { + if (!state.isInlineEnabled()) return; + + CodegenContext parentContext = context.getParentContext(); + while (parentContext != null) { + if (parentContext.isInlineMethodContext()) { + //just init default one to one mapping + codegen.getOrCreateSourceMapper(); + break; + } + parentContext = parentContext.getParentContext(); } - return file; } @Nullable - public static VirtualFile findVirtualFile(@NotNull Project project, @NotNull String internalClassName) { + public static VirtualFile findVirtualFile(@NotNull GenerationState state, @NotNull ClassId classId) { + return JvmVirtualFileFinder.SERVICE.getInstance(state.getProject()).findVirtualFileWithHeader(classId); + } + + @Nullable + public static VirtualFile findVirtualFileImprecise(@NotNull GenerationState state, @NotNull String internalClassName) { FqName packageFqName = JvmClassName.byInternalName(internalClassName).getPackageFqName(); String classNameWithDollars = StringsKt.substringAfterLast(internalClassName, "/", internalClassName); - JvmVirtualFileFinder fileFinder = JvmVirtualFileFinder.SERVICE.getInstance(project); //TODO: we cannot construct proper classId at this point, we need to read InnerClasses info from class file // we construct valid.package.name/RelativeClassNameAsSingleName that should work in compiler, but fails for inner classes in IDE - return fileFinder.findVirtualFileWithHeader(new ClassId(packageFqName, Name.identifier(classNameWithDollars))); + return findVirtualFile(state, new ClassId(packageFqName, Name.identifier(classNameWithDollars))); } public static String getInlineName( @@ -362,8 +369,9 @@ public class InlineCodegenUtil { OutputFile outputFile = state.getFactory().get(internalName + ".class"); if (outputFile != null) { return new ClassReader(outputFile.asByteArray()); - } else { - VirtualFile file = findVirtualFile(state.getProject(), internalName); + } + else { + VirtualFile file = findVirtualFileImprecise(state, internalName); if (file == null) { throw new RuntimeException("Couldn't find virtual file for " + internalName); }