Move visibility check for toplevel private declarations to Visibilities.PRIVATE and fix it.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,6 @@ public interface Errors {
|
||||
DiagnosticFactory3<JetSimpleNameExpression, DeclarationDescriptor, Visibility, DeclarationDescriptor> INVISIBLE_REFERENCE =
|
||||
DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory3<PsiElement, DeclarationDescriptor, Visibility, DeclarationDescriptor> INVISIBLE_MEMBER = DiagnosticFactory3.create(ERROR, CALL_ELEMENT);
|
||||
DiagnosticFactory3<PsiElement, DeclarationDescriptor, Visibility, JetFile> ACCESS_TO_PRIVATE_TOP_LEVEL_FROM_ANOTHER_FILE = DiagnosticFactory3.create(ERROR, CALL_ELEMENT);
|
||||
|
||||
DiagnosticFactory1<JetElement, Collection<ClassDescriptor>> PLATFORM_CLASS_MAPPED_TO_KOTLIN = DiagnosticFactory1.create(WARNING);
|
||||
|
||||
|
||||
+3
-4
@@ -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();
|
||||
|
||||
|
||||
@@ -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<Named> = Renderer { it.getName().asString() }
|
||||
|
||||
public val NAME_OF_PARENT_OR_FILE: Renderer<DeclarationDescriptor> = Renderer {
|
||||
if (DescriptorUtils.isTopLevelDeclaration(it) && it is DeclarationDescriptorWithVisibility && it.visibility == Visibilities.PRIVATE) {
|
||||
"file"
|
||||
}
|
||||
else {
|
||||
"'" + it.containingDeclaration!!.name + "'"
|
||||
}
|
||||
}
|
||||
|
||||
public val ELEMENT_TEXT: Renderer<PsiElement> = Renderer { it.getText() }
|
||||
|
||||
public val DECLARATION_NAME: Renderer<JetNamedDeclaration> = Renderer { it.getNameAsSafeName().asString() }
|
||||
@@ -87,8 +95,6 @@ public object Renderers {
|
||||
|
||||
public val RENDER_TYPE: Renderer<JetType> = Renderer { DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(it) }
|
||||
|
||||
public val RENDER_FILE: Renderer<JetFile> = Renderer { it.name }
|
||||
|
||||
public val RENDER_POSITION_VARIANCE: Renderer<Variance> = Renderer {
|
||||
variance: Variance ->
|
||||
when (variance) {
|
||||
@@ -405,4 +411,4 @@ public object Renderers {
|
||||
}
|
||||
append("(").append(renderTypes(inferenceErrorData.valueArgumentsTypes)).append(")")
|
||||
}.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<AdditionalTypeChecker>()
|
||||
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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-66
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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/");
|
||||
|
||||
+19
@@ -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
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
private fun foo() = 1
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package test
|
||||
|
||||
fun usage() {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
fun usage() {
|
||||
println(foo())
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package test
|
||||
|
||||
fun usage() {
|
||||
}
|
||||
Reference in New Issue
Block a user