[rkward] rkward/core: Add an options-parameter to RObject::getFullName()

Thomas Friedrichsmeier null at kde.org
Thu Jan 17 09:08:25 GMT 2019


Git commit 3853d1ff360892c05ac97d90e2080d7bd64ea89f by Thomas Friedrichsmeier.
Committed on 17/01/2019 at 09:06.
Pushed by tfry into branch 'master'.

Add an options-parameter to RObject::getFullName()

The immediate benefit is that we can do away with RObject::getBaseName(), and RObject::makeChildBaseName(), including its overrides.
The other benefit is that this should allow to implement configurable completion behavior. Importantly using $ instead of [[ on lists,
but also, e.g., always including package names for objects outside globalenv.

M  +1    -1    rkward/core/rcontainerobject.cpp
M  +10   -16   rkward/core/renvironmentobject.cpp
M  +2    -3    rkward/core/renvironmentobject.h
M  +8    -27   rkward/core/rkpseudoobjects.cpp
M  +6    -9    rkward/core/rkpseudoobjects.h
M  +5    -5    rkward/core/rkrownames.cpp
M  +1    -3    rkward/core/rkrownames.h
M  +8    -14   rkward/core/robject.cpp
M  +7    -5    rkward/core/robject.h
M  +1    -1    rkward/core/robjectlist.cpp
M  +2    -3    rkward/core/robjectlist.h

https://commits.kde.org/rkward/3853d1ff360892c05ac97d90e2080d7bd64ea89f

diff --git a/rkward/core/rcontainerobject.cpp b/rkward/core/rcontainerobject.cpp
index 785b00c0..52a322c7 100644
--- a/rkward/core/rcontainerobject.cpp
+++ b/rkward/core/rcontainerobject.cpp
@@ -277,7 +277,7 @@ RObject *RContainerObject::findObjects (const QStringList &path, RObjectSearchMa
 		for (int i = 0; i < childmap.size (); ++i) {
 			RObject* child = childmap[i];
 			if (partial.isEmpty () || child->getShortName ().startsWith (partial)) {
-				QString base_name = child->getBaseName ();
+				QString base_name = child->getFullName (DefaultObjectNameOptions - (DefaultObjectNameOptions & IncludeEnvirIfNotGlobalEnv));
 				if (matches->contains (base_name) || irregularShortName (base_name)) {
 					matches->insert (child->getFullName (), child);
 				} else {
diff --git a/rkward/core/renvironmentobject.cpp b/rkward/core/renvironmentobject.cpp
index 7d4ba659..a808914d 100644
--- a/rkward/core/renvironmentobject.cpp
+++ b/rkward/core/renvironmentobject.cpp
@@ -61,15 +61,15 @@ QString REnvironmentObject::packageName () const {
 	return name.section (':', 1);
 }
 
-QString REnvironmentObject::getFullName () const {
+QString REnvironmentObject::getFullName (int options) const {
 	RK_TRACE (OBJECTS);
 
 	if (type & GlobalEnv) return name;	// .GlobalEnv
-	if (type & ToplevelEnv) return ("as.environment (" + rQuote (name) + ')');
-	return parent->makeChildName (name, type & Misplaced);
+	if ((type & ToplevelEnv) && (options & IncludeEnvirIfNotGlobalEnv)) return ("as.environment (" + rQuote (name) + ')');
+	return parent->makeChildName (name, type & Misplaced, options);
 }
 
-QString REnvironmentObject::makeChildName (const QString &short_child_name, bool misplaced) const {
+QString REnvironmentObject::makeChildName (const QString &short_child_name, bool misplaced, int options) const {
 	RK_TRACE (OBJECTS);
 
 	QString safe_name;
@@ -84,20 +84,14 @@ QString REnvironmentObject::makeChildName (const QString &short_child_name, bool
 		return (safe_name);
 	}
 	if (type & ToplevelEnv) {
+		if (!(options & IncludeEnvirIfNotGlobalEnv)) return (short_child_name);
 /* Some items are placed outside of their native namespace. E.g. in package:boot item "motor". It can be retrieved using as.environment ("package:boot")$motor. This is extremely ugly. We need to give them (and only them) this special treatment. */
 // TODO: hopefully one day operator "::" will work even in those cases. So check back later, and remove after a sufficient amount of backwards compatibility time
-// NOTE: This appears to have been fixed in R 2.14.0, when all packages were forced to have namespaces.
+// NOTE: This appears to have been fixed in R 2.14.0, when all packages were forced to have namespaces. Currently backend has a version check to set "misplaced", appropriately.
 		if ((type & PackageEnv) && (!misplaced)) return (packageName () + "::" + safe_name);
-		return (getFullName () + '$' + safe_name);
+		return (getFullName (options) + '$' + safe_name);
 	}
-	return (getFullName () + '$' + safe_name);
-}
-
-QString REnvironmentObject::makeChildBaseName (const QString &short_child_name) const {
-	RK_TRACE (OBJECTS);
-
-	if (type & ToplevelEnv) return (short_child_name);
-	return (name + '$' + short_child_name);
+	return (getFullName (options) + '$' + safe_name);
 }
 
 void REnvironmentObject::writeMetaData (RCommandChain *chain) {
@@ -120,7 +114,7 @@ void REnvironmentObject::updateFromR (RCommandChain *chain) {
 	if (type & GlobalEnv) options = ", envlevel=-1";	// in the .GlobalEnv recurse one more level
 	if (type & PackageEnv) options.append (", namespacename=" + rQuote (packageName ()));
 
-	RCommand *command = new RCommand (".rk.get.structure (" + getFullName () + ", " + rQuote (getShortName ()) + options + ')', RCommand::App | RCommand::Sync | RCommand::GetStructuredData, QString (), this, ROBJECT_UDPATE_STRUCTURE_COMMAND);
+	RCommand *command = new RCommand (".rk.get.structure (" + getFullName (DefaultObjectNameOptions) + ", " + rQuote (getShortName ()) + options + ')', RCommand::App | RCommand::Sync | RCommand::GetStructuredData, QString (), this, ROBJECT_UDPATE_STRUCTURE_COMMAND);
 	RKGlobals::rInterface ()->issueCommand (command, chain);
 
 	type |= Updating;
@@ -205,7 +199,7 @@ void REnvironmentObject::updateNamespace (RData* new_data) {
 QString REnvironmentObject::renameChildCommand (RObject *object, const QString &new_name) const {
 	RK_TRACE (OBJECTS);
 
-	return (makeChildName (new_name) + " <- " + object->getFullName () + '\n' + removeChildCommand (object));
+	return (makeChildName (new_name, false, IncludeEnvirIfNotGlobalEnv) + " <- " + object->getFullName () + '\n' + removeChildCommand (object));
 }
 
 QString REnvironmentObject::removeChildCommand (RObject *object) const {
diff --git a/rkward/core/renvironmentobject.h b/rkward/core/renvironmentobject.h
index 3a13e879..3577aa54 100644
--- a/rkward/core/renvironmentobject.h
+++ b/rkward/core/renvironmentobject.h
@@ -36,9 +36,8 @@ public:
 /** like updateFromR, but only update new / removed symbols from R. Theoretically this could be defined in RContainerObject, but the only use case is for environments. */
 	virtual void updateFromR (RCommandChain *chain, const QStringList &current_symbols);
 
-	QString getFullName () const override;
-	QString makeChildName (const QString &short_child_name, bool misplaced=false) const override;
-	QString makeChildBaseName (const QString &short_child_name) const override;
+	QString getFullName (int) const override;
+	QString makeChildName (const QString &short_child_name, bool misplaced, int options) const override;
 /** reimplemented from RContainerObject: If this is an environment var, call RContainerObject::writeMetaData (). Else, do nothing. An environment has no meta data. */
 	void writeMetaData (RCommandChain *chain) override;
 	QString packageName () const;
diff --git a/rkward/core/rkpseudoobjects.cpp b/rkward/core/rkpseudoobjects.cpp
index 52b0d500..4e9281fb 100644
--- a/rkward/core/rkpseudoobjects.cpp
+++ b/rkward/core/rkpseudoobjects.cpp
@@ -32,26 +32,18 @@ RSlotsPseudoObject::~RSlotsPseudoObject () {
 	pseudo_object_types.remove (this);
 }
 
-QString RSlotsPseudoObject::getFullName () const {
+QString RSlotsPseudoObject::getFullName (int options) const {
 	RK_TRACE (OBJECTS);
 
-	return (".rk.get.slots (" + parent->getFullName () + ')');
+	return (".rk.get.slots (" + parent->getFullName (options) + ')');
 }
 
-QString RSlotsPseudoObject::makeChildName (const QString &short_child_name, bool) const {
+QString RSlotsPseudoObject::makeChildName (const QString &short_child_name, bool, int options) const {
 	RK_TRACE (OBJECTS);
 
 	QString safe_name = short_child_name;
 	if (irregularShortName (safe_name)) safe_name = rQuote (short_child_name);
-	return (parent->getFullName () + '@' + safe_name);
-}
-
-QString RSlotsPseudoObject::makeChildBaseName (const QString &short_child_name) const {
-	RK_TRACE (OBJECTS);
-
-	QString safe_name = short_child_name;
-	if (irregularShortName (safe_name)) safe_name = rQuote (short_child_name);
-	return (parent->getBaseName () + '@' + safe_name);
+	return (parent->getFullName (options) + '@' + safe_name);
 }
 
 RKNamespaceObject::RKNamespaceObject (REnvironmentObject* package, const QString name) : REnvironmentObject (package, name.isNull () ? "NAMESPACE" : name) {
@@ -67,24 +59,18 @@ RKNamespaceObject::~RKNamespaceObject () {
 	pseudo_object_types.remove (this);
 }
 
-QString RKNamespaceObject::getFullName () const {
+QString RKNamespaceObject::getFullName (int) const {
 	RK_TRACE (OBJECTS);
 	return ("asNamespace (" + rQuote (namespace_name) + ')');
 }
 
-QString RKNamespaceObject::makeChildName (const QString& short_child_name, bool) const {
+QString RKNamespaceObject::makeChildName (const QString& short_child_name, bool, int) const {
 	RK_TRACE (OBJECTS);
 	QString safe_name = short_child_name;
 	if (irregularShortName (safe_name)) safe_name = rQuote (short_child_name);
 	return (namespace_name + ":::" + safe_name);
 }
 
-QString RKNamespaceObject::makeChildBaseName (const QString& short_child_name) const {
-	RK_TRACE (OBJECTS);
-	// since namespaces reside at top level, this is the same as makeChildName()
-	return (makeChildName (short_child_name, false));
-}
-
 #include "robjectlist.h"
 #include "rkmodificationtracker.h"
 #include "../rkglobals.h"
@@ -100,21 +86,16 @@ RKOrphanNamespacesObject::~RKOrphanNamespacesObject () {
 	pseudo_object_types.remove (this);
 }
 
-QString RKOrphanNamespacesObject::getFullName () const {
+QString RKOrphanNamespacesObject::getFullName (int) const {
 	RK_TRACE (OBJECTS);
 	return ("loadedNamespaces ()");
 }
 
-QString RKOrphanNamespacesObject::makeChildName (const QString& short_child_name, bool) const {
+QString RKOrphanNamespacesObject::makeChildName (const QString& short_child_name, bool, int) const {
 	RK_TRACE (OBJECTS);
 	return ("asNamespace (" + rQuote (short_child_name) + ')');
 }
 
-QString RKOrphanNamespacesObject::makeChildBaseName (const QString& short_child_name) const {
-	RK_TRACE (OBJECTS);
-	return (makeChildName (short_child_name, false));
-}
-
 void RKOrphanNamespacesObject::updateFromR (RCommandChain* chain) {
 	RK_TRACE (OBJECTS);
 	Q_UNUSED (chain);
diff --git a/rkward/core/rkpseudoobjects.h b/rkward/core/rkpseudoobjects.h
index 80a9f8b1..db92ed7f 100644
--- a/rkward/core/rkpseudoobjects.h
+++ b/rkward/core/rkpseudoobjects.h
@@ -35,9 +35,8 @@ public:
 	explicit RSlotsPseudoObject (RObject *parent);
 	~RSlotsPseudoObject ();
 
-	QString getFullName () const override;
-	QString makeChildName (const QString &short_child_name, bool misplaced=false) const override;
-	QString makeChildBaseName (const QString &short_child_name) const override;
+	QString getFullName (int) const override;
+	QString makeChildName (const QString &short_child_name, bool misplaced, int) const override;
 };
 
 /**
@@ -52,9 +51,8 @@ public:
 	explicit RKNamespaceObject (REnvironmentObject* package, const QString name = QString ());
 	~RKNamespaceObject ();
 
-	QString getFullName () const override;
-	QString makeChildName (const QString &short_child_name, bool misplaced=false) const override;
-	QString makeChildBaseName (const QString &short_child_name) const override;
+	QString getFullName (int) const override;
+	QString makeChildName (const QString &short_child_name, bool misplaced, int) const override;
 	QString namespaceName () const { return namespace_name; };
 private:
 	QString namespace_name;
@@ -76,9 +74,8 @@ public:
 	explicit RKOrphanNamespacesObject (RObjectList *parent);
 	~RKOrphanNamespacesObject ();
 
-	QString getFullName () const override;
-	QString makeChildName (const QString &short_child_name, bool misplaced=false) const override;
-	QString makeChildBaseName (const QString &short_child_name) const override;
+	QString getFullName (int options) const override;
+	QString makeChildName (const QString &short_child_name, bool misplaced, int options) const override;
 	QString getObjectDescription () const override;
 
 	RKNamespaceObject *findOrphanNamespace (const QString &name) const;
diff --git a/rkward/core/rkrownames.cpp b/rkward/core/rkrownames.cpp
index 7aa532d7..65dc7b06 100644
--- a/rkward/core/rkrownames.cpp
+++ b/rkward/core/rkrownames.cpp
@@ -38,7 +38,7 @@ RKRowNames::RKRowNames (RContainerObject *parent) : RKVariable (parent, QString
 	check_duplicates = true;
 	is_sequential_up_to_row = -1;
 
-	name = i18n ("row names");
+	name = QString ("row.names");
 }
 
 RKRowNames::~RKRowNames () {
@@ -62,17 +62,17 @@ void RKRowNames::beginEdit () {
 	}
 }
 
-QString RKRowNames::getFullName () const {
+QString RKRowNames::getFullName (int options) const {
 //	RK_TRACE (OBJECTS);
 
-	return ("row.names (" + parent->getFullName () + ')');
+	return ("row.names (" + parent->getFullName (options) + ')');
 }
 
 void RKRowNames::writeData (int from_row, int to_row, RCommandChain *chain) {
 	RK_TRACE (OBJECTS);
 
 	if (isSequential ()) {
-		RKGlobals::rInterface ()->issueCommand (getFullName () + " <- NULL", RCommand::App | RCommand::Sync, QString (), 0,0, chain);
+		RKGlobals::rInterface ()->issueCommand (getFullName (DefaultObjectNameOptions) + " <- NULL", RCommand::App | RCommand::Sync, QString (), 0,0, chain);
 	} else {
 		// unfortunately, we always need to write the whole data, as row.names<- does not support indexing.
 		QString data_string = "c (";
@@ -84,7 +84,7 @@ void RKRowNames::writeData (int from_row, int to_row, RCommandChain *chain) {
 			}
 		}
 		data_string.append (")");
-		RKGlobals::rInterface ()->issueCommand (getFullName () + " <- " + data_string, RCommand::App | RCommand::Sync, QString (), 0, 0, chain);
+		RKGlobals::rInterface ()->issueCommand (getFullName (DefaultObjectNameOptions) + " <- " + data_string, RCommand::App | RCommand::Sync, QString (), 0, 0, chain);
 	}
 
 	ChangeSet *set = new ChangeSet;
diff --git a/rkward/core/rkrownames.h b/rkward/core/rkrownames.h
index 6bbf02f7..592aa15c 100644
--- a/rkward/core/rkrownames.h
+++ b/rkward/core/rkrownames.h
@@ -27,9 +27,7 @@ public:
 	explicit RKRowNames (RContainerObject *parent);
 	~RKRowNames ();
 
-	QString getFullName () const override;
-/** Reimplemented to return "row.names" */
-	QString getBaseName () const override { return QString ("row.names"); };
+	QString getFullName (int) const override;
 /** Reimplemented to do nothing. There is no metadata on the rownames. */
 	void writeMetaData (RCommandChain *) override {};
 
diff --git a/rkward/core/robject.cpp b/rkward/core/robject.cpp
index cb96b3f2..81a435d1 100644
--- a/rkward/core/robject.cpp
+++ b/rkward/core/robject.cpp
@@ -71,14 +71,9 @@ bool RObject::irregularShortName (const QString &name) {
 	return (name.contains (invalidChars));
 }
 
-QString RObject::getFullName () const {
+QString RObject::getFullName (int options) const {
 	RK_TRACE (OBJECTS);
-	return parent->makeChildName (RObject::name, type & Misplaced);
-}
-
-QString RObject::getBaseName () const {
-	RK_TRACE (OBJECTS);
-	return parent->makeChildBaseName (RObject::name);
+	return parent->makeChildName (RObject::name, type & Misplaced, options);
 }
 
 QString RObject::getLabel () const {
@@ -189,14 +184,13 @@ bool RObject::inherits (const QString &class_name) const {
 	return (classnames.contains (class_name));
 }
 
-QString RObject::makeChildName (const QString &short_child_name, bool) const {
+QString RObject::makeChildName (const QString &short_child_name, bool, int options) const {
 	RK_TRACE (OBJECTS);
-	return (getFullName () + "[[" + rQuote (short_child_name) + "]]");
-}
-
-QString RObject::makeChildBaseName (const QString &short_child_name) const {
-	RK_TRACE (OBJECTS);
-	return (getBaseName () + "[[" + rQuote (short_child_name) + "]]");
+	if (options & DollarExpansion) {
+		if (irregularShortName (short_child_name)) return (getFullName (options) + '$' + rQuote (short_child_name));
+		return (getFullName (options) + '$' + short_child_name);  // Do not return list$"member", unless necessary
+	}
+	return (getFullName (options) + "[[" + rQuote (short_child_name) + "]]");
 }
 
 void RObject::writeMetaData (RCommandChain *chain) {
diff --git a/rkward/core/robject.h b/rkward/core/robject.h
index 44ee3c0a..f69e19a4 100644
--- a/rkward/core/robject.h
+++ b/rkward/core/robject.h
@@ -114,8 +114,12 @@ public:
 	static bool isMatchingType (int old_type, int new_type) { return ((old_type & ROBJECT_TYPE_INTERNAL_MASK) == (new_type & ROBJECT_TYPE_INTERNAL_MASK)); };
 	
 	QString getShortName () const { return name; };
-	virtual QString getFullName () const;
-	virtual QString getBaseName () const;
+	enum ObjectNameOptions {
+		DollarExpansion = 1,              /**< Return list members as list$member, instead of list[["member"]]  */
+		IncludeEnvirIfNotGlobalEnv = 2,   /**< Include package name for objects on the search path  */
+		DefaultObjectNameOptions = IncludeEnvirIfNotGlobalEnv
+	};
+	virtual QString getFullName (int name_options = DefaultObjectNameOptions) const;
 	QString getLabel () const;
 	QString getMetaProperty (const QString &id) const;
 	QString getDescription () const;
@@ -229,7 +233,7 @@ public:
 	};
 
 /** generates a (full) name for a child of this object with the given name. */
-	virtual QString makeChildName (const QString &short_child_name, bool misplaced=false) const;
+	virtual QString makeChildName (const QString &short_child_name, bool misplaced=false, int object_name_options=DefaultObjectNameOptions) const;
 protected:
 // why do I need those to compile? I thought they were derived classes!
 	friend class RContainerObject;
@@ -254,8 +258,6 @@ protected:
 /** Worker function for findObject() and findObjectsMatching(). If matches != 0, look for partial matches, and store them in the map (findObjectsMatching()). Else look for exact matches and return the first match (findObject()). */
 	virtual RObject *findObjects (const QStringList &path, RObjectSearchMap *matches, const QString &op);
 
-	virtual QString makeChildBaseName (const QString &short_child_name) const;
-
 /** Update object to reflect the structure passed in the new_data argument. If the data is mismatching (i.e. can not be accommodated by this type of object) false is returned (calls canAccommodateStructure () internally). In this case you should delete the object, and create a new one.
 @returns true if the changes could be done, false if this  */
 	virtual bool updateStructure (RData *new_data);
diff --git a/rkward/core/robjectlist.cpp b/rkward/core/robjectlist.cpp
index c71c7022..b22b582f 100644
--- a/rkward/core/robjectlist.cpp
+++ b/rkward/core/robjectlist.cpp
@@ -313,7 +313,7 @@ void RObjectList::timeout () {
 QString RObjectList::renameChildCommand (RObject *object, const QString &new_name) const {
 	RK_TRACE (OBJECTS);
 
-	return (makeChildName (new_name, false) + " <- " + object->getFullName () + '\n' + removeChildCommand (object));
+	return (makeChildName (new_name, false, IncludeEnvirIfNotGlobalEnv) + " <- " + object->getFullName () + '\n' + removeChildCommand (object));
 }
 
 QString RObjectList::removeChildCommand (RObject *object) const {
diff --git a/rkward/core/robjectlist.h b/rkward/core/robjectlist.h
index d4fcd880..5f60a2d0 100644
--- a/rkward/core/robjectlist.h
+++ b/rkward/core/robjectlist.h
@@ -51,9 +51,8 @@ public:
 	/** like updateFromR, but only adjusts to new / missing environments, but does not update the .GlobalEnv. Designed to be used from the backend, when packages were loaded/unloaded . */
 	void updateFromR (RCommandChain *chain, const QStringList &current_searchpath, const QStringList &current_namespaces);
 	
-	QString getFullName () const override { return QString (); };
-	QString getBaseName () const override { return QString (); };
-	QString makeChildName (const QString &short_child_name, bool) const override { return short_child_name; };
+	QString getFullName (int) const override { return QString (); };
+	QString makeChildName (const QString &short_child_name, bool, int) const override { return short_child_name; };
 	/** reimplemented from RContainerObject: do nothing. The object-list has no meta data. */
 	void writeMetaData (RCommandChain *) override {};
 



More information about the rkward-tracker mailing list