#  File src/library/methods/R/SClasses.R
#  Part of the R package, https://www.R-project.org
#
#  Copyright (C) 1995-2016 The R Core Team
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  A copy of the GNU General Public License is available at
#  https://www.R-project.org/Licenses/

setClass <-
    ## Define Class to be an S4 class.
    function(Class, representation = list(), prototype = NULL,
             contains = character(), validity = NULL, access = list(),
             where = topenv(parent.frame()), version = .newExternalptr(),
             sealed = FALSE, package = getPackageName(where),
             S3methods = FALSE, slots)
{
    oldDef <- getClassDef(Class, where)
    if(is(oldDef, "classRepresentation") && oldDef@sealed)
        stop(gettextf("%s has a sealed class definition and cannot be redefined",
                      dQuote(Class)),
             domain = NA)
    if(!missing(slots)) {
        ## The modern version consistent with reference classes
        ## Arguments slots= and contains= are used, representation must not be
        if(!missing(representation))
            stop("Argument \"representation\" cannot be used if argument \"slots\" is supplied")
        properties <- inferProperties(slots, "slot")
        classDef <- makeClassRepresentation(Class, properties, contains, prototype, package,
                                            validity, access, version, sealed, where = where)
    }
    else if(is(representation, "classRepresentation")) {
        ## supplied a class definition object
        classDef <- representation
        if(!(missing(prototype) && missing(contains) && missing(validity) && missing(access)
             && missing(version) && missing(package)))
            stop("only arguments 'Class' and 'where' can be supplied when argument 'representation' is a 'classRepresentation' object")
        if(length(classDef@package) == 0L)
            classDef@package <- package # the default
    }
    else {
        ## catch the special case of a single class name as the representation
        if(is.character(representation) && length(representation) == 1L &&
           is.null(names(representation)))
            representation <- list(representation)
        slots <- nzchar(allNames(representation))
        superClasses <- c(as.character(representation[!slots]), contains)
        properties <- representation[slots]
        classDef <- makeClassRepresentation(Class, properties, superClasses, prototype, package,
                                            validity, access, version, sealed, where = where)
    }
    superClasses <- names(classDef@contains)
    classDef <- completeClassDefinition(Class, classDef, where, doExtends = FALSE)
    ## uncache an old definition for this package, if one is cached
    .uncacheClass(Class, classDef)
    if(length(superClasses) > 0L) {
        sealed <- classDef@sealed
        classDef@sealed <- FALSE # to allow setIs to work anyway; will be reset later
        assignClassDef(Class, classDef, where)
        badContains <- character()
### FIXME: need to iterate over contains, not superclass to get
### package for getClassDef()
        for(class2 in superClasses) {
            if(is(try(setIs(Class, class2, classDef = classDef, where = where)), "try-error"))
                badContains <- c(badContains, class2)
            else { # update class definition
                classDef <- getClassDef(Class, where = where)
                if(is.null(classDef))
                  stop(sprintf("internal error: definition of class %s not properly assigned",
                                dQuote(Class)),
                       domain = NA)
            }
          }
        if(length(badContains)) {
            msg <- paste(.dQ(badContains), collapse = ", ")
            if(is(try(removeClass(Class, where)), "try-error"))
                stop(gettextf("error in contained classes (%s) for class %s and unable to remove definition from %s",
                              msg, dQuote(Class),
                              sQuote(getPackageName(where))),
                     domain = NA)
            if(is.null(oldDef))
                stop(gettextf("error in contained classes (%s) for class %s; class definition removed from %s",
                              msg, dQuote(Class),
                              sQuote(getPackageName(where))),
                     domain = NA)
            else if(is(try(setClass(Class, oldDef, where=where)), "try-error"))
                stop(gettextf("error in contained classes (%s) for class %s and unable to restore previous definition from %s",
                              msg, dQuote(Class),
                              sQuote(getPackageName(where))),
                     domain = NA)
            else
                stop(gettextf("error in contained classes (%s) for class %s; previous definition restored to %s",
                              msg, dQuote(Class),
                              sQuote(getPackageName(where))),
                     domain = NA)
        }
        if(length(attr(classDef@contains, "conflicts")) > 0)
          .reportSuperclassConflicts(Class, classDef@contains, where)
        .checkRequiredGenerics(Class, classDef, where)
        if(sealed) {
            classDef@sealed <- TRUE
        }
    }
    if(S3methods)
      classDef <- .setS3MethodsOn(classDef)
    assignClassDef(Class, classDef, where)
    invisible(classGeneratorFunction(classDef, where))
}

