diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 5d086243e18..38de1d44224 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -270,6 +270,14 @@ public class CodegenUtil { && context.getContextKind() != OwnerKind.TRAIT_IMPL); } + public static boolean isCallInsideSameModuleAsDeclared(CallableMemberDescriptor declarationDescriptor, CodegenContext context) { + if (context == CodegenContext.STATIC) { + return true; + } + DeclarationDescriptor contextDescriptor = context.getContextDescriptor(); + return DescriptorUtils.isInSameModule(declarationDescriptor, contextDescriptor); + } + public static boolean hasAbstractMembers(@NotNull ClassDescriptor classDescriptor) { return ContainerUtil.exists(classDescriptor.getDefaultType().getMemberScope().getAllDescriptors(), new Condition() { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 2a2135f6501..d88938cf94b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1721,6 +1721,7 @@ public class ExpressionCodegen extends JetVisitor implem PropertyDescriptor initialDescriptor = propertyDescriptor; propertyDescriptor = initialDescriptor.getOriginal(); boolean isInsideClass = isCallInsideSameClassAsDeclared(propertyDescriptor, context); + boolean isInsideModule = isCallInsideSameModuleAsDeclared(propertyDescriptor, context); boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null; Method getter = null; Method setter = null; @@ -1794,7 +1795,7 @@ public class ExpressionCodegen extends JetVisitor implem boolean isInterface; if (isStatic) { isInterface = overridesTrait; - owner = ownerParam = typeMapper.getOwner(propertyDescriptor, contextKind()); + owner = ownerParam = typeMapper.getOwner(propertyDescriptor, contextKind(), isInsideModule); getterInvokeOpcode = INVOKESTATIC; setterInvokeOpcode = INVOKESTATIC; @@ -1807,7 +1808,7 @@ public class ExpressionCodegen extends JetVisitor implem getterInvokeOpcode = getOpcodeForPropertyDescriptorWithoutAccessor(propertyDescriptor); } else { - callableGetter = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, isInsideClass, contextKind()); + callableGetter = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, isInsideClass, isInsideModule, contextKind()); getterInvokeOpcode = callableGetter.getInvokeOpcode(); } @@ -1815,13 +1816,13 @@ public class ExpressionCodegen extends JetVisitor implem setterInvokeOpcode = getOpcodeForPropertyDescriptorWithoutAccessor(propertyDescriptor); } else { - callableSetter = typeMapper.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper, isInsideClass, contextKind()); + callableSetter = typeMapper.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper, isInsideClass, isInsideModule, contextKind()); setterInvokeOpcode = callableSetter.getInvokeOpcode(); } CallableMethod callableMethod = callableGetter != null ? callableGetter : callableSetter; if (callableMethod == null) { - owner = ownerParam = typeMapper.getOwner(propertyDescriptor, contextKind()); + owner = ownerParam = typeMapper.getOwner(propertyDescriptor, contextKind(), isInsideModule); } else { owner = isFakeOverride && !overridesTrait && !isInterface(initialDescriptor.getContainingDeclaration()) @@ -2034,7 +2035,10 @@ public class ExpressionCodegen extends JetVisitor implem callableMethod = typeMapper.asCallableMethod(invoke); } else { - callableMethod = typeMapper.mapToCallableMethod(fd, superCall, isCallInsideSameClassAsDeclared(fd, context), OwnerKind.IMPLEMENTATION); + callableMethod = typeMapper.mapToCallableMethod(fd, superCall, + isCallInsideSameClassAsDeclared(fd, context), + isCallInsideSameModuleAsDeclared(fd, context), + OwnerKind.IMPLEMENTATION); } return callableMethod; } @@ -3105,6 +3109,7 @@ public class ExpressionCodegen extends JetVisitor implem descriptor, false, isCallInsideSameClassAsDeclared(descriptor, context), + isCallInsideSameModuleAsDeclared(descriptor, context), OwnerKind.IMPLEMENTATION); invokeMethodWithArguments(callableMethod, expression, StackValue.none()); return type; @@ -3207,6 +3212,7 @@ public class ExpressionCodegen extends JetVisitor implem operationDescriptor, false, isCallInsideSameClassAsDeclared(operationDescriptor, context), + isCallInsideSameModuleAsDeclared(operationDescriptor, context), OwnerKind.IMPLEMENTATION); boolean isGetter = accessor.getSignature().getAsmMethod().getName().equals("get"); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index d6495acfafc..243e97e735e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -76,6 +76,7 @@ public class FunctionCodegen extends GenerationStateAware { functionDescriptor, false, isCallInsideSameClassAsDeclared(functionDescriptor, owner), + isCallInsideSameModuleAsDeclared(functionDescriptor, owner), owner.getContextKind()).getSignature(); generateMethod(f, method, true, null, functionDescriptor); } @@ -345,7 +346,7 @@ public class FunctionCodegen extends GenerationStateAware { MethodVisitor mv ) { if (jvmSignature == null) { - jvmSignature = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false, false, OwnerKind.IMPLEMENTATION).getSignature(); + jvmSignature = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false, false, false, OwnerKind.IMPLEMENTATION).getSignature(); } List paramDescrs = functionDescriptor.getValueParameters(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 92a1abb3e21..849b52cda25 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -791,7 +791,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { typeMapper.mapSignature(original.getName(), original).getAsmMethod(); Type[] argTypes = method.getArgumentTypes(); - String owner = typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(); + String owner = typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isCallInsideSameModuleAsDeclared(original, context)).getInternalName(); MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, bridge.getName().getName(), method.getDescriptor(), null, null); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { @@ -849,12 +849,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.load(0, OBJECT_TYPE); boolean hasBackingField = Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, original)); + boolean isInsideModule = isCallInsideSameModuleAsDeclared(original, context); if (original.getVisibility() == Visibilities.PRIVATE && hasBackingField) { - iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), + iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isInsideModule).getInternalName(), original.getName().getName(), originalMethod.getReturnType().getDescriptor()); } else { - iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), + iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isInsideModule).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor()); } @@ -891,12 +892,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { //noinspection AssignmentToForLoopParameter reg += argType.getSize(); } + boolean isInsideModule = isCallInsideSameModuleAsDeclared(original, context); if (original.getVisibility() == Visibilities.PRIVATE && original.getModality() == Modality.FINAL) { - iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), + iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isInsideModule).getInternalName(), original.getName().getName(), originalMethod.getArgumentTypes()[0].getDescriptor()); } else { - iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), + iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isInsideModule).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor()); } @@ -1354,6 +1356,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { inheritedFun, false, isCallInsideSameClassAsDeclared(inheritedFun, context), + isCallInsideSameModuleAsDeclared(inheritedFun, context), OwnerKind.IMPLEMENTATION).getSignature(); JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); int kotlinFlags = getFlagsForVisibility(fun.getVisibility()); @@ -1588,7 +1591,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } codegen.gen(initializer, type); // @todo write directly to the field. Fix test excloset.jet::test6 - JvmClassName owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION); + JvmClassName owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION, isCallInsideSameModuleAsDeclared(propertyDescriptor, codegen.context)); Type propType = typeMapper.mapType(jetType); StackValue.property(propertyDescriptor, owner, owner, propType, false, false, false, null, null, 0, 0, state).store(propType, iv); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 2d99cf10ef1..984d06a03f0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -212,7 +212,7 @@ public class PropertyCodegen extends GenerationStateAware { iv.visitFieldInsn( kind == OwnerKind.NAMESPACE ? GETSTATIC : GETFIELD, - typeMapper.getOwner(propertyDescriptor, kind).getInternalName(), + typeMapper.getOwner(propertyDescriptor, kind, isCallInsideSameModuleAsDeclared(propertyDescriptor, context)).getInternalName(), propertyDescriptor.getName().getName(), type.getDescriptor()); iv.areturn(type); @@ -296,7 +296,7 @@ public class PropertyCodegen extends GenerationStateAware { } iv.load(paramCode, type); iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? PUTSTATIC : PUTFIELD, - typeMapper.getOwner(propertyDescriptor, kind).getInternalName(), + typeMapper.getOwner(propertyDescriptor, kind, isCallInsideSameModuleAsDeclared(propertyDescriptor, context)).getInternalName(), propertyDescriptor.getName().getName(), type.getDescriptor()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java index 99bed1e22f7..f12b844a3b0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -62,12 +62,12 @@ public class JetTypeMapper extends BindingTraceAware { } @NotNull - public JvmClassName getOwner(DeclarationDescriptor descriptor, OwnerKind kind) { + public JvmClassName getOwner(DeclarationDescriptor descriptor, OwnerKind kind, boolean isInsideModule) { JetTypeMapperMode mapTypeMode = ownerKindToMapTypeMode(kind); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (containingDeclaration instanceof NamespaceDescriptor) { - return jvmClassNameForNamespace((NamespaceDescriptor) containingDeclaration, descriptor); + return jvmClassNameForNamespace((NamespaceDescriptor) containingDeclaration, descriptor, isInsideModule); } else if (containingDeclaration instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; @@ -122,7 +122,11 @@ public class JetTypeMapper extends BindingTraceAware { } @NotNull - private JvmClassName jvmClassNameForNamespace(@NotNull NamespaceDescriptor namespace, @NotNull DeclarationDescriptor descriptor) { + private JvmClassName jvmClassNameForNamespace( + @NotNull NamespaceDescriptor namespace, + @NotNull DeclarationDescriptor descriptor, + boolean insideModule + ) { StringBuilder r = new StringBuilder(); @@ -147,15 +151,10 @@ public class JetTypeMapper extends BindingTraceAware { r.append("/"); } - if (descriptor instanceof PropertyDescriptor) { - JetFile file = BindingContextUtils.getContainingFile(bindingContext, descriptor); - if (file != null) { - String internalName = NamespaceCodegen.getNamespacePartInternalName(file); - r.append(internalName.substring(r.length())); - } - else { - r.append(PackageClassUtils.getPackageClassName(namespace.getFqName())); - } + JetFile file = BindingContextUtils.getContainingFile(bindingContext, descriptor); + if (insideModule && file != null) { + String internalName = NamespaceCodegen.getNamespacePartInternalName(file); + r.append(internalName.substring(r.length())); } else { r.append(PackageClassUtils.getPackageClassName(namespace.getFqName())); @@ -450,6 +449,7 @@ public class JetTypeMapper extends BindingTraceAware { @NotNull FunctionDescriptor functionDescriptor, boolean superCall, boolean isInsideClass, + boolean isInsideModule, OwnerKind kind ) { final DeclarationDescriptor functionParent = functionDescriptor.getOriginal().getContainingDeclaration(); @@ -464,7 +464,7 @@ public class JetTypeMapper extends BindingTraceAware { JvmClassName thisClass; if (functionParent instanceof NamespaceDescriptor) { assert !superCall; - owner = jvmClassNameForNamespace((NamespaceDescriptor) functionParent, functionDescriptor); + owner = jvmClassNameForNamespace((NamespaceDescriptor) functionParent, functionDescriptor, isInsideModule); ownerForDefaultImpl = ownerForDefaultParam = owner; invokeOpcode = INVOKESTATIC; thisClass = null; diff --git a/compiler/testData/codegen/topLevelMemberInvocation/extensionFunction/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/extensionFunction/1.kt new file mode 100644 index 00000000000..f57bee466e0 --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/extensionFunction/1.kt @@ -0,0 +1,8 @@ +fun Int.test1() {} + +fun test2() { + 1.test1() +} + +// 2 INVOKESTATIC _DefaultPackage\$src\$1\$[\-]*[0-9]*\.test1 \(I\)V +// 1 INVOKESTATIC _DefaultPackage\$src\$1\$[\-]*[0-9]*\.test2 \(\)V \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage/1.kt new file mode 100644 index 00000000000..43df2e3d042 --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage/1.kt @@ -0,0 +1,6 @@ +package a + +fun test1() {} + +// 2 INVOKESTATIC a/APackage\$src\$1\$[\-]*[0-9]*\.test1 \(\)V +// 1 INVOKESTATIC b/BPackage\$src\$2\$[\-]*[0-9]*\.test2 \(\)V \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage/2.kt b/compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage/2.kt new file mode 100644 index 00000000000..31923bbe4ec --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage/2.kt @@ -0,0 +1,7 @@ +package b + +import a.test1 + +fun test2() { + test1() +} \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace/1.kt new file mode 100644 index 00000000000..01364d196e6 --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace/1.kt @@ -0,0 +1,4 @@ +fun test1() {} + +// 2 INVOKESTATIC _DefaultPackage\$src\$1\$[\-]*[0-9]*\.test1 \(\)V +// 1 INVOKESTATIC _DefaultPackage\$src\$2\$[\-]*[0-9]*\.test2 \(\)V \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace/2.kt b/compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace/2.kt new file mode 100644 index 00000000000..f127a8cf657 --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace/2.kt @@ -0,0 +1,3 @@ +fun test2() { + test1() +} \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/functionSamePackage/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/functionSamePackage/1.kt new file mode 100644 index 00000000000..26e8ae92fb0 --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/functionSamePackage/1.kt @@ -0,0 +1,8 @@ +fun test1() {} + +fun test2() { + test1() +} + +// 2 INVOKESTATIC _DefaultPackage\$src\$1\$[\-]*[0-9]*\.test1 \(\)V +// 1 INVOKESTATIC _DefaultPackage\$src\$1\$[\-]*[0-9]*\.test2 \(\)V \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/property/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/property/1.kt new file mode 100644 index 00000000000..ca7b4efb10d --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/property/1.kt @@ -0,0 +1,6 @@ +package a + +val prop = 1 + +// 2 INVOKESTATIC a/APackage\$src\$1\$[\-]*[0-9]*\.getProp \(\)I +// 1 GETSTATIC a/APackage\$src\$1\$[\-]*[0-9]*\.prop \: I \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/property/2.kt b/compiler/testData/codegen/topLevelMemberInvocation/property/2.kt new file mode 100644 index 00000000000..10c079660e8 --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/property/2.kt @@ -0,0 +1,7 @@ +package b + +import a.prop + +fun test() { + prop +} \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter/1.kt new file mode 100644 index 00000000000..a60672a7b5c --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter/1.kt @@ -0,0 +1,9 @@ +package a + +val prop: Int = 0 + get() { + return $prop + 1 + } + +// 2 INVOKESTATIC a/APackage\$src\$1\$[\-]*[0-9]*\.getProp \(\)I +// 1 GETSTATIC a/APackage\$src\$1\$[\-]*[0-9]*\.prop \: I \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter/2.kt b/compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter/2.kt new file mode 100644 index 00000000000..10c079660e8 --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter/2.kt @@ -0,0 +1,7 @@ +package b + +import a.prop + +fun test() { + prop +} \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/twoModules/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/twoModules/1.kt new file mode 100644 index 00000000000..9948096c08d --- /dev/null +++ b/compiler/testData/codegen/topLevelMemberInvocation/twoModules/1.kt @@ -0,0 +1,12 @@ +package b + +import a.test1 +import a.prop + +fun test2() { + test1() + prop +} + +// 1 a/APackage\.test1 \(\)V +// 1 a/APackage\.getProp \(\)I \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/twoModules/a.jar b/compiler/testData/codegen/topLevelMemberInvocation/twoModules/a.jar new file mode 100644 index 00000000000..e14bb3330c2 Binary files /dev/null and b/compiler/testData/codegen/topLevelMemberInvocation/twoModules/a.jar differ diff --git a/compiler/tests/org/jetbrains/jet/codegen/AbstractBytecodeTextTest.java b/compiler/tests/org/jetbrains/jet/codegen/AbstractBytecodeTextTest.java index 5e7f9a2013b..5f9a79aba38 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/AbstractBytecodeTextTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/AbstractBytecodeTextTest.java @@ -38,14 +38,14 @@ public abstract class AbstractBytecodeTextTest extends CodegenTestCase { countAndCompareActualOccurrences(expected); } - private void countAndCompareActualOccurrences(@NotNull List expectedOccurrences) { + protected void countAndCompareActualOccurrences(@NotNull List expectedOccurrences) { StringBuilder expected = new StringBuilder(); StringBuilder actual = new StringBuilder(); String text = generateToText(); for (OccurrenceInfo info : expectedOccurrences) { expected.append(info.numberOfOccurrences).append(" ").append(info.needle).append("\n"); - int actualCount = StringUtil.getOccurrenceCount(text, info.needle); + int actualCount = StringUtil.findMatches(text, Pattern.compile("(" + info.needle + ")")).size(); actual.append(actualCount).append(" ").append(info.needle).append("\n"); } @@ -59,7 +59,7 @@ public abstract class AbstractBytecodeTextTest extends CodegenTestCase { } @NotNull - private List readExpectedOccurrences(@NotNull String filename) throws Exception { + protected List readExpectedOccurrences(@NotNull String filename) throws Exception { List result = new ArrayList(); String[] lines = FileUtil.loadFile(new File(filename), true).split("\n"); @@ -75,7 +75,7 @@ public abstract class AbstractBytecodeTextTest extends CodegenTestCase { return result; } - private static class OccurrenceInfo { + protected static class OccurrenceInfo { private final int numberOfOccurrences; private final String needle; diff --git a/compiler/tests/org/jetbrains/jet/codegen/AbstractTopLevelMembersInvocationTest.java b/compiler/tests/org/jetbrains/jet/codegen/AbstractTopLevelMembersInvocationTest.java new file mode 100644 index 00000000000..e557d279423 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/AbstractTopLevelMembersInvocationTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2013 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; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.ConfigurationKind; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.TestJdkKind; +import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public abstract class AbstractTopLevelMembersInvocationTest extends AbstractBytecodeTextTest { + + public void doTest(@NotNull String filename) throws Exception { + final List sourceFiles = new ArrayList(2); + final List classPath = new ArrayList(1); + + FileUtil.processFilesRecursively(new File(filename), new Processor() { + @Override + public boolean process(File file) { + if (file.getName().endsWith(".kt")) { + sourceFiles.add(file.getPath().substring("compiler/testData/codegen/".length())); + } + else if (file.getName().endsWith(".jar")) { + classPath.add(file); + } + return true; + } + }); + + assert !sourceFiles.isEmpty() : getTestName(true) + " should contains at least one .kt file"; + Collections.sort(sourceFiles); + + myEnvironment = new JetCoreEnvironment(getTestRootDisposable(), JetTestUtils.compilerConfigurationForTests( + ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK, Arrays.asList(JetTestUtils.getAnnotationsJar()), classPath)); + + loadFiles(sourceFiles.toArray(new String[sourceFiles.size()])); + + List expected = readExpectedOccurrences("compiler/testData/codegen/" + sourceFiles.get(0)); + countAndCompareActualOccurrences(expected); + } +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java index 1e7a401354a..739ac38c72b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -159,7 +159,8 @@ public class PrimitiveTypesTest extends CodegenTestCase { public void testCastOnStack() throws Exception { loadText("fun foo(): Double = System.currentTimeMillis().toDouble()"); - final Method main = generateFunction(); + final Class mainClass = generateNamespaceSrcClass(); + final Method main = mainClass.getDeclaredMethod("foo"); double currentTimeMillis = (double) System.currentTimeMillis(); double result = (Double) main.invoke(null); double delta = Math.abs(currentTimeMillis - result); diff --git a/compiler/tests/org/jetbrains/jet/codegen/TopLevelMembersInvocationTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/TopLevelMembersInvocationTestGenerated.java new file mode 100644 index 00000000000..3e114b97e42 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/TopLevelMembersInvocationTestGenerated.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010-2013 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; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.codegen.AbstractTopLevelMembersInvocationTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/codegen/topLevelMemberInvocation") +public class TopLevelMembersInvocationTestGenerated extends AbstractTopLevelMembersInvocationTest { + public void testAllFilesPresentInTopLevelMemberInvocation() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/topLevelMemberInvocation"), Pattern.compile("^(.+)$"), false); + } + + @TestMetadata("extensionFunction") + public void testExtensionFunction() throws Exception { + doTest("compiler/testData/codegen/topLevelMemberInvocation/extensionFunction"); + } + + @TestMetadata("functionDifferentPackage") + public void testFunctionDifferentPackage() throws Exception { + doTest("compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage"); + } + + @TestMetadata("functionInMultiFileNamespace") + public void testFunctionInMultiFileNamespace() throws Exception { + doTest("compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace"); + } + + @TestMetadata("functionSamePackage") + public void testFunctionSamePackage() throws Exception { + doTest("compiler/testData/codegen/topLevelMemberInvocation/functionSamePackage"); + } + + @TestMetadata("property") + public void testProperty() throws Exception { + doTest("compiler/testData/codegen/topLevelMemberInvocation/property"); + } + + @TestMetadata("propertyWithGetter") + public void testPropertyWithGetter() throws Exception { + doTest("compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter"); + } + + @TestMetadata("twoModules") + public void testTwoModules() throws Exception { + doTest("compiler/testData/codegen/topLevelMemberInvocation/twoModules"); + } + +} diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 92938f14b16..d7df9391208 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve; import org.jetbrains.jet.checkers.AbstractJetPsiCheckerTest; import org.jetbrains.jet.codegen.AbstractBytecodeTextTest; import org.jetbrains.jet.codegen.AbstractCheckLocalVariablesTableTest; +import org.jetbrains.jet.codegen.AbstractTopLevelMembersInvocationTest; import org.jetbrains.jet.codegen.defaultConstructor.AbstractDefaultConstructorCodegenTest; import org.jetbrains.jet.codegen.flags.AbstractWriteFlagsTest; import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest; @@ -105,6 +106,13 @@ public class GenerateTests { testModel("compiler/testData/codegen/bytecodeText") ); + generateTest( + "compiler/tests/", + "TopLevelMembersInvocationTestGenerated", + AbstractTopLevelMembersInvocationTest.class, + new SimpleTestClassModel(new File("compiler/testData/codegen/topLevelMemberInvocation"), false, Pattern.compile("^(.+)$"), "doTest") + ); + generateTest( "compiler/tests/", "CheckLocalVariablesTableTestGenerated",