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

// A very simple parser for a subset of DartTypes for use in testing type
// algebra.
library kernel.test.type_parser;

import 'package:kernel/kernel.dart';
import 'package:kernel/text/ast_to_text.dart';

typedef TreeNode TypeEnvironment(String name);

/// [lookupType] should return a [Class] or [TypeParameter].
DartType parseDartType(String type, TreeNode lookupType(String name)) {
  return new DartTypeParser(type, lookupType).parseType();
}

class Token {
  static const int Eof = 0;
  static const int Name = 1;
  static const int Comma = 2;
  static const int LeftAngle = 3; // '<'
  static const int RightAngle = 4; // '>'
  static const int LeftParen = 5;
  static const int RightParen = 6;
  static const int LeftBracket = 7;
  static const int RightBracket = 8;
  static const int LeftBrace = 9;
  static const int RightBrace = 10;
  static const int Arrow = 11; // '=>'
  static const int Colon = 12;
  static const int Ampersand = 13;
  static const int QuestionMark = 14;
  static const int Asterisk = 15;
  static const int Invalid = 100;
}

class DartTypeParser {
  final String string;
  int index = 0;
  String tokenText;
  final TypeEnvironment environment;
  final Map<String, TypeParameter> localTypeParameters =
      <String, TypeParameter>{};

  DartTypeParser(this.string, this.environment);

  TreeNode lookupType(String name) {
    return localTypeParameters[name] ?? environment(name);
  }

  bool isIdentifierChar(int charCode) {
    return 65 <= charCode && charCode <= 90 ||
        97 <= charCode && charCode <= 122 ||
        charCode == 95 || // '_'
        charCode == 36; // '$'
  }

  bool isWhitespaceChar(int charCode) {
    return charCode == 32;
  }

  int next() => string.codeUnitAt(index++);
  int peek() => index < string.length ? string.codeUnitAt(index) : 0;

  void skipWhitespace() {
    while (isWhitespaceChar(peek())) {
      next();
    }
  }

  int scanToken() {
    skipWhitespace();
    if (index >= string.length) return Token.Eof;
    int startIndex = index;
    int x = next();
    if (isIdentifierChar(x)) {
      while (isIdentifierChar(peek())) {
        x = next();
      }
      tokenText = string.substring(startIndex, index);
      return Token.Name;
    } else {
      tokenText = string[index - 1];
      int type = getTokenType(x);
      return type;
    }
  }

  int peekToken() {
    skipWhitespace();
    if (index >= string.length) return Token.Eof;
    return getTokenType(peek());
  }

  int getTokenType(int character) {
    switch (character) {
      case 38:
        return Token.Ampersand;
      case 42:
        return Token.Asterisk;
      case 44:
        return Token.Comma;
      case 60:
        return Token.LeftAngle;
      case 62:
        return Token.RightAngle;
      case 63:
        return Token.QuestionMark;
      case 40:
        return Token.LeftParen;
      case 41:
        return Token.RightParen;
      case 91:
        return Token.LeftBracket;
      case 92:
        return Token.RightBracket;
      case 123:
        return Token.LeftBrace;
      case 125:
        return Token.RightBrace;
      case 58:
        return Token.Colon;
      default:
        if (isIdentifierChar(character)) return Token.Name;
        return Token.Invalid;
    }
  }

  void consumeString(String text) {
    skipWhitespace();
    if (string.startsWith(text, index)) {
      index += text.length;
    } else {
      return fail('Expected token $text');
    }
  }

  Nullability parseOptionalNullability(
      [Nullability defaultNullability = Nullability.nonNullable]) {
    int token = peekToken();
    switch (token) {
      case Token.QuestionMark:
        scanToken();
        return Nullability.nullable;
      case Token.Asterisk:
        scanToken();
        return Nullability.legacy;
      default:
        return defaultNullability;
    }
  }

  DartType parseType() {
    int token = peekToken();
    switch (token) {
      case Token.Name:
        scanToken();
        String name = this.tokenText;
        if (name == '_') return const BottomType();
        if (name == 'void') return const VoidType();
        if (name == 'dynamic') return const DynamicType();
        var target = lookupType(name);
        if (target == null) {
          return fail('Unresolved type $name');
        } else if (target is Class) {
          List<DartType> typeArguments = parseOptionalTypeArgumentList();
          Nullability nullability = parseOptionalNullability();
          return new InterfaceType(target, nullability, typeArguments);
        } else if (target is Typedef) {
          List<DartType> typeArguments = parseOptionalTypeArgumentList();
          Nullability nullability = parseOptionalNullability();
          return new TypedefType(target, nullability, typeArguments);
        } else if (target is TypeParameter) {
          Nullability nullability = parseOptionalNullability(null);
          DartType promotedBound;
          switch (peekToken()) {
            case Token.LeftAngle:
              return fail('Attempt to apply type arguments to a type variable');
            case Token.Ampersand:
              scanToken();
              promotedBound = parseType();
              break;
            default:
              break;
          }
          return new TypeParameterType(
              target,
              nullability ??
                  TypeParameterType.computeNullabilityFromBound(target),
              promotedBound);
        }
        return fail("Unexpected lookup result for $name: $target");

      case Token.LeftParen:
        List<DartType> parameters = <DartType>[];
        List<NamedType> namedParameters = <NamedType>[];
        parseParameterList(parameters, namedParameters);
        consumeString('=>');
        Nullability nullability = parseOptionalNullability();
        var returnType = parseType();
        return new FunctionType(parameters, returnType, nullability,
            namedParameters: namedParameters);

      case Token.LeftAngle:
        var typeParameters = parseAndPushTypeParameterList();
        List<DartType> parameters = <DartType>[];
        List<NamedType> namedParameters = <NamedType>[];
        parseParameterList(parameters, namedParameters);
        consumeString('=>');
        Nullability nullability = parseOptionalNullability();
        var returnType = parseType();
        popTypeParameters(typeParameters);
        return new FunctionType(parameters, returnType, nullability,
            typeParameters: typeParameters, namedParameters: namedParameters);

      default:
        return fail('Unexpected token: $tokenText');
    }
  }

