[Swift-commit] r4773 - in trunk: libexec resources src/org/griphyn/vdl/engine src/org/griphyn/vdl/karajan/lib src/org/griphyn/vdl/mapping src/org/griphyn/vdl/mapping/file
hategan at ci.uchicago.edu
hategan at ci.uchicago.edu
Tue Jul 5 15:40:07 CDT 2011
Author: hategan
Date: 2011-07-05 15:40:07 -0500 (Tue, 05 Jul 2011)
New Revision: 4773
Added:
trunk/src/org/griphyn/vdl/karajan/lib/CleanDataset.java
trunk/src/org/griphyn/vdl/mapping/file/FileGarbageCollector.java
trunk/src/org/griphyn/vdl/mapping/file/TestMapper.java
Modified:
trunk/libexec/vdl-lib.xml
trunk/resources/Karajan.stg
trunk/src/org/griphyn/vdl/engine/Karajan.java
trunk/src/org/griphyn/vdl/engine/VariableScope.java
trunk/src/org/griphyn/vdl/karajan/lib/SetFieldValue.java
trunk/src/org/griphyn/vdl/mapping/AbsFile.java
trunk/src/org/griphyn/vdl/mapping/AbstractDataNode.java
trunk/src/org/griphyn/vdl/mapping/AbstractMapper.java
trunk/src/org/griphyn/vdl/mapping/Mapper.java
trunk/src/org/griphyn/vdl/mapping/MapperFactory.java
trunk/src/org/griphyn/vdl/mapping/PhysicalFormat.java
trunk/src/org/griphyn/vdl/mapping/file/ConcurrentMapper.java
Log:
clean up temporary variables (including file removal for the concurrent mapper)
Modified: trunk/libexec/vdl-lib.xml
===================================================================
--- trunk/libexec/vdl-lib.xml 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/libexec/vdl-lib.xml 2011-07-05 20:40:07 UTC (rev 4773)
@@ -70,6 +70,7 @@
<export name="fringePaths"><elementDef classname="org.griphyn.vdl.karajan.lib.FringePaths"/></export>
<export name="closeDataset"><elementDef classname="org.griphyn.vdl.karajan.lib.CloseDataset"/></export>
<export name="partialCloseDataset"><elementDef classname="org.griphyn.vdl.karajan.lib.PartialCloseDataset"/></export>
+ <export name="cleanDataset"><elementDef classname="org.griphyn.vdl.karajan.lib.CleanDataset"/></export>
<export name="range"><elementDef classname="org.griphyn.vdl.karajan.lib.Range"/></export>
<export name="isLogged"><elementDef classname="org.griphyn.vdl.karajan.lib.IsLogged"/></export>
Modified: trunk/resources/Karajan.stg
===================================================================
--- trunk/resources/Karajan.stg 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/resources/Karajan.stg 2011-07-05 20:40:07 UTC (rev 4773)
@@ -55,7 +55,7 @@
<xs:element name="$name$" type="$type$"/>
>>
-procedure(name,outputs,inputs,arguments,optargs,binding,declarations,statements,config,line) ::= <<
+procedure(name,outputs,inputs,arguments,optargs,binding,declarations,statements,config,line,cleanups) ::= <<
<element name="$name$"$if(arguments)$ arguments="$proc_args(args=arguments)$"$endif$$if(optargs)$ optargs="$proc_args(args=optargs)$"$endif$>
$optargs:default_arg();separator="\n"$
$inputs:vdl_log_input();separator="\n"$
@@ -63,19 +63,20 @@
$if(binding)$
$vdl_execute(outputs=outputs,inputs=inputs,application=binding.application, name=name,line=line)$
$else$
- $compound(outputs=outputs,inputs=inputs,declarations=declarations,statements=statements,name=name)$
+ $compound(outputs=outputs,inputs=inputs,declarations=declarations,statements=statements,name=name,cleanups=cleanups)$
$endif$
</element>
>>
-compound(outputs,inputs,declarations,statements,config,name) ::= <<
+compound(outputs,inputs,declarations,statements,config,name,cleanups) ::= <<
<log level="info"><string>STARTCOMPOUND thread={#thread} name=$name$</string></log>
$declarations;separator="\n"$
$if(statements)$
$parallel(statements=statements)$
$endif$
$outputs:vdl_closedataset();separator="\n"$
+$cleanups:vdl_cleandataset();separator="\n"$
<log level="info"><string>ENDCOMPOUND thread={#thread}</string></log>
>>
@@ -137,6 +138,10 @@
<vdl:closedataset var="{$it.name$}"/>
>>
+vdl_cleandataset() ::= <<
+<vdl:cleandataset var="{$it$}"/>
+>>
+
vdl_arguments(arguments,stdin,stdout,stderr) ::= <<
<vdl:arguments>
$arguments;separator="\n"$
@@ -179,7 +184,7 @@
</swiftscript:$name$>
>>
-iterate(declarations,statements,cond,var) ::= <<
+iterate(declarations,statements,cond,var,cleanups) ::= <<
<vdl:infinitecountingwhile>
<set names="\$\$">
@@ -188,7 +193,7 @@
<set name="$var$">
<vdl:new type="int" value="{\$\$}" />
</set>
- $sub_comp(declarations=declarations, statements=statements)$
+ $sub_comp(declarations=declarations, statements=statements, cleanups=cleanups)$
<sys:if>
<vdl:getfieldvalue>$cond$</vdl:getfieldvalue>
<sys:break/>
@@ -197,7 +202,7 @@
</vdl:infinitecountingwhile>
>>
-foreach(var,in,indexVar,declarations,statements,line,selfClose) ::= <<
+foreach(var,in,indexVar,declarations,statements,line,selfClose,cleanups) ::= <<
<vdl:tparallelFor name="\$"$if(selfClose)$ selfClose="$selfClose$"$endif$>
<getarrayiterator>$in$</getarrayiterator>
<set names="\$\$, $var$">
@@ -214,6 +219,7 @@
$declarations;separator="\n"$
$if(statements)$
$parallel(statements=statements)$
+ $cleanups:vdl_cleandataset();separator="\n"$
$endif$
<log level="debug" message="FOREACH_IT_END line=$line$ thread={#thread}"/>
</vdl:tparallelFor>
@@ -430,10 +436,11 @@
</if>
>>
-sub_comp(declarations,statements) ::= <<
+sub_comp(declarations,statements,cleanups) ::= <<
$declarations;separator="\n"$
$if(statements)$
$parallel(statements=statements)$
+$cleanups:vdl_cleandataset();separator="\n"$
$endif$
>>
Modified: trunk/src/org/griphyn/vdl/engine/Karajan.java
===================================================================
--- trunk/src/org/griphyn/vdl/engine/Karajan.java 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/src/org/griphyn/vdl/engine/Karajan.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -350,6 +350,7 @@
compoundScope.bodyTemplate = procST;
statementsForSymbols(proc, compoundScope);
statements(proc, compoundScope);
+ procST.setAttribute("cleanups", compoundScope.getCleanups());
}
}
@@ -765,6 +766,7 @@
for (String v : innerScope.getVariables())
scope.addWriter(v, statementID, true);
scope.appendStatement(iterateST);
+ iterateST.setAttribute("cleanups", innerScope.getCleanups());
}
public void foreachStat(Foreach foreach, VariableScope scope) throws CompilationException {
@@ -802,6 +804,7 @@
foreachST.setAttribute("selfClose", "true");
}
scope.appendStatement(foreachST);
+ foreachST.setAttribute("cleanups", innerScope.getCleanups());
} catch(CompilationException re) {
throw new CompilationException("Compile error in foreach statement at "+foreach.getSrc()+": "+re.getMessage(),re);
}
@@ -824,6 +827,7 @@
statementsForSymbols(thenstat, innerThenScope);
statements(thenstat, innerThenScope);
+ innerThenScope.bodyTemplate.setAttribute("cleanups", innerThenScope.getCleanups());
Object statementID = new Integer(callID++);
@@ -841,6 +845,8 @@
for (String v : innerElseScope.getVariables())
scope.addWriter(v, statementID, true);
+
+ innerElseScope.bodyTemplate.setAttribute("cleanups", innerElseScope.getCleanups());
}
scope.appendStatement(ifST);
}
Modified: trunk/src/org/griphyn/vdl/engine/VariableScope.java
===================================================================
--- trunk/src/org/griphyn/vdl/engine/VariableScope.java 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/src/org/griphyn/vdl/engine/VariableScope.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -318,5 +318,15 @@
public VariableScope getRootScope() {
return rootScope;
}
+
+ public List<String> getCleanups() {
+ List<String> cleanups = new ArrayList<String>();
+ cleanups.addAll(variables);
+ return cleanups;
+ }
+
+ public String toString() {
+ return variables.toString();
+ }
}
Added: trunk/src/org/griphyn/vdl/karajan/lib/CleanDataset.java
===================================================================
--- trunk/src/org/griphyn/vdl/karajan/lib/CleanDataset.java (rev 0)
+++ trunk/src/org/griphyn/vdl/karajan/lib/CleanDataset.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -0,0 +1,25 @@
+/*
+ * Created on Dec 26, 2006
+ */
+package org.griphyn.vdl.karajan.lib;
+
+import org.apache.log4j.Logger;
+import org.globus.cog.karajan.arguments.Arg;
+import org.globus.cog.karajan.stack.VariableStack;
+import org.globus.cog.karajan.workflow.ExecutionException;
+import org.griphyn.vdl.mapping.AbstractDataNode;
+
+public class CleanDataset extends VDLFunction {
+ public static final Logger logger = Logger.getLogger(CleanDataset.class);
+
+ static {
+ setArguments(CleanDataset.class, new Arg[] { PA_VAR });
+ }
+
+ public Object function(VariableStack stack) throws ExecutionException {
+ AbstractDataNode var = (AbstractDataNode) PA_VAR.getValue(stack);
+ logger.info("Cleaning " + var);
+ var.clean();
+ return null;
+ }
+}
Modified: trunk/src/org/griphyn/vdl/karajan/lib/SetFieldValue.java
===================================================================
--- trunk/src/org/griphyn/vdl/karajan/lib/SetFieldValue.java 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/src/org/griphyn/vdl/karajan/lib/SetFieldValue.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -140,7 +140,9 @@
if (logger.isDebugEnabled()) {
logger.debug("Remapping " + dest + " to " + source);
}
- dest.getMapper().remap(dpath, source.getMapper().map(source.getPathFromRoot()));
+
+ dest.getMapper().remap(dpath, source.getMapper(), source.getPathFromRoot());
+
dest.closeShallow();
}
else {
Modified: trunk/src/org/griphyn/vdl/mapping/AbsFile.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/AbsFile.java 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/src/org/griphyn/vdl/mapping/AbsFile.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -169,4 +169,14 @@
public String toString() {
return getURIAsString();
}
+
+ @Override
+ public void clean() {
+ try {
+ getFileResource().deleteFile(path);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
}
Modified: trunk/src/org/griphyn/vdl/mapping/AbstractDataNode.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/AbstractDataNode.java 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/src/org/griphyn/vdl/mapping/AbstractDataNode.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -628,4 +628,15 @@
wrapper.notifyListeners();
}
}
+
+ public synchronized void clean() {
+ Mapper mapper = getMapper();
+ if (mapper != null) {
+ mapper.clean(getPathFromRoot());
+ }
+ field = null;
+ handles = null;
+ value = null;
+ pathFromRoot = null;
+ }
}
Modified: trunk/src/org/griphyn/vdl/mapping/AbstractMapper.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/AbstractMapper.java 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/src/org/griphyn/vdl/mapping/AbstractMapper.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -4,6 +4,7 @@
import java.util.Map;
import org.apache.log4j.Logger;
+import org.griphyn.vdl.mapping.file.FileGarbageCollector;
/** AbstractMapper provides an implementation of the Mapper interface to be
used as a base class for writing other mappers. It provides handling
@@ -55,7 +56,30 @@
return false;
}
- public void remap(Path path, PhysicalFormat file) {
+ public void remap(Path path, Mapper sourceMapper, Path sourcePath) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public void clean(Path path) {
+ // no cleaning by default
+ }
+
+ @Override
+ public boolean isPersistent(Path path) {
+ // persistent unless explicitly overridden
+ return true;
+ }
+
+ protected void ensureCollectionConsistency(Mapper sourceMapper, Path sourcePath) {
+ // if remapping from a persistent mapper, then file removal
+ // should be avoided
+ PhysicalFormat pf = sourceMapper.map(sourcePath);
+ if (sourceMapper.isPersistent(sourcePath)) {
+ FileGarbageCollector.getDefault().markAsPersistent(pf);
+ }
+ else {
+ FileGarbageCollector.getDefault().increaseUsageCount(pf);
+ }
+ }
}
Modified: trunk/src/org/griphyn/vdl/mapping/Mapper.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/Mapper.java 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/src/org/griphyn/vdl/mapping/Mapper.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -50,5 +50,18 @@
*/
boolean canBeRemapped(Path path);
- void remap(Path path, PhysicalFormat file);
+ /**
+ * If this mapper supports remapping then remap the given path to
+ * whatever the source mapper maps the sourcePath to
+ */
+ void remap(Path path, Mapper sourceMapper, Path sourcePath);
+
+ /**
+ * Clean the specified path. A temporary mapper may remove the
+ * corresponding file after this call.
+ */
+ void clean(Path path);
+
+
+ boolean isPersistent(Path path);
}
Modified: trunk/src/org/griphyn/vdl/mapping/MapperFactory.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/MapperFactory.java 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/src/org/griphyn/vdl/mapping/MapperFactory.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -18,6 +18,7 @@
import org.griphyn.vdl.mapping.file.SimpleFileMapper;
import org.griphyn.vdl.mapping.file.SingleFileMapper;
import org.griphyn.vdl.mapping.file.StructuredRegularExpressionMapper;
+import org.griphyn.vdl.mapping.file.TestMapper;
public class MapperFactory {
private static Map<String,Class<Mapper>> mappers =
@@ -41,6 +42,7 @@
registerMapper("airsn_mapper", AirsnMapper.class);
registerMapper("roi_mapper", ROIMapper.class);
registerMapper("ext", ExternalMapper.class);
+ registerMapper("test_mapper", TestMapper.class);
}
public synchronized static Mapper getMapper(String type,
Modified: trunk/src/org/griphyn/vdl/mapping/PhysicalFormat.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/PhysicalFormat.java 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/src/org/griphyn/vdl/mapping/PhysicalFormat.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -5,4 +5,6 @@
public interface PhysicalFormat {
String getType();
+
+ void clean();
}
Modified: trunk/src/org/griphyn/vdl/mapping/file/ConcurrentMapper.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/ConcurrentMapper.java 2011-07-05 20:36:35 UTC (rev 4772)
+++ trunk/src/org/griphyn/vdl/mapping/file/ConcurrentMapper.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -9,6 +9,7 @@
import java.util.Map;
import java.util.Set;
+import org.griphyn.vdl.mapping.Mapper;
import org.griphyn.vdl.mapping.MappingParam;
import org.griphyn.vdl.mapping.Path;
import org.griphyn.vdl.mapping.PhysicalFormat;
@@ -60,10 +61,27 @@
return true;
}
- public synchronized void remap(Path path, PhysicalFormat file) {
+ public synchronized void remap(Path path, Mapper sourceMapper, Path sourcePath) {
if (remappedPaths == null) {
remappedPaths = new HashMap();
}
- remappedPaths.put(path, file);
+ PhysicalFormat pf = sourceMapper.map(sourcePath);
+ remappedPaths.put(path, pf);
+ ensureCollectionConsistency(sourceMapper, sourcePath);
}
+
+ @Override
+ public void clean(Path path) {
+ PhysicalFormat pf = map(path);
+ logger.info("Cleaning file " + pf);
+ FileGarbageCollector.getDefault().decreaseUsageCount(pf);
+ }
+
+ @Override
+ public boolean isPersistent(Path path) {
+ // if the path has been remapped to a persistent file, then
+ // that actual file would already be marked as persistent in the
+ // garbage collector
+ return false;
+ }
}
\ No newline at end of file
Added: trunk/src/org/griphyn/vdl/mapping/file/FileGarbageCollector.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/FileGarbageCollector.java (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/file/FileGarbageCollector.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -0,0 +1,112 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Jul 4, 2011
+ */
+package org.griphyn.vdl.mapping.file;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.griphyn.vdl.mapping.PhysicalFormat;
+
+public class FileGarbageCollector implements Runnable {
+ public static final Logger logger = Logger.getLogger(FileGarbageCollector.class);
+
+ private static FileGarbageCollector instance;
+
+ public synchronized static FileGarbageCollector getDefault() {
+ if (instance == null) {
+ instance = new FileGarbageCollector();
+ }
+ return instance;
+ }
+
+ private Queue<PhysicalFormat> queue;
+ private Thread thread;
+ private Map<PhysicalFormat, Integer> usageCount;
+ private Set<PhysicalFormat> persistent;
+
+ public FileGarbageCollector() {
+ queue = new LinkedList<PhysicalFormat>();
+ usageCount = new HashMap<PhysicalFormat, Integer>();
+ persistent = new HashSet<PhysicalFormat>();
+ thread = new Thread(this, "File Garbage Collector");
+ thread.setDaemon(true);
+ thread.start();
+ }
+
+ public synchronized void markAsPersistent(PhysicalFormat pf) {
+ persistent.add(pf);
+ }
+
+ public synchronized void decreaseUsageCount(PhysicalFormat pf) {
+ assert Thread.holdsLock(this);
+ Integer c = usageCount.get(pf);
+ if (c == null) {
+ if (persistent.remove(pf)) {
+ logger.debug("Usage count of " + pf + " is 0, but file is persistent. Not removing.");
+ }
+ else {
+ logger.debug("Usage count of " + pf + " is 0. Queueing for removal.");
+ queue.add(pf);
+ this.notify();
+ }
+ }
+ else {
+ if (c == 2) {
+ usageCount.remove(pf);
+ logger.debug("Decreasing usage count of " + pf + " to 1");
+ }
+ else {
+ usageCount.put(pf, c - 1);
+ logger.debug("Decreasing usage count of " + pf + " to " + c);
+ }
+ }
+ }
+
+ public synchronized void increaseUsageCount(PhysicalFormat pf) {
+ // a usage count of 1 is assumed if the key is not in the map
+ // A remap of a remappable mapper would increase the usage count to 2
+ Integer c = usageCount.get(pf);
+ if (c == null) {
+ usageCount.put(pf, 2);
+ logger.debug("Increasing usage count of " + pf + " to 2");
+ }
+ else {
+ usageCount.put(pf, c + 1);
+ logger.debug("Increasing usage count of " + pf + " to " + (c + 1));
+ }
+ }
+
+ public void run() {
+ try {
+ while (true) {
+ PhysicalFormat pf;
+ synchronized(this) {
+ while (queue.isEmpty()) {
+ this.wait();
+ }
+ pf = queue.remove();
+ }
+ try {
+ pf.clean();
+ }
+ catch (Exception e) {
+ logger.info("Failed to clean " + pf, e);
+ }
+ }
+ }
+ catch (InterruptedException e) {
+ }
+ }
+}
Added: trunk/src/org/griphyn/vdl/mapping/file/TestMapper.java
===================================================================
--- trunk/src/org/griphyn/vdl/mapping/file/TestMapper.java (rev 0)
+++ trunk/src/org/griphyn/vdl/mapping/file/TestMapper.java 2011-07-05 20:40:07 UTC (rev 4773)
@@ -0,0 +1,87 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Jul 4, 2011
+ */
+package org.griphyn.vdl.mapping.file;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.griphyn.vdl.mapping.AbsFile;
+import org.griphyn.vdl.mapping.AbstractMapper;
+import org.griphyn.vdl.mapping.Mapper;
+import org.griphyn.vdl.mapping.MappingParam;
+import org.griphyn.vdl.mapping.Path;
+import org.griphyn.vdl.mapping.PhysicalFormat;
+
+
+public class TestMapper extends AbstractMapper {
+ public static final MappingParam PARAM_FILE = new MappingParam("file");
+ public static final MappingParam PARAM_TEMP = new MappingParam("temp", false);
+ public static final MappingParam PARAM_REMAPPABLE = new MappingParam("remappable", false);
+ public static final MappingParam PARAM_STATIC = new MappingParam("static", true);
+
+ private PhysicalFormat remap, map;
+
+ @Override
+ public boolean canBeRemapped(Path path) {
+ return PARAM_REMAPPABLE.getBooleanValue(this);
+ }
+
+ @Override
+ public void remap(Path path, Mapper sourceMapper, Path sourcePath) {
+ if (PARAM_REMAPPABLE.getBooleanValue(this)) {
+ remap = sourceMapper.map(sourcePath);
+ System.out.println("Remapping " + path + " -> " + remap);
+ ensureCollectionConsistency(sourceMapper, sourcePath);
+ }
+ else {
+ throw new UnsupportedOperationException("remap");
+ }
+ }
+
+ @Override
+ public void clean(Path path) {
+ PhysicalFormat pf = map(path);
+ if (PARAM_TEMP.getBooleanValue(this)) {
+ System.out.println("Cleaning file " + pf);
+ FileGarbageCollector.getDefault().decreaseUsageCount(pf);
+ }
+ else {
+ System.out.println("Not cleaning " + pf + " (not temporary)");
+ }
+ }
+
+ @Override
+ public boolean isPersistent(Path path) {
+ return !PARAM_TEMP.getBooleanValue(this);
+ }
+
+ @Override
+ public PhysicalFormat map(Path path) {
+ if (remap == null) {
+ if (map == null) {
+ map = new AbsFile(PARAM_FILE.getStringValue(this));
+ }
+ return map;
+ }
+ else {
+ return remap;
+ }
+ }
+
+ @Override
+ public Collection<Path> existing() {
+ return Collections.singletonList(Path.EMPTY_PATH);
+ }
+
+ @Override
+ public boolean isStatic() {
+ return PARAM_STATIC.getBooleanValue(this);
+ }
+}
More information about the Swift-commit
mailing list