public final class TagLibraryIndex extends java.lang.Object
The set of tag libraries and tag names known at compile time.
Each tag library contributes one descriptor under {
TagLib AST transformation as the tag library is compiled. Descriptors are per class rather
than per module so that libraries packaged in separate jars merge on the classpath without any
build step having to combine them, in the same way META-INF/services entries do.
Reading the index answers "which tags exist in namespace x" without loading or reflecting over a single tag library class, which is what allows GSP expressions to be resolved when a page is compiled rather than dispatched dynamically when it renders.
| Modifiers | Name | Description |
|---|---|---|
static int |
FORMAT_VERSION |
Descriptor format this build writes and understands. |
static java.lang.String |
INCOMPLETE_LOCATION |
What the index could not describe, written by whatever produced it. |
static java.lang.String |
INDEX_LOCATION |
Classpath directory holding one descriptor per compiled tag library. |
static java.lang.String |
SETTINGS_LOCATION |
Settings the build states for the compilation the index is read in, written alongside the descriptors by the build and deliberately not packaged into the artifact: they describe how this project is compiled, not what its tag libraries declare. |
| Type Params | Return Type | Name and description |
|---|---|---|
|
public boolean |
declaresNamespace(java.lang.String namespace)Whether this project's own tag libraries declare a namespace. |
|
public static TagLibraryIndex |
forClassLoader(java.lang.ClassLoader classLoader)Reads the index for a class loader, reusing the one already read for it. |
|
public java.util.Set<java.lang.String> |
getDynamicNamespaces()Namespaces the build declared as filled in at runtime, whose tags are therefore never reported as unknown however complete the index is. |
|
public java.util.Set<java.lang.String> |
getNamespaces()
|
|
public java.util.Set<java.lang.String> |
getTagNames(java.lang.String namespace)
|
|
public java.util.Set<java.lang.String> |
getTagNamesForClass(java.lang.String tagLibraryClassName)The tags a given tag library declares, as recorded when it was compiled. |
|
public boolean |
hasNamespace(java.lang.String namespace)
|
|
public boolean |
isAmbiguous(java.lang.String namespace, java.lang.String tagName)Whether more than one tag library declares this tag, in which case which one the runtime will dispatch to depends on registration order and cannot be decided here. |
|
public boolean |
isClassDescribed(java.lang.String tagLibraryClassName)Whether a descriptor for this tag library already exists. |
|
public boolean |
isDynamicNamespace(java.lang.String namespace)
|
|
public boolean |
isEmpty()
|
|
public boolean |
isKnown(java.lang.String namespace, java.lang.String tagName)Whether a compiled tag library declares this tag, including one declared by more than one of them. |
|
public boolean |
isNamespaceComplete(java.lang.String namespace)Whether everything in a namespace was described. |
|
public boolean |
isStrict()Whether the build asked for a tag no compiled tag library declares to fail compilation. |
|
public static TagLibraryIndex |
load(java.lang.ClassLoader classLoader)Reads every tag library descriptor visible to the given class loader. |
|
public TagLibraryIndexEntry |
lookup(java.lang.String namespace, java.lang.String tagName)
|
|
public boolean |
rewritesUnqualifiedCalls()Whether a call written without a namespace may be compiled into an invocation. |
|
public java.lang.String |
toString() |
| Methods inherited from class | Name |
|---|---|
class java.lang.Object |
java.lang.Object#equals(java.lang.Object), java.lang.Object#getClass(), java.lang.Object#hashCode(), java.lang.Object#notify(), java.lang.Object#notifyAll(), java.lang.Object#toString(), java.lang.Object#wait(), java.lang.Object#wait(long), java.lang.Object#wait(long, int) |
Descriptor format this build writes and understands. A descriptor carrying anything else was produced by a different version of Grails and is ignored, so its tags resolve dynamically rather than being read under the wrong set of rules.
What the index could not describe, written by whatever produced it.
An index generated before its project is compiled cannot always read every tag library: one referring to a type that does not exist yet, in a language it cannot parse, or generated by the build itself, is left out. A namespace missing some of its tags must not have a call to one of them reported as a misspelling, so what was missed is recorded rather than left to be inferred from the absence.
Classpath directory holding one descriptor per compiled tag library.
Settings the build states for the compilation the index is read in, written alongside the descriptors by the build and deliberately not packaged into the artifact: they describe how this project is compiled, not what its tag libraries declare.
Whether this project's own tag libraries declare a namespace.
What a namespace holds is only fully knowable for the namespaces this project describes. Every other namespace is contributed to by tag libraries from elsewhere - a plugin built before descriptors existed, one registered while the application runs - and a tag missing from such a namespace is as likely to be one of those as a misspelling.
namespace - a tag library namespaceReads the index for a class loader, reusing the one already read for it.
Reading walks every jar on the classpath, so a compiler that consults the index for each source file it compiles would walk it once per file. Use this from compilation; use load(ClassLoader) where a fresh read is wanted.
classLoader - the loader to scan; when null the thread context loader is usednullNamespaces the build declared as filled in at runtime, whose tags are therefore never reported as unknown however complete the index is.
namespace - a tag library namespaceThe tags a given tag library declares, as recorded when it was compiled.
Answered from that tag library's own descriptor, so a tag it declares is reported whether or not another tag library declares the same name. Which of two tag libraries answers to a name at runtime is a separate question, asked through lookup and isAmbiguous.
This describes the class as it was compiled. A class that has since been reloaded, or one built without a descriptor, is not described here and has to be asked directly.
tagLibraryClassName - the binary name of a tag library
namespace - a tag library namespace, for example gWhether more than one tag library declares this tag, in which case which one the runtime will dispatch to depends on registration order and cannot be decided here.
namespace - a tag library namespacetagName - a tag name within that namespaceWhether a descriptor for this tag library already exists.
Lets a tag library being compiled tell whether something has already described it - the build generating the index ahead of compilation - so that it does not write a second, separately maintained copy. A tag library the build did not manage to describe is not covered here and describes itself instead.
tagLibraryClassName - the binary name of a tag library
namespace - a tag library namespace
Whether a compiled tag library declares this tag, including one declared by more than one of them. Such a tag exists; which tag library answers to it is settled at runtime.
namespace - a tag library namespacetagName - a tag name within that namespaceWhether everything in a namespace was described.
An index generated before its project is compiled may not have been able to read every tag library: one referring to a type that does not exist yet, written in a language it cannot parse, or generated by the build. A tag missing from an incomplete namespace is not evidence of a misspelling, so nothing about it should be reported.
namespace - a tag library namespaceWhether the build asked for a tag no compiled tag library declares to fail compilation.
grails.compileStatic.strictTagsReads every tag library descriptor visible to the given class loader.
classLoader - the loader to scan; when null the thread context loader is usednull
namespace - a tag library namespacetagName - a tag name within that namespacenull when the tag is not statically knownWhether a call written without a namespace may be compiled into an invocation.
Off unless the build asks for it. A namespaced call says which tag library it means; an unqualified one is a bare name, and whether that name is a tag depends on what else answers to it - a method Groovy gives every object, a delegate the enclosing closure is handed, an overload the tag library also declares. The compiler can rule those out only as far as it can see, so the default is to leave such a call to be dispatched as it always was.
grails.compileStatic.unqualifiedTagCalls