// Copyright (c) 2015, 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 dart2js.resolution.result;

import '../constants/expressions.dart';
import '../elements/resolution_types.dart';
import '../elements/elements.dart';
import '../tree/tree.dart';
import '../universe/call_structure.dart' show CallStructure;

enum ResultKind {
  NONE,
  ELEMENT,
  TYPE,
  ASSERT,
  CONSTANT,
  PREFIX,
}

/// The result of resolving a node.
abstract class ResolutionResult {
  const ResolutionResult();

  // TODO(johnniwinther): Remove this factory constructor when `null` is never
  // passed as an element result.
  factory ResolutionResult.forElement(Element element) {
    return element != null ? new ElementResult(element) : const NoneResult();
  }

  ResultKind get kind;
  Node get node => null;
  Element get element => null;
  ResolutionDartType get type => null;
  ConstantExpression get constant => null;
  bool get isConstant => false;
}

/// The prefix of top level or member access, like `prefix.member`,
/// `prefix.Class.member` or `Class.member`.
class PrefixResult extends ResolutionResult {
  final PrefixElement prefix;
  final ClassElement cls;

  PrefixResult(this.prefix, this.cls);

  Element get element => cls != null ? cls : prefix;

  bool get isDeferred => prefix != null && prefix.isDeferred;

  ResultKind get kind => ResultKind.PREFIX;

  String toString() => 'PrefixResult($prefix,$cls)';
}

/// The result for the resolution of a node that points to an [Element].
class ElementResult extends ResolutionResult {
  final Element element;

  ResultKind get kind => ResultKind.ELEMENT;

  ElementResult(this.element) {
    assert(element != null);
  }

  String toString() => 'ElementResult($element)';
}

/// The result for the resolution of a node that points to an
/// [ResolutionDartType].
class TypeResult extends ResolutionResult {
  final ResolutionDartType type;

  TypeResult(this.type) {
    assert(type != null);
  }

  ResultKind get kind => ResultKind.TYPE;

  Element get element => type.element;

  String toString() => 'TypeResult($type)';
}

/// The result for resolving a constant expression.
class ConstantResult extends ResolutionResult {
  final Node node;
  final ConstantExpression constant;
  final Element element;

  /// Creates a result for the [constant] expression. [node] is provided for
  /// error reporting on the constant and [element] is provided if the
  /// expression additionally serves an [Element] like [ElementResult].
  ConstantResult(this.node, this.constant, {this.element});

  bool get isConstant => true;

  ResultKind get kind => ResultKind.CONSTANT;

  String toString() => 'ConstantResult(${constant.toDartText()})';
}

class NoneResult extends ResolutionResult {
  const NoneResult();

  ResultKind get kind => ResultKind.NONE;

  String toString() => 'NoneResult()';
}

/// The result of resolving a list of arguments.
class ArgumentsResult {
  /// The call structure of the arguments.
  final CallStructure callStructure;

  /// The resolutions results for each argument.
  final List<ResolutionResult> argumentResults;

  /// `true` if the arguments are valid as arguments to a constructed constant
  /// expression.
  final bool isValidAsConstant;

  ArgumentsResult(this.callStructure, this.argumentResults,
      {this.isValidAsConstant});

  /// Returns the list of [ConstantExpression]s for each of the arguments. If
  /// [isValidAsConstant] is `false`, `null` is returned.
  List<ConstantExpression> get constantArguments {
    if (!isValidAsConstant) return null;
    return argumentResults.map((ResolutionResult result) {
      return result.constant;
    }).toList();
  }
}
