001 /* Copyright (c) 2005-2008, Torbjorn Ekman 002 * 2015, Jesper �qvist <jesper.oqvist@cs.lth.se> 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without 006 * modification, are permitted provided that the following conditions are met: 007 * 008 * 1. Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * 2. Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * 3. Neither the name of the copyright holder nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 029 * POSSIBILITY OF SUCH DAMAGE. 030 */ 031 032 aspect MethodSignature15 { 033 refine LookupMethod protected SimpleSet MethodAccess.maxSpecific(Collection candidates) { 034 SimpleSet potentiallyApplicable = potentiallyApplicable(candidates); 035 // first phase 036 SimpleSet maxSpecific = applicableBySubtyping(potentiallyApplicable); 037 // second phase 038 maxSpecific = applicableByMethodInvocationConversion(potentiallyApplicable, maxSpecific); 039 // third phase 040 maxSpecific = applicableVariableArity(potentiallyApplicable, maxSpecific); 041 return maxSpecific; 042 } 043 044 protected SimpleSet MethodAccess.potentiallyApplicable(Collection candidates) { 045 SimpleSet potentiallyApplicable = SimpleSet.emptySet; 046 // select potentially applicable methods 047 for (Iterator iter = candidates.iterator(); iter.hasNext(); ) { 048 MethodDecl decl = (MethodDecl) iter.next(); 049 if (potentiallyApplicable(decl) && accessible(decl)) { 050 if (decl.isGeneric()) { 051 GenericMethodDecl gm = decl.genericDecl(); 052 decl = gm.lookupParMethodDecl( 053 inferTypeArguments( 054 gm.type(), 055 gm.getParameterList(), 056 getArgList(), 057 gm.getTypeParameterList())); 058 } 059 potentiallyApplicable = potentiallyApplicable.add(decl); 060 } 061 } 062 return potentiallyApplicable; 063 } 064 065 protected SimpleSet MethodAccess.applicableBySubtyping(SimpleSet potentiallyApplicable) { 066 SimpleSet maxSpecific = SimpleSet.emptySet; 067 for (Iterator iter = potentiallyApplicable.iterator(); iter.hasNext(); ) { 068 MethodDecl decl = (MethodDecl) iter.next(); 069 if (applicableBySubtyping(decl)) { 070 maxSpecific = mostSpecific(maxSpecific, decl); 071 } 072 } 073 return maxSpecific; 074 } 075 076 protected SimpleSet MethodAccess.applicableByMethodInvocationConversion( 077 SimpleSet potentiallyApplicable, SimpleSet maxSpecific) { 078 if (maxSpecific.isEmpty()) { 079 for (Iterator iter = potentiallyApplicable.iterator(); iter.hasNext(); ) { 080 MethodDecl decl = (MethodDecl) iter.next(); 081 if (applicableByMethodInvocationConversion(decl)) { 082 maxSpecific = mostSpecific(maxSpecific, decl); 083 } 084 } 085 } 086 return maxSpecific; 087 } 088 089 protected SimpleSet MethodAccess.applicableVariableArity(SimpleSet potentiallyApplicable, 090 SimpleSet maxSpecific) { 091 if (maxSpecific.isEmpty()) { 092 for (Iterator iter = potentiallyApplicable.iterator(); iter.hasNext(); ) { 093 MethodDecl decl = (MethodDecl) iter.next(); 094 if (decl.isVariableArity() && applicableVariableArity(decl)) { 095 maxSpecific = mostSpecific(maxSpecific, decl); 096 } 097 } 098 } 099 return maxSpecific; 100 } 101 102 refine ConstructScope eq ClassInstanceExpr.decls() { 103 TypeDecl typeDecl = hasTypeDecl() ? getTypeDecl() : getAccess().type(); 104 return chooseConstructor(typeDecl.constructors(), getArgList()); 105 } 106 107 refine ConstructScope eq ConstructorAccess.decls() = 108 chooseConstructor(lookupConstructor(), getArgList()); 109 110 refine ConstructScope eq SuperConstructorAccess.decls() { 111 Collection c = hasPrevExpr() && !prevExpr().isTypeAccess() 112 ? hostType().lookupSuperConstructor() 113 : lookupSuperConstructor(); 114 return chooseConstructor(c, getArgList()); 115 } 116 117 refine AnonymousClasses eq ClassInstanceExpr.getTypeDecl().constructorDecl() { 118 Collection c = getAccess().type().constructors(); 119 SimpleSet maxSpecific = chooseConstructor(c, getArgList()); 120 if (maxSpecific.size() == 1) { 121 return (ConstructorDecl) maxSpecific.iterator().next(); 122 } 123 return unknownConstructor(); 124 } 125 126 protected SimpleSet Expr.chooseConstructor(Collection constructors, List<Expr> argList) { 127 SimpleSet potentiallyApplicable = SimpleSet.emptySet; 128 129 // Select potentially applicable constructors. 130 for (Iterator iter = constructors.iterator(); iter.hasNext(); ) { 131 ConstructorDecl decl = (ConstructorDecl) iter.next(); 132 if (decl.potentiallyApplicable(argList) && decl.accessibleFrom(hostType())) { 133 if (decl.isGeneric()) { 134 GenericConstructorDecl gc = decl.genericDecl(); 135 decl = gc.lookupParConstructorDecl( 136 inferTypeArguments( 137 gc.type(), 138 gc.getParameterList(), 139 argList, 140 gc.getTypeParameterList())); 141 } 142 potentiallyApplicable = potentiallyApplicable.add(decl); 143 } 144 } 145 146 // First phase. 147 SimpleSet maxSpecific = SimpleSet.emptySet; 148 for (Iterator iter = potentiallyApplicable.iterator(); iter.hasNext(); ) { 149 ConstructorDecl decl = (ConstructorDecl) iter.next(); 150 if (decl.applicableBySubtyping(argList)) { 151 maxSpecific = mostSpecific(maxSpecific, decl); 152 } 153 } 154 155 // Second phase. 156 if (maxSpecific.isEmpty()) { 157 for (Iterator iter = potentiallyApplicable.iterator(); iter.hasNext(); ) { 158 ConstructorDecl decl = (ConstructorDecl) iter.next(); 159 if (decl.applicableByMethodInvocationConversion(argList)) { 160 maxSpecific = mostSpecific(maxSpecific, decl); 161 } 162 } 163 } 164 165 // Third phase. 166 if (maxSpecific.isEmpty()) { 167 for (Iterator iter = potentiallyApplicable.iterator(); iter.hasNext(); ) { 168 ConstructorDecl decl = (ConstructorDecl) iter.next(); 169 if (decl.isVariableArity() && decl.applicableVariableArity(argList)) { 170 maxSpecific = mostSpecific(maxSpecific, decl); 171 } 172 } 173 } 174 return maxSpecific; 175 } 176 177 protected static SimpleSet Expr.mostSpecific(SimpleSet maxSpecific, ConstructorDecl decl) { 178 if (maxSpecific.isEmpty()) { 179 maxSpecific = maxSpecific.add(decl); 180 } else { 181 ConstructorDecl other = (ConstructorDecl) maxSpecific.iterator().next(); 182 if (decl.moreSpecificThan(other)) { 183 maxSpecific = SimpleSet.emptySet.add(decl); 184 } else if (!other.moreSpecificThan(decl)) { 185 maxSpecific = maxSpecific.add(decl); 186 } 187 } 188 return maxSpecific; 189 } 190 191 private static SimpleSet MethodAccess.mostSpecific(SimpleSet maxSpecific, MethodDecl decl) { 192 if (maxSpecific.isEmpty()) { 193 maxSpecific = maxSpecific.add(decl); 194 } else { 195 MethodDecl other = (MethodDecl) maxSpecific.iterator().next(); 196 if (decl.moreSpecificThan(other)) { 197 maxSpecific = decl; 198 } else if (!other.moreSpecificThan(decl)) { 199 maxSpecific = maxSpecific.add(decl); 200 } 201 } 202 return maxSpecific; 203 } 204 205 eq ParMethodDecl.lessSpecificThan(MethodDecl m) = 206 genericMethodDecl().lessSpecificThan(m instanceof ParMethodDecl 207 ? ((ParMethodDecl) m).genericMethodDecl() : m ); 208 209 refine MethodDecl eq MethodDecl.lessSpecificThan(MethodDecl m) { 210 int numA = getNumParameter(); 211 int numB = m.getNumParameter(); 212 int num = Math.max(numA, numB); 213 for (int i = 0; i < num; i++) { 214 TypeDecl t1 = getParameter(Math.min(i, numA-1)).type(); 215 TypeDecl t2 = m.getParameter(Math.min(i, numB-1)).type(); 216 if (!t1.instanceOf(t2) && !t1.withinBounds(t2, Parameterization.RAW)) { 217 return true; 218 } 219 } 220 return false; 221 } 222 223 refine ConstructorDecl eq ConstructorDecl.lessSpecificThan(ConstructorDecl m) { 224 int numA = getNumParameter(); 225 int numB = m.getNumParameter(); 226 int num = Math.max(numA, numB); 227 for (int i = 0; i < num; i++) { 228 TypeDecl t1 = getParameter(Math.min(i, numA-1)).type(); 229 TypeDecl t2 = m.getParameter(Math.min(i, numB-1)).type(); 230 if (!t1.instanceOf(t2) && !t1.withinBounds(t2, Parameterization.RAW)) { 231 return true; 232 } 233 } 234 return false; 235 } 236 237 /** 238 * A raw type parameterization. Performs no substitutions. 239 */ 240 public static final Parameterization Parameterization.RAW = new Parameterization() { 241 @Override 242 public boolean isRawType() { 243 return true; 244 } 245 @Override 246 public TypeDecl substitute(TypeVariable typeVariable) { 247 return typeVariable; 248 } 249 }; 250 251 /** 252 * A simple parameterization. Each type variable is mapped to a type decl. 253 */ 254 class SimpleParameterization implements Parameterization { 255 Map<TypeVariable, TypeDecl> typeMap = new HashMap<TypeVariable, TypeDecl>(); 256 public SimpleParameterization(Iterable<TypeVariable> typeParams, Iterable<TypeDecl> typeArgs) { 257 Iterator<TypeVariable> param = typeParams.iterator(); 258 Iterator<TypeDecl> arg = typeArgs.iterator(); 259 while (param.hasNext() && arg.hasNext()) { 260 typeMap.put(param.next(), arg.next()); 261 } 262 } 263 264 @Override 265 public boolean isRawType() { 266 return false; 267 } 268 269 @Override 270 public TypeDecl substitute(TypeVariable typeVariable) { 271 if (typeMap.containsKey(typeVariable)) { 272 return typeMap.get(typeVariable); 273 } 274 return typeVariable; 275 } 276 } 277 278 279 syn boolean MethodAccess.applicableBySubtyping(MethodDecl m) { 280 if (m.getNumParameter() != getNumArg()) { 281 return false; 282 } 283 for (int i = 0; i < m.getNumParameter(); i++) { 284 TypeDecl arg = getArg(i).type(); 285 TypeDecl param = m.getParameter(i).type(); 286 if (!param.isTypeVariable()) { 287 if (!arg.instanceOf(param)) { 288 return false; 289 } 290 } else { 291 if (!arg.withinBounds(param, Parameterization.RAW)) { 292 return false; 293 } 294 } 295 } 296 return true; 297 } 298 299 syn boolean ConstructorDecl.applicableBySubtyping(List<Expr> argList) { 300 if (getNumParameter() != argList.getNumChild()) { 301 return false; 302 } 303 for (int i = 0; i < getNumParameter(); i++) { 304 TypeDecl arg = argList.getChild(i).type(); 305 TypeDecl param = getParameter(i).type(); 306 if (!param.isTypeVariable()) { 307 if (!arg.instanceOf(param)) { 308 return false; 309 } 310 } else { 311 if (!arg.withinBounds(param, Parameterization.RAW)) { 312 return false; 313 } 314 } 315 } 316 return true; 317 } 318 319 syn boolean MethodAccess.applicableByMethodInvocationConversion(MethodDecl m) { 320 if (m.getNumParameter() != getNumArg()) { 321 return false; 322 } 323 for (int i = 0; i < m.getNumParameter(); i++) 324 if (!getArg(i).type().methodInvocationConversionTo(m.getParameter(i).type())) { 325 return false; 326 } 327 return true; 328 } 329 330 syn boolean ConstructorDecl.applicableByMethodInvocationConversion(List<Expr> argList) { 331 if (getNumParameter() != argList.getNumChild()) { 332 return false; 333 } 334 for (int i = 0; i < getNumParameter(); i++) { 335 TypeDecl arg = argList.getChild(i).type(); 336 if (!arg.methodInvocationConversionTo(getParameter(i).type())) { 337 return false; 338 } 339 } 340 return true; 341 } 342 343 syn boolean MethodAccess.applicableVariableArity(MethodDecl m) { 344 for (int i = 0; i < m.getNumParameter() - 1; i++) 345 if (!getArg(i).type().methodInvocationConversionTo(m.getParameter(i).type())) { 346 return false; 347 } 348 for (int i = m.getNumParameter() - 1; i < getNumArg(); i++) 349 if (!getArg(i).type().methodInvocationConversionTo(m.lastParameter().type().componentType())) { 350 return false; 351 } 352 return true; 353 } 354 355 syn boolean ConstructorDecl.applicableVariableArity(List argList) { 356 for (int i = 0; i < getNumParameter() - 1; i++) { 357 TypeDecl arg = ((Expr) argList.getChild(i)).type(); 358 if (!arg.methodInvocationConversionTo(getParameter(i).type())) { 359 return false; 360 } 361 } 362 for (int i = getNumParameter() - 1; i < argList.getNumChild(); i++) { 363 TypeDecl arg = ((Expr) argList.getChild(i)).type(); 364 if (!arg.methodInvocationConversionTo(lastParameter().type().componentType())) { 365 return false; 366 } 367 } 368 return true; 369 } 370 371 /** 372 * @return {@code true} if this is a generic method or constructor, or a 373 * substitued generic method or constructor. 374 */ 375 syn boolean BodyDecl.isGeneric() = false; 376 eq GenericMethodDecl.isGeneric() = true; 377 eq MethodDeclSubstituted.isGeneric() = sourceMethodDecl().isGeneric(); 378 eq GenericConstructorDecl.isGeneric() = true; 379 eq ConstructorDeclSubstituted.isGeneric() = sourceConstructorDecl().isGeneric(); 380 381 /** 382 * Note: isGeneric must be called first to check if this declaration is generic. 383 * Otherwise this attribute will throw an error! 384 * @return the original generic declaration of this method. 385 */ 386 syn GenericMethodDecl MethodDecl.genericDecl() { 387 throw new Error("can not evaulate generic declaration of non-generic method"); 388 } 389 eq GenericMethodDecl.genericDecl() = this; 390 eq MethodDeclSubstituted.genericDecl() = sourceMethodDecl().genericDecl(); 391 392 /** 393 * Note: isGeneric must be called first to check if this declaration is generic. 394 * Otherwise this attribute will throw an error! 395 * @return original generic declaration of this constructor. 396 */ 397 syn GenericConstructorDecl ConstructorDecl.genericDecl() { 398 throw new Error("can not evaulate generic declaration of non-generic constructor"); 399 } 400 eq GenericConstructorDecl.genericDecl() = this; 401 eq ConstructorDeclSubstituted.genericDecl() = sourceConstructorDecl().genericDecl(); 402 403 /** 404 * Note: isGeneric must be called first to check if this declaration is generic. 405 * Otherwise this attribute will throw an error! 406 * @return type parameters for this declaration. 407 */ 408 syn List<TypeVariable> BodyDecl.typeParameters() { 409 throw new Error("can not evaulate type parameters for non-generic declaration"); 410 } 411 412 eq GenericMethodDecl.typeParameters() = getTypeParameterList(); 413 eq MethodDeclSubstituted.typeParameters() = sourceMethodDecl().typeParameters(); 414 eq GenericConstructorDecl.typeParameters() = getTypeParameterList(); 415 eq ConstructorDeclSubstituted.typeParameters() = sourceConstructorDecl().typeParameters(); 416 417 // 15.12.2.1 418 419 /** 420 * A member method is potentially applicable to a method invocation if and 421 * only if all of the following are true: 422 * <ul> 423 * <li>The name of the member is identical to the name of the method in the 424 * method invocation. 425 * <li>The member is accessible (�6.6) to the class or interface in which 426 * the method invocation appears. 427 * <li>The arity of the member is lesser or equal to the arity of the 428 * method invocation. 429 * <li>If the member is a variable arity method with arity n, the arity of 430 * the method invocation is greater or equal to n-1. 431 * <li>If the member is a fixed arity method with arity n, the arity of the 432 * method invocation is equal to n. 433 * <li>If the method invocation includes explicit type parameters, and the 434 * member is a generic method, then the number of actual type parameters is 435 * equal to the number of formal type parameters. 436 * </ul> 437 */ 438 syn boolean MethodAccess.potentiallyApplicable(MethodDecl m) { 439 if (!m.name().equals(name())) { 440 return false; 441 } 442 if (!m.accessibleFrom(hostType())) { 443 return false; 444 } 445 if (m.isVariableArity() && !(arity() >= m.arity()-1)) { 446 return false; 447 } 448 if (!m.isVariableArity() && !(m.arity() == arity())) { 449 return false; 450 } 451 if (m.isGeneric()) { 452 GenericMethodDecl gm = m.genericDecl(); 453 ArrayList<TypeDecl> typeArguments = inferTypeArguments( 454 gm.type(), 455 gm.getParameterList(), 456 getArgList(), 457 gm.getTypeParameterList()); 458 if (!typeArguments.isEmpty()) { 459 if (gm.getNumTypeParameter() != typeArguments.size()) { 460 return false; 461 } 462 Parameterization par = new SimpleParameterization(gm.getTypeParameterList(), typeArguments); 463 for (int i = 0; i < gm.getNumTypeParameter(); i++) { 464 if (!typeArguments.get(i).withinBounds(gm.original().getTypeParameter(i), par)) { 465 return false; 466 } 467 } 468 } 469 } 470 return true; 471 } 472 473 syn int MethodDecl.arity() = getNumParameter(); 474 syn int MethodAccess.arity() = getNumArg(); 475 476 /** 477 * Infers type arguments for this method invocation. 478 */ 479 syn lazy ArrayList<TypeDecl> Expr.inferTypeArguments( 480 TypeDecl resultType, 481 List<ParameterDeclaration> params, 482 List<Expr> args, 483 List<TypeVariable> typeParams) { 484 ArrayList<TypeDecl> typeArguments = new ArrayList<TypeDecl>(); 485 Collection<TypeDecl> arguments = computeConstraints( 486 resultType, 487 params, 488 args, 489 typeParams); 490 if (arguments.isEmpty()) { 491 return typeArguments; 492 } 493 int i = 0; 494 for (Iterator<TypeDecl> iter = arguments.iterator(); iter.hasNext(); i++) { 495 TypeDecl typeDecl = iter.next(); 496 if (typeDecl == null) { 497 TypeVariable v = typeParams.getChild(i); 498 if (v.getNumTypeBound() == 0) { 499 typeDecl = typeObject(); 500 } else if (v.getNumTypeBound() == 1) { 501 typeDecl = v.getTypeBound(0).type(); 502 } else { 503 typeDecl = v.lubType(); 504 } 505 } 506 typeArguments.add(typeDecl); 507 } 508 return typeArguments; 509 } 510 511 eq ParMethodAccess.inferTypeArguments( 512 TypeDecl resultType, 513 List<ParameterDeclaration> params, 514 List<Expr> args, 515 List<TypeVariable> typeParams) { 516 ArrayList<TypeDecl> typeArguments = new ArrayList<TypeDecl>(); 517 for (Access typeArgument : getTypeArgumentList()) { 518 typeArguments.add(typeArgument.type()); 519 } 520 return typeArguments; 521 } 522 523 eq ParConstructorAccess.inferTypeArguments( 524 TypeDecl resultType, 525 List<ParameterDeclaration> params, 526 List<Expr> args, 527 List<TypeVariable> typeParams) { 528 ArrayList<TypeDecl> typeArguments = new ArrayList<TypeDecl>(); 529 for (Access typeArgument : getTypeArgumentList()) { 530 typeArguments.add(typeArgument.type()); 531 } 532 return typeArguments; 533 } 534 535 syn boolean ConstructorDecl.potentiallyApplicable(List<Expr> argList) { 536 if (isVariableArity() && !(argList.getNumChild() >= arity()-1)) { 537 return false; 538 } 539 if (!isVariableArity() && !(arity() == argList.getNumChild())) { 540 return false; 541 } 542 return true; 543 } 544 545 syn int ConstructorDecl.arity() = getNumParameter(); 546 syn int ConstructorAccess.arity() = getNumArg(); 547 syn int ClassInstanceExpr.arity() = getNumArg(); 548 549 // 15.12.3 550 // refine old type checking to be valid when using variable arity parameters 551 refine TypeCheck public void MethodAccess.typeCheck() { 552 for (int i = 0; i < getNumArg(); ++i) { 553 if (getArg(i).type().isVoid()) { 554 errorf("expression '%s' has type void and is not a valid method argument", 555 getArg(i).prettyPrint()); 556 } 557 } 558 if (isQualified() && decl().isAbstract() && qualifier().isSuperAccess()) { 559 error("may not access abstract methods in superclass"); 560 } 561 if (!decl().isVariableArity() || invokesVariableArityAsArray()) { 562 for (int i = 0; i < decl().getNumParameter(); i++) { 563 TypeDecl exprType = getArg(i).type(); 564 TypeDecl parmType = decl().getParameter(i).type(); 565 if (!exprType.methodInvocationConversionTo(parmType) && 566 !exprType.isUnknown() && !parmType.isUnknown()) { 567 errorf("argument '%s' of type %s is not compatible with the method parameter type %s", 568 getArg(i).prettyPrint(), exprType.typeName(), parmType.typeName()); 569 } 570 } 571 } 572 } 573 574 refine MethodDecl eq MethodDecl.signature() { 575 StringBuilder sb = new StringBuilder(); 576 sb.append(name() + "("); 577 for (int i = 0; i < getNumParameter(); i++) { 578 if (i != 0) { 579 sb.append(", "); 580 } 581 sb.append(getParameter(i).type().erasure().typeName()); 582 } 583 sb.append(")"); 584 return sb.toString(); 585 } 586 587 refine MemberMethods eq ClassDecl.methodsSignatureMap() { 588 Map<String,SimpleSet> localMap = localMethodsSignatureMap(); 589 Map<String,SimpleSet> map = new HashMap<String,SimpleSet>(localMap); 590 if (hasSuperclass()) { 591 for (Iterator iter = superclass().methodsIterator(); iter.hasNext(); ) { 592 MethodDecl m = (MethodDecl) iter.next(); 593 if (!m.isPrivate() && m.accessibleFrom(this) && !localMap.containsKey(m.signature())) { 594 if (!(m instanceof MethodDeclSubstituted) 595 || !localMap.containsKey(m.sourceMethodDecl().signature())) { 596 putSimpleSetElement(map, m.signature(), m); 597 } 598 } 599 } 600 } 601 for (Iterator iter = interfacesMethodsIterator(); iter.hasNext(); ) { 602 MethodDecl m = (MethodDecl) iter.next(); 603 if (m.accessibleFrom(this) && !localMap.containsKey(m.signature())) { 604 if (!(m instanceof MethodDeclSubstituted) 605 || !localMap.containsKey(m.sourceMethodDecl().signature())) { 606 if (allMethodsAbstract((SimpleSet) map.get(m.signature())) && 607 (!(m instanceof MethodDeclSubstituted) || 608 allMethodsAbstract((SimpleSet) map.get(m.sourceMethodDecl().signature())) ) 609 ) { 610 putSimpleSetElement(map, m.signature(), m); 611 } 612 } 613 } 614 } 615 return map; 616 } 617 618 refine MemberMethods eq InterfaceDecl.methodsSignatureMap() { 619 Map<String,SimpleSet> localMap = localMethodsSignatureMap(); 620 Map<String,SimpleSet> map = new HashMap<String,SimpleSet>(localMap); 621 for (Iterator iter = interfacesMethodsIterator(); iter.hasNext(); ) { 622 MethodDecl m = (MethodDecl) iter.next(); 623 if (m.accessibleFrom(this) && !localMap.containsKey(m.signature())) { 624 if (!(m instanceof MethodDeclSubstituted) || !localMap.containsKey(m.sourceMethodDecl().signature())) { 625 putSimpleSetElement(map, m.signature(), m); 626 } 627 } 628 } 629 for (Iterator iter = typeObject().methodsIterator(); iter.hasNext(); ) { 630 MethodDecl m = (MethodDecl) iter.next(); 631 if (m.isPublic() && !map.containsKey(m.signature())) { 632 putSimpleSetElement(map, m.signature(), m); 633 } 634 } 635 return map; 636 } 637 638 eq ParTypeDecl.unimplementedMethods() { 639 HashSet set = new HashSet(); 640 HashSet result = new HashSet(); 641 for (Iterator iter = genericDecl().unimplementedMethods().iterator(); iter.hasNext(); ) { 642 MethodDecl m = (MethodDecl) iter.next(); 643 set.add(m.sourceMethodDecl()); 644 } 645 for (Iterator iter = super.unimplementedMethods().iterator(); iter.hasNext(); ) { 646 MethodDecl m = (MethodDecl) iter.next(); 647 if (set.contains(m.sourceMethodDecl())) { 648 result.add(m); 649 } 650 } 651 return result; 652 } 653 654 }