diff options
Diffstat (limited to 'src/main')
47 files changed, 863 insertions, 476 deletions
diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index 128d8b20..3b73f8ac 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -71,6 +71,8 @@ public abstract class CtClass { */ public static final String version = "3.30.2-GA"; + private int linesCount = 0; + /** * Prints the version number and the copyright notice. * @@ -1575,6 +1577,14 @@ public abstract class CtClass { new DelayedFileOutputStream(filename))); } + public int getLinesCount() { + return linesCount; + } + + void addLines(int count) { + this.linesCount += count; + } + /** * Writes a class file as <code>writeFile()</code> does although this * method does not prune or freeze the class after writing the class diff --git a/src/main/javassist/CtNewConstructor.java b/src/main/javassist/CtNewConstructor.java index 9f4225f1..ed3e379b 100644 --- a/src/main/javassist/CtNewConstructor.java +++ b/src/main/javassist/CtNewConstructor.java @@ -69,6 +69,7 @@ public class CtNewConstructor { Javac compiler = new Javac(declaring); try { CtMember obj = compiler.compile(src); + declaring.addLines(src.split("\n").length); if (obj instanceof CtConstructor) { // a stack map table has been already created. return (CtConstructor)obj; diff --git a/src/main/javassist/CtNewMethod.java b/src/main/javassist/CtNewMethod.java index 3daaa026..2cd363b0 100644 --- a/src/main/javassist/CtNewMethod.java +++ b/src/main/javassist/CtNewMethod.java @@ -77,6 +77,7 @@ public class CtNewMethod { compiler.recordProceed(delegateObj, delegateMethod); CtMember obj = compiler.compile(src); + declaring.addLines(src.split("\n").length); if (obj instanceof CtMethod) return (CtMethod)obj; } diff --git a/src/main/javassist/bytecode/CodeAttribute.java b/src/main/javassist/bytecode/CodeAttribute.java index 091edf4c..cf8806ef 100644 --- a/src/main/javassist/bytecode/CodeAttribute.java +++ b/src/main/javassist/bytecode/CodeAttribute.java @@ -353,6 +353,20 @@ public class CodeAttribute extends AttributeInfo implements Opcode { } /** + * Adds a line number table. If another copy of line number table + * is already contained, the old one is removed. + * + * @param lnt the line number table added to this code attribute. + * If it is null, a new line number is not added. + * Only the old line number is removed. + */ + public void setAttribute(LineNumberAttribute lnt) { + AttributeInfo.remove(attributes, LineNumberAttribute.tag); + if (lnt != null) + attributes.add(lnt); + } + + /** * Copies code. */ private byte[] copyCode(ConstPool destCp, Map<String,String> classnames, diff --git a/src/main/javassist/bytecode/LineNumberAttribute.java b/src/main/javassist/bytecode/LineNumberAttribute.java index cead96e0..16b37377 100644 --- a/src/main/javassist/bytecode/LineNumberAttribute.java +++ b/src/main/javassist/bytecode/LineNumberAttribute.java @@ -35,7 +35,7 @@ public class LineNumberAttribute extends AttributeInfo { super(cp, n, in); } - private LineNumberAttribute(ConstPool cp, byte[] i) { + LineNumberAttribute(ConstPool cp, byte[] i) { super(cp, tag, i); } diff --git a/src/main/javassist/bytecode/LineNumberAttributeBuilder.java b/src/main/javassist/bytecode/LineNumberAttributeBuilder.java new file mode 100644 index 00000000..52d9d0c8 --- /dev/null +++ b/src/main/javassist/bytecode/LineNumberAttributeBuilder.java @@ -0,0 +1,40 @@ +package javassist.bytecode; + +import javassist.compiler.ast.ASTree; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class LineNumberAttributeBuilder { + private final HashMap<Integer, Integer> map = new HashMap<>(); + + public void put(int newPc, ASTree tree) { + if (tree != null) + put(newPc, tree.getLineNumber()); + } + + private void put(int newPc, int lineNum) { + Integer pc = map.get(lineNum); + if (pc == null || newPc < pc) { + map.put(lineNum, newPc); + } + } + + public LineNumberAttribute build(ConstPool cp) { + int size = map.size(); + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(size * 4 + 2); + DataOutputStream dos = new DataOutputStream(bos)) { + dos.writeShort(size); + for (Map.Entry<Integer, Integer> entry : map.entrySet()) { + dos.writeShort(entry.getValue()); + dos.writeShort(entry.getKey()); + } + return new LineNumberAttribute(cp, bos.toByteArray()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/javassist/compiler/CodeGen.java b/src/main/javassist/compiler/CodeGen.java index e3115617..e7e274b9 100644 --- a/src/main/javassist/compiler/CodeGen.java +++ b/src/main/javassist/compiler/CodeGen.java @@ -121,8 +121,8 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { typeChecker = checker; } - protected static void fatal() throws CompileError { - throw new CompileError("fatal"); + protected static void fatal(int lineNumber) throws CompileError { + throw new CompileError("fatal", lineNumber); } public static boolean is2word(int type, int dim) { @@ -184,7 +184,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { /* Expands a simple class name to java.lang.*. * For example, this converts Object into java/lang/Object. */ - protected abstract String resolveClassName(String jvmClassName) + protected abstract String resolveClassName(String jvmClassName, int lineNumber) throws CompileError; /** @@ -267,13 +267,13 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { } @Override - public void atASTList(ASTList n) throws CompileError { fatal(); } + public void atASTList(ASTList n) throws CompileError { fatal(n.getLineNumber()); } @Override - public void atPair(Pair n) throws CompileError { fatal(); } + public void atPair(Pair n) throws CompileError { fatal(n.getLineNumber()); } @Override - public void atSymbol(Symbol n) throws CompileError { fatal(); } + public void atSymbol(Symbol n) throws CompileError { fatal(n.getLineNumber()); } @Override public void atFieldDecl(FieldDecl field) throws CompileError { @@ -325,7 +325,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { hasReturned = true; } else - throw new CompileError("no return statement"); + throw new CompileError("no return statement", s.getLineNumber()); } private boolean needsSuperCall(Stmnt body) throws CompileError { @@ -403,7 +403,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { // LABEL, SWITCH label stament might be null?. hasReturned = false; throw new CompileError( - "sorry, not supported statement: TokenId " + op); + "sorry, not supported statement: TokenId " + op, st.getLineNumber()); } } @@ -590,7 +590,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { if (op == DEFAULT) defaultPc = bytecode.currentPc(); else if (op != CASE) - fatal(); + fatal(st.getLineNumber()); else { int curPos = bytecode.currentPc(); long caseLabel; @@ -638,7 +638,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { expr = TypeChecker.stripPlusExpr(expr); if (expr instanceof IntConst) return (int)((IntConst)expr).get(); - throw new CompileError("bad case label"); + throw new CompileError("bad case label", expr.getLineNumber()); } private int computeStringLabel(ASTree expr, int tmpVar, List<Integer> gotoDefaults) @@ -658,7 +658,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { gotoDefaults.add(pc); return (int)label.hashCode(); } - throw new CompileError("bad case label"); + throw new CompileError("bad case label", expr.getLineNumber()); } private void atBreakStmnt(Stmnt st, boolean notCont) @@ -666,7 +666,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { { if (st.head() != null) throw new CompileError( - "sorry, not support labeled break or continue"); + "sorry, not support labeled break or continue", st.getLineNumber()); bytecode.addOpcode(Opcode.GOTO); Integer pc = Integer.valueOf(bytecode.currentPc()); @@ -718,7 +718,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { ASTree e = st.getLeft(); compileExpr(e); if (exprType != CLASS || arrayDim > 0) - throw new CompileError("bad throw statement"); + throw new CompileError("bad throw statement", st.getLineNumber()); bytecode.addOpcode(ATHROW); hasReturned = true; @@ -736,7 +736,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { compileExpr(st.head()); if (exprType != CLASS && arrayDim == 0) - throw new CompileError("bad type expr for synchronized block"); + throw new CompileError("bad type expr for synchronized block", st.getLineNumber()); Bytecode bc = bytecode; final int var = bc.getMaxLocals(); @@ -783,7 +783,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { if (getListSize(breakList) != nbreaks || getListSize(continueList) != ncontinues) throw new CompileError( - "sorry, cannot break/continue in synchronized block"); + "sorry, cannot break/continue in synchronized block", st.getLineNumber()); } private static int getListSize(List<Integer> list) { @@ -802,7 +802,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { @Override public void atDeclarator(Declarator d) throws CompileError { d.setLocalVar(getMaxLocals()); - d.setClassName(resolveClassName(d.getClassName())); + d.setClassName(resolveClassName(d.getClassName(), d.getLineNumber())); int size; if (is2word(d.getType(), d.getArrayDim())) @@ -863,7 +863,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { else msg = "incompatible type for " + expr.getName(); - throw new CompileError(msg); + throw new CompileError(msg, expr.getLineNumber()); } /* op is either =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, or >>>=. @@ -962,7 +962,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { int token = assignOps[op - MOD_E]; int k = lookupBinOp(token); if (k < 0) - fatal(); + fatal(right.getLineNumber()); atArithBinExpr(expr, token, k, type); } @@ -981,9 +981,9 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { if (!jvmJavaLangString.equals(cname)) badAssign(expr); - convToString(type, dim); // the value might be null. + convToString(type, dim, expr.getLineNumber()); // the value might be null. right.accept(this); - convToString(exprType, arrayDim); + convToString(exprType, arrayDim, expr.getLineNumber()); bytecode.addInvokevirtual(javaLangString, "concat", "(Ljava/lang/String;)Ljava/lang/String;"); exprType = CLASS; @@ -1025,7 +1025,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { bytecode.write16bit(pc, bytecode.currentPc() - pc + 1); expr.elseExpr().accept(this); if (dim1 != arrayDim) - throw new CompileError("type mismatch in ?:"); + throw new CompileError("type mismatch in ?:", expr.getLineNumber()); bytecode.write16bit(pc2, bytecode.currentPc() - pc2 + 1); } @@ -1072,7 +1072,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { String cname1 = className; right.accept(this); if (dim1 != arrayDim) - throw new CompileError("incompatible array types"); + throw new CompileError("incompatible array types", expr.getLineNumber()); if (token == '+' && dim1 == 0 && (type1 == CLASS || exprType == CLASS)) @@ -1139,7 +1139,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { = (type2 == CLASS && jvmJavaLangString.equals(className)); if (type2Is2) - convToString(type2, dim2); + convToString(type2, dim2, expr.getLineNumber()); if (is2word(type1, dim1)) { bytecode.addOpcode(DUP_X2); @@ -1149,11 +1149,11 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { bytecode.addOpcode(SWAP); // even if type1 is String, the left operand might be null. - convToString(type1, dim1); + convToString(type1, dim1, expr.getLineNumber()); bytecode.addOpcode(SWAP); if (!type2Is2 && !type2IsString) - convToString(type2, dim2); + convToString(type2, dim2, expr.getLineNumber()); bytecode.addInvokevirtual(javaLangString, "concat", "(Ljava/lang/String;)Ljava/lang/String;"); @@ -1162,7 +1162,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { className = jvmJavaLangString; } - private void convToString(int type, int dim) throws CompileError { + private void convToString(int type, int dim, int lineNumber) throws CompileError { final String method = "valueOf"; if (isRefType(type) || dim > 0) @@ -1184,7 +1184,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { bytecode.addInvokestatic(javaLangString, method, "(C)Ljava/lang/String;"); else if (type == VOID) - throw new CompileError("void type expression"); + throw new CompileError("void type expression", lineNumber); else /* INT, BYTE, SHORT */ bytecode.addInvokestatic(javaLangString, method, "(I)Ljava/lang/String;"); @@ -1237,7 +1237,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { else { // others expr.accept(this); if (exprType != BOOLEAN || arrayDim != 0) - throw new CompileError("boolean expr is required"); + throw new CompileError("boolean expr is required", expr.getLineNumber()); bytecode.addOpcode(branchIf ? IFNE : IFEQ); } @@ -1280,7 +1280,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { expr.oprand2().accept(this); if (dim1 != arrayDim) if (type1 != NULL && exprType != NULL) - throw new CompileError("incompatible array types"); + throw new CompileError("incompatible array types", expr.getLineNumber()); else if (exprType == NULL) arrayDim = dim1; @@ -1348,7 +1348,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { else if (p == P_LONG) bytecode.addOpcode(LCMP); // 1: >, 0: =, -1: < else - fatal(); + fatal(expr.getLineNumber()); int[] op = ifOp2; for (int i = 0; i < op.length; i += 3) @@ -1362,7 +1362,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { } protected static void badTypes(Expr expr) throws CompileError { - throw new CompileError("invalid types for " + expr.getName()); + throw new CompileError("invalid types for " + expr.getName(), expr.getLineNumber()); } private static final int P_DOUBLE = 0; @@ -1462,7 +1462,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { bytecode.addOpcode(SWAP); } else - fatal(); + fatal(expr.getLineNumber()); } else if (op != NOP) bytecode.addOpcode(op); @@ -1503,11 +1503,11 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { int srcDim = arrayDim; if (invalidDim(srcType, arrayDim, className, type, dim, name, true) || srcType == VOID || type == VOID) - throw new CompileError(msg); + throw new CompileError(msg, expr.getLineNumber()); if (type == CLASS) { if (!isRefType(srcType) && srcDim == 0) - throw new CompileError(msg); + throw new CompileError(msg, expr.getLineNumber()); return toJvmArrayName(name, dim); } @@ -1591,7 +1591,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { bytecode.addIconst(0); } else if (token == CALL) // method call - fatal(); + fatal(expr.getLineNumber()); else { expr.oprand1().accept(this); int type = typePrecedence(exprType); @@ -1633,12 +1633,12 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { // do nothing. ignore. } else - fatal(); + fatal(expr.getLineNumber()); } } protected static void badType(Expr expr) throws CompileError { - throw new CompileError("invalid type for " + expr.getName()); + throw new CompileError("invalid type for " + expr.getName(), expr.getLineNumber()); } @Override @@ -1649,14 +1649,14 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { public void atClassObject(Expr expr) throws CompileError { ASTree op1 = expr.oprand1(); if (!(op1 instanceof Symbol)) - throw new CompileError("fatal error: badly parsed .class expr"); + throw new CompileError("fatal error: badly parsed .class expr", expr.getLineNumber()); String cname = ((Symbol)op1).get(); if (cname.startsWith("[")) { int i = cname.indexOf("[L"); if (i >= 0) { String name = cname.substring(i + 2, cname.length() - 1); - String name2 = resolveClassName(name); + String name2 = resolveClassName(name, expr.getLineNumber()); if (!name.equals(name2)) { /* For example, to obtain String[].class, * "[Ljava.lang.String;" (not "[Ljava/lang/String"!) @@ -1673,7 +1673,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { } } else { - cname = resolveClassName(MemberResolver.javaToJvmName(cname)); + cname = resolveClassName(MemberResolver.javaToJvmName(cname), expr.getLineNumber()); cname = MemberResolver.jvmToJavaName(cname); } @@ -1736,13 +1736,13 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { int type = exprType; int dim = arrayDim; if (dim == 0) - throw new CompileError("bad array access"); + throw new CompileError("bad array access", array.getLineNumber()); String cname = className; index.accept(this); if (typePrecedence(exprType) != P_INT || arrayDim > 0) - throw new CompileError("bad array index"); + throw new CompileError("bad array index", array.getLineNumber()); exprType = type; arrayDim = dim - 1; @@ -1992,7 +1992,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { case SUPER : if (inStaticMethod) throw new CompileError("not-available: " - + (token == THIS ? "this" : "super")); + + (token == THIS ? "this" : "super"), k.getLineNumber()); bytecode.addAload(0); exprType = CLASS; @@ -2002,7 +2002,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { className = getSuperName(); break; default : - fatal(); + fatal(k.getLineNumber()); } } diff --git a/src/main/javassist/compiler/CompileError.java b/src/main/javassist/compiler/CompileError.java index 5b857cf2..3a41779c 100644 --- a/src/main/javassist/compiler/CompileError.java +++ b/src/main/javassist/compiler/CompileError.java @@ -25,12 +25,19 @@ public class CompileError extends Exception { private Lex lex; private String reason; + private int lineNumber = -1; + public CompileError(String s, Lex l) { - reason = s; + this(s, l.getLineNumber()); lex = l; } - public CompileError(String s) { + public CompileError(String s, int lineNumber) { + this.lineNumber = lineNumber; + reason = String.format("line %d: %s", lineNumber, s); + } + + private CompileError(String s) { reason = s; lex = null; } @@ -45,6 +52,10 @@ public class CompileError extends Exception { public Lex getLex() { return lex; } + public int getLineNumber() { + return lineNumber; + } + @Override public String getMessage() { return reason; diff --git a/src/main/javassist/compiler/Javac.java b/src/main/javassist/compiler/Javac.java index 084487b4..8d1a04f3 100644 --- a/src/main/javassist/compiler/Javac.java +++ b/src/main/javassist/compiler/Javac.java @@ -43,7 +43,7 @@ import javassist.compiler.ast.Stmnt; import javassist.compiler.ast.Symbol; public class Javac { - JvstCodeGen gen; + JvstCodeGenWitlLineNumber gen; SymbolTable stable; private Bytecode bytecode; @@ -71,7 +71,7 @@ public class Javac { * belongs to. */ public Javac(Bytecode b, CtClass thisClass) { - gen = new JvstCodeGen(b, thisClass, thisClass.getClassPool()); + gen = new JvstCodeGenWitlLineNumber(b, thisClass, thisClass.getClassPool()); stable = new SymbolTable(); bytecode = b; } @@ -94,7 +94,9 @@ public class Javac { * @see #recordProceed(String,String) */ public CtMember compile(String src) throws CompileError { - Parser p = new Parser(new Lex(src)); + int startLine = gen.thisClass.getLinesCount(); + Lex lex = new Lex(src, startLine); + Parser p = new Parser(lex); ASTList mem = p.parseMember1(stable); try { if (mem instanceof FieldDecl) @@ -106,11 +108,8 @@ public class Javac { decl.getClassFile2()); return cb; } - catch (BadBytecode bb) { - throw new CompileError(bb.getMessage()); - } - catch (CannotCompileException e) { - throw new CompileError(e.getMessage()); + catch (BadBytecode | CannotCompileException bb) { + throw new CompileError(bb.getMessage(), lex.getLineNumber()); } } @@ -160,8 +159,9 @@ public class Javac { gen.getThisClass()); cons.setModifiers(mod); md.accept(gen); - cons.getMethodInfo().setCodeAttribute( - bytecode.toCodeAttribute()); + CodeAttribute cattr = bytecode.toCodeAttribute(); + cattr.setAttribute(gen.toLineNumberAttribute()); + cons.getMethodInfo().setCodeAttribute(cattr); cons.setExceptionTypes(tlist); return cons; } @@ -173,17 +173,18 @@ public class Javac { method.setModifiers(mod); gen.setThisMethod(method); md.accept(gen); - if (md.getBody() != null) - method.getMethodInfo().setCodeAttribute( - bytecode.toCodeAttribute()); - else + if (md.getBody() != null) { + CodeAttribute cattr = bytecode.toCodeAttribute(); + cattr.setAttribute(gen.toLineNumberAttribute()); + method.getMethodInfo().setCodeAttribute(cattr); + } else method.setModifiers(mod | Modifier.ABSTRACT); method.setExceptionTypes(tlist); return method; } catch (NotFoundException e) { - throw new CompileError(e.toString()); + throw new CompileError(e.toString(), md.getLineNumber()); } } @@ -219,7 +220,7 @@ public class Javac { Stmnt s = p.parseStatement(stb); if (p.hasMore()) throw new CompileError( - "the method/constructor body must be surrounded by {}"); + "the method/constructor body must be surrounded by {}", s.getLineNumber()); boolean callSuper = false; if (method instanceof CtConstructor) @@ -231,7 +232,7 @@ public class Javac { return bytecode; } catch (NotFoundException e) { - throw new CompileError(e.toString()); + throw new CompileError(e.toString(), -1); } } @@ -443,27 +444,27 @@ public class Javac { ProceedHandler h = new ProceedHandler() { @Override - public void doit(JvstCodeGen gen, Bytecode b, ASTList args) + public void doit(JvstCodeGen gen, Bytecode b, ASTList args, int lineNumber) throws CompileError { - ASTree expr = new Member(m); + ASTree expr = new Member(m, texpr.getLineNumber()); if (texpr != null) - expr = Expr.make('.', texpr, expr); + expr = Expr.make('.', texpr, expr, texpr.getLineNumber()); - expr = CallExpr.makeCall(expr, args); + expr = CallExpr.makeCall(expr, args, texpr.getLineNumber()); gen.compileExpr(expr); gen.addNullIfVoid(); } @Override - public void setReturnType(JvstTypeChecker check, ASTList args) + public void setReturnType(JvstTypeChecker check, ASTList args, int lineNumber) throws CompileError { - ASTree expr = new Member(m); + ASTree expr = new Member(m, texpr.getLineNumber()); if (texpr != null) - expr = Expr.make('.', texpr, expr); + expr = Expr.make('.', texpr, expr, texpr.getLineNumber()); - expr = CallExpr.makeCall(expr, args); + expr = CallExpr.makeCall(expr, args, texpr.getLineNumber()); expr.accept(check); check.addNullIfVoid(); } @@ -489,23 +490,23 @@ public class Javac { ProceedHandler h = new ProceedHandler() { @Override - public void doit(JvstCodeGen gen, Bytecode b, ASTList args) + public void doit(JvstCodeGen gen, Bytecode b, ASTList args, int lineNumber) throws CompileError { Expr expr = Expr.make(TokenId.MEMBER, - new Symbol(c), new Member(m)); - expr = CallExpr.makeCall(expr, args); + new Symbol(c, args.getLineNumber()), new Member(m, args.getLineNumber()), args.getLineNumber()); + expr = CallExpr.makeCall(expr, args, args.getLineNumber()); gen.compileExpr(expr); gen.addNullIfVoid(); } @Override - public void setReturnType(JvstTypeChecker check, ASTList args) + public void setReturnType(JvstTypeChecker check, ASTList args, int lineNumber) throws CompileError { Expr expr = Expr.make(TokenId.MEMBER, - new Symbol(c), new Member(m)); - expr = CallExpr.makeCall(expr, args); + new Symbol(c, args.getLineNumber()), new Member(m, args.getLineNumber()), args.getLineNumber()); + expr = CallExpr.makeCall(expr, args, args.getLineNumber()); expr.accept(check); check.addNullIfVoid(); } @@ -535,14 +536,14 @@ public class Javac { ProceedHandler h = new ProceedHandler() { @Override - public void doit(JvstCodeGen gen, Bytecode b, ASTList args) + public void doit(JvstCodeGen gen, Bytecode b, ASTList args, int lineNumber) throws CompileError { gen.compileInvokeSpecial(texpr, methodIndex, descriptor, args); } @Override - public void setReturnType(JvstTypeChecker c, ASTList args) + public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber) throws CompileError { c.compileInvokeSpecial(texpr, classname, methodname, descriptor, args); diff --git a/src/main/javassist/compiler/JvstCodeGen.java b/src/main/javassist/compiler/JvstCodeGen.java index 714b9699..6a372018 100644 --- a/src/main/javassist/compiler/JvstCodeGen.java +++ b/src/main/javassist/compiler/JvstCodeGen.java @@ -110,14 +110,14 @@ public class JvstCodeGen extends MemberCodeGen { } else if (name.equals(dollarTypeName)) { if (dollarType == null) - throw new CompileError(dollarTypeName + " is not available"); + throw new CompileError(dollarTypeName + " is not available", mem.getLineNumber()); bytecode.addLdc(Descriptor.of(dollarType)); callGetType("getType"); } else if (name.equals(clazzName)) { if (param0Type == null) - throw new CompileError(clazzName + " is not available"); + throw new CompileError(clazzName + " is not available", mem.getLineNumber()); bytecode.addLdc(param0Type); callGetType("getClazz"); @@ -141,13 +141,13 @@ public class JvstCodeGen extends MemberCodeGen { if (left instanceof Member && ((Member)left).get().equals(paramArrayName)) { if (op != '=') - throw new CompileError("bad operator for " + paramArrayName); + throw new CompileError("bad operator for " + paramArrayName, expr.getLineNumber()); right.accept(this); if (arrayDim != 1 || exprType != CLASS) - throw new CompileError("invalid type for " + paramArrayName); + throw new CompileError("invalid type for " + paramArrayName, expr.getLineNumber()); - atAssignParamList(paramTypeList, bytecode); + atAssignParamList(paramTypeList, bytecode, expr.getLineNumber()); if (!doDup) bytecode.addOpcode(POP); } @@ -155,7 +155,7 @@ public class JvstCodeGen extends MemberCodeGen { super.atFieldAssign(expr, op, left, right, doDup); } - protected void atAssignParamList(CtClass[] params, Bytecode code) + protected void atAssignParamList(CtClass[] params, Bytecode code, int lineNumber) throws CompileError { if (params == null) @@ -167,7 +167,7 @@ public class JvstCodeGen extends MemberCodeGen { code.addOpcode(DUP); code.addIconst(i); code.addOpcode(AALOAD); - compileUnwrapValue(params[i], code); + compileUnwrapValue(params[i], code, lineNumber); code.addStore(varNo, params[i]); varNo += is2word(exprType, arrayDim) ? 2 : 1; } @@ -201,17 +201,17 @@ public class JvstCodeGen extends MemberCodeGen { protected void atCastToRtype(CastExpr expr) throws CompileError { expr.getOprand().accept(this); if (exprType == VOID || isRefType(exprType) || arrayDim > 0) - compileUnwrapValue(returnType, bytecode); + compileUnwrapValue(returnType, bytecode, expr.getLineNumber()); else if (returnType instanceof CtPrimitiveType) { CtPrimitiveType pt = (CtPrimitiveType)returnType; - int destType = MemberResolver.descToType(pt.getDescriptor()); + int destType = MemberResolver.descToType(pt.getDescriptor(), expr.getLineNumber()); atNumCastExpr(exprType, destType); exprType = destType; arrayDim = 0; className = null; } else - throw new CompileError("invalid cast"); + throw new CompileError("invalid cast", expr.getLineNumber()); } protected void atCastToWrapper(CastExpr expr) throws CompileError { @@ -219,7 +219,7 @@ public class JvstCodeGen extends MemberCodeGen { if (isRefType(exprType) || arrayDim > 0) return; // Object type. do nothing. - CtClass clazz = resolver.lookupClass(exprType, arrayDim, className); + CtClass clazz = resolver.lookupClass(exprType, arrayDim, className, expr.getLineNumber()); if (clazz instanceof CtPrimitiveType) { CtPrimitiveType pt = (CtPrimitiveType)clazz; String wrapper = pt.getWrapperName(); @@ -249,11 +249,11 @@ public class JvstCodeGen extends MemberCodeGen { if (method instanceof Member) { String name = ((Member)method).get(); if (procHandler != null && name.equals(proceedName)) { - procHandler.doit(this, bytecode, (ASTList)expr.oprand2()); + procHandler.doit(this, bytecode, (ASTList)expr.oprand2(), expr.getLineNumber()); return; } else if (name.equals(cflowName)) { - atCflow((ASTList)expr.oprand2()); + atCflow((ASTList)expr.oprand2(), expr.getLineNumber()); return; } } @@ -263,16 +263,16 @@ public class JvstCodeGen extends MemberCodeGen { /* To support $cflow(). */ - protected void atCflow(ASTList cname) throws CompileError { + protected void atCflow(ASTList cname, int lineNumber) throws CompileError { StringBuilder sbuf = new StringBuilder(); if (cname == null || cname.tail() != null) - throw new CompileError("bad " + cflowName); + throw new CompileError("bad " + cflowName, lineNumber); makeCflowName(sbuf, cname.head()); String name = sbuf.toString(); Object[] names = resolver.getClassPool().lookupCflow(name); if (names == null) - throw new CompileError("no such " + cflowName + ": " + name); + throw new CompileError("no such " + cflowName + ": " + name, lineNumber); bytecode.addGetstatic((String)names[0], (String)names[1], "Ljavassist/runtime/Cflow;"); @@ -305,7 +305,7 @@ public class JvstCodeGen extends MemberCodeGen { } } - throw new CompileError("bad " + cflowName); + throw new CompileError("bad " + cflowName, name.getLineNumber()); } /* To support $$. ($$) is equivalent to ($1, ..., $n). @@ -364,7 +364,7 @@ public class JvstCodeGen extends MemberCodeGen { for (int k = 0; k < n; ++k) { CtClass p = params[k]; regno += bytecode.addLoad(regno, p); - setType(p); + setType(p, a.getLineNumber()); types[i] = exprType; dims[i] = arrayDim; cnames[i] = className; @@ -420,7 +420,7 @@ public class JvstCodeGen extends MemberCodeGen { atMethodArgs(args, new int[nargs], new int[nargs], new String[nargs]); bytecode.addInvokespecial(methodIndex, descriptor); - setReturnType(descriptor, false, false); + setReturnType(descriptor, false, false, target.getLineNumber()); addNullIfVoid(); } @@ -530,7 +530,7 @@ public class JvstCodeGen extends MemberCodeGen { String varName = prefix + "0"; Declarator decl = new Declarator(CLASS, MemberResolver.javaToJvmName(target), - 0, varNo++, new Symbol(varName)); + 0, varNo++, new Symbol(varName, 0), 0); tbl.append(varName, decl); } @@ -569,11 +569,11 @@ public class JvstCodeGen extends MemberCodeGen { className = jvmJavaLangObject; } else - setType(cc); + setType(cc, cc.getLinesCount()); Declarator decl = new Declarator(exprType, className, arrayDim, - varNo, new Symbol(varName)); + varNo, new Symbol(varName, 0), 0); tbl.append(varName, decl); return is2word(exprType, arrayDim) ? 2 : 1; } @@ -593,7 +593,7 @@ public class JvstCodeGen extends MemberCodeGen { while ((c = typeDesc.charAt(dim)) == '[') ++dim; - int type = MemberResolver.descToType(c); + int type = MemberResolver.descToType(c, -1); String cname = null; if (type == CLASS) { if (dim == 0) @@ -603,7 +603,7 @@ public class JvstCodeGen extends MemberCodeGen { } Declarator decl - = new Declarator(type, cname, dim, varNo, new Symbol(varName)); + = new Declarator(type, cname, dim, varNo, new Symbol(varName, 0), 0); tbl.append(varName, decl); } @@ -653,7 +653,7 @@ public class JvstCodeGen extends MemberCodeGen { return 8; } - protected void compileUnwrapValue(CtClass type, Bytecode code) + protected void compileUnwrapValue(CtClass type, Bytecode code, int lineNumber) throws CompileError { if (type == CtClass.voidType) { @@ -662,7 +662,7 @@ public class JvstCodeGen extends MemberCodeGen { } if (exprType == VOID) - throw new CompileError("invalid type for " + returnCastName); + throw new CompileError("invalid type for " + returnCastName, lineNumber); if (type instanceof CtPrimitiveType) { CtPrimitiveType pt = (CtPrimitiveType)type; @@ -671,34 +671,34 @@ public class JvstCodeGen extends MemberCodeGen { code.addCheckcast(wrapper); code.addInvokevirtual(wrapper, pt.getGetMethodName(), pt.getGetMethodDescriptor()); - setType(type); + setType(type, lineNumber); } else { code.addCheckcast(type); - setType(type); + setType(type, lineNumber); } } /* Sets exprType, arrayDim, and className; * If type is void, then this method does nothing. */ - public void setType(CtClass type) throws CompileError { - setType(type, 0); + public void setType(CtClass type, int lineNumber) throws CompileError { + setType(type, 0, lineNumber); } - private void setType(CtClass type, int dim) throws CompileError { + private void setType(CtClass type, int dim, int lineNumber) throws CompileError { if (type.isPrimitive()) { CtPrimitiveType pt = (CtPrimitiveType)type; - exprType = MemberResolver.descToType(pt.getDescriptor()); + exprType = MemberResolver.descToType(pt.getDescriptor(), lineNumber); arrayDim = dim; className = null; } else if (type.isArray()) try { - setType(type.getComponentType(), dim + 1); + setType(type.getComponentType(), dim + 1, lineNumber); } catch (NotFoundException e) { - throw new CompileError("undefined type: " + type.getName()); + throw new CompileError("undefined type: " + type.getName(), lineNumber); } else { exprType = CLASS; @@ -714,9 +714,9 @@ public class JvstCodeGen extends MemberCodeGen { if (type instanceof CtPrimitiveType) { CtPrimitiveType pt = (CtPrimitiveType)type; atNumCastExpr(exprType, - MemberResolver.descToType(pt.getDescriptor())); + MemberResolver.descToType(pt.getDescriptor(), type.getLinesCount() - 1)); } else - throw new CompileError("type mismatch"); + throw new CompileError("type mismatch", type.getLinesCount() - 1); } } diff --git a/src/main/javassist/compiler/JvstCodeGenWitlLineNumber.java b/src/main/javassist/compiler/JvstCodeGenWitlLineNumber.java new file mode 100644 index 00000000..969948c5 --- /dev/null +++ b/src/main/javassist/compiler/JvstCodeGenWitlLineNumber.java @@ -0,0 +1,265 @@ +package javassist.compiler; + +import javassist.ClassPool; +import javassist.CtClass; +import javassist.bytecode.Bytecode; +import javassist.bytecode.LineNumberAttribute; +import javassist.bytecode.LineNumberAttributeBuilder; +import javassist.compiler.ast.*; + +public class JvstCodeGenWitlLineNumber extends JvstCodeGen { + private final LineNumberAttributeBuilder lineNumberAttributeBuilder = new LineNumberAttributeBuilder(); + public JvstCodeGenWitlLineNumber(Bytecode b, CtClass cc, ClassPool cp) { + super(b, cc, cp); + } + + public LineNumberAttribute toLineNumberAttribute() { + return lineNumberAttributeBuilder.build(bytecode.getConstPool()); + } + + @Override + public void atASTList(ASTList n) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), n); + super.atASTList(n); + } + + @Override + public void atPair(Pair n) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), n); + super.atPair(n); + } + + @Override + public void atSymbol(Symbol n) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), n); + super.atSymbol(n); + } + + @Override + public void atFieldDecl(FieldDecl field) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), field); + super.atFieldDecl(field); + } + + @Override + public void atMethodDecl(MethodDecl method) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), method); + super.atMethodDecl(method); + } + + @Override + public void atMethodBody(Stmnt s, boolean isCons, boolean isVoid) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), s); + super.atMethodBody(s, isCons, isVoid); + } + + @Override + public void atStmnt(Stmnt st) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), st); + super.atStmnt(st); + } + + @Override + public void atDeclarator(Declarator d) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), d); + super.atDeclarator(d); + } + + @Override + public void atAssignExpr(AssignExpr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atAssignExpr(expr); + } + + @Override + protected void atAssignExpr(AssignExpr expr, boolean doDup) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atAssignExpr(expr, doDup); + } + + @Override + protected void atAssignCore(Expr expr, int op, ASTree right, int type, int dim, String cname) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atAssignCore(expr, op, right, type, dim, cname); + } + + @Override + public void atCondExpr(CondExpr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atCondExpr(expr); + } + + @Override + public void atBinExpr(BinExpr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atBinExpr(expr); + } + + @Override + public void atInstanceOfExpr(InstanceOfExpr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atInstanceOfExpr(expr); + } + + @Override + public void atExpr(Expr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atExpr(expr); + } + + @Override + public void atClassObject(Expr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atClassObject(expr); + } + + @Override + public void atArrayRead(ASTree array, ASTree index) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), array); + super.atArrayRead(array, index); + } + + @Override + protected void arrayAccess(ASTree array, ASTree index) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), array); + super.arrayAccess(array, index); + } + + @Override + public void atArrayPlusPlus(int token, boolean isPost, Expr expr, boolean doDup) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atArrayPlusPlus(token, isPost, expr, doDup); + } + + @Override + protected void atPlusPlusCore(int dup_code, boolean doDup, int token, boolean isPost, Expr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atPlusPlusCore(dup_code, doDup, token, isPost, expr); + } + + @Override + public void atVariable(Variable v) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), v); + super.atVariable(v); + } + + @Override + public void atKeyword(Keyword k) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), k); + super.atKeyword(k); + } + + @Override + public void atStringL(javassist.compiler.ast.StringL s) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), s); + super.atStringL(s); + } + + @Override + public void atIntConst(IntConst i) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), i); + super.atIntConst(i); + } + + @Override + public void atDoubleConst(DoubleConst d) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), d); + super.atDoubleConst(d); + } + + @Override + public void atMember(Member mem) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), mem); + super.atMember(mem); + } + + @Override + protected void atFieldAssign(Expr expr, int op, ASTree left, ASTree right, boolean doDup) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atFieldAssign(expr, op, left, right, doDup); + } + + @Override + public void atCastExpr(CastExpr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atCastExpr(expr); + } + + @Override + protected void atCastToRtype(CastExpr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atCastToRtype(expr); + } + + @Override + protected void atCastToWrapper(CastExpr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atCastToWrapper(expr); + } + + @Override + public void atCallExpr(CallExpr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atCallExpr(expr); + } + + @Override + protected void atCflow(ASTList cname, int lineNumber) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), cname); + super.atCflow(cname, lineNumber); + } + + @Override + protected void atTryStmnt(Stmnt st) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), st); + super.atTryStmnt(st); + } + + @Override + public void atNewExpr(NewExpr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atNewExpr(expr); + } + + @Override + public void atNewArrayExpr(NewExpr expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atNewArrayExpr(expr); + } + + @Override + protected void atArrayVariableAssign(ArrayInit init, int varType, int varArray, String varClass) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), init); + super.atArrayVariableAssign(init, varType, varArray, varClass); + } + + @Override + public void atArrayInit(ArrayInit init) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), init); + super.atArrayInit(init); + } + + @Override + protected void atMultiNewArray(int type, ASTList classname, ASTList size) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), classname); + super.atMultiNewArray(type, classname, size); + } + + @Override + public void atMethodCallCore(CtClass targetClass, String mname, ASTList args, boolean isStatic, boolean isSpecial, int aload0pos, MemberResolver.Method found) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), args); + super.atMethodCallCore(targetClass, mname, args, isStatic, isSpecial, aload0pos, found); + } + + @Override + protected void atFieldRead(ASTree expr) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atFieldRead(expr); + } + + @Override + protected void atFieldPlusPlus(int token, boolean isPost, ASTree oprand, Expr expr, boolean doDup) throws CompileError { + lineNumberAttributeBuilder.put(bytecode.currentPc(), expr); + super.atFieldPlusPlus(token, isPost, oprand, expr, doDup); + } +} diff --git a/src/main/javassist/compiler/JvstTypeChecker.java b/src/main/javassist/compiler/JvstTypeChecker.java index 13e47291..dbd1b358 100644 --- a/src/main/javassist/compiler/JvstTypeChecker.java +++ b/src/main/javassist/compiler/JvstTypeChecker.java @@ -89,7 +89,7 @@ public class JvstTypeChecker extends TypeChecker { int n = params.length; for (int i = 0; i < n; ++i) - compileUnwrapValue(params[i]); + compileUnwrapValue(params[i], expr.getLineNumber()); } else super.atFieldAssign(expr, op, left, right); @@ -124,10 +124,10 @@ public class JvstTypeChecker extends TypeChecker { CtClass returnType = codeGen.returnType; expr.getOprand().accept(this); if (exprType == VOID || CodeGen.isRefType(exprType) || arrayDim > 0) - compileUnwrapValue(returnType); + compileUnwrapValue(returnType, expr.getLineNumber()); else if (returnType instanceof CtPrimitiveType) { CtPrimitiveType pt = (CtPrimitiveType)returnType; - int destType = MemberResolver.descToType(pt.getDescriptor()); + int destType = MemberResolver.descToType(pt.getDescriptor(), expr.getLineNumber()); exprType = destType; arrayDim = 0; className = null; @@ -139,7 +139,7 @@ public class JvstTypeChecker extends TypeChecker { if (CodeGen.isRefType(exprType) || arrayDim > 0) return; // Object type. do nothing. - CtClass clazz = resolver.lookupClass(exprType, arrayDim, className); + CtClass clazz = resolver.lookupClass(exprType, arrayDim, className, expr.getLineNumber()); if (clazz instanceof CtPrimitiveType) { exprType = CLASS; arrayDim = 0; @@ -158,7 +158,7 @@ public class JvstTypeChecker extends TypeChecker { if (codeGen.procHandler != null && name.equals(codeGen.proceedName)) { codeGen.procHandler.setReturnType(this, - (ASTList)expr.oprand2()); + (ASTList)expr.oprand2(), expr.getLineNumber()); return; } else if (name.equals(JvstCodeGen.cflowName)) { @@ -223,7 +223,7 @@ public class JvstTypeChecker extends TypeChecker { int n = params.length; for (int k = 0; k < n; ++k) { CtClass p = params[k]; - setType(p); + setType(p, a.getLineNumber()); types[i] = exprType; dims[i] = arrayDim; cnames[i] = className; @@ -254,38 +254,38 @@ public class JvstTypeChecker extends TypeChecker { int nargs = getMethodArgsLength(args); atMethodArgs(args, new int[nargs], new int[nargs], new String[nargs]); - setReturnType(descriptor); + setReturnType(descriptor, target.getLineNumber()); addNullIfVoid(); } - protected void compileUnwrapValue(CtClass type) throws CompileError + protected void compileUnwrapValue(CtClass type, int lineNumber) throws CompileError { if (type == CtClass.voidType) addNullIfVoid(); else - setType(type); + setType(type, lineNumber); } /* Sets exprType, arrayDim, and className; * If type is void, then this method does nothing. */ - public void setType(CtClass type) throws CompileError { - setType(type, 0); + public void setType(CtClass type, int lineNumber) throws CompileError { + setType(type, 0, lineNumber); } - private void setType(CtClass type, int dim) throws CompileError { + private void setType(CtClass type, int dim, int lineNumber) throws CompileError { if (type.isPrimitive()) { CtPrimitiveType pt = (CtPrimitiveType)type; - exprType = MemberResolver.descToType(pt.getDescriptor()); + exprType = MemberResolver.descToType(pt.getDescriptor(), lineNumber); arrayDim = dim; className = null; } else if (type.isArray()) try { - setType(type.getComponentType(), dim + 1); + setType(type.getComponentType(), dim + 1, lineNumber); } catch (NotFoundException e) { - throw new CompileError("undefined type: " + type.getName()); + throw new CompileError("undefined type: " + type.getName(), lineNumber); } else { exprType = CLASS; diff --git a/src/main/javassist/compiler/Lex.java b/src/main/javassist/compiler/Lex.java index b7c39a98..9f7f2ec2 100644 --- a/src/main/javassist/compiler/Lex.java +++ b/src/main/javassist/compiler/Lex.java @@ -39,6 +39,10 @@ public class Lex implements TokenId { * Constructs a lexical analyzer. */ public Lex(String s) { + this(s, 0); + } + + Lex(String s, int startLineNumber) { lastChar = -1; textBuffer = new StringBuilder(); currentToken = new Token(); @@ -47,7 +51,7 @@ public class Lex implements TokenId { input = s; position = 0; maxlen = s.length(); - lineNumber = 0; + lineNumber = startLineNumber; } public int get() { @@ -163,7 +167,8 @@ public class Lex implements TokenId { ungetc(c); c = '/'; } - } + } else if (c == '\n') + ++lineNumber; } while(isBlank(c)); return c; } @@ -529,4 +534,8 @@ public class Lex implements TokenId { lastChar = -1; return c; } + + public int getLineNumber() { + return lineNumber + 1; + } } diff --git a/src/main/javassist/compiler/MemberCodeGen.java b/src/main/javassist/compiler/MemberCodeGen.java index e8e9912b..884b39df 100644 --- a/src/main/javassist/compiler/MemberCodeGen.java +++ b/src/main/javassist/compiler/MemberCodeGen.java @@ -234,7 +234,7 @@ public class MemberCodeGen extends CodeGen { body.accept(this); int end = bc.currentPc(); if (start == end) - throw new CompileError("empty try block"); + throw new CompileError("empty try block", st.getLineNumber()); boolean tryNotReturn = !hasReturned; if (tryNotReturn) { @@ -254,7 +254,7 @@ public class MemberCodeGen extends CodeGen { decl.setLocalVar(var); - CtClass type = resolver.lookupClassByJvmName(decl.getClassName()); + CtClass type = resolver.lookupClassByJvmName(decl.getClassName(), st.getLineNumber()); decl.setClassName(MemberResolver.javaToJvmName(type.getName())); bc.addExceptionHandler(start, end, bc.currentPc(), type); bc.growStack(1); @@ -346,21 +346,21 @@ public class MemberCodeGen extends CodeGen { if (init != null) throw new CompileError( "sorry, multi-dimensional array initializer " + - "for new is not supported"); + "for new is not supported", expr.getLineNumber()); atMultiNewArray(type, classname, size); return; } ASTree sizeExpr = size.head(); - atNewArrayExpr2(type, sizeExpr, Declarator.astToClassName(classname, '/'), init); + atNewArrayExpr2(type, sizeExpr, Declarator.astToClassName(classname, '/'), init, expr.getLineNumber()); } private void atNewArrayExpr2(int type, ASTree sizeExpr, - String jvmClassname, ArrayInit init) throws CompileError { + String jvmClassname, ArrayInit init, int lineNumber) throws CompileError { if (init == null) if (sizeExpr == null) - throw new CompileError("no array size"); + throw new CompileError("no array size", lineNumber); else sizeExpr.accept(this); else @@ -369,11 +369,11 @@ public class MemberCodeGen extends CodeGen { bytecode.addIconst(s); } else - throw new CompileError("unnecessary array size specified for new"); + throw new CompileError("unnecessary array size specified for new", lineNumber); String elementClass; if (type == CLASS) { - elementClass = resolveClassName(jvmClassname); + elementClass = resolveClassName(jvmClassname, lineNumber); bytecode.addAnewarray(MemberResolver.jvmToJavaName(elementClass)); } else { @@ -405,7 +405,7 @@ public class MemberCodeGen extends CodeGen { atype = T_LONG; break; default : - badNewExpr(); + badNewExpr(lineNumber); break; } @@ -433,19 +433,19 @@ public class MemberCodeGen extends CodeGen { className = elementClass; } - private static void badNewExpr() throws CompileError { - throw new CompileError("bad new expression"); + private static void badNewExpr(int lineNumber) throws CompileError { + throw new CompileError("bad new expression", lineNumber); } @Override protected void atArrayVariableAssign(ArrayInit init, int varType, int varArray, String varClass) throws CompileError { - atNewArrayExpr2(varType, null, varClass, init); + atNewArrayExpr2(varType, null, varClass, init, init.getLineNumber()); } @Override public void atArrayInit(ArrayInit init) throws CompileError { - throw new CompileError("array initializer is not supported"); + throw new CompileError("array initializer is not supported", init.getLineNumber()); } protected void atMultiNewArray(int type, ASTList classname, ASTList size) @@ -461,7 +461,7 @@ public class MemberCodeGen extends CodeGen { ++count; s.accept(this); if (exprType != INT) - throw new CompileError("bad type for array size"); + throw new CompileError("bad type for array size", classname.getLineNumber()); } String desc; @@ -503,7 +503,7 @@ public class MemberCodeGen extends CodeGen { mname = MethodInfo.nameInit; // <init> targetClass = thisClass; if (inStaticMethod) - throw new CompileError("a constructor cannot be static"); + throw new CompileError("a constructor cannot be static", expr.getLineNumber()); bytecode.addAload(0); // this if (((Keyword)method).get() == SUPER) @@ -515,7 +515,7 @@ public class MemberCodeGen extends CodeGen { int op = e.getOperator(); if (op == MEMBER) { // static method targetClass - = resolver.lookupClass(((Symbol)e.oprand1()).get(), false); + = resolver.lookupClass(((Symbol)e.oprand1()).get(), false, expr.getLineNumber()); isStatic = true; } else if (op == '.') { @@ -552,25 +552,25 @@ public class MemberCodeGen extends CodeGen { } if (arrayDim > 0) - targetClass = resolver.lookupClass(javaLangObject, true); + targetClass = resolver.lookupClass(javaLangObject, true, expr.getLineNumber()); else if (exprType == CLASS /* && arrayDim == 0 */) - targetClass = resolver.lookupClassByJvmName(className); + targetClass = resolver.lookupClassByJvmName(className, expr.getLineNumber()); else - badMethod(); + badMethod(e.getLineNumber()); } } else - badMethod(); + badMethod(expr.getLineNumber()); } else - fatal(); + fatal(expr.getLineNumber()); atMethodCallCore(targetClass, mname, args, isStatic, isSpecial, aload0pos, cached); } - private static void badMethod() throws CompileError { - throw new CompileError("bad method"); + private static void badMethod(int lineNumber) throws CompileError { + throw new CompileError("bad method", lineNumber); } /* @@ -612,7 +612,7 @@ public class MemberCodeGen extends CodeGen { msg = "Method " + mname + " not found in " + targetClass.getName(); - throw new CompileError(msg); + throw new CompileError(msg, args.getLineNumber()); } atMethodCallCore2(targetClass, mname, isStatic, isSpecial, @@ -645,7 +645,7 @@ public class MemberCodeGen extends CodeGen { if (mname.equals(MethodInfo.nameInit)) { isSpecial = true; if (declClass != targetClass) - throw new CompileError("no such constructor: " + targetClass.getName()); + throw new CompileError("no such constructor: " + targetClass.getName(), targetClass.getLinesCount() - 1); if (declClass != thisClass && AccessFlag.isPrivate(acc)) { if (declClass.getClassFile().getMajorVersion() < ClassFile.JAVA_8 @@ -701,12 +701,12 @@ public class MemberCodeGen extends CodeGen { } else if (isStatic) - throw new CompileError(mname + " is not static"); + throw new CompileError(mname + " is not static", targetClass.getLinesCount() - 1); else bytecode.addInvokevirtual(declClass, mname, desc); } - setReturnType(desc, isStatic, popTarget); + setReturnType(desc, isStatic, popTarget, targetClass.getLinesCount() - 1); } /* @@ -729,7 +729,7 @@ public class MemberCodeGen extends CodeGen { } throw new CompileError("Method " + methodName - + " is private"); + + " is private", declClass.getLinesCount() - 1); } /* @@ -752,7 +752,7 @@ public class MemberCodeGen extends CodeGen { } throw new CompileError("the called constructor is private in " - + declClass.getName()); + + declClass.getName(), declClass.getLinesCount() - 1); } private boolean isEnclosing(CtClass outer, CtClass inner) { @@ -785,12 +785,12 @@ public class MemberCodeGen extends CodeGen { } } - void setReturnType(String desc, boolean isStatic, boolean popTarget) + void setReturnType(String desc, boolean isStatic, boolean popTarget, int lineNumber) throws CompileError { int i = desc.indexOf(')'); if (i < 0) - badMethod(); + badMethod(lineNumber); char c = desc.charAt(++i); int dim = 0; @@ -803,13 +803,13 @@ public class MemberCodeGen extends CodeGen { if (c == 'L') { int j = desc.indexOf(';', i + 1); if (j < 0) - badMethod(); + badMethod(lineNumber); exprType = CLASS; className = desc.substring(i + 1, j); } else { - exprType = MemberResolver.descToType(c); + exprType = MemberResolver.descToType(c, lineNumber); className = null; } @@ -843,15 +843,15 @@ public class MemberCodeGen extends CodeGen { int fi; if (op == '=') { FieldInfo finfo = f.getFieldInfo2(); - setFieldType(finfo); - AccessorMaker maker = isAccessibleField(f, finfo); + setFieldType(finfo, expr.getLineNumber()); + AccessorMaker maker = isAccessibleField(f, finfo, expr.getLineNumber()); if (maker == null) fi = addFieldrefInfo(f, finfo); else fi = 0; } else - fi = atFieldRead(f, is_static); + fi = atFieldRead(f, is_static, expr.getLineNumber()); int fType = exprType; int fDim = arrayDim; @@ -921,18 +921,18 @@ public class MemberCodeGen extends CodeGen { } boolean is_static = resultStatic; - ASTree cexpr = TypeChecker.getConstantFieldValue(f); + ASTree cexpr = TypeChecker.getConstantFieldValue(f, expr.getLineNumber()); if (cexpr == null) - atFieldRead(f, is_static); + atFieldRead(f, is_static,expr.getLineNumber() ); else { cexpr.accept(this); - setFieldType(f.getFieldInfo2()); + setFieldType(f.getFieldInfo2(), expr.getLineNumber()); } } private void atArrayLength(ASTree expr) throws CompileError { if (arrayDim == 0) - throw new CompileError(".length applied to a non array"); + throw new CompileError(".length applied to a non array", expr.getLineNumber()); bytecode.addOpcode(ARRAYLENGTH); exprType = INT; @@ -944,10 +944,10 @@ public class MemberCodeGen extends CodeGen { * It returns a fieldref_info index or zero if the field is a private * one declared in an enclosing class. */ - private int atFieldRead(CtField f, boolean isStatic) throws CompileError { + private int atFieldRead(CtField f, boolean isStatic, int lineNumber) throws CompileError { FieldInfo finfo = f.getFieldInfo2(); - boolean is2byte = setFieldType(finfo); - AccessorMaker maker = isAccessibleField(f, finfo); + boolean is2byte = setFieldType(finfo, lineNumber); + AccessorMaker maker = isAccessibleField(f, finfo, lineNumber); if (maker != null) { MethodInfo minfo = maker.getFieldGetter(finfo, isStatic); bytecode.addInvokestatic(f.getDeclaringClass(), minfo.getName(), @@ -973,7 +973,7 @@ public class MemberCodeGen extends CodeGen { * an exception or it returns AccessorMaker if the field is a private * one declared in an enclosing class. */ - private AccessorMaker isAccessibleField(CtField f, FieldInfo finfo) + private AccessorMaker isAccessibleField(CtField f, FieldInfo finfo, int lineNumber) throws CompileError { if (AccessFlag.isPrivate(finfo.getAccessFlags()) @@ -985,7 +985,7 @@ public class MemberCodeGen extends CodeGen { return maker; } throw new CompileError("Field " + f.getName() + " in " - + declClass.getName() + " is private."); + + declClass.getName() + " is private.", lineNumber); } return null; // accessible field @@ -996,7 +996,7 @@ public class MemberCodeGen extends CodeGen { * * @return true if the field type is long or double. */ - private boolean setFieldType(FieldInfo finfo) throws CompileError { + private boolean setFieldType(FieldInfo finfo, int lineNumber) throws CompileError { String type = finfo.getDescriptor(); int i = 0; @@ -1008,7 +1008,7 @@ public class MemberCodeGen extends CodeGen { } arrayDim = dim; - exprType = MemberResolver.descToType(c); + exprType = MemberResolver.descToType(c, lineNumber); if (c == 'L') className = type.substring(i + 1, type.indexOf(';', i + 1)); @@ -1046,7 +1046,7 @@ public class MemberCodeGen extends CodeGen { if (!is_static) bytecode.addOpcode(DUP); - int fi = atFieldRead(f, is_static); + int fi = atFieldRead(f, is_static, oprand.getLineNumber()); int t = exprType; boolean is2w = is2word(t, arrayDim); @@ -1082,7 +1082,7 @@ public class MemberCodeGen extends CodeGen { if (!is_static) if (inStaticMethod) throw new CompileError( - "not available in a static method: " + name); + "not available in a static method: " + name, expr.getLineNumber()); else bytecode.addAload(0); // this @@ -1117,7 +1117,7 @@ public class MemberCodeGen extends CodeGen { && ((Symbol)e.oprand2()).get().equals("length")) return null; // expr is an array length. else - badLvalue(); + badLvalue(expr.getLineNumber()); boolean is_static = Modifier.isStatic(f.getModifiers()); if (is_static) @@ -1142,17 +1142,17 @@ public class MemberCodeGen extends CodeGen { } } else - badLvalue(); + badLvalue(expr.getLineNumber()); } else - badLvalue(); + badLvalue(expr.getLineNumber()); resultStatic = false; return null; // never reach } - private static void badLvalue() throws CompileError { - throw new CompileError("bad l-value"); + private static void badLvalue(int lineNumber) throws CompileError { + throw new CompileError("bad l-value", lineNumber); } public CtClass[] makeParamList(MethodDecl md) throws CompileError { @@ -1201,7 +1201,7 @@ public class MemberCodeGen extends CodeGen { * For example, this converts Object into java/lang/Object. */ @Override - protected String resolveClassName(String jvmName) throws CompileError { - return resolver.resolveJvmClassName(jvmName); + protected String resolveClassName(String jvmName, int lineNumber) throws CompileError { + return resolver.resolveJvmClassName(jvmName, lineNumber); } } diff --git a/src/main/javassist/compiler/MemberResolver.java b/src/main/javassist/compiler/MemberResolver.java index dd271368..3b0cc012 100644 --- a/src/main/javassist/compiler/MemberResolver.java +++ b/src/main/javassist/compiler/MemberResolver.java @@ -50,8 +50,8 @@ public class MemberResolver implements TokenId { public ClassPool getClassPool() { return classPool; } - private static void fatal() throws CompileError { - throw new CompileError("fatal"); + private static void fatal(int lineNumber) throws CompileError { + throw new CompileError("fatal", lineNumber); } public static class Method { @@ -85,7 +85,7 @@ public class MemberResolver implements TokenId { if (current != null && clazz == currentClass) if (current.getName().equals(methodName)) { int res = compareSignature(current.getDescriptor(), - argTypes, argDims, argClassNames); + argTypes, argDims, argClassNames, currentClass.getLinesCount() - 1); if (res != NO) { Method r = new Method(clazz, current, res); if (res == YES) @@ -116,7 +116,7 @@ public class MemberResolver implements TokenId { if (minfo.getName().equals(methodName) && (minfo.getAccessFlags() & AccessFlag.BRIDGE) == 0) { int res = compareSignature(minfo.getDescriptor(), - argTypes, argDims, argClassNames); + argTypes, argDims, argClassNames, clazz.getLinesCount() - 1); if (res != NO) { Method r = new Method(clazz, minfo, res); if (res == YES) @@ -199,7 +199,7 @@ public class MemberResolver implements TokenId { * of parameter types that do not exactly match. */ private int compareSignature(String desc, int[] argTypes, - int[] argDims, String[] argClassNames) + int[] argDims, String[] argClassNames, int lineNumber) throws CompileError { int result = YES; @@ -247,9 +247,9 @@ public class MemberResolver implements TokenId { String cname = desc.substring(i, j); if (!cname.equals(argClassNames[n])) { - CtClass clazz = lookupClassByJvmName(argClassNames[n]); + CtClass clazz = lookupClassByJvmName(argClassNames[n], lineNumber); try { - if (clazz.subtypeOf(lookupClassByJvmName(cname))) + if (clazz.subtypeOf(lookupClassByJvmName(cname, lineNumber))) result++; else return NO; @@ -262,7 +262,7 @@ public class MemberResolver implements TokenId { i = j + 1; } else { - int t = descToType(c); + int t = descToType(c, lineNumber); int at = argTypes[n]; if (t != at) if (t == INT @@ -280,7 +280,7 @@ public class MemberResolver implements TokenId { * Only used by fieldAccess() in MemberCodeGen and TypeChecker. * * @param jvmClassName a JVM class name. e.g. java/lang/String - * @see #lookupClass(String, boolean) + * @see #lookupClass(String, boolean, int) */ public CtField lookupFieldByJvmName2(String jvmClassName, Symbol fieldSym, ASTree expr) throws NoFieldException @@ -288,7 +288,7 @@ public class MemberResolver implements TokenId { String field = fieldSym.get(); CtClass cc = null; try { - cc = lookupClass(jvmToJavaName(jvmClassName), true); + cc = lookupClass(jvmToJavaName(jvmClassName), true, expr.getLineNumber()); } catch (CompileError e) { // EXPR might be part of a qualified class name. @@ -320,55 +320,56 @@ public class MemberResolver implements TokenId { public CtField lookupField(String className, Symbol fieldName) throws CompileError { - CtClass cc = lookupClass(className, false); + CtClass cc = lookupClass(className, false, fieldName.getLineNumber()); try { return cc.getField(fieldName.get()); } catch (NotFoundException e) {} - throw new CompileError("no such field: " + fieldName.get()); + throw new CompileError("no such field: " + fieldName.get(), fieldName.getLineNumber()); } public CtClass lookupClassByName(ASTList name) throws CompileError { - return lookupClass(Declarator.astToClassName(name, '.'), false); + return lookupClass(Declarator.astToClassName(name, '.'), false, name.getLineNumber()); } - public CtClass lookupClassByJvmName(String jvmName) throws CompileError { - return lookupClass(jvmToJavaName(jvmName), false); + public CtClass lookupClassByJvmName(String jvmName, int lineNumber) throws CompileError { + return lookupClass(jvmToJavaName(jvmName), false, lineNumber); } public CtClass lookupClass(Declarator decl) throws CompileError { return lookupClass(decl.getType(), decl.getArrayDim(), - decl.getClassName()); + decl.getClassName(), decl.getLineNumber()); } /** - * @param classname jvm class name. + * @param classname jvm class name. + * @param lineNumber */ - public CtClass lookupClass(int type, int dim, String classname) + public CtClass lookupClass(int type, int dim, String classname, int lineNumber) throws CompileError { String cname = ""; CtClass clazz; if (type == CLASS) { - clazz = lookupClassByJvmName(classname); + clazz = lookupClassByJvmName(classname, lineNumber); if (dim > 0) cname = clazz.getName(); else return clazz; } else - cname = getTypeName(type); + cname = getTypeName(type, lineNumber); while (dim-- > 0) cname += "[]"; - return lookupClass(cname, false); + return lookupClass(cname, false, lineNumber); } /* * type cannot be CLASS */ - static String getTypeName(int type) throws CompileError { + static String getTypeName(int type, int lineNumber) throws CompileError { String cname = ""; switch (type) { case BOOLEAN : @@ -399,22 +400,23 @@ public class MemberResolver implements TokenId { cname = "void"; break; default : - fatal(); + fatal(lineNumber); } return cname; } /** - * @param name a qualified class name. e.g. java.lang.String + * @param name a qualified class name. e.g. java.lang.String + * @param lineNumber */ - public CtClass lookupClass(String name, boolean notCheckInner) + public CtClass lookupClass(String name, boolean notCheckInner, int lineNumber) throws CompileError { Map<String,String> cache = getInvalidNames(); String found = cache.get(name); if (found == INVALID) - throw new CompileError("no such class: " + name); + throw new CompileError("no such class: " + name, lineNumber); else if (found != null) try { return classPool.get(found); @@ -426,7 +428,7 @@ public class MemberResolver implements TokenId { cc = lookupClass0(name, notCheckInner); } catch (NotFoundException e) { - cc = searchImports(name); + cc = searchImports(name, lineNumber); } cache.put(name, cc.getName()); @@ -461,7 +463,7 @@ public class MemberResolver implements TokenId { return ht; } - private CtClass searchImports(String orgName) + private CtClass searchImports(String orgName, int lineNumber) throws CompileError { if (orgName.indexOf('.') < 0) { @@ -483,7 +485,7 @@ public class MemberResolver implements TokenId { } getInvalidNames().put(orgName, INVALID); - throw new CompileError("no such class: " + orgName); + throw new CompileError("no such class: " + orgName, lineNumber); } private CtClass lookupClass0(String classname, boolean notCheckInner) @@ -520,10 +522,10 @@ public class MemberResolver implements TokenId { /* Expands a simple class name to java.lang.*. * For example, this converts Object into java/lang/Object. */ - public String resolveJvmClassName(String jvmName) throws CompileError { + public String resolveJvmClassName(String jvmName, int lineNumber) throws CompileError { if (jvmName == null) return null; - return javaToJvmName(lookupClassByJvmName(jvmName).getName()); + return javaToJvmName(lookupClassByJvmName(jvmName, lineNumber).getName()); } public static CtClass getSuperclass(CtClass c) throws CompileError { @@ -534,7 +536,7 @@ public class MemberResolver implements TokenId { } catch (NotFoundException e) {} throw new CompileError("cannot find the super class of " - + c.getName()); + + c.getName(), c.getLinesCount() - 1); } public static CtClass getSuperInterface(CtClass c, String interfaceName) @@ -547,7 +549,7 @@ public class MemberResolver implements TokenId { return intfs[i]; } catch (NotFoundException e) {} throw new CompileError("cannot find the super interface " + interfaceName - + " of " + c.getName()); + + " of " + c.getName(), c.getLinesCount() - 1); } public static String javaToJvmName(String classname) { @@ -558,7 +560,7 @@ public class MemberResolver implements TokenId { return classname.replace('/', '.'); } - public static int descToType(char c) throws CompileError { + public static int descToType(char c, int lineNumber) throws CompileError { switch (c) { case 'Z' : return BOOLEAN; @@ -582,7 +584,7 @@ public class MemberResolver implements TokenId { case '[' : return CLASS; default : - fatal(); + fatal(lineNumber); return VOID; // never reach here } } diff --git a/src/main/javassist/compiler/NoFieldException.java b/src/main/javassist/compiler/NoFieldException.java index dd878590..898998d1 100644 --- a/src/main/javassist/compiler/NoFieldException.java +++ b/src/main/javassist/compiler/NoFieldException.java @@ -27,7 +27,7 @@ public class NoFieldException extends CompileError { /* NAME must be JVM-internal representation. */ public NoFieldException(String name, ASTree e) { - super("no such field: " + name); + super("no such field: " + name, e.getLineNumber()); fieldName = name; expr = e; } diff --git a/src/main/javassist/compiler/Parser.java b/src/main/javassist/compiler/Parser.java index 2b0dfd69..7e742a6b 100644 --- a/src/main/javassist/compiler/Parser.java +++ b/src/main/javassist/compiler/Parser.java @@ -66,7 +66,7 @@ public final class Parser implements TokenId { Declarator d; boolean isConstructor = false; if (lex.lookAhead() == Identifier && lex.lookAhead(1) == '(') { - d = new Declarator(VOID, 0); + d = new Declarator(VOID, 0, lex.getLineNumber()); isConstructor = true; } else @@ -81,7 +81,7 @@ public final class Parser implements TokenId { else name = lex.getString(); - d.setVariable(new Symbol(name)); + d.setVariable(new Symbol(name, lex.getLineNumber())); if (isConstructor || lex.lookAhead() == '(') return parseMethod1(tbl, isConstructor, mods, d); return parseField(tbl, mods, d); @@ -103,7 +103,7 @@ public final class Parser implements TokenId { int c = lex.get(); if (c == ';') - return new FieldDecl(mods, new ASTList(d, new ASTList(expr))); + return new FieldDecl(mods, new ASTList(d, new ASTList(expr, lex.getLineNumber()), lex.getLineNumber()), lex.getLineNumber()); else if (c == ',') throw new CompileError( "only one field can be declared in one declaration", lex); @@ -131,7 +131,7 @@ public final class Parser implements TokenId { ASTList parms = null; if (lex.lookAhead() != ')') while (true) { - parms = ASTList.append(parms, parseFormalParam(tbl)); + parms = ASTList.append(parms, parseFormalParam(tbl), lex.getLineNumber()); int t = lex.lookAhead(); if (t == ',') lex.get(); @@ -148,7 +148,7 @@ public final class Parser implements TokenId { if (lex.lookAhead() == THROWS) { lex.get(); while (true) { - throwsList = ASTList.append(throwsList, parseClassType(tbl)); + throwsList = ASTList.append(throwsList, parseClassType(tbl), lex.getLineNumber()); if (lex.lookAhead() == ',') lex.get(); else @@ -157,7 +157,7 @@ public final class Parser implements TokenId { } return new MethodDecl(mods, new ASTList(d, - ASTList.make(parms, throwsList, null))); + ASTList.make(parms, throwsList, null, lex.getLineNumber()), lex.getLineNumber()), lex.getLineNumber()); } /* Parses a method body. @@ -171,7 +171,7 @@ public final class Parser implements TokenId { else { body = parseBlock(tbl); if (body == null) - body = new Stmnt(BLOCK); + body = new Stmnt(BLOCK, lex.getLineNumber()); } md.sublist(4).setHead(body); @@ -191,7 +191,7 @@ public final class Parser implements TokenId { if (t == ABSTRACT || t == FINAL || t == PUBLIC || t == PROTECTED || t == PRIVATE || t == SYNCHRONIZED || t == STATIC || t == VOLATILE || t == TRANSIENT || t == STRICT) - list = new ASTList(new Keyword(lex.get()), list); + list = new ASTList(new Keyword(lex.get(), lex.getLineNumber()), list, lex.getLineNumber()); else break; } @@ -206,11 +206,11 @@ public final class Parser implements TokenId { if (isBuiltinType(t) || t == VOID) { lex.get(); // primitive type int dim = parseArrayDimension(); - return new Declarator(t, dim); + return new Declarator(t, dim, lex.getLineNumber()); } ASTList name = parseClassType(tbl); int dim = parseArrayDimension(); - return new Declarator(name, dim); + return new Declarator(name, dim, lex.getLineNumber()); } private static boolean isBuiltinType(int t) { @@ -228,7 +228,7 @@ public final class Parser implements TokenId { throw new SyntaxError(lex); String name = lex.getString(); - d.setVariable(new Symbol(name)); + d.setVariable(new Symbol(name, lex.getLineNumber())); d.addArrayDim(parseArrayDimension()); tbl.append(name, d); return d; @@ -261,13 +261,13 @@ public final class Parser implements TokenId { return parseBlock(tbl); else if (t == ';') { lex.get(); - return new Stmnt(BLOCK); // empty statement + return new Stmnt(BLOCK, lex.getLineNumber()); // empty statement } else if (t == Identifier && lex.lookAhead(1) == ':') { lex.get(); // Identifier String label = lex.getString(); lex.get(); // ':' - return Stmnt.make(LABEL, new Symbol(label), parseStatement(tbl)); + return Stmnt.make(LABEL, new Symbol(label, lex.getLineNumber()), parseStatement(tbl), lex.getLineNumber()); } else if (t == IF) return parseIf(tbl); @@ -298,20 +298,22 @@ public final class Parser implements TokenId { /* block.statement : "{" statement* "}" */ private Stmnt parseBlock(SymbolTable tbl) throws CompileError { + int blockLineNumber = lex.getLineNumber(); if (lex.get() != '{') throw new SyntaxError(lex); Stmnt body = null; SymbolTable tbl2 = new SymbolTable(tbl); while (lex.lookAhead() != '}') { + int lineNumber = lex.getLineNumber(); Stmnt s = parseStatement(tbl2); if (s != null) - body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s)); + body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s, lineNumber)); } lex.get(); // '}' if (body == null) - return new Stmnt(BLOCK); // empty block + return new Stmnt(BLOCK, blockLineNumber); // empty block return body; } @@ -321,7 +323,9 @@ public final class Parser implements TokenId { private Stmnt parseIf(SymbolTable tbl) throws CompileError { int t = lex.get(); // IF ASTree expr = parseParExpression(tbl); + int exprLineNum = lex.getLineNumber(); Stmnt thenp = parseStatement(tbl); + int thenLineNum = lex.getLineNumber(); Stmnt elsep; if (lex.lookAhead() == ELSE) { lex.get(); @@ -330,7 +334,7 @@ public final class Parser implements TokenId { else elsep = null; - return new Stmnt(t, expr, new ASTList(thenp, new ASTList(elsep))); + return new Stmnt(t, expr, new ASTList(thenp, new ASTList(elsep, lex.getLineNumber()), thenLineNum), exprLineNum); } /* while.statement : WHILE "(" expression ")" statement @@ -340,8 +344,9 @@ public final class Parser implements TokenId { { int t = lex.get(); // WHILE ASTree expr = parseParExpression(tbl); + int lineNumber = lex.getLineNumber(); Stmnt body = parseStatement(tbl); - return new Stmnt(t, expr, body); + return new Stmnt(t, expr, body, lineNumber); } /* do.statement : DO statement WHILE "(" expression ")" ";" @@ -356,7 +361,7 @@ public final class Parser implements TokenId { if (lex.get() != ')' || lex.get() != ';') throw new SyntaxError(lex); - return new Stmnt(t, expr, body); + return new Stmnt(t, expr, body, lex.getLineNumber()); } /* for.statement : FOR "(" decl.or.expr expression ";" expression ")" @@ -372,6 +377,7 @@ public final class Parser implements TokenId { if (lex.get() != '(') throw new SyntaxError(lex); + int expr1LineNumber = lex.getLineNumber(); if (lex.lookAhead() == ';') { lex.get(); expr1 = null; @@ -379,6 +385,7 @@ public final class Parser implements TokenId { else expr1 = parseDeclarationOrExpression(tbl2, true); + int expr2LineNumber = lex.getLineNumber(); if (lex.lookAhead() == ';') expr2 = null; else @@ -387,6 +394,7 @@ public final class Parser implements TokenId { if (lex.get() != ';') throw new CompileError("; is missing", lex); + int expr3LineNumber = lex.getLineNumber(); if (lex.lookAhead() == ')') expr3 = null; else @@ -397,7 +405,7 @@ public final class Parser implements TokenId { Stmnt body = parseStatement(tbl2); return new Stmnt(t, expr1, new ASTList(expr2, - new ASTList(expr3, body))); + new ASTList(expr3, body, expr3LineNumber), expr2LineNumber), expr1LineNumber); } /* switch.statement : SWITCH "(" expression ")" "{" switch.block "}" @@ -411,7 +419,7 @@ public final class Parser implements TokenId { int t = lex.get(); // SWITCH ASTree expr = parseParExpression(tbl); Stmnt body = parseSwitchBlock(tbl); - return new Stmnt(t, expr, body); + return new Stmnt(t, expr, body, lex.getLineNumber()); } private Stmnt parseSwitchBlock(SymbolTable tbl) throws CompileError { @@ -428,17 +436,17 @@ public final class Parser implements TokenId { throw new CompileError("no case or default in a switch block", lex); - Stmnt body = new Stmnt(BLOCK, s); + Stmnt body = new Stmnt(BLOCK, s, lex.getLineNumber()); while (lex.lookAhead() != '}') { Stmnt s2 = parseStmntOrCase(tbl2); if (s2 != null) { int op2 = s2.getOperator(); if (op2 == CASE || op2 == DEFAULT) { - body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s2)); + body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s2, lex.getLineNumber())); s = s2; } else - s = (Stmnt)ASTList.concat(s, new Stmnt(BLOCK, s2)); + s = (Stmnt)ASTList.concat(s, new Stmnt(BLOCK, s2, lex.getLineNumber())); } } @@ -454,9 +462,9 @@ public final class Parser implements TokenId { lex.get(); Stmnt s; if (t == CASE) - s = new Stmnt(t, parseExpression(tbl)); + s = new Stmnt(t, parseExpression(tbl), lex.getLineNumber()); else - s = new Stmnt(DEFAULT); + s = new Stmnt(DEFAULT, lex.getLineNumber()); if (lex.get() != ':') throw new CompileError(": is missing", lex); @@ -477,7 +485,7 @@ public final class Parser implements TokenId { throw new SyntaxError(lex); Stmnt body = parseBlock(tbl); - return new Stmnt(t, expr, body); + return new Stmnt(t, expr, body, lex.getLineNumber()); } /* try.statement @@ -503,7 +511,7 @@ public final class Parser implements TokenId { throw new SyntaxError(lex); Stmnt b = parseBlock(tbl2); - catchList = ASTList.append(catchList, new Pair(d, b)); + catchList = ASTList.append(catchList, new Pair(d, b), lex.getLineNumber()); } Stmnt finallyBlock = null; @@ -512,14 +520,14 @@ public final class Parser implements TokenId { finallyBlock = parseBlock(tbl); } - return Stmnt.make(TRY, block, catchList, finallyBlock); + return Stmnt.make(TRY, block, catchList, finallyBlock, lex.getLineNumber()); } /* return.statement : RETURN [ expression ] ";" */ private Stmnt parseReturn(SymbolTable tbl) throws CompileError { int t = lex.get(); // RETURN - Stmnt s = new Stmnt(t); + Stmnt s = new Stmnt(t, lex.getLineNumber()); if (lex.lookAhead() != ';') s.setLeft(parseExpression(tbl)); @@ -537,7 +545,7 @@ public final class Parser implements TokenId { if (lex.get() != ';') throw new CompileError("; is missing", lex); - return new Stmnt(t, expr); + return new Stmnt(t, expr, lex.getLineNumber()); } /* break.statement : BREAK [ Identifier ] ";" @@ -554,10 +562,10 @@ public final class Parser implements TokenId { throws CompileError { int t = lex.get(); // CONTINUE - Stmnt s = new Stmnt(t); + Stmnt s = new Stmnt(t, lex.getLineNumber()); int t2 = lex.get(); if (t2 == Identifier) { - s.setLeft(new Symbol(lex.getString())); + s.setLeft(new Symbol(lex.getString(), lex.getLineNumber())); t2 = lex.get(); } @@ -589,7 +597,7 @@ public final class Parser implements TokenId { if (isBuiltinType(t)) { t = lex.get(); int dim = parseArrayDimension(); - return parseDeclarators(tbl, new Declarator(t, dim)); + return parseDeclarators(tbl, new Declarator(t, dim, lex.getLineNumber())); } else if (t == Identifier) { int i = nextIsClassType(0); @@ -597,7 +605,7 @@ public final class Parser implements TokenId { if (lex.lookAhead(i) == Identifier) { ASTList name = parseClassType(tbl); int dim = parseArrayDimension(); - return parseDeclarators(tbl, new Declarator(name, dim)); + return parseDeclarators(tbl, new Declarator(name, dim, lex.getLineNumber())); } } @@ -605,7 +613,7 @@ public final class Parser implements TokenId { if (exprList) expr = parseExprList(tbl); else - expr = new Stmnt(EXPR, parseExpression(tbl)); + expr = new Stmnt(EXPR, parseExpression(tbl), lex.getLineNumber()); if (lex.get() != ';') throw new CompileError("; is missing", lex); @@ -618,8 +626,8 @@ public final class Parser implements TokenId { private Stmnt parseExprList(SymbolTable tbl) throws CompileError { Stmnt expr = null; for (;;) { - Stmnt e = new Stmnt(EXPR, parseExpression(tbl)); - expr = (Stmnt)ASTList.concat(expr, new Stmnt(BLOCK, e)); + Stmnt e = new Stmnt(EXPR, parseExpression(tbl), lex.getLineNumber()); + expr = (Stmnt)ASTList.concat(expr, new Stmnt(BLOCK, e, lex.getLineNumber())); if (lex.lookAhead() == ',') lex.get(); else @@ -635,7 +643,7 @@ public final class Parser implements TokenId { Stmnt decl = null; for (;;) { decl = (Stmnt)ASTList.concat(decl, - new Stmnt(DECL, parseDeclarator(tbl, d))); + new Stmnt(DECL, parseDeclarator(tbl, d), lex.getLineNumber())); int t = lex.get(); if (t == ';') return decl; @@ -653,7 +661,7 @@ public final class Parser implements TokenId { throw new SyntaxError(lex); String name = lex.getString(); - Symbol symbol = new Symbol(name); + Symbol symbol = new Symbol(name, lex.getLineNumber()); int dim = parseArrayDimension(); ASTree init = null; if (lex.lookAhead() == '=') { @@ -661,7 +669,7 @@ public final class Parser implements TokenId { init = parseInitializer(tbl); } - Declarator decl = d.make(symbol, dim, init); + Declarator decl = d.make(symbol, dim, init, lex.getLineNumber()); tbl.append(name, decl); return decl; } @@ -683,14 +691,14 @@ public final class Parser implements TokenId { lex.get(); // '{' if(lex.lookAhead() == '}'){ lex.get(); - return new ArrayInit(null); + return new ArrayInit(null, lex.getLineNumber()); } ASTree expr = parseExpression(tbl); - ArrayInit init = new ArrayInit(expr); + ArrayInit init = new ArrayInit(expr, lex.getLineNumber()); while (lex.lookAhead() == ',') { lex.get(); expr = parseExpression(tbl); - ASTList.append(init, expr); + ASTList.append(init, expr, lex.getLineNumber()); } if (lex.get() != '}') @@ -722,7 +730,7 @@ public final class Parser implements TokenId { int t = lex.get(); ASTree right = parseExpression(tbl); - return AssignExpr.makeAssign(t, left, right); + return AssignExpr.makeAssign(t, left, right, lex.getLineNumber()); } private static boolean isAssignOp(int t) { @@ -744,7 +752,7 @@ public final class Parser implements TokenId { throw new CompileError(": is missing", lex); ASTree elseExpr = parseExpression(tbl); - return new CondExpr(cond, thenExpr, elseExpr); + return new CondExpr(cond, thenExpr, elseExpr, lex.getLineNumber()); } return cond; } @@ -808,11 +816,11 @@ public final class Parser implements TokenId { if (isBuiltinType(t)) { lex.get(); // primitive type int dim = parseArrayDimension(); - return new InstanceOfExpr(t, dim, expr); + return new InstanceOfExpr(t, dim, expr, lex.getLineNumber()); } ASTList name = parseClassType(tbl); int dim = parseArrayDimension(); - return new InstanceOfExpr(name, dim, expr); + return new InstanceOfExpr(name, dim, expr, lex.getLineNumber()); } private ASTree binaryExpr2(SymbolTable tbl, ASTree expr, int prec) @@ -829,7 +837,7 @@ public final class Parser implements TokenId { if (p2 != 0 && prec > p2) expr2 = binaryExpr2(tbl, expr2, p2); else - return BinExpr.makeBin(t, expr, expr2); + return BinExpr.makeBin(t, expr, expr2, lex.getLineNumber()); } } @@ -887,17 +895,17 @@ public final class Parser implements TokenId { case IntConstant : case CharConstant : lex.get(); - return new IntConst(-lex.getLong(), t2); + return new IntConst(-lex.getLong(), t2, lex.getLineNumber()); case DoubleConstant : case FloatConstant : lex.get(); - return new DoubleConst(-lex.getDouble(), t2); + return new DoubleConst(-lex.getDouble(), t2, lex.getLineNumber()); default : break; } } - return Expr.make(t, parseUnaryExpr(tbl)); + return Expr.make(t, parseUnaryExpr(tbl), lex.getLineNumber()); case '(' : return parseCast(tbl); default : @@ -922,7 +930,7 @@ public final class Parser implements TokenId { if (lex.get() != ')') throw new CompileError(") is missing", lex); - return new CastExpr(t, dim, parseUnaryExpr(tbl)); + return new CastExpr(t, dim, parseUnaryExpr(tbl), lex.getLineNumber()); } else if (t == Identifier && nextIsClassCast()) { lex.get(); // '(' @@ -931,7 +939,7 @@ public final class Parser implements TokenId { if (lex.get() != ')') throw new CompileError(") is missing", lex); - return new CastExpr(name, dim, parseUnaryExpr(tbl)); + return new CastExpr(name, dim, parseUnaryExpr(tbl), lex.getLineNumber()); } else return parsePostfix(tbl); @@ -1001,7 +1009,7 @@ public final class Parser implements TokenId { if (lex.get() != Identifier) throw new SyntaxError(lex); - list = ASTList.append(list, new Symbol(lex.getString())); + list = ASTList.append(list, new Symbol(lex.getString(), lex.getLineNumber()), lex.getLineNumber()); if (lex.lookAhead() == '.') lex.get(); else @@ -1035,11 +1043,11 @@ public final class Parser implements TokenId { case IntConstant : case CharConstant : lex.get(); - return new IntConst(lex.getLong(), token); + return new IntConst(lex.getLong(), token, lex.getLineNumber()); case DoubleConstant : case FloatConstant : lex.get(); - return new DoubleConst(lex.getDouble(), token); + return new DoubleConst(lex.getDouble(), token, lex.getLineNumber()); default : break; } @@ -1066,13 +1074,13 @@ public final class Parser implements TokenId { if (index == null) throw new SyntaxError(lex); - expr = Expr.make(ARRAY, expr, index); + expr = Expr.make(ARRAY, expr, index, lex.getLineNumber()); } break; case PLUSPLUS : case MINUSMINUS : t = lex.get(); - expr = Expr.make(t, null, expr); + expr = Expr.make(t, null, expr, lex.getLineNumber()); break; case '.' : lex.get(); @@ -1080,10 +1088,10 @@ public final class Parser implements TokenId { if (t == CLASS) expr = parseDotClass(expr, 0); else if (t == SUPER) - expr = Expr.make('.', new Symbol(toClassName(expr)), new Keyword(t)); + expr = Expr.make('.', new Symbol(toClassName(expr), lex.getLineNumber()), new Keyword(t, lex.getLineNumber()), lex.getLineNumber()); else if (t == Identifier) { str = lex.getString(); - expr = Expr.make('.', expr, new Member(str)); + expr = Expr.make('.', expr, new Member(str, lex.getLineNumber()), lex.getLineNumber()); } else throw new CompileError("missing member name", lex); @@ -1095,8 +1103,8 @@ public final class Parser implements TokenId { throw new CompileError("missing static member name", lex); str = lex.getString(); - expr = Expr.make(MEMBER, new Symbol(toClassName(expr)), - new Member(str)); + expr = Expr.make(MEMBER, new Symbol(toClassName(expr), lex.getLineNumber()), + new Member(str, lex.getLineNumber()), lex.getLineNumber()); break; default : return expr; @@ -1121,7 +1129,7 @@ public final class Parser implements TokenId { cname = sbuf.toString(); } - return Expr.make('.', new Symbol(cname), new Member("class")); + return Expr.make('.', new Symbol(cname, className.getLineNumber()), new Member("class", className.getLineNumber()), lex.getLineNumber()); } /* Parses a .class expression on a built-in type. For example, @@ -1133,7 +1141,7 @@ public final class Parser implements TokenId { { if (dim > 0) { String cname = CodeGen.toJvmTypeName(builtinType, dim); - return Expr.make('.', new Symbol(cname), new Member("class")); + return Expr.make('.', new Symbol(cname, lex.getLineNumber()), new Member("class", lex.getLineNumber()), lex.getLineNumber()); } String cname; switch(builtinType) { @@ -1166,10 +1174,10 @@ public final class Parser implements TokenId { break; default : throw new CompileError("invalid builtin type: " - + builtinType); + + builtinType, lex); } - return Expr.make(MEMBER, new Symbol(cname), new Member("TYPE")); + return Expr.make(MEMBER, new Symbol(cname, lex.getLineNumber()), new Member("TYPE", lex.getLineNumber()), lex.getLineNumber()); } /* method.call : method.expr "(" argument.list ")" @@ -1193,7 +1201,7 @@ public final class Parser implements TokenId { throw new SyntaxError(lex); } - return CallExpr.makeCall(expr, parseArgumentList(tbl)); + return CallExpr.makeCall(expr, parseArgumentList(tbl), lex.getLineNumber()); } private String toClassName(ASTree name) @@ -1246,15 +1254,15 @@ public final class Parser implements TokenId { case TRUE : case FALSE : case NULL : - return new Keyword(t); + return new Keyword(t, lex.getLineNumber()); case Identifier : name = lex.getString(); decl = tbl.lookup(name); if (decl == null) - return new Member(name); // this or static member - return new Variable(name, decl); // local variable + return new Member(name, lex.getLineNumber()); // this or static member + return new Variable(name, decl, lex.getLineNumber()); // local variable case StringL : - return new StringL(lex.getString()); + return new StringL(lex.getString(), lex.getLineNumber()); case NEW : return parseNew(tbl); case '(' : @@ -1286,21 +1294,21 @@ public final class Parser implements TokenId { if (lex.lookAhead() == '{') init = parseArrayInitializer(tbl); - return new NewExpr(t, size, init); + return new NewExpr(t, size, init, lex.getLineNumber()); } else if (t == Identifier) { ASTList name = parseClassType(tbl); t = lex.lookAhead(); if (t == '(') { ASTList args = parseArgumentList(tbl); - return new NewExpr(name, args); + return new NewExpr(name, args, lex.getLineNumber()); } else if (t == '[') { ASTList size = parseArraySize(tbl); if (lex.lookAhead() == '{') init = parseArrayInitializer(tbl); - return NewExpr.makeObjectArray(name, size, init); + return NewExpr.makeObjectArray(name, size, init, lex.getLineNumber()); } } @@ -1312,7 +1320,7 @@ public final class Parser implements TokenId { private ASTList parseArraySize(SymbolTable tbl) throws CompileError { ASTList list = null; while (lex.lookAhead() == '[') - list = ASTList.append(list, parseArrayIndex(tbl)); + list = ASTList.append(list, parseArrayIndex(tbl), lex.getLineNumber()); return list; } @@ -1341,7 +1349,7 @@ public final class Parser implements TokenId { ASTList list = null; if (lex.lookAhead() != ')') for (;;) { - list = ASTList.append(list, parseExpression(tbl)); + list = ASTList.append(list, parseExpression(tbl), lex.getLineNumber()); if (lex.lookAhead() == ',') lex.get(); else diff --git a/src/main/javassist/compiler/ProceedHandler.java b/src/main/javassist/compiler/ProceedHandler.java index 1c3cd47a..04023717 100644 --- a/src/main/javassist/compiler/ProceedHandler.java +++ b/src/main/javassist/compiler/ProceedHandler.java @@ -25,6 +25,6 @@ import javassist.compiler.ast.ASTList; * @see javassist.compiler.JvstCodeGen#setProceedHandler(ProceedHandler, String) */ public interface ProceedHandler { - void doit(JvstCodeGen gen, Bytecode b, ASTList args) throws CompileError; - void setReturnType(JvstTypeChecker c, ASTList args) throws CompileError; + void doit(JvstCodeGen gen, Bytecode b, ASTList args, int lineNumber) throws CompileError; + void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber) throws CompileError; } diff --git a/src/main/javassist/compiler/TypeChecker.java b/src/main/javassist/compiler/TypeChecker.java index bceba419..0d7c8e92 100644 --- a/src/main/javassist/compiler/TypeChecker.java +++ b/src/main/javassist/compiler/TypeChecker.java @@ -73,14 +73,14 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { * into a String object. */ protected static String argTypesToString(int[] types, int[] dims, - String[] cnames) { + String[] cnames, int lineNumber) { StringBuilder sbuf = new StringBuilder(); sbuf.append('('); int n = types.length; if (n > 0) { int i = 0; while (true) { - typeToString(sbuf, types[i], dims[i], cnames[i]); + typeToString(sbuf, types[i], dims[i], cnames[i], lineNumber); if (++i < n) sbuf.append(','); else @@ -97,7 +97,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { * into a String object. */ protected static StringBuilder typeToString(StringBuilder sbuf, - int type, int dim, String cname) { + int type, int dim, String cname, int lineNumber) { String s; if (type == CLASS) s = MemberResolver.jvmToJavaName(cname); @@ -105,7 +105,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { s = "Object"; else try { - s = MemberResolver.getTypeName(type); + s = MemberResolver.getTypeName(type, lineNumber); } catch (CompileError e) { s = "?"; @@ -125,8 +125,8 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { thisMethod = m; } - protected static void fatal() throws CompileError { - throw new CompileError("fatal"); + protected static void fatal(int lineLum) throws CompileError { + throw new CompileError("fatal", lineLum); } /** @@ -156,8 +156,8 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { /* Expands a simple class name to java.lang.*. * For example, this converts Object into java/lang/Object. */ - protected String resolveClassName(String jvmName) throws CompileError { - return resolver.resolveJvmClassName(jvmName); + protected String resolveClassName(String jvmName, int lineNumber) throws CompileError { + return resolver.resolveJvmClassName(jvmName, lineNumber); } @Override @@ -168,7 +168,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { CtClass clazz = resolver.lookupClassByName(expr.getClassName()); String cname = clazz.getName(); ASTList args = expr.getArguments(); - atMethodCallCore(clazz, MethodInfo.nameInit, args); + atMethodCallCore(clazz, MethodInfo.nameInit, args, expr.getLineNumber()); exprType = CLASS; arrayDim = 0; className = MemberResolver.javaToJvmName(cname); @@ -294,7 +294,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { throws CompileError { CtField f = fieldAccess(left); - atFieldRead(f); + atFieldRead(f, expr.getLineNumber()); int fType = exprType; int fDim = arrayDim; String cname = className; @@ -316,9 +316,9 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { if (dim1 == 0 && dim1 == arrayDim) if (CodeGen.rightIsStrong(type1, exprType)) - expr.setThen(new CastExpr(exprType, 0, expr.thenExpr())); + expr.setThen(new CastExpr(exprType, 0, expr.thenExpr(), expr.getLineNumber())); else if (CodeGen.rightIsStrong(exprType, type1)) { - expr.setElse(new CastExpr(type1, 0, expr.elseExpr())); + expr.setElse(new CastExpr(type1, 0, expr.elseExpr(), expr.getLineNumber())); exprType = type1; } } @@ -343,7 +343,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { * an expression using StringBuffer. */ e = CallExpr.makeCall(Expr.make('.', e, - new Member("toString")), null); + new Member("toString", expr.getLineNumber()), expr.getLineNumber()), null, expr.getLineNumber()); expr.setOprand1(e); expr.setOprand2(null); // <---- look at this! className = jvmJavaLangString; @@ -404,9 +404,10 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { if ((type1 == CLASS && dim1 == 0 && jvmJavaLangString.equals(cname)) || (exprType == CLASS && arrayDim == 0 && jvmJavaLangString.equals(className))) { - ASTList sbufClass = ASTList.make(new Symbol("java"), - new Symbol("lang"), new Symbol("StringBuffer")); - ASTree e = new NewExpr(sbufClass, null); + int lineNum = expr.getLineNumber(); + ASTList sbufClass = ASTList.make(new Symbol("java", lineNum), + new Symbol("lang", lineNum), new Symbol("StringBuffer", lineNum), lineNum); + ASTree e = new NewExpr(sbufClass, null, lineNum); exprType = CLASS; arrayDim = 0; className = "java/lang/StringBuffer"; @@ -424,7 +425,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { ASTree newExpr = null; if (left instanceof StringL && right instanceof StringL && op == '+') newExpr = new StringL(((StringL)left).get() - + ((StringL)right).get()); + + ((StringL)right).get(), left.getLineNumber()); else if (left instanceof IntConst) newExpr = ((IntConst)left).compute(op, right); else if (left instanceof DoubleConst) @@ -451,7 +452,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { Expr e = (Expr)expr; int op = e.getOperator(); if (op == MEMBER) { - ASTree cexpr = getConstantFieldValue((Member)e.oprand2()); + ASTree cexpr = getConstantFieldValue((Member)e.oprand2(), expr.getLineNumber()); if (cexpr != null) return cexpr; } @@ -459,7 +460,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { return e.getLeft(); } else if (expr instanceof Member) { - ASTree cexpr = getConstantFieldValue((Member)expr); + ASTree cexpr = getConstantFieldValue((Member)expr, expr.getLineNumber()); if (cexpr != null) return cexpr; } @@ -471,11 +472,11 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { * If MEM is a static final field, this method returns a constant * expression representing the value of that field. */ - private static ASTree getConstantFieldValue(Member mem) { - return getConstantFieldValue(mem.getField()); + private static ASTree getConstantFieldValue(Member mem, int lineNumber) { + return getConstantFieldValue(mem.getField(), lineNumber); } - public static ASTree getConstantFieldValue(CtField f) { + public static ASTree getConstantFieldValue(CtField f, int lineNumber) { if (f == null) return null; @@ -484,19 +485,19 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { return null; if (value instanceof String) - return new StringL((String)value); + return new StringL((String)value, lineNumber); else if (value instanceof Double || value instanceof Float) { int token = (value instanceof Double) ? DoubleConstant : FloatConstant; - return new DoubleConst(((Number)value).doubleValue(), token); + return new DoubleConst(((Number)value).doubleValue(), token, lineNumber); } else if (value instanceof Number) { int token = (value instanceof Long) ? LongConstant : IntConstant; - return new IntConst(((Number)value).longValue(), token); + return new IntConst(((Number)value).longValue(), token, lineNumber); } else if (value instanceof Boolean) return new Keyword(((Boolean)value).booleanValue() - ? TokenId.TRUE : TokenId.FALSE); + ? TokenId.TRUE : TokenId.FALSE, lineNumber); else return null; } @@ -512,8 +513,8 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { } private static Expr makeAppendCall(ASTree target, ASTree arg) { - return CallExpr.makeCall(Expr.make('.', target, new Member("append")), - new ASTList(arg)); + return CallExpr.makeCall(Expr.make('.', target, new Member("append", target.getLineNumber()), target.getLineNumber()), + new ASTList(arg, target.getLineNumber()), target.getLineNumber()); } private void computeBinExprType(BinExpr expr, int token, int type1) @@ -561,7 +562,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { throws CompileError { if (CodeGen.rightIsStrong(type1, type2)) - expr.setLeft(new CastExpr(type2, 0, expr.oprand1())); + expr.setLeft(new CastExpr(type2, 0, expr.oprand1(), expr.getLineNumber())); else exprType = type1; } @@ -618,7 +619,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { else if (token == '!') booleanExpr(expr); else if (token == CALL) // method call - fatal(); + fatal(expr.getLineNumber()); else { oprand.accept(this); if (!isConstant(expr, token, oprand)) @@ -681,7 +682,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { if (op == MEMBER) // static method targetClass = resolver.lookupClass(((Symbol)e.oprand1()).get(), - false); + false, e.getLineNumber()); else if (op == '.') { ASTree target = e.oprand1(); String classFollowedByDotSuper = isDotSuper(target); @@ -702,30 +703,30 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { className = nfe.getField(); // JVM-internal e.setOperator(MEMBER); e.setOprand1(new Symbol(MemberResolver.jvmToJavaName( - className))); + className), e.getLineNumber())); } if (arrayDim > 0) - targetClass = resolver.lookupClass(javaLangObject, true); + targetClass = resolver.lookupClass(javaLangObject, true, e.getLineNumber()); else if (exprType == CLASS /* && arrayDim == 0 */) - targetClass = resolver.lookupClassByJvmName(className); + targetClass = resolver.lookupClassByJvmName(className, e.getLineNumber()); else - badMethod(); + badMethod(e.getLineNumber()); } } else - badMethod(); + badMethod(expr.getLineNumber()); } else - fatal(); + fatal(expr.getLineNumber()); MemberResolver.Method minfo - = atMethodCallCore(targetClass, mname, args); + = atMethodCallCore(targetClass, mname, args, expr.getLineNumber()); expr.setMethod(minfo); } - private static void badMethod() throws CompileError { - throw new CompileError("bad method"); + private static void badMethod(int lineNumber) throws CompileError { + throw new CompileError("bad method", lineNumber); } /** @@ -753,7 +754,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { * and the MethodInfo of that method. Never null. */ public MemberResolver.Method atMethodCallCore(CtClass targetClass, - String mname, ASTList args) + String mname, ASTList args, int lineNumber) throws CompileError { int nargs = getMethodArgsLength(args); @@ -767,18 +768,18 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { mname, types, dims, cnames); if (found == null) { String clazz = targetClass.getName(); - String signature = argTypesToString(types, dims, cnames); + String signature = argTypesToString(types, dims, cnames, lineNumber); String msg; if (mname.equals(MethodInfo.nameInit)) msg = "cannot find constructor " + clazz + signature; else msg = mname + signature + " not found in " + clazz; - throw new CompileError(msg); + throw new CompileError(msg, lineNumber); } String desc = found.info.getDescriptor(); - setReturnType(desc); + setReturnType(desc, lineNumber); return found; } @@ -800,10 +801,10 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { } } - void setReturnType(String desc) throws CompileError { + void setReturnType(String desc, int lineNumber) throws CompileError { int i = desc.indexOf(')'); if (i < 0) - badMethod(); + badMethod(lineNumber); char c = desc.charAt(++i); int dim = 0; @@ -816,22 +817,22 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { if (c == 'L') { int j = desc.indexOf(';', i + 1); if (j < 0) - badMethod(); + badMethod(lineNumber); exprType = CLASS; className = desc.substring(i + 1, j); } else { - exprType = MemberResolver.descToType(c); + exprType = MemberResolver.descToType(c, lineNumber); className = null; } } private void atFieldRead(ASTree expr) throws CompileError { - atFieldRead(fieldAccess(expr)); + atFieldRead(fieldAccess(expr), expr.getLineNumber()); } - private void atFieldRead(CtField f) throws CompileError { + private void atFieldRead(CtField f, int lineNumber) throws CompileError { FieldInfo finfo = f.getFieldInfo2(); String type = finfo.getDescriptor(); @@ -844,7 +845,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { } arrayDim = dim; - exprType = MemberResolver.descToType(c); + exprType = MemberResolver.descToType(c, lineNumber); if (c == 'L') className = type.substring(i + 1, type.indexOf(';', i + 1)); @@ -933,14 +934,14 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { } } - throw new CompileError("bad field access"); + throw new CompileError("bad field access", expr.getLineNumber()); } private CtField fieldAccess2(Expr e, String jvmClassName) throws CompileError { Member fname = (Member)e.oprand2(); CtField f = resolver.lookupFieldByJvmName2(jvmClassName, fname, e); e.setOperator(MEMBER); - e.setOprand1(new Symbol(MemberResolver.jvmToJavaName(jvmClassName))); + e.setOprand1(new Symbol(MemberResolver.jvmToJavaName(jvmClassName), e.getLineNumber())); fname.setField(f); return f; } @@ -1006,7 +1007,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { protected void atFieldPlusPlus(ASTree oprand) throws CompileError { CtField f = fieldAccess(oprand); - atFieldRead(f); + atFieldRead(f, oprand.getLineNumber()); int t = exprType; if (t == INT || t == BYTE || t == CHAR || t == SHORT) exprType = INT; @@ -1046,7 +1047,7 @@ public class TypeChecker extends Visitor implements Opcode, TokenId { className = getSuperName(); break; default : - fatal(); + fatal(k.getLineNumber()); } } diff --git a/src/main/javassist/compiler/ast/ASTList.java b/src/main/javassist/compiler/ast/ASTList.java index d9232ca0..786957f5 100644 --- a/src/main/javassist/compiler/ast/ASTList.java +++ b/src/main/javassist/compiler/ast/ASTList.java @@ -28,18 +28,18 @@ public class ASTList extends ASTree { private ASTree left; private ASTList right; - public ASTList(ASTree _head, ASTList _tail) { + public ASTList(ASTree _head, ASTList _tail, int lineNumber) { + super(lineNumber); left = _head; right = _tail; } - public ASTList(ASTree _head) { - left = _head; - right = null; + public ASTList(ASTree _head, int lineNumber) { + this(_head, null, lineNumber); } - public static ASTList make(ASTree e1, ASTree e2, ASTree e3) { - return new ASTList(e1, new ASTList(e2, new ASTList(e3))); + public static ASTList make(ASTree e1, ASTree e2, ASTree e3 , int lineNumber) { + return new ASTList(e1, new ASTList(e2, new ASTList(e3, lineNumber), lineNumber), lineNumber); } @Override @@ -146,8 +146,8 @@ public class ASTList extends ASTree { /** * Appends an object to a list. */ - public static ASTList append(ASTList a, ASTree b) { - return concat(a, new ASTList(b)); + public static ASTList append(ASTList a, ASTree b, int lineNumber) { + return concat(a, new ASTList(b, lineNumber)); } /** diff --git a/src/main/javassist/compiler/ast/ASTree.java b/src/main/javassist/compiler/ast/ASTree.java index 3d4dd842..f155fa87 100644 --- a/src/main/javassist/compiler/ast/ASTree.java +++ b/src/main/javassist/compiler/ast/ASTree.java @@ -29,6 +29,12 @@ public abstract class ASTree implements Serializable { /** default serialVersionUID */ private static final long serialVersionUID = 1L; + private final int lineNumber; + + public ASTree(int lineNumber) { + this.lineNumber = lineNumber; + } + public ASTree getLeft() { return null; } public ASTree getRight() { return null; } @@ -61,4 +67,8 @@ public abstract class ASTree implements Serializable { String name = getClass().getName(); return name.substring(name.lastIndexOf('.') + 1); } + + public int getLineNumber() { + return lineNumber; + } } diff --git a/src/main/javassist/compiler/ast/ArrayInit.java b/src/main/javassist/compiler/ast/ArrayInit.java index 0b87200e..bc3f06ea 100644 --- a/src/main/javassist/compiler/ast/ArrayInit.java +++ b/src/main/javassist/compiler/ast/ArrayInit.java @@ -27,10 +27,12 @@ public class ArrayInit extends ASTList { /** * Constructs an object. - * @param firstElement maybe null when the initializer is <code>{}</code> (empty). + * + * @param firstElement maybe null when the initializer is <code>{}</code> (empty). + * @param lineNumber */ - public ArrayInit(ASTree firstElement) { - super(firstElement); + public ArrayInit(ASTree firstElement, int lineNumber) { + super(firstElement, lineNumber); } /** diff --git a/src/main/javassist/compiler/ast/AssignExpr.java b/src/main/javassist/compiler/ast/AssignExpr.java index a5e1857d..97dfc6e7 100644 --- a/src/main/javassist/compiler/ast/AssignExpr.java +++ b/src/main/javassist/compiler/ast/AssignExpr.java @@ -29,13 +29,13 @@ public class AssignExpr extends Expr { /** default serialVersionUID */ private static final long serialVersionUID = 1L; - private AssignExpr(int op, ASTree _head, ASTList _tail) { - super(op, _head, _tail); + private AssignExpr(int op, ASTree _head, ASTList _tail, int lineNumber) { + super(op, _head, _tail, lineNumber); } public static AssignExpr makeAssign(int op, ASTree oprand1, - ASTree oprand2) { - return new AssignExpr(op, oprand1, new ASTList(oprand2)); + ASTree oprand2, int lineNumber) { + return new AssignExpr(op, oprand1, new ASTList(oprand2, lineNumber), lineNumber); } @Override diff --git a/src/main/javassist/compiler/ast/BinExpr.java b/src/main/javassist/compiler/ast/BinExpr.java index 9630ada9..789312ec 100644 --- a/src/main/javassist/compiler/ast/BinExpr.java +++ b/src/main/javassist/compiler/ast/BinExpr.java @@ -33,12 +33,12 @@ public class BinExpr extends Expr { /** default serialVersionUID */ private static final long serialVersionUID = 1L; - private BinExpr(int op, ASTree _head, ASTList _tail) { - super(op, _head, _tail); + private BinExpr(int op, ASTree _head, ASTList _tail, int lineNumber) { + super(op, _head, _tail, lineNumber); } - public static BinExpr makeBin(int op, ASTree oprand1, ASTree oprand2) { - return new BinExpr(op, oprand1, new ASTList(oprand2)); + public static BinExpr makeBin(int op, ASTree oprand1, ASTree oprand2, int lineNumber) { + return new BinExpr(op, oprand1, new ASTList(oprand2, lineNumber), lineNumber); } @Override diff --git a/src/main/javassist/compiler/ast/CallExpr.java b/src/main/javassist/compiler/ast/CallExpr.java index 395915ed..72a3ca51 100644 --- a/src/main/javassist/compiler/ast/CallExpr.java +++ b/src/main/javassist/compiler/ast/CallExpr.java @@ -28,8 +28,8 @@ public class CallExpr extends Expr { private static final long serialVersionUID = 1L; private MemberResolver.Method method; // cached result of lookupMethod() - private CallExpr(ASTree _head, ASTList _tail) { - super(TokenId.CALL, _head, _tail); + private CallExpr(ASTree _head, ASTList _tail, int lineNumber) { + super(TokenId.CALL, _head, _tail, lineNumber); method = null; } @@ -41,8 +41,8 @@ public class CallExpr extends Expr { return method; } - public static CallExpr makeCall(ASTree target, ASTree args) { - return new CallExpr(target, new ASTList(args)); + public static CallExpr makeCall(ASTree target, ASTree args, int lineNumber) { + return new CallExpr(target, new ASTList(args, lineNumber), lineNumber); } @Override diff --git a/src/main/javassist/compiler/ast/CastExpr.java b/src/main/javassist/compiler/ast/CastExpr.java index 903e5bbd..d3938078 100644 --- a/src/main/javassist/compiler/ast/CastExpr.java +++ b/src/main/javassist/compiler/ast/CastExpr.java @@ -28,14 +28,14 @@ public class CastExpr extends ASTList implements TokenId { protected int castType; protected int arrayDim; - public CastExpr(ASTList className, int dim, ASTree expr) { - super(className, new ASTList(expr)); + public CastExpr(ASTList className, int dim, ASTree expr, int lineNumber) { + super(className, new ASTList(expr, lineNumber), lineNumber); castType = CLASS; arrayDim = dim; } - public CastExpr(int type, int dim, ASTree expr) { - super(null, new ASTList(expr)); + public CastExpr(int type, int dim, ASTree expr, int lineNumber) { + super(null, new ASTList(expr, lineNumber), lineNumber); castType = type; arrayDim = dim; } diff --git a/src/main/javassist/compiler/ast/CondExpr.java b/src/main/javassist/compiler/ast/CondExpr.java index 46435012..e4b6e07b 100644 --- a/src/main/javassist/compiler/ast/CondExpr.java +++ b/src/main/javassist/compiler/ast/CondExpr.java @@ -25,8 +25,8 @@ public class CondExpr extends ASTList { /** default serialVersionUID */ private static final long serialVersionUID = 1L; - public CondExpr(ASTree cond, ASTree thenp, ASTree elsep) { - super(cond, new ASTList(thenp, new ASTList(elsep))); + public CondExpr(ASTree cond, ASTree thenp, ASTree elsep, int lineNumber) { + super(cond, new ASTList(thenp, new ASTList(elsep, lineNumber), lineNumber), lineNumber); } public ASTree condExpr() { return head(); } diff --git a/src/main/javassist/compiler/ast/Declarator.java b/src/main/javassist/compiler/ast/Declarator.java index c29f6740..1713d908 100644 --- a/src/main/javassist/compiler/ast/Declarator.java +++ b/src/main/javassist/compiler/ast/Declarator.java @@ -30,16 +30,16 @@ public class Declarator extends ASTList implements TokenId { protected int localVar; protected String qualifiedClass; // JVM-internal representation - public Declarator(int type, int dim) { - super(null); + public Declarator(int type, int dim, int lineNumber) { + super(null, lineNumber); varType = type; arrayDim = dim; localVar = -1; qualifiedClass = null; } - public Declarator(ASTList className, int dim) { - super(null); + public Declarator(ASTList className, int dim, int lineNumber) { + super(null, lineNumber); varType = CLASS; arrayDim = dim; localVar = -1; @@ -49,21 +49,21 @@ public class Declarator extends ASTList implements TokenId { /* For declaring a pre-defined? local variable. */ public Declarator(int type, String jvmClassName, int dim, - int var, Symbol sym) { - super(null); + int var, Symbol sym, int lineNumber) { + super(null, lineNumber); varType = type; arrayDim = dim; localVar = var; qualifiedClass = jvmClassName; setLeft(sym); - append(this, null); // initializer + append(this, null, lineNumber); // initializer } - public Declarator make(Symbol sym, int dim, ASTree init) { - Declarator d = new Declarator(this.varType, this.arrayDim + dim); + public Declarator make(Symbol sym, int dim, ASTree init, int lineNumber) { + Declarator d = new Declarator(this.varType, this.arrayDim + dim, lineNumber); d.qualifiedClass = this.qualifiedClass; d.setLeft(sym); - append(d, init); + append(d, init, lineNumber); return d; } diff --git a/src/main/javassist/compiler/ast/DoubleConst.java b/src/main/javassist/compiler/ast/DoubleConst.java index f8d0afde..d55821f0 100644 --- a/src/main/javassist/compiler/ast/DoubleConst.java +++ b/src/main/javassist/compiler/ast/DoubleConst.java @@ -28,7 +28,11 @@ public class DoubleConst extends ASTree { protected double value; protected int type; - public DoubleConst(double v, int tokenId) { value = v; type = tokenId; } + public DoubleConst(double v, int tokenId, int lineNumber) { + super(lineNumber); + value = v; + type = tokenId; + } public double get() { return value; } @@ -63,15 +67,15 @@ public class DoubleConst extends ASTree { else newType = TokenId.FloatConstant; - return compute(op, this.value, right.value, newType); + return compute(op, this.value, right.value, newType, getLineNumber()); } private DoubleConst compute0(int op, IntConst right) { - return compute(op, this.value, right.value, this.type); + return compute(op, this.value, right.value, this.type, getLineNumber()); } private static DoubleConst compute(int op, double value1, double value2, - int newType) + int newType, int lineNumber) { double newValue; switch (op) { @@ -94,6 +98,6 @@ public class DoubleConst extends ASTree { return null; } - return new DoubleConst(newValue, newType); + return new DoubleConst(newValue, newType, lineNumber); } } diff --git a/src/main/javassist/compiler/ast/Expr.java b/src/main/javassist/compiler/ast/Expr.java index ed5cb60b..4d2ce1a0 100644 --- a/src/main/javassist/compiler/ast/Expr.java +++ b/src/main/javassist/compiler/ast/Expr.java @@ -33,22 +33,22 @@ public class Expr extends ASTList implements TokenId { private static final long serialVersionUID = 1L; protected int operatorId; - Expr(int op, ASTree _head, ASTList _tail) { - super(_head, _tail); + Expr(int op, ASTree _head, ASTList _tail, int lineNumber) { + super(_head, _tail, lineNumber); operatorId = op; } - Expr(int op, ASTree _head) { - super(_head); + Expr(int op, ASTree _head, int lineNumber) { + super(_head, lineNumber); operatorId = op; } - public static Expr make(int op, ASTree oprand1, ASTree oprand2) { - return new Expr(op, oprand1, new ASTList(oprand2)); + public static Expr make(int op, ASTree oprand1, ASTree oprand2, int lineNumber) { + return new Expr(op, oprand1, new ASTList(oprand2, lineNumber), lineNumber); } - public static Expr make(int op, ASTree oprand1) { - return new Expr(op, oprand1); + public static Expr make(int op, ASTree oprand1, int lineNumber) { + return new Expr(op, oprand1, lineNumber); } public int getOperator() { return operatorId; } diff --git a/src/main/javassist/compiler/ast/FieldDecl.java b/src/main/javassist/compiler/ast/FieldDecl.java index e2a066e9..44df192e 100644 --- a/src/main/javassist/compiler/ast/FieldDecl.java +++ b/src/main/javassist/compiler/ast/FieldDecl.java @@ -22,8 +22,8 @@ public class FieldDecl extends ASTList { /** default serialVersionUID */ private static final long serialVersionUID = 1L; - public FieldDecl(ASTree _head, ASTList _tail) { - super(_head, _tail); + public FieldDecl(ASTree _head, ASTList _tail, int lineNumber) { + super(_head, _tail, lineNumber); } public ASTList getModifiers() { return (ASTList)getLeft(); } diff --git a/src/main/javassist/compiler/ast/InstanceOfExpr.java b/src/main/javassist/compiler/ast/InstanceOfExpr.java index ddf07bd2..e012defe 100644 --- a/src/main/javassist/compiler/ast/InstanceOfExpr.java +++ b/src/main/javassist/compiler/ast/InstanceOfExpr.java @@ -25,12 +25,12 @@ public class InstanceOfExpr extends CastExpr { /** default serialVersionUID */ private static final long serialVersionUID = 1L; - public InstanceOfExpr(ASTList className, int dim, ASTree expr) { - super(className, dim, expr); + public InstanceOfExpr(ASTList className, int dim, ASTree expr, int lineNumber) { + super(className, dim, expr, lineNumber); } - public InstanceOfExpr(int type, int dim, ASTree expr) { - super(type, dim, expr); + public InstanceOfExpr(int type, int dim, ASTree expr, int lineNumber) { + super(type, dim, expr, lineNumber); } @Override diff --git a/src/main/javassist/compiler/ast/IntConst.java b/src/main/javassist/compiler/ast/IntConst.java index 7040b0c9..8ffce479 100644 --- a/src/main/javassist/compiler/ast/IntConst.java +++ b/src/main/javassist/compiler/ast/IntConst.java @@ -28,7 +28,11 @@ public class IntConst extends ASTree { protected long value; protected int type; - public IntConst(long v, int tokenId) { value = v; type = tokenId; } + public IntConst(long v, int tokenId, int lineNumber) { + super(lineNumber); + value = v; + type = tokenId; + } public long get() { return value; } @@ -111,7 +115,7 @@ public class IntConst extends ASTree { return null; } - return new IntConst(newValue, newType); + return new IntConst(newValue, newType, right.getLineNumber()); } private DoubleConst compute0(int op, DoubleConst right) { @@ -138,6 +142,6 @@ public class IntConst extends ASTree { return null; } - return new DoubleConst(newValue, right.type); + return new DoubleConst(newValue, right.type, right.getLineNumber()); } } diff --git a/src/main/javassist/compiler/ast/Keyword.java b/src/main/javassist/compiler/ast/Keyword.java index b509375c..858316d5 100644 --- a/src/main/javassist/compiler/ast/Keyword.java +++ b/src/main/javassist/compiler/ast/Keyword.java @@ -26,7 +26,8 @@ public class Keyword extends ASTree { private static final long serialVersionUID = 1L; protected int tokenId; - public Keyword(int token) { + public Keyword(int token, int lineNumber) { + super(lineNumber); tokenId = token; } diff --git a/src/main/javassist/compiler/ast/Member.java b/src/main/javassist/compiler/ast/Member.java index 192c9ef3..279e2516 100644 --- a/src/main/javassist/compiler/ast/Member.java +++ b/src/main/javassist/compiler/ast/Member.java @@ -29,8 +29,8 @@ public class Member extends Symbol { // this is used to obtain the value of a static final field. private CtField field; - public Member(String name) { - super(name); + public Member(String name, int lineNumber) { + super(name, lineNumber); field = null; } diff --git a/src/main/javassist/compiler/ast/MethodDecl.java b/src/main/javassist/compiler/ast/MethodDecl.java index d96e3d4d..263775b0 100644 --- a/src/main/javassist/compiler/ast/MethodDecl.java +++ b/src/main/javassist/compiler/ast/MethodDecl.java @@ -23,8 +23,8 @@ public class MethodDecl extends ASTList { private static final long serialVersionUID = 1L; public static final String initName = "<init>"; - public MethodDecl(ASTree _head, ASTList _tail) { - super(_head, _tail); + public MethodDecl(ASTree _head, ASTList _tail, int lineNumber) { + super(_head, _tail, lineNumber); } public boolean isConstructor() { diff --git a/src/main/javassist/compiler/ast/NewExpr.java b/src/main/javassist/compiler/ast/NewExpr.java index 44b264c0..d4f7f475 100644 --- a/src/main/javassist/compiler/ast/NewExpr.java +++ b/src/main/javassist/compiler/ast/NewExpr.java @@ -28,26 +28,26 @@ public class NewExpr extends ASTList implements TokenId { protected boolean newArray; protected int arrayType; - public NewExpr(ASTList className, ASTList args) { - super(className, new ASTList(args)); + public NewExpr(ASTList className, ASTList args, int lineNumber) { + super(className, new ASTList(args, lineNumber), lineNumber); newArray = false; arrayType = CLASS; } - public NewExpr(int type, ASTList arraySize, ArrayInit init) { - super(null, new ASTList(arraySize)); + public NewExpr(int type, ASTList arraySize, ArrayInit init, int lineNumber) { + super(null, new ASTList(arraySize, lineNumber), lineNumber); newArray = true; arrayType = type; if (init != null) - append(this, init); + append(this, init, lineNumber); } public static NewExpr makeObjectArray(ASTList className, - ASTList arraySize, ArrayInit init) { - NewExpr e = new NewExpr(className, arraySize); + ASTList arraySize, ArrayInit init, int lineNumber) { + NewExpr e = new NewExpr(className, arraySize, lineNumber); e.newArray = true; if (init != null) - append(e, init); + append(e, init, lineNumber); return e; } diff --git a/src/main/javassist/compiler/ast/Pair.java b/src/main/javassist/compiler/ast/Pair.java index 949028a4..44411b8d 100644 --- a/src/main/javassist/compiler/ast/Pair.java +++ b/src/main/javassist/compiler/ast/Pair.java @@ -28,6 +28,7 @@ public class Pair extends ASTree { protected ASTree left, right; public Pair(ASTree _left, ASTree _right) { + super(_left.getLineNumber()); left = _left; right = _right; } diff --git a/src/main/javassist/compiler/ast/Stmnt.java b/src/main/javassist/compiler/ast/Stmnt.java index c5aa5df3..7333d026 100644 --- a/src/main/javassist/compiler/ast/Stmnt.java +++ b/src/main/javassist/compiler/ast/Stmnt.java @@ -27,26 +27,26 @@ public class Stmnt extends ASTList implements TokenId { private static final long serialVersionUID = 1L; protected int operatorId; - public Stmnt(int op, ASTree _head, ASTList _tail) { - super(_head, _tail); + public Stmnt(int op, ASTree _head, ASTList _tail, int lineNumber) { + super(_head, _tail, lineNumber); operatorId = op; } - public Stmnt(int op, ASTree _head) { - super(_head); + public Stmnt(int op, ASTree _head, int lineNumber) { + super(_head, lineNumber); operatorId = op; } - public Stmnt(int op) { - this(op, null); + public Stmnt(int op, int lineNumber) { + this(op, null, lineNumber); } - public static Stmnt make(int op, ASTree oprand1, ASTree oprand2) { - return new Stmnt(op, oprand1, new ASTList(oprand2)); + public static Stmnt make(int op, ASTree oprand1, ASTree oprand2, int lineNumber) { + return new Stmnt(op, oprand1, new ASTList(oprand2, lineNumber), lineNumber); } - public static Stmnt make(int op, ASTree op1, ASTree op2, ASTree op3) { - return new Stmnt(op, op1, new ASTList(op2, new ASTList(op3))); + public static Stmnt make(int op, ASTree op1, ASTree op2, ASTree op3, int lineNumber) { + return new Stmnt(op, op1, new ASTList(op2, new ASTList(op3, lineNumber), lineNumber), lineNumber); } @Override diff --git a/src/main/javassist/compiler/ast/StringL.java b/src/main/javassist/compiler/ast/StringL.java index 7c7e00c3..063bb5ed 100644 --- a/src/main/javassist/compiler/ast/StringL.java +++ b/src/main/javassist/compiler/ast/StringL.java @@ -26,7 +26,8 @@ public class StringL extends ASTree { private static final long serialVersionUID = 1L; protected String text; - public StringL(String t) { + public StringL(String t, int lineNumber) { + super(lineNumber); text = t; } diff --git a/src/main/javassist/compiler/ast/Symbol.java b/src/main/javassist/compiler/ast/Symbol.java index 2b66207a..64c598eb 100644 --- a/src/main/javassist/compiler/ast/Symbol.java +++ b/src/main/javassist/compiler/ast/Symbol.java @@ -26,7 +26,8 @@ public class Symbol extends ASTree { private static final long serialVersionUID = 1L; protected String identifier; - public Symbol(String sym) { + public Symbol(String sym, int lineNumber) { + super(lineNumber); identifier = sym; } diff --git a/src/main/javassist/compiler/ast/Variable.java b/src/main/javassist/compiler/ast/Variable.java index c9224a7a..2e186950 100644 --- a/src/main/javassist/compiler/ast/Variable.java +++ b/src/main/javassist/compiler/ast/Variable.java @@ -26,8 +26,8 @@ public class Variable extends Symbol { private static final long serialVersionUID = 1L; protected Declarator declarator; - public Variable(String sym, Declarator d) { - super(sym); + public Variable(String sym, Declarator d, int lineNumber) { + super(sym, lineNumber); declarator = d; } diff --git a/src/main/javassist/expr/Cast.java b/src/main/javassist/expr/Cast.java index 31522e5a..29f91f3e 100644 --- a/src/main/javassist/expr/Cast.java +++ b/src/main/javassist/expr/Cast.java @@ -163,26 +163,26 @@ public class Cast extends Expr { } @Override - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber) throws CompileError { if (gen.getMethodArgsLength(args) != 1) throw new CompileError(Javac.proceedName + "() cannot take more than one parameter " - + "for cast"); + + "for cast", lineNumber); gen.atMethodArgs(args, new int[1], new int[1], new String[1]); bytecode.addOpcode(Opcode.CHECKCAST); bytecode.addIndex(index); - gen.setType(retType); + gen.setType(retType, lineNumber); } @Override - public void setReturnType(JvstTypeChecker c, ASTList args) + public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber) throws CompileError { c.atMethodArgs(args, new int[1], new int[1], new String[1]); - c.setType(retType); + c.setType(retType, lineNumber); } } } diff --git a/src/main/javassist/expr/FieldAccess.java b/src/main/javassist/expr/FieldAccess.java index 335314a5..9075e5fa 100644 --- a/src/main/javassist/expr/FieldAccess.java +++ b/src/main/javassist/expr/FieldAccess.java @@ -259,12 +259,12 @@ public class FieldAccess extends Expr { } @Override - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber) throws CompileError { if (args != null && !gen.isParamListName(args)) throw new CompileError(Javac.proceedName - + "() cannot take a parameter for field reading"); + + "() cannot take a parameter for field reading", lineNumber); int stack; if (isStatic(opcode)) @@ -282,14 +282,14 @@ public class FieldAccess extends Expr { bytecode.add(opcode); bytecode.addIndex(index); bytecode.growStack(stack); - gen.setType(fieldType); + gen.setType(fieldType, lineNumber); } @Override - public void setReturnType(JvstTypeChecker c, ASTList args) + public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber) throws CompileError { - c.setType(fieldType); + c.setType(fieldType, lineNumber); } } @@ -309,13 +309,13 @@ public class FieldAccess extends Expr { } @Override - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber) throws CompileError { if (gen.getMethodArgsLength(args) != 1) throw new CompileError(Javac.proceedName + "() cannot take more than one parameter " - + "for field writing"); + + "for field writing", lineNumber); int stack; if (isStatic(opcode)) @@ -335,16 +335,16 @@ public class FieldAccess extends Expr { bytecode.add(opcode); bytecode.addIndex(index); bytecode.growStack(stack); - gen.setType(CtClass.voidType); + gen.setType(CtClass.voidType, lineNumber); gen.addNullIfVoid(); } @Override - public void setReturnType(JvstTypeChecker c, ASTList args) + public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber) throws CompileError { c.atMethodArgs(args, new int[1], new int[1], new String[1]); - c.setType(CtClass.voidType); + c.setType(CtClass.voidType, lineNumber); c.addNullIfVoid(); } } diff --git a/src/main/javassist/expr/Instanceof.java b/src/main/javassist/expr/Instanceof.java index a046ddbc..e56a3819 100644 --- a/src/main/javassist/expr/Instanceof.java +++ b/src/main/javassist/expr/Instanceof.java @@ -167,26 +167,26 @@ public class Instanceof extends Expr { } @Override - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber) throws CompileError { if (gen.getMethodArgsLength(args) != 1) throw new CompileError(Javac.proceedName + "() cannot take more than one parameter " - + "for instanceof"); + + "for instanceof", lineNumber); gen.atMethodArgs(args, new int[1], new int[1], new String[1]); bytecode.addOpcode(Opcode.INSTANCEOF); bytecode.addIndex(index); - gen.setType(CtClass.booleanType); + gen.setType(CtClass.booleanType, lineNumber); } @Override - public void setReturnType(JvstTypeChecker c, ASTList args) + public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber) throws CompileError { c.atMethodArgs(args, new int[1], new int[1], new String[1]); - c.setType(CtClass.booleanType); + c.setType(CtClass.booleanType, lineNumber); } } } diff --git a/src/main/javassist/expr/NewArray.java b/src/main/javassist/expr/NewArray.java index df30e26f..33dc417f 100644 --- a/src/main/javassist/expr/NewArray.java +++ b/src/main/javassist/expr/NewArray.java @@ -270,13 +270,13 @@ public class NewArray extends Expr { } @Override - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber) throws CompileError { int num = gen.getMethodArgsLength(args); if (num != dimension) throw new CompileError(Javac.proceedName - + "() with a wrong number of parameters"); + + "() with a wrong number of parameters", lineNumber); gen.atMethodArgs(args, new int[num], new int[num], new String[num]); @@ -291,14 +291,14 @@ public class NewArray extends Expr { bytecode.growStack(1 - dimension); } - gen.setType(arrayType); + gen.setType(arrayType, lineNumber); } @Override - public void setReturnType(JvstTypeChecker c, ASTList args) + public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber) throws CompileError { - c.setType(arrayType); + c.setType(arrayType, lineNumber); } } } diff --git a/src/main/javassist/expr/NewExpr.java b/src/main/javassist/expr/NewExpr.java index ee065167..e45a4c54 100644 --- a/src/main/javassist/expr/NewExpr.java +++ b/src/main/javassist/expr/NewExpr.java @@ -263,7 +263,7 @@ public class NewExpr extends Expr { } @Override - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber) throws CompileError { bytecode.addOpcode(NEW); @@ -271,15 +271,15 @@ public class NewExpr extends Expr { bytecode.addOpcode(DUP); gen.atMethodCallCore(newType, MethodInfo.nameInit, args, false, true, -1, null); - gen.setType(newType); + gen.setType(newType, lineNumber); } @Override - public void setReturnType(JvstTypeChecker c, ASTList args) + public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber) throws CompileError { - c.atMethodCallCore(newType, MethodInfo.nameInit, args); - c.setType(newType); + c.atMethodCallCore(newType, MethodInfo.nameInit, args, lineNumber); + c.setType(newType, lineNumber); } } } |