Explorar el Código

line numbers for undefined ids & more

pull/484/head
akuznetsov hace 4 meses
padre
commit
9777bae93c

+ 4
- 4
src/main/javassist/compiler/CodeGen.java Ver fichero

/* Expands a simple class name to java.lang.*. /* Expands a simple class name to java.lang.*.
* For example, this converts Object into java/lang/Object. * 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; throws CompileError;


/** /**
@Override @Override
public void atDeclarator(Declarator d) throws CompileError { public void atDeclarator(Declarator d) throws CompileError {
d.setLocalVar(getMaxLocals()); d.setLocalVar(getMaxLocals());
d.setClassName(resolveClassName(d.getClassName()));
d.setClassName(resolveClassName(d.getClassName(), d.getLineNumber()));


int size; int size;
if (is2word(d.getType(), d.getArrayDim())) if (is2word(d.getType(), d.getArrayDim()))
int i = cname.indexOf("[L"); int i = cname.indexOf("[L");
if (i >= 0) { if (i >= 0) {
String name = cname.substring(i + 2, cname.length() - 1); String name = cname.substring(i + 2, cname.length() - 1);
String name2 = resolveClassName(name);
String name2 = resolveClassName(name, expr.getLineNumber());
if (!name.equals(name2)) { if (!name.equals(name2)) {
/* For example, to obtain String[].class, /* For example, to obtain String[].class,
* "[Ljava.lang.String;" (not "[Ljava/lang/String"!) * "[Ljava.lang.String;" (not "[Ljava/lang/String"!)
} }
} }
else { else {
cname = resolveClassName(MemberResolver.javaToJvmName(cname));
cname = resolveClassName(MemberResolver.javaToJvmName(cname), expr.getLineNumber());
cname = MemberResolver.jvmToJavaName(cname); cname = MemberResolver.jvmToJavaName(cname);
} }



+ 1
- 1
src/main/javassist/compiler/CompileError.java Ver fichero

reason = String.format("line %d: %s", lineNumber, s); reason = String.format("line %d: %s", lineNumber, s);
} }


public CompileError(String s) {
private CompileError(String s) {
reason = s; reason = s;
lex = null; lex = null;
} }

+ 13
- 15
src/main/javassist/compiler/Javac.java Ver fichero

*/ */
public CtMember compile(String src) throws CompileError { public CtMember compile(String src) throws CompileError {
int startLine = gen.thisClass.getLinesCount(); int startLine = gen.thisClass.getLinesCount();
Parser p = new Parser(new Lex(src, startLine));
Lex lex = new Lex(src, startLine);
Parser p = new Parser(lex);
ASTList mem = p.parseMember1(stable); ASTList mem = p.parseMember1(stable);
try { try {
if (mem instanceof FieldDecl) if (mem instanceof FieldDecl)
decl.getClassFile2()); decl.getClassFile2());
return cb; 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());
} }
} }


return method; return method;
} }
catch (NotFoundException e) { catch (NotFoundException e) {
throw new CompileError(e.toString());
throw new CompileError(e.toString(), md.getLineNumber());
} }
} }


Stmnt s = p.parseStatement(stb); Stmnt s = p.parseStatement(stb);
if (p.hasMore()) if (p.hasMore())
throw new CompileError( throw new CompileError(
"the method/constructor body must be surrounded by {}");
"the method/constructor body must be surrounded by {}", s.getLineNumber());


boolean callSuper = false; boolean callSuper = false;
if (method instanceof CtConstructor) if (method instanceof CtConstructor)
return bytecode; return bytecode;
} }
catch (NotFoundException e) { catch (NotFoundException e) {
throw new CompileError(e.toString());
throw new CompileError(e.toString(), -1);
} }
} }




