// 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(compiler.createMessage(
          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;
  }
}