46 import static com.sun.tools.javac.code.Flags.*; |
46 import static com.sun.tools.javac.code.Flags.*; |
47 import static com.sun.tools.javac.code.Scope.*; |
47 import static com.sun.tools.javac.code.Scope.*; |
48 import static com.sun.tools.javac.code.Symbol.*; |
48 import static com.sun.tools.javac.code.Symbol.*; |
49 import static com.sun.tools.javac.code.Type.*; |
49 import static com.sun.tools.javac.code.Type.*; |
50 import static com.sun.tools.javac.code.TypeTag.*; |
50 import static com.sun.tools.javac.code.TypeTag.*; |
|
51 import static com.sun.tools.javac.jvm.ClassFile.externalize; |
51 import static com.sun.tools.javac.util.ListBuffer.lb; |
52 import static com.sun.tools.javac.util.ListBuffer.lb; |
52 |
53 |
53 /** |
54 /** |
54 * Utility class containing various operations on types. |
55 * Utility class containing various operations on types. |
55 * |
56 * |
4352 } |
4353 } |
4353 } |
4354 } |
4354 return vis; |
4355 return vis; |
4355 } |
4356 } |
4356 // </editor-fold> |
4357 // </editor-fold> |
|
4358 |
|
4359 // <editor-fold defaultstate="collapsed" desc="Signature Generation"> |
|
4360 |
|
4361 public static abstract class SignatureGenerator { |
|
4362 |
|
4363 private final Types types; |
|
4364 |
|
4365 protected abstract void append(char ch); |
|
4366 protected abstract void append(byte[] ba); |
|
4367 protected abstract void append(Name name); |
|
4368 protected void classReference(ClassSymbol c) { /* by default: no-op */ } |
|
4369 |
|
4370 protected SignatureGenerator(Types types) { |
|
4371 this.types = types; |
|
4372 } |
|
4373 |
|
4374 /** |
|
4375 * Assemble signature of given type in string buffer. |
|
4376 */ |
|
4377 public void assembleSig(Type type) { |
|
4378 type = type.unannotatedType(); |
|
4379 switch (type.getTag()) { |
|
4380 case BYTE: |
|
4381 append('B'); |
|
4382 break; |
|
4383 case SHORT: |
|
4384 append('S'); |
|
4385 break; |
|
4386 case CHAR: |
|
4387 append('C'); |
|
4388 break; |
|
4389 case INT: |
|
4390 append('I'); |
|
4391 break; |
|
4392 case LONG: |
|
4393 append('J'); |
|
4394 break; |
|
4395 case FLOAT: |
|
4396 append('F'); |
|
4397 break; |
|
4398 case DOUBLE: |
|
4399 append('D'); |
|
4400 break; |
|
4401 case BOOLEAN: |
|
4402 append('Z'); |
|
4403 break; |
|
4404 case VOID: |
|
4405 append('V'); |
|
4406 break; |
|
4407 case CLASS: |
|
4408 append('L'); |
|
4409 assembleClassSig(type); |
|
4410 append(';'); |
|
4411 break; |
|
4412 case ARRAY: |
|
4413 ArrayType at = (ArrayType) type; |
|
4414 append('['); |
|
4415 assembleSig(at.elemtype); |
|
4416 break; |
|
4417 case METHOD: |
|
4418 MethodType mt = (MethodType) type; |
|
4419 append('('); |
|
4420 assembleSig(mt.argtypes); |
|
4421 append(')'); |
|
4422 assembleSig(mt.restype); |
|
4423 if (hasTypeVar(mt.thrown)) { |
|
4424 for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) { |
|
4425 append('^'); |
|
4426 assembleSig(l.head); |
|
4427 } |
|
4428 } |
|
4429 break; |
|
4430 case WILDCARD: { |
|
4431 Type.WildcardType ta = (Type.WildcardType) type; |
|
4432 switch (ta.kind) { |
|
4433 case SUPER: |
|
4434 append('-'); |
|
4435 assembleSig(ta.type); |
|
4436 break; |
|
4437 case EXTENDS: |
|
4438 append('+'); |
|
4439 assembleSig(ta.type); |
|
4440 break; |
|
4441 case UNBOUND: |
|
4442 append('*'); |
|
4443 break; |
|
4444 default: |
|
4445 throw new AssertionError(ta.kind); |
|
4446 } |
|
4447 break; |
|
4448 } |
|
4449 case TYPEVAR: |
|
4450 append('T'); |
|
4451 append(type.tsym.name); |
|
4452 append(';'); |
|
4453 break; |
|
4454 case FORALL: |
|
4455 Type.ForAll ft = (Type.ForAll) type; |
|
4456 assembleParamsSig(ft.tvars); |
|
4457 assembleSig(ft.qtype); |
|
4458 break; |
|
4459 default: |
|
4460 throw new AssertionError("typeSig " + type.getTag()); |
|
4461 } |
|
4462 } |
|
4463 |
|
4464 public boolean hasTypeVar(List<Type> l) { |
|
4465 while (l.nonEmpty()) { |
|
4466 if (l.head.hasTag(TypeTag.TYPEVAR)) { |
|
4467 return true; |
|
4468 } |
|
4469 l = l.tail; |
|
4470 } |
|
4471 return false; |
|
4472 } |
|
4473 |
|
4474 public void assembleClassSig(Type type) { |
|
4475 type = type.unannotatedType(); |
|
4476 ClassType ct = (ClassType) type; |
|
4477 ClassSymbol c = (ClassSymbol) ct.tsym; |
|
4478 classReference(c); |
|
4479 Type outer = ct.getEnclosingType(); |
|
4480 if (outer.allparams().nonEmpty()) { |
|
4481 boolean rawOuter = |
|
4482 c.owner.kind == Kinds.MTH || // either a local class |
|
4483 c.name == types.names.empty; // or anonymous |
|
4484 assembleClassSig(rawOuter |
|
4485 ? types.erasure(outer) |
|
4486 : outer); |
|
4487 append('.'); |
|
4488 Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname)); |
|
4489 append(rawOuter |
|
4490 ? c.flatname.subName(c.owner.enclClass().flatname.getByteLength() + 1, c.flatname.getByteLength()) |
|
4491 : c.name); |
|
4492 } else { |
|
4493 append(externalize(c.flatname)); |
|
4494 } |
|
4495 if (ct.getTypeArguments().nonEmpty()) { |
|
4496 append('<'); |
|
4497 assembleSig(ct.getTypeArguments()); |
|
4498 append('>'); |
|
4499 } |
|
4500 } |
|
4501 |
|
4502 public void assembleParamsSig(List<Type> typarams) { |
|
4503 append('<'); |
|
4504 for (List<Type> ts = typarams; ts.nonEmpty(); ts = ts.tail) { |
|
4505 Type.TypeVar tvar = (Type.TypeVar) ts.head; |
|
4506 append(tvar.tsym.name); |
|
4507 List<Type> bounds = types.getBounds(tvar); |
|
4508 if ((bounds.head.tsym.flags() & INTERFACE) != 0) { |
|
4509 append(':'); |
|
4510 } |
|
4511 for (List<Type> l = bounds; l.nonEmpty(); l = l.tail) { |
|
4512 append(':'); |
|
4513 assembleSig(l.head); |
|
4514 } |
|
4515 } |
|
4516 append('>'); |
|
4517 } |
|
4518 |
|
4519 private void assembleSig(List<Type> types) { |
|
4520 for (List<Type> ts = types; ts.nonEmpty(); ts = ts.tail) { |
|
4521 assembleSig(ts.head); |
|
4522 } |
|
4523 } |
|
4524 } |
|
4525 // </editor-fold> |
4357 } |
4526 } |