representation <-
  ## Representation of a class; that is,
  ## a list of named slots and unnamed classes to be included in a class
  ## definition.
  function(...)
{
    value <- list(...)
    ## unlike the S-Plus function, this does not form the class representation,
    ## since set SClass works separately with the slots and extends arguments.
    anames <- allNames(value)
    for(i in seq_along(value)) {
        ei <- value[[i]]
        if(!is.character(ei) || length(ei) != 1L)
            stop(gettextf("element %d of the representation was not a single character string", i), domain = NA)
    }
    includes <- as.character(value[!nzchar(anames)])
    if(anyDuplicated(includes))
        stop(gettextf("duplicate class names among superclasses: %s",
                      paste(.dQ(includes[duplicated(includes)]),
                            collapse = ", ")),
             domain = NA)
    slots <- anames[nzchar(anames)]
    if(anyDuplicated(slots)) {
        dslots <- slots[duplicated(slots)]
        stop(sprintf(ngettext(length(dslots),
                              "duplicated slot name: %s",
                              "duplicated slot names: %s"),
                     paste(sQuote(dslots), collapse="")),
             domain = NA)
    }
    value
}

### the version called prototype is the external interface.  But functions with argument
### named prototype in R cannot call the prototype function (until there is a methods namespace
### to allow methods::prototype(...)
prototype <- function(...)
    .prototype(...)

.prototype <- function(...) {
    props <- list(...)
    names <- allNames(props)
    data <- !nzchar(names)
    dataPart <- any(data)
    if(dataPart) {
        if(sum(data) > 1)
            stop("only one data object (unnamed argument to prototype) allowed")
        obj <- unclass(props[[seq_along(data)[data] ]])
        props <- props[!data]
        names <- names[!data]
    }
    else
        obj <- defaultPrototype()
    for(i in seq_along(names))
        slot(obj, names[[i]], FALSE) <- props[[i]]
    new("classPrototypeDef", object = obj, slots = names, dataPart = dataPart)
}

makeClassRepresentation <-
  ## Set the Class Definition.
  ## The formal definition of the class is set according to the arguments.
  ##
  ## Users should call setClass instead of this function.
  function(name, slots = list(), superClasses = character(), prototype = NULL,
	   package, validity = NULL, access = list(), version = .newExternalptr(),
	   sealed = FALSE, virtual = NA, where)
{
    if(any(superClasses %in% .AbnormalTypes))
        superClasses <- .addAbnormalDataType(superClasses)
    if(!is.null(prototype) || length(slots) || length(superClasses)) {
        ## collect information about slots, create prototype if needed
        pp <- reconcilePropertiesAndPrototype(name, slots, prototype, superClasses, where)
        slots <- pp$properties
        prototype <- pp$prototype
    }
    contains <- list()
    if(nzchar(package))
        packageSlot(name) <- package
    for(what in superClasses) {
	whatClassDef <-
	    if(is(what, "classRepresentation"))
		what
	    else if(is.null(packageSlot(what)))
		getClass(what, where = where)
	    else
		getClass(what)
        what <- whatClassDef@className # includes package name as attribute
        ## Create the SClassExtension objects (will be simple, possibly dataPart).
        ## The slots are supplied explicitly, since `name' is currently an undefined class
        contains[[what]] <- makeExtends(name, what, slots = slots,
                                              classDef2 = whatClassDef, package = package)
    }
    validity <- .makeValidityMethod(name, validity)
    if(is.na(virtual)) {
        virtual <- testVirtual(slots, contains, prototype, where)
        if(virtual && !is.na(match("VIRTUAL", superClasses)))
            contains[["VIRTUAL"]] <- NULL
    }
    # new() must return an S4 object, except perhaps for basic classes
    if(!is.null(prototype) && is.na(match(name, .BasicClasses)))
      prototype <- .asS4(prototype)
    if(".S3Class" %in% names(slots))
      prototype <- .addS3Class(name, prototype, contains, where)
    newClassRepresentation(className = name, slots = slots,
                           contains = contains,
                           prototype = prototype,
                           virtual = virtual,
                           validity = validity,
                           access = access,
                           package = package,
                           versionKey = version,
                           sealed = sealed)
}

getClassDef <-
  ## Get the definition of the class supplied as a string.
  function(Class, where = topenv(parent.frame()), package = packageSlot(Class),
           inherits = TRUE)
{
    if(inherits) {
                 value <- .getClassesFromCache(Class)
                 if(is.list(value))
                     value <- .resolveClassList(value, where, package)
    } else
        value <- NULL

    if(is.null(value)) {
	cname <- classMetaName(if(length(Class) > 1L)
			  ## S3 class; almost certainly has no packageSlot,
			  ## but we'll continue anyway
			  Class[[1L]] else Class)
	## a string with a package slot strongly implies the class definition
	## should be in that package.
        if(is.character(where)) {
            package <- where
        }

        if(isTRUE(nzchar(package))) {
	    package <- .requirePackage(package)
        }
        if (is.environment(package)) {
            value <- get0(cname, package, inherits = inherits)
        }
	if(is.null(value))
	    value <- get0(cname, where, inherits = inherits) # NULL if not existing
    }
    value
}

