@Override protected void migrate( org.lgna.project.ast.MethodInvocation methodInvocation, org.lgna.project.Project projectIfApplicable) { org.lgna.project.ast.AbstractMethod method = methodInvocation.method.getValue(); if (method instanceof org.lgna.project.ast.JavaMethod) { org.lgna.project.ast.JavaMethod javaMethod = (org.lgna.project.ast.JavaMethod) method; if (javaMethod.getDeclaringType() == org.lgna.project.ast.JavaType.getInstance(org.lgna.story.SScene.class)) { String methodName = javaMethod.getName(); if (methodName.equals("addMouseClickOnScreenListener")) { for (org.lgna.project.ast.AbstractArgument argument : methodInvocation.keyedArguments) { if (DEBUG_MODE) { edu.cmu.cs.dennisc.java.util.logging.Logger.errln( "ALERT: migration removing", argument); } } methodInvocation.keyedArguments.clear(); methodInvocation.method.setValue( org.lgna.story.ast.EventListenerMethodUtilities .ADD_MOUSE_CLICK_ON_SCREEN_LISTENER_METHOD); } else if (methodName.equals("addMouseClickOnObjectListener")) { for (org.lgna.project.ast.AbstractArgument argument : methodInvocation.keyedArguments) { if (DEBUG_MODE) { edu.cmu.cs.dennisc.java.util.logging.Logger.errln( "ALERT: migration removing", argument); } } methodInvocation.keyedArguments.clear(); methodInvocation.method.setValue( org.lgna.story.ast.EventListenerMethodUtilities .ADD_MOUSE_CLICK_ON_OBJECT_LISTENER_METHOD); } } } }
/** @author Dennis Cosgrove */ public class TypeManager { public TypeManager() { throw new AssertionError(); } private static final org.lgna.project.ast.Expression[] USE_PARAMETER_ACCESSES_AS_ARGUMENTS_TO_SUPER = null; private static org.lgna.project.ast.NamedUserType createTypeFor( org.lgna.project.ast.AbstractType<?, ?, ?> superType, String typeName, org.lgna.project.ast.AbstractType<?, ?, ?>[] parameterTypes, org.lgna.project.ast.Expression[] argumentExpressions) { org.lgna.project.ast.NamedUserType rv = new org.lgna.project.ast.NamedUserType(); rv.name.setValue(typeName); rv.superType.setValue(superType); for (org.lgna.project.ast.AbstractConstructor superConstructor : superType.getDeclaredConstructors()) { java.util.List<? extends org.lgna.project.ast.AbstractParameter> javaParameters = superConstructor.getRequiredParameters(); org.lgna.project.ast.NamedUserConstructor userConstructor = new org.lgna.project.ast.NamedUserConstructor(); org.lgna.project.ast.ConstructorBlockStatement body = new org.lgna.project.ast.ConstructorBlockStatement(); org.lgna.project.ast.SuperConstructorInvocationStatement superConstructorInvocationStatement = new org.lgna.project.ast.SuperConstructorInvocationStatement(); superConstructorInvocationStatement.constructor.setValue(superConstructor); final int N = javaParameters.size(); for (int i = 0; i < N; i++) { org.lgna.project.ast.AbstractParameter javaParameterI = javaParameters.get(i); org.lgna.project.ast.Expression argumentExpressionI; if (argumentExpressions != USE_PARAMETER_ACCESSES_AS_ARGUMENTS_TO_SUPER) { argumentExpressionI = argumentExpressions[i]; } else { String parameterName = javaParameterI.getName(); // todo? if (parameterName != null) { // pass } else { parameterName = "p" + i; } org.lgna.project.ast.AbstractType<?, ?, ?> parameterTypeI; if (parameterTypes != null) { parameterTypeI = parameterTypes[i]; } else { parameterTypeI = javaParameterI.getValueType(); } org.lgna.project.ast.UserParameter userParameterI = new org.lgna.project.ast.UserParameter(parameterName, parameterTypeI); userConstructor.requiredParameters.add(userParameterI); argumentExpressionI = new org.lgna.project.ast.ParameterAccess(userParameterI); } superConstructorInvocationStatement.requiredArguments.add( new org.lgna.project.ast.SimpleArgument(javaParameterI, argumentExpressionI)); } body.constructorInvocationStatement.setValue(superConstructorInvocationStatement); userConstructor.body.setValue(body); rv.constructors.add(userConstructor); } org.alice.ide.IDE ide = org.alice.ide.IDE.getActiveInstance(); if (ide != null) { ide.getApiConfigurationManager().augmentTypeIfNecessary(rv); } return rv; } private abstract static class ExtendsTypeCriterion implements edu.cmu.cs.dennisc.pattern.Criterion<org.lgna.project.ast.NamedUserType> { private final org.lgna.project.ast.AbstractType<?, ?, ?> superType; public ExtendsTypeCriterion(org.lgna.project.ast.AbstractType<?, ?, ?> superType) { assert superType != null; this.superType = superType; } @Override public boolean accept(org.lgna.project.ast.NamedUserType userType) { return userType.superType.getValue() == this.superType; } } private static final class DefaultConstructorExtendsTypeCriterion extends ExtendsTypeCriterion { public DefaultConstructorExtendsTypeCriterion( org.lgna.project.ast.AbstractType<?, ?, ?> superType) { super(superType); } } private static final class ExtendsTypeWithConstructorParameterTypeCriterion extends ExtendsTypeCriterion { private final org.lgna.project.ast.AbstractType<?, ?, ?> parameterType; public ExtendsTypeWithConstructorParameterTypeCriterion( org.lgna.project.ast.AbstractType<?, ?, ?> superType, org.lgna.project.ast.AbstractType<?, ?, ?> parameterType) { super(superType); assert parameterType != null; this.parameterType = parameterType; } @Override public boolean accept(org.lgna.project.ast.NamedUserType userType) { if (super.accept(userType)) { org.lgna.project.ast.AbstractConstructor constructor = userType.getDeclaredConstructor(this.parameterType); if (constructor != null) { org.lgna.project.ast.AbstractParameter parameter0 = constructor.getRequiredParameters().get(0); return parameter0.getValueType() == this.parameterType; } else { return false; } } else { return false; } } } private static final class ExtendsTypeWithSuperArgumentFieldCriterion extends ExtendsTypeCriterion { private final org.lgna.project.ast.AbstractField superArgumentField; public ExtendsTypeWithSuperArgumentFieldCriterion( org.lgna.project.ast.AbstractType<?, ?, ?> superType, org.lgna.project.ast.AbstractField superArgumentField) { super(superType); assert superArgumentField != null; this.superArgumentField = superArgumentField; } @Override public boolean accept(org.lgna.project.ast.NamedUserType userType) { if (super.accept(userType)) { org.lgna.project.ast.NamedUserConstructor constructor = userType.getDeclaredConstructor(); if (constructor != null) { org.lgna.project.ast.ConstructorInvocationStatement constructorInvocationStatement = constructor.body.getValue().constructorInvocationStatement.getValue(); if (constructorInvocationStatement instanceof org.lgna.project.ast.SuperConstructorInvocationStatement) { if (constructorInvocationStatement.requiredArguments.size() == 1) { org.lgna.project.ast.Expression argumentExpression = constructorInvocationStatement.requiredArguments.get(0).expression.getValue(); if (argumentExpression instanceof org.lgna.project.ast.FieldAccess) { org.lgna.project.ast.FieldAccess fieldAccess = (org.lgna.project.ast.FieldAccess) argumentExpression; return fieldAccess.field.getValue() == this.superArgumentField; } } } } } return false; } } private static java.util.List<org.lgna.project.ast.AbstractType<?, ?, ?>> updateArgumentTypes( java.util.List<org.lgna.project.ast.AbstractType<?, ?, ?>> rv, org.lgna.project.ast.AbstractType<?, ?, ?> rootArgumentType, org.lgna.project.ast.AbstractType<?, ?, ?> argumentType) { rv.add(argumentType); if (argumentType == rootArgumentType) { // pass } else { org.lgna.project.ast.AbstractType<?, ?, ?>[] interfaces = argumentType.getInterfaces(); org.lgna.project.ast.AbstractType<?, ?, ?> nextType; if (interfaces.length == 1) { nextType = interfaces[0]; } else { nextType = argumentType.getSuperType(); } if (nextType != null) { updateArgumentTypes(rv, rootArgumentType, nextType); } } return rv; } public static org.lgna.project.ast.AbstractType<?, ?, ?>[] getArgumentTypes( org.lgna.project.ast.AbstractType<?, ?, ?> ancestorType, org.lgna.project.ast.AbstractType<?, ?, ?> resourceType) { java.util.List<org.lgna.project.ast.AbstractType<?, ?, ?>> types = edu.cmu.cs.dennisc.java.util.Lists.newLinkedList(); updateArgumentTypes( types, ConstructorArgumentUtilities.getContructor0Parameter0Type(ancestorType), resourceType); org.lgna.project.ast.AbstractType<?, ?, ?>[] rv = new org.lgna.project.ast.AbstractType<?, ?, ?>[types.size()]; types.toArray(rv); return rv; } private static org.lgna.project.ast.AbstractType<?, ?, ?>[] getArgumentTypes( org.lgna.project.ast.AbstractType<?, ?, ?> ancestorType, org.lgna.project.ast.AbstractField field) { return getArgumentTypes(ancestorType, field.getDeclaringType()); } private static void appendTypeName(StringBuilder sb, String name) { sb.append(name); } private static String createClassNameFromResourceType( org.lgna.project.ast.AbstractType<?, ?, ?> resourceType) { StringBuilder sb = new StringBuilder(); appendTypeName(sb, resourceType.getName().replace("Resource", "")); return sb.toString(); } public static String createClassNameFromArgumentField( org.lgna.project.ast.AbstractType<?, ?, ?> ancestorType, org.lgna.project.ast.AbstractField argumentField) { org.lgna.project.ast.AbstractType<?, ?, ?>[] argumentTypes = getArgumentTypes(ancestorType, argumentField); return createClassNameFromResourceType(argumentTypes[0]); } public static String createClassNameFromSuperType( org.lgna.project.ast.AbstractType<?, ?, ?> superType) { String superTypeName = superType.getName(); if (superTypeName.length() > 1) { if (superTypeName.charAt(0) == 'S') { if (Character.isUpperCase(superTypeName.charAt(1))) { return superTypeName.substring(1); } } } return superTypeName; } private static final org.lgna.project.ast.JavaMethod SET_JOINTED_MODEL_RESOURCE_METHOD = org.lgna.project.ast.JavaMethod.getInstance( org.lgna.story.SJointedModel.class, "setJointedModelResource", org.lgna.story.resources.JointedModelResource.class); private static org.lgna.project.ast.NamedUserType getNamedUserTypeFor( org.lgna.project.ast.AbstractType<?, ?, ?> ancestorType, org.lgna.project.ast.AbstractType<?, ?, ?>[] argumentTypes, int i, org.lgna.project.ast.AbstractField argumentField) { org.lgna.project.ast.AbstractType<?, ?, ?> superType; final int LAST_INDEX = argumentTypes.length - 1; if (i < LAST_INDEX) { superType = getNamedUserTypeFor(ancestorType, argumentTypes, i + 1, null); } else { superType = ancestorType; } edu.cmu.cs.dennisc.pattern.Criterion<org.lgna.project.ast.NamedUserType> criterion; if (argumentField != null) { criterion = new ExtendsTypeWithSuperArgumentFieldCriterion(superType, argumentField); } else { criterion = new ExtendsTypeWithConstructorParameterTypeCriterion(superType, argumentTypes[i]); } // org.alice.ide.IDE ide = org.alice.ide.IDE.getActiveInstance(); // if( ide != null ) { // org.alice.ide.ProjectDocument projectDocument = ide.getDocument(); // if( projectDocument != null ) { // org.alice.ide.type.TypeCache typeCache = projectDocument.getTypeCache(); // typeCache.getNamedUserTypeFor( ancestorType, argumentTypes, i, argumentField ); // } // } org.lgna.project.Project project = org.alice.ide.ProjectStack.peekProject(); if (project != null) { java.util.Set<org.lgna.project.ast.NamedUserType> existingTypes = project.getNamedUserTypes(); for (org.lgna.project.ast.NamedUserType existingType : existingTypes) { if (criterion.accept(existingType)) { return existingType; } } } org.lgna.project.ast.Expression[] expressions; if (argumentField != null) { expressions = new org.lgna.project.ast.Expression[] { new org.lgna.project.ast.FieldAccess( new org.lgna.project.ast.TypeExpression(argumentField.getDeclaringType()), argumentField) }; } else { expressions = USE_PARAMETER_ACCESSES_AS_ARGUMENTS_TO_SUPER; } String name = createClassNameFromResourceType(argumentTypes[i]); org.lgna.project.ast.NamedUserType rv = createTypeFor( superType, name, new org.lgna.project.ast.AbstractType[] {argumentTypes[i]}, expressions); if (argumentTypes[i] instanceof org.lgna.project.ast.JavaType) { org.lgna.project.ast.JavaType javaArgumentTypeI = (org.lgna.project.ast.JavaType) argumentTypes[i]; Class<?> cls = javaArgumentTypeI.getClassReflectionProxy().getReification(); if (edu.cmu.cs.dennisc.java.lang.reflect.ReflectionUtilities.isFinal(cls)) { boolean isSetResourceMethodDesired; if (cls.isEnum()) { isSetResourceMethodDesired = cls.getEnumConstants().length > 1; } else { isSetResourceMethodDesired = true; } if (isSetResourceMethodDesired) { String simpleClsName = cls.getSimpleName(); org.lgna.project.ast.UserMethod setResourceMethod = new org.lgna.project.ast.UserMethod(); setResourceMethod.managementLevel.setValue( org.lgna.project.ast.ManagementLevel.GENERATED); setResourceMethod.name.setValue("set" + simpleClsName); setResourceMethod.returnType.setValue(org.lgna.project.ast.JavaType.VOID_TYPE); org.lgna.project.ast.BlockStatement body = new org.lgna.project.ast.BlockStatement(); setResourceMethod.body.setValue(body); StringBuilder parameterNameSB = new StringBuilder(); parameterNameSB.append(Character.toLowerCase(simpleClsName.charAt(0))); parameterNameSB.append(simpleClsName.substring(1)); org.lgna.project.ast.UserParameter parameter = new org.lgna.project.ast.UserParameter(); parameter.name.setValue(parameterNameSB.toString()); parameter.valueType.setValue(javaArgumentTypeI); setResourceMethod.requiredParameters.add(parameter); body.statements.add( org.lgna.project.ast.AstUtilities.createMethodInvocationStatement( new org.lgna.project.ast.ThisExpression(), SET_JOINTED_MODEL_RESOURCE_METHOD, new org.lgna.project.ast.ParameterAccess(parameter))); setResourceMethod.isSignatureLocked.setValue(true); rv.methods.add(setResourceMethod); } } } return rv; } public static org.lgna.project.ast.JavaField getEnumConstantFieldIfOneAndOnly( org.lgna.project.ast.AbstractType<?, ?, ?> type) { org.lgna.project.ast.JavaField rv = null; if (type instanceof org.lgna.project.ast.JavaType) { org.lgna.project.ast.JavaType javaType = (org.lgna.project.ast.JavaType) type; if (type.isAssignableTo(Enum.class)) { Class<Enum<?>> cls = (Class<Enum<?>>) javaType.getClassReflectionProxy().getReification(); Enum<?>[] constants = cls.getEnumConstants(); if (constants.length == 1) { Enum<?> constant = constants[0]; rv = org.lgna.project.ast.JavaField.getInstance(constant.getClass(), constant.name()); } } } return rv; } public static org.lgna.project.ast.NamedUserType getNamedUserTypeFromArgumentField( org.lgna.project.ast.AbstractType<?, ?, ?> ancestorType, org.lgna.project.ast.JavaField argumentField) { org.lgna.project.ast.AbstractType<?, ?, ?>[] argumentTypes = getArgumentTypes(ancestorType, argumentField); return getNamedUserTypeFor( ancestorType, argumentTypes, 0, getEnumConstantFieldIfOneAndOnly(argumentTypes[0])); } // Method not used // public static org.lgna.project.ast.NamedUserType getNamedUserTypeFromPersonResource( // org.lgna.story.resources.sims2.PersonResource personResource ) { // org.lgna.project.ast.JavaType bipedType = org.lgna.project.ast.JavaType.getInstance( // org.lgna.story.SBiped.class ); // org.lgna.project.ast.AbstractType<?, ?, ?>[] argumentTypes = getArgumentTypes( bipedType, // org.lgna.project.ast.JavaType.getInstance( personResource.getClass() ) ); // return getNamedUserTypeFor( bipedType, argumentTypes, 0, null ); // } public static org.lgna.project.ast.NamedUserType getNamedUserTypeFromPersonResourceInstanceCreation( org.lgna.project.ast.InstanceCreation instanceCreation) { org.lgna.project.ast.JavaType bipedType = org.lgna.project.ast.JavaType.getInstance(org.lgna.story.SBiped.class); org.lgna.project.ast.AbstractType<?, ?, ?>[] argumentTypes = getArgumentTypes(bipedType, instanceCreation.getType()); return getNamedUserTypeFor(bipedType, argumentTypes, 0, null); } public static org.lgna.project.ast.NamedUserType getNamedUserTypeFromSuperType( org.lgna.project.ast.JavaType superType) { // <lg> Added to support generality in reuse if (superType.isAssignableTo(org.lgna.story.SScene.class)) { return getSceneUserType(); } // </lg> org.lgna.project.ast.AbstractType<?, ?, ?> parameter0Type = ConstructorArgumentUtilities.getContructor0Parameter0Type(superType); ExtendsTypeCriterion criterion; if (parameter0Type != null) { criterion = new ExtendsTypeWithConstructorParameterTypeCriterion( superType, ConstructorArgumentUtilities.getContructor0Parameter0Type(superType)); } else { criterion = new DefaultConstructorExtendsTypeCriterion(superType); } org.alice.ide.IDE ide = org.alice.ide.IDE.getActiveInstance(); if (ide != null) { org.lgna.project.Project project = ide.getProject(); if (project != null) { java.util.Set<org.lgna.project.ast.NamedUserType> existingTypes = project.getNamedUserTypes(); for (org.lgna.project.ast.NamedUserType existingType : existingTypes) { if (criterion.accept(existingType)) { return existingType; } } } } return createTypeFor(superType, createClassNameFromSuperType(superType), null, null); } // <lg> Added to support generality in reuse private static final edu.cmu.cs.dennisc.java.util.DStack<org.lgna.project.ast.NamedUserType> sceneUserTypeStack = edu.cmu.cs.dennisc.java.util.Stacks.newStack(); public static void pushSceneUserType(org.lgna.project.ast.NamedUserType sceneUserType) { sceneUserTypeStack.push(sceneUserType); } public static org.lgna.project.ast.NamedUserType peekSceneUserType() { if (sceneUserTypeStack.isEmpty()) { return null; } else { return sceneUserTypeStack.peek(); } } public static org.lgna.project.ast.NamedUserType popSceneUserType() { return sceneUserTypeStack.pop(); } public static boolean isSceneUserTypeEmpty() { return sceneUserTypeStack.isEmpty(); } public static org.lgna.project.ast.NamedUserType getSceneUserType() { if (sceneUserTypeStack.isEmpty()) { // note: currently necessary for scene editor set up org.alice.ide.IDE ide = org.alice.ide.IDE.getActiveInstance(); if (ide != null) { org.lgna.project.Project project = ide.getProject(); if (project != null) { for (org.lgna.project.ast.UserField field : project.getProgramType().getDeclaredFields()) { if (field.valueType.getValue().isAssignableTo(org.lgna.story.SScene.class)) { return (org.lgna.project.ast.NamedUserType) field.valueType.getValue(); } } } } return null; } else { return sceneUserTypeStack.peek(); } } // </lg> public static java.util.List<org.lgna.project.ast.NamedUserType> getNamedUserTypesFromSuperTypes( java.util.List<org.lgna.project.ast.JavaType> superTypes) { java.util.ArrayList<org.lgna.project.ast.NamedUserType> rv = edu.cmu.cs.dennisc.java.util.Lists.newArrayListWithInitialCapacity(superTypes.size()); for (org.lgna.project.ast.JavaType superType : superTypes) { rv.add(getNamedUserTypeFromSuperType(superType)); } return rv; } }