diff options
Diffstat (limited to 'src/main/java/io/devnulllabs/openjava/ptree/util/MemberAccessCorrector.java')
-rw-r--r-- | src/main/java/io/devnulllabs/openjava/ptree/util/MemberAccessCorrector.java | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/src/main/java/io/devnulllabs/openjava/ptree/util/MemberAccessCorrector.java b/src/main/java/io/devnulllabs/openjava/ptree/util/MemberAccessCorrector.java new file mode 100644 index 0000000..8c1a2d8 --- /dev/null +++ b/src/main/java/io/devnulllabs/openjava/ptree/util/MemberAccessCorrector.java @@ -0,0 +1,222 @@ +/* + * MemberAccessCorrector.java + * + * Firstly, the parser generates a temporal parse tree. + * This class correct them. + * <p> + * + * All the continuous field access are stored in a single Variable ptree + * object. + * [p.p.f.f].f [p.f].m() ([] a single Variable object) + * FieldAccess := Variable name + * MemberAccess := Variable name "(" .. ")" + * + * @author Michiaki Tatsubori + * @version %VERSION% %DATE% + * @see java.lang.Object + * + * COPYRIGHT 1998 by Michiaki Tatsubori, ALL RIGHTS RESERVED. + */ +package io.devnulllabs.openjava.ptree.util; + +import io.devnulllabs.openjava.mop.Environment; +import io.devnulllabs.openjava.mop.NoSuchMemberException; +import io.devnulllabs.openjava.mop.OJClass; +import io.devnulllabs.openjava.mop.OJClassNotFoundException; +import io.devnulllabs.openjava.mop.OJField; +import io.devnulllabs.openjava.ptree.Expression; +import io.devnulllabs.openjava.ptree.FieldAccess; +import io.devnulllabs.openjava.ptree.MethodCall; +import io.devnulllabs.openjava.ptree.ParseTreeException; +import io.devnulllabs.openjava.ptree.TypeName; +import io.devnulllabs.openjava.ptree.Variable; +import io.devnulllabs.openjava.tools.DebugOut; + +/** + * The class <code>MemberAccessCorrector</code> + * <p> + * For example + * <pre> + * </pre> + * <p> + * + * @author Michiaki Tatsubori + * @version 1.0 + * @since $Id: MemberAccessCorrector.java,v 1.2 2003/02/19 02:55:00 tatsubori Exp $ + * @see java.lang.Object + */ +public class MemberAccessCorrector extends VariableBinder { + + private String errorState = null; + + public MemberAccessCorrector(Environment env) { + super(env); + } + + public String getErrorState() { + return errorState; + } + + public Expression evaluateDown(FieldAccess ptree) + throws ParseTreeException { + super.evaluateDown(ptree); + + if (ptree.getReferenceType() != null) + return ptree; + + Expression ref = ptree.getReferenceExpr(); + String field_name = ptree.getName(); + + if (ref == null) { + if (isVariable(field_name)) { + /* this is a variable. */ + DebugOut.println("MC variable - " + field_name); + return new Variable(field_name); + } else if (isField(field_name)) { + /* this is a field access */ + DebugOut.println("MC field access - " + field_name); + } else { + /* unknown variable or field */ + System.err.println("unknown field or variable : " + field_name); + System.err.println(getEnvironment()); + } + } else if (ref instanceof Variable) { + FieldAccess fa = name2fieldaccess(ref.toString(), field_name); + TypeName typename = fa.getReferenceType(); + Expression refexpr = fa.getReferenceExpr(); + if (typename != null) { + ptree.setReferenceType(typename); + } else { + ptree.setReferenceExpr(refexpr); + } + } + + return ptree; + } + + public Expression evaluateDown(MethodCall ptree) + throws ParseTreeException { + super.evaluateDown(ptree); + + if (ptree.getReferenceType() != null) + return ptree; + + Expression ref = ptree.getReferenceExpr(); + if (ref == null || !(ref instanceof Variable)) + return ptree; + String method_name = ptree.getName(); + + if (ref instanceof Variable) { + FieldAccess fa = name2fieldaccess(ref.toString(), method_name); + TypeName typename = fa.getReferenceType(); + Expression refexpr = fa.getReferenceExpr(); + if (typename != null) { + ptree.setReferenceType(typename); + } else { + ptree.setReferenceExpr(refexpr); + } + } + return ptree; + } + + private FieldAccess name2fieldaccess(String names, String field) { + Expression result_expr; + String first = getFirst(names); + String rest = getRest(names); + + if (isVariable(first)) { + /* this is a variable */ + DebugOut.println("MC variable - " + first); + result_expr = new Variable(first); + } else if (isField(first)) { + /* this is a field */ + DebugOut.println("MC field - " + first); + result_expr = new FieldAccess((Variable) null, first); + } else { + /* this is a class */ + while (rest != null && !isClass(first)) { + first = first + "." + getFirst(rest); + rest = getRest(rest); + } + while (isClass(first + "." + getFirst(rest))) { + first = first + "." + getFirst(rest); + rest = getRest(rest); + } + if (isClass(first)) { + DebugOut.println("MC class - " + first); + } else { + System.err.println("unknown class : " + first); + } + + TypeName type = new TypeName(first); + if (rest == null) { + /* ref is a typename */ + return new FieldAccess(type, field); + } + first = getFirst(rest); + rest = getRest(rest); + result_expr = new FieldAccess(type, first); + } + + /* remainder is field access */ + while (rest != null) { + first = getFirst(rest); + rest = getRest(rest); + result_expr = new FieldAccess(result_expr, first); + } + + return new FieldAccess(result_expr, field); + } + + private boolean isVariable(String name) { + Environment env = getEnvironment(); + OJClass bindedtype = env.lookupBind(name); + return (bindedtype != null); + } + + private boolean isField(String name) { + Environment env = getEnvironment(); + String qcname = env.toQualifiedName(env.currentClassName()); + OJClass declarer = env.lookupClass(qcname); + OJField field = null; + while (declarer != null && field == null) { + try { + field = declarer.getField(name, declarer); + } catch (NoSuchMemberException e) { + } + declarer = declarer.getDeclaringClass(); + } + return (field != null); + } + + private boolean isClass(String name) { + Environment env = getEnvironment(); + String qname = env.toQualifiedName(name); + try { + OJClass.forName(qname); + return true; + } catch (OJClassNotFoundException e) { + } + OJClass clazz = env.lookupClass(qname); + return (clazz != null); + } + + private static final String getFirst(String qname) { + if (qname == null) + return null; + int dot = qname.indexOf('.'); + if (dot == -1) + return qname; + return qname.substring(0, dot); + } + + private static final String getRest(String qname) { + if (qname == null) + return null; + int dot = qname.indexOf('.'); + if (dot == -1) + return null; + return qname.substring(dot + 1); + } + +} |