// TODO: needs serious rewrite aspect IntroduceIndirection { public void MethodDeclSubstituted.introduceIndirection(String indname, String parmname, TypeDecl targetType) { sourceMethodDecl().introduceIndirection(indname, parmname, targetType); } // TODO: rewrite this as Extract Method; Make Method Static; Move Static Method (but what about overriding methods?) public void MethodDecl.introduceIndirection(String indname, String parmname, TypeDecl targetType) { MethodDecl indirection = lockedCopyWithEmptyBody(); indirection.setModifiers(new Modifiers("public", "static")); indirection.setID(indname); List args = new List(); for(ParameterDeclaration pd : indirection.getParameters()) args.addChild(pd.createLockedAccess()); ParameterDeclaration parm = null; Block body = null; if(isStatic()) { body = new Block(new ReturnStmt(this.createLockedAccess(args))); } else { parm = new FreshParameter(hostType().createLockedAccess(), parmname); indirection.insertParameter(parm, 0); body = new Block(new ReturnStmt(parm.createLockedAccess().qualifiesAccess(this.createLockedAccess(args)))); } indirection.setBlock(body); targetType.insertUnusedMethod(indirection, getChildIndex()); indirection = closeOverTypeVariables(indirection); for(MethodAccess ma : usesOfAllCopies()) { if(ma.hostBodyDecl() == indirection) continue; if(ma.isMonoCall() && !this.overridingMethods().isEmpty()) continue; if(!isStatic()) { ma.bundleQualifier(); ASTNode p = ma; if(ma.isQualified()) p = p.getParent(); Expr qual = ma.isQualified() && !ma.qualifier().isSuperAccess() ? ma.qualifier() : null; if(qual == null) { for(TypeDecl enc=ma.hostType(); enc!=null; enc=enc.enclosingType()) { if(enc.memberMethod(this) == this) { if(enc == ma.hostType()) qual = new ThisAccess("this"); else qual = enc.createLockedAccess().qualifiesAccess(new ThisAccess("this")); break; } } } ma.getArgList().insertChild(qual == null ? new ThisAccess("this") : qual, 0); p.replaceWith(ma); } ma.lock(indirection); } programRoot().flushCaches(); } public void MethodDecl.doIntroduceIndirection(String indname, String parmname, TypeDecl targetType) { introduceIndirection(indname, parmname, targetType); programRoot().eliminate(RETURN_VOID, FRESH_VARIABLES, BARE_PARMETHODACCESS, LOCKED_NAMES); } public void MethodDecl.doIntroduceIndirection(String indname, TypeDecl targetType) { String hostname = hostType().name(); doIntroduceIndirection(indname, Character.toLowerCase(hostname.charAt(0))+hostname.substring(1), targetType); } }