// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library services.src.correction.source_range_factory;

import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/scanner.dart';
import 'package:analyzer/src/generated/source.dart';


SourceRange rangeElementName(Element element) {
  return new SourceRange(element.nameOffset, element.displayName.length);
}

SourceRange rangeEndEnd(a, b) {
  int offset = a.end;
  var length = b.end - offset;
  return new SourceRange(offset, length);
}

SourceRange rangeEndLength(a, int length) {
  int offset = a is int ? a : a.end;
  return new SourceRange(offset, length);
}

SourceRange rangeEndStart(a, b) {
  int offset = a.end;
  var length = (b is int ? b : b.offset) - offset;
  return new SourceRange(offset, length);
}

SourceRange rangeError(AnalysisError error) {
  return new SourceRange(error.offset, error.length);
}

/**
 * Returns the [SourceRange] of [r] with offset from the given [base].
 */
SourceRange rangeFromBase(SourceRange r, int base) {
  int start = r.offset - base;
  int length = r.length;
  return rangeStartLength(start, length);
}

SourceRange rangeNode(AstNode node) {
  return new SourceRange(node.offset, node.length);
}

SourceRange rangeNodes(List<AstNode> nodes) {
  if (nodes.isEmpty) {
    return new SourceRange(0, 0);
  }
  AstNode first = nodes.first;
  AstNode last = nodes.last;
  return rangeStartEnd(first, last);
}

SourceRange rangeOffsetEnd(o) {
  int offset = o.offset;
  int length = o.end - offset;
  return new SourceRange(offset, length);
}

SourceRange rangeStartEnd(a, b) {
  int offset = a is int ? a : a.offset;
  int end = b is int ? b : b.end;
  var length = end - offset;
  return new SourceRange(offset, length);
}

SourceRange rangeStartLength(a, int length) {
  int offset = a is int ? a : a.offset;
  return new SourceRange(offset, length);
}

SourceRange rangeStartStart(a, b) {
  int offset = a is int ? a : a.offset;
  var length = (b is int ? b : b.offset) - offset;
  return new SourceRange(offset, length);
}

SourceRange rangeToken(Token token) {
  return new SourceRange(token.offset, token.length);
}
