Interpolation constructor

Interpolation(
  1. Iterable<Object> contents,
  2. Iterable<FileSpan?> spans,
  3. FileSpan span
)

Creates a new Interpolation with the given contents.

The spans must include a FileSpan for each Expression in contents. These spans should generally cover the entire #{} surrounding the expression.

The single span must cover the entire interpolation.

Implementation

Interpolation(Iterable<Object /* String | Expression */ > contents,
    Iterable<FileSpan?> spans, this.span)
    : contents = List.unmodifiable(contents),
      spans = List.unmodifiable(spans) {
  if (spans.length != contents.length) {
    throw ArgumentError.value(
        this.spans, "spans", "Must be the same length as contents.");
  }

  for (var i = 0; i < this.contents.length; i++) {
    var isString = this.contents[i] is String;
    if (!isString && this.contents[i] is! Expression) {
      throw ArgumentError.value(this.contents, "contents",
          "May only contain Strings or Expressions.");
    } else if (isString) {
      if (i != 0 && this.contents[i - 1] is String) {
        throw ArgumentError.value(
            this.contents, "contents", "May not contain adjacent Strings.");
      } else if (i < spans.length && this.spans[i] != null) {
        throw ArgumentError.value(this.spans, "spans",
            "May not have a value for string elements (at index $i).");
      }
    } else if (i >= spans.length || this.spans[i] == null) {
      throw ArgumentError.value(this.spans, "spans",
          "Must not have a value for expression elements (at index $i).");
    }
  }
}