Properly resolve paths of symbols of imports
This solves a long-standing problem whereby relative paths are not properly resolved, leading to incorrect symbol conflicts when relative paths to the same package vary between two imports. See doc/notes/path-processing for an illustration. * src/current/include/preproc/path.xsl (preproc:resolve-relative-import): Add function. (preproc:resolv-path, preproc:resolve-path, preproc:get-path): Add functions to invoke existing templates. * src/current/include/preproc/symtable.xsl (preproc:symimport): Use `preproc:resolve-relative-import'. * doc/notes/path-processing: Add notes.master
parent
7472cb882c
commit
52c1bb5ebe
|
@ -0,0 +1,65 @@
|
|||
Path processing
|
||||
---------------
|
||||
Need rules that will work for both the existing scenario (B) and the new
|
||||
scenario (A):
|
||||
|
||||
|
||||
_
|
||||
/ \
|
||||
/ _ \
|
||||
/ ___ \
|
||||
/_/ \_\
|
||||
---------
|
||||
|
||||
root = ../
|
||||
package = suppliers/colony <--- /suppliers/colony
|
||||
import = ../map/return/colony <--- /map/return/colony
|
||||
|
||||
mapimport = ../../suppliers/colony/gl <-- /suppliers/colony/gl
|
||||
|
||||
|
||||
this is the root
|
||||
/ \
|
||||
v v
|
||||
1) <..>/map/return/ | <..>/../suppliers/colony/gl
|
||||
= ../suppliers/colony/gl
|
||||
^^^^^^^^^^^^^^^^
|
||||
\ /
|
||||
package name
|
||||
|
||||
2) strip root||(package base) from package import
|
||||
= ../map/return | <../suppliers/>colony/gl
|
||||
= colony/gl
|
||||
^^^^^^^^^
|
||||
` The relative path from package
|
||||
|
||||
|
||||
|
||||
____
|
||||
| __ )
|
||||
| _ \
|
||||
| |_) |
|
||||
|____/
|
||||
-------
|
||||
|
||||
what about normal includes?
|
||||
|
||||
|
||||
root = ../
|
||||
package = suppliers/colony <--- /suppliers/colony
|
||||
import = ../common/foo <--- /common/foo
|
||||
|
||||
subimport = bar/baz <--- /common/foo/bar/baz
|
||||
|
||||
|
||||
one has root, other does not
|
||||
/
|
||||
v
|
||||
1) <..>/common/ | bar/baz
|
||||
= ../common/bar/baz
|
||||
|
||||
2) strip root||(package base) from package import
|
||||
= ../common/bar/baz
|
||||
^^^^^^^^^^^^^^^^^
|
||||
` no such prefix,
|
||||
so this is the relative path
|
|
@ -22,6 +22,7 @@
|
|||
-->
|
||||
<stylesheet version="2.0"
|
||||
xmlns="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:preproc="http://www.lovullo.com/rater/preproc">
|
||||
|
||||
|
||||
|
@ -59,6 +60,15 @@
|
|||
</template>
|
||||
|
||||
|
||||
<function name="preproc:get-path" as="xs:string">
|
||||
<param name="path" />
|
||||
|
||||
<call-template name="preproc:get-path">
|
||||
<with-param name="path" select="$path" />
|
||||
</call-template>
|
||||
</function>
|
||||
|
||||
|
||||
<!-- FIXME: duplicate code with above -->
|
||||
<template name="preproc:get-basename">
|
||||
<param name="path" />
|
||||
|
@ -94,6 +104,7 @@
|
|||
</template>
|
||||
|
||||
|
||||
<!-- TODO: rename to preproc:resolve-path -->
|
||||
<template name="preproc:resolv-path">
|
||||
<param name="path" />
|
||||
|
||||
|
@ -112,6 +123,26 @@
|
|||
</template>
|
||||
|
||||
|
||||
<function name="preproc:resolv-path" as="xs:string">
|
||||
<param name="path" />
|
||||
|
||||
<variable name="result" as="xs:string*">
|
||||
<call-template name="preproc:resolv-path">
|
||||
<with-param name="path" select="$path" />
|
||||
</call-template>
|
||||
</variable>
|
||||
|
||||
<sequence select="string-join( $result, '' )" />
|
||||
</function>
|
||||
|
||||
<!-- alias to the above -->
|
||||
<function name="preproc:resolve-path" as="xs:string">
|
||||
<param name="path" />
|
||||
|
||||
<sequence select="preproc:resolv-path( $path )" />
|
||||
</function>
|
||||
|
||||
|
||||
<!-- XXX: warning, this won't like 'foo../' -->
|
||||
<template name="preproc:resolv-rel-path">
|
||||
<param name="path" />
|
||||
|
@ -244,4 +275,44 @@
|
|||
</choose>
|
||||
</template>
|
||||
|
||||
|
||||
<!--
|
||||
Resolve relative package imports
|
||||
|
||||
This situation arises when a source package (src) imports another
|
||||
package (src-import) that has a reference to an external symbol
|
||||
(sub-import).
|
||||
|
||||
See /doc/notes/path-processing for an illustration.
|
||||
-->
|
||||
<function name="preproc:resolve-relative-import" as="xs:string">
|
||||
<param name="src-root" as="xs:string" />
|
||||
<param name="src-name" as="xs:string" />
|
||||
<param name="src-import" as="xs:string" />
|
||||
<param name="sub-import" as="xs:string" />
|
||||
|
||||
<variable name="src-prefix" as="xs:string"
|
||||
select="concat( $src-root, '/', $src-name )" />
|
||||
|
||||
<!-- Step 1: resolve relative paths from sub-import -->
|
||||
<variable name="src-import-dir" as="xs:string"
|
||||
select="preproc:get-path( $src-import )" />
|
||||
<variable name="sub-concat" as="xs:string"
|
||||
select="if ( $src-import-dir ) then
|
||||
preproc:resolve-path(
|
||||
concat( $src-import-dir, '/', $sub-import ) )
|
||||
else
|
||||
$sub-import" />
|
||||
|
||||
<!-- Step 2: remove package name prefix, if present -->
|
||||
<variable name="src-name-base" as="xs:string"
|
||||
select="preproc:get-path( $src-name )" />
|
||||
<variable name="src-prefix" as="xs:string"
|
||||
select="concat( $src-root, $src-name-base, '/' )" />
|
||||
<variable name="suffix" as="xs:string"
|
||||
select="substring-after( $sub-concat, $src-prefix )" />
|
||||
|
||||
<sequence select="if ( $suffix ) then $suffix else $sub-concat" />
|
||||
</function>
|
||||
|
||||
</stylesheet>
|
||||
|
|
|
@ -521,12 +521,18 @@
|
|||
<xsl:param name="no-extclass" select="@no-extclass" />
|
||||
<xsl:param name="keep-classes" select="@keep-classes" />
|
||||
|
||||
<xsl:variable name="path" select="concat( $package, '.xmlo' )" />
|
||||
<xsl:variable name="path" as="xs:string"
|
||||
select="concat( $package, '.xmlo' )" />
|
||||
<xsl:variable name="syms"
|
||||
select="document( $path, $orig-root )/lv:*/preproc:symtable" />
|
||||
|
||||
<xsl:variable name="import-path" select="$package" />
|
||||
|
||||
<xsl:variable name="src-root" as="xs:string"
|
||||
select="ancestor::lv:package/@__rootpath" />
|
||||
<xsl:variable name="src-name" as="xs:string"
|
||||
select="ancestor::lv:package/@name" />
|
||||
|
||||
<!-- if they're including a program package, do they realize what they're
|
||||
doing!? -->
|
||||
<!-- FIXME: @allow-nonpkg is no longer accurate terminology; change to
|
||||
|
@ -542,14 +548,6 @@
|
|||
</xsl:message>
|
||||
</xsl:if>
|
||||
|
||||
<!-- determine our path from our name -->
|
||||
<xsl:variable name="our-path">
|
||||
<xsl:call-template name="preproc:get-path">
|
||||
<xsl:with-param name="path"
|
||||
select="ancestor::lv:package/@name" />
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
|
||||
<!-- to keep everything consistent and to simplify package equality
|
||||
assertions, resolve relative paths -->
|
||||
<xsl:variable name="import-default-path" select="$import-path" />
|
||||
|
@ -626,23 +624,11 @@
|
|||
itself) onto the existing relative path and resolving relative
|
||||
paths -->
|
||||
<xsl:otherwise>
|
||||
<xsl:call-template name="preproc:resolv-path">
|
||||
<xsl:with-param name="path">
|
||||
<!-- get the path of the import, sans package name -->
|
||||
<xsl:variable name="path">
|
||||
<xsl:call-template name="preproc:get-path">
|
||||
<xsl:with-param name="path" select="$import-path" />
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
|
||||
<!-- concatenate it with the existing relative path -->
|
||||
<xsl:if test="not( $path = '' )">
|
||||
<xsl:value-of select="concat( $path, '/' )" />
|
||||
</xsl:if>
|
||||
|
||||
<xsl:value-of select="@src" />
|
||||
</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
<xsl:sequence select="preproc:resolve-relative-import(
|
||||
$src-root,
|
||||
$src-name,
|
||||
$import-path,
|
||||
@src )" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:attribute>
|
||||
|
|
Loading…
Reference in New Issue