diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/kotlin/cfg/JetFlowInformationProvider.java index b2407fa2bbf..0a2c3b9eb37 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/JetFlowInformationProvider.java @@ -432,7 +432,7 @@ public class JetFlowInformationProvider { if (Visibilities.isVisible(receiverValue, variableDescriptor, descriptor) && setterDescriptor != null && !Visibilities.isVisible(receiverValue, setterDescriptor, descriptor)) { report(Errors.INVISIBLE_SETTER.on(expression, variableDescriptor, setterDescriptor.getVisibility(), - variableDescriptor.getContainingDeclaration()), ctxt); + setterDescriptor), ctxt); return true; } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index a36130d9e87..d3b0c16b258 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -71,7 +71,6 @@ public interface Errors { DiagnosticFactory3 INVISIBLE_REFERENCE = DiagnosticFactory3.create(ERROR); DiagnosticFactory3 INVISIBLE_MEMBER = DiagnosticFactory3.create(ERROR, CALL_ELEMENT); - DiagnosticFactory3 ACCESS_TO_PRIVATE_TOP_LEVEL_FROM_ANOTHER_FILE = DiagnosticFactory3.create(ERROR, CALL_ELEMENT); DiagnosticFactory1> PLATFORM_CLASS_MAPPED_TO_KOTLIN = DiagnosticFactory1.create(WARNING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index c2ea735c00c..129507b4273 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -109,8 +109,8 @@ public class DefaultErrorMessages { static { MAP.put(UNRESOLVED_REFERENCE, "Unresolved reference: {0}", ELEMENT_TEXT); - MAP.put(INVISIBLE_REFERENCE, "Cannot access ''{0}'': it is ''{1}'' in ''{2}''", NAME, TO_STRING, NAME); - MAP.put(INVISIBLE_MEMBER, "Cannot access ''{0}'': it is ''{1}'' in ''{2}''", NAME, TO_STRING, NAME); + MAP.put(INVISIBLE_REFERENCE, "Cannot access ''{0}'': it is ''{1}'' in {2}", NAME, TO_STRING, NAME_OF_PARENT_OR_FILE); + MAP.put(INVISIBLE_MEMBER, "Cannot access ''{0}'': it is ''{1}'' in {2}", NAME, TO_STRING, NAME_OF_PARENT_OR_FILE); MAP.put(REDECLARATION, "Redeclaration: {0}", STRING); MAP.put(NAME_SHADOWING, "Name shadowed: {0}", STRING); @@ -261,7 +261,7 @@ public class DefaultErrorMessages { MAP.put(VAL_REASSIGNMENT, "Val cannot be reassigned", NAME); MAP.put(SETTER_PROJECTED_OUT, "Setter for ''{0}'' is removed by type projection", NAME); - MAP.put(INVISIBLE_SETTER, "Cannot assign to ''{0}'': the setter is ''{1}'' in ''{2}''", NAME, TO_STRING, NAME); + MAP.put(INVISIBLE_SETTER, "Cannot assign to ''{0}'': the setter is ''{1}'' in {2}", NAME, TO_STRING, NAME_OF_PARENT_OR_FILE); MAP.put(INITIALIZATION_BEFORE_DECLARATION, "Variable cannot be initialized before declaration", NAME); MAP.put(VARIABLE_EXPECTED, "Variable expected"); @@ -658,7 +658,6 @@ public class DefaultErrorMessages { 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"); - MAP.put(ACCESS_TO_PRIVATE_TOP_LEVEL_FROM_ANOTHER_FILE, "Cannot access ''{0}'': it is ''{1}'' in ''{2}''", NAME, TO_STRING, RENDER_FILE); MAP.setImmutable(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt index 04cc406e9f8..4198e323d99 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.diagnostics.rendering.TabledDescriptorRenderer.newTa import org.jetbrains.kotlin.diagnostics.rendering.TabledDescriptorRenderer.newText import org.jetbrains.kotlin.psi.JetClass import org.jetbrains.kotlin.psi.JetClassOrObject -import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetNamedDeclaration import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.Renderer @@ -73,6 +72,15 @@ public object Renderers { public val NAME: Renderer = Renderer { it.getName().asString() } + public val NAME_OF_PARENT_OR_FILE: Renderer = Renderer { + if (DescriptorUtils.isTopLevelDeclaration(it) && it is DeclarationDescriptorWithVisibility && it.visibility == Visibilities.PRIVATE) { + "file" + } + else { + "'" + it.containingDeclaration!!.name + "'" + } + } + public val ELEMENT_TEXT: Renderer = Renderer { it.getText() } public val DECLARATION_NAME: Renderer = Renderer { it.getNameAsSafeName().asString() } @@ -87,8 +95,6 @@ public object Renderers { public val RENDER_TYPE: Renderer = Renderer { DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(it) } - public val RENDER_FILE: Renderer = Renderer { it.name } - public val RENDER_POSITION_VARIANCE: Renderer = Renderer { variance: Variance -> when (variance) { @@ -405,4 +411,4 @@ public object Renderers { } append("(").append(renderTypes(inferenceErrorData.valueArgumentsTypes)).append(")") }.toString() -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt index db566c8c2df..b1d832f79e3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt @@ -348,7 +348,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa val visibleDescriptors = descriptors.filter { isVisible(it, shouldBeVisibleFrom, inImport) } if (visibleDescriptors.isEmpty()) { val descriptor = descriptors.first() as DeclarationDescriptorWithVisibility - trace.report(Errors.INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.visibility, descriptor.containingDeclaration!!)) + trace.report(Errors.INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.visibility, descriptor)) } else if (visibleDescriptors.size() > 1) { trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, visibleDescriptors) @@ -382,7 +382,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa } if (descriptor is DeclarationDescriptorWithVisibility && !isVisible(descriptor, shouldBeVisibleFrom, inImport)) { - trace.report(Errors.INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.visibility, descriptor.containingDeclaration!!)) + trace.report(Errors.INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.visibility, descriptor)) } if (isQualifier) { @@ -411,4 +411,4 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa } return Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, descriptor, shouldBeVisibleFrom) } -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt index a6ca4b84627..269c5ff06c1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.resolve import org.jetbrains.kotlin.container.StorageComponentContainer import org.jetbrains.kotlin.container.useInstance import org.jetbrains.kotlin.resolve.calls.checkers.* -import org.jetbrains.kotlin.resolve.validation.AccessToPrivateTopLevelSymbolValidator import org.jetbrains.kotlin.resolve.validation.DeprecatedSymbolValidator import org.jetbrains.kotlin.resolve.validation.OperatorValidator import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator @@ -42,7 +41,7 @@ public abstract class TargetPlatform( private val DEFAULT_DECLARATION_CHECKERS = listOf(DataClassAnnotationChecker(), ConstModifierChecker, UnderscoreChecker, OperatorModifierChecker()) private val DEFAULT_CALL_CHECKERS = listOf(CapturingInClosureChecker(), InlineCheckerWrapper(), ReifiedTypeParameterSubstitutionChecker()) private val DEFAULT_TYPE_CHECKERS = emptyList() -private val DEFAULT_VALIDATORS = listOf(DeprecatedSymbolValidator(), AccessToPrivateTopLevelSymbolValidator(), OperatorValidator()) +private val DEFAULT_VALIDATORS = listOf(DeprecatedSymbolValidator(), OperatorValidator()) public open class PlatformConfigurator( @@ -69,4 +68,4 @@ public open class PlatformConfigurator( additionalAnnotationCheckers.forEach { useInstance(it) } } } -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/AbstractTracingStrategy.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/AbstractTracingStrategy.java index f7747eb3395..7ba54f0fdf7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/AbstractTracingStrategy.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/AbstractTracingStrategy.java @@ -194,7 +194,7 @@ public abstract class AbstractTracingStrategy implements TracingStrategy { @Override public void invisibleMember(@NotNull BindingTrace trace, @NotNull DeclarationDescriptorWithVisibility descriptor) { - trace.report(INVISIBLE_MEMBER.on(call.getCallElement(), descriptor, descriptor.getVisibility(), descriptor.getContainingDeclaration())); + trace.report(INVISIBLE_MEMBER.on(call.getCallElement(), descriptor, descriptor.getVisibility(), descriptor)); } @Override diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/validation/AccessToPrivateTopLevelSymbolValidator.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/validation/AccessToPrivateTopLevelSymbolValidator.kt deleted file mode 100644 index f005dcc6b54..00000000000 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/validation/AccessToPrivateTopLevelSymbolValidator.kt +++ /dev/null @@ -1,66 +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.resolve.validation - -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.diagnostics.Errors -import org.jetbrains.kotlin.psi.JetElement -import org.jetbrains.kotlin.psi.JetFile -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.BindingTrace -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils -import org.jetbrains.kotlin.resolve.DescriptorUtils - -public class AccessToPrivateTopLevelSymbolValidator : SymbolUsageValidator { - override fun validateCall(targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement) { - val descriptor = - if (DescriptorUtils.isTopLevelDeclaration(targetDescriptor)) targetDescriptor - else DescriptorUtils.getContainingClass(targetDescriptor) - - descriptor?.let { - reportIfNeeded(it, trace, element) - } - } - - override fun validateTypeUsage(targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement) = - reportIfNeeded(targetDescriptor, trace, element) - - private fun reportIfNeeded(descriptor: DeclarationDescriptor, trace: BindingTrace, element: PsiElement) { - if (descriptor !is DeclarationDescriptorWithVisibility || - descriptor.visibility != Visibilities.PRIVATE || - !DescriptorUtils.isTopLevelDeclaration(descriptor)) return - - if (descriptor is PropertySetterDescriptor && descriptor.correspondingProperty.visibility == Visibilities.PRIVATE) return - - if (element !is JetElement) return - - DescriptorToSourceUtils.getContainingFile(descriptor)?.let { - val jetFile = element.containingFile as? JetFile ?: return - - val currentPackageViewDescriptor = trace.bindingContext.get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, jetFile) - if (currentPackageViewDescriptor != null && !DescriptorUtils.areInSameModule(currentPackageViewDescriptor, descriptor)) return - - val packageFqName = DescriptorUtils.getParentOfType(descriptor, PackageFragmentDescriptor::class.java)?.fqName - if (packageFqName != currentPackageViewDescriptor?.fqName) return - - if (jetFile != it) { - trace.report(Errors.ACCESS_TO_PRIVATE_TOP_LEVEL_FROM_ANOTHER_FILE.on(element, descriptor, descriptor.visibility, it)) - } - } - } -} \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/Visibilities.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/Visibilities.java index 5e4ee02f7bb..b5d886c1f16 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/Visibilities.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/Visibilities.java @@ -36,6 +36,13 @@ public class Visibilities { @Override public boolean isVisible(@NotNull ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { + if (DescriptorUtils.isTopLevelDeclaration(what)) { + SourceFile fromContainingFile = DescriptorUtils.getContainingSourceFile(from); + if (fromContainingFile != SourceFile.NO_SOURCE_FILE) { + return fromContainingFile.equals(DescriptorUtils.getContainingSourceFile(what)); + } + } + DeclarationDescriptor parent = what; while (parent != null) { parent = parent.getContainingDeclaration(); diff --git a/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java b/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java index d2f1a958083..53efe232f9d 100644 --- a/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java +++ b/jps-plugin/test/org/jetbrains/kotlin/jps/build/IncrementalJpsTestGenerated.java @@ -599,6 +599,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest { doTest(fileName); } + @TestMetadata("topLevelPrivateValUsageAdded") + public void testTopLevelPrivateValUsageAdded() throws Exception { + String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/"); + doTest(fileName); + } + @TestMetadata("traitClassObjectConstantChanged") public void testTraitClassObjectConstantChanged() throws Exception { String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/traitClassObjectConstantChanged/"); diff --git a/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/build.log b/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/build.log new file mode 100644 index 00000000000..992db6b386d --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/build.log @@ -0,0 +1,19 @@ +Cleaning output files: +out/production/module/META-INF/module.kotlin_module +out/production/module/test/TestPackage.class +out/production/module/test/UsageKt.class +End of files +Compiling files: +src/usage.kt +End of files +COMPILATION FAILED +Cannot access 'foo': it is 'private' in file + + +Cleaning output files: +out/production/module/test/FooKt.class +End of files +Compiling files: +src/foo.kt +src/usage.kt +End of files diff --git a/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/foo.kt b/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/foo.kt new file mode 100644 index 00000000000..5715a620ced --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/foo.kt @@ -0,0 +1,3 @@ +package test + +private fun foo() = 1 diff --git a/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/usage.kt b/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/usage.kt new file mode 100644 index 00000000000..6bdc11105c7 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/usage.kt @@ -0,0 +1,4 @@ +package test + +fun usage() { +} diff --git a/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/usage.kt.new.1 b/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/usage.kt.new.1 new file mode 100644 index 00000000000..e62a20dd934 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/usage.kt.new.1 @@ -0,0 +1,5 @@ +package test + +fun usage() { + println(foo()) +} diff --git a/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/usage.kt.new.2 b/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/usage.kt.new.2 new file mode 100644 index 00000000000..6bdc11105c7 --- /dev/null +++ b/jps-plugin/testData/incremental/pureKotlin/topLevelPrivateValUsageAdded/usage.kt.new.2 @@ -0,0 +1,4 @@ +package test + +fun usage() { +}