Community
Participate
Working Groups
Currently OTTypeHierarchy.getSuperclass(IType) throws UnsupportedOperationException for roles because roles have multiple supers. However, too many parts of the JDT rely on this functions. So we should try harder to implement that method in a way the truthfully reflects the semantics of OT/J. Given that we implicitly support a linearization of superclasses we might use IType wrappers that internally store the full superclass graph together with a cursor where in this hierarchy we are while ascending using getSuperclass(IType).
Initial work on this issue shows that it should be much easier to replace OTTypeHierarchy with an adaptation layer on top of the original TypeHierarchy. Adjusting bug title to reflect the change in strategy.
Created attachment 176486 [details] proposed implementation This is the initial implementation of an OT/J-based alternative to the old OTTypeHierarchy: * New Team OTTypeHiearchies adapts TypeHierarchy and friends - role OTHierarchyBuilder intercepts new join point builder.hookableConnect, in order to connect types along implicit inheritance. - nested team OTTypeHierarchy intercepts several top-level queries of TypeHiearchy in order to handle the following: - unwrap OTTypes - filter/substitute phantom roles in result - compute superclasses/supertypes in considering implicit inheritance, too. - nested role OTTypeHierarchy.ConnectedType contains the additional wiring - direct tsupers, all known tsubs, linearized tsupers, root of chain - phantom flag, enum-tag of where in the hierarchy we are (relative to focus type) - key trick is to intercept TypeHierarchy.getSuperclass() and answer the next element from the linearized list of tsupers (as looking from focus type) - the team provides several API methods for additional queries (actual hierarchy is passed as an argument). * Prepare core classes for adaptation - type hierarchy unwraps any OTTypes - IndexBasedHierarchyBuilder additionally traverses from roles to their enclosing team to cover team inheritance and thus implicit inheritance. TODO: check if this is sufficient in the case of role files. - HierarchyResolver & HierarchyBuilder: - swaps order: first completeTypeBindings and only then report (rememberAllTypes), to ensure copied roles are captured, too. - for purely copied roles create a HierarchyType as the IGenericType - pass more information into builder.connect (new wrapper hookableConnect), which serves as a join point for the OTTypeHierarchies team: tsuper classes, phantom flags, and the original compiler bindings - greatly simplify subTypeOfType by using roleModel.getTSuperRoleBindings() * Extend super-ref entries in index to include AccRole (incr. index version) Note that the hierarchy works slightly different for the focus types vs. its sub/supertypes: * for types below the focus type, no supertypes that are unrelated to the focus type will be answered. Single remain issue is witnessed as a regression in CompleteRoleHierarchyWithClasses.testGetAllSuperclasses_ofImplSuperSuperRole() When querying all supertypes (or classes) of a type above the focus role, after traversing tsupers the regular supers of the focus type will be answered.
Patch has been committed as r676/r677 (plus a little update in r678). OT hierarchy tests have been migrated in r679: Migrate all OT hierarchy tests to the new OT/J based implementation. Changes in test cases: - OTSuperTypeHierarchyTest013 has a clash of incompatible "extends", don't expect all these types to be reported as superclasses - OTSuperTypeHierarchyTest011: fix handle for nested phantom role & test it - OTSuperTypeHierarchyTest009: expect new behavior of getSuperclass - OTSuperTypeHierarchyTest008: new tests for type below the focus type - OTSuperTypeHierarchyTest007: bugfix. - OTSuperTypeHierarchyTest001: new test for linearization through repeated calls to getSuperclass() - OTSubTypeHierarchyTest017: several bugfixes - type not a subtype of query type - type is indirect subtype additional tests (phantomMode) - OTSubTypeHierarchyTest011: bugfix: type is indirect subtype - OTSubTypeHierarchyTest010: bugfix: type is indirect subtype - OTSubTypeHierarchyTest006: bugfix: type is indirect subtype (pict. is wrong) - OTSubTypeHierarchyTest004: bugfix: type is indirect subtype - OTSubTypeHierarchyTest001: many bugfixes: - type is indirect sub via phantom type - type is not a subtype of query type - type is indirect subtype additional test for phantom mode - CompleteRoleHierarchyWithClasses: several bugfixes: - type is not reachable from focusRole new tests: use more specific focus type Tests pass except for one regression mentioned already in comment 2
r684, r684 adjust the first refactoring (pushdown) to the new strategy. Required fixes in OTTypeHierarchies: - make getRealTSuper() succeed even if allTSupersLinearized is null (below focus) - support explicit creation of ConnectedPhantomType - filtering phantoms explicitly replaces ConnectedType with ConnectedPhantomType
Created attachment 176593 [details] More migration Migrate more refactorings to the new strategy: * pullup, rename type, Cleanup: * migrate two functions from team PhantomTypeAdaptor to PhantomType and remove the team. * do not require internal class TypeHierarchy in API methods, solved by an abstract super role bound to ITypeHierarchy * remove adaptations used for - replacing TypeHierarchy with OTTypeHierarchy - avoiding getSuperclass calls on OTTypeHierarchy * remove obsolete team OTTypeHierarchyAdaptor Necessary addition in OTTypeHierarchies: * new query getAllTSubTypes(TypeHierarchy,IType)
Created attachment 176601 [details] Still more migration Cleanup: * enable classic hierarchy mode (= remove role ViewPart) * no longer create OTTypeHierarchy - remove role LifeCycle * consume new strategy for superclass linearization, remove these roles: - SubTypeHierarchyContentProvider (original getParent() is fine now) - JavaModelUtil (original isSuperType() is fine now) - MethodOverrideTester (original methods are fine: findOverriddenMethod, computeSubstitutions) - TraditionalHierarchyContent (original getParentType() is fine now) * stop prefixing role names with their team, post qualification works OK - remove roles HierarchyLabelProvider, MethodsLabelProvider Enhancement: * enable F4 (open type hierarchy for method mappings in the outline view) Minor issue: MethodOverrideTester.computeSubstitutions first calls IType.getSuperclassSignature and then fHierarchy.getSuperclass(type), assuming both refer to the same type, which is not true if type has tsupers. Not clear what could possibly break here.
Last references to OTTypeHierarchy have been removed from otdt.refactoring: * no longer adapt RippleMethodFinder2: the adaptation was crippled more than it helps now after the change * no longer create OTTypeHierarchy from - RenameVirtualMethodProcessor - PullUpRefactoringProcessorRole this is r697 More plugins have been cleaned up after the strategy change: - otdt.ui: r696 - otdt.debug.ui: r698 (dependency on objectteams.runtime shouldn't be needed) - jdt.core: r699 with one addition in otdt r700 - otdt.tests: r701 Three classes in jdt.core used to depend on OTTypeHierarchy which is now solved like such: - MethodPattern.resolveLevelForType() and RoleType.findSuperBaseClass(): both methods used to call OTTypeHierarchy.getTSuperTypes(). Instead we now call ITypeHierarchy.getSuperclass() and rely on the fact that OTTypeHierarchies adapts this method to yield the full superclass linearization. - OTType.getRoleTypes() used three different queries depending on a bitset argument. Only one of three cases is no implemented in OTType, relying on a new role in OTTypeHierarchies to intercept and handle the other two cases (getTypesToSearchForRoles())
Commits r704 - r706 remove some useless API from OTTypeHierarchies: * getAllSuperTypes(): instead of providing alternative implementations, adapt the original one from TypeHierarchy (supported by a small change in TypeHierarchy, as to use getSubclass() for a proper join point). * getAllSuperclasses() was only chaining through the team (except for a check isInterface()). This alone caused behavior changes which are compensated by * also filtering phantoms from getAllSuperTypes() * checking isInterface inside getSuperclassLinearized() (based on a new flag remembered from connectTSupers(), we can't use isInterface due to in-exists()ing phantom types). For performance reasons, getSuperclassLinearized has now a a binding base guard (OTModelManager.isRole()). Additionally, comments from old OTTypeHierarchy have been transferred to the new team and were further improved.
Commit r707 - r711 contain the final cleanup: * remove OTTypeHierarchy* & CopyInheritanceInfo from org.eclipse.jdt.core * three classes have found their new home in org.eclipse.objectteams.otdt: - OTTypeHierarchyTraverser - TraverseRequestor - InheritedMethodsRequestor this implied that two methods from TypeHelper had to be moved out of the core they are now in RefactoringUtil. I have also slightly simplified the three moved classes: - replace HashMap<String,Boolean> with a small record class - remove unsupported option "hierarchyToTraverse", only super is implemented + also support reuse of a client-provided type hierarchy. Finally, tests in RefactoringUtilTest have been revived (which were disabled since the 3.2 migration, I believe)
Regressions in OTSubHierarchyContentProviderTests showed that we were not correctly handling the following cases: (A) types that are unrelated to the focus type (B) filtering/substituting phantom types in subtype hierarchies Commits r715 - r718 fix these by the following changes: (A) Fix tsuper-navigation for types unrelated to the focus type: don't rely on allTSupersLinearized being set but use directTSupers. (B) Ensure symmetry between tsub and tsuper navigation: in non-phantom mode always try to replace a phantom role with the next non-phantom role(s). This is important for capturing roles beyond 'holes' (phantoms) in the middle of a hierarchy. * when computing subtypes in non-phantom mode replace phantoms with all their non-phantom tsubtypes (new method collectRealTSubs()) TODO: might have to include explicit subtypes, if they are not otherwise rooted. * avoid that traversals would stop when encountering a phantom role: - conditionally filter from addTSubs() only if intercepting a toplevel query - no longer intercept getAllSuperclasses, but let getSuperclassLinearized() take care of phantoms. Tests have been adjusted correspondingly: * Some indirect tsub roles had been removed from expected results, reverted. (OTSubTypeHierarchyTest{001,004,017}) * OTSubHierarchyContentProviderTests: do expect meaningful answers from getParent(), correct expected results and added one more test. Additionally, one more method in LookupEnvironment is integrated with Dependencies, as required by RenameTypeTests (tsupers were not correctly connected).
Verified using I201009211735