ProceedHandler h = new ProceedHandler() { ProceedHandler h = new ProceedHandler() {
@Override @Override
public void doit(JvstCodeGen gen, Bytecode b, ASTList args)
public void doit(JvstCodeGen gen, Bytecode b, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
ASTree expr = new Member(m, texpr.getLineNumber()); ASTree expr = new Member(m, texpr.getLineNumber());
} }


@Override @Override
public void setReturnType(JvstTypeChecker check, ASTList args)
public void setReturnType(JvstTypeChecker check, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
ASTree expr = new Member(m, texpr.getLineNumber()); ASTree expr = new Member(m, texpr.getLineNumber());


ProceedHandler h = new ProceedHandler() { ProceedHandler h = new ProceedHandler() {
@Override @Override
public void doit(JvstCodeGen gen, Bytecode b, ASTList args)
public void doit(JvstCodeGen gen, Bytecode b, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
Expr expr = Expr.make(TokenId.MEMBER, Expr expr = Expr.make(TokenId.MEMBER,
} }


@Override @Override
public void setReturnType(JvstTypeChecker check, ASTList args)
public void setReturnType(JvstTypeChecker check, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
Expr expr = Expr.make(TokenId.MEMBER, Expr expr = Expr.make(TokenId.MEMBER,


ProceedHandler h = new ProceedHandler() { ProceedHandler h = new ProceedHandler() {
@Override @Override
public void doit(JvstCodeGen gen, Bytecode b, ASTList args)
public void doit(JvstCodeGen gen, Bytecode b, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
gen.compileInvokeSpecial(texpr, methodIndex, descriptor, args); gen.compileInvokeSpecial(texpr, methodIndex, descriptor, args);
} }


@Override @Override
public void setReturnType(JvstTypeChecker c, ASTList args)
public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
c.compileInvokeSpecial(texpr, classname, methodname, descriptor, args); c.compileInvokeSpecial(texpr, classname, methodname, descriptor, args);

+ 23
- 23
src/main/javassist/compiler/JvstCodeGen.java Ver fichero

if (arrayDim != 1 || exprType != CLASS) if (arrayDim != 1 || exprType != CLASS)
throw new CompileError("invalid type for " + paramArrayName, expr.getLineNumber()); throw new CompileError("invalid type for " + paramArrayName, expr.getLineNumber());


atAssignParamList(paramTypeList, bytecode);
atAssignParamList(paramTypeList, bytecode, expr.getLineNumber());
if (!doDup) if (!doDup)
bytecode.addOpcode(POP); bytecode.addOpcode(POP);
} }
super.atFieldAssign(expr, op, left, right, doDup); 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 throws CompileError
{ {
if (params == null) if (params == null)
code.addOpcode(DUP); code.addOpcode(DUP);
code.addIconst(i); code.addIconst(i);
code.addOpcode(AALOAD); code.addOpcode(AALOAD);
compileUnwrapValue(params[i], code);
compileUnwrapValue(params[i], code, lineNumber);
code.addStore(varNo, params[i]); code.addStore(varNo, params[i]);
varNo += is2word(exprType, arrayDim) ? 2 : 1; varNo += is2word(exprType, arrayDim) ? 2 : 1;
} }
protected void atCastToRtype(CastExpr expr) throws CompileError { protected void atCastToRtype(CastExpr expr) throws CompileError {
expr.getOprand().accept(this); expr.getOprand().accept(this);
if (exprType == VOID || isRefType(exprType) || arrayDim > 0) if (exprType == VOID || isRefType(exprType) || arrayDim > 0)
compileUnwrapValue(returnType, bytecode);
compileUnwrapValue(returnType, bytecode, expr.getLineNumber());
else if (returnType instanceof CtPrimitiveType) { else if (returnType instanceof CtPrimitiveType) {
CtPrimitiveType pt = (CtPrimitiveType)returnType; CtPrimitiveType pt = (CtPrimitiveType)returnType;
int destType = MemberResolver.descToType(pt.getDescriptor());
int destType = MemberResolver.descToType(pt.getDescriptor(), expr.getLineNumber());
atNumCastExpr(exprType, destType); atNumCastExpr(exprType, destType);
exprType = destType; exprType = destType;
arrayDim = 0; arrayDim = 0;
if (isRefType(exprType) || arrayDim > 0) if (isRefType(exprType) || arrayDim > 0)
return; // Object type. do nothing. 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) { if (clazz instanceof CtPrimitiveType) {
CtPrimitiveType pt = (CtPrimitiveType)clazz; CtPrimitiveType pt = (CtPrimitiveType)clazz;
String wrapper = pt.getWrapperName(); String wrapper = pt.getWrapperName();
if (method instanceof Member) { if (method instanceof Member) {
String name = ((Member)method).get(); String name = ((Member)method).get();
if (procHandler != null && name.equals(proceedName)) { if (procHandler != null && name.equals(proceedName)) {
procHandler.doit(this, bytecode, (ASTList)expr.oprand2());
procHandler.doit(this, bytecode, (ASTList)expr.oprand2(), expr.getLineNumber());
return; return;
} }
else if (name.equals(cflowName)) { else if (name.equals(cflowName)) {
for (int k = 0; k < n; ++k) { for (int k = 0; k < n; ++k) {
CtClass p = params[k]; CtClass p = params[k];
regno += bytecode.addLoad(regno, p); regno += bytecode.addLoad(regno, p);
setType(p);
setType(p, a.getLineNumber());
types[i] = exprType; types[i] = exprType;
dims[i] = arrayDim; dims[i] = arrayDim;
cnames[i] = className; cnames[i] = className;
atMethodArgs(args, new int[nargs], new int[nargs], atMethodArgs(args, new int[nargs], new int[nargs],
new String[nargs]); new String[nargs]);
bytecode.addInvokespecial(methodIndex, descriptor); bytecode.addInvokespecial(methodIndex, descriptor);
setReturnType(descriptor, false, false);
setReturnType(descriptor, false, false, target.getLineNumber());
addNullIfVoid(); addNullIfVoid();
} }


className = jvmJavaLangObject; className = jvmJavaLangObject;
} }
else else
setType(cc);
setType(cc, cc.getLinesCount());


Declarator decl Declarator decl
= new Declarator(exprType, className, arrayDim, = new Declarator(exprType, className, arrayDim,
while ((c = typeDesc.charAt(dim)) == '[') while ((c = typeDesc.charAt(dim)) == '[')
++dim; ++dim;


int type = MemberResolver.descToType(c);
int type = MemberResolver.descToType(c, -1);
String cname = null; String cname = null;
if (type == CLASS) { if (type == CLASS) {
if (dim == 0) if (dim == 0)
return 8; return 8;
} }


protected void compileUnwrapValue(CtClass type, Bytecode code)
protected void compileUnwrapValue(CtClass type, Bytecode code, int lineNumber)
throws CompileError throws CompileError
{ {
if (type == CtClass.voidType) { if (type == CtClass.voidType) {
} }


if (exprType == VOID) if (exprType == VOID)
throw new CompileError("invalid type for " + returnCastName);
throw new CompileError("invalid type for " + returnCastName, lineNumber);


if (type instanceof CtPrimitiveType) { if (type instanceof CtPrimitiveType) {
CtPrimitiveType pt = (CtPrimitiveType)type; CtPrimitiveType pt = (CtPrimitiveType)type;
code.addCheckcast(wrapper); code.addCheckcast(wrapper);
code.addInvokevirtual(wrapper, pt.getGetMethodName(), code.addInvokevirtual(wrapper, pt.getGetMethodName(),
pt.getGetMethodDescriptor()); pt.getGetMethodDescriptor());
setType(type);
setType(type, lineNumber);
} }
else { else {
code.addCheckcast(type); code.addCheckcast(type);
setType(type);
setType(type, lineNumber);
} }
} }


/* Sets exprType, arrayDim, and className; /* Sets exprType, arrayDim, and className;
* If type is void, then this method does nothing. * 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()) { if (type.isPrimitive()) {
CtPrimitiveType pt = (CtPrimitiveType)type; CtPrimitiveType pt = (CtPrimitiveType)type;
exprType = MemberResolver.descToType(pt.getDescriptor());
exprType = MemberResolver.descToType(pt.getDescriptor(), lineNumber);
arrayDim = dim; arrayDim = dim;
className = null; className = null;
} }
else if (type.isArray()) else if (type.isArray())
try { try {
setType(type.getComponentType(), dim + 1);
setType(type.getComponentType(), dim + 1, lineNumber);
} }
catch (NotFoundException e) { catch (NotFoundException e) {
throw new CompileError("undefined type: " + type.getName());
throw new CompileError("undefined type: " + type.getName(), lineNumber);
} }
else { else {
exprType = CLASS; exprType = CLASS;
if (type instanceof CtPrimitiveType) { if (type instanceof CtPrimitiveType) {
CtPrimitiveType pt = (CtPrimitiveType)type; CtPrimitiveType pt = (CtPrimitiveType)type;
atNumCastExpr(exprType, atNumCastExpr(exprType,
MemberResolver.descToType(pt.getDescriptor()));
MemberResolver.descToType(pt.getDescriptor(), type.getLinesCount() - 1));
} }
else else
throw new CompileError("type mismatch");
throw new CompileError("type mismatch", type.getLinesCount() - 1);
} }
} }

+ 12
- 12
src/main/javassist/compiler/JvstTypeChecker.java Ver fichero

compileUnwrapValue(returnType, expr.getLineNumber()); compileUnwrapValue(returnType, expr.getLineNumber());
else if (returnType instanceof CtPrimitiveType) { else if (returnType instanceof CtPrimitiveType) {
CtPrimitiveType pt = (CtPrimitiveType)returnType; CtPrimitiveType pt = (CtPrimitiveType)returnType;
int destType = MemberResolver.descToType(pt.getDescriptor());
int destType = MemberResolver.descToType(pt.getDescriptor(), expr.getLineNumber());
exprType = destType; exprType = destType;
arrayDim = 0; arrayDim = 0;
className = null; className = null;
if (CodeGen.isRefType(exprType) || arrayDim > 0) if (CodeGen.isRefType(exprType) || arrayDim > 0)
return; // Object type. do nothing. 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) { if (clazz instanceof CtPrimitiveType) {
exprType = CLASS; exprType = CLASS;
arrayDim = 0; arrayDim = 0;
if (codeGen.procHandler != null if (codeGen.procHandler != null
&& name.equals(codeGen.proceedName)) { && name.equals(codeGen.proceedName)) {
codeGen.procHandler.setReturnType(this, codeGen.procHandler.setReturnType(this,
(ASTList)expr.oprand2());
(ASTList)expr.oprand2(), expr.getLineNumber());
return; return;
} }
else if (name.equals(JvstCodeGen.cflowName)) { else if (name.equals(JvstCodeGen.cflowName)) {
int n = params.length; int n = params.length;
for (int k = 0; k < n; ++k) { for (int k = 0; k < n; ++k) {
CtClass p = params[k]; CtClass p = params[k];
setType(p);
setType(p, a.getLineNumber());
types[i] = exprType; types[i] = exprType;
dims[i] = arrayDim; dims[i] = arrayDim;
cnames[i] = className; cnames[i] = className;
int nargs = getMethodArgsLength(args); int nargs = getMethodArgsLength(args);
atMethodArgs(args, new int[nargs], new int[nargs], atMethodArgs(args, new int[nargs], new int[nargs],
new String[nargs]); new String[nargs]);
setReturnType(descriptor);
setReturnType(descriptor, target.getLineNumber());
addNullIfVoid(); addNullIfVoid();
} }


if (type == CtClass.voidType) if (type == CtClass.voidType)
addNullIfVoid(); addNullIfVoid();
else else
setType(type);
setType(type, lineNumber);
} }


/* Sets exprType, arrayDim, and className; /* Sets exprType, arrayDim, and className;
* If type is void, then this method does nothing. * 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()) { if (type.isPrimitive()) {
CtPrimitiveType pt = (CtPrimitiveType)type; CtPrimitiveType pt = (CtPrimitiveType)type;
exprType = MemberResolver.descToType(pt.getDescriptor());
exprType = MemberResolver.descToType(pt.getDescriptor(), lineNumber);
arrayDim = dim; arrayDim = dim;
className = null; className = null;
} }
else if (type.isArray()) else if (type.isArray())
try { try {
setType(type.getComponentType(), dim + 1);
setType(type.getComponentType(), dim + 1, lineNumber);
} }
catch (NotFoundException e) { catch (NotFoundException e) {
throw new CompileError("undefined type: " + type.getName());
throw new CompileError("undefined type: " + type.getName(), lineNumber);
} }
else { else {
exprType = CLASS; exprType = CLASS;

+ 25
- 25
src/main/javassist/compiler/MemberCodeGen.java Ver fichero



decl.setLocalVar(var); decl.setLocalVar(var);


CtClass type = resolver.lookupClassByJvmName(decl.getClassName());
CtClass type = resolver.lookupClassByJvmName(decl.getClassName(), st.getLineNumber());
decl.setClassName(MemberResolver.javaToJvmName(type.getName())); decl.setClassName(MemberResolver.javaToJvmName(type.getName()));
bc.addExceptionHandler(start, end, bc.currentPc(), type); bc.addExceptionHandler(start, end, bc.currentPc(), type);
bc.growStack(1); bc.growStack(1);


String elementClass; String elementClass;
if (type == CLASS) { if (type == CLASS) {
elementClass = resolveClassName(jvmClassname);
elementClass = resolveClassName(jvmClassname, lineNumber);
bytecode.addAnewarray(MemberResolver.jvmToJavaName(elementClass)); bytecode.addAnewarray(MemberResolver.jvmToJavaName(elementClass));
} }
else { else {
int op = e.getOperator(); int op = e.getOperator();
if (op == MEMBER) { // static method if (op == MEMBER) { // static method
targetClass targetClass
= resolver.lookupClass(((Symbol)e.oprand1()).get(), false);
= resolver.lookupClass(((Symbol)e.oprand1()).get(), false, expr.getLineNumber());
isStatic = true; isStatic = true;
} }
else if (op == '.') { else if (op == '.') {
} }


if (arrayDim > 0) if (arrayDim > 0)
targetClass = resolver.lookupClass(javaLangObject, true);
targetClass = resolver.lookupClass(javaLangObject, true, expr.getLineNumber());
else if (exprType == CLASS /* && arrayDim == 0 */) else if (exprType == CLASS /* && arrayDim == 0 */)
targetClass = resolver.lookupClassByJvmName(className);
targetClass = resolver.lookupClassByJvmName(className, expr.getLineNumber());
else else
badMethod();
badMethod(e.getLineNumber());
} }
} }
else else
badMethod();
badMethod(expr.getLineNumber());
} }
else else
fatal(expr.getLineNumber()); fatal(expr.getLineNumber());
aload0pos, cached); 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);
} }


/* /*
if (mname.equals(MethodInfo.nameInit)) { if (mname.equals(MethodInfo.nameInit)) {
isSpecial = true; isSpecial = true;
if (declClass != targetClass) 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 != thisClass && AccessFlag.isPrivate(acc)) {
if (declClass.getClassFile().getMajorVersion() < ClassFile.JAVA_8 if (declClass.getClassFile().getMajorVersion() < ClassFile.JAVA_8
} }
else else
if (isStatic) if (isStatic)
throw new CompileError(mname + " is not static");
throw new CompileError(mname + " is not static", targetClass.getLinesCount() - 1);
else else
bytecode.addInvokevirtual(declClass, mname, desc); bytecode.addInvokevirtual(declClass, mname, desc);
} }


setReturnType(desc, isStatic, popTarget);
setReturnType(desc, isStatic, popTarget, targetClass.getLinesCount() - 1);
} }


/* /*
} }


throw new CompileError("Method " + methodName throw new CompileError("Method " + methodName
+ " is private");
+ " is private", declClass.getLinesCount() - 1);
} }


/* /*
} }


throw new CompileError("the called constructor is private in " throw new CompileError("the called constructor is private in "
+ declClass.getName());
+ declClass.getName(), declClass.getLinesCount() - 1);
} }


private boolean isEnclosing(CtClass outer, CtClass inner) { private boolean isEnclosing(CtClass outer, CtClass inner) {
} }
} }


void setReturnType(String desc, boolean isStatic, boolean popTarget)
void setReturnType(String desc, boolean isStatic, boolean popTarget, int lineNumber)
throws CompileError throws CompileError
{ {
int i = desc.indexOf(')'); int i = desc.indexOf(')');
if (i < 0) if (i < 0)
badMethod();
badMethod(lineNumber);


char c = desc.charAt(++i); char c = desc.charAt(++i);
int dim = 0; int dim = 0;
if (c == 'L') { if (c == 'L') {
int j = desc.indexOf(';', i + 1); int j = desc.indexOf(';', i + 1);
if (j < 0) if (j < 0)
badMethod();
badMethod(lineNumber);


exprType = CLASS; exprType = CLASS;
className = desc.substring(i + 1, j); className = desc.substring(i + 1, j);
} }
else { else {
exprType = MemberResolver.descToType(c);
exprType = MemberResolver.descToType(c, lineNumber);
className = null; className = null;
} }


int fi; int fi;
if (op == '=') { if (op == '=') {
FieldInfo finfo = f.getFieldInfo2(); FieldInfo finfo = f.getFieldInfo2();
setFieldType(finfo);
setFieldType(finfo, expr.getLineNumber());
AccessorMaker maker = isAccessibleField(f, finfo, expr.getLineNumber()); AccessorMaker maker = isAccessibleField(f, finfo, expr.getLineNumber());
if (maker == null) if (maker == null)
fi = addFieldrefInfo(f, finfo); fi = addFieldrefInfo(f, finfo);
atFieldRead(f, is_static,expr.getLineNumber() ); atFieldRead(f, is_static,expr.getLineNumber() );
else { else {
cexpr.accept(this); cexpr.accept(this);
setFieldType(f.getFieldInfo2());
setFieldType(f.getFieldInfo2(), expr.getLineNumber());
} }
} }


*/ */
private int atFieldRead(CtField f, boolean isStatic, int lineNumber) throws CompileError { private int atFieldRead(CtField f, boolean isStatic, int lineNumber) throws CompileError {
FieldInfo finfo = f.getFieldInfo2(); FieldInfo finfo = f.getFieldInfo2();
boolean is2byte = setFieldType(finfo);
boolean is2byte = setFieldType(finfo, lineNumber);
AccessorMaker maker = isAccessibleField(f, finfo, lineNumber); AccessorMaker maker = isAccessibleField(f, finfo, lineNumber);
if (maker != null) { if (maker != null) {
MethodInfo minfo = maker.getFieldGetter(finfo, isStatic); MethodInfo minfo = maker.getFieldGetter(finfo, isStatic);
* *
* @return true if the field type is long or double. * @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(); String type = finfo.getDescriptor();


int i = 0; int i = 0;
} }


arrayDim = dim; arrayDim = dim;
exprType = MemberResolver.descToType(c);
exprType = MemberResolver.descToType(c, lineNumber);


if (c == 'L') if (c == 'L')
className = type.substring(i + 1, type.indexOf(';', i + 1)); className = type.substring(i + 1, type.indexOf(';', i + 1));
* For example, this converts Object into java/lang/Object. * For example, this converts Object into java/lang/Object.
*/ */
@Override @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);
} }
} }

+ 37
- 35
src/main/javassist/compiler/MemberResolver.java Ver fichero



public ClassPool getClassPool() { return classPool; } 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 { public static class Method {
if (current != null && clazz == currentClass) if (current != null && clazz == currentClass)
if (current.getName().equals(methodName)) { if (current.getName().equals(methodName)) {
int res = compareSignature(current.getDescriptor(), int res = compareSignature(current.getDescriptor(),
argTypes, argDims, argClassNames);
argTypes, argDims, argClassNames, currentClass.getLinesCount() - 1);
if (res != NO) { if (res != NO) {
Method r = new Method(clazz, current, res); Method r = new Method(clazz, current, res);
if (res == YES) if (res == YES)
if (minfo.getName().equals(methodName) if (minfo.getName().equals(methodName)
&& (minfo.getAccessFlags() & AccessFlag.BRIDGE) == 0) { && (minfo.getAccessFlags() & AccessFlag.BRIDGE) == 0) {
int res = compareSignature(minfo.getDescriptor(), int res = compareSignature(minfo.getDescriptor(),
argTypes, argDims, argClassNames);
argTypes, argDims, argClassNames, clazz.getLinesCount() - 1);
if (res != NO) { if (res != NO) {
Method r = new Method(clazz, minfo, res); Method r = new Method(clazz, minfo, res);
if (res == YES) if (res == YES)
* of parameter types that do not exactly match. * of parameter types that do not exactly match.
*/ */
private int compareSignature(String desc, int[] argTypes, private int compareSignature(String desc, int[] argTypes,
int[] argDims, String[] argClassNames)
int[] argDims, String[] argClassNames, int lineNumber)
throws CompileError throws CompileError
{ {
int result = YES; int result = YES;


String cname = desc.substring(i, j); String cname = desc.substring(i, j);
if (!cname.equals(argClassNames[n])) { if (!cname.equals(argClassNames[n])) {
CtClass clazz = lookupClassByJvmName(argClassNames[n]);
CtClass clazz = lookupClassByJvmName(argClassNames[n], lineNumber);
try { try {
if (clazz.subtypeOf(lookupClassByJvmName(cname)))
if (clazz.subtypeOf(lookupClassByJvmName(cname, lineNumber)))
result++; result++;
else else
return NO; return NO;
i = j + 1; i = j + 1;
} }
else { else {
int t = descToType(c);
int t = descToType(c, lineNumber);
int at = argTypes[n]; int at = argTypes[n];
if (t != at) if (t != at)
if (t == INT if (t == INT
* Only used by fieldAccess() in MemberCodeGen and TypeChecker. * Only used by fieldAccess() in MemberCodeGen and TypeChecker.
* *
* @param jvmClassName a JVM class name. e.g. java/lang/String * @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, public CtField lookupFieldByJvmName2(String jvmClassName, Symbol fieldSym,
ASTree expr) throws NoFieldException ASTree expr) throws NoFieldException
String field = fieldSym.get(); String field = fieldSym.get();
CtClass cc = null; CtClass cc = null;
try { try {
cc = lookupClass(jvmToJavaName(jvmClassName), true);
cc = lookupClass(jvmToJavaName(jvmClassName), true, expr.getLineNumber());
} }
catch (CompileError e) { catch (CompileError e) {
// EXPR might be part of a qualified class name. // EXPR might be part of a qualified class name.
public CtField lookupField(String className, Symbol fieldName) public CtField lookupField(String className, Symbol fieldName)
throws CompileError throws CompileError
{ {
CtClass cc = lookupClass(className, false);
CtClass cc = lookupClass(className, false, fieldName.getLineNumber());
try { try {
return cc.getField(fieldName.get()); return cc.getField(fieldName.get());
} }
catch (NotFoundException e) {} 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 { 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 { public CtClass lookupClass(Declarator decl) throws CompileError {
return lookupClass(decl.getType(), decl.getArrayDim(), 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 throws CompileError
{ {
String cname = ""; String cname = "";
CtClass clazz; CtClass clazz;
if (type == CLASS) { if (type == CLASS) {
clazz = lookupClassByJvmName(classname);
clazz = lookupClassByJvmName(classname, lineNumber);
if (dim > 0) if (dim > 0)
cname = clazz.getName(); cname = clazz.getName();
else else
return clazz; return clazz;
} }
else else
cname = getTypeName(type);
cname = getTypeName(type, lineNumber);


while (dim-- > 0) while (dim-- > 0)
cname += "[]"; cname += "[]";


return lookupClass(cname, false);
return lookupClass(cname, false, lineNumber);
} }


/* /*
* type cannot be CLASS * type cannot be CLASS
*/ */
static String getTypeName(int type) throws CompileError {
static String getTypeName(int type, int lineNumber) throws CompileError {
String cname = ""; String cname = "";
switch (type) { switch (type) {
case BOOLEAN : case BOOLEAN :
cname = "void"; cname = "void";
break; break;
default : default :
fatal();
fatal(lineNumber);
} }


return cname; 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 throws CompileError
{ {
Map<String,String> cache = getInvalidNames(); Map<String,String> cache = getInvalidNames();
String found = cache.get(name); String found = cache.get(name);
if (found == INVALID) if (found == INVALID)
throw new CompileError("no such class: " + name);
throw new CompileError("no such class: " + name, lineNumber);
else if (found != null) else if (found != null)
try { try {
return classPool.get(found); return classPool.get(found);
cc = lookupClass0(name, notCheckInner); cc = lookupClass0(name, notCheckInner);
} }
catch (NotFoundException e) { catch (NotFoundException e) {
cc = searchImports(name);
cc = searchImports(name, lineNumber);
} }


cache.put(name, cc.getName()); cache.put(name, cc.getName());
return ht; return ht;
} }


private CtClass searchImports(String orgName)
private CtClass searchImports(String orgName, int lineNumber)
throws CompileError throws CompileError
{ {
if (orgName.indexOf('.') < 0) { if (orgName.indexOf('.') < 0) {
} }


getInvalidNames().put(orgName, INVALID); 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) private CtClass lookupClass0(String classname, boolean notCheckInner)
/* Expands a simple class name to java.lang.*. /* Expands a simple class name to java.lang.*.
* For example, this converts Object into java/lang/Object. * 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) if (jvmName == null)
return null; return null;
return javaToJvmName(lookupClassByJvmName(jvmName).getName());
return javaToJvmName(lookupClassByJvmName(jvmName, lineNumber).getName());
} }


public static CtClass getSuperclass(CtClass c) throws CompileError { public static CtClass getSuperclass(CtClass c) throws CompileError {
} }
catch (NotFoundException e) {} catch (NotFoundException e) {}
throw new CompileError("cannot find the super class of " throw new CompileError("cannot find the super class of "
+ c.getName());
+ c.getName(), c.getLinesCount() - 1);
} }


public static CtClass getSuperInterface(CtClass c, String interfaceName) public static CtClass getSuperInterface(CtClass c, String interfaceName)
return intfs[i]; return intfs[i];
} catch (NotFoundException e) {} } catch (NotFoundException e) {}
throw new CompileError("cannot find the super interface " + interfaceName throw new CompileError("cannot find the super interface " + interfaceName
+ " of " + c.getName());
+ " of " + c.getName(), c.getLinesCount() - 1);
} }


public static String javaToJvmName(String classname) { public static String javaToJvmName(String classname) {
return classname.replace('/', '.'); return classname.replace('/', '.');
} }


public static int descToType(char c) throws CompileError {
public static int descToType(char c, int lineNumber) throws CompileError {
switch (c) { switch (c) {
case 'Z' : case 'Z' :
return BOOLEAN; return BOOLEAN;
case '[' : case '[' :
return CLASS; return CLASS;
default : default :
fatal();
fatal(lineNumber);
return VOID; // never reach here return VOID; // never reach here
} }
} }

+ 2
- 2
src/main/javassist/compiler/ProceedHandler.java Ver fichero

* @see javassist.compiler.JvstCodeGen#setProceedHandler(ProceedHandler, String) * @see javassist.compiler.JvstCodeGen#setProceedHandler(ProceedHandler, String)
*/ */
public interface ProceedHandler { 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;
} }

+ 28
- 28
src/main/javassist/compiler/TypeChecker.java Ver fichero

* into a String object. * into a String object.
*/ */
protected static String argTypesToString(int[] types, int[] dims, protected static String argTypesToString(int[] types, int[] dims,
String[] cnames) {
String[] cnames, int lineNumber) {
StringBuilder sbuf = new StringBuilder(); StringBuilder sbuf = new StringBuilder();
sbuf.append('('); sbuf.append('(');
int n = types.length; int n = types.length;
if (n > 0) { if (n > 0) {
int i = 0; int i = 0;
while (true) { while (true) {
typeToString(sbuf, types[i], dims[i], cnames[i]);
typeToString(sbuf, types[i], dims[i], cnames[i], lineNumber);
if (++i < n) if (++i < n)
sbuf.append(','); sbuf.append(',');
else else
* into a String object. * into a String object.
*/ */
protected static StringBuilder typeToString(StringBuilder sbuf, protected static StringBuilder typeToString(StringBuilder sbuf,
int type, int dim, String cname) {
int type, int dim, String cname, int lineNumber) {
String s; String s;
if (type == CLASS) if (type == CLASS)
s = MemberResolver.jvmToJavaName(cname); s = MemberResolver.jvmToJavaName(cname);
s = "Object"; s = "Object";
else else
try { try {
s = MemberResolver.getTypeName(type);
s = MemberResolver.getTypeName(type, lineNumber);
} }
catch (CompileError e) { catch (CompileError e) {
s = "?"; s = "?";
/* Expands a simple class name to java.lang.*. /* Expands a simple class name to java.lang.*.
* For example, this converts Object into java/lang/Object. * 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 @Override
CtClass clazz = resolver.lookupClassByName(expr.getClassName()); CtClass clazz = resolver.lookupClassByName(expr.getClassName());
String cname = clazz.getName(); String cname = clazz.getName();
ASTList args = expr.getArguments(); ASTList args = expr.getArguments();
atMethodCallCore(clazz, MethodInfo.nameInit, args);
atMethodCallCore(clazz, MethodInfo.nameInit, args, expr.getLineNumber());
exprType = CLASS; exprType = CLASS;
arrayDim = 0; arrayDim = 0;
className = MemberResolver.javaToJvmName(cname); className = MemberResolver.javaToJvmName(cname);
throws CompileError throws CompileError
{ {
CtField f = fieldAccess(left); CtField f = fieldAccess(left);
atFieldRead(f);
atFieldRead(f, expr.getLineNumber());
int fType = exprType; int fType = exprType;
int fDim = arrayDim; int fDim = arrayDim;
String cname = className; String cname = className;
if (op == MEMBER) // static method if (op == MEMBER) // static method
targetClass targetClass
= resolver.lookupClass(((Symbol)e.oprand1()).get(), = resolver.lookupClass(((Symbol)e.oprand1()).get(),
false);
false, e.getLineNumber());
else if (op == '.') { else if (op == '.') {
ASTree target = e.oprand1(); ASTree target = e.oprand1();
String classFollowedByDotSuper = isDotSuper(target); String classFollowedByDotSuper = isDotSuper(target);
} }


if (arrayDim > 0) if (arrayDim > 0)
targetClass = resolver.lookupClass(javaLangObject, true);
targetClass = resolver.lookupClass(javaLangObject, true, e.getLineNumber());
else if (exprType == CLASS /* && arrayDim == 0 */) else if (exprType == CLASS /* && arrayDim == 0 */)
targetClass = resolver.lookupClassByJvmName(className);
targetClass = resolver.lookupClassByJvmName(className, e.getLineNumber());
else else
badMethod();
badMethod(e.getLineNumber());
} }
} }
else else
badMethod();
badMethod(expr.getLineNumber());
} }
else else
fatal(expr.getLineNumber()); fatal(expr.getLineNumber());


MemberResolver.Method minfo MemberResolver.Method minfo
= atMethodCallCore(targetClass, mname, args);
= atMethodCallCore(targetClass, mname, args, expr.getLineNumber());
expr.setMethod(minfo); 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);
} }


/** /**
* and the MethodInfo of that method. Never null. * and the MethodInfo of that method. Never null.
*/ */
public MemberResolver.Method atMethodCallCore(CtClass targetClass, public MemberResolver.Method atMethodCallCore(CtClass targetClass,
String mname, ASTList args)
String mname, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
int nargs = getMethodArgsLength(args); int nargs = getMethodArgsLength(args);
mname, types, dims, cnames); mname, types, dims, cnames);
if (found == null) { if (found == null) {
String clazz = targetClass.getName(); String clazz = targetClass.getName();
String signature = argTypesToString(types, dims, cnames);
String signature = argTypesToString(types, dims, cnames, lineNumber);
String msg; String msg;
if (mname.equals(MethodInfo.nameInit)) if (mname.equals(MethodInfo.nameInit))
msg = "cannot find constructor " + clazz + signature; msg = "cannot find constructor " + clazz + signature;
else else
msg = mname + signature + " not found in " + clazz; msg = mname + signature + " not found in " + clazz;


throw new CompileError(msg);
throw new CompileError(msg, lineNumber);
} }


String desc = found.info.getDescriptor(); String desc = found.info.getDescriptor();
setReturnType(desc);
setReturnType(desc, lineNumber);
return found; return found;
} }


} }
} }


void setReturnType(String desc) throws CompileError {
void setReturnType(String desc, int lineNumber) throws CompileError {
int i = desc.indexOf(')'); int i = desc.indexOf(')');
if (i < 0) if (i < 0)
badMethod();
badMethod(lineNumber);


char c = desc.charAt(++i); char c = desc.charAt(++i);
int dim = 0; int dim = 0;
if (c == 'L') { if (c == 'L') {
int j = desc.indexOf(';', i + 1); int j = desc.indexOf(';', i + 1);
if (j < 0) if (j < 0)
badMethod();
badMethod(lineNumber);


exprType = CLASS; exprType = CLASS;
className = desc.substring(i + 1, j); className = desc.substring(i + 1, j);
} }
else { else {
exprType = MemberResolver.descToType(c);
exprType = MemberResolver.descToType(c, lineNumber);
className = null; className = null;
} }
} }


private void atFieldRead(ASTree expr) throws CompileError { 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(); FieldInfo finfo = f.getFieldInfo2();
String type = finfo.getDescriptor(); String type = finfo.getDescriptor();


} }


arrayDim = dim; arrayDim = dim;
exprType = MemberResolver.descToType(c);
exprType = MemberResolver.descToType(c, lineNumber);


if (c == 'L') if (c == 'L')
className = type.substring(i + 1, type.indexOf(';', i + 1)); className = type.substring(i + 1, type.indexOf(';', i + 1));
protected void atFieldPlusPlus(ASTree oprand) throws CompileError protected void atFieldPlusPlus(ASTree oprand) throws CompileError
{ {
CtField f = fieldAccess(oprand); CtField f = fieldAccess(oprand);
atFieldRead(f);
atFieldRead(f, oprand.getLineNumber());
int t = exprType; int t = exprType;
if (t == INT || t == BYTE || t == CHAR || t == SHORT) if (t == INT || t == BYTE || t == CHAR || t == SHORT)
exprType = INT; exprType = INT;

+ 5
- 5
src/main/javassist/expr/Cast.java Ver fichero

} }


@Override @Override
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
if (gen.getMethodArgsLength(args) != 1) if (gen.getMethodArgsLength(args) != 1)
throw new CompileError(Javac.proceedName throw new CompileError(Javac.proceedName
+ "() cannot take more than one parameter " + "() cannot take more than one parameter "
+ "for cast");
+ "for cast", lineNumber);


gen.atMethodArgs(args, new int[1], new int[1], new String[1]); gen.atMethodArgs(args, new int[1], new int[1], new String[1]);
bytecode.addOpcode(Opcode.CHECKCAST); bytecode.addOpcode(Opcode.CHECKCAST);
bytecode.addIndex(index); bytecode.addIndex(index);
gen.setType(retType);
gen.setType(retType, lineNumber);
} }


@Override @Override
public void setReturnType(JvstTypeChecker c, ASTList args)
public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
c.atMethodArgs(args, new int[1], new int[1], new String[1]); c.atMethodArgs(args, new int[1], new int[1], new String[1]);
c.setType(retType);
c.setType(retType, lineNumber);
} }
} }
} }

+ 10
- 10
src/main/javassist/expr/FieldAccess.java Ver fichero

} }


@Override @Override
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
if (args != null && !gen.isParamListName(args)) if (args != null && !gen.isParamListName(args))
throw new CompileError(Javac.proceedName throw new CompileError(Javac.proceedName
+ "() cannot take a parameter for field reading");
+ "() cannot take a parameter for field reading", lineNumber);


int stack; int stack;
if (isStatic(opcode)) if (isStatic(opcode))
bytecode.add(opcode); bytecode.add(opcode);
bytecode.addIndex(index); bytecode.addIndex(index);
bytecode.growStack(stack); bytecode.growStack(stack);
gen.setType(fieldType);
gen.setType(fieldType, lineNumber);
} }


@Override @Override
public void setReturnType(JvstTypeChecker c, ASTList args)
public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
c.setType(fieldType);
c.setType(fieldType, lineNumber);
} }
} }


} }


@Override @Override
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
if (gen.getMethodArgsLength(args) != 1) if (gen.getMethodArgsLength(args) != 1)
throw new CompileError(Javac.proceedName throw new CompileError(Javac.proceedName
+ "() cannot take more than one parameter " + "() cannot take more than one parameter "
+ "for field writing");
+ "for field writing", lineNumber);


int stack; int stack;
if (isStatic(opcode)) if (isStatic(opcode))
bytecode.add(opcode); bytecode.add(opcode);
bytecode.addIndex(index); bytecode.addIndex(index);
bytecode.growStack(stack); bytecode.growStack(stack);
gen.setType(CtClass.voidType);
gen.setType(CtClass.voidType, lineNumber);
gen.addNullIfVoid(); gen.addNullIfVoid();
} }


