summaryrefslogtreecommitdiff
path: root/src/main/java/io/devnulllabs/openjava/ptree/util/MemberAccessCorrector.java
diff options
context:
space:
mode:
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.java222
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);
+ }
+
+}