001 /* 002 * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered 003 * by the modified BSD License. You should have received a copy of the 004 * modified BSD license with this compiler. 005 * 006 * Copyright (c) 2005-2008, Torbjorn Ekman 007 * All rights reserved. 008 */ 009 010 aspect Generics { 011 012 /** 013 * Qualified access for wildcard types. 014 * Since they have no ordinary package and type name 015 * we just return the bound access. 016 */ 017 public Access AbstractWildcardType.createQualifiedAccess() { 018 // this was suggested by Hyunik Na as a fix for bug 019 // http://svn.cs.lth.se/trac/jastadd-trac/ticket/60 020 return createBoundAccess(); 021 } 022 023 eq ParClassDecl.hostType() = original(); 024 eq ParInterfaceDecl.hostType() = original(); 025 eq RawClassDecl.hostType() = original(); 026 eq RawInterfaceDecl.hostType() = original(); 027 eq ClassDeclSubstituted.hostType() = getOriginal(); 028 eq InterfaceDeclSubstituted.hostType() = getOriginal(); 029 eq GenericClassDeclSubstituted.hostType() = getOriginal(); 030 eq GenericInterfaceDeclSubstituted.hostType() = getOriginal(); 031 032 refine TypeAnalysis eq MethodAccess.type() { 033 if(getNumArg() == 0 && name().equals("getClass") && decl().hostType().isObject()) { 034 TypeDecl bound = isQualified() ? qualifier().type() : hostType(); 035 ArrayList args = new ArrayList(); 036 args.add(bound.erasure().asWildcardExtends()); 037 return ((GenericClassDecl)lookupType("java.lang", "Class")).lookupParTypeDecl(args); 038 } 039 else 040 return refined(); 041 } 042 043 // imported types are considered raw types by the name resolver 044 // here we replace them by their generic counter parts 045 refine TypeScopePropagation eq CompilationUnit.getChild().lookupType(String name) { 046 SimpleSet result = SimpleSet.emptySet; 047 for(Iterator iter = refined(name).iterator(); iter.hasNext(); ) { 048 TypeDecl typeDecl = (TypeDecl)iter.next(); 049 if(typeDecl instanceof ParTypeDecl) 050 result = result.add(((ParTypeDecl)typeDecl).genericDecl()); 051 else 052 result = result.add(typeDecl); 053 } 054 return result; 055 } 056 057 refine TypeConversion eq ClassDecl.castingConversionTo(TypeDecl type) { 058 TypeDecl S = this; 059 TypeDecl T = type; 060 if(T instanceof TypeVariable) { 061 TypeVariable t = (TypeVariable)T; 062 if(t.getNumTypeBound() == 0) return true; 063 for(int i = 0; i < t.getNumTypeBound(); i++) 064 if(castingConversionTo(t.getTypeBound(i).type())) 065 return true; 066 return false; 067 } 068 if(T.isClassDecl() && (S.erasure() != S || T.erasure() != T)) 069 return S.erasure().castingConversionTo(T.erasure()); 070 return refined(type); 071 } 072 073 refine TypeConversion eq InterfaceDecl.castingConversionTo(TypeDecl type) { 074 TypeDecl S = this; 075 TypeDecl T = type; 076 if(T.isArrayDecl()) 077 return T.instanceOf(S); 078 else if(T.isReferenceType() && !T.isFinal()) { 079 return true; 080 } 081 else { 082 return T.instanceOf(S); 083 } 084 } 085 086 eq TypeVariable.castingConversionTo(TypeDecl type) { 087 if(!type.isReferenceType()) 088 return false; 089 if(getNumTypeBound() == 0) return true; 090 for(int i = 0; i < getNumTypeBound(); i++) 091 if(getTypeBound(i).type().castingConversionTo(type)) 092 return true; 093 return false; 094 } 095 096 refine TypeConversion eq ArrayDecl.castingConversionTo(TypeDecl type) { 097 TypeDecl S = this; 098 TypeDecl T = type; 099 if(T instanceof TypeVariable) { 100 TypeVariable t = (TypeVariable)T; 101 if(!type.isReferenceType()) 102 return false; 103 if(t.getNumTypeBound() == 0) return true; 104 for(int i = 0; i < t.getNumTypeBound(); i++) { 105 TypeDecl bound = t.getTypeBound(i).type(); 106 if(bound.isObject() || bound == typeSerializable() || bound == typeCloneable()) 107 return true; 108 if(bound.isTypeVariable() && castingConversionTo(bound)) 109 return true; 110 if(bound.isArrayDecl() && castingConversionTo(bound)) 111 return true; 112 } 113 return false; 114 } 115 else 116 return refined(type); 117 } 118 119 refine TypeAnalysis eq ClassAccess.type() { 120 GenericClassDecl d = (GenericClassDecl)refined(); 121 TypeDecl type = qualifier().type(); 122 if(type.isPrimitiveType()) 123 type = type.boxed(); 124 ArrayList list = new ArrayList(); 125 list.add(type); 126 return d.lookupParTypeDecl(list); 127 } 128 129 refine AutoBoxing eq ConditionalExpr.type() { 130 TypeDecl type = refined(); 131 TypeDecl trueType = getTrueExpr().type(); 132 TypeDecl falseType = getFalseExpr().type(); 133 134 if(type.isUnknown()) { 135 if(!trueType.isReferenceType() && !trueType.boxed().isUnknown()) 136 trueType = trueType.boxed(); 137 if(!falseType.isReferenceType() && !falseType.boxed().isUnknown()) 138 falseType = falseType.boxed(); 139 140 ArrayList list = new ArrayList(); 141 list.add(trueType); 142 list.add(falseType); 143 return type.lookupLUBType(list); 144 } 145 return type; 146 } 147 148 syn boolean TypeVariable.isNestedType() = false; 149 150 // accessibility for members in generic classes 151 // the accessibility for parameterized and raw versions of a generic class 152 // should be the same as for the generic class, in other words the erasure of the 153 // paramterized version. 154 eq ParClassDecl.topLevelType() = erasure().topLevelType(); 155 156 157 interface GenericTypeDecl { 158 syn boolean isGenericType(); 159 TypeDecl original(); 160 int getNumTypeParameter(); 161 TypeVariable getTypeParameter(int index); 162 List getTypeParameterList(); 163 syn lazy TypeDecl rawType(); 164 public String fullName(); 165 public String typeName(); 166 // 167 // ES: replaced these with a syn nta(param) 168 // public int getNumParTypeDecl(); 169 // public ParTypeDecl getParTypeDecl(int index); 170 // 171 sons BodyDecl:BodyDecl* TypeParameter:TypeVariable* ParTypeDecl:ParTypeDecl*; 172 } 173 GenericClassDecl implements GenericTypeDecl; 174 GenericInterfaceDecl implements GenericTypeDecl; 175 176 eq GenericClassDecl.rawType() = lookupParTypeDecl(new ArrayList()); 177 eq GenericInterfaceDecl.rawType() = lookupParTypeDecl(new ArrayList()); 178 179 syn boolean TypeDecl.isGenericType() = false; 180 eq GenericTypeDecl.isGenericType() = true; 181 182 // Brute force replacesment with generic one in AST 183 // make sure that the AST has not beed traversed yet! 184 public TypeDecl TypeDecl.makeGeneric(Signatures.ClassSignature s) { 185 return this; 186 } 187 public TypeDecl ClassDecl.makeGeneric(Signatures.ClassSignature s) { 188 if(s.hasFormalTypeParameters()) { 189 ASTNode node = getParent(); 190 int index = node.getIndexOfChild(this); 191 node.setChild( 192 new GenericClassDecl( 193 getModifiersNoTransform(), 194 getID(), 195 s.hasSuperclassSignature() ? new Opt(s.superclassSignature()) : getSuperClassAccessOptNoTransform(), 196 s.hasSuperinterfaceSignature() ? s.superinterfaceSignature() : getImplementsListNoTransform(), 197 getBodyDeclListNoTransform(), 198 s.typeParameters() 199 ), 200 index 201 ); 202 return (TypeDecl)node.getChildNoTransform(index); 203 } 204 else { 205 if(s.hasSuperclassSignature()) 206 setSuperClassAccessOpt(new Opt(s.superclassSignature())); 207 if(s.hasSuperinterfaceSignature()) 208 setImplementsList(s.superinterfaceSignature()); 209 return this; 210 } 211 } 212 213 public TypeDecl InterfaceDecl.makeGeneric(Signatures.ClassSignature s) { 214 if(s.hasFormalTypeParameters()) { 215 ASTNode node = getParent(); 216 int index = node.getIndexOfChild(this); 217 node.setChild( 218 new GenericInterfaceDecl( 219 getModifiersNoTransform(), 220 getID(), 221 s.hasSuperinterfaceSignature() ? s.superinterfaceSignature() : getSuperInterfaceIdListNoTransform(), 222 getBodyDeclListNoTransform(), 223 s.typeParameters() 224 ), 225 index 226 ); 227 return (TypeDecl)node.getChildNoTransform(index); 228 } 229 else { 230 if(s.hasSuperinterfaceSignature()) 231 setSuperInterfaceIdList(s.superinterfaceSignature()); 232 return this; 233 } 234 } 235 public TypeDecl GenericTypeDecl.makeGeneric(Signatures.ClassSignature s) { 236 return (TypeDecl)this; 237 } 238 239 240 interface ParTypeDecl { 241 //syn String name(); 242 int getNumArgument(); 243 Access getArgument(int index); 244 syn boolean isParameterizedType(); 245 syn boolean isRawType(); 246 public String typeName(); 247 SimpleSet localFields(String name); 248 HashMap localMethodsSignatureMap(); 249 } 250 ParClassDecl implements ParTypeDecl; 251 ParInterfaceDecl implements ParTypeDecl; 252 253 syn boolean TypeDecl.isParameterizedType() = false; 254 eq ParTypeDecl.isParameterizedType() = true; 255 256 syn boolean TypeDecl.isRawType() = isNestedType() && enclosingType().isRawType(); 257 eq ParClassDecl.isRawType() = isNestedType() && enclosingType().isRawType(); 258 eq ParInterfaceDecl.isRawType() = isNestedType() && enclosingType().isRawType(); 259 eq RawClassDecl.isRawType() = true; 260 eq RawInterfaceDecl.isRawType() = true; 261 } 262 263 aspect GenericsTypeAnalysis { 264 eq ParTypeAccess.unqualifiedScope() = getParent() instanceof Access ? ((Access)getParent()).unqualifiedScope() : super.unqualifiedScope(); 265 eq ParTypeAccess.getTypeArgument().lookupType(String name) = unqualifiedScope().lookupType(name); 266 267 eq Program.getChild().inExtendsOrImplements() = false; 268 eq ClassDecl.getSuperClassAccess().inExtendsOrImplements() = true; 269 eq ClassDecl.getImplements(int i).inExtendsOrImplements() = true; 270 eq InterfaceDecl.getSuperInterfaceId().inExtendsOrImplements() = true; 271 inh boolean Expr.inExtendsOrImplements(); 272 273 eq ParTypeAccess.type() { 274 TypeDecl typeDecl = genericDecl(); 275 if(typeDecl instanceof GenericTypeDecl) { 276 // use signature in lookup for types that are used in extends and implements clauses 277 if (unqualifiedScope().inExtendsOrImplements()) { 278 return ((GenericTypeDecl)typeDecl).lookupParTypeDecl(this); 279 } 280 ArrayList args = new ArrayList(); 281 for(int i = 0; i < getNumTypeArgument(); i++) 282 args.add(getTypeArgument(i).type()); 283 return ((GenericTypeDecl)typeDecl).lookupParTypeDecl(args); 284 } 285 return typeDecl; 286 } 287 syn TypeDecl ParTypeAccess.genericDecl() = getTypeAccess().type(); 288 eq ParTypeAccess.isTypeAccess() = true; 289 290 refine TypeScopePropagation eq TypeAccess.decl() { 291 TypeDecl decl = refined(); 292 if(decl instanceof GenericTypeDecl && isRaw()) 293 return ((GenericTypeDecl)decl).lookupParTypeDecl(new ArrayList()); 294 return decl; 295 } 296 297 // this method assumes that the bound type is generic 298 public boolean TypeAccess.isRaw() { 299 /* 300 if(hasNextAccess()) 301 return false; 302 */ 303 ASTNode parent = getParent(); 304 while(parent instanceof AbstractDot) 305 parent = parent.getParent(); 306 if(parent instanceof ParTypeAccess) 307 return false; 308 if(parent instanceof ImportDecl) 309 return false; 310 /* 311 Access a = this; 312 while(a.isTypeAccess() && hasNextAccess()) 313 a = a.nextAccess(); 314 if(a.isThisAccess() || a.isSuperAccess()) 315 return false; 316 */ 317 return true; 318 } 319 320 refine TypeScopePropagation eq ThisAccess.decl() { 321 TypeDecl typeDecl = refined(); 322 if(typeDecl instanceof ParTypeDecl) 323 typeDecl = ((ParTypeDecl)typeDecl).genericDecl(); 324 return typeDecl; 325 } 326 refine TypeScopePropagation eq SuperAccess.decl() { 327 TypeDecl typeDecl = refined(); 328 if(typeDecl instanceof ParTypeDecl) 329 typeDecl = ((ParTypeDecl)typeDecl).genericDecl(); 330 return typeDecl; 331 } 332 333 public boolean BoundTypeAccess.isRaw() { 334 return getTypeDecl().isRawType(); 335 } 336 public boolean ParTypeAccess.isRaw() { 337 return false; 338 } 339 340 } 341 342 aspect GenericsErasure { 343 syn lazy TypeDecl TypeDecl.erasure() { 344 if(isAnonymous() || isLocalClass()) 345 return this; 346 if(!isNestedType()) 347 return this; 348 return extractSingleType(enclosingType().erasure().memberTypes(name())); 349 } 350 eq ParClassDecl.erasure() = genericDecl(); 351 eq ParInterfaceDecl.erasure() = genericDecl(); 352 eq TypeVariable.erasure() = getTypeBound(0).type().erasure(); // Skip last erasure? 353 eq ArrayDecl.erasure() = componentType().erasure().arrayType(); 354 } 355 356 aspect GenericsTypeCheck { 357 358 // different parameterizations of the same generic interface may not be implemented 359 refine TypeHierarchyCheck public void TypeDecl.typeCheck() { 360 refined(); 361 ArrayList list = new ArrayList(); 362 list.addAll(implementedInterfaces()); 363 for(int i = 0; i < list.size(); i++) { 364 InterfaceDecl decl = (InterfaceDecl)list.get(i); 365 if(decl instanceof ParInterfaceDecl) { 366 ParInterfaceDecl p = (ParInterfaceDecl)decl; 367 for(Iterator i2 = list.listIterator(i); i2.hasNext(); ) { 368 InterfaceDecl decl2 = (InterfaceDecl)i2.next(); 369 if(decl2 instanceof ParInterfaceDecl) { 370 ParInterfaceDecl q = (ParInterfaceDecl)decl2; 371 if(p != q && p.genericDecl() == q.genericDecl() && !p.sameArgument(q)) 372 error(p.genericDecl().name() + " cannot be inherited with different arguments: " + 373 p.typeName() + " and " + q.typeName()); 374 } 375 } 376 } 377 } 378 } 379 380 syn boolean ParTypeDecl.sameArgument(ParTypeDecl decl) { 381 if(this == decl) return true; 382 if(genericDecl() != decl.genericDecl()) 383 return false; 384 for(int i = 0; i < getNumArgument(); i++) { 385 TypeDecl t1 = getArgument(i).type(); 386 TypeDecl t2 = decl.getArgument(i).type(); 387 if(t1 instanceof ParTypeDecl && t2 instanceof ParTypeDecl) { 388 if(!((ParTypeDecl)t1).sameArgument((ParTypeDecl)t2)) 389 return false; 390 } 391 else { 392 if(t1 != t2) 393 return false; 394 } 395 } 396 return true; 397 } 398 399 syn lazy HashSet TypeDecl.implementedInterfaces() = new HashSet(); 400 eq ClassDecl.implementedInterfaces() { 401 HashSet set = new HashSet(); 402 if(hasSuperclass()) 403 set.addAll(superclass().implementedInterfaces()); 404 for(Iterator iter = interfacesIterator(); iter.hasNext(); ) { 405 InterfaceDecl decl = (InterfaceDecl)iter.next(); 406 set.add(decl); 407 set.addAll(decl.implementedInterfaces()); 408 } 409 return set; 410 } 411 eq InterfaceDecl.implementedInterfaces() { 412 HashSet set= new HashSet(); 413 set.addAll(typeObject().implementedInterfaces()); 414 for(Iterator iter = superinterfacesIterator(); iter.hasNext(); ) { 415 InterfaceDecl decl = (InterfaceDecl)iter.next(); 416 set.add(decl); 417 set.addAll(decl.implementedInterfaces()); 418 } 419 return set; 420 } 421 422 423 424 425 public void GenericClassDecl.typeCheck() { 426 super.typeCheck(); 427 if(instanceOf(typeThrowable())) 428 error(" generic class " + typeName() + " may not directly or indirectly inherit java.lang.Throwable"); 429 } 430 public void GenericInterfaceDecl.typeCheck() { 431 super.typeCheck(); 432 if(instanceOf(typeThrowable())) 433 error(" generic interface " + typeName() + " may not directly or indirectly inherit java.lang.Throwable"); 434 } 435 inh TypeDecl GenericClassDecl.typeThrowable(); 436 inh TypeDecl GenericInterfaceDecl.typeThrowable(); 437 438 public void TypeAccess.typeCheck() { 439 TypeDecl type = type(); 440 if(type.isRawType() && type.isNestedType() && type.enclosingType().isParameterizedType() && !type.enclosingType().isRawType()) 441 error("Can not access a member type of a paramterized type as a raw type"); 442 } 443 444 public void ParTypeAccess.typeCheck() { 445 super.typeCheck(); 446 if(!genericDecl().isUnknown()) { 447 TypeDecl type = type(); 448 if(!genericDecl().isGenericType()) { 449 error(genericDecl().typeName() + " is not a generic type but used as one in " + this); 450 } 451 else if(!type.isRawType() && type.isNestedType() && type.enclosingType().isRawType()) 452 error("Can not access a member type of a raw type as a parameterized type"); 453 else { 454 GenericTypeDecl decl = (GenericTypeDecl)genericDecl(); 455 GenericTypeDecl original = (GenericTypeDecl)decl.original(); 456 if(original.getNumTypeParameter() != getNumTypeArgument()) { 457 error(decl.typeName() + " takes " + original.getNumTypeParameter() + " type parameters, not " + getNumTypeArgument() + " as used in " + this); 458 } 459 else { 460 ParTypeDecl typeDecl = (ParTypeDecl)type(); 461 for(int i = 0; i < getNumTypeArgument(); i++) { 462 if(!getTypeArgument(i).type().instanceOf(original.getTypeParameter(i))) { 463 error("type argument " + i + " is of type " + getTypeArgument(i).type().typeName() 464 + " which is not a subtype of " + original.getTypeParameter(i).typeName()); 465 } 466 } 467 } 468 } 469 } 470 } 471 472 } 473 474 aspect GenericsNameBinding { 475 476 eq ParClassDecl.getArgument().nameType() = NameType.TYPE_NAME; 477 eq ParInterfaceDecl.getArgument().nameType() = NameType.TYPE_NAME; 478 479 //eq GenericClassDecl.getParTypeDecl().isNestedType() = isNestedType(); 480 //eq GenericClassDecl.getParTypeDecl().enclosingType() = enclosingType(); 481 eq GenericClassDecl.getTypeParameter().isNestedType() = true; 482 eq GenericClassDecl.getTypeParameter().enclosingType() = this; 483 484 //eq GenericInterfaceDecl.getParTypeDecl().isNestedType() = isNestedType(); 485 //eq GenericInterfaceDecl.getParTypeDecl().enclosingType() = enclosingType(); 486 eq GenericInterfaceDecl.getTypeParameter().isNestedType() = true; 487 eq GenericInterfaceDecl.getTypeParameter().enclosingType() = this; 488 489 public SimpleSet GenericTypeDecl.addTypeVariables(SimpleSet c, String name) { 490 GenericTypeDecl original = (GenericTypeDecl)original(); 491 for(int i = 0; i < original.getNumTypeParameter(); i++) { 492 TypeVariable p = original.getTypeParameter(i); 493 if(p.name().equals(name)) 494 c = c.add(p); 495 } 496 return c; 497 } 498 499 eq GenericInterfaceDecl.getSuperInterfaceId().lookupType(String name) { 500 SimpleSet c = addTypeVariables(SimpleSet.emptySet, name); 501 return !c.isEmpty() ? c : lookupType(name); 502 } 503 eq GenericClassDecl.getSuperClassAccess().lookupType(String name) { 504 SimpleSet c = addTypeVariables(SimpleSet.emptySet, name); 505 return !c.isEmpty() ? c : lookupType(name); 506 } 507 eq GenericClassDecl.getImplements().lookupType(String name) { 508 SimpleSet c = addTypeVariables(SimpleSet.emptySet, name); 509 return !c.isEmpty() ? c : lookupType(name); 510 } 511 512 eq GenericTypeDecl.getTypeParameter().lookupType(String name) { 513 SimpleSet c = memberTypes(name); 514 c = addTypeVariables(c, name); 515 if(!c.isEmpty()) return c; 516 // 8.5.2 517 if(isClassDecl() && isStatic() && !isTopLevelType()) { 518 for(Iterator iter = lookupType(name).iterator(); iter.hasNext(); ) { 519 TypeDecl d = (TypeDecl)iter.next(); 520 if(d.isStatic() || (d.enclosingType() != null && instanceOf(d.enclosingType()))) { 521 c = c.add(d); 522 } 523 } 524 } 525 else 526 c = lookupType(name); 527 if(!c.isEmpty()) 528 return c; 529 return topLevelType().lookupType(name); // Fix to search imports 530 } 531 eq GenericTypeDecl.getBodyDecl(int index).lookupType(String name) { 532 SimpleSet c = memberTypes(name); 533 if(getBodyDecl(index).visibleTypeParameters()) 534 c = addTypeVariables(c, name); 535 if(!c.isEmpty()) 536 return c; 537 // 8.5.2 538 if(isClassDecl() && isStatic() && !isTopLevelType()) { 539 for(Iterator iter = lookupType(name).iterator(); iter.hasNext(); ) { 540 TypeDecl d = (TypeDecl)iter.next(); 541 if(d.isStatic() || (d.enclosingType() != null && instanceOf(d.enclosingType()))) { 542 c = c.add(d); 543 } 544 } 545 } 546 else 547 c = lookupType(name); 548 if(!c.isEmpty()) 549 return c; 550 return topLevelType().lookupType(name); // Fix to search imports 551 // include type parameters if not static 552 } 553 554 public void ParClassDecl.collectErrors() { 555 // Disable error check for ParClassDecl which is an instanciated GenericClassDecl 556 } 557 public void ParInterfaceDecl.collectErrors() { 558 // Disable error check for ParInterfaceDecl which is an instanciated GenericInterfaceDecl 559 } 560 561 } 562 aspect LookupParTypeDecl { 563 eq TypeVariable.fullName() { 564 if(getParent().getParent() instanceof TypeDecl) { 565 TypeDecl typeDecl = (TypeDecl)getParent().getParent(); 566 return typeDecl.fullName() + "@" + name(); 567 } 568 return super.fullName(); 569 } 570 571 syn boolean TypeDecl.sameSignature(Access a) { 572 if(a instanceof ParTypeAccess) return false; 573 if(a instanceof AbstractWildcard) return false; 574 return this == a.type(); 575 } 576 eq TypeVariable.sameSignature(Access a) = a.type() == this; 577 syn boolean ParTypeDecl.sameSignature(Access a){ 578 if(a instanceof ParTypeAccess) { 579 ParTypeAccess ta = (ParTypeAccess)a; 580 if(genericDecl() != ta.genericDecl()) 581 return false; 582 if(getNumArgument() != ta.getNumTypeArgument()) 583 return false; 584 for(int i = 0; i < getNumArgument(); i++) 585 if(!getArgument(i).type().sameSignature(ta.getTypeArgument(i))) 586 return false; 587 return true; 588 } 589 else if(a instanceof TypeAccess && ((TypeAccess)a).isRaw()) 590 return false; 591 return super.sameSignature(a); 592 } 593 eq RawClassDecl.sameSignature(Access a) = a instanceof TypeAccess && a.type() == this; 594 eq RawInterfaceDecl.sameSignature(Access a) = a instanceof TypeAccess && a.type() == this; 595 596 eq WildcardType.sameSignature(Access a) { 597 if(a instanceof Wildcard) 598 return true; 599 return super.sameSignature(a); 600 } 601 eq WildcardExtendsType.sameSignature(Access a) { 602 if(a instanceof WildcardExtends) 603 return getAccess().type().sameSignature(((WildcardExtends)a).getAccess()); 604 return super.sameSignature(a); 605 } 606 eq WildcardSuperType.sameSignature(Access a) { 607 if(a instanceof WildcardSuper) 608 return getAccess().type().sameSignature(((WildcardSuper)a).getAccess()); 609 return super.sameSignature(a); 610 } 611 612 syn lazy boolean ParTypeDecl.sameSignature(ArrayList list) circular [true] { 613 if(getNumArgument() != list.size()) 614 return false; 615 for(int i = 0; i < list.size(); i++) 616 if(getArgument(i).type() != list.get(i)) 617 return false; 618 return true; 619 } 620 621 // ES: removing these in benefit for parameterized syn nta attributes 622 //syn lazy final List GenericClassDecl.getParTypeDeclList() = new List(); 623 //syn lazy final List GenericInterfaceDecl.getParTypeDeclList() = new List(); 624 625 626 /* ES: replacing these: 627 syn lazy TypeDecl GenericTypeDecl.lookupParTypeDecl(ParTypeAccess p); 628 eq GenericClassDecl.lookupParTypeDecl(ParTypeAccess p) { 629 for(int i = 0; i < getNumParTypeDecl(); i++) { 630 ParTypeDecl decl = (ParTypeDecl)getParTypeDecl(i); 631 if(!decl.isRawType() && decl.sameSignature(p)) 632 return (TypeDecl)decl; 633 } 634 ParClassDecl typeDecl = new ParClassDecl(); 635 typeDecl.setModifiers((Modifiers)getModifiers().fullCopy()); 636 typeDecl.setID(getID()); 637 addParTypeDecl(typeDecl); 638 List list = new List(); 639 for(int i = 0; i < p.getNumTypeArgument(); i++) 640 list.add(p.getTypeArgument(i).type().createBoundAccess()); 641 typeDecl.setArgumentList(list); 642 // Here we should access typeDecl through an ordinary 643 // child accessor instead of setting is$Final directly, 644 // however doing so appears to cause unexpected behaviour! 645 typeDecl.is$Final = true; 646 return typeDecl; 647 } 648 eq GenericInterfaceDecl.lookupParTypeDecl(ParTypeAccess p) { 649 for(int i = 0; i < getNumParTypeDecl(); i++) { 650 ParTypeDecl decl = (ParTypeDecl)getParTypeDecl(i); 651 if(!decl.isRawType() && decl.sameSignature(p)) 652 return (TypeDecl)decl; 653 } 654 ParInterfaceDecl typeDecl = new ParInterfaceDecl(); 655 typeDecl.setModifiers((Modifiers)getModifiers().fullCopy()); 656 typeDecl.setID(getID()); 657 addParTypeDecl(typeDecl); 658 List list = new List(); 659 for(int i = 0; i < p.getNumTypeArgument(); i++) 660 list.add(p.getTypeArgument(i).type().createBoundAccess()); 661 typeDecl.setArgumentList(list); 662 // Here we should access typeDecl through an ordinary 663 // child accessor instead of setting is$Final directly, 664 // however doing so appears to cause unexpected behaviour! 665 typeDecl.is$Final = true; 666 return typeDecl; 667 } 668 669 // used by methods inference when looking up paramterizations from wildcards 670 syn lazy final TypeDecl GenericTypeDecl.lookupParTypeDecl(ArrayList list); 671 eq GenericClassDecl.lookupParTypeDecl(ArrayList list) { 672 for(int i = 0; i < getNumParTypeDecl(); i++) { 673 ParTypeDecl decl = (ParTypeDecl)getParTypeDecl(i); 674 if(decl.isRawType() ? list.isEmpty() : (!list.isEmpty() && decl.sameSignature(list))) 675 return (TypeDecl)decl; 676 } 677 ParClassDecl typeDecl = list.size() == 0 ? new RawClassDecl() : new ParClassDecl(); 678 typeDecl.setModifiers((Modifiers)getModifiers().fullCopy()); 679 typeDecl.setID(getID()); 680 addParTypeDecl(typeDecl); 681 typeDecl.setArgumentList(createArgumentList(list)); 682 // Here we should access typeDecl through an ordinary 683 // child accessor instead of setting is$Final directly, 684 // however doing so appears to cause unexpected behaviour! 685 typeDecl.is$Final = true; 686 return typeDecl; 687 } 688 eq GenericInterfaceDecl.lookupParTypeDecl(ArrayList list) { 689 for(int i = 0; i < getNumParTypeDecl(); i++) { 690 ParTypeDecl decl = (ParTypeDecl)getParTypeDecl(i); 691 if(decl.isRawType() ? list.isEmpty() : (!list.isEmpty() && decl.sameSignature(list))) 692 return (TypeDecl)decl; 693 } 694 ParInterfaceDecl typeDecl = list.size() == 0 ? new RawInterfaceDecl() : new ParInterfaceDecl(); 695 typeDecl.setModifiers((Modifiers)getModifiers().fullCopy()); 696 typeDecl.setID(getID()); 697 addParTypeDecl(typeDecl); 698 typeDecl.setArgumentList(createArgumentList(list)); 699 // Here we should access typeDecl through an ordinary 700 // child accessor instead of setting is$Final directly, 701 // however doing so appears to cause unexpected behaviour! 702 typeDecl.is$Final = true; 703 return typeDecl; 704 } 705 with: 706 */ 707 // Transforms the parameter and calls the lookupParTypeDecl attribute for ArrayList arguments 708 syn lazy TypeDecl GenericTypeDecl.lookupParTypeDecl(ParTypeAccess p) { 709 ArrayList typeArguments = new ArrayList(); 710 for(int i = 0; i < p.getNumTypeArgument(); i++) 711 typeArguments.add(p.getTypeArgument(i).type()); 712 return lookupParTypeDecl(typeArguments); 713 } 714 syn nta TypeDecl GenericTypeDecl.lookupParTypeDecl(ArrayList list); 715 eq GenericClassDecl.lookupParTypeDecl(ArrayList list) { 716 /* 717 int size = createParTypeDeclStub_ArrayList_list != null ? createParTypeDeclStub_ArrayList_list.numChildren : 0; 718 ParClassDecl typeDecl = (ParClassDecl)createParTypeDeclStub(list); 719 if (size < createParTypeDeclStub_ArrayList_list.numChildren) { 720 createParTypeDeclBody(list, typeDecl); 721 } 722 return typeDecl; 723 */ 724 725 ParClassDecl typeDecl = list.size() == 0 ? new RawClassDecl() : new ParClassDecl(); 726 typeDecl.setModifiers((Modifiers)getModifiers().fullCopy()); 727 typeDecl.setID(getID()); 728 // ES: trying to only so this for ParClassDecl and then later for RawClassDecl 729 if (!(typeDecl instanceof RawClassDecl)) 730 typeDecl.setArgumentList(createArgumentList(list)); 731 return typeDecl; 732 733 } 734 eq GenericInterfaceDecl.lookupParTypeDecl(ArrayList list) { 735 /* 736 int size = createParTypeDeclStub_ArrayList_list != null ? createParTypeDeclStub_ArrayList_list.numChildren : 0; 737 ParInterfaceDecl typeDecl = (ParInterfaceDecl)createParTypeDeclStub(list); 738 if (size < createParTypeDeclStub_ArrayList_list.numChildren) { 739 createParTypeDeclBody(list, typeDecl); 740 } 741 return typeDecl; 742 */ 743 744 ParInterfaceDecl typeDecl = list.size() == 0 ? new RawInterfaceDecl() : new ParInterfaceDecl(); 745 typeDecl.setModifiers((Modifiers)getModifiers().fullCopy()); 746 typeDecl.setID(getID()); 747 // ES: trying to only so this for ParInterfaceDecl and then later for RawInterfaceDecl 748 if (!(typeDecl instanceof RawInterfaceDecl)) 749 typeDecl.setArgumentList(createArgumentList(list)); 750 return typeDecl; 751 752 } 753 754 755 syn lazy final List RawClassDecl.getArgumentList() = ((GenericClassDecl)genericDecl()).createArgumentList(new ArrayList()); 756 syn lazy final List RawInterfaceDecl.getArgumentList() = ((GenericInterfaceDecl)genericDecl()).createArgumentList(new ArrayList()); 757 758 /* 759 syn nta TypeDecl GenericTypeDecl.createParTypeDeclStub(ArrayList list); 760 eq GenericClassDecl.createParTypeDeclStub(ArrayList list) { 761 ParClassDecl typeDecl = list.size() == 0 ? new RawClassDecl() : new ParClassDecl(); 762 return typeDecl; 763 } 764 eq GenericInterfaceDecl.createParTypeDeclStub(ArrayList list) { 765 ParInterfaceDecl typeDecl = list.size() == 0 ? new RawInterfaceDecl() : new ParInterfaceDecl(); 766 return typeDecl; 767 } 768 769 public TypeDecl GenericClassDecl.createParTypeDeclBody(ArrayList list, ParClassDecl typeDecl) { 770 typeDecl.setModifiers((Modifiers)getModifiers().fullCopy()); 771 typeDecl.setID(getID()); 772 typeDecl.setArgumentList(createArgumentList(list)); 773 return typeDecl; 774 } 775 776 public TypeDecl GenericInterfaceDecl.createParTypeDeclBody(ArrayList list, ParInterfaceDecl typeDecl) { 777 typeDecl.setModifiers((Modifiers)getModifiers().fullCopy()); 778 typeDecl.setID(getID()); 779 typeDecl.setArgumentList(createArgumentList(list)); 780 return typeDecl; 781 } 782 */ 783 784 785 /* ES: replacing this: 786 public List GenericTypeDecl.createArgumentList(ArrayList params) { 787 GenericTypeDecl original = (GenericTypeDecl)original(); 788 List list = new List(); 789 if(params.isEmpty()) 790 for(int i = 0; i < original.getNumTypeParameter(); i++) 791 list.add(original.getTypeParameter(i).erasure().createBoundAccess()); 792 else 793 for(Iterator iter = params.iterator(); iter.hasNext(); ) 794 list.add(((TypeDecl)iter.next()).createBoundAccess()); 795 return list; 796 } 797 with: 798 */ 799 public List GenericTypeDecl.createArgumentList(ArrayList params) { 800 GenericTypeDecl original = (GenericTypeDecl)original(); 801 List list = new List(); 802 if(params.isEmpty()) { 803 // Change: Don't add any thing to the list. 804 // Concern: The previous version seem to add the erasure of the type variable for some reason, 805 // maybe this is how the raw type is represented (?), but this doesn't really comply with the 806 // claim that raw types don't have any type variables...? 807 for(int i = 0; i < original.getNumTypeParameter(); i++) 808 list.add(original.getTypeParameter(i).erasure().createBoundAccess()); 809 } else 810 for(Iterator iter = params.iterator(); iter.hasNext(); ) 811 list.add(((TypeDecl)iter.next()).createBoundAccess()); 812 return list; 813 } 814 815 816 interface Parameterization { 817 boolean isRawType(); 818 TypeDecl substitute(TypeVariable typeVariable); 819 } 820 ParTypeDecl implements Parameterization; 821 822 interface MemberSubstitutor extends Parameterization { 823 TypeDecl original(); 824 void addBodyDecl(BodyDecl b); 825 TypeDecl substitute(TypeVariable typeVariable); 826 } 827 828 ParClassDecl implements MemberSubstitutor; 829 ParInterfaceDecl implements MemberSubstitutor; 830 ClassDeclSubstituted implements MemberSubstitutor; 831 InterfaceDeclSubstituted implements MemberSubstitutor; 832 GenericClassDeclSubstituted implements MemberSubstitutor; 833 GenericInterfaceDeclSubstituted implements MemberSubstitutor; 834 835 public TypeDecl TypeDecl.substitute(TypeVariable typeVariable) { 836 if(isTopLevelType()) 837 return typeVariable; 838 return enclosingType().substitute(typeVariable); 839 } 840 public TypeDecl ParTypeDecl.substitute(TypeVariable typeVariable) { 841 for(int i = 0; i < numTypeParameter(); i++) 842 if(typeParameter(i) == typeVariable) 843 return getArgument(i).type(); 844 return super.substitute(typeVariable); 845 } 846 public TypeDecl ParMethodDecl.substitute(TypeVariable typeVariable) { 847 for(int i = 0; i < numTypeParameter(); i++) 848 if(typeParameter(i) == typeVariable) 849 return getTypeArgument(i).type(); 850 return genericMethodDecl().hostType().substitute(typeVariable); 851 } 852 853 public int ParTypeDecl.numTypeParameter() { 854 return ((GenericTypeDecl)original()).getNumTypeParameter(); 855 } 856 public TypeVariable ParTypeDecl.typeParameter(int index) { 857 return ((GenericTypeDecl)original()).getTypeParameter(index); 858 } 859 ParMethodDecl implements Parameterization; 860 public boolean ParMethodDecl.isRawType() { 861 return false; 862 } 863 public boolean RawMethodDecl.isRawType() { 864 return true; 865 } 866 public int ParMethodDecl.numTypeParameter() { 867 return genericMethodDecl().original().getNumTypeParameter(); 868 } 869 public TypeVariable ParMethodDecl.typeParameter(int index) { 870 return genericMethodDecl().original().getTypeParameter(index); 871 } 872 873 public Access TypeDecl.substitute(Parameterization parTypeDecl) { 874 if(parTypeDecl instanceof ParTypeDecl && ((ParTypeDecl)parTypeDecl).genericDecl() == this) 875 return ((TypeDecl)parTypeDecl).createBoundAccess(); 876 if(isTopLevelType()) 877 return createBoundAccess(); 878 return enclosingType().substitute(parTypeDecl).qualifiesAccess(new TypeAccess(name())); 879 } 880 public Access ArrayDecl.substitute(Parameterization parTypeDecl) { 881 return new ArrayTypeAccess(componentType().substitute(parTypeDecl)); 882 } 883 public Access TypeVariable.substitute(Parameterization parTypeDecl) { 884 if(parTypeDecl.isRawType()) 885 return erasure().createBoundAccess(); 886 return parTypeDecl.substitute(this).createBoundAccess(); 887 } 888 public Access ParTypeDecl.substitute(Parameterization parTypeDecl) { 889 // TODO: include nesting as well.... 890 if(parTypeDecl.isRawType()) 891 return ((GenericTypeDecl)genericDecl()).rawType().createBoundAccess(); 892 if(!usesTypeVariable()) 893 return super.substitute(parTypeDecl); 894 List list = new List(); 895 for(int i = 0; i < getNumArgument(); i++) 896 list.add(getArgument(i).type().substitute(parTypeDecl)); 897 return new ParTypeAccess(genericDecl().createQualifiedAccess(), list); 898 } 899 public Access RawClassDecl.substitute(Parameterization parTypeDecl) { return createBoundAccess(); } 900 public Access RawInterfaceDecl.substitute(Parameterization parTypeDecl) { return createBoundAccess(); } 901 902 public Access WildcardExtendsType.substitute(Parameterization parTypeDecl) { 903 if(!usesTypeVariable()) 904 return super.substitute(parTypeDecl); 905 return new WildcardExtends(getAccess().type().substitute(parTypeDecl)); 906 } 907 public Access WildcardSuperType.substitute(Parameterization parTypeDecl) { 908 if(!usesTypeVariable()) 909 return super.substitute(parTypeDecl); 910 return new WildcardSuper(getAccess().type().substitute(parTypeDecl)); 911 } 912 913 public Access TypeDecl.substituteReturnType(Parameterization parTypeDecl) { 914 return substitute(parTypeDecl); 915 } 916 public Access ArrayDecl.substituteReturnType(Parameterization parTypeDecl) { 917 return new ArrayTypeAccess(componentType().substituteReturnType(parTypeDecl)); 918 } 919 inh TypeDecl TypeVariable.typeObject(); 920 921 syn lazy TypeDecl TypeVariable.lubType() { 922 ArrayList list = new ArrayList(); 923 for(int i = 0; i < getNumTypeBound(); i++) 924 list.add(getTypeBound(i).type()); 925 return lookupLUBType(list); 926 } 927 928 public Access TypeVariable.substituteReturnType(Parameterization parTypeDecl) { 929 if(parTypeDecl.isRawType()) 930 return erasure().createBoundAccess(); 931 TypeDecl typeDecl = parTypeDecl.substitute(this); 932 if(typeDecl instanceof WildcardType) { 933 // the bound of this type variable 934 return createBoundAccess(); 935 //return lubType().createBoundAccess(); 936 //return typeObject().createBoundAccess(); 937 } 938 else if(typeDecl instanceof WildcardExtendsType) { 939 if(typeDecl.instanceOf(this)) 940 return ((WildcardExtendsType)typeDecl).extendsType().createBoundAccess(); 941 else 942 return createBoundAccess(); 943 944 // the bound of this type variable of the bound of the wild card if it is more specific 945 //return ((WildcardExtendsType)typeDecl).extendsType().createBoundAccess(); 946 } 947 else if(typeDecl instanceof WildcardSuperType) { 948 // the bound of this type variable 949 return createBoundAccess(); 950 //return typeObject().createBoundAccess(); 951 } 952 return typeDecl.createBoundAccess(); 953 } 954 public Access RawClassDecl.substituteReturnType(Parameterization parTypeDecl) { return createBoundAccess(); } 955 public Access RawInterfaceDecl.substituteReturnType(Parameterization parTypeDecl) { return createBoundAccess(); } 956 957 public Access TypeDecl.substituteParameterType(Parameterization parTypeDecl) { 958 return substitute(parTypeDecl); 959 } 960 961 inh TypeDecl TypeVariable.typeNull(); 962 public Access TypeVariable.substituteParameterType(Parameterization parTypeDecl) { 963 if(parTypeDecl.isRawType()) 964 return erasure().createBoundAccess(); 965 TypeDecl typeDecl = parTypeDecl.substitute(this); 966 if(typeDecl instanceof WildcardType) 967 return typeNull().createQualifiedAccess(); 968 else if(typeDecl instanceof WildcardExtendsType) 969 return typeNull().createQualifiedAccess(); 970 else if(typeDecl instanceof WildcardSuperType) 971 return ((WildcardSuperType)typeDecl).superType().createBoundAccess(); 972 return typeDecl.createBoundAccess(); 973 } 974 public Access RawClassDecl.substituteParameterType(Parameterization parTypeDecl) { return createBoundAccess(); } 975 public Access RawInterfaceDecl.substituteParameterType(Parameterization parTypeDecl) { return createBoundAccess(); } 976 977 public List List.substitute(Parameterization parTypeDecl) { 978 List list = new List(); 979 for(int i = 0; i < getNumChild(); i++) { 980 ASTNode node = getChild(i); 981 if(node instanceof Access) { 982 Access a = (Access)node; 983 list.add(a.type().substitute(parTypeDecl)); 984 } 985 else if(node instanceof VariableArityParameterDeclaration) { 986 VariableArityParameterDeclaration p = (VariableArityParameterDeclaration)node; 987 list.add( 988 new VariableArityParameterDeclarationSubstituted( 989 (Modifiers)p.getModifiers().fullCopy(), 990 // use the type acces since VariableArity adds to the dimension 991 p.getTypeAccess().type().substituteParameterType(parTypeDecl), 992 p.getID(), 993 p 994 ) 995 ); 996 } 997 else if(node instanceof ParameterDeclaration) { 998 ParameterDeclaration p = (ParameterDeclaration)node; 999 list.add( 1000 new ParameterDeclarationSubstituted( 1001 (Modifiers)p.getModifiers().fullCopy(), 1002 p.type().substituteParameterType(parTypeDecl), 1003 p.getID(), 1004 p 1005 ) 1006 ); 1007 } 1008 else { 1009 throw new Error("Can only substitute lists of access nodes but node number " + i + " is of type " + node.getClass().getName()); 1010 } 1011 } 1012 return list; 1013 } 1014 1015 syn lazy Opt ParClassDecl.getSuperClassAccessOpt() { 1016 GenericClassDecl decl = (GenericClassDecl)genericDecl(); 1017 Opt opt; 1018 //System.err.println("Begin substituting extends clause"); 1019 if(decl.hasSuperClassAccess()) 1020 opt = new Opt((decl.getSuperClassAccess().type().substitute(this))); 1021 else 1022 opt = new Opt(); 1023 //System.err.println("End substituting extends clause"); 1024 return opt; 1025 } 1026 syn lazy List ParClassDecl.getImplementsList() { 1027 GenericClassDecl decl = (GenericClassDecl)genericDecl(); 1028 //System.err.println("Begin substituting implements list"); 1029 List list = decl.getImplementsList().substitute(this); 1030 //System.err.println("End substituting implements list"); 1031 return list; 1032 } 1033 // ES: Creating instance of List subclass instead 1034 //syn lazy List ParClassDecl.getBodyDeclList() = new List(); 1035 syn lazy List ParClassDecl.getBodyDeclList() = new BodyDeclList(); 1036 1037 syn lazy List ParInterfaceDecl.getSuperInterfaceIdList() { 1038 GenericInterfaceDecl decl = (GenericInterfaceDecl)genericDecl(); 1039 //System.err.println("Begin substituting implements list"); 1040 List list = decl.getSuperInterfaceIdList().substitute(this); 1041 //System.err.println("End substituting implements list"); 1042 return list; 1043 } 1044 1045 // ES: Creating instance of List subclass instead of List 1046 //syn lazy List ParInterfaceDecl.getBodyDeclList() = new List(); 1047 syn lazy List ParInterfaceDecl.getBodyDeclList() = new BodyDeclList(); 1048 1049 // ES: Adding creation of NTA list to types implementing MemberSubstitutor 1050 syn lazy List ClassDeclSubstituted.getBodyDeclList() = new BodyDeclList(); 1051 syn lazy List InterfaceDeclSubstituted.getBodyDeclList() = new BodyDeclList(); 1052 syn lazy List GenericClassDeclSubstituted.getBodyDeclList() = new BodyDeclList(); 1053 syn lazy List GenericInterfaceDeclSubstituted.getBodyDeclList() = new BodyDeclList(); 1054 1055 1056 syn boolean ASTNode.usesTypeVariable() { 1057 for(int i = 0; i < getNumChild(); i++) 1058 if(getChild(i).usesTypeVariable()) 1059 return true; 1060 return false; 1061 } 1062 syn lazy boolean MethodDecl.usesTypeVariable() = 1063 getModifiers().usesTypeVariable() || getTypeAccess().usesTypeVariable() || 1064 getParameterList().usesTypeVariable() || getExceptionList().usesTypeVariable(); 1065 syn lazy boolean FieldDeclaration.usesTypeVariable() = getTypeAccess().usesTypeVariable(); 1066 eq TypeAccess.usesTypeVariable() = decl().usesTypeVariable() || super.usesTypeVariable(); 1067 1068 syn lazy boolean TypeDecl.usesTypeVariable() circular [false] = isNestedType() && enclosingType().usesTypeVariable(); 1069 eq ParTypeDecl.usesTypeVariable() { 1070 if(super.usesTypeVariable()) 1071 return true; 1072 for(int i = 0; i < getNumArgument(); i++) 1073 if(getArgument(i).type().usesTypeVariable()) 1074 return true; 1075 return false; 1076 } 1077 eq GenericClassDecl.usesTypeVariable() = true; 1078 eq GenericInterfaceDecl.usesTypeVariable() = true; 1079 eq TypeVariable.usesTypeVariable() = true; 1080 eq WildcardExtendsType.usesTypeVariable() = getAccess().type().usesTypeVariable(); 1081 eq WildcardSuperType.usesTypeVariable() = getAccess().type().usesTypeVariable(); 1082 eq ArrayDecl.usesTypeVariable() = elementType().usesTypeVariable(); 1083 1084 syn lazy final HashMap MemberSubstitutor.localMethodsSignatureMap() { 1085 HashMap map = new HashMap(); 1086 for(Iterator iter = original().localMethodsIterator(); iter.hasNext(); ) { 1087 MethodDecl decl = (MethodDecl)iter.next(); 1088 1089 /* ES removing this: 1090 if(!decl.isStatic() && (decl.usesTypeVariable() || isRawType())) { 1091 BodyDecl b = decl.substitutedBodyDecl(this); 1092 addBodyDecl(b); 1093 // Here we should access b through an ordinary 1094 // child accessor instead of setting is$Final directly, 1095 // however doing so appears to cause unexpected behaviour! 1096 b.is$Final = true; 1097 decl = (MethodDecl) b; 1098 } 1099 map.put(decl.signature(), decl); 1100 * and replacing with: 1101 */ 1102 if(!decl.isStatic() && (decl.usesTypeVariable() || isRawType())) { 1103 BodyDecl copyDecl = ((BodyDeclList)getBodyDeclList()).localMethodSignatureCopy(decl, this); 1104 decl = (MethodDecl) copyDecl; 1105 } 1106 map.put(decl.signature(), decl); 1107 1108 } 1109 return map; 1110 } 1111 1112 1113 // ES: Adding NTA to keep copies in 1114 syn nta BodyDecl BodyDeclList.localMethodSignatureCopy(MethodDecl originalMethod, MemberSubstitutor m) { 1115 return originalMethod.substitutedBodyDecl(m); 1116 } 1117 1118 1119 syn lazy final SimpleSet MemberSubstitutor.localFields(String name) { 1120 SimpleSet set = SimpleSet.emptySet; 1121 for(Iterator iter = original().localFields(name).iterator(); iter.hasNext(); ) { 1122 FieldDeclaration f = (FieldDeclaration)iter.next(); 1123 1124 /* ES removing this: 1125 if(!f.isStatic() && (f.usesTypeVariable() || isRawType())) { 1126 BodyDecl b = f.substitutedBodyDecl(this); 1127 addBodyDecl(b); 1128 // Here we should access b through an ordinary 1129 // child accessor instead of setting is$Final directly, 1130 // however doing so appears to cause unexpected behaviour! 1131 b.is$Final = true; 1132 f = (FieldDeclaration) b; 1133 } 1134 set = set.add(f); 1135 * and replacing with: 1136 */ 1137 if(!f.isStatic() && (f.usesTypeVariable() || isRawType())) { 1138 BodyDecl fCopy = ((BodyDeclList)getBodyDeclList()).localFieldCopy(f, this); 1139 f = (FieldDeclaration) fCopy; 1140 } 1141 set = set.add(f); 1142 1143 } 1144 return set; 1145 } 1146 1147 // ES: Adding NTA to keep copies in 1148 syn nta BodyDecl BodyDeclList.localFieldCopy(FieldDeclaration originalDecl, MemberSubstitutor m) { 1149 return originalDecl.substitutedBodyDecl(m); 1150 } 1151 1152 1153 // TODO-ES: Add NTA for copies like above 1154 syn lazy final SimpleSet MemberSubstitutor.localTypeDecls(String name) circular [SimpleSet.emptySet] { 1155 SimpleSet set = SimpleSet.emptySet; 1156 for(Iterator iter = original().localTypeDecls(name).iterator(); iter.hasNext(); ) { 1157 TypeDecl t = (TypeDecl)iter.next(); 1158 1159 /* ES: removing this: 1160 if(t.isStatic()) 1161 set = set.add(t); 1162 else { 1163 BodyDecl b; 1164 TypeDecl typeDecl; 1165 if(t instanceof ClassDecl) { 1166 ClassDecl classDecl = (ClassDecl)t; 1167 typeDecl = classDecl.substitutedClassDecl(this); 1168 b = new MemberClassDecl((ClassDecl)typeDecl); 1169 addBodyDecl(b); 1170 // Here we should access b through an ordinary 1171 // child accessor instead of setting is$Final directly, 1172 // however doing so appears to cause unexpected behaviour! 1173 b.is$Final = true; 1174 set = set.add(typeDecl); 1175 } 1176 else if(t instanceof InterfaceDecl) { 1177 InterfaceDecl interfaceDecl = (InterfaceDecl)t; 1178 typeDecl = interfaceDecl.substitutedInterfaceDecl(this); 1179 b = new MemberInterfaceDecl((InterfaceDecl)typeDecl); 1180 addBodyDecl(b); 1181 // Here we should access b through an ordinary 1182 // child accessor instead of setting is$Final directly, 1183 // however doing so appears to cause unexpected behaviour! 1184 b.is$Final = true; 1185 set = set.add(typeDecl); 1186 } 1187 } 1188 * and replacing with: 1189 */ 1190 if(t.isStatic()) { 1191 set = set.add(t); 1192 } else if (t instanceof ClassDecl) { 1193 MemberClassDecl copy = ((BodyDeclList)getBodyDeclList()).localClassDeclCopy((ClassDecl)t, this); 1194 set = set.add(copy.getClassDecl()); 1195 } else if (t instanceof InterfaceDecl) { 1196 MemberInterfaceDecl copy = ((BodyDeclList)getBodyDeclList()).localInterfaceDeclCopy((InterfaceDecl)t, this); 1197 set = set.add(copy.getInterfaceDecl()); 1198 } 1199 } 1200 return set; 1201 } 1202 1203 // ES: adding NTA to store copies in 1204 syn nta MemberClassDecl BodyDeclList.localClassDeclCopy(ClassDecl originalDecl, MemberSubstitutor m) { 1205 ClassDecl copy = originalDecl.substitutedClassDecl(m); 1206 return new MemberClassDecl(copy); 1207 } 1208 syn nta MemberInterfaceDecl BodyDeclList.localInterfaceDeclCopy(InterfaceDecl originalDecl, MemberSubstitutor m) { 1209 InterfaceDecl copy = originalDecl.substitutedInterfaceDecl(m); 1210 return new MemberInterfaceDecl(copy); 1211 } 1212 1213 syn lazy Collection MemberSubstitutor.constructors() { 1214 Collection set = new ArrayList(); 1215 for(Iterator iter = original().constructors().iterator(); iter.hasNext(); ) { 1216 ConstructorDecl c = (ConstructorDecl)iter.next(); 1217 1218 /* ES: removing this: 1219 BodyDecl b = c.substitutedBodyDecl(this); 1220 addBodyDecl(b); 1221 // Here we should access b through an ordinary 1222 // child accessor instead of setting is$Final directly, 1223 // however doing so appears to cause unexpected behaviour! 1224 b.is$Final = true; 1225 * and replacing with: 1226 */ 1227 BodyDecl b = ((BodyDeclList)getBodyDeclList()).constructorCopy(c, this); 1228 set.add(b); 1229 } 1230 return set; 1231 } 1232 1233 // ES: adding NTA to store copies in 1234 syn nta BodyDecl BodyDeclList.constructorCopy(ConstructorDecl originalDecl, MemberSubstitutor m) { 1235 return originalDecl.substitutedBodyDecl(m); 1236 } 1237 1238 public BodyDecl BodyDecl.substitutedBodyDecl(Parameterization parTypeDecl) { 1239 throw new Error("Operation substitutedBodyDecl not supported for " + getClass().getName()); 1240 } 1241 1242 public BodyDecl MethodDecl.substitutedBodyDecl(Parameterization parTypeDecl) { 1243 //System.out.println("Begin substituting " + signature() + " in " + hostType().typeName() + " with " + parTypeDecl.typeSignature()); 1244 MethodDecl m = new MethodDeclSubstituted( 1245 (Modifiers)getModifiers().fullCopy(), 1246 getTypeAccess().type().substituteReturnType(parTypeDecl), 1247 getID(), 1248 getParameterList().substitute(parTypeDecl), 1249 getExceptionList().substitute(parTypeDecl), 1250 substituteBody(parTypeDecl), 1251 this 1252 ); 1253 //System.out.println("End substituting " + signature()); 1254 return m; 1255 } 1256 1257 public Opt MethodDecl.substituteBody(Parameterization parTypeDecl) { 1258 return new Opt(); 1259 } 1260 1261 public BodyDecl GenericMethodDecl.substitutedBodyDecl(Parameterization parTypeDecl) { 1262 //System.out.println("Begin substituting generic " + signature() + " in " + hostType().typeName() + " with " + parTypeDecl.typeSignature()); 1263 GenericMethodDecl m = new GenericMethodDecl( 1264 (Modifiers)getModifiers().fullCopy(), 1265 getTypeAccess().type().substituteReturnType(parTypeDecl), 1266 getID(), 1267 getParameterList().substitute(parTypeDecl), 1268 getExceptionList().substitute(parTypeDecl), 1269 new Opt(), 1270 (List)getTypeParameterList().fullCopy() 1271 ); 1272 m.original = this; 1273 //System.out.println("End substituting generic " + signature()); 1274 return m; 1275 } 1276 syn GenericMethodDecl GenericMethodDecl.original() = original != null ? original : this; 1277 public GenericMethodDecl GenericMethodDecl.original; 1278 1279 syn GenericConstructorDecl GenericConstructorDecl.original() = original != null ? original : this; 1280 public GenericConstructorDecl GenericConstructorDecl.original; 1281 1282 1283 public BodyDecl ConstructorDecl.substitutedBodyDecl(Parameterization parTypeDecl) { 1284 ConstructorDecl c = new ConstructorDeclSubstituted( 1285 (Modifiers)getModifiers().fullCopy(), 1286 getID(), 1287 getParameterList().substitute(parTypeDecl), 1288 getExceptionList().substitute(parTypeDecl), 1289 new Opt(), 1290 new Block(), 1291 this 1292 ); 1293 return c; 1294 } 1295 public BodyDecl FieldDeclaration.substitutedBodyDecl(Parameterization parTypeDecl) { 1296 FieldDeclaration f = new FieldDeclarationSubstituted( 1297 (Modifiers)getModifiers().fullCopy(), 1298 getTypeAccess().type().substituteReturnType(parTypeDecl), 1299 getID(), 1300 new Opt(), 1301 this 1302 ); 1303 return f; 1304 } 1305 1306 syn TypeDecl TypeDecl.original() = this; 1307 eq ClassDeclSubstituted.original() = getOriginal().original(); 1308 eq InterfaceDeclSubstituted.original() = getOriginal().original(); 1309 eq GenericClassDeclSubstituted.original() = getOriginal().original(); 1310 eq GenericInterfaceDeclSubstituted.original() = getOriginal().original(); 1311 eq ParTypeDecl.original() = genericDecl().original(); 1312 1313 public ClassDecl ClassDecl.substitutedClassDecl(Parameterization parTypeDecl) { 1314 ClassDecl c = new ClassDeclSubstituted( 1315 (Modifiers)getModifiers().fullCopy(), 1316 getID(), 1317 hasSuperClassAccess() ? new Opt(getSuperClassAccess().type().substitute(parTypeDecl)) : new Opt(), 1318 getImplementsList().substitute(parTypeDecl), 1319 // ES: new List(), 1320 this 1321 ); 1322 return c; 1323 } 1324 public ClassDecl GenericClassDecl.substitutedClassDecl(Parameterization parTypeDecl) { 1325 GenericClassDecl c = new GenericClassDeclSubstituted( 1326 (Modifiers)getModifiers().fullCopy(), 1327 getID(), 1328 hasSuperClassAccess() ? new Opt(getSuperClassAccess().type().substitute(parTypeDecl)) : new Opt(), 1329 getImplementsList().substitute(parTypeDecl), 1330 // ES: new List(), 1331 new List(), // delegates TypeParameter lookup to original 1332 this 1333 ); 1334 return c; 1335 } 1336 public InterfaceDecl InterfaceDecl.substitutedInterfaceDecl(Parameterization parTypeDecl) { 1337 InterfaceDecl c = new InterfaceDeclSubstituted( 1338 (Modifiers)getModifiers().fullCopy(), 1339 getID(), 1340 getSuperInterfaceIdList().substitute(parTypeDecl), 1341 // ES: new List(), 1342 this 1343 ); 1344 return c; 1345 } 1346 public InterfaceDecl GenericInterfaceDecl.substitutedInterfaceDecl(Parameterization parTypeDecl) { 1347 GenericInterfaceDecl c = new GenericInterfaceDeclSubstituted( 1348 (Modifiers)getModifiers().fullCopy(), 1349 getID(), 1350 getSuperInterfaceIdList().substitute(parTypeDecl), 1351 // ES: new List(), 1352 new List(), // delegates TypeParameter lookup to original 1353 this 1354 ); 1355 return c; 1356 } 1357 1358 syn nta WildcardsCompilationUnit Program.wildcards() { 1359 return new WildcardsCompilationUnit( 1360 "wildcards", 1361 new List(), 1362 new List() 1363 ); 1364 } 1365 1366 syn TypeDecl WildcardExtendsType.extendsType() = getAccess().type(); 1367 syn TypeDecl WildcardSuperType.superType() = getAccess().type(); 1368 1369 eq Wildcard.type() = typeWildcard(); 1370 eq WildcardExtends.type() = lookupWildcardExtends(getAccess().type()); 1371 eq WildcardSuper.type() = lookupWildcardSuper(getAccess().type()); 1372 inh TypeDecl WildcardSuper.lookupWildcardSuper(TypeDecl typeDecl); 1373 inh TypeDecl WildcardExtends.lookupWildcardExtends(TypeDecl typeDecl); 1374 inh TypeDecl Wildcard.typeWildcard(); 1375 1376 syn nta TypeDecl WildcardsCompilationUnit.typeWildcard() { 1377 TypeDecl decl = new WildcardType( 1378 new Modifiers(new List().add(new Modifier("public"))), 1379 "?", 1380 new List() 1381 ); 1382 return decl; 1383 } 1384 inh TypeDecl TypeDecl.typeWildcard(); 1385 eq Program.getChild().typeWildcard() = wildcards().typeWildcard(); 1386 1387 syn nta TypeDecl WildcardsCompilationUnit.lookupWildcardExtends(TypeDecl bound) { 1388 TypeDecl decl = new WildcardExtendsType( 1389 new Modifiers(new List().add(new Modifier("public"))), 1390 "? extends " + bound.fullName(), 1391 new List(), 1392 bound.createBoundAccess() 1393 ); 1394 return decl; 1395 } 1396 eq Program.getChild().lookupWildcardExtends(TypeDecl typeDecl) = wildcards().lookupWildcardExtends(typeDecl); 1397 inh TypeDecl TypeDecl.lookupWildcardExtends(TypeDecl typeDecl); 1398 syn TypeDecl TypeDecl.asWildcardExtends() = lookupWildcardExtends(this); 1399 1400 syn nta TypeDecl WildcardsCompilationUnit.lookupWildcardSuper(TypeDecl bound) { 1401 TypeDecl decl = new WildcardSuperType( 1402 new Modifiers(new List().add(new Modifier("public"))), 1403 "? super " + bound.fullName(), 1404 new List(), 1405 bound.createBoundAccess() 1406 ); 1407 return decl; 1408 } 1409 eq Program.getChild().lookupWildcardSuper(TypeDecl typeDecl) = wildcards().lookupWildcardSuper(typeDecl); 1410 inh TypeDecl TypeDecl.lookupWildcardSuper(TypeDecl typeDecl); 1411 syn TypeDecl TypeDecl.asWildcardSuper() = lookupWildcardSuper(this); 1412 1413 syn nta LUBType WildcardsCompilationUnit.lookupLUBType(Collection bounds) = createLUBType(bounds); 1414 public static LUBType WildcardsCompilationUnit.createLUBType(Collection bounds) { 1415 List boundList = new List(); 1416 StringBuffer name = new StringBuffer(); 1417 for(Iterator iter = bounds.iterator(); iter.hasNext(); ) { 1418 TypeDecl typeDecl = (TypeDecl)iter.next(); 1419 boundList.add(typeDecl.createBoundAccess()); 1420 name.append("& " + typeDecl.typeName()); 1421 } 1422 LUBType decl = new LUBType( 1423 new Modifiers(new List().add(new Modifier("public"))), 1424 name.toString(), 1425 new List(), 1426 boundList 1427 ); 1428 return decl; 1429 } 1430 inh LUBType TypeDecl.lookupLUBType(Collection bounds); 1431 eq Program.getChild().lookupLUBType(Collection bounds) = 1432 wildcards().lookupLUBType(bounds); 1433 1434 syn String LUBType.typeName() { 1435 if(getNumTypeBound() == 0) 1436 return "<NOTYPE>"; 1437 StringBuffer s = new StringBuffer(); 1438 s.append(getTypeBound(0).type().typeName()); 1439 for(int i = 1; i < getNumTypeBound(); i++) 1440 s.append(" & " + getTypeBound(i).type().typeName()); 1441 return s.toString(); 1442 } 1443 1444 public HashSet LUBType.implementedInterfaces(){ 1445 HashSet ret = new HashSet(); 1446 for (int i = 0; i < getNumTypeBound(); i++) { 1447 ret.addAll(getTypeBound(i).type().implementedInterfaces()); 1448 } 1449 return ret; 1450 } 1451 1452 syn nta GLBType WildcardsCompilationUnit.lookupGLBType(ArrayList bounds) { 1453 List boundList = new List(); 1454 StringBuffer name = new StringBuffer(); 1455 for(Iterator iter = bounds.iterator(); iter.hasNext(); ) { 1456 TypeDecl typeDecl = (TypeDecl)iter.next(); 1457 boundList.add(typeDecl.createBoundAccess()); 1458 name.append("& " + typeDecl.typeName()); 1459 } 1460 GLBType decl = new GLBType( 1461 new Modifiers(new List().add(new Modifier("public"))), 1462 name.toString(), 1463 new List(), 1464 boundList 1465 ); 1466 return decl; 1467 } 1468 inh GLBType TypeDecl.lookupGLBType(ArrayList bounds); 1469 eq Program.getChild().lookupGLBType(ArrayList bounds) = 1470 wildcards().lookupGLBType(bounds); 1471 1472 syn String GLBType.typeName() { 1473 if(getNumTypeBound() == 0) 1474 return "<NOTYPE>"; 1475 StringBuffer s = new StringBuffer(); 1476 s.append(getTypeBound(0).type().typeName()); 1477 for(int i = 1; i < getNumTypeBound(); i++) 1478 s.append(" & " + getTypeBound(i).type().typeName()); 1479 return s.toString(); 1480 } 1481 1482 public HashSet GLBType.implementedInterfaces(){ 1483 HashSet ret = new HashSet(); 1484 for (int i = 0; i < getNumTypeBound(); i++) { 1485 ret.addAll(getTypeBound(i).type().implementedInterfaces()); 1486 } 1487 return ret; 1488 } 1489 1490 } 1491 1492 1493 aspect NewGenerics { 1494 1495 public Access TypeVariable.createQualifiedAccess() { 1496 return createBoundAccess(); 1497 } 1498 1499 eq TypeVariable.accessibleFrom(TypeDecl type) = true; 1500 1501 eq TypeVariable.typeName() = name(); 1502 } 1503 aspect SourceDeclarations { 1504 syn lazy TypeDecl TypeDecl.sourceTypeDecl() = this; 1505 eq ParTypeDecl.sourceTypeDecl() = genericDecl().original().sourceTypeDecl(); 1506 eq ClassDeclSubstituted.sourceTypeDecl() = original().sourceTypeDecl(); 1507 eq InterfaceDeclSubstituted.sourceTypeDecl() = original().sourceTypeDecl(); 1508 eq GenericClassDeclSubstituted.sourceTypeDecl() = original().sourceTypeDecl(); 1509 eq GenericInterfaceDeclSubstituted.sourceTypeDecl() = original().sourceTypeDecl(); 1510 1511 syn lazy MethodDecl MethodDecl.sourceMethodDecl() = this; 1512 eq ParMethodDecl.sourceMethodDecl() = genericMethodDecl().original().sourceMethodDecl(); 1513 eq MethodDeclSubstituted.sourceMethodDecl() = getOriginal().sourceMethodDecl(); 1514 1515 syn lazy ConstructorDecl ConstructorDecl.sourceConstructorDecl() = this; 1516 eq ParConstructorDecl.sourceConstructorDecl() = genericConstructorDecl().original().sourceConstructorDecl(); 1517 eq ConstructorDeclSubstituted.sourceConstructorDecl() = getOriginal().sourceConstructorDecl(); 1518 1519 syn lazy Variable Variable.sourceVariableDecl(); 1520 eq VariableDeclaration.sourceVariableDecl() = this; 1521 eq FieldDeclaration.sourceVariableDecl() = this; 1522 eq FieldDeclarationSubstituted.sourceVariableDecl() = getOriginal().sourceVariableDecl(); 1523 eq ParameterDeclaration.sourceVariableDecl() = this; 1524 eq ParameterDeclarationSubstituted.sourceVariableDecl() = getOriginal().sourceVariableDecl(); 1525 1526 }