@Override @Override
public void setReturnType(JvstTypeChecker c, ASTList args)
public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
c.atMethodArgs(args, new int[1], new int[1], new String[1]); c.atMethodArgs(args, new int[1], new int[1], new String[1]);
c.setType(CtClass.voidType);
c.setType(CtClass.voidType, lineNumber);
c.addNullIfVoid(); c.addNullIfVoid();
} }
} }

+ 5
- 5
src/main/javassist/expr/Instanceof.java Ver fichero

} }


@Override @Override
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
if (gen.getMethodArgsLength(args) != 1) if (gen.getMethodArgsLength(args) != 1)
throw new CompileError(Javac.proceedName throw new CompileError(Javac.proceedName
+ "() cannot take more than one parameter " + "() cannot take more than one parameter "
+ "for instanceof");
+ "for instanceof", lineNumber);


gen.atMethodArgs(args, new int[1], new int[1], new String[1]); gen.atMethodArgs(args, new int[1], new int[1], new String[1]);
bytecode.addOpcode(Opcode.INSTANCEOF); bytecode.addOpcode(Opcode.INSTANCEOF);
bytecode.addIndex(index); bytecode.addIndex(index);
gen.setType(CtClass.booleanType);
gen.setType(CtClass.booleanType, lineNumber);
} }


