// public boolean canAccept( List<ModifiedType> inputTypes, SubstitutionType substitutionType, // List<String> reasons ) public boolean canAccept( SequenceType inputTypes, SubstitutionKind substitutionType, List<TypeCheckException> errors) { if (types.size() != inputTypes.size()) { BaseChecker.addError( errors, Error.INVALID_ASSIGNMENT, "Sequence type " + inputTypes + " does not have the same number of elements as sequence type " + this); return false; } for (int i = 0; i < types.size(); i++) { if (types.get(i) != null) { ModifiedType left = types.get(i); ModifiedType right = inputTypes.get(i); if (!BaseChecker.checkAssignment( left, right, AssignmentType.EQUAL, substitutionType, errors)) return false; } } return true; }
@Override public SequenceType partiallyReplace(List<ModifiedType> values, List<ModifiedType> replacements) { SequenceType temp = new SequenceType(); for (int i = 0; i < types.size(); i++) { ModifiedType type = types.get(i); if (type != null) { SimpleModifiedType dummy = new SimpleModifiedType( type.getType().partiallyReplace(values, replacements), type.getModifiers()); temp.add(dummy); } else temp.add(null); } return temp; }
public boolean canAccept( ModifiedType inputType, SubstitutionKind substitutionType, List<TypeCheckException> errors) { if (substitutionType.equals(SubstitutionKind.BINDING)) { SequenceType input = new SequenceType(); input.add(inputType); return canAccept(input, substitutionType, errors); } else { if (inputType.getType() instanceof SequenceType) return canAccept((SequenceType) inputType.getType(), substitutionType, errors); // for splats for (ModifiedType modifiedType : types) { if (!BaseChecker.checkAssignment( modifiedType, inputType, AssignmentType.EQUAL, substitutionType, errors)) return false; } return true; } }
@Override public boolean isSubtype(Type t) { if (equals(t)) return true; if (t instanceof SequenceType) { SequenceType inputTypes = (SequenceType) t; if (types.size() != inputTypes.size()) return false; for (int i = 0; i < types.size(); i++) { if (types.get(i) != null) { Type inputType = inputTypes.get(i).getType(); Modifiers inputModifiers = inputTypes.get(i).getModifiers(); Type type = types.get(i).getType(); Modifiers modifiers = types.get(i).getModifiers(); if (!type.isSubtype(inputType)) return false; // if either type is immutable, it will work out no matter what // if both are mutable, their modifiers had better both be immutable or both mutable if (!type.getModifiers().isImmutable() && !inputType.getModifiers().isImmutable()) { // inputModifiers = modifiers // if this is immutable, storage reference must be readonly or immutable (temporary // readonly isn't good enough) if (modifiers.isImmutable() && !inputModifiers.isImmutable() && !inputModifiers.isReadonly()) return false; // you can't put a readonly thing into a mutable reference // but you can put a mutable thing into a readonly reference (but not an immutable one) if (modifiers.isReadonly() && !inputModifiers.isReadonly()) return false; if (inputModifiers.isImmutable() && !modifiers.isImmutable()) return false; } if (modifiers.isNullable() && !inputModifiers.isNullable()) return false; } } return true; } else return false; }
@Override public boolean equals(Type type) { if (type == Type.NULL) return true; if (type != null && type instanceof SequenceType) { SequenceType inputTypes = (SequenceType) type; if (types.size() != inputTypes.size()) return false; for (int i = 0; i < types.size(); i++) if (inputTypes.get(i) == null || types.get(i) == null || !inputTypes.get(i).getType().equals(getType(i)) || !inputTypes.get(i).getModifiers().equals(get(i).getModifiers())) return false; return true; } return false; }
public void addParameter(String name, ModifiedType type) { SequenceType parameterTypes = getType(); parameterNames.add(name); parameterTypes.add(type); }