/* * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered * by the modified BSD License. You should have received a copy of the * modified BSD license with this compiler. * * Copyright (c) 2005-2008, Torbjorn Ekman * All rights reserved. */ aspect IntertypeConstructorCodegeneration { //eq IntertypeConstructorDecl.isBytecodeMethod() = false; eq IntertypeConstructorDecl.generate() = false; syn TypeDecl IntroducedConstructorDecl.introducedType() = hostType(); eq IntroducedConstructorDecl.getBlock().lookupMethod(String name) { Collection c = introducedType().memberMethods(name); if(!c.isEmpty()) return c; return getITDBodyDecl().lookupMethod(name); } eq IntroducedConstructorDecl.getBlock().lookupVariable(String name) { SimpleSet set = parameterDeclaration(name); if(!set.isEmpty()) return set; set = introducedType().memberFields(name); if(!set.isEmpty()) return set; return getITDBodyDecl().lookupVariable(name); } public void IntertypeConstructorDecl.generateIntertypeDecls() { if(isPrivate()) { createAccessor(); return; } introducedType().addBodyDecl(createDelegate()); } public ConstructorDecl IntertypeConstructorDecl.createDelegate() { List args = new List(); args.add(new ThisAccess("this")); for(int i = 0; i < getNumParameter(); i++) args.add(new VarAccess(getParameter(i).name())); Block block = new Block( new List().add( new ExprStmt( createBodyDelegate().createBoundAccess(args) ) ).add( new ReturnStmt(new Opt()) ) ); Modifiers m = new Modifiers(new List().add(new Modifier("public"))); List parameters = copyParameterList(getParameterList()); return new IntroducedConstructorDecl( m, getID(), parameters, copyTypeList(getExceptionList()), (Opt)getConstructorInvocationOpt().boundCopy(), block, this ); } public ConstructorDecl IntertypeConstructorDecl.createAccessor() { ConstructorDecl c = (ConstructorDecl)hostType().getAccessor(this, "constructor"); if(c != null) return c; // make sure enclosing varibles are added as parameters prior to building accessor addEnclosingVariables(); Modifiers modifiers = new Modifiers(new List()); modifiers.addModifier(new Modifier("synthetic")); modifiers.addModifier(new Modifier("public")); List parameters = createAccessorParameters(); // add all parameters as arguments except for the dummy parameter List args = new List(); args.add(new ThisAccess("this")); for(int i = 0; i < parameters.getNumChildNoTransform() - 1; i++) args.add(new VarAccess(((ParameterDeclaration)parameters.getChildNoTransform(i)).name())); c = new ConstructorDecl( modifiers, name(), parameters, copyTypeList(getExceptionList()), (Opt)getConstructorInvocationOpt().boundCopy(), new Block( new List().add( new ExprStmt( createBodyDelegate().createBoundAccess(args) ) ).add( new ReturnStmt(new Opt()) ) ) ); c = hostType().addConstructor(c); c.addEnclosingVariables = false; hostType().addAccessor(this, "constructor", c); return c; } syn String IntertypeConstructorDecl.constructorBodyName() = "abc$interConstructorBody$" + abcMangledSignature(); syn String IntertypeConstructorDecl.abcMangledSignature() = hostAspect().abcMangledName() + "$" + introducedType().abcMangledName(); public MethodDecl IntertypeConstructorDecl.createBodyDelegate() { String name = "constructor_body"; TypeDecl typeDecl = hostAspect(); MethodDecl m = (MethodDecl)typeDecl.getAccessor(this, name); if(m != null) return m; List list = copyParameterList(getParameterList()); list.insertChild(new ParameterDeclaration(hostType(), "this"), 0); Modifiers modifiers = createAccessorModifiers(true); m = new IntroducedMethodDecl( modifiers, hostType().typeVoid().createQualifiedAccess(), constructorBodyName(), list, new List(), new Opt(getBlock().boundCopy()), introducedType(), this ); m = typeDecl.addMemberMethod(m); typeDecl.addAccessor(this, name, m); return m; //return buildAccessor(m, hostType().typeVoid(), "constructorInit", list, new Opt(getBlock().fullCopy()), hostAspect()); } public void IntroducedConstructorDecl.toString(StringBuffer s) { s.append(indent()); s.append("/*@IntroducedType(" + introducedType().typeName() + ")*/ "); //s.append("@ITDBodyDecl(" + getITDBodyDecl().typeName() + ") "); getModifiers().toString(s); s.append(name() + "("); if(getNumParameter() > 0) { getParameter(0).toString(s); for(int i = 1; i < getNumParameter(); i++) { s.append(", "); getParameter(i).toString(s); } } s.append(")"); if(getNumException() > 0) { s.append(" throws "); getException(0).toString(s); for(int i = 1; i < getNumException(); i++) { s.append(", "); getException(i).toString(s); } } s.append(" {"); if(hasConstructorInvocation()) { getConstructorInvocation().toString(s); } for(int i = 0; i < getBlock().getNumStmt(); i++) { getBlock().getStmt(i).toString(s); } s.append(indent()); s.append("}"); } }