@Override @Override
public void setReturnType(JvstTypeChecker c, ASTList args)
public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
c.atMethodArgs(args, new int[1], new int[1], new String[1]); c.atMethodArgs(args, new int[1], new int[1], new String[1]);
c.setType(CtClass.booleanType);
c.setType(CtClass.booleanType, lineNumber);
} }
} }
} }

+ 5
- 5
src/main/javassist/expr/NewArray.java Ver fichero

} }


@Override @Override
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
int num = gen.getMethodArgsLength(args); int num = gen.getMethodArgsLength(args);
if (num != dimension) if (num != dimension)
throw new CompileError(Javac.proceedName throw new CompileError(Javac.proceedName
+ "() with a wrong number of parameters");
+ "() with a wrong number of parameters", lineNumber);


gen.atMethodArgs(args, new int[num], gen.atMethodArgs(args, new int[num],
new int[num], new String[num]); new int[num], new String[num]);
bytecode.growStack(1 - dimension); bytecode.growStack(1 - dimension);
} }


gen.setType(arrayType);
gen.setType(arrayType, lineNumber);
} }


@Override @Override
public void setReturnType(JvstTypeChecker c, ASTList args)
public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
c.setType(arrayType);
c.setType(arrayType, lineNumber);
} }
} }
} }

