Beispiel #1
0
RObject *RObjectList::findObjects (const QStringList &path, RObjectSearchMap *matches, const QString &op) {
	RK_TRACE (OBJECTS);
	RK_ASSERT (op == "$");

	if (path.value (1) == "::") {
		RObject *environment = findPackage (path[0]);
		if (!environment) return 0;
		
		return environment->findObjects (path.mid (2), matches, "$");
	} else if (path.value (1) == ":::") {
		RObject *environment = findPackage (path[0]);
		if (environment) environment = static_cast<REnvironmentObject*> (environment)->namespaceEnvironment ();
		if (!environment) environment = orphan_namespaces->findOrphanNamespace (path[0]);
		if (!environment) return 0;

		return environment->findObjects (path.mid (2), matches, "$");
	} else if (path.value (0) == ".GlobalEnv") {
		if (path.length () > 1) return getGlobalEnv ()->findObjects (path.mid (2), matches, "$");
		else if (matches) matches->insert (path.value (0), getGlobalEnv ());	// no return, here: At least one more match will be found in base
		else return getGlobalEnv ();
	}

	// no namespace given. Search all environments for matches
	RObject *found = getGlobalEnv ()->findObjects (path, matches, "$");
	if (found && !matches) return found;
	for (int i = 0; i < childmap.size (); ++i) {
		found = childmap[i]->findObjects (path, matches, "$");
		if (found && !matches) return found;
	}
	return 0;
}
Beispiel #2
0
Value LocalScope::getVar(VarNameRef name) const {
	if (name == "_current") return table;
	if (name == "_super") return parent.getVar("_current");
	if (name == "_global") return getGlobalEnv().getVar("_current");
	JSON::INode *nd = table->getVariable(name);
	if (nd == 0) return parent.getVar(name);
	else return nd;

}
Beispiel #3
0
void RObjectList::updateEnvironments (const QStringList &_env_names, bool force_globalenv_update) {
	RK_TRACE (OBJECTS);

	RObjectMap newchildmap;
	QStringList env_names = _env_names;
	if (!env_names.isEmpty ()) {
		QString dummy = env_names.takeFirst ();
		RK_ASSERT (dummy == ".GlobalEnv");
		if (force_globalenv_update) {
			// for now, we only update the .GlobalEnv. All others we assume to be static
			getGlobalEnv ()->updateFromR (update_chain);
		}
	} else {
		RK_ASSERT (!env_names.isEmpty ());
	}

	// find which items are new, and copy the old ones
	for (int i = 0; i < env_names.count (); ++i) {
		QString name = env_names[i];

		RObject *obj = findChildByName (name);
		if (obj && (i > 0) && (env_names.lastIndexOf (name, i-1) > -1)) {		// duplicate environment names can happen (e.g. if a data.frame is attached multiple times)
			obj = 0;	// only copy the old item once
		}
		if (!obj) {
			obj = createTopLevelEnvironment (name);
			RKGlobals::tracker ()->beginAddObject (obj, this, i);
			childmap.insert (i, obj);
			RKGlobals::tracker ()->endAddObject (obj, this, i);
		}
		newchildmap.insert (i, obj);
	}

	// check which envs have been removed or changed position
	for (int i = 0; i < childmap.size (); ++i) {	// do *not* cache the childmap.size ()! We may change it in the loop.
		RObject *obj = childmap[i];
		int new_pos = newchildmap.indexOf (obj);
		
		if (new_pos < 0) {	// environment is gone
			RK_DEBUG (OBJECTS, DL_INFO, "removing toplevel environment %s from list", obj->getShortName ().toLatin1 ().data ());
			if (RKGlobals::tracker ()->removeObject (obj, 0, true)) --i;
			else (newchildmap.insert (i, obj));
		} else if (new_pos != i) {
			// this call is rather expensive, all in all, but fortunately called very rarely
			moveChild (obj, i, new_pos);
		}
	}

	RK_DO (RK_ASSERT (childmap == newchildmap), OBJECTS, DL_DEBUG);	// this is an expensive assert, hence wrapping it inside RK_DO
}