  void parseParameterList(List<DartType> positional, List<NamedType> named) {
    int token = scanToken();
    assert(token == Token.LeftParen);
    token = peekToken();
    while (token != Token.RightParen) {
      var type = parseType(); // Could be a named parameter name.
      token = scanToken();
      if (token == Token.Colon) {
        String name = convertTypeToParameterName(type);
        named.add(new NamedType(name, parseType()));
        token = scanToken();
      } else {
        positional.add(type);
      }
      if (token != Token.Comma && token != Token.RightParen) {
        return fail('Unterminated parameter list');
      }
    }
    named.sort();
  }

  String convertTypeToParameterName(DartType type) {
    if (type is InterfaceType && type.typeArguments.isEmpty) {
      return type.classNode.name;
    } else if (type is TypeParameterType) {
      return type.parameter.name;
    } else {
      return fail('Unexpected colon after $type');
    }
  }

  List<DartType> parseTypeList(int open, int close) {
    int token = scanToken();
    assert(token == open);
    List<DartType> types = <DartType>[];
    token = peekToken();
    while (token != close) {
      types.add(parseType());
      token = scanToken();
      if (token != Token.Comma && token != close) {
        throw fail('Unterminated list');
      }
    }
    return types;
  }

  List<DartType> parseOptionalList(int open, int close) {
    if (peekToken() != open) return null;
    return parseTypeList(open, close);
  }

  List<DartType> parseOptionalTypeArgumentList() {
    return parseOptionalList(Token.LeftAngle, Token.RightAngle);
  }

  void popTypeParameters(List<TypeParameter> typeParameters) {
    typeParameters.forEach(localTypeParameters.remove);
  }

  List<TypeParameter> parseAndPushTypeParameterList() {
    int token = scanToken();
    assert(token == Token.LeftAngle);
    List<TypeParameter> typeParameters = <TypeParameter>[];
    token = peekToken();
    while (token != Token.RightAngle) {
      typeParameters.add(parseAndPushTypeParameter());
      token = scanToken();
      if (token != Token.Comma && token != Token.RightAngle) {
        throw fail('Unterminated type parameter list');
      }
    }
    return typeParameters;
  }

  TypeParameter parseAndPushTypeParameter() {
    var nameTok = scanToken();
    if (nameTok != Token.Name) return fail('Expected a name');
    var typeParameter = new TypeParameter(tokenText);
    if (localTypeParameters.containsKey(typeParameter.name)) {
      return fail('Shadowing a type parameter is not allowed');
    }
    localTypeParameters[typeParameter.name] = typeParameter;
    var next = peekToken();
    if (next == Token.Colon) {
      scanToken();
      typeParameter.bound = parseType();
    } else {
      typeParameter.bound =
          new InterfaceType(lookupType('Object'), Nullability.nullable);
    }
    return typeParameter;
  }

  dynamic fail(String message) {
    throw '$message at index $index';
  }
}

class LazyTypeEnvironment {
  final Map<String, Class> classes = <String, Class>{};
  final Map<String, TypeParameter> typeParameters = <String, TypeParameter>{};
  Library dummyLibrary;
  final Component component = new Component();

  LazyTypeEnvironment() {
    dummyLibrary = new Library(Uri.parse('file://dummy.dart'))
      ..isNonNullableByDefault = true;
    component.libraries.add(dummyLibrary..parent = component);
    dummyLibrary.name = 'lib';
  }

  TreeNode lookup(String name) {
    return name.length == 1
        ? typeParameters.putIfAbsent(
            name,
            () => new TypeParameter(name,
                new InterfaceType(lookupClass('Object'), Nullability.nullable)))
        : lookupClass(name);
  }

  Class lookupClass(String name) {
    return classes.putIfAbsent(name, () => makeClass(name));
  }

  Class makeClass(String name) {
    var class_ = new Class(name: name);
    dummyLibrary.addClass(class_);
    return class_;
  }

  void clearTypeParameters() {
    typeParameters.clear();
  }

  void setupTypeParameters(String typeParametersList) {
    for (var typeParameter
        in new DartTypeParser('<$typeParametersList>', lookup)
            .parseAndPushTypeParameterList()) {
      typeParameters[typeParameter.name] = typeParameter;
    }
  }

  DartType parse(String type) => parseDartType(type, lookup);

  Supertype parseSuper(String type) {
    InterfaceType interfaceType = parse(type);
    return new Supertype(interfaceType.classNode, interfaceType.typeArguments);
  }

  DartType parseFresh(String type) {
    clearTypeParameters();
    return parse(type);
  }

  TypeParameter getTypeParameter(String name) {
    if (name.length != 1) throw 'Type parameter names must have length 1';
    return lookup(name);
  }
}

void main(List<String> args) {
  if (args.length != 1) {
    print('Usage: type_parser TYPE');
  }
  var environment = new LazyTypeEnvironment();
  var type = parseDartType(args[0], environment.lookup);
  var buffer = new StringBuffer();
  new Printer(buffer).writeType(type);
  print(buffer);
}