getClass <-
  ## Get the complete definition of the class supplied as a string,
  ## including all slots, etc. in classes that this class extends.
  function(Class, .Force = FALSE,
	   where = .classEnv(Class, topenv(parent.frame()), FALSE))
{
    value <- getClassDef(Class, where)
    if(is.null(value)) {
            if(!.Force)
                stop(gettextf("%s is not a defined class",
                              dQuote(Class)),
                     domain = NA)
            else
                value <- makeClassRepresentation(Class, package = "base",
                                                 virtual = TRUE, where = where)
    }
    value
}

slot <-
  ## Get the value of the named slot.  This function does exact, not partial, matching of names,
  ## and the name must be one of the slot names specified in the class's definition.
  ##
  ## Because slots are stored as attributes, the validity check is not 100% guaranteed,
  ## but should be OK if nobody has "cheated" (e.g., by setting other attributes directly).
  function(object, name)
    .Call(C_R_get_slot, object, name)

"slot<-" <-
  ## Set the value of the named slot.  Must be one of the slots in the class's definition.
  function(object, name, check = TRUE, value) {
      if(check)
          value <- checkSlotAssignment(object, name, value)
      .Call(C_R_set_slot, object, name, value)
      ## currently --> R_do_slot_assign() in ../../../main/attrib.c
  }

## ". - hidden" since one should typically rather use is(), extends() etc:
.hasSlot <- function(object, name)
    .Call(C_R_hasSlot, object, name)

checkSlotAssignment <- function(obj, name, value)
{
    cl <- class(obj)
    ClassDef <- getClass(cl) # fails if cl not a defined class (!)
    slotClass <- ClassDef@slots[[name]]
    if(is.null(slotClass))
        stop(gettextf("%s is not a slot in class %s",
                      sQuote(name), dQuote(cl)),
             domain = NA)
    valueClass <- class(value)
    if(.identC(slotClass, valueClass))
       return(value)
    ## check the value, but be careful to use the definition of the slot's class from
    ## the class environment of obj (change validObject too if a better way is found)
    ok <- possibleExtends(valueClass, slotClass,
                          ClassDef2 = getClassDef(slotClass, where = .classEnv(ClassDef)))
    if(isFALSE(ok))
       stop(gettextf("assignment of an object of class %s is not valid for slot %s in an object of class %s; is(value, \"%s\") is not TRUE",
		     dQuote(valueClass), sQuote(name), dQuote(cl), slotClass),
            domain = NA)
    else if(isTRUE(ok))
        value
    else
       as(value, slotClass, strict=FALSE, ext = ok)
}

## slightly simpler verison to be called from do_attrgets()
checkAtAssignment <- function(cl, name, valueClass)
{
    ClassDef <- getClass(cl) # fails if cl not a defined class (!)
    slotClass <- ClassDef@slots[[name]]
    if(is.null(slotClass))
        stop(gettextf("%s is not a slot in class %s",
                      sQuote(name), dQuote(cl)),
             domain = NA)
    if(.identC(slotClass, valueClass))
       return(TRUE)
    ## check the value, but be careful to use the definition of the slot's class from
    ## the class environment of obj (change validObject too if a better way is found)
    ok <- possibleExtends(valueClass, slotClass,
                          ClassDef2 = getClassDef(slotClass, where = .classEnv(ClassDef)))
    if(isFALSE(ok))
       stop(gettextf("assignment of an object of class %s is not valid for @%s in an object of class %s; is(value, \"%s\") is not TRUE",
		     dQuote(valueClass), sQuote(name), dQuote(cl), slotClass),
            domain = NA)
    TRUE
}

## Now a primitive in base
## "@<-" <-
##    function(object, name, value) {
##      arg <- substitute(name)
##      if(is.name(arg))
##        name <- as.character(arg)
##      "slot<-"(object, name, TRUE, value)
##    }

##  The names of the class's slots.  The argument is either the name
##  of a class, or an object from the relevant class.

## NOTA BENE:  .slotNames() shouldn't be needed,
##             rather slotNames() should be changed (to work like .slotNames())!
slotNames <- function(x)
    if(is(x, "classRepresentation")) names(x@slots) else .slotNames(x)

