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

import 'package:kernel/ast.dart'
    show Constructor, Field, Member, Procedure, ProcedureKind;

import '../builder/builder.dart';
import '../builder/member_builder.dart';
import '../builder/library_builder.dart';

import '../kernel/class_hierarchy_builder.dart'
    show ClassHierarchyBuilder, ClassMember;
import '../kernel/member_covariance.dart';
import '../kernel/kernel_builder.dart'
    show isRedirectingGenerativeConstructorImplementation;

import '../modifier.dart'
    show abstractMask, constMask, externalMask, finalMask, lateMask, staticMask;

import '../problems.dart' show unhandled;

abstract class DillMemberBuilder extends MemberBuilderImpl {
  final int modifiers;

  DillMemberBuilder(Member member, Builder parent)
      : modifiers = computeModifiers(member),
        super(parent, member.fileOffset);

  Member get member;

  Iterable<Member> get exportedMembers => [member];

  String get debugName => "DillMemberBuilder";

  String get name => member.name.text;

  bool get isConstructor => member is Constructor;

  ProcedureKind get kind {
    final Member member = this.member;
    return member is Procedure ? member.kind : null;
  }

  bool get isRegularMethod => identical(ProcedureKind.Method, kind);

  bool get isGetter => identical(ProcedureKind.Getter, kind);

  bool get isSetter => identical(ProcedureKind.Setter, kind);

  bool get isOperator => identical(ProcedureKind.Operator, kind);

  bool get isFactory => identical(ProcedureKind.Factory, kind);

  bool get isRedirectingGenerativeConstructor {
    return isConstructor &&
        isRedirectingGenerativeConstructorImplementation(member);
  }

  bool get isSynthetic {
    final Member member = this.member;
    return member is Constructor && member.isSynthetic;
  }

  @override
  bool get isAssignable => false;

  @override
  void buildMembers(
      LibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
    throw new UnsupportedError('DillMemberBuilder.buildMembers');
  }

  List<ClassMember> _localMembers;
  List<ClassMember> _localSetters;

  @override
  List<ClassMember> get localMembers => _localMembers ??= isSetter
      ? const <ClassMember>[]
      : <ClassMember>[new DillClassMember(this, forSetter: false)];

  @override
  List<ClassMember> get localSetters =>
      _localSetters ??= isSetter || member is Field && member.hasSetter
          ? <ClassMember>[new DillClassMember(this, forSetter: true)]
          : const <ClassMember>[];
}

class DillFieldBuilder extends DillMemberBuilder {
  final Field field;

  DillFieldBuilder(this.field, Builder parent) : super(field, parent);

  Member get member => field;

  @override
  Member get readTarget => field;
  @override
  Member get writeTarget => isAssignable ? field : null;

  @override
  Member get invokeTarget => field;

  bool get isField => true;

  @override
  bool get isAssignable => field.hasSetter;
}

class DillGetterBuilder extends DillMemberBuilder {
  final Procedure procedure;

  DillGetterBuilder(this.procedure, Builder parent)
      : assert(procedure.kind == ProcedureKind.Getter),
        super(procedure, parent);

  Member get member => procedure;

  @override
  Member get readTarget => procedure;

  @override
  Member get writeTarget => null;

  @override
  Member get invokeTarget => procedure;
}

class DillSetterBuilder extends DillMemberBuilder {
  final Procedure procedure;

  DillSetterBuilder(this.procedure, Builder parent)
      : assert(procedure.kind == ProcedureKind.Setter),
        super(procedure, parent);

  Member get member => procedure;

  @override
  Member get readTarget => null;

  @override
  Member get writeTarget => procedure;

  @override
  Member get invokeTarget => null;
}

class DillMethodBuilder extends DillMemberBuilder {
  final Procedure procedure;

  DillMethodBuilder(this.procedure, Builder parent)
      : assert(procedure.kind == ProcedureKind.Method),
        super(procedure, parent);

  Member get member => procedure;

  @override
  Member get readTarget => procedure;

  @override
  Member get writeTarget => null;

  @override
  Member get invokeTarget => procedure;
}

class DillOperatorBuilder extends DillMemberBuilder {
  final Procedure procedure;

  DillOperatorBuilder(this.procedure, Builder parent)
      : assert(procedure.kind == ProcedureKind.Operator),
        super(procedure, parent);

  Member get member => procedure;

  @override
  Member get readTarget => null;

  @override
  Member get writeTarget => null;

  @override
  Member get invokeTarget => procedure;
}

class DillFactoryBuilder extends DillMemberBuilder {
  final Procedure procedure;

  DillFactoryBuilder(this.procedure, Builder parent) : super(procedure, parent);

  Member get member => procedure;

  @override
  Member get readTarget => null;

  @override
  Member get writeTarget => null;

  @override
  Member get invokeTarget => procedure;
}

class DillConstructorBuilder extends DillMemberBuilder {
  final Constructor constructor;

  DillConstructorBuilder(this.constructor, Builder parent)
      : super(constructor, parent);

  @override
  Constructor get member => constructor;

  @override
  Member get readTarget => null;

  @override
  Member get writeTarget => null;

  @override
  Constructor get invokeTarget => constructor;
}

class DillClassMember extends BuilderClassMember {
  @override
  final DillMemberBuilder memberBuilder;

  Covariance _covariance;

  @override
  final bool forSetter;

  DillClassMember(this.memberBuilder, {this.forSetter})
      : assert(forSetter != null);

  @override
  bool get isSourceDeclaration => false;

  @override
  bool get isInternalImplementation {
    Member member = memberBuilder.member;
    return member is Field && member.isInternalImplementation;
  }

  @override
  bool get isProperty =>
      memberBuilder.kind == null ||
      memberBuilder.kind == ProcedureKind.Getter ||
      memberBuilder.kind == ProcedureKind.Setter;

  @override
  bool get isSynthesized {
    Member member = memberBuilder.member;
    return member is Procedure &&
        (member.isMemberSignature ||
            (member.isForwardingStub && !member.isForwardingSemiStub));
  }

  @override
  Member getMember(ClassHierarchyBuilder hierarchy) => memberBuilder.member;

  @override
  Covariance getCovariance(ClassHierarchyBuilder hierarchy) {
    return _covariance ??=
        new Covariance.fromMember(memberBuilder.member, forSetter: forSetter);
  }

  @override
  bool get isFunction => !isProperty;

  @override
  void inferType(ClassHierarchyBuilder hierarchy) {
    // Do nothing; this is only for source members.
  }

  @override
  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
    // Do nothing; this is only for source members.
  }

  @override
  bool isSameDeclaration(ClassMember other) {
    return other is DillClassMember && memberBuilder == other.memberBuilder;
  }

  String toString() => 'DillClassMember($memberBuilder,forSetter=${forSetter})';
}

int computeModifiers(Member member) {
  int modifier = member.isAbstract ? abstractMask : 0;
  modifier |= member.isExternal ? externalMask : 0;
  if (member is Field) {
    modifier |= member.isConst ? constMask : 0;
    modifier |= member.isFinal ? finalMask : 0;
    modifier |= member.isLate ? lateMask : 0;
    modifier |= member.isStatic ? staticMask : 0;
  } else if (member is Procedure) {
    modifier |= member.isConst ? constMask : 0;
    modifier |= member.isStatic ? staticMask : 0;
  } else if (member is Constructor) {
    modifier |= member.isConst ? constMask : 0;
  } else {
    dynamic parent = member.parent;
    unhandled("${member.runtimeType}", "computeModifiers", member.fileOffset,
        Uri.base.resolve(parent.fileUri));
  }
  return modifier;
}
