forked from MapComplete/MapComplete
		
	Fixed all shadowed mappings, make those an error
This commit is contained in:
		
							parent
							
								
									aa5e944447
								
							
						
					
					
						commit
						fe8c63d762
					
				
					 4 changed files with 75 additions and 66 deletions
				
			
		|  | @ -19,14 +19,17 @@ export abstract class Conversion<TIn, TOut> { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static strict<T>(fixed: { errors?: string[], warnings?: string[], information?: string[], result?: T }): T { |     public static strict<T>(fixed: { errors?: string[], warnings?: string[], information?: string[], result?: T }): T { | ||||||
|         if (fixed?.errors !== undefined &&  fixed?.errors?.length > 0) { |         | ||||||
|             throw fixed.errors.join("\n\n"); |  | ||||||
|         } |  | ||||||
|         fixed.information?.forEach(i => console.log("    ", i)) |         fixed.information?.forEach(i => console.log("    ", i)) | ||||||
|         const yellow = (s) => "\x1b[33m"+s+"\x1b[0m" |         const yellow = (s) => "\x1b[33m"+s+"\x1b[0m" | ||||||
|         const red = s => '\x1b[31m'+s+'\x1b[0m' |         const red = s => '\x1b[31m'+s+'\x1b[0m' | ||||||
|          |  | ||||||
|         fixed.warnings?.forEach(w => console.warn(red(`<!> `), yellow (w))) |         fixed.warnings?.forEach(w => console.warn(red(`<!> `), yellow (w))) | ||||||
|  | 
 | ||||||
|  |         if (fixed?.errors !== undefined &&  fixed?.errors?.length > 0) { | ||||||
|  |             fixed.errors?.forEach(e => console.error(red(`ERR `+e))) | ||||||
|  |             throw "Detected one or more errors, stopping now" | ||||||
|  |         } | ||||||
|  |          | ||||||
|         return fixed.result; |         return fixed.result; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -238,8 +238,25 @@ export class PrevalidateTheme extends Fuse<LayoutConfigJson> { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJson> { | export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJson> { | ||||||
|     constructor() { |     private readonly _calculatedTagNames: string[]; | ||||||
|  |     constructor(layerConfig?: LayerConfigJson) { | ||||||
|         super("Checks that the mappings don't shadow each other", [], "DetectShadowedMappings"); |         super("Checks that the mappings don't shadow each other", [], "DetectShadowedMappings"); | ||||||
|  |         this._calculatedTagNames = DetectShadowedMappings.extractCalculatedTagNames(layerConfig); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      *  | ||||||
|  |      * DetectShadowedMappings.extractCalculatedTagNames({calculatedTags: ["_abc:=js()"]}) // => ["_abc"]
 | ||||||
|  |      * DetectShadowedMappings.extractCalculatedTagNames({calculatedTags: ["_abc=js()"]}) // => ["_abc"]
 | ||||||
|  |      */ | ||||||
|  |     private static extractCalculatedTagNames(layerConfig?: LayerConfigJson){ | ||||||
|  |         return layerConfig?.calculatedTags?.map(ct => { | ||||||
|  |             if(ct.indexOf(':=') >= 0){ | ||||||
|  |                 return ct.split(':=')[0] | ||||||
|  |             } | ||||||
|  |             return ct.split("=")[0] | ||||||
|  |         }) ?? [] | ||||||
|  |          | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     convert(json: TagRenderingConfigJson, context: string): { result: TagRenderingConfigJson; errors?: string[]; warnings?: string[] } { |     convert(json: TagRenderingConfigJson, context: string): { result: TagRenderingConfigJson; errors?: string[]; warnings?: string[] } { | ||||||
|  | @ -248,6 +265,10 @@ export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJso | ||||||
|         if (json.mappings === undefined || json.mappings.length === 0) { |         if (json.mappings === undefined || json.mappings.length === 0) { | ||||||
|             return {result: json} |             return {result: json} | ||||||
|         } |         } | ||||||
|  |         const defaultProperties = {} | ||||||
|  |         for (const calculatedTagName of this._calculatedTagNames) { | ||||||
|  |             defaultProperties[calculatedTagName] = "some_calculated_tag_value_for_"+calculatedTagName | ||||||
|  |         } | ||||||
|         const parsedConditions = json.mappings.map(m => { |         const parsedConditions = json.mappings.map(m => { | ||||||
|             const ifTags = TagUtils.Tag(m.if); |             const ifTags = TagUtils.Tag(m.if); | ||||||
|             if(m.hideInAnswer !== undefined && m.hideInAnswer !== false && m.hideInAnswer !== true){ |             if(m.hideInAnswer !== undefined && m.hideInAnswer !== false && m.hideInAnswer !== true){ | ||||||
|  | @ -263,7 +284,7 @@ export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJso | ||||||
|                 // Yes, it might be shadowed, but running this check is to difficult right now
 |                 // Yes, it might be shadowed, but running this check is to difficult right now
 | ||||||
|                 continue |                 continue | ||||||
|             } |             } | ||||||
|             const keyValues = parsedConditions[i].asChange({}); |             const keyValues = parsedConditions[i].asChange(defaultProperties); | ||||||
|             const properties = {} |             const properties = {} | ||||||
|             keyValues.forEach(({k, v}) => { |             keyValues.forEach(({k, v}) => { | ||||||
|                 properties[k] = v |                 properties[k] = v | ||||||
|  | @ -289,10 +310,6 @@ export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJso | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // TODO make this errors again
 |  | ||||||
|         warnings.push(...errors) |  | ||||||
|         errors.splice(0, errors.length) |  | ||||||
| 
 |  | ||||||
|         return { |         return { | ||||||
|             errors, |             errors, | ||||||
|             warnings, |             warnings, | ||||||
|  | @ -341,9 +358,9 @@ export class DetectMappingsWithImages extends DesugaringStep<TagRenderingConfigJ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export class ValidateTagRenderings extends Fuse<TagRenderingConfigJson> { | export class ValidateTagRenderings extends Fuse<TagRenderingConfigJson> { | ||||||
|     constructor() { |     constructor(layerConfig: LayerConfigJson) { | ||||||
|         super("Various validation on tagRenderingConfigs", |         super("Various validation on tagRenderingConfigs", | ||||||
|             new DetectShadowedMappings(), |             new DetectShadowedMappings( layerConfig), | ||||||
|             new DetectMappingsWithImages()     |             new DetectMappingsWithImages()     | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  | @ -439,7 +456,7 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> { | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if (json.tagRenderings !== undefined) { |             if (json.tagRenderings !== undefined) { | ||||||
|                const r = new OnEvery("tagRenderings", new ValidateTagRenderings()).convert(json, context) |                const r = new OnEvery("tagRenderings", new ValidateTagRenderings(json)).convert(json, context) | ||||||
|                 warnings.push(...(r.warnings??[])) |                 warnings.push(...(r.warnings??[])) | ||||||
|                 errors.push(...(r.errors??[])) |                 errors.push(...(r.errors??[])) | ||||||
|                 information.push(...(r.information??[])) |                 information.push(...(r.information??[])) | ||||||
|  |  | ||||||
|  | @ -127,16 +127,12 @@ | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
|               "if": "building=apartments", |               "if": "building=apartments", | ||||||
|               "then": "An apartment building - highrise for living" |               "then": "An apartment building (a highrise building for living)" | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
|               "if": "building=office", |               "if": "building=office", | ||||||
|               "then": "An office building - highrise for work" |               "then": "An office building - highrise for work" | ||||||
|             }, |             }, | ||||||
|             { |  | ||||||
|               "if": "building=apartments", |  | ||||||
|               "then": "An apartment building" |  | ||||||
|             }, |  | ||||||
|             { |             { | ||||||
|               "if": "building=shed", |               "if": "building=shed", | ||||||
|               "then": "A small shed, e.g. in a garden" |               "then": "A small shed, e.g. in a garden" | ||||||
|  |  | ||||||
|  | @ -256,13 +256,14 @@ | ||||||
|           }, |           }, | ||||||
|           "mappings": [ |           "mappings": [ | ||||||
|             { |             { | ||||||
|               "if": "addr:unit=", |               "if": "not:addr:unit=yes", | ||||||
|               "then": "<div class='subtle'>Sub-unit (e.g. \"1\", \"Flat 2\", \"Unit C\")</div>", |               "then": "There is no sub-unit within this address", | ||||||
|               "hideInAnswer": true |               "addExtraTags": ["addr:unit="] | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
|               "if": "addr:unit=", |               "if": "addr:unit=", | ||||||
|               "then": "There is no sub-unit within this address" |               "then": "<div class='subtle'>Sub-unit (e.g. \"1\", \"Flat 2\", \"Unit C\")</div>", | ||||||
|  |               "hideInAnswer": true | ||||||
|             } |             } | ||||||
|           ], |           ], | ||||||
|           "condition": { |           "condition": { | ||||||
|  | @ -291,17 +292,12 @@ | ||||||
|                   "addr:housename=" |                   "addr:housename=" | ||||||
|                 ] |                 ] | ||||||
|               }, |               }, | ||||||
|               "then": "<div class='subtle'>House or building name</div>", |               "then": "This building has no housename" | ||||||
|               "hideInAnswer": true |  | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
|               "if": { |               "if": "addr:housename=", | ||||||
|                 "and": [ |               "then": "<div class='subtle'>House or building name</div>", | ||||||
|                   "nohousename=yes", |               "hideInAnswer": true | ||||||
|                   "addr:housename=" |  | ||||||
|                 ] |  | ||||||
|               }, |  | ||||||
|               "then": "This building has no housename" |  | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
|               "#": "By adding nohousenumber!=yes, this option will trigger when first added, but will be untriggered if a housenumber is added, resulting in the question poping up!", |               "#": "By adding nohousenumber!=yes, this option will trigger when first added, but will be untriggered if a housenumber is added, resulting in the question poping up!", | ||||||
|  | @ -329,10 +325,18 @@ | ||||||
|             ] |             ] | ||||||
|           }, |           }, | ||||||
|           "mappings": [ |           "mappings": [ | ||||||
|  |             { | ||||||
|  |               "if": "nohousenumber=yes", | ||||||
|  |               "then": { | ||||||
|  |                 "en": "This building has no house number", | ||||||
|  |                 "nl": "Dit gebouw heeft geen huisnummer", | ||||||
|  |                 "de": "Dieses Gebäude hat keine Hausnummer" | ||||||
|  |               }, | ||||||
|  |               "addExtraTags": [ "addr:housenumber="] | ||||||
|  |             }, | ||||||
|             { |             { | ||||||
|               "if": { |               "if": { | ||||||
|                 "and": [ |                 "and": [ | ||||||
|                   "nohousenumber=yes", |  | ||||||
|                   "addr:housenumber=" |                   "addr:housenumber=" | ||||||
|                 ] |                 ] | ||||||
|               }, |               }, | ||||||
|  | @ -340,19 +344,6 @@ | ||||||
|                 "en": "<div class='subtle'>Number (e.g. 1, 1A, 2)</div>" |                 "en": "<div class='subtle'>Number (e.g. 1, 1A, 2)</div>" | ||||||
|               }, |               }, | ||||||
|               "hideInAnswer": true |               "hideInAnswer": true | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|               "if": { |  | ||||||
|                 "and": [ |  | ||||||
|                   "nohousenumber=yes", |  | ||||||
|                   "addr:housenumber=" |  | ||||||
|                 ] |  | ||||||
|               }, |  | ||||||
|               "then": { |  | ||||||
|                 "en": "This building has no house number", |  | ||||||
|                 "nl": "Dit gebouw heeft geen huisnummer", |  | ||||||
|                 "de": "Dieses Gebäude hat keine Hausnummer" |  | ||||||
|               } |  | ||||||
|             } |             } | ||||||
|           ] |           ] | ||||||
|         }, |         }, | ||||||
|  | @ -373,17 +364,17 @@ | ||||||
|           }, |           }, | ||||||
|           "mappings": [ |           "mappings": [ | ||||||
|             { |             { | ||||||
|  |               "if": "not:addr:substreet=yes", | ||||||
|  |               "then": { | ||||||
|  |                 "en": "No extra place name is given or needed" | ||||||
|  |               }, | ||||||
|  |               "addExtraTags": ["addr:substreet="] | ||||||
|  |             },{ | ||||||
|               "if": "addr:substreet=", |               "if": "addr:substreet=", | ||||||
|               "then": { |               "then": { | ||||||
|                 "en": "<div class='subtle'>Place (e.g. \"Castle Mews\", \"West Business Park\")</div>" |                 "en": "<div class='subtle'>Place (e.g. \"Castle Mews\", \"West Business Park\")</div>" | ||||||
|               }, |               }, | ||||||
|               "hideInAnswer": true |               "hideInAnswer": true | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|               "if": "addr:substreet=", |  | ||||||
|               "then": { |  | ||||||
|                 "en": "No extra place name is given or needed" |  | ||||||
|               } |  | ||||||
|             } |             } | ||||||
|           ], |           ], | ||||||
|           "condition": "addr:parentstreet=" |           "condition": "addr:parentstreet=" | ||||||
|  | @ -403,18 +394,19 @@ | ||||||
|             ] |             ] | ||||||
|           }, |           }, | ||||||
|           "mappings": [ |           "mappings": [ | ||||||
|  |             { | ||||||
|  |               "if": "not:addr:substreet=yes", | ||||||
|  |               "then": { | ||||||
|  |                 "en": "No extra place name is given or needed" | ||||||
|  |               }, | ||||||
|  |               "addExtraTags": ["addr:substreet="] | ||||||
|  |             }, | ||||||
|             { |             { | ||||||
|               "if": "addr:substreet=", |               "if": "addr:substreet=", | ||||||
|               "then": { |               "then": { | ||||||
|                 "en": "<div class='subtle'>Place (e.g. \"Castle Mews\", \"West Business Park\")</div>" |                 "en": "<div class='subtle'>Place (e.g. \"Castle Mews\", \"West Business Park\")</div>" | ||||||
|               }, |               }, | ||||||
|               "hideInAnswer": true |               "hideInAnswer": true | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|               "if": "addr:substreet=", |  | ||||||
|               "then": { |  | ||||||
|                 "en": "No extra place name is given or needed" |  | ||||||
|               } |  | ||||||
|             } |             } | ||||||
|           ], |           ], | ||||||
|           "condition": { |           "condition": { | ||||||
|  | @ -479,15 +471,9 @@ | ||||||
|           }, |           }, | ||||||
|           "mappings": [ |           "mappings": [ | ||||||
|             { |             { | ||||||
|               "if": "addr:parentstreet=", |               "if": "not:addr:parentstreet=yes", | ||||||
|               "then": { |               "then": "No parent street name is needed within this address", | ||||||
|                 "en": "<div class='subtle'>Parent street name</div>" |               "addExtraTags": ["addr:parentstreet="] | ||||||
|               }, |  | ||||||
|               "hideInAnswer": true |  | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|               "if": "addr:parentstreet=", |  | ||||||
|               "then": "No parent street name is needed within this address" |  | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
|               "if": "addr:parentstreet:={_closest_street:0:name}", |               "if": "addr:parentstreet:={_closest_street:0:name}", | ||||||
|  | @ -503,6 +489,13 @@ | ||||||
|               "if": "addr:parentstreet:={_closest_street:2:name}", |               "if": "addr:parentstreet:={_closest_street:2:name}", | ||||||
|               "then": "<b>{_closest_street:2:name}</b>", |               "then": "<b>{_closest_street:2:name}</b>", | ||||||
|               "hideInAnswer": "_closest_street:2:name=" |               "hideInAnswer": "_closest_street:2:name=" | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               "if": "addr:parentstreet=", | ||||||
|  |               "then": { | ||||||
|  |                 "en": "<div class='subtle'>Parent street name</div>" | ||||||
|  |               }, | ||||||
|  |               "hideInAnswer": true | ||||||
|             } |             } | ||||||
|           ], |           ], | ||||||
|           "condition": { |           "condition": { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue