// 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 related_types;

import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/core_types.dart';
import 'package:compiler/src/dart_types.dart';
import 'package:compiler/src/diagnostics/messages.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/filenames.dart';
import 'package:compiler/src/resolution/semantic_visitor.dart';
import 'package:compiler/src/tree/tree.dart';
import 'package:compiler/src/universe/call_structure.dart';
import 'package:compiler/src/universe/selector.dart';
import 'package:compiler/src/world.dart';
import 'memory_compiler.dart';

main(List<String> arguments) async {
  if (arguments.isNotEmpty) {
    Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.last));
    CompilationResult result = await runCompiler(
        entryPoint: entryPoint,
        options: [Flags.analyzeOnly, '--categories=Client,Server']);
    if (result.isSuccess) {
      checkRelatedTypes(result.compiler);
    }
  } else {
    print('Usage dart related_types.dart <entry-point>');
  }
}

/// Check all loaded libraries in [compiler] for unrelated types.
void checkRelatedTypes(Compiler compiler) {
  for (LibraryElement library in compiler.libraryLoader.libraries) {
    checkLibraryElement(compiler, library);
  }
}

/// Check [library] for unrelated types.
void checkLibraryElement(Compiler compiler, LibraryElement library) {
  library.forEachLocalMember((Element element) {
    if (element.isClass) {
      ClassElement cls = element;
      cls.forEachLocalMember((MemberElement member) {
        checkMemberElement(compiler, member);
      });
    } else if (!element.isTypedef) {
      checkMemberElement(compiler, element);
    }
  });
}

/// Check [member] for unrelated types.
void checkMemberElement(Compiler compiler, MemberElement member) {
  if (!compiler.enqueuer.resolution.hasBeenResolved(member)) return;

  ResolvedAst resolvedAst = member.resolvedAst;
  RelatedTypesChecker relatedTypesChecker =
      new RelatedTypesChecker(compiler, resolvedAst);
  if (resolvedAst.node != null) {
    compiler.withCurrentElement(member.implementation, () {
      relatedTypesChecker.apply(resolvedAst.node);
    });
  }
}

class RelatedTypesChecker extends TraversalVisitor<DartType, dynamic> {
  final Compiler compiler;
  final ResolvedAst resolvedAst;

  RelatedTypesChecker(this.compiler, ResolvedAst resolvedAst)
      : this.resolvedAst = resolvedAst,
        super(resolvedAst.elements);

  ClassWorld get world => compiler.world;

  CoreTypes get coreTypes => compiler.coreTypes;

  InterfaceType get thisType => resolvedAst.element.enclosingClass.thisType;

  /// Returns `true` if there exists no common subtype of [left] and [right].
  bool hasEmptyIntersection(DartType left, DartType right) {
    if (left == right) return false;
    if (left == null || right == null) return false;
    ClassElement leftClass = const ClassFinder().findClass(left);
    ClassElement rightClass = const ClassFinder().findClass(right);
    if (leftClass != null && rightClass != null) {
      return !world.haveAnyCommonSubtypes(leftClass, rightClass);
    }
    return false;
  }

  /// Checks that there exists a common subtype of [left] and [right] or report
  /// a hint otherwise.
  void checkRelated(Node node, DartType left, DartType right) {
    if (hasEmptyIntersection(left, right)) {
      compiler.reportHint(
          node, MessageKind.NO_COMMON_SUBTYPES, {'left': left, 'right': right});
    }
  }

  /// Check weakly typed collection methods, like `Map.containsKey`,
  /// `Map.containsValue` and `Iterable.contains`.
  void checkDynamicInvoke(
      Node node,
      DartType receiverType,
      List<DartType> argumentTypes,
      Selector selector) {
    if (selector.name == 'containsKey' &&
        selector.callStructure == CallStructure.ONE_ARG) {
      InterfaceType mapType = findMapType(receiverType);
      if (mapType != null) {
        DartType keyType = findMapKeyType(mapType);
        checkRelated(node, keyType, argumentTypes.first);
      }
    } else if (selector.name == 'containsValue' &&
               selector.callStructure == CallStructure.ONE_ARG) {
      InterfaceType mapType = findMapType(receiverType);
      if (mapType != null) {
        DartType valueType = findMapValueType(mapType);
        checkRelated(node, valueType, argumentTypes.first);
      }
    } else if (selector.name == 'contains' &&
               selector.callStructure == CallStructure.ONE_ARG) {
      InterfaceType iterableType = findIterableType(receiverType);
      if (iterableType != null) {
        DartType elementType = findIterableElementType(iterableType);
        checkRelated(node, elementType, argumentTypes.first);
      }
    } else if (selector.name == 'remove' &&
               selector.callStructure == CallStructure.ONE_ARG) {
      InterfaceType mapType = findMapType(receiverType);
      if (mapType != null) {
        DartType keyType = findMapKeyType(mapType);
        checkRelated(node, keyType, argumentTypes.first);
      }
      InterfaceType listType = findListType(receiverType);
      if (listType != null) {
        DartType valueType = findListElementType(listType);
        checkRelated(node, valueType, argumentTypes.first);
      }
    }
  }

