You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MemberCodeGen.java 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999-2004 Shigeru Chiba. All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. Alternatively, the contents of this file may be used under
  8. * the terms of the GNU Lesser General Public License Version 2.1 or later.
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. */
  15. package javassist.compiler;
  16. import javassist.*;
  17. import javassist.bytecode.*;
  18. import javassist.compiler.ast.*;
  19. /* Code generator methods depending on javassist.* classes.
  20. */
  21. public class MemberCodeGen extends CodeGen {
  22. protected MemberResolver resolver;
  23. protected CtClass thisClass;
  24. protected MethodInfo thisMethod;
  25. protected boolean resultStatic;
  26. public MemberCodeGen(Bytecode b, CtClass cc, ClassPool cp)
  27. {
  28. super(b);
  29. resolver = new MemberResolver(cp);
  30. thisClass = cc;
  31. thisMethod = null;
  32. }
  33. /**
  34. * Records the currently compiled method.
  35. */
  36. public void setThisMethod(CtMethod m) {
  37. thisMethod = m.getMethodInfo2();
  38. if (typeChecker != null)
  39. typeChecker.setThisMethod(thisMethod);
  40. }
  41. public CtClass getThisClass() { return thisClass; }
  42. /**
  43. * Returns the JVM-internal representation of this class name.
  44. */
  45. protected String getThisName() {
  46. return MemberResolver.javaToJvmName(thisClass.getName());
  47. }
  48. /**
  49. * Returns the JVM-internal representation of this super class name.
  50. */
  51. protected String getSuperName() throws CompileError {
  52. return MemberResolver.javaToJvmName(
  53. MemberResolver.getSuperclass(thisClass).getName());
  54. }
  55. protected void insertDefaultSuperCall() throws CompileError {
  56. bytecode.addAload(0);
  57. bytecode.addInvokespecial(MemberResolver.getSuperclass(thisClass),
  58. "<init>", "()V");
  59. }
  60. protected void atTryStmnt(Stmnt st) throws CompileError {
  61. Stmnt body = (Stmnt)st.getLeft();
  62. if (body == null)
  63. return;
  64. int start = bytecode.currentPc();
  65. body.accept(this);
  66. int end = bytecode.currentPc();
  67. if (start == end)
  68. throw new CompileError("empty try block");
  69. bytecode.addOpcode(Opcode.GOTO);
  70. int pc = bytecode.currentPc();
  71. bytecode.addIndex(0); // correct later
  72. int var = getMaxLocals();
  73. incMaxLocals(1);
  74. ASTList catchList = (ASTList)st.getRight().getLeft();
  75. while (catchList != null) {
  76. Pair p = (Pair)catchList.head();
  77. catchList = catchList.tail();
  78. Declarator decl = (Declarator)p.getLeft();
  79. Stmnt block = (Stmnt)p.getRight();
  80. decl.setLocalVar(var);
  81. CtClass type = resolver.lookupClassByJvmName(decl.getClassName());
  82. decl.setClassName(MemberResolver.javaToJvmName(type.getName()));
  83. bytecode.addExceptionHandler(start, end, bytecode.currentPc(),
  84. type);
  85. bytecode.growStack(1);
  86. bytecode.addAstore(var);
  87. if (block != null)
  88. block.accept(this);
  89. bytecode.addOpcode(Opcode.GOTO);
  90. bytecode.addIndex(pc - bytecode.currentPc());
  91. }
  92. Stmnt finallyBlock = (Stmnt)st.getRight().getRight().getLeft();
  93. if (finallyBlock != null)
  94. throw new CompileError(
  95. "sorry, finally has not been supported yet");
  96. bytecode.write16bit(pc, bytecode.currentPc() - pc + 1);
  97. hasReturned = false;
  98. }
  99. public void atNewExpr(NewExpr expr) throws CompileError {
  100. if (expr.isArray())
  101. atNewArrayExpr(expr);
  102. else {
  103. CtClass clazz = resolver.lookupClassByName(expr.getClassName());
  104. String cname = clazz.getName();
  105. ASTList args = expr.getArguments();
  106. bytecode.addNew(cname);
  107. bytecode.addOpcode(DUP);
  108. atMethodCallCore(clazz, MethodInfo.nameInit, args,
  109. false, true, -1, null);
  110. exprType = CLASS;
  111. arrayDim = 0;
  112. className = MemberResolver.javaToJvmName(cname);
  113. }
  114. }
  115. public void atNewArrayExpr(NewExpr expr) throws CompileError {
  116. if (expr.getInitializer() != null)
  117. throw new CompileError("array initializer is not supported");
  118. int type = expr.getArrayType();
  119. ASTList size = expr.getArraySize();
  120. ASTList classname = expr.getClassName();
  121. if (size.length() > 1) {
  122. atMultiNewArray(type, classname, size);
  123. return;
  124. }
  125. size.head().accept(this);
  126. exprType = type;
  127. arrayDim = 1;
  128. if (type == CLASS) {
  129. className = resolveClassName(classname);
  130. bytecode.addAnewarray(MemberResolver.jvmToJavaName(className));
  131. }
  132. else {
  133. className = null;
  134. int atype = 0;
  135. switch (type) {
  136. case BOOLEAN :
  137. atype = T_BOOLEAN;
  138. break;
  139. case CHAR :
  140. atype = T_CHAR;
  141. break;
  142. case FLOAT :
  143. atype = T_FLOAT;
  144. break;
  145. case DOUBLE :
  146. atype = T_DOUBLE;
  147. break;
  148. case BYTE :
  149. atype = T_BYTE;
  150. break;
  151. case SHORT :
  152. atype = T_SHORT;
  153. break;
  154. case INT :
  155. atype = T_INT;
  156. break;
  157. case LONG :
  158. atype = T_LONG;
  159. break;
  160. default :
  161. badNewExpr();
  162. break;
  163. }
  164. bytecode.addOpcode(NEWARRAY);
  165. bytecode.add(atype);
  166. }
  167. }
  168. private static void badNewExpr() throws CompileError {
  169. throw new CompileError("bad new expression");
  170. }
  171. protected void atMultiNewArray(int type, ASTList classname, ASTList size)
  172. throws CompileError
  173. {
  174. int count, dim;
  175. dim = size.length();
  176. for (count = 0; size != null; size = size.tail()) {
  177. ASTree s = size.head();
  178. if (s == null)
  179. break; // int[][][] a = new int[3][4][];
  180. ++count;
  181. s.accept(this);
  182. if (exprType != INT)
  183. throw new CompileError("bad type for array size");
  184. }
  185. String desc;
  186. exprType = type;
  187. arrayDim = dim;
  188. if (type == CLASS) {
  189. className = resolveClassName(classname);
  190. desc = toJvmArrayName(className, dim);
  191. }
  192. else
  193. desc = toJvmTypeName(type, dim);
  194. bytecode.addMultiNewarray(desc, count);
  195. }
  196. public void atCallExpr(CallExpr expr) throws CompileError {
  197. String mname = null;
  198. CtClass targetClass = null;
  199. ASTree method = expr.oprand1();
  200. ASTList args = (ASTList)expr.oprand2();
  201. boolean isStatic = false;
  202. boolean isSpecial = false;
  203. int aload0pos = -1;
  204. MemberResolver.Method cached = expr.getMethod();
  205. if (method instanceof Member) {
  206. mname = ((Member)method).get();
  207. targetClass = thisClass;
  208. if (inStaticMethod || (cached != null && cached.isStatic()))
  209. isStatic = true; // should be static
  210. else {
  211. aload0pos = bytecode.currentPc();
  212. bytecode.addAload(0); // this
  213. }
  214. }
  215. else if (method instanceof Keyword) { // constructor
  216. isSpecial = true;
  217. mname = MethodInfo.nameInit; // <init>
  218. targetClass = thisClass;
  219. if (inStaticMethod)
  220. throw new CompileError("a constructor cannot be static");
  221. else
  222. bytecode.addAload(0); // this
  223. if (((Keyword)method).get() == SUPER)
  224. targetClass = MemberResolver.getSuperclass(targetClass);
  225. }
  226. else if (method instanceof Expr) {
  227. Expr e = (Expr)method;
  228. mname = ((Symbol)e.oprand2()).get();
  229. int op = e.getOperator();
  230. if (op == MEMBER) { // static method
  231. targetClass
  232. = resolver.lookupClass(((Symbol)e.oprand1()).get(), false);
  233. isStatic = true;
  234. }
  235. else if (op == '.') {
  236. ASTree target = e.oprand1();
  237. if (target instanceof Keyword)
  238. if (((Keyword)target).get() == SUPER)
  239. isSpecial = true;
  240. try {
  241. target.accept(this);
  242. }
  243. catch (NoFieldException nfe) {
  244. if (nfe.getExpr() != target)
  245. throw nfe;
  246. // it should be a static method.
  247. exprType = CLASS;
  248. arrayDim = 0;
  249. className = nfe.getField(); // JVM-internal
  250. resolver.recordPackage(className);
  251. isStatic = true;
  252. }
  253. if (arrayDim > 0)
  254. targetClass = resolver.lookupClass(javaLangObject, true);
  255. else if (exprType == CLASS /* && arrayDim == 0 */)
  256. targetClass = resolver.lookupClassByJvmName(className);
  257. else
  258. badMethod();
  259. }
  260. else
  261. badMethod();
  262. }
  263. else
  264. fatal();
  265. atMethodCallCore(targetClass, mname, args, isStatic, isSpecial,
  266. aload0pos, cached);
  267. }
  268. private static void badMethod() throws CompileError {
  269. throw new CompileError("bad method");
  270. }
  271. /*
  272. * atMethodCallCore() is also called by doit() in NewExpr.ProceedForNew
  273. *
  274. * @param targetClass the class at which method lookup starts.
  275. * @param found not null if the method look has been already done.
  276. */
  277. public void atMethodCallCore(CtClass targetClass, String mname,
  278. ASTList args, boolean isStatic, boolean isSpecial,
  279. int aload0pos, MemberResolver.Method found)
  280. throws CompileError
  281. {
  282. int nargs = getMethodArgsLength(args);
  283. int[] types = new int[nargs];
  284. int[] dims = new int[nargs];
  285. String[] cnames = new String[nargs];
  286. if (!isStatic && found != null && found.isStatic()) {
  287. bytecode.addOpcode(POP);
  288. isStatic = true;
  289. }
  290. int stack = bytecode.getStackDepth();
  291. atMethodArgs(args, types, dims, cnames);
  292. // used by invokeinterface
  293. int count = bytecode.getStackDepth() - stack + 1;
  294. if (found == null)
  295. found = resolver.lookupMethod(targetClass, thisMethod, mname,
  296. types, dims, cnames, false);
  297. if (found == null) {
  298. String msg;
  299. if (mname.equals(MethodInfo.nameInit))
  300. msg = "constructor not found";
  301. else
  302. msg = "Method " + mname + " not found in "
  303. + targetClass.getName();
  304. throw new CompileError(msg);
  305. }
  306. atMethodCallCore2(targetClass, mname, isStatic, isSpecial,
  307. aload0pos, count, found);
  308. }
  309. private void atMethodCallCore2(CtClass targetClass, String mname,
  310. boolean isStatic, boolean isSpecial,
  311. int aload0pos, int count,
  312. MemberResolver.Method found)
  313. throws CompileError
  314. {
  315. CtClass declClass = found.declaring;
  316. MethodInfo minfo = found.info;
  317. String desc = minfo.getDescriptor();
  318. int acc = minfo.getAccessFlags();
  319. if (mname.equals(MethodInfo.nameInit)) {
  320. isSpecial = true;
  321. if (declClass != targetClass)
  322. throw new CompileError("no such a constructor");
  323. }
  324. else if ((acc & AccessFlag.PRIVATE) != 0) {
  325. if (declClass == thisClass)
  326. isSpecial = true;
  327. else {
  328. String orgName = mname;
  329. isSpecial = false;
  330. isStatic = true;
  331. String origDesc = desc;
  332. if ((acc & AccessFlag.STATIC) == 0)
  333. desc = Descriptor.insertParameter(declClass.getName(),
  334. origDesc);
  335. acc = AccessFlag.setPackage(acc) | AccessFlag.STATIC;
  336. mname = getAccessiblePrivate(mname, origDesc, desc,
  337. minfo, declClass);
  338. if (mname == null)
  339. throw new CompileError("Method " + orgName
  340. + " is private");
  341. }
  342. }
  343. boolean popTarget = false;
  344. if ((acc & AccessFlag.STATIC) != 0) {
  345. if (!isStatic) {
  346. /* this method is static but the target object is
  347. on stack. It must be popped out. If aload0pos >= 0,
  348. then the target object was pushed by aload_0. It is
  349. overwritten by NOP.
  350. */
  351. isStatic = true;
  352. if (aload0pos >= 0)
  353. bytecode.write(aload0pos, NOP);
  354. else
  355. popTarget = true;
  356. }
  357. bytecode.addInvokestatic(declClass, mname, desc);
  358. }
  359. else if (isSpecial) // if (isSpecial && notStatic(acc))
  360. bytecode.addInvokespecial(declClass, mname, desc);
  361. else if (declClass.isInterface())
  362. bytecode.addInvokeinterface(declClass, mname, desc, count);
  363. else
  364. if (isStatic)
  365. throw new CompileError(mname + " is not static");
  366. else
  367. bytecode.addInvokevirtual(declClass, mname, desc);
  368. setReturnType(desc, isStatic, popTarget);
  369. }
  370. /*
  371. * Finds (or adds if necessary) a hidden accessor if the method
  372. * is in an enclosing class.
  373. *
  374. * @param desc the descriptor of the method.
  375. * @param declClass the class declaring the method.
  376. */
  377. protected String getAccessiblePrivate(String methodName, String desc,
  378. String newDesc, MethodInfo minfo,
  379. CtClass declClass)
  380. throws CompileError
  381. {
  382. if (isEnclosing(declClass, thisClass)) {
  383. AccessorMaker maker = declClass.getAccessorMaker();
  384. if (maker == null)
  385. return null;
  386. else
  387. return maker.getMethodAccessor(methodName, desc, newDesc,
  388. minfo);
  389. }
  390. else
  391. return null; // cannot access this private method.
  392. }
  393. private boolean isEnclosing(CtClass outer, CtClass inner) {
  394. try {
  395. while (inner != null) {
  396. inner = inner.getDeclaringClass();
  397. if (inner == outer)
  398. return true;
  399. }
  400. }
  401. catch (NotFoundException e) {}
  402. return false;
  403. }
  404. public int getMethodArgsLength(ASTList args) {
  405. return ASTList.length(args);
  406. }
  407. public void atMethodArgs(ASTList args, int[] types, int[] dims,
  408. String[] cnames) throws CompileError {
  409. int i = 0;
  410. while (args != null) {
  411. ASTree a = args.head();
  412. a.accept(this);
  413. types[i] = exprType;
  414. dims[i] = arrayDim;
  415. cnames[i] = className;
  416. ++i;
  417. args = args.tail();
  418. }
  419. }
  420. void setReturnType(String desc, boolean isStatic, boolean popTarget)
  421. throws CompileError
  422. {
  423. int i = desc.indexOf(')');
  424. if (i < 0)
  425. badMethod();
  426. char c = desc.charAt(++i);
  427. int dim = 0;
  428. while (c == '[') {
  429. ++dim;
  430. c = desc.charAt(++i);
  431. }
  432. arrayDim = dim;
  433. if (c == 'L') {
  434. int j = desc.indexOf(';', i + 1);
  435. if (j < 0)
  436. badMethod();
  437. exprType = CLASS;
  438. className = desc.substring(i + 1, j);
  439. }
  440. else {
  441. exprType = MemberResolver.descToType(c);
  442. className = null;
  443. }
  444. int etype = exprType;
  445. if (isStatic) {
  446. if (popTarget) {
  447. if (is2word(etype, dim)) {
  448. bytecode.addOpcode(DUP2_X1);
  449. bytecode.addOpcode(POP2);
  450. bytecode.addOpcode(POP);
  451. }
  452. else if (etype == VOID)
  453. bytecode.addOpcode(POP);
  454. else {
  455. bytecode.addOpcode(SWAP);
  456. bytecode.addOpcode(POP);
  457. }
  458. }
  459. }
  460. }
  461. protected void atFieldAssign(Expr expr, int op, ASTree left,
  462. ASTree right, boolean doDup) throws CompileError
  463. {
  464. CtField f = fieldAccess(left);
  465. boolean is_static = resultStatic;
  466. if (op != '=' && !is_static)
  467. bytecode.addOpcode(DUP);
  468. int fi = atFieldRead(f, is_static, op == '=');
  469. int fType = exprType;
  470. int fDim = arrayDim;
  471. String cname = className;
  472. atAssignCore(expr, op, right, fType, fDim, cname);
  473. boolean is2w = is2word(fType, fDim);
  474. if (doDup) {
  475. int dup_code;
  476. if (is_static)
  477. dup_code = (is2w ? DUP2 : DUP);
  478. else
  479. dup_code = (is2w ? DUP2_X1 : DUP_X1);
  480. bytecode.addOpcode(dup_code);
  481. }
  482. if (is_static) {
  483. bytecode.add(PUTSTATIC);
  484. bytecode.growStack(is2w ? -2 : -1);
  485. }
  486. else {
  487. bytecode.add(PUTFIELD);
  488. bytecode.growStack(is2w ? -3 : -2);
  489. }
  490. bytecode.addIndex(fi);
  491. exprType = fType;
  492. arrayDim = fDim;
  493. className = cname;
  494. }
  495. /* overwritten in JvstCodeGen.
  496. */
  497. public void atMember(Member mem) throws CompileError {
  498. atFieldRead(mem);
  499. }
  500. protected void atFieldRead(ASTree expr) throws CompileError
  501. {
  502. CtField f = fieldAccess(expr);
  503. boolean is_static = resultStatic;
  504. atFieldRead(f, is_static, false);
  505. }
  506. private int atFieldRead(CtField f, boolean isStatic, boolean noRead)
  507. throws CompileError
  508. {
  509. FieldInfo finfo = f.getFieldInfo2();
  510. String type = finfo.getDescriptor();
  511. int fi = addFieldrefInfo(f, finfo, type);
  512. int i = 0;
  513. int dim = 0;
  514. char c = type.charAt(i);
  515. while (c == '[') {
  516. ++dim;
  517. c = type.charAt(++i);
  518. }
  519. arrayDim = dim;
  520. boolean is2byte = (c == 'J' || c == 'D');
  521. exprType = MemberResolver.descToType(c);
  522. if (c == 'L')
  523. className = type.substring(i + 1, type.indexOf(';', i + 1));
  524. else
  525. className = null;
  526. if (noRead)
  527. return fi;
  528. if (isStatic) {
  529. bytecode.add(GETSTATIC);
  530. bytecode.growStack(is2byte ? 2 : 1);
  531. }
  532. else {
  533. bytecode.add(GETFIELD);
  534. bytecode.growStack(is2byte ? 1 : 0);
  535. }
  536. bytecode.addIndex(fi);
  537. return fi;
  538. }
  539. protected int addFieldrefInfo(CtField f, FieldInfo finfo, String type) {
  540. ConstPool cp = bytecode.getConstPool();
  541. String cname = f.getDeclaringClass().getName();
  542. int ci = cp.addClassInfo(cname);
  543. String name = finfo.getName();
  544. return cp.addFieldrefInfo(ci, name, type);
  545. }
  546. protected void atFieldPlusPlus(int token, boolean isPost,
  547. ASTree oprand, Expr expr, boolean doDup)
  548. throws CompileError
  549. {
  550. CtField f = fieldAccess(oprand);
  551. boolean is_static = resultStatic;
  552. if (!is_static)
  553. bytecode.addOpcode(DUP);
  554. int fi = atFieldRead(f, is_static, false);
  555. int t = exprType;
  556. boolean is2w = is2word(t, arrayDim);
  557. int dup_code;
  558. if (is_static)
  559. dup_code = (is2w ? DUP2 : DUP);
  560. else
  561. dup_code = (is2w ? DUP2_X1 : DUP_X1);
  562. atPlusPlusCore(dup_code, doDup, token, isPost, expr);
  563. if (is_static) {
  564. bytecode.add(PUTSTATIC);
  565. bytecode.growStack(is2w ? -2 : -1);
  566. }
  567. else {
  568. bytecode.add(PUTFIELD);
  569. bytecode.growStack(is2w ? -3 : -2);
  570. }
  571. bytecode.addIndex(fi);
  572. }
  573. /* This method also returns a value in resultStatic.
  574. */
  575. protected CtField fieldAccess(ASTree expr) throws CompileError {
  576. if (expr instanceof Member) {
  577. String name = ((Member)expr).get();
  578. CtField f = null;
  579. try {
  580. f = thisClass.getField(name);
  581. }
  582. catch (NotFoundException e) {
  583. // EXPR might be part of a static member access?
  584. throw new NoFieldException(name, expr);
  585. }
  586. boolean is_static = Modifier.isStatic(f.getModifiers());
  587. if (!is_static)
  588. if (inStaticMethod)
  589. throw new CompileError(
  590. "not available in a static method: " + name);
  591. else
  592. bytecode.addAload(0); // this
  593. resultStatic = is_static;
  594. return f;
  595. }
  596. else if (expr instanceof Expr) {
  597. Expr e = (Expr)expr;
  598. int op = e.getOperator();
  599. if (op == MEMBER) {
  600. // static member by # (extension by Javassist)
  601. CtField f = resolver.lookupField(((Symbol)e.oprand1()).get(),
  602. (Symbol)e.oprand2());
  603. resultStatic = true;
  604. return f;
  605. }
  606. else if (op == '.') {
  607. CtField f = null;
  608. try {
  609. e.oprand1().accept(this);
  610. /* Don't call lookupFieldByJvmName2().
  611. * The left operand of . is not a class name but
  612. * a normal expression.
  613. */
  614. if (exprType == CLASS && arrayDim == 0)
  615. f = resolver.lookupFieldByJvmName(className,
  616. (Symbol)e.oprand2());
  617. else
  618. badLvalue();
  619. boolean is_static = Modifier.isStatic(f.getModifiers());
  620. if (is_static)
  621. bytecode.addOpcode(POP);
  622. resultStatic = is_static;
  623. return f;
  624. }
  625. catch (NoFieldException nfe) {
  626. if (nfe.getExpr() != e.oprand1())
  627. throw nfe;
  628. /* EXPR should be a static field.
  629. * If EXPR might be part of a qualified class name,
  630. * lookupFieldByJvmName2() throws NoFieldException.
  631. */
  632. Symbol fname = (Symbol)e.oprand2();
  633. String cname = nfe.getField();
  634. f = resolver.lookupFieldByJvmName2(cname, fname, expr);
  635. resolver.recordPackage(cname);
  636. resultStatic = true;
  637. return f;
  638. }
  639. }
  640. else
  641. badLvalue();
  642. }
  643. else
  644. badLvalue();
  645. resultStatic = false;
  646. return null; // never reach
  647. }
  648. private static void badLvalue() throws CompileError {
  649. throw new CompileError("bad l-value");
  650. }
  651. public CtClass[] makeParamList(MethodDecl md) throws CompileError {
  652. CtClass[] params;
  653. ASTList plist = md.getParams();
  654. if (plist == null)
  655. params = new CtClass[0];
  656. else {
  657. int i = 0;
  658. params = new CtClass[plist.length()];
  659. while (plist != null) {
  660. params[i++] = resolver.lookupClass((Declarator)plist.head());
  661. plist = plist.tail();
  662. }
  663. }
  664. return params;
  665. }
  666. public CtClass[] makeThrowsList(MethodDecl md) throws CompileError {
  667. CtClass[] clist;
  668. ASTList list = md.getThrows();
  669. if (list == null)
  670. return null;
  671. else {
  672. int i = 0;
  673. clist = new CtClass[list.length()];
  674. while (list != null) {
  675. clist[i++] = resolver.lookupClassByName((ASTList)list.head());
  676. list = list.tail();
  677. }
  678. return clist;
  679. }
  680. }
  681. /* Converts a class name into a JVM-internal representation.
  682. *
  683. * It may also expand a simple class name to java.lang.*.
  684. * For example, this converts Object into java/lang/Object.
  685. */
  686. protected String resolveClassName(ASTList name) throws CompileError {
  687. return resolver.resolveClassName(name);
  688. }
  689. /* Expands a simple class name to java.lang.*.
  690. * For example, this converts Object into java/lang/Object.
  691. */
  692. protected String resolveClassName(String jvmName) throws CompileError {
  693. return resolver.resolveJvmClassName(jvmName);
  694. }
  695. }