📄 lookupmethod.jrag
字号:
/* * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered * by the modified BSD License. You should have received a copy of the * modified BSD license with this compiler. * * Copyright (c) 2005-2008, Torbjorn Ekman * All rights reserved. */import java.util.*;import java.util.ArrayList;aspect LookupMethod { inh MethodDecl MethodDecl.unknownMethod(); inh MethodDecl MethodAccess.unknownMethod(); syn Expr Access.unqualifiedScope() = isQualified() ? nestedScope() : this; inh Expr Access.nestedScope(); eq AbstractDot.getRight().nestedScope() = isQualified() ? nestedScope() : this; eq AbstractDot.getLeft().nestedScope() = isQualified() ? nestedScope() : this; eq Program.getChild().nestedScope() { throw new UnsupportedOperationException(); } inh Collection Expr.lookupMethod(String name); inh Collection Stmt.lookupMethod(String name); inh Collection BodyDecl.lookupMethod(String name); inh lazy Collection TypeDecl.lookupMethod(String name); eq MethodAccess.getArg().lookupMethod(String name) = unqualifiedScope().lookupMethod(name); eq ConstructorAccess.getArg().lookupMethod(String name) = unqualifiedScope().lookupMethod(name); eq ArrayAccess.getExpr().lookupMethod(String name) = unqualifiedScope().lookupMethod(name); eq ArrayTypeWithSizeAccess.getExpr().lookupMethod(String name) = unqualifiedScope().lookupMethod(name); eq Program.getChild().lookupMethod(String name) = Collections.EMPTY_LIST; eq TypeDecl.getBodyDecl(int i).lookupMethod(String name) = unqualifiedLookupMethod(name); syn lazy Collection TypeDecl.unqualifiedLookupMethod(String name) { Collection c = memberMethods(name); if(!c.isEmpty()) return c; if(isInnerType()) return lookupMethod(name); return removeInstanceMethods(lookupMethod(name)); } // in explicit constructor invocation eq ConstructorDecl.getConstructorInvocation().lookupMethod(String name) { Collection c = new ArrayList(); for(Iterator iter = lookupMethod(name).iterator(); iter.hasNext(); ) { MethodDecl m = (MethodDecl)iter.next(); if(!hostType().memberMethods(name).contains(m) || m.isStatic()) c.add(m); } return c; } public static Collection ASTNode.removeInstanceMethods(Collection c) { c = new LinkedList(c); for(Iterator iter = c.iterator(); iter.hasNext(); ) { MethodDecl m = (MethodDecl)iter.next(); if(!m.isStatic()) iter.remove(); } return c; } eq AbstractDot.getRight().lookupMethod(String name) = getLeft().type().memberMethods(name); syn MethodDecl MethodAccess.singleCandidateDecl() { MethodDecl result = null; for(Iterator iter = lookupMethod(name()).iterator(); iter.hasNext(); ) { MethodDecl m = (MethodDecl)iter.next(); if(result == null) result = m; else if(m.getNumParameter() == getNumArg() && result.getNumParameter() != getNumArg()) result = m; } return result; } syn lazy SimpleSet MethodAccess.decls() { SimpleSet maxSpecific = SimpleSet.emptySet; for(Iterator iter = lookupMethod(name()).iterator(); iter.hasNext(); ) { MethodDecl decl = (MethodDecl)iter.next(); if(applicable(decl) && accessible(decl)) { if(maxSpecific.isEmpty()) maxSpecific = maxSpecific.add(decl); else { if(decl.moreSpecificThan((MethodDecl)maxSpecific.iterator().next())) maxSpecific = SimpleSet.emptySet.add(decl); else if(!((MethodDecl)maxSpecific.iterator().next()).moreSpecificThan(decl)) maxSpecific = maxSpecific.add(decl); } } } if(isQualified() ? qualifier().staticContextQualifier() : inStaticContext()) maxSpecific = removeInstanceMethods(maxSpecific); return maxSpecific; } syn lazy MethodDecl MethodAccess.decl() { SimpleSet decls = decls(); if(decls.size() == 1) return (MethodDecl)decls.iterator().next(); // 8.4.6.4 - only return the first method in case of multply inherited abstract methods boolean allAbstract = true; for(Iterator iter = decls.iterator(); iter.hasNext() && allAbstract; ) { MethodDecl m = (MethodDecl)iter.next(); if(!m.isAbstract() && !m.hostType().isObject()) allAbstract = false; } if(decls.size() > 1 && allAbstract) return (MethodDecl)decls.iterator().next(); return unknownMethod(); } private static SimpleSet MethodAccess.removeInstanceMethods(SimpleSet c) { SimpleSet set = SimpleSet.emptySet; for(Iterator iter = c.iterator(); iter.hasNext(); ) { MethodDecl m = (MethodDecl)iter.next(); if(m.isStatic()) set = set.add(m); } return set; }}aspect MethodDecl { syn String MethodDecl.name() = getID(); // 8.4.2 syn lazy String MethodDecl.signature() { StringBuffer s = new StringBuffer(); s.append(name() + "("); for(int i = 0; i < getNumParameter(); i++) { if(i != 0) s.append(", "); s.append(getParameter(i).type().typeName()); } s.append(")"); return s.toString(); } // 8.4.2 Method Signature syn boolean MethodDecl.sameSignature(MethodDecl m) = signature().equals(m.signature()); syn lazy boolean MethodDecl.moreSpecificThan(MethodDecl m) { if(getNumParameter() == 0) return false; for(int i = 0; i < getNumParameter(); i++) { if(!getParameter(i).type().instanceOf(m.getParameter(i).type())) return false; } return true; } public boolean MethodAccess.applicable(MethodDecl decl) { if(getNumArg() != decl.getNumParameter()) return false; if(!name().equals(decl.name())) return false; for(int i = 0; i < getNumArg(); i++) { if(!getArg(i).type().instanceOf(decl.getParameter(i).type())) return false; } return true; } syn boolean MethodAccess.accessible(MethodDecl m) { if(!isQualified()) return true; if(!m.accessibleFrom(hostType())) return false; // the method is not accessible if the type is not accessible if(!qualifier().type().accessibleFrom(hostType())) return false; // 6.6.2.1 - include qualifier type for protected access if(m.isProtected() && !m.hostPackage().equals(hostPackage()) && !m.isStatic() && !qualifier().isSuperAccess()) { TypeDecl C = m.hostType(); TypeDecl S = hostType().subclassWithinBody(C); TypeDecl Q = qualifier().type(); if(S == null || !Q.instanceOf(S)) return false; } return true; } syn lazy boolean MethodDecl.overrides(MethodDecl m) = !isStatic() && !m.isPrivate() && m.accessibleFrom(hostType()) && hostType().instanceOf(m.hostType()) && m.signature().equals(signature()); syn lazy boolean MethodDecl.hides(MethodDecl m) = isStatic() && !m.isPrivate() && m.accessibleFrom(hostType()) && hostType().instanceOf(m.hostType()) && m.signature().equals(signature());}aspect MemberMethods { syn Collection TypeDecl.memberMethods(String name) { Collection c = (Collection)methodsNameMap().get(name); if(c != null) return c; return Collections.EMPTY_LIST; } // name -> Collection syn lazy HashMap TypeDecl.methodsNameMap() { HashMap map = new HashMap(); for(Iterator iter = methodsIterator(); iter.hasNext(); ) { MethodDecl m = (MethodDecl)iter.next(); ArrayList list = (ArrayList)map.get(m.name()); if(list == null) { list = new ArrayList(4); map.put(m.name(), list); } list.add(m);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -