All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.expr.instruct.Actor Maven / Gradle / Ivy

There is a newer version: 12.5
Show newest version
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2018-2022 Saxonica Limited
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package net.sf.saxon.expr.instruct;

import net.sf.saxon.expr.*;
import net.sf.saxon.expr.parser.RetainedStaticContext;
import net.sf.saxon.lib.NamespaceConstant;
import net.sf.saxon.om.StandardNames;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.s9api.Location;
import net.sf.saxon.style.StyleElement;
import net.sf.saxon.style.StylesheetPackage;
import net.sf.saxon.style.XSLGlobalParam;
import net.sf.saxon.trace.ExpressionPresenter;
import net.sf.saxon.trans.SymbolicName;
import net.sf.saxon.trans.Visibility;
import net.sf.saxon.trans.VisibilityProvenance;
import net.sf.saxon.trans.XPathException;

import java.util.List;

/**
 * This object represents the compiled form of a user-written function, template, attribute-set, etc
 * (the source can be either an XSLT stylesheet function or an XQuery function).
 * 

It is assumed that type-checking, of both the arguments and the results, * has been handled at compile time. That is, the expression supplied as the body * of the function must be wrapped in code to check or convert the result to the * required type, and calls on the function must be wrapped at compile time to check or * convert the supplied arguments.

*/ public abstract class Actor implements ExpressionOwner, Location { protected Expression body; private String systemId; private int lineNumber; private int columnNumber; private SlotManager stackFrameMap; private PackageData packageData; private Component declaringComponent; private Visibility declaredVisibility = Visibility.UNDEFINED; private RetainedStaticContext retainedStaticContext; public Actor() { } /** * Get the symbolic name of the component * * @return the symbolic name */ public abstract SymbolicName getSymbolicName(); /** * Get the name of the component as a QName * @return the component's name */ public StructuredQName getComponentName() { return getSymbolicName().getComponentName(); } /** * Get a string used to identify this kind of component when used in tracing output * @return a diagnostic string used to identify the component when tracing */ public String getTracingTag() { return StandardNames.getLocalName(getSymbolicName().getComponentKind()); } /** * Set basic data about the unit of compilation (XQuery module, XSLT package) to which this * procedure belongs * * @param packageData information about the containing package */ public void setPackageData(PackageData packageData) { this.packageData = packageData; } /** * Get basic data about the unit of compilation (XQuery module, XSLT package) to which this * container belongs * @return the package information */ public PackageData getPackageData() { return packageData; } public Component makeDeclaringComponent(Visibility visibility, StylesheetPackage declaringPackage) { if (declaringComponent == null) { declaringComponent = Component.makeComponent(this, visibility, VisibilityProvenance.DEFAULTED, declaringPackage, declaringPackage); } return declaringComponent; } /** * Return the declaring component, creating it if it does not already exist. * * @param declaration The source element in the stylesheet corresponding to the component * @return the component corresponding to this declaration. */ public Component obtainDeclaringComponent(StyleElement declaration) { if (declaringComponent == null) { StylesheetPackage declaringPackage = declaration.getContainingPackage(); Visibility defaultVisibility = declaration instanceof XSLGlobalParam ? Visibility.PUBLIC : Visibility.PRIVATE; Visibility declaredVisibility = declaration.getDeclaredVisibility(); Visibility actualVisibility = declaredVisibility == Visibility.UNDEFINED ? defaultVisibility : declaredVisibility; VisibilityProvenance provenance = declaredVisibility == Visibility.UNDEFINED ? VisibilityProvenance.DEFAULTED : VisibilityProvenance.EXPLICIT; declaringComponent = Component.makeComponent(this, actualVisibility, provenance, declaringPackage, declaringPackage); } return declaringComponent; } public Component getDeclaringComponent() { return declaringComponent; } public void setDeclaringComponent(Component comp) { declaringComponent = comp; } /** * Allocate slot numbers to all the external component references in this component * * @param pack the containing package */ public void allocateAllBindingSlots(StylesheetPackage pack) { if (getBody() != null && getDeclaringComponent().getDeclaringPackage() == pack && packageData.isXSLT()) { allocateBindingSlotsRecursive(pack, this, getBody(), getDeclaringComponent().getComponentBindings()); } } public static void allocateBindingSlotsRecursive(StylesheetPackage pack, Actor p, Expression exp, List bindings) { if (exp instanceof ComponentInvocation) { p.processComponentReference(pack, (ComponentInvocation) exp, bindings); } for (Operand o : exp.operands()) { allocateBindingSlotsRecursive(pack, p, o.getChildExpression(), bindings); } } /** * Process a component reference from this component to some other component. Specifically, allocate * a slot number to the component reference, and add the reference to the supplied binding vector * * @param pack the containing package * @param invocation the instruction or expression representing the external reference, for example * a call-template instruction * @param bindings the supplied binding vector, containing all outward references * from this component; this list is modified by the call */ private void processComponentReference(StylesheetPackage pack, ComponentInvocation invocation, List bindings) { SymbolicName name = invocation.getSymbolicName(); if (name == null) { // there is no target component, e.g. with apply-templates mode="#current" return; } Component target = pack.getComponent(name); if (target == null && name.getComponentName().hasURI(NamespaceConstant.XSLT) && name.getComponentName().getLocalPart().equals("original")) { target = pack.getOverriddenComponent(getSymbolicName()); } if (target == null) { throw new AssertionError("Target of component reference " + name + " is undefined"); } if (invocation.getBindingSlot() >= 0) { throw new AssertionError("**** Component reference " + name + " is already bound"); } int slot = bindings.size(); ComponentBinding cb = new ComponentBinding(name, target); bindings.add(cb); invocation.setBindingSlot(slot); } public void setBody(Expression body) { this.body = body; if (body != null) { body.setParentExpression(null); } } public final Expression getBody() { return body; } @Override public final Expression getChildExpression() { return getBody(); } public void setStackFrameMap(SlotManager map) { stackFrameMap = map; } public SlotManager getStackFrameMap() { return stackFrameMap; } public void setLineNumber(int lineNumber) { this.lineNumber = lineNumber; } public void setColumnNumber(int col) { this.columnNumber = col; } public void setSystemId(String systemId) { this.systemId = systemId; } public Location getLocation() { return this; } @Override public int getLineNumber() { return lineNumber; } @Override public String getSystemId() { return systemId; } @Override public int getColumnNumber() { return columnNumber; } /*@Nullable*/ @Override public String getPublicId() { return null; } @Override public Location saveLocation() { return this; } public void setRetainedStaticContext(RetainedStaticContext rsc) { this.retainedStaticContext = rsc; } public RetainedStaticContext getRetainedStaticContext() { return retainedStaticContext; } public Object getProperty(String name) { return null; } /** * Set the visibility of the component as defined using its actual @visibility attribute * * @param visibility the actual declared visibility; null if the visibility attribute is absent */ public void setDeclaredVisibility(Visibility visibility) { this.declaredVisibility = visibility; } /** * Get the visibility of the component as defined using its actual @visibility attribute * * @return the actual declared visibility; null if the visibility attribute is absent */ public Visibility getDeclaredVisibility() { return declaredVisibility; } /** * Export expression structure. The abstract expression tree * is written to the supplied outputstream. * * @param presenter the expression presenter used to generate the XML representation of the structure * @throws XPathException if things go wrong, for example an I/O failure */ public abstract void export(ExpressionPresenter presenter) throws XPathException; public boolean isExportable() { return true; } @Override public void setChildExpression(Expression expr) { setBody(expr); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy