Open UndefinedOffset opened 7 years ago
It's also possible that html comments maybe ending the SilverStripe comment highlight (which it should not).
Actually seems to be that %>
is ending them when it shouldn't
I think it's the lexer, honestly I wonder if it should just be re-written pehaps a port from the plugin for IntelliJ IDEA platform. Also see here, the highlighting looks good at least.
What's really interesting is closing and re-opening the editor styles the document properly, so I wonder if a full refresh of the highlighting might fix the issue too.
It may also be the SSSourceParser not sure, this diff helps but line 125 can sometimes result in a null pointer
diff --git a/ca.edchipman.silverStripePDT/src/ca/edchipman/silverstripepdt/parser/SSSourceParser.java b/ca.edchipman.silverStripePDT/src/ca/edchipman/silverstripepdt/parser/SSSourceParser.java
index 0856390..2c669cf 100644
--- a/ca.edchipman.silverStripePDT/src/ca/edchipman/silverstripepdt/parser/SSSourceParser.java
+++ b/ca.edchipman.silverStripePDT/src/ca/edchipman/silverstripepdt/parser/SSSourceParser.java
@@ -1,7 +1,14 @@
package ca.edchipman.silverstripepdt.parser;
import org.eclipse.wst.sse.core.internal.ltk.parser.BlockTokenizer;
+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer;
+import org.eclipse.wst.sse.core.internal.util.Debug;
import org.eclipse.wst.xml.core.internal.parser.XMLSourceParser;
+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
+
+import ca.edchipman.silverstripepdt.regions.SilverStripeRegionContext;
@SuppressWarnings("restriction")
public class SSSourceParser extends XMLSourceParser {
@@ -11,4 +18,196 @@
}
return fTokenizer;
}
+
+ protected IStructuredDocumentRegion parseNodes() {
+ // regions are initially reported as complete offsets within the
+ // scanned input
+ // they are adjusted here to be indexes from the currentNode's start
+ // offset
+ IStructuredDocumentRegion headNode = null;
+ IStructuredDocumentRegion lastNode = null;
+ ITextRegion region = null;
+ IStructuredDocumentRegion currentNode = null;
+ String type = null;
+
+ while ((region = getNextRegion()) != null) {
+ type = region.getType();
+ // these types (might) demand a IStructuredDocumentRegion for each
+ // of them
+ if (type == DOMRegionContext.BLOCK_TEXT) {
+ if (currentNode != null && currentNode.getLastRegion().getType() == DOMRegionContext.BLOCK_TEXT) {
+ // multiple block texts indicated embedded containers; no
+ // new IStructuredDocumentRegion
+ currentNode.addRegion(region);
+ currentNode.setLength(region.getStart() + region.getLength() - currentNode.getStart());
+ region.adjustStart(-currentNode.getStart());
+ // DW 4/16/2003 regions no longer have parents
+ // region.setParent(currentNode);
+ if (region instanceof ITextRegionContainer) {
+ ((ITextRegionContainer) region).setParent(currentNode);
+ }
+ }
+ else {
+ // not continuing a IStructuredDocumentRegion
+ if (currentNode != null) {
+ // ensure that any existing node is at least
+ // terminated
+ if (!currentNode.isEnded()) {
+ currentNode.setLength(region.getStart() - currentNode.getStart());
+ // fCurrentNode.setTextLength(region.getStart() -
+ // fCurrentNode.getStart());
+ }
+ lastNode = currentNode;
+ }
+ fireNodeParsed(currentNode);
+ currentNode = createStructuredDocumentRegion(type);
+ if (lastNode != null) {
+ lastNode.setNext(currentNode);
+ }
+ currentNode.setPrevious(lastNode);
+ currentNode.setStart(region.getStart());
+ currentNode.setLength(region.getStart() + region.getLength() - currentNode.getStart());
+ currentNode.setEnded(true);
+ region.adjustStart(-currentNode.getStart());
+ currentNode.addRegion(region);
+ // DW 4/16/2003 regions no longer have parents
+ // region.setParent(currentNode);
+ if (region instanceof ITextRegionContainer) {
+ ((ITextRegionContainer) region).setParent(currentNode);
+ }
+ }
+ }
+ // the following contexts OPEN new StructuredDocumentRegions
+ else if ((currentNode != null && currentNode.isEnded())
+ || (type == SilverStripeRegionContext.SS_OPEN) || (type == SilverStripeRegionContext.SS_CONDITIONAL_OPEN) || (type == SilverStripeRegionContext.SS_COMMENT_OPEN) || (type == SilverStripeRegionContext.SS_REQUIREMENT_OPEN) || (type == SilverStripeRegionContext.SS_CONTROL_OPEN) || (type == SilverStripeRegionContext.SS_INCLUDE_OPEN) || (type == SilverStripeRegionContext.SS_CACHEBLOCK_OPEN) || (type == SilverStripeRegionContext.SS_UNCACHED_OPEN) || (type == SilverStripeRegionContext.SS_TEMPLATE_FUNCTION_OPEN) || (type == SilverStripeRegionContext.SS_LOOP_OPEN) || (type == SilverStripeRegionContext.SS_WITH_OPEN) || (type == SilverStripeRegionContext.SS_I18N_OPEN)
+ || (type == DOMRegionContext.XML_CONTENT) || (type == DOMRegionContext.XML_CHAR_REFERENCE) || (type == DOMRegionContext.XML_ENTITY_REFERENCE) || (type == DOMRegionContext.XML_PI_OPEN) || (type == DOMRegionContext.XML_TAG_OPEN) || (type == DOMRegionContext.XML_END_TAG_OPEN) || (type == DOMRegionContext.XML_COMMENT_OPEN) || (type == DOMRegionContext.XML_CDATA_OPEN) || (type == DOMRegionContext.XML_DECLARATION_OPEN)) {
+ if (currentNode != null) {
+ // ensure that any existing node is at least terminated
+ if (!currentNode.isEnded()) {
+ currentNode.setLength(region.getStart() - currentNode.getStart());
+ // fCurrentNode.setTextLength(region.getStart() -
+ // fCurrentNode.getStart());
+ }
+ lastNode = currentNode;
+ }
+ fireNodeParsed(currentNode);
+ currentNode = createStructuredDocumentRegion(type);
+ if (lastNode != null) {
+ lastNode.setNext(currentNode);
+ }
+ currentNode.setPrevious(lastNode);
+ currentNode.setStart(region.getStart());
+ currentNode.addRegion(region);
+ currentNode.setLength(region.getStart() + region.getLength() - currentNode.getStart());
+ region.adjustStart(-currentNode.getStart());
+ // DW 4/16/2003 regions no longer have parents
+ // region.setParent(currentNode);
+ if (region instanceof ITextRegionContainer) {
+ ((ITextRegionContainer) region).setParent(currentNode);
+ }
+ }
+ // the following contexts neither open nor close
+ // StructuredDocumentRegions; just add to them
+ else if ((type == SilverStripeRegionContext.SS_COMMENT_TEXT) || (type == SilverStripeRegionContext.SS_CONDITIONAL_TEXT) || (type == SilverStripeRegionContext.SS_COMMENT_TEXT) || (type == SilverStripeRegionContext.SS_REQUIREMENT_CONTENT) || (type == SilverStripeRegionContext.SS_CONTROL_CONTENT) || (type == SilverStripeRegionContext.SS_INCLUDE_CONTENT) || (type == SilverStripeRegionContext.SS_CACHEBLOCK_CONTENT) || (type == SilverStripeRegionContext.SS_UNCACHED_CONTENT) || (type == SilverStripeRegionContext.SS_TEMPLATE_FUNCTION_CONTENT) || (type == SilverStripeRegionContext.SS_LOOP_CONTENT) || (type == SilverStripeRegionContext.SS_WITH_CONTENT) || (type == SilverStripeRegionContext.SS_I18N_CONTENT)
+ || (type == DOMRegionContext.XML_TAG_NAME) || (type == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) || (type == DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS) || (type == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) || (type == DOMRegionContext.XML_COMMENT_TEXT) || (type == DOMRegionContext.XML_PI_CONTENT) || (type == DOMRegionContext.XML_DOCTYPE_INTERNAL_SUBSET)) {
+ currentNode.addRegion(region);
+ currentNode.setLength(region.getStart() + region.getLength() - currentNode.getStart());
+ region.adjustStart(-currentNode.getStart());
+ // DW 4/16/2003 regions no longer have parents
+ // region.setParent(currentNode);
+ if (region instanceof ITextRegionContainer) {
+ ((ITextRegionContainer) region).setParent(currentNode);
+ }
+ }
+ // the following contexts close off StructuredDocumentRegions
+ // cleanly
+ else if ((type == SilverStripeRegionContext.SS_CLOSE) || (type == SilverStripeRegionContext.SS_COMMENT_CLOSE) || (type == DOMRegionContext.XML_PI_CLOSE) || (type == DOMRegionContext.XML_TAG_CLOSE) || (type == DOMRegionContext.XML_EMPTY_TAG_CLOSE) || (type == DOMRegionContext.XML_COMMENT_CLOSE) || (type == DOMRegionContext.XML_DECLARATION_CLOSE) || (type == DOMRegionContext.XML_CDATA_CLOSE)) {
+ currentNode.setEnded(true);
+ currentNode.setLength(region.getStart() + region.getLength() - currentNode.getStart());
+ currentNode.addRegion(region);
+ region.adjustStart(-currentNode.getStart());
+ // DW 4/16/2003 regions no longer have parents
+ // region.setParent(currentNode);
+ if (region instanceof ITextRegionContainer) {
+ ((ITextRegionContainer) region).setParent(currentNode);
+ }
+ }
+ // this is extremely rare, but valid
+ else if (type == DOMRegionContext.WHITE_SPACE) {
+ ITextRegion lastRegion = currentNode.getLastRegion();
+ // pack the embedded container with this region
+ if (lastRegion instanceof ITextRegionContainer) {
+ ITextRegionContainer container = (ITextRegionContainer) lastRegion;
+ container.getRegions().add(region);
+ // containers must have parent set ...
+ // setting for EACH subregion is redundent, but not sure
+ // where else to do, so will do here for now.
+ container.setParent(currentNode);
+ // DW 4/16/2003 regions no longer have parents
+ // region.setParent(container);
+ if (region instanceof ITextRegionContainer) {
+ ((ITextRegionContainer) region).setParent(currentNode);
+ }
+ region.adjustStart(container.getLength() - region.getStart());
+ }
+ currentNode.getLastRegion().adjustLength(region.getLength());
+ currentNode.adjustLength(region.getLength());
+ }
+ else if (type == DOMRegionContext.UNDEFINED && currentNode != null) {
+ // skip on a very-first region situation as the default
+ // behavior is good enough
+ // combine with previous if also undefined
+ if (currentNode.getLastRegion() != null && currentNode.getLastRegion().getType() == DOMRegionContext.UNDEFINED) {
+ currentNode.getLastRegion().adjustLength(region.getLength());
+ currentNode.adjustLength(region.getLength());
+ }
+ // previous wasn't undefined
+ else {
+ currentNode.addRegion(region);
+ currentNode.setLength(region.getStart() + region.getLength() - currentNode.getStart());
+ region.adjustStart(-currentNode.getStart());
+ }
+ }
+ else {
+ // if an unknown type is the first region in the document,
+ // ensure that a node exists
+ if (currentNode == null) {
+ currentNode = createStructuredDocumentRegion(type);
+ currentNode.setStart(region.getStart());
+ }
+ currentNode.addRegion(region);
+ currentNode.setLength(region.getStart() + region.getLength() - currentNode.getStart());
+ region.adjustStart(-currentNode.getStart());
+ // DW 4/16/2003 regions no longer have parents
+ // region.setParent(currentNode);
+ if (region instanceof ITextRegionContainer) {
+ ((ITextRegionContainer) region).setParent(currentNode);
+ }
+ if (Debug.debugTokenizer)
+ System.out.println(getClass().getName() + " found region of not specifically handled type " + region.getType() + " @ " + region.getStart() + "[" + region.getLength() + "]"); //$NON-NLS-4$//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+ //$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+ }
+
+ // these regions also get their own node, so close them cleanly
+ // NOTE: these regions have new StructuredDocumentRegions created
+ // for them above; it may
+ // be more readable if that is handled here as well, but the
+ // current layout
+ // ensures that they open StructuredDocumentRegions the same way
+ if ((type == DOMRegionContext.XML_CONTENT) || (type == DOMRegionContext.XML_CHAR_REFERENCE) || (type == DOMRegionContext.XML_ENTITY_REFERENCE) || type == SilverStripeRegionContext.SS_CLOSE) {
+ currentNode.setEnded(true);
+ }
+ if (headNode == null && currentNode != null) {
+ headNode = currentNode;
+ }
+ }
+ if (currentNode != null) {
+ fireNodeParsed(currentNode);
+ currentNode.setPrevious(lastNode);
+ }
+
+ // fStringInput = null;
+ primReset();
+ return headNode;
+ }
}
I think the root cause is the lexer, it likely requires a full rewrite of it deferring to a future release
Seems as though at least in SilverStripe 3.6.0+ multiple line SilverStripe template comments are supported. Right now the lexer for the templates does not support this so we should extend it to support this.