package me.tomassetti.turin.parser.analysis; import me.tomassetti.jvm.JvmNameUtils; import me.tomassetti.turin.parser.analysis.exceptions.UnsolvedSymbolException; import me.tomassetti.turin.resolvers.SymbolResolver; import me.tomassetti.turin.parser.ast.*; import me.tomassetti.turin.parser.ast.expressions.Expression; import me.tomassetti.turin.parser.ast.properties.PropertyConstraint; import me.tomassetti.turin.parser.ast.properties.PropertyDefinition; import me.tomassetti.turin.parser.ast.properties.PropertyReference; import me.tomassetti.turin.parser.ast.typeusage.TypeUsageNode; import me.tomassetti.turin.typesystem.PrimitiveTypeUsage; import me.tomassetti.turin.typesystem.TypeUsage; import java.util.Collections; import java.util.List; import java.util.Optional; /** * A Property can be derived by a definition in the type (PropertyDefinition) or by a reference (PropertyReference) */ public class Property extends Node { private String name; private TypeUsageNode typeUsage; private Optional<Expression> initialValue; private Optional<Expression> defaultValue; private List<PropertyConstraint> constraints; public List<PropertyConstraint> getConstraints() { return constraints; } public Optional<Expression> getInitialValue() { return initialValue; } public Optional<Expression> getDefaultValue() { return defaultValue; } private Property(String name, TypeUsageNode typeUsage, Optional<Expression> initialValue, Optional<Expression> defaultValue, List<PropertyConstraint> constraints) { if (!JvmNameUtils.isValidJavaIdentifier(name)) { throw new IllegalArgumentException(); } this.name = name; this.typeUsage = typeUsage; this.initialValue = initialValue; this.defaultValue = defaultValue; this.constraints = constraints; } public static Property fromDefinition(PropertyDefinition propertyDefinition) { Property property = new Property(propertyDefinition.getName(), propertyDefinition.getType(), propertyDefinition.getInitialValue(), propertyDefinition.getDefaultValue(), propertyDefinition.getConstraints()); property.setParent(propertyDefinition.getParent()); return property; } public static Property fromReference(PropertyReference propertyReference, SymbolResolver resolver) { Optional<PropertyDefinition> propertyDefinition = resolver.findDefinition(propertyReference); if (!propertyDefinition.isPresent()) { throw new UnsolvedSymbolException(propertyReference); } Property property = new Property(propertyReference.getName(), propertyDefinition.get().getType(), propertyDefinition.get().getInitialValue(), propertyDefinition.get().getDefaultValue(), propertyDefinition.get().getConstraints()); property.setParent(propertyReference.getParent()); return property; } public String getName() { return name; } public TypeUsageNode getTypeUsage() { return typeUsage; } @Override public TypeUsageNode calcType() { return typeUsage; } public static String getterName(TypeUsage typeUsage, String propertyName, SymbolResolver resolver) { String prefix = typeUsage.sameType(PrimitiveTypeUsage.BOOLEAN) ? "is" : "get"; String rest = propertyName.length() > 1 ? propertyName.substring(1) : ""; return prefix + Character.toUpperCase(propertyName.charAt(0)) + rest; } public String getterName(SymbolResolver resolver) { return getterName(getTypeUsage(), getName(), resolver); } public String setterName() { String rest = getName().length() > 1 ? getName().substring(1) : ""; return "set" + Character.toUpperCase(getName().charAt(0)) + rest; } public String fieldName() { return name; } @Override public Iterable<Node> getChildren() { // this is intended return Collections.emptyList(); } public boolean hasDefaultValue() { return defaultValue.isPresent(); } public boolean hasInitialValue() { return initialValue.isPresent(); } }