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

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

/// Special bottom type used to signal that an expression or statement does
/// not complete normally. This is the case for instance of throw expressions
/// and return statements.
class DoesNotCompleteType extends ir.NeverType {
  const DoesNotCompleteType() : super.internal(ir.Nullability.nonNullable);

  @override
  String toString() => 'DoesNotCompleteType()';
}

/// Special interface type used to signal that the static type of an expression
/// has precision of a this-expression.
class ThisInterfaceType extends ir.InterfaceType {
  ThisInterfaceType(ir.Class classNode, ir.Nullability nullability,
      [List<ir.DartType>? typeArguments])
      : super(classNode, nullability, typeArguments);

  static from(ir.InterfaceType? type) => type != null
      ? ThisInterfaceType(type.classNode, type.nullability, type.typeArguments)
      : null;

  @override
  String toString() => 'this:${super.toString()}';
}

/// Special interface type used to signal that the static type of an expression
/// is exact, i.e. the runtime type is not a subtype or subclass of the type.
class ExactInterfaceType extends ir.InterfaceType {
  ExactInterfaceType(ir.Class classNode, ir.Nullability nullability,
      [List<ir.DartType>? typeArguments])
      : super(classNode, nullability, typeArguments);

  static from(ir.InterfaceType? type) => type != null
      ? ExactInterfaceType(type.classNode, type.nullability, type.typeArguments)
      : null;

  @override
  String toString() => 'exact:${super.toString()}';
}

/// Base class for computing static types.
///
/// This class uses the visitor pattern to compute the static type that are
/// directly defined by the expression kind.
///
/// Subclasses will compute the static type or use a cache to look up the static
/// type of expression whose static type is not directly defined by the
/// expression kind. For instance method invocations whose static type depend
/// on the static types of the receiver and type arguments and the signature
/// of the targeted procedure.
abstract class StaticTypeBase extends ir.TreeVisitor<ir.DartType> {
  final ir.TypeEnvironment _typeEnvironment;

  StaticTypeBase(this._typeEnvironment);

  ir.TypeEnvironment get typeEnvironment => _typeEnvironment;

  ir.StaticTypeContext get staticTypeContext;

  ThisInterfaceType get thisType;

  @override
  ir.DartType defaultTreeNode(ir.TreeNode node) {
    throw UnsupportedError('Unhandled node $node (${node.runtimeType})');
  }

  ir.DartType visitNode(ir.TreeNode node) => node.accept(this);

  ir.DartType? visitNodeOrNull(ir.TreeNode? node) => node?.accept(this);

  void visitNodes(Iterable<ir.TreeNode> nodes) {
    for (ir.TreeNode node in nodes) {
      visitNode(node);
    }
  }

  @override
  ir.DartType visitAsExpression(ir.AsExpression node) {
    return node.type;
  }

  @override
  ir.DartType visitAwaitExpression(ir.AwaitExpression node) {
    return typeEnvironment.flatten(visitNode(node.operand));
  }

  @override
  ir.DartType visitBoolLiteral(ir.BoolLiteral node) =>
      typeEnvironment.coreTypes.boolNonNullableRawType;

