builtins.toJSON: fix __toString usage
(cherry picked from commit e583df52800b4baa1564b027fe3b83a21756c2cc)
This commit is contained in:
		
							parent
							
								
									6c90e3b9ac
								
							
						
					
					
						commit
						3130aafd01
					
				
					 5 changed files with 29 additions and 8 deletions
				
			
		|  | @ -1568,6 +1568,19 @@ bool EvalState::isDerivation(Value & v) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | std::optional<string> EvalState::tryAttrsToString(const Pos & pos, Value & v, | ||||||
|  |     PathSet & context, bool coerceMore, bool copyToStore) | ||||||
|  | { | ||||||
|  |     auto i = v.attrs->find(sToString); | ||||||
|  |     if (i != v.attrs->end()) { | ||||||
|  |         Value v1; | ||||||
|  |         callFunction(*i->value, v, v1, pos); | ||||||
|  |         return coerceToString(pos, v1, context, coerceMore, copyToStore); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return {}; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, | string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, | ||||||
|     bool coerceMore, bool copyToStore) |     bool coerceMore, bool copyToStore) | ||||||
| { | { | ||||||
|  | @ -1586,13 +1599,11 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (v.type == tAttrs) { |     if (v.type == tAttrs) { | ||||||
|         auto i = v.attrs->find(sToString); |         auto maybeString = tryAttrsToString(pos, v, context, coerceMore, copyToStore); | ||||||
|         if (i != v.attrs->end()) { |         if (maybeString) { | ||||||
|             Value v1; |             return *maybeString; | ||||||
|             callFunction(*i->value, v, v1, pos); |  | ||||||
|             return coerceToString(pos, v1, context, coerceMore, copyToStore); |  | ||||||
|         } |         } | ||||||
|         i = v.attrs->find(sOutPath); |         auto i = v.attrs->find(sOutPath); | ||||||
|         if (i == v.attrs->end()) throwTypeError("cannot coerce a set to a string, at %1%", pos); |         if (i == v.attrs->end()) throwTypeError("cannot coerce a set to a string, at %1%", pos); | ||||||
|         return coerceToString(pos, *i->value, context, coerceMore, copyToStore); |         return coerceToString(pos, *i->value, context, coerceMore, copyToStore); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| #include "function-trace.hh" | #include "function-trace.hh" | ||||||
| 
 | 
 | ||||||
| #include <map> | #include <map> | ||||||
|  | #include <optional> | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -196,6 +197,9 @@ public: | ||||||
|        set with attribute `type = "derivation"'). */ |        set with attribute `type = "derivation"'). */ | ||||||
|     bool isDerivation(Value & v); |     bool isDerivation(Value & v); | ||||||
| 
 | 
 | ||||||
|  |     std::optional<string> tryAttrsToString(const Pos & pos, Value & v, | ||||||
|  |         PathSet & context, bool coerceMore = false, bool copyToStore = true); | ||||||
|  | 
 | ||||||
|     /* String coercion.  Converts strings, paths and derivations to a
 |     /* String coercion.  Converts strings, paths and derivations to a
 | ||||||
|        string.  If `coerceMore' is set, also converts nulls, integers, |        string.  If `coerceMore' is set, also converts nulls, integers, | ||||||
|        booleans and lists to a string.  If `copyToStore' is set, |        booleans and lists to a string.  If `copyToStore' is set, | ||||||
|  |  | ||||||
|  | @ -40,7 +40,12 @@ void printValueAsJSON(EvalState & state, bool strict, | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|         case tAttrs: { |         case tAttrs: { | ||||||
|             Bindings::iterator i = v.attrs->find(state.sOutPath); |             auto maybeString = state.tryAttrsToString(noPos, v, context, false, false); | ||||||
|  |             if (maybeString) { | ||||||
|  |                 out.write(*maybeString); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             auto i = v.attrs->find(state.sOutPath); | ||||||
|             if (i == v.attrs->end()) { |             if (i == v.attrs->end()) { | ||||||
|                 auto obj(out.object()); |                 auto obj(out.object()); | ||||||
|                 StringSet names; |                 StringSet names; | ||||||
|  |  | ||||||
|  | @ -1 +1 @@ | ||||||
| "{\"a\":123,\"b\":-456,\"c\":\"foo\",\"d\":\"foo\\n\\\"bar\\\"\",\"e\":true,\"f\":false,\"g\":[1,2,3],\"h\":[\"a\",[\"b\",{\"foo\\nbar\":{}}]],\"i\":3,\"j\":1.44}" | "{\"a\":123,\"b\":-456,\"c\":\"foo\",\"d\":\"foo\\n\\\"bar\\\"\",\"e\":true,\"f\":false,\"g\":[1,2,3],\"h\":[\"a\",[\"b\",{\"foo\\nbar\":{}}]],\"i\":3,\"j\":1.44,\"k\":\"foo\"}" | ||||||
|  |  | ||||||
|  | @ -9,4 +9,5 @@ builtins.toJSON | ||||||
|     h = [ "a" [ "b" { "foo\nbar" = {}; } ] ]; |     h = [ "a" [ "b" { "foo\nbar" = {}; } ] ]; | ||||||
|     i = 1 + 2; |     i = 1 + 2; | ||||||
|     j = 1.44; |     j = 1.44; | ||||||
|  |     k = { __toString = self: self.a; a = "foo"; }; | ||||||
|   } |   } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue