Пример #1
0
  public static void init() {
    Thing t;

    t = Lib.extend("base poison", "temporary effect");
    t.set("IsActive", 1);
    t.addHandler("OnAction", new PoisonAction());
    t.set("IsPoison", 1);
    t.set("DamageType", "poison");
    t.set("EffectName", "poisoned");
    t.set("ResistStat", "TG");
    t.set("ResistMessage", null);
    t.set("ResistDifficulty", 10);
    t.set("CureDifficulty", 5);
    Lib.add(t);

    t = Lib.extend("weakening poison", "base poison");
    t.set("LifeTime", 50000);
    t.set("EffectName", "poisoned");
    t.set("Strength", 100);
    t.set("Damage", 2);
    t.set("DamageType", "poison");
    t.set("DamageMessage", "You feel sick...");
    t.set("ResistMessage", "You manage to shake off a feeling of weakness");
    t.set("AttributeAddMessage", "You feel weakened!");
    t.add("CarriedModifiers", Modifier.linear("ST", 90, 0));
    Lib.add(t);

    t = Lib.extend("poison", "base poison");
    t.set("LifeTime", 20000);
    t.set("Strength", 200);
    t.set("Damage", 3);
    t.set("DamageType", "poison");
    t.set("ResistMessage", "You feel queasy for a moment");
    t.set("DamageMessage", "You feel the effects of poison...");
    t.set("AttributeAddMessage", "You feel poisoned!");
    Lib.add(t);

    t = Lib.extend("strong poison", "base poison");
    t.set("LifeTime", 30000);
    t.set("Strength", 300);
    t.set("Damage", 6);
    t.set("DamageType", "poison");
    t.set("ResistMessage", "You feel very queasy for a moment");
    t.set("DamageMessage", "You feel the poison weakening you...");
    t.set("AttributeAddMessage", "You feel badly poisoned!");
    t.set("CureDifficulty", 15);
    Lib.add(t);

    t = Lib.extend("deadly poison", "base poison");
    t.set("LifeTime", 40000);
    t.set("Strength", 2000);
    t.set("Damage", 10);
    t.set("DamageType", "poison");
    t.set("ResistMessage", "You feel very queasy for a moment");
    t.set("DamageMessage", "You feel the poison weakening you...");
    t.set("AttributeAddMessage", "You feel badly poisoned!");
    t.set("CureDifficulty", 40);
    Lib.add(t);

    t = Lib.extend("extreme poison", "base poison");
    t.set("LifeTime", 50000);
    t.set("Strength", 6000);
    t.set("Damage", 15);
    t.set("DamageType", "poison");
    t.set("ResistMessage", "You feel very queasy for a moment");
    t.set("DamageMessage", "You feel the poison weakening you...");
    t.set("AttributeAddMessage", "You feel badly poisoned!");
    t.set("CureDifficulty", 100);
    Lib.add(t);

    t = Lib.extend("ultimate poison", "base poison");
    t.set("LifeTime", 100000);
    t.set("Strength", 12000);
    t.set("Damage", 30);
    t.set("DamageType", "poison");
    t.set("ResistMessage", "You feel very queasy for a moment");
    t.set("DamageMessage", "You feel the poison weakening you...");
    t.set("AttributeAddMessage", "You feel badly poisoned!");
    t.set("CureDifficulty", 300);
    Lib.add(t);

    t = Lib.extend("sickness", "base poison");
    t.set("LifeTime", 50000);
    t.set("Strength", 100);
    t.set("Damage", 2);
    t.set("DamageType", "poison");
    t.set("DamageMessage", "You feel sick...");
    t.set("ResistMessage", "You manage to shake off a feeling of illness");
    t.set("AttributeAddMessage", "You feel sick!");
    t.add("CarriedModifiers", Modifier.bonus("ST", -2));
    t.add("CarriedModifiers", Modifier.bonus("SK", -2));
    t.set("CureDifficulty", 15);
    Lib.add(t);

    t = Lib.extend("pestilence", "poison");
    t.set("LifeTime", 120000);
    t.set("Strength", 200);
    t.set("Damage", 4);
    t.set("EffectName", "pestilent");
    t.set("DamageType", "poison");
    t.set("DamageMessage", "You feel grotty...");
    t.set("AttributeAddMessage", "You feel the touch of pestilence!");
    t.set("ResistDifficulty", 20);
    t.addHandler("OnAction", Scripts.generator("fly swarm", 100));
    t.set("CureDifficulty", 25);
    Lib.add(t);

    t = Lib.extend("plague", "poison");
    t.set("LifeTime", 100000);
    t.set("Strength", 200);
    t.set("Damage", 8);
    t.set("EffectName", "plague");
    t.set("DamageType", "poison");
    t.set("DamageMessage", "You feel sick...");
    t.set("AttributeAddMessage", "You feel the touch of the plague!");
    t.set("ResistDifficulty", 20);
    t.add("CarriedModifiers", Modifier.linear("CH", 100, -10));
    t.addHandler("OnAction", Scripts.generator("plague cloud", 30));
    t.set("CureDifficulty", 100);
    Lib.add(t);
  }
  //	private AnnotationValue get(Map<String, AnnotationValue> values, String name, AnnotationValue
  // def) {
  //		AnnotationValue value = values.get(name);
  //		if (value != null)
  //			return value;
  //		return def;
  //	}
  private void processProperties(Thing data, Map<String, AnnotationValue> beanValues) {
    boolean atLeastOneBound = false;
    boolean atLeastOneDouble = false;
    boolean atLeastOneObject = false;
    String firstPropertyName = null;
    AnnotationValue propertiesValue = beanValues.get("properties");
    if (propertiesValue == null) {
      data.setEmpty("properties");
    } else {
      Set<String> propertyNames = new HashSet<String>();
      AnnotationValue defaultType = null;
      AnnotationValue defaultTypeString = null;
      AnnotationValue defaultKeyType = null;
      AnnotationValue defaultKeyTypeString = null;
      AnnotationValue defaultReader = null;
      AnnotationValue defaultWriter = null;
      AnnotationValue defaultBound = null;
      AnnotationValue defaultKind = null;
      AnnotationValue defaultOmitFromToString = null;
      AnnotationValue defaultNotNull = null;
      AnnotationValue defaultIsStatic = null;
      AnnotationValue defaultIsSynchronized = null;

      @SuppressWarnings("unchecked")
      List<AnnotationValue> properties = (List<AnnotationValue>) propertiesValue.getValue();
      for (AnnotationValue annotationValue : properties) {
        AnnotationMirror propertyMirror = (AnnotationMirror) annotationValue.getValue();
        Map<String, AnnotationValue> propertyValues = getAnnotationValues(propertyMirror);
        AnnotationValue name = propertyValues.get("name");
        AnnotationValue plural = propertyValues.get("plural");
        AnnotationValue type = propertyValues.get("type");
        AnnotationValue typeString = propertyValues.get("typeString");
        AnnotationValue keyType = propertyValues.get("keyType");
        AnnotationValue keyTypeString = propertyValues.get("keyTypeString");
        AnnotationValue reader = propertyValues.get("reader");
        AnnotationValue writer = propertyValues.get("writer");
        AnnotationValue bound = propertyValues.get("bound");
        AnnotationValue kind = propertyValues.get("kind");
        AnnotationValue omitFromToString = propertyValues.get("omitFromToString");
        AnnotationValue notNull = propertyValues.get("notNull");
        AnnotationValue isStatic = propertyValues.get("isStatic");
        AnnotationValue isSynchronized = propertyValues.get("isSynchronized");

        if (Property.DEFAULTS.equals(name.getValue())) {
          defaultType = type;
          defaultTypeString = typeString;
          defaultKeyType = keyType;
          defaultKeyTypeString = keyTypeString;
          defaultReader = reader;
          defaultWriter = writer;
          defaultBound = bound;
          defaultKind = kind;
          defaultOmitFromToString = omitFromToString;
          defaultNotNull = notNull;
          defaultIsStatic = isStatic;
          defaultIsSynchronized = isSynchronized;
          continue;
        }

        // plugin the default values
        if (type == null && typeString == null) {
          type = defaultType;
          typeString = defaultTypeString;
        }
        if (keyType == null && keyTypeString == null) {
          keyType = defaultKeyType;
          keyTypeString = defaultKeyTypeString;
        }
        if (reader == null) {
          reader = defaultReader;
        }
        if (writer == null) {
          writer = defaultWriter;
        }
        if (bound == null) {
          bound = defaultBound;
        }
        if (kind == null) {
          kind = defaultKind;
        }
        if (omitFromToString == null) {
          omitFromToString = defaultOmitFromToString;
        }
        if (notNull == null) {
          notNull = defaultNotNull;
        }
        if (isStatic == null) {
          isStatic = defaultIsStatic;
        }
        if (isSynchronized == null) {
          isSynchronized = defaultIsSynchronized;
        }

        Thing property = new Thing("property");
        property.put("name", name.getValue());

        if (typeString == null) {
          if (type == null) {
            property.put("type", "java.lang.String");
          } else {
            if (type.getValue() instanceof TypeDeclaration) {
              property.put("type", ((TypeDeclaration) type.getValue()).getQualifiedName());
            } else {
              property.put("type", ((PrimitiveType) type.getValue()).toString());
            }
          }
        } else {
          if (type != null) {
            String message = "@Property cannot have both type and typeString attributes specified";
            error(typeString, message);
            error(type, message);
            property.put("type", "<ERROR>");
          } else {
            property.put("type", typeString.getValue());
          }
        }

        PropertyKind propertyKind = PropertyKind.SIMPLE;
        if (kind != null) {
          propertyKind = PropertyKind.valueOf(kind.getValue().toString());
        }

        // check for duplicate keytype specifications
        if (propertyKind.isMap()) {
          if (keyTypeString == null) {
            if (keyType == null) {
              property.put("keyType", "java.lang.String");
            } else {
              property.put("keyType", ((TypeDeclaration) keyType.getValue()).getQualifiedName());
            }
          } else if (keyType != null) {
            String message =
                "@Property cannot have both keyType and keyTypeString attributes specified";
            error(keyType, message);
            error(keyTypeString, message);
            property.put("keyType", "<ERROR>");
          }
        } else {
          if (keyTypeString != null) {
            error(
                keyTypeString,
                "@Property can only have a keyTypeString attribute if kind is MAP or UNMODIFIABLE_MAP");
          }
          if (keyType != null) {
            error(
                keyType,
                "@Property can only have a keyType attribute if kind is MAP or UNMODIFIABLE_MAP");
          }
          property.put("keyType", "<ERROR>");
        }

        // check for plural names
        if (propertyKind.isSimple()) {
          if (plural != null) {
            error(plural, "@Property cannot have plural specified if kind is SIMPLE");
          }
          property.put("pluralName", null);
        } else {
          if (plural == null) {
            property.put("pluralName", name.getValue() + "s");
          } else {
            property.put("pluralName", plural.getValue());
          }
        }

        property.put("simple", propertyKind.isSimple());
        property.put("list", propertyKind.isList());
        property.put("map", propertyKind.isMap());
        property.put("set", propertyKind.isSet());
        String typeName = (String) property.get("type");

        property.put("float", "float".equals(typeName));
        property.put("double", "double".equals(typeName));
        property.put("boolean", "boolean".equals(typeName));
        property.put("char", "char".equals(typeName));
        property.put("byte", "byte".equals(typeName));
        property.put("long", "long".equals(typeName));
        property.put("int", "int".equals(typeName));
        property.put("short", "short".equals(typeName));

        if (property.containsKey("firstPropertyName")) {
          property.put("firstPropertyName", name.getValue());
        }
        if (propertyNames.contains(name.getValue())) {
          error(
              name,
              "Duplicate property name '" + name + "' specified for @Bean properties definition");
        } else {
          propertyNames.add((String) name.getValue());
        }

        if (bound != null) {
          if (isStatic != null) {
            error(bound, "Static properties cannot be declared bound");
            error(isStatic, "Static properties cannot be declared bound");
          } else {
            atLeastOneBound = true;
          }
        }

        if ("double".equals(property.get("type"))) {
          data.put("atLeastOneDouble", true);
        }
        property.put("kind", propertyKind);
        property.put("omitFromToString", b(omitFromToString));
        data.add("properties", property);

        // evil hack to get the type, which is a Class

        boolean isPrimitive =
            BeanAnnotationProcessor.PRIMITIVE_TYPES.contains(property.get("type"));
        property.put("primitive", isPrimitive);

        if (!isPrimitive) {
          data.put("atLeastOneObject", true);
        }

        property.put("bound", b(bound));
        if (writer == null) {
          property.put("writerAccess", Access.PUBLIC.getModifier());
          property.put("writeable", true);
        } else {
          EnumConstantDeclaration writerValue = (EnumConstantDeclaration) writer.getValue();
          Access writerAccess = Access.valueOf(writerValue.toString());
          property.put("writerAccess", writerAccess.getModifier());
          property.put("writeable", writerAccess != Access.NONE);
        }
        if (reader == null) {
          property.put("readerAccess", Access.PUBLIC.getModifier());
          property.put("readable", true);
        } else {
          EnumConstantDeclaration readerValue = (EnumConstantDeclaration) reader.getValue();
          Access readerAccess = Access.valueOf(readerValue.toString());
          property.put("readerAccess", readerAccess.getModifier());
          property.put("readable", readerAccess != Access.NONE);
        }

        boolean bNotNull = b(notNull);
        boolean bIsStatic = b(isStatic);
        boolean bIsSynchronized = b(isSynchronized);
        property.put("notNull", bNotNull);

        if (bNotNull && isPrimitive) {
          error(
              notNull,
              "Cannot specify notNull for primitive-typed property "
                  + name.getValue()
                  + " in @Property");
        }
        String extraFieldKeywords = "";
        String extraMethodKeywords = "";
        if (bIsStatic) {
          extraFieldKeywords = "static ";
          extraMethodKeywords = "static ";
        }
        if (bIsSynchronized) {
          if (bIsStatic) {
            extraMethodKeywords += "synchronized ";
          } else {
            extraMethodKeywords = "synchronized ";
          }
        }
        property.put("extraFieldKeywords", extraFieldKeywords);
        property.put("extraMethodKeywords", extraMethodKeywords);
        property.checkAllValuesSet(propertiesValue, this);
      }
    }
    data.put(
        "definePropertyChangeSupport",
        !((Boolean) data.get("getPropertyChangeSupportInherited")) && atLeastOneBound);
    data.put("atLeastOneDouble", atLeastOneDouble);
    data.put("atLeastOneObject", atLeastOneObject);
    data.put("firstPropertyName", firstPropertyName);
  }
  private void processDefaultMethods(Thing data, ClassDeclaration classDeclaration) {
    // find any methods that have default parameters
    boolean error = false;
    for (ConstructorDeclaration constructorDeclaration : classDeclaration.getConstructors()) {
      Collection<ParameterDeclaration> parameters = constructorDeclaration.getParameters();
      for (ParameterDeclaration parameterDeclaration : parameters) {
        Default annotation = parameterDeclaration.getAnnotation(Default.class);
        if (annotation != null) {
          error(parameterDeclaration, "@Default is not legal in constructor parameters");
          error = true;
        }
      }
    }
    if (error) {
      return;
    }

    boolean atLeastOneDefault = false;
    methods:
    for (MethodDeclaration methodDeclaration : classDeclaration.getMethods()) {
      Collection<ParameterDeclaration> parameters = methodDeclaration.getParameters();
      boolean seenDefault = false;
      String[] names = new String[parameters.size()];
      String[] types = new String[parameters.size()];
      String[] defaults = new String[parameters.size()];
      int n = 0;
      for (ParameterDeclaration parameterDeclaration : parameters) {
        Default annotation = parameterDeclaration.getAnnotation(Default.class);
        names[n] = parameterDeclaration.getSimpleName();
        types[n] = parameterDeclaration.getType().toString();
        if (annotation != null) {
          seenDefault = true;
          if ("java.lang.String".equals(types[n])) {
            defaults[n] = '"' + annotation.value() + '"';
          } else {
            defaults[n] = annotation.value();
          }
        } else if (seenDefault) {
          error(
              parameterDeclaration,
              "All parameters after a parameter annotated with @Default must be annotated with @Default");
          continue methods;
        }
        n++;
      }

      if (seenDefault) {
        atLeastOneDefault = true;
        if (methodDeclaration.getModifiers().contains(Modifier.PRIVATE)) {
          error(methodDeclaration, "Private methods cannot use @Default parameters");
        }
        if (methodDeclaration.getModifiers().contains(Modifier.STATIC)) {
          error(methodDeclaration, "Static methods cannot use @Default parameters");
        }
        String modifiers3 = "";
        if (methodDeclaration.getModifiers().contains(Modifier.PUBLIC)) {
          modifiers3 = "public ";
        } else if (methodDeclaration.getModifiers().contains(Modifier.PROTECTED)) {
          modifiers3 = "protected ";
        }
        String throwsClause = getThrowsClause(methodDeclaration);
        String returnType = methodDeclaration.getReturnType().toString();
        String methodName = methodDeclaration.getSimpleName();
        String argDecl = "";
        String callArgs = "";
        for (int i = 0; i < n; i++) {
          if (defaults[i] != null) {
            String callArgsWithDefaults = callArgs;
            for (int j = i; j < n; j++) {
              if (j > 0) {
                callArgsWithDefaults += ", ";
              }
              callArgsWithDefaults += defaults[j];
            }
            Thing method = new Thing("method");
            method.put("name", methodName);
            method.put("returnType", returnType);
            method.put("throwsClause", throwsClause);
            method.put("argDecls", argDecl);
            method.put("modifiers", modifiers3);
            method.put("args", callArgsWithDefaults);
            data.add("defaultMethods", method);
          }
          if (i > 0) {
            argDecl += ", ";
            callArgs += ", ";
          }
          argDecl += types[i] + ' ' + names[i];
          callArgs += names[i];
        }
        Thing method = new Thing("method");
        method.put("name", methodName);
        method.put("returnType", returnType);
        method.put("throwsClause", throwsClause);
        method.put("modifiers", modifiers3);
        method.put("abstract", true);
        method.put("argDecls", argDecl);
        data.add("defaultMethods", method);
      }
    }
    data.put("atLeastOneDefault", atLeastOneDefault);
    if (!atLeastOneDefault) {
      data.setEmpty("defaultMethods");
    }
  }
  private void processSuperclass(Thing data, Map<String, AnnotationValue> beanValues) {
    AnnotationValue value = beanValues.get("superclass");
    data.put("superclass", null);
    data.put("genericDecls", "");
    data.put("classModifiers", "");
    data.put("propertyNameConstantsInherited", false);
    data.put("getPropertyChangeSupportInherited", false);
    data.put("getPropertyChangeSupportModifiers", "protected");
    data.put("paramStringInherited", false);
    data.put("paramStringModifiers", "protected");
    data.put("createPropertyMapInherited", false);
    data.put("createPropertyMapModifiers", "public");
    data.put("atLeastOneDouble", false);
    data.put("atLeastOneBound", false);
    data.put("atLeastOneObject", false);
    data.put("atLeastOneDefault", false);

    if (value == null) {
      data.setEmpty("superclassConstructors");
    } else {
      if (!(value.getValue() instanceof ClassDeclaration)) {
        error(value, "superclass must be a class");
        return;
      }
      ClassDeclaration superclass = (ClassDeclaration) value.getValue();
      data.put("superclass", superclass.getQualifiedName());
      boolean hasProperties = !l(beanValues, "properties").isEmpty();
      // check if getPropertyChangeSupport or some superclass defines bound properties in @Bean
      checkInheritedMethod(
          data,
          "getPropertyChangeSupport",
          "java.beans.PropertyChangeSupport",
          superclass,
          true,
          new InheritCheck() {
            @Override
            public boolean isInherited(Thing d, ClassDeclaration classDeclaration) {
              Bean beanAnn = classDeclaration.getAnnotation(Bean.class);
              if (beanAnn != null) {
                Property[] properties = beanAnn.properties();
                for (Property property : properties) {
                  if (property.bound()) {
                    d.put("getPropertyChangeSupportInherited", true);
                    d.put("getPropertyChangeSupportModifiers", "protected");
                    return true;
                  }
                }
              }
              return false;
            }
          });
      // check if paramString inherited or some superclass has @Bean
      checkInheritedMethod(
          data,
          "paramString",
          "java.lang.String",
          superclass,
          !hasProperties,
          new InheritCheck() {
            @Override
            public boolean isInherited(Thing d, ClassDeclaration classDeclaration) {
              if (classDeclaration.getAnnotation(Bean.class) != null) {
                d.put("paramStringInherited", true);
                d.put("paramStringModifiers", "protected");
                return true;
              }
              return false;
            }
          });
      // check if createPropertyMap inherited or some superclass has @Bean with
      // defineCreatePropertyMap
      checkInheritedMethod(
          data,
          "createPropertyMap",
          "java.lang.String",
          superclass,
          !hasProperties,
          new InheritCheck() {
            @Override
            public boolean isInherited(Thing d, ClassDeclaration classDeclaration) {
              Bean beanAnn = classDeclaration.getAnnotation(Bean.class);
              if (beanAnn != null && beanAnn.defineCreatePropertyMap()) {
                d.put("createPropertyMapInherited", true);
                d.put("createPropertyMapModifiers", "public");
                return true;
              }
              return false;
            }
          });

      String genericDecls = null;
      Collection<TypeParameterDeclaration> formalTypeParameters2 =
          superclass.getFormalTypeParameters();
      for (TypeParameterDeclaration typeParameterDeclaration : formalTypeParameters2) {
        genericDecls = addWithCommasBetween(genericDecls, typeParameterDeclaration);
      }
      if (genericDecls == null) {
        genericDecls = "";
      } else {
        genericDecls = '<' + genericDecls + '>';
      }
      data.put("genericDecls", genericDecls);

      String classModifiers = "";
      for (Modifier modifier : superclass.getModifiers()) {
        if (!"abstract".equals(modifier.toString())) {
          classModifiers += modifier.toString() + ' ';
        }
      }
      data.put("classModifiers", classModifiers);

      Collection<ConstructorDeclaration> constructors = superclass.getConstructors();
      if (constructors.isEmpty()) {
        data.setEmpty("superclassConstructors");
      } else {
        for (ConstructorDeclaration constructorDeclaration : constructors) {
          data.add("superclassConstructors", setupMethod(constructorDeclaration, false));
        }
      }

      boolean extendPropertyNameConstants = false;
      if (b(beanValues, "definePropertyNameConstants")) {
        // if superclass has a PropertyNameConstants interface or a Bean annotation with
        //     definePropertyNameConstants=true, we need to have our PropertyNameConstants
        //     extend it
        Collection<TypeDeclaration> nestedTypes = superclass.getNestedTypes();
        for (TypeDeclaration typeDeclaration : nestedTypes) {
          if ("PropertyNames".equals(typeDeclaration.getSimpleName())
              && (typeDeclaration instanceof InterfaceDeclaration)) {
            extendPropertyNameConstants = true;
          }
        }
        if (!extendPropertyNameConstants) {
          // check if the superclass is annotated with Bean
          Bean annotation = superclass.getAnnotation(Bean.class);
          if (annotation != null) {
            extendPropertyNameConstants = annotation.definePropertyNameConstants();
          }
        }
      }
      data.put("propertyNameConstantsInherited", extendPropertyNameConstants);
    }
  }