.slotNames <- function(x)
{
    classDef <- getClassDef(
	if(!isS4(x) && is.character(x) && length(x) == 1L) x else class(x))
    if(is.null(classDef))
	character()
    else
	names(classDef@slots)
}


removeClass <-  function(Class, where = topenv(parent.frame())) {
    if(missing(where)) {
       classEnv <- .classEnv(Class, where, FALSE)
        classWhere <- findClass(Class, where = classEnv)
        if(length(classWhere) == 0L) {
            warning(gettextf("class definition for %s not found (no action taken)",
                             dQuote(Class)),
                    domain = NA)
            return(FALSE)
        }
        if(length(classWhere) > 1L)
	    warning(gettextf(
		"class %s has multiple definitions visible; only the first removed",
                             dQuote(Class)),
                    domain = NA)
        classWhere <- classWhere[[1L]]
    }
    else classWhere <- where
    classDef <- getClassDef(Class, where=classWhere)
    if(length(classDef@subclasses)) {
      subclasses <- names(classDef@subclasses)
      found <- vapply(subclasses, isClass, NA, where = where, USE.NAMES=TRUE)
      for(what in subclasses[found])
          .removeSuperClass(what, Class)
    }
    .removeSuperclassBackRefs(Class, classDef, classWhere)
    .uncacheClass(Class, classDef)
    .undefineMethod("initialize", Class, classWhere)
    what <- classMetaName(Class)
    rm(list=what, pos=classWhere)
    TRUE
}


isClass <-
  ## Is this a formally defined class?
  function(Class, formal=TRUE, where = topenv(parent.frame()))
    ## argument formal is for Splus compatibility & is ignored.  (All classes that
    ## are defined must have a class definition object.)
    !is.null(getClassDef(Class, where))

### TODO   s/Class/._class/  -- in order to allow 'Class' as regular slot name
new <-
  ## Generate an object from the specified class.
  ##
  ## Note that the basic vector classes, `"numeric"', etc. are implicitly defined,
  ## so one can use `new' for these classes.
  ##
  function(Class, ...)
{
    ClassDef <- getClass(Class, where = topenv(parent.frame()))
    value <- .Call(C_new_object, ClassDef)
    initialize(value, ...)
}

getClasses <-
  ## The names of all the classes formally defined on `where'.
  ## If called with no argument, all the classes currently known in the session
  ## (which does not include classes that may be defined on one of the attached
  ## libraries, but have not yet been used in the session).
  function(where = .externalCallerEnv(), inherits = missing(where))
{
    pat <- paste0("^",classMetaName(""))
    if(!is.environment(where)) ## e.g. for "package:stats4"
	where <- as.environment(where)
    if(inherits) {
        evList <- .parentEnvList(where)
        clNames <- character()
        for(ev in evList)
            clNames <- c(clNames, grep(pat, names(ev), value=TRUE))
        clNames <- unique(clNames)
    }
    else
        clNames <- grep(pat, names(where), value=TRUE)
    ## strip off the leading pattern (this implicitly assumes the characters
    ## in classMetaName("") are either "." or not metacharacters
    substring(clNames, nchar(pat, "c"))
}


