Kotlin: explicitly set visibility to internal for elements nested in other internal types#1801
Open
pwrobeldev wants to merge 23 commits intomasterfrom
Open
Kotlin: explicitly set visibility to internal for elements nested in other internal types#1801pwrobeldev wants to merge 23 commits intomasterfrom
pwrobeldev wants to merge 23 commits intomasterfrom
Conversation
Hsilgos
previously approved these changes
Feb 19, 2026
This is not a functional change. The logic is preserved. All tests work in the identical way. This change introduces a new function, which will be used later for all types. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
The logic was simplified to use 'return when' statement. This improves readability and prepares for further changes. This is not a functional change. The code works as previously. All tests pass. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
…internal This change ensures that all elements nested in internal types hierarchy are internal and annotated with JvmSyntetic. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
All elements nested in internal types hierarchy are internal. This does not apply to direct members of interfaces. According to Kotlin rules such types cannot be internal. However, such direct nested elements like functions and properties should use 'JvmSynthetic'. This will be fixed in the next commit. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
…pile
The previous changes ensure that more elements are not accessible in Java.
The following errors were visible -- the test cases were removed, because
with the new handling of nested internal the compilation error was expected.
```
> Task :functional:compileReleaseUnitTestJavaWithJavac FAILED
/functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:57: error: cannot find symbol
SomeInternalClassWithMembers someObject = SomeInternalClassWithMembers.create();
^
symbol: method create()
location: class SomeInternalClassWithMembers
/functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:58: error: cannot find symbol
assertEquals(987, someObject.someFunction());
^
symbol: method someFunction()
location: variable someObject of type SomeInternalClassWithMembers
/functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:63: error: cannot find symbol
assertEquals(765, SomeInternalClassWithMembers.someStaticFunction());
^
symbol: method someStaticFunction()
location: class SomeInternalClassWithMembers
/functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:68: error: cannot find symbol
SomeInternalStructWithMembers someObject = SomeInternalStructWithMembers.create();
^
symbol: method create()
location: class SomeInternalStructWithMembers
/functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:69: error: cannot find symbol
assertEquals(123, someObject.someInteger);
^
symbol: variable someInteger
location: variable someObject of type SomeInternalStructWithMembers
/functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:70: error: cannot find symbol
assertEquals(456, someObject.someLong);
^
symbol: variable someLong
location: variable someObject of type SomeInternalStructWithMembers
/functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:75: error: cannot find symbol
SomeInternalStructWithMembers someObject = SomeInternalStructWithMembers.create();
^
symbol: method create()
location: class SomeInternalStructWithMembers
/functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:76: error: cannot find symbol
assertEquals(32, someObject.someFunction());
^
symbol: method someFunction()
location: variable someObject of type SomeInternalStructWithMembers
```
Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
The logic will be handled in dedicated classes for resolving synthetic annotation and visibility. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
Some elements cannot use internal keyword even though conceptually they are internal. A good example are direct children elements of interfaces. Kotlin interface disallows internal elements as the direct children elements. Even though such children elements are not visible when accessed from Kotlin (because interface is internal), in Java they are accessible. To remove them from Java we will need to annotate them as synthetic via annotation. We need to have a way to nicely check whether element should be annotated as synthetic instead of having logic in mustache template. This change introduces new class, which checks for the conceptual internal visibility. The new class is applied in KotlinVisibilityResolver. No changes in smoke tests are present -- the logic is preserved. In next commits the new class will be used to create synthetic resolver. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
In the past we had special logic for properties getters/setters when resolving visibility for extensions. The extensions have been removed and the special logic is a dead code. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
This allows to minimize the logic in mustache files. Moreover, the JvmSynthetic is used for elements defined in internal interfaces and internal lambda. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
Still, the synthetic annotation is missing for properties. This will be adjusted in the next commit. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
…pile Due to usage of jvm synthetic for functions of internal interfaces the interoperability cases stopped to compile -- functions in such interfaces are not visible for Java now. ``` > Task :functional:compileReleaseUnitTestJavaWithJavac FAILED /functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:34: error: method does not override or implement a method from a supertype @OverRide ^ /functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:39: error: method does not override or implement a method from a supertype @OverRide ``` Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
The properties should also be synthetic to hide them from Java. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
This hides them from Java. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
…aces Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
In Kotlin the internal interface can be used and fields can be overridden. Similar example was implemented in Java, but it did not compile -- we could not override the required methods. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
The test case called 'internalFieldOfStructCanBeAccessed' initially
used internal fields, but the usage was removed when it stopped to
compile.
The fields 'someInteger' and 'someLong' are public in public type:
```
struct SomeStructWithInternalMembers {
someInteger: Int
someLong: Long
```
Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
This commit brings new smoke tests related to elements nested in the internal class in Kotlin. The expected result is: "ALL NESTED ELEMENTS ARE TREATED AS INTERNAL". One finding, that will be fixed in upcoming commits: - the 'error' field of internal exception is not annotated as synthetic -> this must be adjusted Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
This commit brings functional tests used to validate if nested elements (including multi-level nesting) in internal class can be accessed and there are no runtime problems with symbols. This commit is implementation of tests similar to the smoke tests introduced in the previous commit. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
This commit adjusts the mustache template to generate synthetic annotation for exceptions when they are internal. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
When exceptions are internal the synthetic annotation is used to hide the field. Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
…erop test
Because we generate 'JvmSynthetic' for exception fields, the compilation error
was trigerred.
```
/functional/android/src/test/java/com/here/android/test/VisibilityAttributeTest.java:76: error: cannot find symbol
assertEquals(exception.error, SomeInternalEnum.ONE);
^
symbol: variable error
location: variable exception of type SomethingBadHappenedException
```
Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
Signed-off-by: Patryk Wrobel <183546751+pwrobeldev@users.noreply.github.com>
1c41b27 to
1384afe
Compare
Hsilgos
approved these changes
Feb 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
---------- Motivation ----------
When Kotlin code is accessed from Java, then 'internal' elements become public.
In our mustache templates we annotate internal functions, properties and fields via
internal and
JvmSynthetic. The latter removes such element altogether for Javacompiler.
However, if we have elements not annotated as
@Internalin some internal type e.g.:Then in Java the
bar()function was accessible. The problem did not exist for Kotlin.---------- Solution ----------
Explicitly treat each element nested in another internal type like it is internal.
This change introduces the following:
KotlinInternalVisibilityPredicatewhich providesisConceptuallyInternal()function that checks if element is internal or is nested in some internal types.KotlinVisibilityResolverto resolve visibility to 'internal' for conceptually internal elements that are not direct elements of interfaces.KotlinSyntheticResolverclass that is used to resolve string when element needsJvmSyntheticannotation and is conceptually internal --> direct children of interface cannot beinternalin Kotlin, but can useJvmSyntheticto remove them from Java.