001: // This file is part of KeY - Integrated Deductive Software Design
002: // Copyright (C) 2001-2007 Universitaet Karlsruhe, Germany
003: // Universitaet Koblenz-Landau, Germany
004: // Chalmers University of Technology, Sweden
005: //
006: // The KeY system is protected by the GNU General Public License.
007: // See LICENSE.TXT for details.
008: //
009: // This file is part of KeY - Integrated Deductive Software Design
010: // Copyright (C) 2001-2004 Universitaet Karlsruhe, Germany
011: // Universitaet Koblenz-Landau, Germany
012: // Chalmers University of Technology, Sweden
013: //
014: // The KeY system is protected by the GNU General Public License.
015: // See LICENSE.TXT for details.
016: package de.uka.ilkd.key.java.recoderext;
017:
018: import recoder.CrossReferenceServiceConfiguration;
019: import recoder.java.Identifier;
020: import recoder.java.StatementBlock;
021: import recoder.java.declaration.ClassDeclaration;
022: import recoder.java.declaration.LocalVariableDeclaration;
023: import recoder.java.declaration.MethodDeclaration;
024: import recoder.java.declaration.TypeDeclaration;
025: import recoder.java.declaration.modifier.Public;
026: import recoder.java.declaration.modifier.Static;
027: import recoder.java.reference.MethodReference;
028: import recoder.java.reference.TypeReference;
029: import recoder.java.reference.VariableReference;
030: import recoder.java.statement.Return;
031: import recoder.list.*;
032:
033: /**
034: * If an allocation expression <code>new Class(...)</code> occurs, a new object
035: * has to be created, in KeY this is quite similar to take it out of a list of
036: * objects and setting the implicit flag <code> <created> </code> to
037: * <code>true</code> as well as setting all fields of the object to their
038: * default values. For the complete procedure, the method creates the
039: * implicit method <code><createObject$gt;</code> which on its part calls
040: * another implicit method <code>lt;prepare></code> for setting the fields
041: * default values.
042: */
043: public class CreateObjectBuilder extends RecoderModelTransformer {
044:
045: public static final String IMPLICIT_OBJECT_CREATE = "<createObject>";
046: public static final String NEW_OBJECT_VAR_NAME = "__NEW__";
047:
048: public CreateObjectBuilder(
049: CrossReferenceServiceConfiguration services,
050: CompilationUnitMutableList units) {
051: super (services, units);
052: }
053:
054: /**
055: * Creates the body of the static <code><createObject></code>
056: * method.
057: */
058: private StatementBlock createBody(ClassDeclaration recoderClass) {
059:
060: StatementMutableList result = new StatementArrayList(10);
061: LocalVariableDeclaration local = declare(NEW_OBJECT_VAR_NAME,
062: recoderClass);
063:
064: result.add(local);
065:
066: final ExpressionMutableList arguments = new ExpressionArrayList(
067: 0);
068:
069: result
070: .add(assign(
071: new VariableReference(new Identifier(
072: NEW_OBJECT_VAR_NAME)),
073: new MethodReference(
074: new TypeReference(
075: (Identifier) recoderClass
076: .getIdentifier()
077: .deepClone()),
078: new ImplicitIdentifier(
079: InstanceAllocationMethodBuilder.IMPLICIT_INSTANCE_ALLOCATE),
080: arguments)));
081:
082: result.add(new MethodReference(new VariableReference(
083: new Identifier(NEW_OBJECT_VAR_NAME)),
084: new ImplicitIdentifier(CreateBuilder.IMPLICIT_CREATE)));
085:
086: result.add(new Return(new VariableReference(new Identifier(
087: NEW_OBJECT_VAR_NAME))));
088:
089: return new StatementBlock(result);
090:
091: }
092:
093: /**
094: * creates the implicit static <code><createObject></code>
095: * method that takes the object to be created out of the pool
096: * @param type the TypeDeclaration for which the
097: * <code><prepare></code> is created
098: * @return the implicit <code><prepare></code> method
099: */
100: public MethodDeclaration createMethod(ClassDeclaration type) {
101: ModifierMutableList modifiers = new ModifierArrayList(2);
102: modifiers.add(new Public());
103: modifiers.add(new Static());
104: MethodDeclaration md = new MethodDeclaration(modifiers,
105: new TypeReference((Identifier) type.getIdentifier()
106: .deepClone()), new ImplicitIdentifier(
107: IMPLICIT_OBJECT_CREATE),
108: new ParameterDeclarationArrayList(0), null,
109: createBody(type));
110: md.makeAllParentRolesValid();
111: return md;
112: }
113:
114: /**
115: * entry method for the constructor normalform builder
116: * @param td the TypeDeclaration
117: */
118: protected void makeExplicit(TypeDeclaration td) {
119: if (td instanceof ClassDeclaration) {
120: attach(createMethod((ClassDeclaration) td), td, td
121: .getMembers().size());
122: // java.io.StringWriter sw = new java.io.StringWriter();
123: // services.getProgramFactory().getPrettyPrinter(sw).visitClassDeclaration((ClassDeclaration)td);
124: // System.out.println(sw.toString());
125: // try { sw.close(); } catch (Exception e) {}
126: }
127: }
128:
129: }
|