@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);
       }
     }
   }
 }
Exemplo n.º 2
0
/** @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;
  }
}