  /// Return the interface type implemented by [type] or `null` if no interface
  /// type is implied by [type].
  InterfaceType findInterfaceType(DartType type) {
    return Types.computeInterfaceType(compiler, type);
  }

  /// Returns the supertype of [receiver] that implements [cls], if any.
  InterfaceType findClassType(DartType receiver, ClassElement cls) {
    InterfaceType interfaceType = findInterfaceType(receiver);
    if (interfaceType == null) return null;
    InterfaceType mapType = interfaceType.asInstanceOf(cls);
    if (mapType == null) return null;
    return mapType;
  }

  /// Returns the supertype of [receiver] that implements `Iterable`, if any.
  InterfaceType findIterableType(DartType receiver) {
    return findClassType(receiver, compiler.iterableClass);
  }

  /// Returns the element type of the supertype of [receiver] that implements
  /// `Iterable`, if any.
  DartType findIterableElementType(InterfaceType iterableType) {
    if (iterableType == null) return null;
    return iterableType.typeArguments[0];
  }

  /// Returns the supertype of [receiver] that implements `Map`, if any.
  InterfaceType findMapType(DartType receiver) {
    return findClassType(receiver, compiler.mapClass);
  }

  /// Returns the key type of the supertype of [receiver] that implements
  /// `Map`, if any.
  DartType findMapKeyType(InterfaceType mapType) {
    if (mapType == null) return null;
    return mapType.typeArguments[0];
  }

  /// Returns the value type of the supertype of [receiver] that implements
  /// `Map`, if any.
  DartType findMapValueType(InterfaceType mapType) {
    if (mapType == null) return null;
    return mapType.typeArguments[1];
  }

  /// Returns the supertype of [receiver] that implements `List`, if any.
  InterfaceType findListType(DartType receiver) {
    return findClassType(receiver, compiler.listClass);
  }

  /// Returns the element type of the supertype of [receiver] that implements
  /// `List`, if any.
  DartType findListElementType(InterfaceType listType) {
    if (listType == null) return null;
    return listType.typeArguments[0];
  }

  /// Returns the implied return type of [type] or `dynamic` if no return type
  /// is implied.
  DartType findReturnType(DartType type) {
    if (type is FunctionType) {
      return type.returnType;
    }
    return const DynamicType();
  }

  /// Visits [arguments] and returns the list of their corresponding types.
  List<DartType> findArgumentTypes(NodeList arguments) {
    List<DartType> argumentTypes = <DartType>[];
    for (Node argument in arguments) {
      argumentTypes.add(apply(argument));
    }
    return argumentTypes;
  }

  /// Finds the [MemberSignature] of the [name] property on [type], if any.
  MemberSignature lookupInterfaceMember(DartType type, Name name) {
    InterfaceType interfaceType = findInterfaceType(type);
    if (interfaceType == null) return null;
    return interfaceType.lookupInterfaceMember(name);
  }

  /// Returns the type of an access of the [name] property on [type], or
  /// `dynamic` if no property was found.
  DartType lookupInterfaceMemberAccessType(DartType type, Name name) {
    MemberSignature member = lookupInterfaceMember(type, name);
    if (member == null) return const DynamicType();
    return member.type;
  }

  /// Returns the function type of the [name] property on [type], or
  /// `dynamic` if no property was found.
  FunctionType lookupInterfaceMemberInvocationType(DartType type, Name name) {
    MemberSignature member = lookupInterfaceMember(type, name);
    if (member == null) return null;
    return member.functionType;
  }

  DartType apply(Node node, [_]) {
    DartType type = node.accept(this);
    if (type == null) {
      type = const DynamicType();
    }
    return type;
  }

  @override
  DartType visitEquals(Send node, Node left, Node right, _) {
    DartType leftType = apply(left);
    DartType rightType = apply(right);
    checkRelated(node, leftType, rightType);
    return coreTypes.boolType;
  }

  @override
  DartType visitNotEquals(Send node, Node left, Node right, _) {
    DartType leftType = apply(left);
    DartType rightType = apply(right);
    checkRelated(node, leftType, rightType);
    return coreTypes.boolType;
  }