validObject <- function(object, test = FALSE, complete = FALSE)
{
    Class <- class(object)
    classDef <- getClassDef(Class)
    where <- .classEnv(classDef)
    anyStrings <- function(x) if(isTRUE(x)) character() else x
    ## perform, from bottom up, the default and any explicit validity tests
    ## First, validate the slots.
    errors <- character()
    slotTypes <- classDef@slots
    slotNames <- names(slotTypes)
    attrNames <- c(".Data", ".S3Class", names(attributes(object)))
    if(any(is.na(match(slotNames, attrNames)))) {
        badSlots <- is.na(match(slotNames, attrNames))
	errors <-
	    c(errors,
	      paste("slots in class definition but not in object:",
		    paste0('"', slotNames[badSlots], '"', collapse = ", ")))
        slotTypes <- slotTypes[!badSlots]
        slotNames <- slotNames[!badSlots]
    }
    for(i in seq_along(slotTypes)) {
	classi <- slotTypes[[i]]
	classDefi <- getClassDef(classi, where = where)
	if(is.null(classDefi)) {
	    errors <- c(errors,
			paste0("undefined class for slot \"", slotNames[[i]],
			       "\" (\"", classi, "\")"))
	    next
	}
        namei <- slotNames[[i]]
        sloti <- try(switch(namei,
                            ## .S3Class for S3 objects (e.g., "factor")
                            .S3Class = S3Class(object),
                            slot(object, namei)
                            ), silent = TRUE)
        if(inherits(sloti, "try-error")) {
           errors <- c(errors, sloti)
           next
        }
	## note that the use of possibleExtends is shared with checkSlotAssignment(), in case a
	## future revision improves on it!
	ok <- possibleExtends(class(sloti), classi, ClassDef2 = classDefi)
	if(isFALSE(ok)) {
	    errors <- c(errors,
			paste0("invalid object for slot \"", slotNames[[i]],
			       "\" in class \"", Class,
			       "\": got class \"", class(sloti),
			       "\", should be or extend class \"", classi, "\""))
	    next
	}
	if(!complete)
          next
        errori <- anyStrings(Recall(sloti, TRUE, TRUE))
        if(length(errori)) {
	    errori <- paste0("In slot \"", slotNames[[i]],
			     "\" of class \"", class(sloti), "\": ", errori)
            errors <- c(errors, errori)
        }
    }
    extends <- rev(classDef@contains)
    for(i in seq_along(extends)) {
	exti <- extends[[i]]
	superClass <- exti@superClass
	if(!exti@simple && !is(object, superClass))
	    next ## skip conditional relations that don't hold for this object
	superDef <- getClassDef(superClass, package = packageSlot(exti))
	if(is.null(superDef)) {
	    errors <- c(errors,
			paste0("superclass \"", superClass,
			       "\" not defined in the environment of the object's class"))
	    break
	}
	validityMethod <- superDef@validity
	if(is.function(validityMethod)) {
	    errors <- c(errors, anyStrings(validityMethod(as(object, superClass))))
	    if(length(errors))
		break
	}
    }
    validityMethod <- classDef@validity
    if(length(errors) == 0L && is.function(validityMethod)) {
	errors <- c(errors, anyStrings(validityMethod(object)))
    }
    if(length(errors)) {
	if(test)
	    errors
	else {
	    msg <- gettextf("invalid class %s object", dQuote(Class))
	    if(length(errors) > 1L)
		stop(paste(paste0(msg, ":"),
                           paste(seq_along(errors), errors, sep=": "),
			   collapse = "\n"), domain = NA)
	    else stop(msg, ": ", errors, domain = NA)
	}
    }
    else
	TRUE
}

setValidity <- function(Class, method, where = topenv(parent.frame())) {
    if(isClassDef(Class)) {
	ClassDef <- Class
	Class <- ClassDef@className
    }
    else {
	ClassDef <- getClassDef(Class, where)
    }
    method <- .makeValidityMethod(Class, method)
    if(is.null(method) ||
       (is.function(method) && length(formalArgs(method)) == 1L))
	ClassDef@validity <- method
    else
	stop("validity method must be NULL or a function of one argument")
    ## TO DO:  check the where argument against the package of the class def.
    assignClassDef(Class, ClassDef, where = where)
    resetClass(Class, ClassDef, where = where)
}

getValidity <- function (ClassDef) {
    ## "needed" according to ../man/validObject.Rd
    ClassDef@validity
}


resetClass <- function(Class, classDef, where) {
        if(is(Class, "classRepresentation")) {
            classDef <- Class
            Class <- Class@className
            if(missing(where))
                where <- .classDefEnv(classDef)
        }
        else {
            if(missing(where)) {
                if(missing(classDef))
                    where <- findClass(Class, unique = "resetting the definition")[[1L]]
                else
                    where <- .classDefEnv(classDef)
            }
            if(missing(classDef)) {
                classDef <- getClassDef(Class, where)
                if(is.null(classDef)) {
                    warning(gettextf("class %s not found on %s; 'resetClass' will have no effect",
                                     dQuote(Class),
                                     sQuote(getPackageName(where))),
                            domain = NA)
                    return(classDef)
                }
            }
            else if(!is(classDef, "classRepresentation"))
                stop(gettextf("argument 'classDef' must be a string or a class representation; got an object of class %s",
                              dQuote(class(classDef))),
                     domain = NA)
#            package <- getPackageName(where)
        }
        if(classDef@sealed)
            warning(gettextf("class %s is sealed; 'resetClass' will have no effect",
                             dQuote(Class)),
                    domain = NA)
        else {
            classDef <-  .uncompleteClassDefinition(classDef)
            classDef <- completeClassDefinition(Class, classDef, where)
            assignClassDef(Class, classDef, where)
        }
        classDef
    }

## the (default) initialization:  becomes the default method when the function
## is made a generic by .InitMethodDefinitions