  @override
  ir.DartType visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded node) =>
      typeEnvironment.coreTypes.objectNonNullableRawType;

  @override
  ir.DartType visitStringLiteral(ir.StringLiteral node) =>
      typeEnvironment.coreTypes.stringNonNullableRawType;

  @override
  ir.DartType visitStringConcatenation(ir.StringConcatenation node) {
    return typeEnvironment.coreTypes.stringNonNullableRawType;
  }

  @override
  ir.DartType visitNullLiteral(ir.NullLiteral node) => const ir.NullType();

  @override
  ir.DartType visitIntLiteral(ir.IntLiteral node) =>
      typeEnvironment.coreTypes.intNonNullableRawType;

  @override
  ir.DartType visitDoubleLiteral(ir.DoubleLiteral node) =>
      typeEnvironment.coreTypes.doubleNonNullableRawType;

  @override
  ir.DartType visitSymbolLiteral(ir.SymbolLiteral node) =>
      typeEnvironment.coreTypes.symbolNonNullableRawType;

  @override
  ir.DartType visitListLiteral(ir.ListLiteral node) {
    return typeEnvironment.listType(
        node.typeArgument, ir.Nullability.nonNullable);
  }

  @override
  ir.DartType visitSetLiteral(ir.SetLiteral node) {
    return typeEnvironment.setType(
        node.typeArgument, ir.Nullability.nonNullable);
  }

  @override
  ir.DartType visitMapLiteral(ir.MapLiteral node) {
    return typeEnvironment.mapType(
        node.keyType, node.valueType, ir.Nullability.nonNullable);
  }

  @override
  ir.DartType visitVariableSet(ir.VariableSet node) {
    return visitNode(node.value);
  }

  @override
  ThisInterfaceType visitThisExpression(ir.ThisExpression node) => thisType;

  @override
  ir.DartType visitStaticGet(ir.StaticGet node) => node.target.getterType;

  @override
  ir.DartType visitStaticSet(ir.StaticSet node) {
    return visitNode(node.value);
  }

  @override
  ir.DartType visitSuperPropertySet(ir.SuperPropertySet node) {
    return visitNode(node.value);
  }

  @override
  ir.DartType visitThrow(ir.Throw node) => const DoesNotCompleteType();

  @override
  ir.DartType visitRethrow(ir.Rethrow node) => const DoesNotCompleteType();

  @override
  ir.DartType visitLogicalExpression(ir.LogicalExpression node) =>
      typeEnvironment.coreTypes.boolNonNullableRawType;

  @override
  ir.DartType visitNot(ir.Not node) {
    return typeEnvironment.coreTypes.boolNonNullableRawType;
  }

  @override
  ir.DartType visitConditionalExpression(ir.ConditionalExpression node) {
    return node.staticType;
  }

  @override
  ir.DartType visitIsExpression(ir.IsExpression node) {
    return typeEnvironment.coreTypes.boolNonNullableRawType;
  }

  @override
  ir.DartType visitTypeLiteral(ir.TypeLiteral node) =>
      typeEnvironment.coreTypes.typeNonNullableRawType;

  @override
  ir.DartType visitFunctionExpression(ir.FunctionExpression node) {
    return node.function.computeFunctionType(staticTypeContext.nonNullable);
  }

  @override
  ir.DartType visitLet(ir.Let node) {
    return visitNode(node.body);
  }

  @override
  ir.DartType visitBlockExpression(ir.BlockExpression node) {
    return visitNode(node.value);
  }

  @override
  ir.DartType visitInvalidExpression(ir.InvalidExpression node) =>
      const DoesNotCompleteType();

  @override
  ir.DartType visitLoadLibrary(ir.LoadLibrary node) {
    return typeEnvironment.futureType(
        const ir.DynamicType(), ir.Nullability.nonNullable);
  }

  @override
  ir.DartType visitConstantExpression(ir.ConstantExpression node) {
    // TODO(johnniwinther): Include interface exactness where applicable.
    return node.getStaticType(staticTypeContext);
  }

  @override
  ir.DartType visitEqualsNull(ir.EqualsNull node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitEqualsCall(ir.EqualsCall node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitDynamicInvocation(ir.DynamicInvocation node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitFunctionInvocation(ir.FunctionInvocation node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitLocalFunctionInvocation(ir.LocalFunctionInvocation node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitInstanceInvocation(ir.InstanceInvocation node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitInstanceGetterInvocation(ir.InstanceGetterInvocation node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitFunctionTearOff(ir.FunctionTearOff node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitInstanceTearOff(ir.InstanceTearOff node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitDynamicGet(ir.DynamicGet node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitInstanceGet(ir.InstanceGet node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitDynamicSet(ir.DynamicSet node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitInstanceSet(ir.InstanceSet node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitStaticTearOff(ir.StaticTearOff node) =>
      node.getStaticType(staticTypeContext);
}
<commit_msg>[dart2js] Add == override to Dart2JS ir.InterfaceType subclasses.<commit_after>// Copyright (c) 2017, 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.

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

/// Special bottom type used to signal that an expression or statement does
/// not complete normally. This is the case for instance of throw expressions
/// and return statements.
class DoesNotCompleteType extends ir.NeverType {
  const DoesNotCompleteType() : super.internal(ir.Nullability.nonNullable);

  @override
  String toString() => 'DoesNotCompleteType()';
}

/// Special interface type used to signal that the static type of an expression
/// has precision of a this-expression.
class ThisInterfaceType extends ir.InterfaceType {
  ThisInterfaceType(ir.Class classNode, ir.Nullability nullability,
      [List<ir.DartType>? typeArguments])
      : super(classNode, nullability, typeArguments);

  static from(ir.InterfaceType? type) => type != null
      ? ThisInterfaceType(type.classNode, type.nullability, type.typeArguments)
      : null;

  /// We rely on the [ir.InterfaceType] implementation of [hashCode]. Collisions
  /// should be infrequent enough.
  @override
  bool operator ==(Object other) {
    if (other is! ThisInterfaceType) return false;
    return super == other;
  }

  @override
  String toString() => 'this:${super.toString()}';
}

/// Special interface type used to signal that the static type of an expression
/// is exact, i.e. the runtime type is not a subtype or subclass of the type.
class ExactInterfaceType extends ir.InterfaceType {
  ExactInterfaceType(ir.Class classNode, ir.Nullability nullability,
      [List<ir.DartType>? typeArguments])
      : super(classNode, nullability, typeArguments);

  static from(ir.InterfaceType? type) => type != null
      ? ExactInterfaceType(type.classNode, type.nullability, type.typeArguments)
      : null;

  /// We rely on the [ir.InterfaceType] implementation of [hashCode]. Collisions
  /// should be infrequent enough.
  @override
  bool operator ==(Object other) {
    if (other is! ExactInterfaceType) return false;
    return super == other;
  }

  @override
  String toString() => 'exact:${super.toString()}';
}

/// Base class for computing static types.
///
/// This class uses the visitor pattern to compute the static type that are
/// directly defined by the expression kind.
///
/// Subclasses will compute the static type or use a cache to look up the static
/// type of expression whose static type is not directly defined by the
/// expression kind. For instance method invocations whose static type depend
/// on the static types of the receiver and type arguments and the signature
/// of the targeted procedure.
abstract class StaticTypeBase extends ir.TreeVisitor<ir.DartType> {
  final ir.TypeEnvironment _typeEnvironment;

  StaticTypeBase(this._typeEnvironment);

  ir.TypeEnvironment get typeEnvironment => _typeEnvironment;

  ir.StaticTypeContext get staticTypeContext;

  ThisInterfaceType get thisType;

  @override
  ir.DartType defaultTreeNode(ir.TreeNode node) {
    throw UnsupportedError('Unhandled node $node (${node.runtimeType})');
  }

  ir.DartType visitNode(ir.TreeNode node) => node.accept(this);

  ir.DartType? visitNodeOrNull(ir.TreeNode? node) => node?.accept(this);

  void visitNodes(Iterable<ir.TreeNode> nodes) {
    for (ir.TreeNode node in nodes) {
      visitNode(node);
    }
  }

  @override
  ir.DartType visitAsExpression(ir.AsExpression node) {
    return node.type;
  }

  @override
  ir.DartType visitAwaitExpression(ir.AwaitExpression node) {
    return typeEnvironment.flatten(visitNode(node.operand));
  }

  @override
  ir.DartType visitBoolLiteral(ir.BoolLiteral node) =>
      typeEnvironment.coreTypes.boolNonNullableRawType;

  @override
  ir.DartType visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded node) =>
      typeEnvironment.coreTypes.objectNonNullableRawType;

  @override
  ir.DartType visitStringLiteral(ir.StringLiteral node) =>
      typeEnvironment.coreTypes.stringNonNullableRawType;

  @override
  ir.DartType visitStringConcatenation(ir.StringConcatenation node) {
    return typeEnvironment.coreTypes.stringNonNullableRawType;
  }

  @override
  ir.DartType visitNullLiteral(ir.NullLiteral node) => const ir.NullType();

  @override
  ir.DartType visitIntLiteral(ir.IntLiteral node) =>
      typeEnvironment.coreTypes.intNonNullableRawType;

  @override
  ir.DartType visitDoubleLiteral(ir.DoubleLiteral node) =>
      typeEnvironment.coreTypes.doubleNonNullableRawType;

  @override
  ir.DartType visitSymbolLiteral(ir.SymbolLiteral node) =>
      typeEnvironment.coreTypes.symbolNonNullableRawType;

  @override
  ir.DartType visitListLiteral(ir.ListLiteral node) {
    return typeEnvironment.listType(
        node.typeArgument, ir.Nullability.nonNullable);
  }

  @override
  ir.DartType visitSetLiteral(ir.SetLiteral node) {
    return typeEnvironment.setType(
        node.typeArgument, ir.Nullability.nonNullable);
  }

  @override
  ir.DartType visitMapLiteral(ir.MapLiteral node) {
    return typeEnvironment.mapType(
        node.keyType, node.valueType, ir.Nullability.nonNullable);
  }

  @override
  ir.DartType visitVariableSet(ir.VariableSet node) {
    return visitNode(node.value);
  }

  @override
  ThisInterfaceType visitThisExpression(ir.ThisExpression node) => thisType;

  @override
  ir.DartType visitStaticGet(ir.StaticGet node) => node.target.getterType;

  @override
  ir.DartType visitStaticSet(ir.StaticSet node) {
    return visitNode(node.value);
  }

  @override
  ir.DartType visitSuperPropertySet(ir.SuperPropertySet node) {
    return visitNode(node.value);
  }

  @override
  ir.DartType visitThrow(ir.Throw node) => const DoesNotCompleteType();

  @override
  ir.DartType visitRethrow(ir.Rethrow node) => const DoesNotCompleteType();

  @override
  ir.DartType visitLogicalExpression(ir.LogicalExpression node) =>
      typeEnvironment.coreTypes.boolNonNullableRawType;

  @override
  ir.DartType visitNot(ir.Not node) {
    return typeEnvironment.coreTypes.boolNonNullableRawType;
  }

  @override
  ir.DartType visitConditionalExpression(ir.ConditionalExpression node) {
    return node.staticType;
  }

  @override
  ir.DartType visitIsExpression(ir.IsExpression node) {
    return typeEnvironment.coreTypes.boolNonNullableRawType;
  }

  @override
  ir.DartType visitTypeLiteral(ir.TypeLiteral node) =>
      typeEnvironment.coreTypes.typeNonNullableRawType;

  @override
  ir.DartType visitFunctionExpression(ir.FunctionExpression node) {
    return node.function.computeFunctionType(staticTypeContext.nonNullable);
  }

  @override
  ir.DartType visitLet(ir.Let node) {
    return visitNode(node.body);
  }

  @override
  ir.DartType visitBlockExpression(ir.BlockExpression node) {
    return visitNode(node.value);
  }

  @override
  ir.DartType visitInvalidExpression(ir.InvalidExpression node) =>
      const DoesNotCompleteType();

  @override
  ir.DartType visitLoadLibrary(ir.LoadLibrary node) {
    return typeEnvironment.futureType(
        const ir.DynamicType(), ir.Nullability.nonNullable);
  }

  @override
  ir.DartType visitConstantExpression(ir.ConstantExpression node) {
    // TODO(johnniwinther): Include interface exactness where applicable.
    return node.getStaticType(staticTypeContext);
  }

  @override
  ir.DartType visitEqualsNull(ir.EqualsNull node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitEqualsCall(ir.EqualsCall node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitDynamicInvocation(ir.DynamicInvocation node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitFunctionInvocation(ir.FunctionInvocation node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitLocalFunctionInvocation(ir.LocalFunctionInvocation node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitInstanceInvocation(ir.InstanceInvocation node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitInstanceGetterInvocation(ir.InstanceGetterInvocation node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitFunctionTearOff(ir.FunctionTearOff node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitInstanceTearOff(ir.InstanceTearOff node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitDynamicGet(ir.DynamicGet node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitInstanceGet(ir.InstanceGet node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitDynamicSet(ir.DynamicSet node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitInstanceSet(ir.InstanceSet node) =>
      node.getStaticType(staticTypeContext);

  @override
  ir.DartType visitStaticTearOff(ir.StaticTearOff node) =>
      node.getStaticType(staticTypeContext);
}

{'fraction_non_alphanumeric': 0.09303106633081444, 'fraction_numerical': 0.000559753708368318, 'mean_word_length': 4.4008464328899635, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6072423', 'n_tokens_mistral': 5281, 'n_tokens_neox': 5150, 'n_words': 1194}