  @override
  DartType visitIndex(Send node, Node receiver, Node index, _) {
    DartType receiverType = apply(receiver);
    DartType indexType = apply(index);
    InterfaceType mapType = findMapType(receiverType);
    DartType keyType = findMapKeyType(mapType);
    DartType valueType = findMapValueType(mapType);
    checkRelated(index, keyType, indexType);
    return valueType;
  }

  @override
  DartType visitLiteralInt(LiteralInt node) {
    return coreTypes.intType;
  }

  @override
  DartType visitLiteralString(LiteralString node) {
    return coreTypes.stringType;
  }

  @override
  DartType visitLiteralBool(LiteralBool node) {
    return coreTypes.boolType;
  }

  @override
  DartType visitLiteralMap(LiteralMap node) {
    return elements.getType(node);
  }

  @override
  DartType visitLiteralList(LiteralList node) {
    return elements.getType(node);
  }

  @override
  DartType visitLiteralNull(LiteralNull node) {
    return elements.getType(node);
  }

  @override
  DartType visitLocalVariableGet(Send node, LocalVariableElement variable, _) {
    return variable.type;
  }

  @override
  DartType visitLocalFunctionGet(Send node, LocalFunctionElement function, _) {
    return function.type;
  }

  @override
  DartType visitParameterGet(Send node, ParameterElement parameter, _) {
    return parameter.type;
  }

  @override
  DartType visitThisPropertyGet(Send node, Name name, _) {
    return lookupInterfaceMemberAccessType(thisType, name);
  }

  @override
  DartType visitDynamicPropertyGet(Send node, Node receiver, Name name, _) {
    DartType receiverType = apply(receiver);
    return lookupInterfaceMemberAccessType(receiverType, name);
  }

  @override
  DartType visitIfNotNullDynamicPropertyGet(
      Send node, Node receiver, Name name, _) {
    DartType receiverType = apply(receiver);
    return lookupInterfaceMemberAccessType(receiverType, name);
  }

  @override
  DartType visitStaticFieldGet(Send node, FieldElement field, _) {
    return field.type;
  }

  @override
  DartType visitTopLevelFieldGet(Send node, FieldElement field, _) {
    return field.type;
  }

  @override
  DartType visitDynamicPropertyInvoke(
      Send node,
      Node receiver,
      NodeList arguments,
      Selector selector, _) {
    DartType receiverType = apply(receiver);
    List<DartType> argumentTypes = findArgumentTypes(arguments);
    FunctionType methodType = lookupInterfaceMemberInvocationType(
        receiverType, selector.memberName);
    checkDynamicInvoke(node, receiverType, argumentTypes, selector);
    return findReturnType(methodType);
  }

  @override
  DartType visitThisPropertyInvoke(
      Send node,
      NodeList arguments,
      Selector selector, _) {
    DartType receiverType = thisType;
    List<DartType> argumentTypes = findArgumentTypes(arguments);
    FunctionType methodType = lookupInterfaceMemberInvocationType(
        receiverType, selector.memberName);
    checkDynamicInvoke(node, receiverType, argumentTypes, selector);
    return findReturnType(methodType);
  }

  @override
  DartType visitIfNotNullDynamicPropertyInvoke(
      Send node,
      Node receiver,
      NodeList arguments,
      Selector selector, _) {
    DartType receiverType = apply(receiver);
    List<DartType> argumentTypes = findArgumentTypes(arguments);
    FunctionType methodType = lookupInterfaceMemberInvocationType(
        receiverType, selector.memberName);
    checkDynamicInvoke(node, receiverType, argumentTypes, selector);
    return findReturnType(methodType);
  }

  @override
  DartType visitTopLevelFunctionInvoke(
      Send node,
      MethodElement function,
      NodeList arguments,
      CallStructure callStructure, _) {
    apply(arguments);
    return findReturnType(function.type);
  }

  @override
  DartType visitStaticFunctionInvoke(
      Send node,
      MethodElement function,
      NodeList arguments,
      CallStructure callStructure, _) {
    apply(arguments);
    return findReturnType(function.type);
  }
}

/// Computes the [ClassElement] implied by a type.
// TODO(johnniwinther): Handle type variables, function types and typedefs.
class ClassFinder extends BaseDartTypeVisitor<ClassElement, dynamic> {
  const ClassFinder();

  ClassElement findClass(DartType type) => type.accept(this, null);

  @override
  ClassElement visitType(DartType type, _) => null;

  @override
  ClassElement visitInterfaceType(InterfaceType type, _) {
    return type.element;
  }
}