initialize <- function(.Object, ...) {
    args <- list(...)
    if(length(args)) {
        Class <- class(.Object)
        ## the basic classes have fixed definitions
        if(!is.na(match(Class, .BasicClasses)))
            return(newBasic(Class, ...))
        ClassDef <- getClass(Class)
        ## separate the slots, superclass objects
        snames <- allNames(args)
        which <- nzchar(snames)
        elements <- args[which]
        supers <- args[!which]
        thisExtends <- names(ClassDef@contains)
        slotDefs <- ClassDef@slots
        dataPart <- slotDefs[[".Data"]]
        if(is.null(dataPart)) dataPart <- "missing"
        if(length(supers)) {
            for(i in rev(seq_along(supers))) {
                obj <- supers[[i]]
                Classi <- class(obj)
                if(length(Classi) > 1L)
                    Classi <- Classi[[1L]] #possible S3 inheritance
                ## test some cases that let information be copied into the
                ## object, ordered from more to less:  all the slots in the
                ## first two cases, some in the 3rd, just the data part in 4th
                if(.identC(Classi, Class))
                    .Object <- obj
                else if(extends(Classi, Class))
                    .Object <- as(obj, Class, strict=FALSE)
                else if(extends(Class, Classi))
                    as(.Object, Classi) <- obj
                else if(extends(Classi, dataPart))
                    .Object@.Data <- obj
                else {
                    ## is there a class to which we can coerce obj
                    ## that is then among the superclasses of Class?
                    extendsi <- extends(Classi)[-1L]
                    ## look for the common extensions, choose the first
                    ## one in the extensions of Class
                    which <- match(thisExtends, extendsi)
                    which <- seq_along(which)[!is.na(which)]
                    if(length(which)) {
                        Classi <- thisExtends[which[1L]]
###                    was:    as(.Object, Classi) <- as(obj, Classi, strict = FALSE)
                        ## but   as<- does an as(....) to its value argument
                        as(.Object, Classi) <- obj
                    }
                    else
                        stop(gettextf("cannot use object of class %s in new():  class %s does not extend that class",
                                      dQuote(Classi),
                                      dQuote(Class)),
                             domain = NA)
                }
            }
        }
        if(length(elements)) {
            snames <- names(elements)
	    if(anyDuplicated(snames))
                stop(gettextf("duplicated slot names: %s",
                              paste(sQuote(snames[duplicated(snames)]),
                                    collapse = ", ")), domain = NA)
            which  <- match(snames, names(slotDefs))
            if(anyNA(which))
                stop(sprintf(ngettext(sum(is.na(which)),
                                      "invalid name for slot of class %s: %s",
                                      "invalid names for slots of class %s: %s"),
                              dQuote(Class),
                              paste(snames[is.na(which)], collapse=", ")),
                     domain = NA)
            firstTime <- TRUE
            for(i in seq_along(snames)) {
                slotName <- snames[[i]]
                slotClass <- slotDefs[[slotName]]
                slotClassDef <- getClassDef(slotClass,
                                            package = packageSlot(slotClass))
                slotVal <- elements[[i]]
                ## perform non-strict coercion, but leave the error messages for
                ## values not conforming to the slot definitions to validObject(),
                ## hence the check = FALSE argument in the slot assignment
                if(!.identC(class(slotVal), slotClass)
                   && !is.null(slotClassDef) ) {
                    valClass <- class(slotVal)
                    valClassDef <- getClassDef(valClass, package = ClassDef@package)
                    if(!identical(possibleExtends(valClass, slotClass,
                                         valClassDef, slotClassDef), FALSE))
                        slotVal <- as(slotVal, slotClass, strict = FALSE)
                }
                if (firstTime) {
                    ## force a copy of .Object
                    slot(.Object, slotName, check = FALSE) <- slotVal
                    firstTime <- FALSE
                } else {
                    ## XXX: do the assignment in-place
                    "slot<-"(.Object, slotName, check = FALSE, slotVal)
                }
            }
        }
        validObject(.Object)
     }
    .Object
}

