// Copyright (c) 2018, 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.

// @dart = 2.10

import 'package:kernel/ast.dart' as ir;

import '../common.dart';
import '../elements/entities.dart';

/// Returns a textual representation of [node] that include the runtime type and
/// hash code of the node and a one line prefix of the node toString text.
String nodeToDebugString(ir.Node node, [int textLength = 40]) {
  String blockText = node.toString().replaceAll('\n', ' ');
  if (blockText.length > textLength) {
    blockText = blockText.substring(0, textLength - 3) + '...';
  }
  return '(${node.runtimeType}:${node.hashCode})${blockText}';
}

/// Comparator for the canonical order or named parameters.
// TODO(johnniwinther): Remove this when named parameters are sorted in dill.
int namedOrdering(ir.VariableDeclaration a, ir.VariableDeclaration b) {
  return a.name.compareTo(b.name);
}

/// Comparator for the declaration order of parameters.
int nativeOrdering(ir.VariableDeclaration a, ir.VariableDeclaration b) {
  return a.fileOffset.compareTo(b.fileOffset);
}

SourceSpan computeSourceSpanFromTreeNode(ir.TreeNode node) {
  // TODO(johnniwinther): Use [ir.Location] directly as a [SourceSpan].
  Uri uri;
  int offset;
  while (node != null) {
    if (node.fileOffset != ir.TreeNode.noOffset) {
      offset = node.fileOffset;
      // @patch annotations have no location.
      uri = node.location?.file;
      break;
    }
    node = node.parent;
  }
  if (uri != null) {
    return SourceSpan(uri, offset, offset + 1);
  }
  return null;
}

/// Returns the `AsyncMarker` corresponding to `node.asyncMarker`.
AsyncMarker getAsyncMarker(ir.FunctionNode node) {
  switch (node.asyncMarker) {
    case ir.AsyncMarker.Async:
      return AsyncMarker.ASYNC;
    case ir.AsyncMarker.AsyncStar:
      return AsyncMarker.ASYNC_STAR;
    case ir.AsyncMarker.Sync:
      return AsyncMarker.SYNC;
    case ir.AsyncMarker.SyncStar:
      return AsyncMarker.SYNC_STAR;
    case ir.AsyncMarker.SyncYielding:
    default:
      throw UnsupportedError(
          "Async marker ${node.asyncMarker} is not supported.");
  }
}

/// Returns the `Variance` corresponding to `node.variance`.
Variance convertVariance(ir.TypeParameter node) {
  if (node.isLegacyCovariant) return Variance.legacyCovariant;
  switch (node.variance) {
    case ir.Variance.covariant:
      return Variance.covariant;
    case ir.Variance.contravariant:
      return Variance.contravariant;
    case ir.Variance.invariant:
      return Variance.invariant;
    default:
      throw UnsupportedError("Variance ${node.variance} is not supported.");
  }
}

/// Returns `true` if [node] is a null literal or a null constant.
bool isNullLiteral(ir.Expression node) {
  return node is ir.NullLiteral ||
      (node is ir.ConstantExpression && node.constant is ir.NullConstant);
}

/// Kernel encodes a null-aware expression `a?.b` as
///
///     let final #1 = a in #1 == null ? null : #1.b
///
/// [getNullAwareExpression] recognizes such expressions storing the result in
/// a [NullAwareExpression] object.
///
/// [syntheticVariable] holds the synthesized `#1` variable. [expression] holds
/// the `#1.b` expression. [receiver] returns `a` expression. [parent] returns
/// the parent of the let node, i.e. the parent node of the original null-aware
/// expression. [let] returns the let node created for the encoding.
class NullAwareExpression {
  final ir.VariableDeclaration syntheticVariable;
  final ir.Expression expression;

  NullAwareExpression(this.syntheticVariable, this.expression);

  ir.Expression get receiver => syntheticVariable.initializer;

  ir.TreeNode get parent => syntheticVariable.parent.parent;

  ir.Let get let => syntheticVariable.parent;

  @override
  String toString() => let.toString();
}

NullAwareExpression getNullAwareExpression(ir.TreeNode node) {
  if (node is ir.Let) {
    ir.Expression body = node.body;
    if (node.variable.name == null &&
        node.variable.isFinal &&
        body is ir.ConditionalExpression) {
      if (body.condition is ir.EqualsNull) {
        ir.EqualsNull equalsNull = body.condition;
        ir.Expression receiver = equalsNull.expression;
        if (receiver is ir.VariableGet && receiver.variable == node.variable) {
          // We have
          //   let #t1 = e0 in #t1 == null ? null : e1
          return NullAwareExpression(node.variable, body.otherwise);
        }
      }
    }
  }
  return null;
}

