Community
Participate
Working Groups
A specific combination of team nesting, protected role and private method yields a bogus error "Cannot externalize non-public role..." as witnessed by test0a1a_privateRoleMethod10(). This problem is probably reported against a synthetic bridge method.
Created attachment 177369 [details] fix part 1 This is indeed caused by those bridges that a callout needs for accessing private methods of a role bound as the callout's base method. While fixing this issue I decided to switch generation of role method bridges from an AST strategy to a new kind of synthetic method bindings: * new class: SyntheticRoleBridgeMethodBinding * create synthetic bridges right in STB.resolveTypesFor(MethodBinding) * CalloutImplementor creates a special MessageSend - pretend to directly access the private role method - pre-set the bridge method as syntheticAccessor for resolve - use that accessor for codegen * for method lookup, if decapsulation is allowed seek private role method in the class part * collect new synthetics in STB.syntheticMethods(), too for code gen. * SyntheticRoleBridgeMethodBinding directly creates its body as bytecode * don't copy inherited role bridges, but generate anew + a few more small refactorings and cleanup still missing: do the same for bridges to private role fields (also via callout)
Created attachment 177507 [details] fix part 2 Part two which extends the previous solution to cover also access to fields. * no longer generate AST for bridges to field (team-level) * store fake method bindings of what the OTRE will generate in the field model (inner level static accessor); re-use if possible * STB.resolveTypeFor(FieldBinding) triggers creation of both levels of bridges * STB.findOuterRoleMethodSyntheticAccessor now recognizes the faked OTRE methods in order to proceed to the outer level Fine points about the signatures of these bridge methods: * at team-level the role arg may require weakening to support overriding (applies to method-bridges, too) * the OTRE-generated inner bridge (static role method) uses the class-part for the role arg, outer accessor is declared with the ifc-part and casts internally * when transforming c-t-f, switch between using base instance vs. class as the receiver - when using a synth accessor pretend we are accessing the base instance - only for direct access replace instance with a static class reference * during code-gen for callout-using-synth-accessor - c-t-f: replace receiver with a synth team instance, role instance is a regular argument - c-t-m: add synth team instance as a receiver, original role receiver will become an implicit argument (in this case synth bridges keep the original method signature) Also contains an improvement in ConstantPoolObjectMapper.mapClass: * also map base-classes which are subject to implicit specialization (see "playedBy R<@base>" in test1126_nestingAndLayering4pf)
Part 1 was committed as r737, part 2 is r740.
additional small fixes: - r741: fix a logic-error which caused a build failure. - r742: fix an AIOOBE which caused a build failure (RenameTypeAdaptor.RenameTypeProcessor.CONFINED) - r743: don't produce setter synth method for final fields fixes broken bytecode in CompletionAdaptor.OverrideRoleCompletionProposal caused by incompatible signatures (w/ vs. w/o role arg) witness is test0a9_staticFinalRoleField4
Verified using I201009211735
.