findClass <- function(Class, where = topenv(parent.frame()), unique = "") {
    if(is(Class, "classRepresentation")) {
        pkg <- Class@package
        classDef <- Class
        Class <- Class@className
    }
    else {
        pkg <- packageSlot(Class)
        if(is.null(pkg))
	    pkg <- ""
        classDef <- getClassDef(Class, where, pkg)
    }
    where <- if(missing(where) && nzchar(pkg)) .requirePackage(pkg) else as.environment(where)
    what <- classMetaName(Class)
    where <- .findAll(what, where)
    if(length(where) > 1L && nzchar(pkg)) {
        pkgs <- sapply(where, function(db)get(what, db)@package)
        where <- where[match(pkg, pkgs, 0L)]
    }
    else
      pkgs <- pkg
    if(length(where) == 0L) {
        if(is.null(classDef))
            classDef <- getClassDef(Class) # but won't likely succeed over previous
        if(nzchar(unique)) {
            if(is(classDef, "classRepresentation"))
                stop(gettextf("class %s is defined, with package %s, but no corresponding metadata object was found (not exported?)",
                              dQuote(Class),
                              sQuote(classDef@package)),
                     domain = NA)
            else
                stop(gettextf("no definition of %s to use for %s",
                              dQuote(Class),
                              unique),
                     domain = NA)
        }
    }
    else if(length(where) > 1L) {
        pkgs <- sapply(where, getPackageName, create = FALSE)
        ## not all environments need be packages (e.g., imports)
        ## We only try to eliminate duplicate package namespaces
        where <- where[!(nzchar(pkgs) & duplicated(pkgs))]
        if(length(where) > 1L)
            if(nzchar(unique)) {
                pkgs <- base::unique(pkgs)
                where <- where[1L]
                ## problem: 'unique'x is text passed in, so do not translate
                warning(sprintf(ngettext(length(pkgs),
                                         "multiple definition of class %s visible (%s); using the definition\n   in package %s for %s",
                                         "multiple definitions of class %s visible (%s); using the definition\n   in package %s for %s"),
                                dQuote(Class),
                                paste(sQuote(pkgs), collapse = ", "),
                                sQuote(pkgs[[1L]]),
                                unique),
                        domain = NA)
            }
            ## else returns a list of >1 places, for the caller to sort out (e.g., .findOrCopyClass)
    }
    where
}

isSealedClass <- function(Class, where = topenv(parent.frame())) {
    if(is.character(Class))
            Class <- getClass(Class, TRUE, where)
    if(!is(Class, "classRepresentation"))
        FALSE
    else
        Class@sealed
}

sealClass <- function(Class, where = topenv(parent.frame())) {
    if(missing(where))
        where <- findClass(Class, unique = "sealing the class", where = where)
    classDef <- getClassDef(Class, where)
    if(!classDef@sealed) {
        classDef@sealed <- TRUE
        assignClassDef(Class, classDef, where)
    }
    invisible(classDef)
}

## see $RHOME/src/main/duplicate.c for the corresponding datatypes
## not copied by duplicate1
.AbnormalTypes <- c("environment", "name", "externalptr",  "NULL")


.indirectAbnormalClasses <- paste0(".", .AbnormalTypes)
names(.indirectAbnormalClasses) <- .AbnormalTypes

## the types not supported by indirect classes (yet)
.AbnormalTypes <- c(.AbnormalTypes,
                    "special","builtin", "weakref", "bytecode")

.addAbnormalDataType <- function(classes) {
  types <- match(classes, .AbnormalTypes, 0) > 0
  type = classes[types]
  if(length(type) == 0)
    return(classes)
  if(length(type) > 1)
    stop(gettextf("class definition cannot extend more than one of these data types: %s",
		  paste0('"',type, '"', collapse = ", ")),
         domain = NA)
  class <- .indirectAbnormalClasses[type]
  if(is.na(class))
    stop(gettextf("abnormal type %s is not supported as a superclass of a class definition",
                  dQuote(type)),
         domain = NA)
  ## this message USED TO BE PRINTED: reminds programmers that
  ## they will see an unexpected superclass
  ## message(gettextf('Defining type "%s" as a superclass via class "%s"',
  ##                 type, class), domain = NA)
  c(class, classes[!types])
}

.checkRequiredGenerics <- function(Class, classDef, where) {}

..checkRequiredGenerics <- function(Class, classDef, where) {
  ## If any of the superclasses are in the .NeedPrimitiveMethods
  ## list, cache the corresponding generics now and also save their names in
  ## .requireCachedGenerics to be used when the environment
  ## where= is loaded.
  supers <- names(classDef@contains)
  allNeeded <- get(".NeedPrimitiveMethods", envir = .methodsNamespace)
  specials <- names(allNeeded)
  needed <- match(specials, supers, 0L) > 0L
  if(any(needed)) {
    generics <- unique(allNeeded[needed])
    packages <- vapply(generics, function(g) {
        def <- getGeneric(g)
        pkg <- def@package # must be "methods" ?
        cacheGenericsMetaData(g, def, TRUE, where, pkg)
        pkg
    }, character(1))
    previous <- if(exists(".requireCachedGenerics", where, inherits = FALSE))
		      get(".requireCachedGenerics", where) else character()
    packages <- c(attr(previous, "package"), packages)
    gg <- c(previous, generics)
    attr(gg, "package") <- packages
    assign(".requireCachedGenerics", gg, where)
  }
}