/// Check whether [node] is immediately guarded by a
/// [ir.CheckLibraryIsLoaded], and hence the node is a deferred access.
ir.LibraryDependency getDeferredImport(ir.TreeNode node) {
  // Note: this code relies on the CFE generating the code as we expect it here.
  // If one day we optimize away redundant CheckLibraryIsLoaded instructions,
  // we'd need to derive this information directly from the CFE (See #35005),
  ir.TreeNode parent = node.parent;

  // TODO(sigmund): remove when CFE generates the correct tree (#35320). For
  // instance, it currently generates
  //
  //   let _ = check(prefix) in (prefix::field.property)
  //
  // instead of:
  //
  //   (let _ = check(prefix) in prefix::field).property
  if (node is ir.StaticGet || node is ir.ConstantExpression) {
    while (parent is ir.InstanceGet ||
        parent is ir.DynamicGet ||
        parent is ir.InstanceTearOff ||
        parent is ir.FunctionTearOff ||
        parent is ir.InstanceInvocation ||
        parent is ir.InstanceGetterInvocation ||
        parent is ir.DynamicInvocation ||
        parent is ir.FunctionInvocation) {
      parent = parent.parent;
    }
  }

  if (parent is ir.Let) {
    var initializer = parent.variable.initializer;
    if (initializer is ir.CheckLibraryIsLoaded) {
      return initializer.import;
    }
  }
  return null;
}

class _FreeVariableVisitor implements ir.DartTypeVisitor<bool> {
  const _FreeVariableVisitor();

  bool visit(ir.DartType type) {
    if (type != null) return type.accept(this);
    return false;
  }

  bool visitList(List<ir.DartType> types) {
    for (ir.DartType type in types) {
      if (visit(type)) return true;
    }
    return false;
  }

  @override
  bool visitTypedefType(ir.TypedefType node) {
    return visitList(node.typeArguments);
  }

  @override
  bool visitTypeParameterType(ir.TypeParameterType node) {
    return true;
  }

  @override
  bool visitFunctionType(ir.FunctionType node) {
    if (visit(node.returnType)) return true;
    if (visitList(node.positionalParameters)) return true;
    for (ir.NamedType namedType in node.namedParameters) {
      if (visit(namedType.type)) return true;
    }
    return false;
  }

  @override
  bool visitInterfaceType(ir.InterfaceType node) {
    return visitList(node.typeArguments);
  }

  @override
  bool visitExtensionType(ir.ExtensionType node) {
    return visitList(node.typeArguments);
  }

  @override
  bool visitFutureOrType(ir.FutureOrType node) {
    return visit(node.typeArgument);
  }

  @override
  bool visitNeverType(ir.NeverType node) => false;

  @override
  bool visitNullType(ir.NullType node) => false;

  @override
  bool visitVoidType(ir.VoidType node) => false;

  @override
  bool visitDynamicType(ir.DynamicType node) => false;

  @override
  bool visitInvalidType(ir.InvalidType node) => false;

  @override
  bool defaultDartType(ir.DartType node) {
    throw UnsupportedError("FreeVariableVisitor.defaultTypeNode");
  }
}

/// Returns `true` if [type] contains a type variable.
///
/// All type variables (class type variables, generic method type variables,
/// and function type variables) are considered.
bool containsFreeVariables(ir.DartType type) =>
    type.accept(const _FreeVariableVisitor());

/// Returns true if [importUri] corresponds to dart:html and related libraries.
bool _isWebLibrary(Uri importUri) =>
    importUri.isScheme('dart') &&
        (importUri.path == 'html' ||
            importUri.path == 'svg' ||
            importUri.path == 'indexed_db' ||
            importUri.path == 'web_audio' ||
            importUri.path == 'web_gl' ||
            importUri.path == 'web_sql' ||
            importUri.path == 'html_common') ||
    // Mock web library path for testing.
    importUri.path
        .contains('native_null_assertions/web_library_interfaces.dart');

bool nodeIsInWebLibrary(ir.TreeNode node) {
  if (node == null) return false;
  if (node is ir.Library) return _isWebLibrary(node.importUri);
  return nodeIsInWebLibrary(node.parent);
}

bool memberEntityIsInWebLibrary(MemberEntity entity) {
  var importUri = entity?.library?.canonicalUri;
  if (importUri == null) return false;
  return _isWebLibrary(importUri);
}

/// Returns the effective target of a super access of [target].
///
/// If [target] is a concrete mixin stub then the stub target is returned
/// instead of the concrete mixin stub. This is done to avoid unnecessary
/// indirections in super accesses.
///
/// See [ir.ProcedureStubKind.ConcreteMixinStub] for why concrete mixin stubs
/// are inserted in the first place.
ir.Member getEffectiveSuperTarget(ir.Member target) {
  if (target is ir.Procedure) {
    if (target.stubKind == ir.ProcedureStubKind.ConcreteMixinStub) {
      return getEffectiveSuperTarget(target.stubTarget);
    }
  }
  return target;
}
