PageRenderTime 25ms CodeModel.GetById 12ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/ooc/backend/cdirty/MemberAccessWriter.java

http://github.com/nddrylliog/ooc
Java | 103 lines | 82 code | 19 blank | 2 comment | 16 complexity | d7e7a6faa5fbda19e3f854c639e5c2be MD5 | raw file
  1package org.ooc.backend.cdirty;
  2
  3import java.io.IOException;
  4
  5import org.ooc.frontend.model.ClassDecl;
  6import org.ooc.frontend.model.Dereference;
  7import org.ooc.frontend.model.Expression;
  8import org.ooc.frontend.model.FunctionDecl;
  9import org.ooc.frontend.model.MemberAccess;
 10import org.ooc.frontend.model.PotentiallyStatic;
 11import org.ooc.frontend.model.Type;
 12import org.ooc.frontend.model.TypeDecl;
 13import org.ooc.frontend.model.VariableAccess;
 14
 15public class MemberAccessWriter {
 16
 17	public static void write(MemberAccess memberAccess, boolean doTypeParams, CGenerator cgen, int refOffset) throws IOException {
 18		
 19		// Allows to do things like "if(T == Int)"
 20		if(memberAccess.getExpression() instanceof VariableAccess) {
 21			VariableAccess varAcc = (VariableAccess) memberAccess.getExpression();
 22			if(varAcc.getRef() instanceof TypeDecl) {
 23				if(memberAccess.getName().equals("class")) {
 24					cgen.current.app(varAcc.getUnderName()).app("_class()");
 25					return;
 26				}
 27			}
 28		}
 29		
 30		// duplicated code with LocalAccessWriter: modularize!
 31		int refLevel = memberAccess.getRef().getType().getReferenceLevel();
 32		refLevel += refOffset;
 33		
 34		TypeDecl refTypeDecl = memberAccess.getRef().getTypeDecl();
 35		boolean isStatic = ((PotentiallyStatic) memberAccess.getRef()).isStatic();
 36		
 37		if(memberAccess.getRef() instanceof FunctionDecl) {
 38			writeFuncAccess(memberAccess, cgen);
 39			return;
 40		}
 41		
 42		if(refLevel > 0) {
 43			cgen.current.app('(');
 44			for(int i = 0; i < refLevel; i++) {
 45				cgen.current.app('*');
 46			}
 47		}
 48		
 49		if(isStatic) {
 50			if(memberAccess.getRef().isExternWithName()) {
 51				cgen.current.app(memberAccess.getRef().getExternName());
 52				if(refLevel > 0) cgen.current.app(')');
 53				return;
 54			}
 55			
 56			cgen.current.app("((").app(refTypeDecl.getType().getUnderName())
 57				.app("Class*) ").app(refTypeDecl.getType().getUnderName())
 58				.app("_class())->").app(memberAccess.getName());
 59		} else {
 60			boolean isArrow = (refTypeDecl instanceof ClassDecl);
 61			boolean didDeref = false;
 62			
 63			Expression expression = memberAccess.getExpression();
 64			if(!isArrow && expression instanceof Dereference) {
 65				Dereference deref = (Dereference) expression;
 66				expression = deref.getExpression();
 67				isArrow = true;
 68				didDeref = true;
 69			}
 70			
 71			if(refTypeDecl.getType().equals(expression.getType())) {		
 72				expression.accept(cgen);
 73			} else {
 74				cgen.current.app("((");
 75				cgen.current.app(((TypeDecl) refTypeDecl.getInstanceType().getRef()).getUnderName());
 76				Type membExprType = memberAccess.getExpression().getType();
 77				TypeWriter.writeFinale(membExprType, cgen);
 78				if(didDeref) cgen.current.app("*");
 79				cgen.current.app(") ");
 80				expression.accept(cgen);
 81				cgen.current.app(')');
 82			}
 83			
 84			cgen.current.app(isArrow ? "->" : ".");
 85			LocalAccessWriter.write(memberAccess, false, cgen);
 86			if(refLevel > 0) cgen.current.app(')');
 87		}
 88		
 89	}
 90
 91	private static void writeFuncAccess(MemberAccess memberAccess,
 92			CGenerator cgen) throws IOException {
 93		FunctionDecl funcDecl = (FunctionDecl) memberAccess.getRef();
 94		
 95		TypeDecl typeDecl = funcDecl.getTypeDecl();
 96		String typeName = typeDecl.getUnderName();
 97		
 98		cgen.current.app("((").app(typeName).app("Class *) ");
 99		memberAccess.getExpression().accept(cgen);
100		cgen.current.app(")->").app(memberAccess.getName());
101	}
102	
103}