private void propagate( TypePattern pattern, HashMap<String, SemanticType> environment, HashSet<String> generics, WyalFile.Context context) { SemanticType type = builder.convert(pattern.toSyntacticType(), generics, context); if (pattern instanceof TypePattern.Tuple) { TypePattern.Tuple tt = (TypePattern.Tuple) pattern; for (TypePattern p : tt.patterns) { propagate(p, environment, generics, context); } } if (pattern.var != null) { environment.put(pattern.var, type); } if (pattern.source != null) { SemanticType ct = propagate(pattern.source, environment, generics, context); checkIsSubtype(SemanticType.SetAny, ct, pattern); // TODO: need effective set here SemanticType.Set set_t = (SemanticType.Set) ct; checkIsSubtype(type, set_t.element(), pattern); } if (pattern.constraint != null) { SemanticType ct = propagate(pattern.constraint, environment, generics, context); checkIsSubtype(SemanticType.Bool, ct, pattern); } pattern.attributes().add(new TypeAttribute(type)); }
private static FuzzyBoolean inStar( final TypePattern[] pattern, ResolvableTypeList target, int pi, int ti, final int pLeft, int tLeft, int starsLeft, TypePattern.MatchKind kind, ResolvedType[][] parameterAnnotations) { // invariant: pLeft > 0, so we know we'll run out of stars and find a real char in pattern TypePattern patternChar = pattern[pi]; while (patternChar == TypePattern.ELLIPSIS) { starsLeft--; patternChar = pattern[++pi]; } while (true) { // invariant: if (tLeft > 0) then (ti < target.length) if (pLeft > tLeft) { return FuzzyBoolean.NO; } ResolvedType type = target.getResolved(ti); FuzzyBoolean ff = null; try { if (parameterAnnotations != null) { type.temporaryAnnotationTypes = parameterAnnotations[ti]; } ff = patternChar.matches(type, kind); } finally { type.temporaryAnnotationTypes = null; } if (ff.maybeTrue()) { FuzzyBoolean xx = outOfStar( pattern, target, pi + 1, ti + 1, pLeft - 1, tLeft - 1, starsLeft, kind, parameterAnnotations); if (xx.maybeTrue()) { return ff.and(xx); } } ti++; tLeft--; } }
@Override public String toString() { StringBuffer buf = new StringBuffer(); buf.append("("); for (int i = 0, len = typePatterns.length; i < len; i++) { TypePattern type = typePatterns[i]; if (i > 0) { buf.append(", "); } if (type == TypePattern.ELLIPSIS) { buf.append(".."); } else { buf.append(type.toString()); } } buf.append(")"); return buf.toString(); }
public static TypePatternList read(VersionedDataInputStream s, ISourceContext context) throws IOException { short len = s.readShort(); TypePattern[] arguments = new TypePattern[len]; for (int i = 0; i < len; i++) { arguments[i] = TypePattern.read(s, context); } TypePatternList ret = new TypePatternList(arguments); if (!s.isAtLeast169()) { ret.readLocation(context, s); } return ret; }
private void addNamedVariables( TypePattern pattern, HashMap<String, SemanticType> environment, HashSet<String> generics, WyalFile.Context context) { SemanticType type = builder.convert(pattern.toSyntacticType(), generics, context); if (pattern.var != null) { if (environment.containsKey(pattern.var)) { internalFailure("duplicate variable name encountered", filename, pattern); } environment.put(pattern.var, type); } if (pattern instanceof TypePattern.Tuple) { TypePattern.Tuple st = (TypePattern.Tuple) pattern; for (TypePattern t : st.patterns) { addNamedVariables(t, environment, generics, context); } } pattern.attributes().add(new TypeAttribute(type)); }
public void postRead(ResolvedType enclosingType) { for (int i = 0; i < typePatterns.length; i++) { TypePattern p = typePatterns[i]; p.postRead(enclosingType); } }
public FuzzyBoolean matches( ResolvableTypeList types, TypePattern.MatchKind kind, ResolvedType[][] parameterAnnotations) { int nameLength = types.length; int patternLength = typePatterns.length; int nameIndex = 0; int patternIndex = 0; if (ellipsisCount == 0) { if (nameLength != patternLength) { return FuzzyBoolean.NO; } FuzzyBoolean finalReturn = FuzzyBoolean.YES; while (patternIndex < patternLength) { ResolvedType t = types.getResolved(nameIndex); FuzzyBoolean ret = null; try { if (parameterAnnotations != null) { t.temporaryAnnotationTypes = parameterAnnotations[nameIndex]; } ret = typePatterns[patternIndex].matches(t, kind); } finally { t.temporaryAnnotationTypes = null; } patternIndex++; nameIndex++; if (ret == FuzzyBoolean.NO) { return ret; } if (ret == FuzzyBoolean.MAYBE) { finalReturn = ret; } } return finalReturn; } else if (ellipsisCount == 1) { if (nameLength < patternLength - 1) { return FuzzyBoolean.NO; } FuzzyBoolean finalReturn = FuzzyBoolean.YES; while (patternIndex < patternLength) { TypePattern p = typePatterns[patternIndex++]; if (p == TypePattern.ELLIPSIS) { nameIndex = nameLength - (patternLength - patternIndex); } else { ResolvedType t = types.getResolved(nameIndex); FuzzyBoolean ret = null; try { if (parameterAnnotations != null) { t.temporaryAnnotationTypes = parameterAnnotations[nameIndex]; } ret = p.matches(t, kind); } finally { t.temporaryAnnotationTypes = null; } nameIndex++; if (ret == FuzzyBoolean.NO) { return ret; } if (ret == FuzzyBoolean.MAYBE) { finalReturn = ret; } } } return finalReturn; } else { // System.err.print("match(" + arguments + ", " + types + ") -> "); FuzzyBoolean b = outOfStar( typePatterns, types, 0, 0, patternLength - ellipsisCount, nameLength, ellipsisCount, kind, parameterAnnotations); // System.err.println(b); return b; } }