+ 5
- 5
src/main/javassist/expr/NewExpr.java Ver fichero

} }


@Override @Override
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
bytecode.addOpcode(NEW); bytecode.addOpcode(NEW);
bytecode.addOpcode(DUP); bytecode.addOpcode(DUP);
gen.atMethodCallCore(newType, MethodInfo.nameInit, args, gen.atMethodCallCore(newType, MethodInfo.nameInit, args,
false, true, -1, null); false, true, -1, null);
gen.setType(newType);
gen.setType(newType, lineNumber);
} }


@Override @Override
public void setReturnType(JvstTypeChecker c, ASTList args)
public void setReturnType(JvstTypeChecker c, ASTList args, int lineNumber)
throws CompileError throws CompileError
{ {
c.atMethodCallCore(newType, MethodInfo.nameInit, args);
c.setType(newType);
c.atMethodCallCore(newType, MethodInfo.nameInit, args, lineNumber);
c.setType(newType, lineNumber);
} }
} }
} }

+ 14
- 0
src/test/javassist/LineNumberTest.java Ver fichero

"}"), "line 3: syntax error near \" return\n}\""); "}"), "line 3: syntax error near \" return\n}\"");
} }


public void testUndevField() {
doTestCompile(String.join("\n",
"public void run() {",
" foo = 5;",
"}"), "line 2: no such field: foo");
}

public void testUndevMethod() {
doTestCompile(String.join("\n",
"public void run() {",
" foo();",
"}"), "line 2: foo() not found in javassist.LineNumberCompileTest2");
}

public void testException() { public void testException() {
doTestRuntime(String.join("\n", doTestRuntime(String.join("\n",
"public void run() {", "public void run() {",

+ 2
- 2
src/test/javassist/compiler/CompTest.java Ver fichero



public void testArgTypesToString() { public void testArgTypesToString() {
String s; String s;
s = TypeChecker.argTypesToString(new int[0], new int[0], new String[0]);
s = TypeChecker.argTypesToString(new int[0], new int[0], new String[0], 0);
assertEquals("()", s); assertEquals("()", s);
s = TypeChecker.argTypesToString(new int[] { TokenId.INT, TokenId.CHAR, TokenId.CLASS }, s = TypeChecker.argTypesToString(new int[] { TokenId.INT, TokenId.CHAR, TokenId.CLASS },
new int[] { 0, 1, 0 }, new int[] { 0, 1, 0 },
new String[] { null, null, "String" });
new String[] { null, null, "String" }, 0);
assertEquals("(int,char[],String)", s); assertEquals("(int,char[],String)", s);
} }



Cargando…
Cancelar
Guardar