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

library fasta.formal_parameter_builder;

import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart'
    show FormalParameterKind, FormalParameterKindExtension;
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
import 'package:kernel/ast.dart'
    show DartType, DynamicType, Expression, NullLiteral, VariableDeclaration;

import '../constant_context.dart' show ConstantContext;
import '../kernel/body_builder.dart' show BodyBuilder;
import '../kernel/internal_ast.dart' show VariableDeclarationImpl;
import '../modifier.dart';
import '../scope.dart' show Scope;
import '../source/source_factory_builder.dart';
import '../source/source_field_builder.dart';
import '../source/source_library_builder.dart';
import '../util/helpers.dart' show DelayedActionPerformer;
import 'builder.dart';
import 'class_builder.dart';
import 'constructor_builder.dart';
import 'library_builder.dart';
import 'metadata_builder.dart';
import 'modifier_builder.dart';
import 'named_type_builder.dart';
import 'type_builder.dart';
import 'variable_builder.dart';

abstract class ParameterBuilder {
  /// List of metadata builders for the metadata declared on this parameter.
  List<MetadataBuilder>? get metadata;
  TypeBuilder? get type;

  /// The kind of this parameter, i.e. if it's required, positional optional,
  /// or named optional.
  FormalParameterKind get kind;

  bool get isPositional;
  bool get isRequiredPositional;
  bool get isNamed;
  bool get isRequiredNamed;

  String? get name;

  ParameterBuilder clone(
      List<NamedTypeBuilder> newTypes,
      SourceLibraryBuilder contextLibrary,
      TypeParameterScopeBuilder contextDeclaration);
}

