// 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.typedefs;

import '../common.dart';
import '../common/resolution.dart';
import '../elements/resolution_types.dart';
import '../elements/elements.dart'
    show FunctionSignature, TypedefElement, TypeVariableElement;
import '../elements/modelx.dart' show ErroneousElementX, TypedefElementX;
import '../tree/tree.dart';
import '../util/util.dart' show Link;
import 'class_hierarchy.dart' show TypeDefinitionVisitor;
import 'registry.dart' show ResolutionRegistry;
import 'scope.dart' show MethodScope, TypeDeclarationScope;
import 'signatures.dart' show SignatureResolver;

class TypedefResolverVisitor extends TypeDefinitionVisitor {
  TypedefElementX get element => enclosingElement;

  TypedefResolverVisitor(Resolution resolution, TypedefElement typedefElement,
      ResolutionRegistry registry)
      : super(resolution, typedefElement, registry);

  visitTypedef(Typedef node) {
    element.computeType(resolution);
    scope = new TypeDeclarationScope(scope, element);
    resolveTypeVariableBounds(node.typeParameters);

    FunctionSignature signature = SignatureResolver.analyze(
        resolution,
        scope,
        null /* typeVariables */,
        node.formals,
        node.returnType,
        element,
        registry,
        defaultValuesError: MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT);
    element.functionSignature = signature;

    scope = new MethodScope(scope, element);
    signature.forEachParameter(addToScope);

    element.aliasCache = signature.type;

    void checkCyclicReference() {
      element.checkCyclicReference(resolution);
    }

    addDeferredAction(element, checkCyclicReference);
  }
}

// TODO(johnniwinther): Replace with a traversal on the AST when the type
// annotations in typedef alias are stored in a [TreeElements] mapping.
class TypedefCyclicVisitor extends BaseDartTypeVisitor {
  final DiagnosticReporter reporter;
  final TypedefElementX element;
  bool hasCyclicReference = false;

  Link<TypedefElement> seenTypedefs = const Link<TypedefElement>();

  int seenTypedefsCount = 0;

  Link<TypeVariableElement> seenTypeVariables =
      const Link<TypeVariableElement>();

  TypedefCyclicVisitor(this.reporter, this.element);

  visitType(ResolutionDartType type, _) {
    // Do nothing.
  }

  visitTypedefType(ResolutionTypedefType type, _) {
    TypedefElementX typedefElement = type.element;
    if (seenTypedefs.contains(typedefElement)) {
      if (!hasCyclicReference && identical(element, typedefElement)) {
        // Only report an error on the checked typedef to avoid generating
        // multiple errors for the same cyclicity.
        hasCyclicReference = true;
        if (seenTypedefsCount == 1) {
          // Direct cyclicity.
          reporter.reportErrorMessage(element, MessageKind.CYCLIC_TYPEDEF,
              {'typedefName': element.name});
        } else if (seenTypedefsCount == 2) {
          // Cyclicity through one other typedef.
          reporter.reportErrorMessage(element, MessageKind.CYCLIC_TYPEDEF_ONE, {
            'typedefName': element.name,
            'otherTypedefName': seenTypedefs.head.name
          });
        } else {
          // Cyclicity through more than one other typedef.
          for (TypedefElement cycle in seenTypedefs) {
            if (!identical(typedefElement, cycle)) {
              reporter.reportErrorMessage(
                  element, MessageKind.CYCLIC_TYPEDEF_ONE, {
                'typedefName': element.name,
                'otherTypedefName': cycle.name
              });
            }
          }
        }
        ErroneousElementX erroneousElement = new ErroneousElementX(
            MessageKind.CYCLIC_TYPEDEF,
            {'typedefName': element.name},
            element.name,
            element);
        element.aliasCache =
            new MalformedType(erroneousElement, typedefElement.aliasCache);
        element.hasBeenCheckedForCycles = true;
      }
    } else {
      seenTypedefs = seenTypedefs.prepend(typedefElement);
      seenTypedefsCount++;
      type.visitChildren(this, null);
      if (!typedefElement.isMalformed) {
        typedefElement.aliasCache.accept(this, null);
      }
      seenTypedefs = seenTypedefs.tail;
      seenTypedefsCount--;
    }
  }

  visitFunctionType(ResolutionFunctionType type, _) {
    type.visitChildren(this, null);
  }

  visitInterfaceType(ResolutionInterfaceType type, _) {
    type.visitChildren(this, null);
  }

  visitTypeVariableType(ResolutionTypeVariableType type, _) {
    TypeVariableElement typeVariableElement = type.element;
    if (seenTypeVariables.contains(typeVariableElement)) {
      // Avoid running in cycles on cyclic type variable bounds.
      // Cyclicity is reported elsewhere.
      return;
    }
    seenTypeVariables = seenTypeVariables.prepend(typeVariableElement);
    typeVariableElement.bound.accept(this, null);
    seenTypeVariables = seenTypeVariables.tail;
  }
}
