<commit_before>var isDescriptor = require('./isDescriptor')

// This method allows precise addition to or modification of a property on an object.

// Normal property addition through assignment creates properties which show up during property enumeration (for...in loop or Object.keys method), whose values may be changed, and which may be deleted. This method allows these extra details to be changed from their defaults.

// By default, values added using Object.defineProperty() are immutable.

// Property descriptors present in objects come in two main flavors: data descriptors and accessor descriptors. A descriptor must be one of these two flavors; it cannot be both.
// Both data and accessor descriptors are objects.

// They share the following required keys: configurable, enumerable

// A data descriptor is a property that has a value, which may or may not be writable.

// An accessor descriptor is a property described by a getter-setter pair of functions.

// This is extrememly raw.
// obj: object to be mutated
// prop: property to add.
// config: boolean for configurable key or descriptor object
// enumerable: boolean for enumerable key
// a: boolean if data-descriptor (alias for writable key), function if accessor-descriptor (alias for getter function)
// b: a javascript value if data-descriptor (alias for value), function if accessor-descriptor (alias for setter function)

function defineProperty (obj, prop, config, enumerable, a, b) {
  if (typeof config === 'boolean') {
    // defining an accessor descriptor
    if (typeof a === 'function') {
      return Object.defineProperty(obj, prop, {
        configurable: config || false,
        enumerable: enumerable || false,
        get: a,
        set: b
      })
    } else {
      // defining a data descriptor
      return Object.defineProperty(obj, prop, {
        configurable: config || false,
        enumerable: enumerable || false,
        writable: a || false,
        value: b
      })
    }
  } else if (isDescriptor(config)) {
    return Object.defineProperty(obj, prop, config)
  }
}

module.exports = defineProperty<commit_msg>update lang/defineProp -- a refactor<commit_after>var omit                 = require('../object/omit')
var extend               = require('../object/extend')
var hasOwn               = require('../object/hasOwn')
var isBoolean            = require('./isBoolean')
var isFunction           = require('./isFunction')
var isPlainObject        = require('./isPlainObject')
var isDataDescriptor     = require('./isDescriptorData')
var isAccessorDescriptor = require('./isDescriptorAccessor')

// This method allows precise addition to or modification of a property on an object.

// Normal property addition through assignment creates properties which show up during property enumeration (for...in loop or Object.keys method), whose values may be changed, and which may be deleted. This method allows these extra details to be changed from their defaults.

// By default, values added using Object.defineProperty() are immutable.

// Property descriptors present in objects come in two main flavors: data descriptors and accessor descriptors. A descriptor must be one of these two flavors; it cannot be both.
// Both data and accessor descriptors are objects.

// They share the following required keys: configurable, enumerable

// A data descriptor is a property that has a value, which may or may not be writable.

// An accessor descriptor is a property described by a getter-setter pair of functions.

// This is extrememly raw.
// obj: object to be mutated
// prop: property to add.
// config: boolean for configurable key or descriptor object
// enumerable: boolean for enumerable key
// a: boolean if data-descriptor (alias for writable key), function if accessor-descriptor (alias for getter function)
// b: a javascript value if data-descriptor (alias for value), function if accessor-descriptor (alias for setter function)

function defineProperty (obj, prop, config, enumerable, a, b) {
  if (isPlainObject(config)) {
    return Object.defineProperty(obj, prop, definePropDefaults(config))
  }

  if (isBoolean(config)) {
    var configuration = {}
    configuration.configurable = config || false
    configuration.enumerable = enumerable || false

    if (isFunction(a)) {
      configuration.get = a
      configuration.set = b
    } else {
      configuration.writable = a || false
      configuration.value = b
    }

    return Object.defineProperty(obj, prop, configuration)
  }
}

function definePropDefaults (obj) {
  var options = {
    configurable: true,
    enumerable: true,
    writable: false,
    value: undefined,
    get: undefined,
    set: undefined
  }

  if (isDataDescriptor(obj) || hasOwn(obj, 'value')) {
    return extend({}, omit(options, ['get', 'set']), obj)
  }

  if (isAccessorDescriptor(obj) || hasOwn(obj, 'get')) {
    return extend({}, omit(options, ['writable', 'value']), obj)
  }
}

module.exports = defineProperty
{'fraction_non_alphanumeric': 0.09229534510433386, 'fraction_numerical': 0.0, 'mean_word_length': 3.427175843694494, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '1035885', 'n_tokens_mistral': 1276, 'n_tokens_neox': 1243, 'n_words': 555}