/// A builder for a formal parameter, i.e. a parameter on a method or
/// constructor.
class FormalParameterBuilder extends ModifierBuilderImpl
    implements VariableBuilder, ParameterBuilder {
  static const String noNameSentinel = 'no name sentinel';

  /// List of metadata builders for the metadata declared on this parameter.
  @override
  final List<MetadataBuilder>? metadata;

  @override
  final int modifiers;

  @override
  final TypeBuilder? type;

  @override
  final String name;

  @override
  final Uri? fileUri;

  @override
  final FormalParameterKind kind;

  /// The variable declaration created for this formal parameter.
  @override
  VariableDeclaration? variable;

  /// The first token of the default value, if any.
  ///
  /// This is stored until outlines have been built through
  /// [buildOutlineExpressions].
  Token? initializerToken;

  bool initializerWasInferred = false;

  /// True if the initializer was declared by the programmer.
  bool hasDeclaredInitializer = false;

  final bool isExtensionThis;

  FormalParameterBuilder(this.metadata, this.kind, this.modifiers, this.type,
      this.name, LibraryBuilder? compilationUnit, int charOffset,
      {Uri? fileUri, this.isExtensionThis: false})
      : this.fileUri = fileUri ?? compilationUnit?.fileUri,
        super(compilationUnit, charOffset);

  @override
  String get debugName => "FormalParameterBuilder";

  @override
  bool get isRequiredPositional => kind.isRequiredPositional;

  // TODO(johnniwinther): This was previously named `isOptional` so we might
  // have some uses that intended to use the now existing `isOptional` method.
  bool get isOptionalPositional => !isRequiredPositional;

  @override
  bool get isRequiredNamed => kind.isRequiredNamed;

  @override
  bool get isPositional => kind.isPositional;

  @override
  bool get isNamed => kind.isNamed;

  bool get isOptional => kind.isOptional;

  @override
  bool get isLocal => true;

  bool get isInitializingFormal => (modifiers & initializingFormalMask) != 0;

  bool get isSuperInitializingFormal =>
      (modifiers & superInitializingFormalMask) != 0;

  bool get isCovariantByDeclaration => (modifiers & covariantMask) != 0;

  // An initializing formal parameter might be final without its
  // VariableDeclaration being final. See
  // [ProcedureBuilder.computeFormalParameterInitializerScope]..
  @override
  bool get isAssignable =>
      variable!.isAssignable &&
      !isInitializingFormal &&
      !isSuperInitializingFormal;

  @override
  String get fullNameForErrors => name;

  VariableDeclaration build(
      SourceLibraryBuilder library, int functionNestingLevel) {
    if (variable == null) {
      DartType? builtType = type?.build(library, TypeUse.parameterType);
      variable = new VariableDeclarationImpl(
          name == noNameSentinel ? null : name, functionNestingLevel,
          type: builtType,
          isFinal: isFinal,
          isConst: false,
          isInitializingFormal: isInitializingFormal,
          isCovariantByDeclaration: isCovariantByDeclaration,
          isRequired: isRequiredNamed,
          hasDeclaredInitializer: hasDeclaredInitializer,
          isLowered: isExtensionThis)
        ..fileOffset = charOffset;
    }
    return variable!;
  }

  @override
  ParameterBuilder clone(
      List<NamedTypeBuilder> newTypes,
      SourceLibraryBuilder contextLibrary,
      TypeParameterScopeBuilder contextDeclaration) {
    // TODO(cstefantsova):  It's not clear how [metadata] is used currently,
    // and how it should be cloned.  Consider cloning it instead of reusing it.
    return new FunctionTypeParameterBuilder(metadata, kind,
        type?.clone(newTypes, contextLibrary, contextDeclaration), name);
  }

  FormalParameterBuilder forFormalParameterInitializerScope() {
    // ignore: unnecessary_null_comparison
    assert(variable != null);
    if (isInitializingFormal) {
      return new FormalParameterBuilder(
          metadata,
          kind,
          modifiers | finalMask | initializingFormalMask,
          type,
          name,
          null,
          charOffset,
          fileUri: fileUri,
          isExtensionThis: isExtensionThis)
        ..parent = parent
        ..variable = variable;
    } else if (isSuperInitializingFormal) {
      return new FormalParameterBuilder(
          metadata,
          kind,
          modifiers | finalMask | superInitializingFormalMask,
          type,
          name,
          null,
          charOffset,
          fileUri: fileUri,
          isExtensionThis: isExtensionThis)
        ..parent = parent
        ..variable = variable;
    } else {
      return this;
    }
  }

  void finalizeInitializingFormal(ClassBuilder classBuilder) {
    Builder? fieldBuilder = classBuilder.lookupLocalMember(name);
    if (fieldBuilder is SourceFieldBuilder) {
      variable!.type = fieldBuilder.inferType();
    } else {
      variable!.type = const DynamicType();
    }
  }

  /// Builds the default value from this [initializerToken] if this is a
  /// formal parameter on a const constructor or instance method.
  void buildOutlineExpressions(SourceLibraryBuilder library,
      List<DelayedActionPerformer> delayedActionPerformers) {
    // For modular compilation we need to include default values for optional
    // and named parameters in several cases:
    // * for const constructors to enable constant evaluation,
    // * for instance methods because these might be needed to generated
    //   noSuchMethod forwarders, and
    // * for generative constructors to support forwarding constructors
    //   in mixin applications.
    bool needsDefaultValues = false;
    if (parent is ConstructorBuilder) {
      needsDefaultValues = true;
    } else if (parent is SourceFactoryBuilder) {
      needsDefaultValues = parent!.isFactory && parent!.isConst;
    } else {
      needsDefaultValues = parent!.isClassInstanceMember;
    }
    if (needsDefaultValues) {
      if (initializerToken != null) {
        final ClassBuilder classBuilder = parent!.parent as ClassBuilder;
        Scope scope = classBuilder.scope;
        BodyBuilder bodyBuilder = library.loader
            .createBodyBuilderForOutlineExpression(
                library, classBuilder, this, scope, fileUri!);
        bodyBuilder.constantContext = ConstantContext.required;
        assert(!initializerWasInferred);
        Expression initializer =
            bodyBuilder.parseFieldInitializer(initializerToken!);
        initializer = bodyBuilder.typeInferrer.inferParameterInitializer(
            bodyBuilder, initializer, variable!.type, hasDeclaredInitializer);
        variable!.initializer = initializer..parent = variable;
        library.loader.transformPostInference(
            variable!,
            bodyBuilder.transformSetLiterals,
            bodyBuilder.transformCollections,
            library.library);
        initializerWasInferred = true;
        bodyBuilder.performBacklogComputations(delayedActionPerformers);
      } else if (kind != FormalParameterKind.requiredPositional) {
        // As done by BodyBuilder.endFormalParameter.
        variable!.initializer = new NullLiteral()..parent = variable;
      }
    }
    initializerToken = null;
  }
}

class FunctionTypeParameterBuilder implements ParameterBuilder {
  @override
  final List<MetadataBuilder>? metadata;

  @override
  final FormalParameterKind kind;

  @override
  final TypeBuilder? type;

  @override
  final String? name;

  FunctionTypeParameterBuilder(this.metadata, this.kind, this.type, this.name);

  @override
  ParameterBuilder clone(
      List<NamedTypeBuilder> newTypes,
      SourceLibraryBuilder contextLibrary,
      TypeParameterScopeBuilder contextDeclaration) {
    // TODO(cstefantsova):  It's not clear how [metadata] is used currently,
    // and how it should be cloned.  Consider cloning it instead of reusing it.
    return new FunctionTypeParameterBuilder(metadata, kind,
        type?.clone(newTypes, contextLibrary, contextDeclaration), name);
  }

  @override
  bool get isNamed => kind.isNamed;

  @override
  bool get isRequiredNamed => kind.isRequiredNamed;

  @override
  bool get isPositional => kind.isPositional;

  @override
  bool get isRequiredPositional => kind.isRequiredPositional;
}