.setS3MethodsOn <- function(classDef) {
    ext <- extends(classDef)
    slots <- classDef@slots
    if(is.na(match(".S3Class", names(slots)))) {
        ## add the slot if it's not there
        slots$.S3Class <- getClass("oldClass")@slots$.S3Class
        classDef@slots <- slots
    }
    ## in any case give the prototype the full extends as .S3Class
    proto <- classDef@prototype
    if(is.null(proto)) # simple virtual class--unlikely but valid
        proto <- defaultPrototype()
    attr(proto, ".S3Class") <- ext
    classDef@prototype <- proto
    classDef
  }

multipleClasses <- function(details = FALSE) {
    classes <- as.list(.classTable, all.names=TRUE)
    dups <- Filter(is.list, classes)
    if(details) dups else names(dups)
}

className <- function(class, package) {
    if(is(class, "character")) {
        className <- as.character(class)
        if(missing(package))
            package <- packageSlot(class)
        if(is.null(package)) {
            if(exists(className, envir = .classTable, inherits = FALSE))
                classDef <- get(className, envir = .classTable)
            else {
                classDef <- findClass(className, topenv(parent.frame()))
                if(length(classDef) == 1)
                    classDef <- classDef[[1]]
            }
            ## at this point, classDef is the definition if
            ## unique, otherwise a list of 0 or >1 definitions
            if(is(classDef, "classRepresentation"))
                package <- classDef@package
            else if(length(classDef) > 1L) {
                pkgs <- sapply(classDef, function(cl)cl@package)
                warning(gettextf("multiple class definitions for %s from packages: %s; picking the first",
                                 dQuote(className),
                                 paste(sQuote(pkgs), collapse = ", ")),
                        domain = NA)
                package <- pkgs[[1L]]
            }
            else
                stop(gettextf("no package name supplied and no class definition found for %s",
                              dQuote(className)),
                     domain = NA)
        }
    }
    else if(is(class, classDef)) {
        className <- class@className
        if(missing(package))
            package <- class@package
    }
    new("className", .Data = className, package = package)
}

## bootstrap version before the class is defined
classGeneratorFunction <- function(classDef, env = topenv(parent.frame())) {
    fun <- function(...)NULL
    ## put the class name with package attribute into new()
    body(fun) <- substitute(new(CLASS, ...),
                            list(CLASS = classDef@className))
    environment(fun) <- env
    fun
}

.classGeneratorFunction <- function(classDef, env = topenv(parent.frame())) {
    if(is(classDef, "classRepresentation")) {}
    else if(is(classDef, "character")) {
        if(is.null(packageSlot(classDef)))
            classDef <- getClass(classDef, where = env)
        else
            classDef <- getClass(classDef)
    }
    else
        stop("argument 'classDef' must be a class definition or the name of a class")
    fun <- function(...)NULL
    ## put the class name with package attribute into new()
    body(fun) <- substitute(new(CLASS, ...),
                            list(CLASS = classDef@className))
    environment(fun) <- env
    fun <- as(fun, "classGeneratorFunction")
    fun@className <- classDef@className
    fun@package <- classDef@package
    fun
}

## grammar: 'what' is an adjective, so not plural ....
inferProperties <- function(props, what) {
    .validPropNames <- function(propNames) {
        n <- length(props)
        if(!n)
            return(character())
        else if(is.null(propNames))
            stop(gettextf("No %s names supplied", what),
                 domain = NA, call. = FALSE)
        else if(!all(nzchar(propNames)))
            stop(gettextf("All %s names must be nonempty in:\n(%s)", what,
                          paste(sQuote(propNames), collapse = ", ")),
                 domain = NA, call. = FALSE)
        else if(any(duplicated(propNames))) # NB: not translatable because of plurals
            stop(gettextf("All %s names must be distinct in:\n(%s)", what,
                          paste(sQuote(propNames), collapse = ", ")),
                 domain = NA, call. = FALSE)
        propNames
    }
    if(is.character(props)) {
        propNames <- names(props)
        if(is.null(propNames)) {
            propNames <- .validPropNames(props) # the text is the names
            ## treat as "ANY"
            props <- as.list(rep("ANY", length(props)))
            names(props) <- propNames
        }
        else {
            .validPropNames(propNames)
            props <- as.list(props)
        }
    }
    else if(is.list(props)) {
        if(length(props) > 0) # just validate them
            .validPropNames(names(props))
    }
    else
        stop(gettextf("argument %s must be a list or a character vector; got an object of class %s",
                      dQuote(what), dQuote(class(fields))),
             domain = NA)
    props
}


